Updated composer.lock file

This commit is contained in:
Pranshu Tomar 2020-05-13 17:37:15 +05:30
commit 7e4e979799
36 changed files with 2999 additions and 275 deletions

2
.gitignore vendored
View File

@ -25,4 +25,4 @@ yarn.lock
storage/
storage/*.key
/docker-compose-collection/
/resources/themes/velocity/*
/resources/themes/velocity/*

View File

@ -109,7 +109,10 @@
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
"Tests\\Acceptance\\": "tests/acceptance/",
"Tests\\Functional\\": "tests/functional/",
"Tests\\Unit\\": "tests/unit/",
"Tests\\Trigger\\": "tests/trigger/"
}
},

215
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": "89956b3147bad29980a3486770493059",
"content-hash": "0ba9dbd80803ce19df6735d4a92a17c6",
"packages": [
{
"name": "astrotomic/laravel-translatable",
@ -2664,76 +2664,6 @@
],
"time": "2019-11-08T13:50:10+00:00"
},
{
"name": "nwidart/laravel-modules",
"version": "3.3.1",
"source": {
"type": "git",
"url": "https://github.com/nWidart/laravel-modules.git",
"reference": "a7ec8a5871e57d337b7d37bbeb246fb99c41c703"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nWidart/laravel-modules/zipball/a7ec8a5871e57d337b7d37bbeb246fb99c41c703",
"reference": "a7ec8a5871e57d337b7d37bbeb246fb99c41c703",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.7",
"laravel/framework": "5.6.*",
"mockery/mockery": "~1.0",
"orchestra/testbench": "^3.6",
"phpstan/phpstan": "^0.9.2",
"phpunit/phpunit": "~7.0",
"spatie/phpunit-snapshot-assertions": "^1.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Nwidart\\Modules\\LaravelModulesServiceProvider"
],
"aliases": {
"Module": "Nwidart\\Modules\\Facades\\Module"
}
},
"branch-alias": {
"dev-master": "3.0-dev"
}
},
"autoload": {
"psr-4": {
"Nwidart\\Modules\\": "src"
},
"files": [
"src/helpers.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Widart",
"email": "n.widart@gmail.com",
"homepage": "https://nicolaswidart.com",
"role": "Developer"
}
],
"description": "Laravel Module management",
"keywords": [
"laravel",
"module",
"modules",
"nwidart",
"rad"
],
"time": "2018-07-13T15:36:59+00:00"
},
{
"name": "opis/closure",
"version": "3.5.1",
@ -4147,6 +4077,20 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-03-30T14:07:33+00:00"
},
{
@ -4299,6 +4243,20 @@
"mime",
"mime-type"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-03-27T16:56:45+00:00"
},
{
@ -4478,6 +4436,20 @@
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-03-09T19:04:49+00:00"
},
{
@ -4537,6 +4509,20 @@
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-03-09T19:04:49+00:00"
},
{
@ -4648,6 +4634,20 @@
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-02-27T09:26:54+00:00"
},
{
@ -6204,6 +6204,76 @@
],
"time": "2018-11-21T21:40:54+00:00"
},
{
"name": "nwidart/laravel-modules",
"version": "3.3.1",
"source": {
"type": "git",
"url": "https://github.com/nWidart/laravel-modules.git",
"reference": "a7ec8a5871e57d337b7d37bbeb246fb99c41c703"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nWidart/laravel-modules/zipball/a7ec8a5871e57d337b7d37bbeb246fb99c41c703",
"reference": "a7ec8a5871e57d337b7d37bbeb246fb99c41c703",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.7",
"laravel/framework": "5.6.*",
"mockery/mockery": "~1.0",
"orchestra/testbench": "^3.6",
"phpstan/phpstan": "^0.9.2",
"phpunit/phpunit": "~7.0",
"spatie/phpunit-snapshot-assertions": "^1.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Nwidart\\Modules\\LaravelModulesServiceProvider"
],
"aliases": {
"Module": "Nwidart\\Modules\\Facades\\Module"
}
},
"branch-alias": {
"dev-master": "3.0-dev"
}
},
"autoload": {
"psr-4": {
"Nwidart\\Modules\\": "src"
},
"files": [
"src/helpers.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Widart",
"email": "n.widart@gmail.com",
"homepage": "https://nicolaswidart.com",
"role": "Developer"
}
],
"description": "Laravel Module management",
"keywords": [
"laravel",
"module",
"modules",
"nwidart",
"rad"
],
"time": "2018-07-13T15:36:59+00:00"
},
{
"name": "phar-io/manifest",
"version": "1.0.3",
@ -7770,5 +7840,6 @@
"ext-pdo_mysql": "*",
"ext-tokenizer": "*"
},
"platform-dev": []
"platform-dev": [],
"plugin-api-version": "1.1.0"
}

View File

@ -3,9 +3,6 @@
namespace Webkul\Admin\Providers;
use Illuminate\Support\ServiceProvider;
use Webkul\Admin\Providers\EventServiceProvider;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Webkul\Admin\Exceptions\Handler;
use Webkul\Core\Tree;
class AdminServiceProvider extends ServiceProvider
@ -32,11 +29,6 @@ class AdminServiceProvider extends ServiceProvider
$this->registerACL();
$this->app->register(EventServiceProvider::class);
$this->app->bind(
ExceptionHandler::class,
Handler::class
);
}
/**
@ -96,7 +88,7 @@ class AdminServiceProvider extends ServiceProvider
view()->composer(['admin::users.roles.create', 'admin::users.roles.edit'], function ($view) {
$view->with('acl', $this->createACL());
});
view()->composer(['admin::catalog.products.create'], function ($view) {
$items = array();

File diff suppressed because it is too large Load Diff

View File

@ -341,7 +341,7 @@
<div class="summary-comment-container">
<div class="comment-container">
<form action="{{ route('admin.sales.orders.comment', $order->id) }}" method="post">
<form action="{{ route('admin.sales.orders.comment', $order->id) }}" method="post" @submit.prevent="onSubmit">
@csrf()
<div class="control-group" :class="[errors.has('comment') ? 'has-error' : '']">

View File

@ -0,0 +1,125 @@
<?php
return [
'admin' => [
'catalog' => [
'products' => [
'booking' => 'Informazioni Prenotazione',
'booking-type' => 'Prenotazione Tipo',
'default' => 'Default',
'appointment-booking' => 'Prenotazione Appuntamento',
'event-booking' => 'Prenotazione Evento',
'rental-booking' => 'Prenotazione Noleggio',
'table-booking' => 'Prenotazione Tavolo',
'slot-duration' => 'Durata Slot (Min)',
'break-time' => 'Break Time b/w Slots (Mins)',
'available-every-week' => 'Disponibiità Ogni Settimana',
'yes' => 'Sì',
'no' => 'No',
'available-from' => 'Disponibile Da',
'available-to' => 'Disponibile Fino A',
'same-slot-all-days' => 'Stesso Slot tutti i giorni',
'slot-has-quantity' => 'Slot ha quantità',
'slots' => 'Slot',
'from' => 'Da',
'to' => 'A',
'qty' => 'Qtà',
'add-slot' => 'Aggiungi Slot',
'sunday' => 'Domenica',
'monday' => 'Lunedì',
'tuesday' => 'Martedì',
'wednesday' => 'Mercoledì',
'thursday' => 'Giovedì',
'friday' => 'Venerdì',
'saturday' => 'Sabato',
'renting-type' => 'Tipo di noleggio',
'daily' => 'Base Giornaliera',
'hourly' => 'Base Oraria',
'daily-hourly' => 'Entrambe (Base Giornaliera e Oraria)',
'daily-price' => 'Prezzo al giorno',
'hourly-price' => 'Prezzo all\'ora',
'location' => 'Location',
'show-location' => 'Mostra Location',
'event-start-date' => 'Data Inizio Evento',
'event-end-date' => 'Data Fine Evento',
'tickets' => 'Biglietti',
'add-ticket' => 'Aggungi Biglietto',
'name' => 'Nome',
'price' => 'Prezzo',
'quantity' => 'Quantità',
'description' => 'Descrizione',
'charged-per' => 'Charged Per',
'guest' => 'Ospite',
'table' => 'Tavolo',
'prevent-scheduling-before' => 'Previeni Scheduling Prima',
'guest-limit' => 'Limite Ospiti per Tavolo',
'guest-capacity' => 'Capacità Ospiti',
'type' => 'Tipo',
'many-bookings-for-one-day' => 'Diverse prenotazioni di un giorno',
'one-booking-for-many-days' => 'Una prenotazione per diversi giorni',
'day' => 'Giorno',
'status' => 'Stato',
'open' => 'Aperto',
'close' => 'Chiuso'
]
]
],
'shop' => [
'products' => [
'location' => 'Location',
'contact' => 'Contatto',
'email' => 'Email',
'slot-duration' => 'Durata Slot',
'slot-duration-in-minutes' => ':minutes Minuti',
'today-availability' => 'Disponibilità odierna',
'slots-for-all-days' => 'Mostra per tutti i giorni',
'sunday' => 'Domenica',
'monday' => 'Lunedì',
'tuesday' => 'Martedì',
'wednesday' => 'Mercoledì',
'thursday' => 'Giovedì',
'friday' => 'Venerdì',
'saturday' => 'Sabato',
'closed' => 'Chiuso',
'book-an-appointment' => 'Prenota un Appuntamento',
'date' => 'Data',
'slot' => 'Slot',
'rent-an-item' => 'Noleggia un Articolo',
'choose-rent-option' => 'Scegli una opzione di noleggio',
'daily-basis' => 'Base Giornaliera',
'hourly-basis' => 'Base Oraria',
'select-time-slot'=> 'Seleziona slot di tempo',
'select-slot' => 'Seleziona Slot',
'select-date' => 'Seleziona data',
'select-rent-time' => 'Seleziona Periodo di Noleggio',
'from' => 'Da',
'to' => 'A',
'book-a-table' => 'Prenota un Tavolo',
'special-notes' => 'Richieste/Note Speciali',
'event-on' => 'Evento del',
'book-your-ticket' => 'Prenota il tuo Biglietto',
'per-ticket-price' => ':price per Biglietto',
'number-of-tickets' => 'Numero di Biglietti',
'total-tickets' => 'Totale Biglietti',
'base-price' => 'Prezzo Base',
'total-price' => 'Prezzo Totale',
'base-price-info' => '(Questo si applicherà ad ogni tipo di biglietto per ciascuna quantità)'
],
'cart' => [
'renting_type' => 'Tipo Noleggio',
'daily' => 'Giornaliero',
'hourly' => 'Orario',
'event-ticket' => 'Biglietto Evento',
'event-from' => 'Evento dal',
'event-till' => 'Evento al',
'rent-type' => 'Tipo Noleggio',
'rent-from' => 'Noleggio Da',
'rent-till' => 'Noleggio A',
'booking-from' => 'Prenotazione Da',
'booking-till' => 'Prenotazione A',
'special-note' => 'Richieste/Note Speciali',
]
]
];

View File

@ -124,7 +124,9 @@ class CartRule
$this->processFreeShippingDiscount($cart);
$this->validateCouponCode();
if (! $this->checkCouponCode()) {
cart()->removeCouponCode();
}
}
/**
@ -324,16 +326,14 @@ class CartRule
break;
}
$item->discount_amount = round(
min(
$item->discount_amount + $discountAmount,
$item->price * $quantity + $item->tax_amount
),2);
$item->base_discount_amount = round(
min(
$item->base_discount_amount + $baseDiscountAmount,
$item->base_price * $quantity + $item->base_tax_amount
), 2);
$item->discount_amount = min(
$item->discount_amount + $discountAmount,
$item->price * $quantity + $item->tax_amount
);
$item->base_discount_amount = min(
$item->base_discount_amount + $baseDiscountAmount,
$item->base_price * $quantity + $item->base_tax_amount
);
$appliedRuleIds[$rule->id] = $rule->id;
@ -518,23 +518,26 @@ class CartRule
}
/**
* Check if coupon code is valid or not, if not remove from cart
* Check if coupon code is applied or not
*
* @return void
* @return bool
*/
public function validateCouponCode()
public function checkCouponCode(): bool
{
$cart = Cart::getCart();
$cart = cart()->getCart();
if (! $cart->coupon_code) {
return;
return true;
}
$coupon = $this->cartRuleCouponRepository->findOneByField('code', $cart->coupon_code);
if (! $coupon || ! in_array($coupon->cart_rule_id, explode(',', $cart->applied_cart_rule_ids))) {
Cart::removeCouponCode();
$coupons = $this->cartRuleCouponRepository->where(['code' => $cart->coupon_code])->get();
foreach ($coupons as $coupon) {
if (in_array($coupon->cart_rule_id, explode(',', $cart->applied_cart_rule_ids))) {
return true;
}
}
return false;
}
/**

View File

@ -2,6 +2,7 @@
namespace Webkul\Checkout;
use Webkul\Checkout\Models\Cart as CartModel;
use Webkul\Checkout\Models\CartAddress;
use Webkul\Checkout\Repositories\CartRepository;
use Webkul\Checkout\Repositories\CartItemRepository;
@ -600,6 +601,8 @@ class Cart
$cart->base_discount_amount += $shipping->base_discount_amount;
}
$cart = $this->finalizeCartTotals($cart);
$quantities = 0;
foreach ($cart->items as $item) {
@ -1052,6 +1055,25 @@ class Cart
}
}
/**
* Round cart totals
*
* @param \Webkul\Checkout\Models\Cart $cart
*
* @return \Webkul\Checkout\Models\Cart
*/
private function finalizeCartTotals(CartModel $cart): CartModel
{
$cart->discount_amount = round($cart->discount_amount, 2);
$cart->base_discount_amount = round($cart->base_discount_amount, 2);
$cart->grand_total = round($cart->grand_total, 2);
$cart->grand_total = round($cart->grand_total, 2);
$cart->base_grand_total = round($cart->base_grand_total, 2);
return $cart;
}
/**
* @param $user
*

View File

@ -1,15 +1,15 @@
<?php
namespace Webkul\Admin\Exceptions;
namespace Webkul\Core\Exceptions;
use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\PDOException;
use Doctrine\DBAL\Driver\PDOException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use App\Exceptions\Handler as AppExceptionHandler;
class Handler extends ExceptionHandler
class Handler extends AppExceptionHandler
{
protected $jsonErrorMessages = [
404 => 'Resource not found',

View File

@ -2,11 +2,13 @@
namespace Webkul\Core\Providers;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Illuminate\Database\Eloquent\Factory as EloquentFactory;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\AliasLoader;
use Webkul\Core\Core;
use Webkul\Core\Exceptions\Handler;
use Webkul\Core\Facades\Core as CoreFacade;
use Webkul\Core\Models\SliderProxy;
use Webkul\Core\Observers\SliderObserver;
@ -41,6 +43,11 @@ class CoreServiceProvider extends ServiceProvider
dirname(__DIR__) . '/Config/concord.php' => config_path('concord.php'),
]);
$this->app->bind(
ExceptionHandler::class,
Handler::class
);
SliderProxy::observe(SliderObserver::class);
}

View File

@ -0,0 +1,7 @@
<?php
return [
'slug' => ':attribute deve essere uno slug valido.',
'code' => ':attribute deve essere valido.',
'decimal' => ':attribute deve essere valido.'
];

View File

@ -0,0 +1,21 @@
<?php
return [
'wishlist' => [
'success' => 'Prodotto aggiunto ai Preferiti',
'failure' => 'Il Prodotto non può essere aggiunto ai Preferiti',
'already' => 'Prodotto già presente nei tuoi Preferiti',
'removed' => 'Prodotto rimosso con successo dai Preferiti',
'remove-fail' => 'Non è stato possibile rimuovere il prodotto dai Preferiti',
'empty' => 'Non hai prodotti nei tuoi Preferiti',
'select-options' => 'Seleziona una opzione del prodotto prima di aggiungerlo ai Preferiti',
'remove-all-success' => 'Tutti i Prodotti presenti nei preferiti sono stati rimossi',
],
'reviews' => [
'empty' => 'Non hai ancora recensito i nostri prodotti'
],
'forget_password' => [
'reset_link_sent' => 'Ti abbiamo inviato una email per generare una nuova password.'
]
];

View File

@ -2,13 +2,13 @@
namespace Webkul\Product\Repositories;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Facades\DB;
use Illuminate\Container\Container as App;
use Illuminate\Support\Facades\Event;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Core\Eloquent\Repository;
use Webkul\Product\Repositories\ProductFlatRepository;
use Webkul\Product\Models\ProductAttributeValue;
class ProductRepository extends Repository
@ -108,18 +108,22 @@ class ProductRepository extends Repository
{
$params = request()->input();
$results = app(ProductFlatRepository::class)->scopeQuery(function($query) use($params, $categoryId) {
$perPage = isset($params['limit']) ? $params['limit'] : 9;
$page = Paginator::resolveCurrentPage('page');
$repository = app(ProductFlatRepository::class)->scopeQuery(function($query) use($params, $categoryId) {
$channel = request()->get('channel') ?: (core()->getCurrentChannelCode() ?: core()->getDefaultChannelCode());
$locale = request()->get('locale') ?: app()->getLocale();
$qb = $query->distinct()
->addSelect('product_flat.*')
->leftJoin('products', 'product_flat.product_id', '=', 'products.id')
->leftJoin('product_categories', 'products.id', '=', 'product_categories.product_id')
->where('product_flat.channel', $channel)
->where('product_flat.locale', $locale)
->whereNotNull('product_flat.url_key');
->select('product_flat.*')
->join('product_flat as variants', 'product_flat.id', '=', DB::raw('COALESCE(variants.parent_id, variants.id)'))
->leftJoin('product_categories', 'product_categories.product_id', '=', 'product_flat.product_id')
->leftJoin('product_attribute_values', 'product_attribute_values.product_id', '=', 'variants.product_id')
->where('product_flat.channel', $channel)
->where('product_flat.locale', $locale)
->whereNotNull('product_flat.url_key');
if ($categoryId) {
$qb->where('product_categories.category_id', $categoryId);
@ -133,12 +137,6 @@ class ProductRepository extends Repository
$qb->where('product_flat.visible_individually', 1);
}
$queryBuilder = $qb->leftJoin('product_flat as flat_variants', function($qb) use($channel, $locale) {
$qb->on('product_flat.id', '=', 'flat_variants.parent_id')
->where('flat_variants.channel', $channel)
->where('flat_variants.locale', $locale);
});
if (isset($params['search']))
$qb->where('product_flat.name', 'like', '%' . urldecode($params['search']) . '%');
@ -158,50 +156,84 @@ class ProductRepository extends Repository
}
}
$qb = $qb->leftJoin('products as variants', 'products.id', '=', 'variants.parent_id');
if( $priceFilter = request('price') ){
$priceRange = explode(',', $priceFilter);
if( count($priceRange) > 0 ) {
$qb->where('variants.min_price', '>=', core()->convertToBasePrice($priceRange[0]));
$qb->where('variants.min_price', '<=', core()->convertToBasePrice(end($priceRange)));
}
}
$qb = $qb->where(function($query1) use($qb) {
$aliases = [
'products' => 'filter_',
'variants' => 'variant_filter_',
];
$attributeFilters = $this->attributeRepository
->getProductDefaultAttributes(array_keys(
request()->except(['price'])
));
foreach($aliases as $table => $alias) {
$query1 = $query1->orWhere(function($query2) use ($qb, $table, $alias) {
if( count($attributeFilters) > 0 ) {
$qb->where(function ($filterQuery) use($attributeFilters){
foreach ($this->attributeRepository->getProductDefaultAttributes(array_keys(request()->input())) as $code => $attribute) {
$aliasTemp = $alias . $attribute->code;
foreach ($attributeFilters as $attribute) {
$filterQuery->orWhere(function ($attributeQuery) use ($attribute) {
$qb = $qb->leftJoin('product_attribute_values as ' . $aliasTemp, $table . '.id', '=', $aliasTemp . '.product_id');
$column = 'product_attribute_values.' . ProductAttributeValue::$attributeTypeFields[$attribute->type];
$column = ProductAttributeValue::$attributeTypeFields[$attribute->type];
$filterInputValues = explode(',', request()->get($attribute->code));
$temp = explode(',', request()->get($attribute->code));
# define the attribute we are filtering
$attributeQuery = $attributeQuery->where('product_attribute_values.attribute_id', $attribute->id);
# apply the filter values to the correct column for this type of attribute.
if ($attribute->type != 'price') {
$query2 = $query2->where($aliasTemp . '.attribute_id', $attribute->id);
$query2 = $query2->where(function($query3) use($aliasTemp, $column, $temp) {
foreach($temp as $code => $filterValue) {
if (! is_numeric($filterValue)) {
$attributeQuery->where(function ($attributeValueQuery) use ($column, $filterInputValues) {
foreach ($filterInputValues as $filterValue) {
if (!is_numeric($filterValue)) {
continue;
}
$columns = $aliasTemp . '.' . $column;
$query3 = $query3->orwhereRaw("find_in_set($filterValue, $columns)");
$attributeValueQuery->orWhereRaw("find_in_set(?, {$column})", [$filterValue]);
}
});
} else {
$query2->where('product_flat.min_price', '>=', core()->convertToBasePrice(current($temp)))
->where('product_flat.min_price', '<=', core()->convertToBasePrice(end($temp)));
$attributeQuery->where($column, '>=', core()->convertToBasePrice(current($filterInputValues)))
->where($column, '<=', core()->convertToBasePrice(end($filterInputValues)));
}
}
});
}
});
});
}
});
# this is key! if a product has been filtered down to the same number of attributes that we filtered on,
# we know that it has matched all of the requested filters.
$qb->groupBy('variants.id');
$qb->havingRaw('COUNT(*) = ' . count($attributeFilters));
}
return $qb->groupBy('product_flat.id');
})->paginate(isset($params['limit']) ? $params['limit'] : 9);
});
# apply scope query so we can fetch the raw sql and perform a count
$repository->applyScope();
$countQuery = "select count(*) as aggregate from ({$repository->model->toSql()}) c";
$count = collect(DB::select($countQuery, $repository->model->getBindings()))->pluck('aggregate')->first();
if($count > 0) {
# apply a new scope query to limit results to one page
$repository->scopeQuery(function ($query) use ($page, $perPage) {
return $query->forPage($page, $perPage);
});
# manually build the paginator
$items = $repository->get();
} else {
$items = [];
}
$results = new \Illuminate\Pagination\LengthAwarePaginator($items, $count, $perPage, $page, [
'path' => request()->url(),
'query' => request()->query()
]);
return $results;
}

View File

@ -573,6 +573,8 @@ class Configurable extends AbstractType
public function haveSufficientQuantity($qty)
{
$backorders = core()->getConfigData('catalog.inventory.stock_options.backorders');
$backorders = ! is_null ($backorders) ? $backorders : false;
foreach ($this->product->variants as $variant) {
if ($variant->haveSufficientQuantity($qty)) {
@ -598,4 +600,35 @@ class Configurable extends AbstractType
return false;
}
/**
* @return int
*/
public function totalQuantity()
{
$total = 0;
$channelInventorySourceIds = core()->getCurrentChannel()
->inventory_sources()
->where('status', 1)
->pluck('id');
foreach ($this->product->variants as $variant) {
foreach ($variant->inventories as $inventory) {
if (is_numeric($index = $channelInventorySourceIds->search($inventory->inventory_source_id))) {
$total += $inventory->qty;
}
}
$orderedInventory = $variant->ordered_inventories()
->where('channel_id', core()->getCurrentChannel()->id)
->first();
if ($orderedInventory) {
$total -= $orderedInventory->qty;
}
}
return $total;
}
}

View File

@ -56,7 +56,9 @@ class Simple extends AbstractType
public function haveSufficientQuantity($qty)
{
$backorders = core()->getConfigData('catalog.inventory.stock_options.backorders');
$backorders = ! is_null ($backorders) ? $backorders : false;
return $qty <= $this->totalQuantity() ? true : $backorders;
}
}

View File

@ -1,79 +0,0 @@
<?php
namespace Webkul\Shop\Exceptions;
use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\PDOException;
use Illuminate\Database\Eloquent\ErrorException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
protected $jsonErrorMessages = [
404 => 'Resource not found',
403 => '403 forbidden Error',
401 => 'Unauthenticated',
500 => '500 Internal Server Error',
];
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
$path = 'shop';
if ($exception instanceof HttpException) {
$statusCode = in_array($exception->getStatusCode(), [401, 403, 404, 503]) ? $exception->getStatusCode() : 500;
return $this->response($path, $statusCode);
} elseif ($exception instanceof ModelNotFoundException) {
return $this->response($path, 404);
} elseif ($exception instanceof PDOException) {
return $this->response($path, 500);
}
return parent::render($request, $exception);
}
/**
* Convert an authentication exception into a response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Auth\AuthenticationException $exception
* @return \Illuminate\Http\Response
*/
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => $this->jsonErrorMessages[401]], 401);
}
return redirect()->guest(route('auth.login'));
}
private function isSopUri()
{
return strpos(\Illuminate\Support\Facades\Request::path(), 'shop') !== false ? true : false;
}
private function response($path, $statusCode)
{
if (request()->expectsJson()) {
return response()->json([
'error' => isset($this->jsonErrorMessages[$statusCode])
? $this->jsonErrorMessages[$statusCode]
: 'Something went wrong, please try again later.'
], $statusCode);
}
return response()->view("{$path}::errors.{$statusCode}", [], $statusCode);
}
}

View File

@ -0,0 +1,687 @@
<?php
return [
'invalid_vat_format' => 'La partita IVA indicata ha un formato non corretto',
'security-warning' => 'Identificata attività sospetta!!!',
'nothing-to-delete' => 'Niente da eliminare',
'layouts' => [
'my-account' => 'Il Mio Account',
'profile' => 'Profilo',
'address' => 'Indirizzo',
'reviews' => 'Recensioni',
'wishlist' => 'Preferiti',
'orders' => 'Ordini',
'downloadable-products' => 'Prodotti Scaricabili'
],
'common' => [
'error' => 'Qualcosa è andato storto, per favore prova ancora più tardi.',
'no-result-found' => 'Non abbiamo trovato risultati.'
],
'home' => [
'page-title' => config('app.name') . ' - Home',
'featured-products' => 'Prodotti in evidenza',
'new-products' => 'Nuovi Prodotti',
'verify-email' => 'Verifica il tuo indirizzo email',
'resend-verify-email' => 'Reinvia email di verifica'
],
'header' => [
'title' => 'Account',
'dropdown-text' => 'Gestione Carrello, Ordini e Preferiti',
'sign-in' => 'Login',
'sign-up' => 'Registrati',
'account' => 'Account',
'cart' => 'Carrello',
'profile' => 'Profilo',
'wishlist' => 'Preferiti',
'cart' => 'Carrello',
'logout' => 'Logout',
'search-text' => 'Cerca prodotti qui'
],
'minicart' => [
'view-cart' => 'Mostra Carrello',
'checkout' => 'Cassa',
'cart' => 'Carrello',
'zero' => '0'
],
'footer' => [
'subscribe-newsletter' => 'Iscriviti alla Newsletter',
'subscribe' => 'Iscriviti',
'locale' => 'Lingua',
'currency' => 'Valuta',
],
'subscription' => [
'unsubscribe' => 'Cancellati',
'subscribe' => 'Iscriviti',
'subscribed' => 'Ora sei iscritto al nostro servizio di notifica.',
'not-subscribed' => 'Non è stato possibile iscriverti al nostro servizio di notifica, prova di nuovo più tardi.',
'already' => 'Sei già iscritto al nostro servizio di notifica.',
'unsubscribed' => 'Sei stato rimosso dal nostro servizio di notifica.',
'already-unsub' => 'Sei già stato cancellato.',
'not-subscribed' => 'Errore! L\'email non può essere inviata in questo momento, per favore riprovare più tardi.'
],
'search' => [
'no-results' => 'Nessun risultato trovato',
'page-title' => config('app.name') . ' - Cerca',
'found-results' => 'Risultati trovati',
'found-result' => 'Risultato trovato'
],
'reviews' => [
'title' => 'Titolo',
'add-review-page-title' => 'Aggiungi Recensione',
'write-review' => 'Scrivi una recensione',
'review-title' => 'Dai un titolo alla tua recensione',
'product-review-page-title' => 'Recensione Prodotto',
'rating-reviews' => 'Valutazioni e recensioni',
'submit' => 'INVIA',
'delete-all' => 'Tutte le recensioni sono state eliminate con successo',
'ratingreviews' => ':rating Valutazioni e :review Recensioni',
'star' => 'Stella',
'percentage' => ':percentage %',
'id-star' => 'stella',
'name' => 'Nome',
],
'customer' => [
'signup-text' => [
'account_exists' => 'Sei già registrato?',
'title' => 'Login'
],
'signup-form' => [
'page-title' => 'Crea subito il tuo profilo',
'title' => 'Registrati',
'firstname' => 'Nome',
'lastname' => 'Cognome',
'email' => 'Email',
'password' => 'Password',
'confirm_pass' => 'Conferma Password',
'button_title' => 'Registrati',
'agree' => 'Acconsento',
'terms' => 'Termini',
'conditions' => 'Condizioni',
'using' => 'utilizzando questo sito',
'agreement' => 'Accordo',
'success' => 'Account creato con successo.',
'success-verify' => 'Account creato con successo, una e-mail è stata inviata per verifica.',
'success-verify-email-unsent' => 'Account creato con successo, ma non è stato possibile inviare l\'email di verifica.',
'failed' => 'Errore! Non è stato possibile creare il tuo profilo, prova di nuovo più tardi.',
'already-verified' => 'Il tuo profilo è già stato verificato oppure il link di verifica è scaduto. Prova a chidere una nuova email di verifica.',
'verification-not-sent' => 'Errore! Problema nell\'invio dell\'email di verifica, prova di nuovo più tardi.',
'verification-sent' => 'Email di verifica inviata',
'verified' => 'Il tuo account è stato verificato, prova ora ad autenticarti.',
'verify-failed' => 'Non possiamo verificare la tua email',
'dont-have-account' => 'Non risulti registrato sul nostro sito.',
'customer-registration' => 'CIl cliente è stato registrato con successo'
],
'login-text' => [
'no_account' => 'Primo accesso?',
'title' => 'Registrati',
],
'login-form' => [
'page-title' => 'Login',
'title' => 'Login',
'email' => 'Email',
'password' => 'Password',
'forgot_pass' => 'Dimenticato Password?',
'button_title' => 'Login',
'remember' => 'Ricordami',
'footer' => '© Copyright :year Webkul Software, Tutti i diritti riservati',
'invalid-creds' => 'Per favore verifica le tue credenziali e prova di nuovo.',
'verify-first' => 'Verifica prima il tuo account email.',
'not-activated' => 'La tua attivazione richiede l\'approvazione di un amministratore',
'resend-verification' => 'Reinvia l\'email di verifica'
],
'forgot-password' => [
'title' => 'Recupera Password',
'email' => 'Email',
'submit' => 'Richiedi nuova Password',
'page_title' => 'Hai dimenticato la Password?'
],
'reset-password' => [
'title' => 'Crea nuova Password',
'email' => 'Email registrata',
'password' => 'Password',
'confirm-password' => 'Conferma Password',
'back-link-title' => 'Ritorna a Login',
'submit-btn-title' => 'Aggiorna Password'
],
'account' => [
'dashboard' => 'Modifica Profilo',
'menu' => 'Menu',
'profile' => [
'index' => [
'page-title' => 'Profilo',
'title' => 'Profilo',
'edit' => 'Modifica',
],
'edit-success' => 'Profilo aggiornato con successo.',
'edit-fail' => 'Errore! Non è stato possibile aggiornare il profilo, prova nuovamente più tardi.',
'unmatch' => 'La vecchia password non coincide.',
'fname' => 'Nome',
'lname' => 'Cognome',
'gender' => 'Sesso',
'other' => 'Altro',
'male' => 'Uomo',
'female' => 'Donna',
'dob' => 'Data di nascita',
'phone' => 'Telefono',
'email' => 'Email',
'opassword' => 'Vecchia Password',
'password' => 'Password',
'cpassword' => 'Conferma Password',
'submit' => 'Aggiorna Profilo',
'edit-profile' => [
'title' => 'Modifica Profilo',
'page-title' => 'Modifica Profilo'
]
],
'address' => [
'index' => [
'page-title' => 'Indirizzo',
'title' => 'Indirizzo',
'add' => 'Aggiungi Indirizzo',
'edit' => 'Modifica',
'empty' => 'Non hai ancora salvato i tuoi indirizzi, prova ad aggiungerne uno cliccando il link qui sotto',
'create' => 'Crea Indirizzo',
'delete' => 'Elimina',
'make-default' => 'Rendi Predefinito',
'default' => 'Predefinito',
'contact' => 'Contatto',
'confirm-delete' => 'Vuoi veramente eliminare questo indirizzo?',
'default-delete' => 'L\'indirizzo predefinito non può essere modificato.',
'enter-password' => 'Inserisci la tua Password.',
],
'create' => [
'page-title' => 'Aggiungi Indirizzo',
'company_name' => 'Ragione Sociale',
'first_name' => 'Nome',
'last_name' => 'Cognome',
'vat_id' => 'Partita IVA',
'vat_help_note' => '[Nota: Utilizza il codice paese con la Partita IVA. Es. IT01234567891]',
'title' => 'Aggiungi Indirizzo',
'street-address' => 'Indirizzo',
'country' => 'Paese',
'state' => 'Provincia',
'select-state' => 'Seleziona provincia',
'city' => 'Città',
'postcode' => 'CAP',
'phone' => 'Telefono',
'submit' => 'Salva Indirizzo',
'success' => 'Indirizzo aggiunto con successo.',
'error' => 'Non è stato possibile aggiungere l\'indirizzo.'
],
'edit' => [
'page-title' => 'Modifica Indirizzo',
'company_name' => 'Ragione Sociale',
'first_name' => 'Nome',
'last_name' => 'Cognome',
'vat_id' => 'Partita IVA',
'title' => 'Modifica Indirizzo',
'street-address' => 'Indirizzo',
'submit' => 'Salva Indirizzo',
'success' => 'Indirizzo aggiornato con successo.',
],
'delete' => [
'success' => 'Indirizzo eliminato con successo',
'failure' => 'L\'indirizzo non può essere eliminato',
'wrong-password' => 'Password errata !'
]
],
'order' => [
'index' => [
'page-title' => 'Ordini',
'title' => 'Ordini',
'order_id' => 'Ordine Nro',
'date' => 'Data',
'status' => 'Status',
'total' => 'Totale',
'order_number' => 'Numero Ordine',
'processing' => 'In lavorazione',
'completed' => 'Completato',
'canceled' => 'Cancellato',
'closed' => 'Chiuso',
'pending' => 'In attesa',
'pending-payment' => 'In attesa pagamento',
'fraud' => 'Frode'
],
'view' => [
'page-tile' => 'Ordine #:order_id',
'info' => 'Informazioni',
'placed-on' => 'Data Ordine',
'products-ordered' => 'Prodotti Ordinati',
'invoices' => 'Fatture',
'shipments' => 'Spedizioni',
'SKU' => 'SKU',
'product-name' => 'Articolo',
'qty' => 'Qtà',
'item-status' => 'Stato Articolo',
'item-ordered' => 'Ordinato (:qty_ordered)',
'item-invoice' => 'Fatturato (:qty_invoiced)',
'item-shipped' => 'spedito (:qty_shipped)',
'item-canceled' => 'Cancellato (:qty_canceled)',
'item-refunded' => 'Rimborsato (:qty_refunded)',
'price' => 'Prezzo',
'total' => 'Totale',
'subtotal' => 'Subtotale',
'shipping-handling' => 'Spedizione',
'tax' => 'IVA',
'discount' => 'Sconto',
'tax-percent' => 'IVA %',
'tax-amount' => 'IVA',
'discount-amount' => 'Sconto',
'grand-total' => 'Totale',
'total-paid' => 'Totale Pagato',
'total-refunded' => 'Total Rimborsato',
'total-due' => 'Totale da pagare',
'shipping-address' => 'Indirizzo Spedizione',
'billing-address' => 'Indirizzo Ordinante',
'shipping-method' => 'Metodo Spedizione',
'payment-method' => 'Metodo Pagamento',
'individual-invoice' => 'Fattura #:invoice_id',
'individual-shipment' => 'Spedizione #:shipment_id',
'print' => 'Stampa',
'invoice-id' => 'Fattura Nro',
'order-id' => 'Ordine Nro',
'order-date' => 'Ordine Data',
'bill-to' => 'Fatturato a',
'ship-to' => 'Spedito a',
'contact' => 'Contatto',
'refunds' => 'Rimborsi',
'individual-refund' => 'Rimborso #:refund_id',
'adjustment-refund' => 'Rimborso',
'adjustment-fee' => 'Commissione di rimborso',
'cancel-btn-title' => 'Cancella',
]
],
'wishlist' => [
'page-title' => 'Preferiti',
'title' => 'Preferiti',
'deleteall' => 'Elimina tutti',
'moveall' => 'Aggiungi tutti i Prodotti al Carrello',
'move-to-cart' => 'Aggiungi al Carrello',
'error' => 'Non è possibile aggiungere il prodotto ai preferiti per un problema sconosciuto, provare nuovamente più tardi',
'add' => 'Il prodotto è stato aggiunto ai preferiti',
'remove' => 'Articolo rimosso dai preferiti',
'moved' => 'Articolo aggiunto al carrello',
'option-missing' => 'Le opzioni del prodotto mancano, per questo il prodotto non può essere aggiunto ai preferiti.',
'move-error' => 'Il prodotto non può essere aggiunto ai preferiti, prova nuovamente più tardi',
'success' => 'Il prodotto è stato aggiunto ai preferiti',
'failure' => 'Il prodotto non può essere aggiunto ai preferiti, prova nuovamente più tardi',
'already' => 'Il prodotto è già presente nei tuoi preferiti',
'removed' => 'Il prodotto è stato rimosso dai preferiti',
'remove-fail' => 'Il prodotto non può essere rimosso dai preferiti, prova nuovamente più tardi',
'empty' => 'Non hai ancora aggiunto prodotti ai tuoi preferiti',
'remove-all-success' => 'Tutti gli articoli sono stati rimossi dai tuoi preferiti',
],
'downloadable_products' => [
'title' => 'Prodotti scaricabili',
'order-id' => 'Id Ordine',
'date' => 'Data',
'name' => 'Titolo',
'status' => 'Status',
'pending' => 'In attesa',
'available' => 'Disponibile',
'expired' => 'Scaduto',
'remaining-downloads' => 'Download rimasti',
'unlimited' => 'Illimitati',
'download-error' => 'Il link per il Download è scaduto.'
],
'review' => [
'index' => [
'title' => 'Recensioni',
'page-title' => 'Recensioni'
],
'view' => [
'page-tile' => 'Recensione #:id',
]
]
]
],
'products' => [
'layered-nav-title' => 'Acquista per',
'price-label' => 'A partire da',
'remove-filter-link-title' => 'Rimuovi filtri',
'sort-by' => 'Ordina per',
'from-a-z' => 'Da A-Z',
'from-z-a' => 'Da Z-A',
'newest-first' => 'I più recenti prima',
'oldest-first' => 'I più datati prima',
'cheapest-first' => 'Prezzo più basso prima',
'expensive-first' => 'Prezzo più alto prima',
'show' => 'Mostra',
'pager-info' => 'Stai vedendo :showing di :total Items',
'description' => 'Descrizione',
'specification' => 'Specifiche',
'total-reviews' => ':total Recensioni',
'total-rating' => ':total_rating valutazioni e :total_reviews recensioni',
'by' => 'Per :name',
'up-sell-title' => 'Abbiamo trovato altri prodotti che potrebbero piacerti!',
'related-product-title' => 'Prodotti correlati',
'cross-sell-title' => 'Altre scelte',
'reviews-title' => 'Valutazioni e Recensioni',
'write-review-btn' => 'Scrivi una recensione',
'choose-option' => 'Scegli una opzione',
'sale' => 'Promo',
'new' => 'Nuovo',
'empty' => 'Nessun prodotto disponibile in questa categoria',
'add-to-cart' => 'Aggiungi al Carrello',
'buy-now' => 'Compra ora',
'whoops' => 'Whoops!',
'quantity' => 'Quantità',
'in-stock' => 'Disponibile',
'out-of-stock' => 'Esaurito',
'view-all' => 'Mostra Tutto',
'select-above-options' => 'Per favore seleziona prima le opzioni sopra.',
'less-quantity' => 'La quantità non può essere inferiore a uno.',
'samples' => 'Campioni',
'links' => 'Links',
'sample' => 'Campione',
'name' => 'Nome',
'qty' => 'Qtà',
'starting-at' => 'A partire da',
'customize-options' => 'Customizza opzioni',
'choose-selection' => 'Scegli una selezione',
'your-customization' => 'La tua Personalizzazione',
'total-amount' => 'Totale',
'none' => 'Nessuno',
'available' => 'Disponibile'
],
// 'reviews' => [
// 'empty' => 'Non hai ancora recensito alcun prodotto'
// ]
'buynow' => [
'no-options' => 'Per favore seleziona le opzioni per acquistare questo prodotto.'
],
'checkout' => [
'cart' => [
'integrity' => [
'missing_fields' => 'Mancano alcuni campi obbligatori per questo prodotto.',
'missing_options' => 'Mancano alcune Opzioni obbligatorie per questo prodotto.',
'missing_links' => 'I link per il download di questo prodotto sono mancanti.',
'qty_missing' => 'Almeno un prodotto dovrebbe avere una quantità superiore a 1.',
'qty_impossible' => 'Non è possibile aggiungere più di un pezzo di questo articolo nel carrello.'
],
'create-error' => 'Si è verificato un problema durante la visualizzazione del carrello.',
'title' => 'Carrello',
'empty' => 'Il tuo carrello è ancora vuoto',
'update-cart' => 'Aggiorna Carrello',
'continue-shopping' => 'Continua con i tuoi acquisti',
'proceed-to-checkout' => 'Procedi alla Cassa',
'remove' => 'Rimuovi',
'remove-link' => 'Rimuovi',
'move-to-wishlist' => 'Sposta nella Wishlist',
'move-to-wishlist-success' => 'Articolo spostato nella tua wishlist.',
'move-to-wishlist-error' => 'Non è possibile spostare l\'articolo nella tua wishlist, prova ancora.',
'add-config-warning' => 'Seleziona una opzione prima di aggiungere al carrello.',
'quantity' => [
'quantity' => 'Quantità',
'success' => 'Articoli nel carrello aggiornati con successo.',
'illegal' => 'La quantità non può essere inferiore a 0.',
'inventory_warning' => 'La quantità richiesta non è disponibile, prova ancora.',
'error' => 'Non è posibile aggiornare gli articoli al momento, prova ancora.'
],
'item' => [
'error_remove' => 'Nessun prodotto da rimuovere nel carrello.',
'success' => 'Prodotto aggiunto al carrello.',
'success-remove' => 'Prodotto rimosso dal carrello.',
'error-add' => 'Il prodotto non può essere aggiunto al carrello, prova ancora.',
],
'quantity-error' => 'La quantità richiesta non è disponibile.',
'cart-subtotal' => 'Subtotale Carrello',
'cart-remove-action' => 'Vuoi veramente farlo ?',
'partial-cart-update' => 'Solo alcuni dei prodotti sono stati aggiornati',
'link-missing' => '',
'event' => [
'expired' => 'Questo evento è terminato.'
]
],
'onepage' => [
'title' => 'Cassa',
'information' => 'Informazioni',
'shipping' => 'Spedizione',
'payment' => 'Pagamento',
'complete' => 'Completo',
'billing-address' => 'Indirizzo Fatturazione',
'sign-in' => 'Login',
'company-name' => 'Azienda',
'first-name' => 'Nome',
'last-name' => 'Cognome',
'email' => 'Email',
'address1' => 'Indirizzo',
'city' => 'Città',
'state' => 'Provincia',
'select-state' => 'Seleziona una provincia',
'postcode' => 'CAP',
'phone' => 'Telefono',
'country' => 'Paese',
'order-summary' => 'Riepilogo Ordine',
'shipping-address' => 'Indirizzo Spedizione',
'use_for_shipping' => 'Spedisci a questo indirizzo',
'continue' => 'Continua',
'shipping-method' => 'Seleziona Metodo di Spedizione',
'payment-methods' => 'Seleziona Metodo di Pagamento',
'payment-method' => 'Metodo di Pagamento',
'summary' => 'Riepilogo Ordine',
'price' => 'Prezzo',
'quantity' => 'Quantità',
'billing-address' => 'Indirizzo Fatturazione',
'shipping-address' => 'Indirizzo Spedizione',
'contact' => 'Contatto',
'place-order' => 'Procedi con Ordine',
'new-address' => 'Aggiungi Nuovo Indirizzo',
'save_as_address' => 'Salva questo indirizzo',
'apply-coupon' => 'Codice Promo',
'amt-payable' => 'Totale da Pagare',
'got' => 'Got',
'free' => 'Gratis',
'coupon-used' => 'Codice Utilizzato',
'applied' => 'Applicato',
'back' => 'Indietro',
'cash-desc' => 'Contrassegno',
'money-desc' => 'Bonifico',
'paypal-desc' => 'Paypal',
'free-desc' => 'Questa è una spedizine gratuita',
'flat-desc' => 'Questa è una spedizione a prezzo fisso',
'password' => 'Password',
'login-exist-message' => 'Sei già registrato nel nostro store, effettua la login o continua come ospite.',
'enter-coupon-code' => 'Inserisci Codice Promo'
],
'total' => [
'order-summary' => 'Riepilogo Ordine',
'sub-total' => 'Articoli',
'grand-total' => 'Totale',
'delivery-charges' => 'Spedizione',
'tax' => 'IVA',
'discount' => 'Sconto',
'price' => 'prezzo',
'disc-amount' => 'Totale Scontato',
'new-grand-total' => 'Nuovo Totale',
'coupon' => 'Codice Promo',
'coupon-applied' => 'Codice Promo Applicato',
'remove-coupon' => 'Rimuovi Codice Promo',
'cannot-apply-coupon' => 'Non è possibile Applicare il Codice Promo',
'invalid-coupon' => 'Il Codice Promo non è valido.',
'success-coupon' => 'Codice Promo applicato con successo.',
'coupon-apply-issue' => 'Il Codice Promo non può essere applicato.'
],
'success' => [
'title' => 'Ordine completato con successo',
'thanks' => 'Grazie per il tuo ordine!',
'order-id-info' => 'Il tuo id ordine è #:order_id',
'info' => 'Ti invieremo via email i dettagli del tuo ordine e le informazioni di tracking'
]
],
'mail' => [
'order' => [
'subject' => 'Nuova Conferma Ordine',
'heading' => 'Conferma Ordine!',
'dear' => ':customer_name',
'dear-admin' => ':admin_name',
'greeting' => 'Grazie per il tuo Oridne :order_id su :created_at',
'greeting-admin' => 'Id Ordine :order_id su :created_at',
'summary' => 'Riepilogo Ordine',
'shipping-address' => 'Indirizzo Spedizione',
'billing-address' => 'Indirizzo Fatturazione',
'contact' => 'Contatto',
'shipping' => 'Metodo di Spedizione',
'payment' => 'Metodo di Pagamento',
'price' => 'Prezzo',
'quantity' => 'Quantità',
'subtotal' => 'Subtotale',
'shipping-handling' => 'Spedizione',
'tax' => 'IVA',
'discount' => 'Sconto',
'grand-total' => 'Totale',
'final-summary' => 'Grazie per il tuo interesse nel nostro store, ti invieremo un codice di tracking una volta che la spedizione sarà completata',
'help' => 'Se hai bisogno di aiuto contattaci qui :support_email',
'thanks' => 'Grazie!',
'comment' => [
'subject' => 'Nuovo commento aggiunto al tuo ordine',
'dear' => ':customer_name',
'final-summary' => 'Grazie per aver mostrato interesse per il nostro store',
'help' => 'Se hai bisogno di aiuto contattaci all'indirizzo :support_email',
'thanks' => 'Graze!',
],
'cancel' => [
'subject' => 'Conferma Cancellazione Ordine',
'heading' => 'Ordine Cancellato',
'dear' => ':customer_name',
'greeting' => 'Il tuo Ordine #:order_id su :created_at è stato cancellato',
'summary' => 'Riepilogo Ordine',
'shipping-address' => 'Indirizzo di Spedizione',
'billing-address' => 'Indirizzo di Fattuazione',
'contact' => 'Contatti',
'shipping' => 'Metodo di Spedizione',
'payment' => 'Metodo di Pagamento',
'subtotal' => 'Subtotale',
'shipping-handling' => 'Spedizione',
'tax' => 'IVA',
'discount' => 'Sconto',
'grand-total' => 'Totale',
'final-summary' => 'Grazie per l\'interesse mostrato nel nostro store',
'help' => 'Se hai bisogno di qualsiasi tipo di aiuto contattaci a :support_email',
'thanks' => 'Grazie!',
]
],
'invoice' => [
'heading' => 'Fattura #:invoice_id per l\'Ordine #:order_id',
'subject' => 'Fattura per ordine #:order_id',
'summary' => 'Dettaglio Fattura',
],
'shipment' => [
'heading' => 'La Spedizione #:shipment_id relativa all\'Ordine #:order_id è stata generata ',
'inventory-heading' => 'Nuova Spedizione #:shipment_id relativa all\'Ordine #:order_id è stata generata',
'subject' => 'Spedizione per il tuo ordine #:order_id',
'inventory-subject' => 'Nuova spedizione generata per l\'Ordine #:order_id',
'summary' => 'Riepilogo Spedizione',
'carrier' => 'Corriere',
'tracking-number' => 'Codice Tracking',
'greeting' => 'Un ordine :order_id è stato piazzato su :created_at',
],
'refund' => [
'heading' => 'Il tuo rimborso #:refund_id per l\'Ordine #:order_id',
'subject' => 'Rimborso per il tuo ordine #:order_id',
'summary' => 'Riepilogo rimborso',
'adjustment-refund' => 'Rimborso accordato',
'adjustment-fee' => 'Commissione di rimborso'
],
'forget-password' => [
'subject' => 'Generazione Nuova Password',
'dear' => ':name',
'info' => 'Ricevi questa email perchè abbiamo ricevuto una richiesta di generazione di nuova password per il tuo account',
'reset-password' => 'Generazione nuova Password',
'final-summary' => 'Se non hai inviato tu questa richiesta, non è necessario effettuare alcuna operazione',
'thanks' => 'Grazie!'
],
'customer' => [
'new' => [
'dear' => 'Gentile :customer_name',
'username-email' => 'UserName/Email',
'subject' => 'Nuova registrazione cliente',
'password' => 'Password',
'summary' => 'Il tuo account è stato creato.
I dettagli del tuo account sono i seguenti: ',
'thanks' => 'Grazie!',
],
'registration' => [
'subject' => 'Nuova registrazione cliente',
'customer-registration' => 'Cliente registrato con successo',
'dear' => 'Gentile :customer_name',
'greeting' => 'Benvenuto e grazie per esserti registrato!',
'summary' => 'Il tuo account è stato creato e puoi ora effettuare la login utilizzando il tuo indirizzo email e la password che hai scelto. Una volta effettuato l\'accesso, potrai accedere ad altri servizi tra cui revisione ordini passati, gestione prodotti preferiti e modifica dei tuoi dati.',
'thanks' => 'Grazie!',
],
'verification' => [
'heading' => config('app.name') . ' - Email di Verifica',
'subject' => 'Email di verifica',
'verify' => 'Verifica il tuo Account',
'summary' => 'Questa email serve a verificare che l\'indirizzo email che hai inserito ti appartenga veramente.
Clicca il bottone Verifica il tuo Account qui sotto per verificare il tuo account.'
],
'subscription' => [
'subject' => 'Email Iscrizione',
'greeting' => ' Benvenuto ' . config('app.name') . ' - Email Iscrizione',
'unsubscribe' => 'Cancellati',
'summary' => 'Grazie per avere scelto di ricevere le nostre email. È passato un po\' di tempo da quando hai letto le email di ' . config('app.name') . '. Non è un nostro desidero inondare la tua casella email con le nostre comunicazioni. Se desideri comunque
non ricevere più le nostre news clicca il bottone qui sotto.'
]
]
],
'webkul' => [
'copy-right' => '© Copyright :year Webkul Software, Tutti i diritti riservati',
],
'response' => [
'create-success' => ':name creato con successoy.',
'update-success' => ':name aggiornato con successo.',
'delete-success' => ':name eliminato con successo.',
'submit-success' => ':name inviato con successo.'
],
];

View File

@ -21,11 +21,19 @@
@foreach ($cart->items as $key => $item)
@php
$productBaseImage = $item->product->getTypeInstance()->getBaseImage($item);
if (is_null ($item->product->url_key)) {
if (! is_null($item->product->parent)) {
$url_key = $item->product->parent->url_key;
}
} else {
$url_key = $item->product->url_key;
}
@endphp
<div class="item mt-5">
<div class="item-image" style="margin-right: 15px;">
<a href="{{ route('shop.productOrCategory.index', $item->product->url_key) }}"><img src="{{ $productBaseImage['medium_image_url'] }}" /></a>
<a href="{{ route('shop.productOrCategory.index', $url_key) }}"><img src="{{ $productBaseImage['medium_image_url'] }}" /></a>
</div>
<div class="item-details">
@ -33,7 +41,7 @@
{!! view_render_event('bagisto.shop.checkout.cart.item.name.before', ['item' => $item]) !!}
<div class="item-title">
<a href="{{ route('shop.productOrCategory.index', $item->product->url_key) }}">
<a href="{{ route('shop.productOrCategory.index', $url_key) }}">
{{ $item->product->name }}
</a>
</div>

View File

@ -13,16 +13,16 @@ class Tax
/**
* Returns an array with tax rates and tax amount
*
* @param \Webkul\Checkout\Contracts\Cart $cart
* @param bool $asBase
* @param object $that
* @param bool $asBase
*
* @return array
*/
public static function getTaxRatesWithAmount(\Webkul\Checkout\Contracts\Cart $cart, bool $asBase = false): array
public static function getTaxRatesWithAmount(object $that, bool $asBase = false): array
{
$taxes = [];
foreach ($cart->items as $item) {
foreach ($that->items as $item) {
$taxRate = (string) round((float) $item->tax_percent, self::TAX_RATE_PRECISION);
if (! array_key_exists($taxRate, $taxes)) {
@ -43,14 +43,14 @@ class Tax
/**
* Returns the total tax amount
*
* @param \Webkul\Checkout\Contracts\Cart $cart
* @param bool $asBase
* @param object $that
* @param bool $asBase
*
* @return float
*/
public static function getTaxTotal(\Webkul\Checkout\Contracts\Cart $cart, bool $asBase = false): float
public static function getTaxTotal(object $that, bool $asBase = false): float
{
$taxes = self::getTaxRatesWithAmount($cart, $asBase);
$taxes = self::getTaxRatesWithAmount($that, $asBase);
$result = 0;

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
{
"/js/ui.js": "/js/ui.js?id=f703bc98cad12f53c89d",
"/js/ui.js": "/js/ui.js?id=5c5ae91d95c2c0668124",
"/css/ui.css": "/css/ui.css?id=b87eb840235219138c2c"
}

View File

@ -0,0 +1,40 @@
<?php
return [
'datagrid' => [
'actions' => 'Azioni',
'id' => 'Le colonne indice hanno solo valore maggiore di zero',
'massaction' => [
'mass-delete-confirm' => 'Vuoi eliminare davvero :resource selezionati?',
'mass-update-status' => 'Vuoi aggiornare davvero lo stato dei :resource selezionati?',
'delete' => 'Vuoi davvero effettuare questa azione?',
'edit' => 'Vuoi davvero modificare questo :resource?',
],
'zero-index' => 'Le colonnne indice possono avere solo valori maggiori di zero',
'no-records' => 'Nessun risultato trovato',
'filter-fields-missing' => 'Alcuni dei campi obbligatori sono nulli, per favore verificare le colonne, le condizioni e i valori inseriti',
'click_on_action' => 'Vuoi davvero effettuare questa azione?',
'search' => 'Cerca qui...',
'filter' => 'Filtro',
'column' => 'Seleziona Colonna',
'condition' => 'Seleziona Condizione',
'contains' => 'Contiene',
'ncontains' => 'Non contiene',
'equals' => 'È uguale a',
'nequals' => 'Non è uguale a',
'greater' => 'Maggiore di',
'less' => 'Minore di',
'greatere' => 'Uguale o maggiore di',
'lesse' => 'Uguale o minore di',
'value' => 'Seleziona Valore',
'true' => 'Vero / Attivo',
'false' => 'Falso / Inattivo',
'between' => 'Compreso tra',
'apply' => 'Applica',
'items-per-page' => 'Risultati per pagina',
'value-here' => 'Valore qui',
'numeric-value-here' => 'Valore numerico qui',
'submit' => 'Invia'
]
];

View File

@ -0,0 +1,6 @@
<?php
return [
'enter-attribute' => 'Inserisci :attribute',
'select-attribute' => 'Seleziona :attribute'
];

View File

@ -0,0 +1,298 @@
<?php
return [
'admin' => [
'system' => [
'velocity' => [
'general' => 'Generale',
'category' => 'Categoria',
'settings' => 'Impostazioni',
'extension_name' => 'Velocity Theme',
'error-module-inactive' => 'Attenzione: lo stato del tema Velocity è insattivo',
],
'settings' => [
'channels'=> [
'subscription_bar' => 'Contenuto barra iscrizione'
],
],
'general' => [
'status' => 'Stato',
'active' => 'Attivo',
'inactive' => 'Inattivo',
],
'category' => [
'all' => 'Tutto',
'left' => 'Sinistra',
'right' => 'Destra',
'active' => 'Attivo',
'custom' => 'Custom',
'inactive' => 'Non Attivo',
'image-alignment' => 'Allineamento Immagine',
'icon-status' => 'Stato Icona Categoria',
'image-status' => 'Stato Immagine Categoria',
'sub-category-show' => 'Mostra Sub Categoria',
'image-height' => 'Altezza Immagine [in Pixel]',
'image-width' => 'Larghezza Immagine [in Pixel]',
'show-tooltip' => 'Mostra Tooltip Categoria',
'num-sub-category' => 'Numero della Sub Categoria',
]
],
'layouts' => [
'velocity' => 'Velocity',
'cms-pages' => 'Pagine CMS',
'meta-data' => 'Meta Data',
'category-menu' => 'Menu Categoria',
'header-content' => 'Contenuto Header',
],
'contents' => [
'self' => 'Self',
'active' => 'Attivo',
'new-tab' => 'Nuovo Tab',
'inactive' => 'Non Attivo',
'title' => 'Elenco Contenuti',
'select' => '-- Selezione --',
'add-title' => 'Aggiungi Contenuto',
'btn-add-content' => 'Aggiungi Contenuto',
'save-btn-title' => 'Salva Contenuto',
'autocomplete' => '[Autocompleta]',
'no-result-found' => 'Nessun record trovato.',
'search-hint' => 'Cerca prodotto qui...',
'mass-delete-success' => 'Contenuti selezionati eliminati con successo.',
'tab' => [
'page' => 'Impostazioni Pagina',
'content' => 'Impostazioni Contenuto',
'meta_content' => 'Meta Data',
],
'page' => [
'title' => 'Titolo',
'status' => 'Stato',
'position' => 'Posizione',
],
'content' => [
'content-type' => 'Tipo Contenuto',
'custom-title' => 'Titolo Custom',
'category-slug' => 'Slug Categoria',
'link-target' => 'Target Link a Pagina',
'custom-product' => 'Prodotti dello Store',
'custom-heading' => 'Custom Heading',
'catalog-type' => 'Tipo Catalogo Prodotti',
'static-description' => 'Descrizione Contenuto',
'page-link' => 'Link Pagina [es. http://example.com/../../]',
],
'datagrid' => [
'id' => 'Id',
'title' => 'Titolo',
'status' => 'Stato',
'position' => 'Posizione',
'content-type' => 'Tpo Contenuto',
'actions' => 'Azioni',
]
],
'meta-data' => [
'footer' => 'Footer',
'title' => 'Velocity meta data',
'activate-slider' => 'Attiva Slider',
'home-page-content' => 'Contenuti Home Page',
'footer-left-content' => 'Contenuti Footer Sinistra',
'subscription-content' => 'Conenuti Subscription bar',
'sidebar-categories' => 'Categorie Sidebar',
'footer-left-raw-content' => '<p>Ci piace personalizzare software e risolvere problemi del mondo reale. Siamo fortemente to our goals. We invest our resources to create world class easy to use softwares and applications for the enterprise business with the top notch, on the edge technology expertise.</p>',
'slider-path' => 'Percorso Slider',
'category-logo' => 'Logo Categoria',
'product-policy' => 'Policy Prodotto',
'featured-product' => 'Prodotti in evidenza',
'new-products' => 'Nuovi Prodotti',
'update-meta-data' => 'Aggiorna Meta Data',
'product-view-image' => 'Immagine Vista Prodotto',
'advertisement-two' => 'Advertisement Two Images',
'advertisement-one' => 'Advertisement One Images',
'footer-middle-content' => 'Contenuto Footer Centrale',
'advertisement-four' => 'Advertisement Four Images',
'advertisement-three' => 'Advertisement Three Images',
'images' => 'Immmagini',
'general' => 'Generale',
'add-image-btn-title' => 'Aggiungi Immagine'
],
'category' => [
'save-btn-title' => 'Salva Menu',
'title' => 'Elenco Menu Categorie',
'add-title' => 'Aggiungi Menu Contenuto',
'edit-title' => 'Modifica Menu Contenuto',
'btn-add-category' => 'Aggiungi Contenuto Categoria',
'datagrid' => [
'category-id' => 'Id Categoria',
'category-name' => 'Nome Categoria',
'category-icon' => 'Icona Categoria',
'category-status' => 'Stato',
],
'tab' => [
'general' => 'Generale',
],
'status' => 'Status',
'active' => 'Attivo',
'inactive' => 'Non Attivo',
'select' => '-- Seleziona --',
'icon-class' => 'Classe Icona',
'select-category' => 'Scegli Categoria',
'tooltip-content' => 'Contenuto Tooltip',
'mass-delete-success' => 'Categorie a menu eliminate con successo.',
],
'general' => [
'locale_logo' => 'Logo Lingua',
],
],
'home' => [
'view-all' => 'Mostra tutto',
'add-to-cart' => 'Aggiungi al Carrello',
'hot-categories' => 'Categorie Hot',
'payment-methods' => 'Metodi Pagamenti',
'customer-reviews' => 'Recensioni Clienti',
'shipping-methods' => 'Metodi di Spedizione',
'popular-categories' => 'Categorie Popolari',
],
'header' => [
'cart' => 'Carrello',
'cart' => 'Carrello',
'guest' => 'Guest',
'logout' => 'Logout',
'title' => 'Account',
'account' => 'Account',
'profile' => 'Profilo',
'wishlist' => 'Wishlist',
'all-categories' => 'Tutte le Categorie',
'search-text' => 'Cerca prodotti qui',
'welcome-message' => 'Benvenuto, :customer_name',
'dropdown-text' => 'Gestione Carrello, Ordini e Wishlist',
],
'menu-navbar' => [
'text-more' => 'More',
'text-category' => 'Acquista per Categoria',
],
'minicart' => [
'cart' => 'Carrello',
'view-cart' => 'Vai al Carrello',
],
'checkout' => [
'qty' => 'Qtà',
'checkout' => 'Cassa',
'cart' => [
'view-cart' => 'Vai al Carrello',
'cart-summary' => 'Sommario Carrello',
],
'qty' => 'Qtà',
'items' => 'Articoli',
'subtotal' => 'Subtotale',
'sub-total' => 'Sub Totale',
'proceed' => 'Procedi alla cassa',
],
'customer' => [
'compare' => [
'text' => 'Compara',
'compare_similar_items' => 'Compara articoli simili',
'added' => 'Articolo aggiunto alla lista di comparazione',
'already_added' => 'Articolo già aggiunto alla lista di comparazione',
'removed' => 'Articolo rimosso dalla lista di comparazione',
'empty-text' => "Non hai articoli nella tua lista di comparazione",
],
'login-form' => [
'sign-up' => 'Registrati',
'new-customer' => 'Nuovo Cliente',
'customer-login' => 'Login Cliente',
'registered-user' => 'Utente Registrato',
'your-email-address' => 'Il tuo indirizzo email',
'form-login-text' => 'Se hai un account, effettua login con la tua email.',
],
'signup-form' => [
'login' => 'Login',
'become-user' => 'Diventa Utente',
'user-registration' => 'Registrazione Utente',
'form-sginup-text' => 'Se sei nuovo nel nostro store, siamo lieti di averti come nuovo amico.',
],
'forget-password' => [
'login' => 'Login',
'forgot-password' => 'Password dimenticata',
'recover-password' => 'Recupera Password',
'recover-password-text' => 'Se hai dimenticato la password, recuperala inserendo il tuo indirizzo email.',
]
],
'error' => [
'go-to-home' => 'Vai alla home',
'page-lost-short' => 'Page lost content',
'something-went-wrong' => 'Qualcosa è andato storto',
'page-lost-description' => "La pagina che stavi cercando non è disponibile. Prova a cercare ancora o usa il tasto Torna Indietro qui sotto.",
],
'products' => [
'text' => 'Prodotti',
'details' => 'Dettagli',
'reviews-title' => 'Recensioni',
'reviewed' => 'Recensito',
'review-by' => 'Recensione di',
'quick-view' => 'Vista veloce',
'not-available' => 'Non Disponibile',
'submit-review' => 'Invia Recensione',
'ratings' => 'Valutazioni :totalRatings',
'reviews-count' => ':totalReviews Recensioni',
'customer-rating' => 'Valutazione Cliente',
'more-infomation' => 'Scopri di più',
'view-all-reviews' => 'Mostra tutte le Recensioni',
'write-your-review' => 'Scrivi la tua Recensione',
'short-description' => 'Descrizioni Brevi',
'recently-viewed' => 'Prodotti visti di recente',
'be-first-review' => 'Sii il primo a scrivere una review',
],
'shop' => [
'gender' => [
'male' => 'Maschio',
'other' => 'Altro',
'female' => 'Femmina',
],
'general' => [
'no' => 'No',
'yes' => 'Sì',
'view' => 'View',
'filter' => 'Filtro',
'orders' => 'Ordini',
'update' => 'Aggiorna',
'reviews' => 'Recensioni',
'addresses' => 'Indirizzi',
'top-brands' => 'Marchi top',
'new-password' => 'Nuova password',
'downloadables' => 'Prodotti Scaricabili',
'confirm-new-password' => 'Conferma nuova password',
'enter-current-password' => 'Inserisci la password attuale',
'alert' => [
'info' => 'Info',
'error' => 'Errore',
'success' => 'Successo',
'warning' => 'Attenzione',
],
],
'wishlist' => [
'add-wishlist-text' => 'Aggiungi prodotto a wishlist',
'remove-wishlist-text' => 'Rimuovi prodotti da wishlist'
]
],
'responsive' => [
'header' => [
'done' => 'Fatto',
'languages' => 'Lingue',
'greeting' => 'Benvenuto, :customer !',
]
],
]
?>

View File

@ -61,13 +61,21 @@
$productPrice = $product->getTypeInstance()->getProductPrices();
if (is_null ($product->url_key)) {
if (! is_null($product->parent)) {
$url_key = $product->parent->url_key;
}
} else {
$url_key = $product->url_key;
}
@endphp
<div class="row col-12" v-if="!isMobileDevice">
<a
title="{{ $product->name }}"
class="product-image-container col-2"
href="{{ route('shop.productOrCategory.index', $product->url_key) }}">
href="{{ route('shop.productOrCategory.index', $url_key) }}">
<img
class="card-img-top"
@ -79,7 +87,7 @@
<div class="product-details-content col-7 pr0">
<div class="row item-title no-margin">
<a
href="{{ route('shop.productOrCategory.index', $product->url_key) }}"
href="{{ route('shop.productOrCategory.index', $url_key) }}"
title="{{ $product->name }}"
class="unset col-12 no-padding">
@ -163,7 +171,7 @@
<a
title="{{ $product->name }}"
class="product-image-container col-2"
href="{{ route('shop.productOrCategory.index', $product->url_key) }}">
href="{{ route('shop.productOrCategory.index', $url_key) }}">
<img
src="{{ $productBaseImage['medium_image_url'] }}"
@ -173,7 +181,7 @@
<div class="col-10 pr0 item-title">
<a
href="{{ route('shop.productOrCategory.index', $product->url_key) }}"
href="{{ route('shop.productOrCategory.index', $url_key) }}"
title="{{ $product->name }}"
class="unset col-12 no-padding">

View File

@ -1,6 +1,6 @@
<?php
namespace Tests\Functional\Webkul\Admin;
namespace Tests\Functional\Admin\Catalog;
use FunctionalTester;
use Faker\Factory;

View File

@ -1,10 +1,12 @@
<?php
namespace Tests\Functional\CartRule;
use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Models\ProductFlat;
use FunctionalTester;
use Webkul\CartRule\Models\CartRule;
use Haendlerbund\SalesforceApi\Models\HbCartRule;
class CartRuleCest
{

View File

@ -1,6 +1,6 @@
<?php
namespace Tests\Functional\Checkout\Cart;
namespace Tests\Functional\Checkout\Order;
use Faker\Factory;
use FunctionalTester;

View File

@ -1,7 +1,10 @@
<?php
namespace Tests\Functional\Customer;
use Webkul\Customer\Models\Customer;
use Webkul\Customer\Models\CustomerAddress;
use FunctionalTester;
class CustomerCest
{
@ -34,7 +37,7 @@ class CustomerCest
public function updateCustomerAddress(FunctionalTester $I)
{
$I->wantTo('Instantiate a european faker factory to have the vat provider available');
$faker = Faker\Factory::create('at_AT');
$faker = \Faker\Factory::create('at_AT');
$formCssSelector = '#customer-address-form';

View File

@ -1,6 +1,6 @@
<?php
namespace Tests\Functional\Cart;
namespace Tests\Functional\Shop;
use FunctionalTester;
use Illuminate\Support\Facades\Config;

View File

@ -1,6 +1,6 @@
<?php
namespace Tests\Unit\Shop;
namespace Tests\Trigger\Shop;
use UnitTester;
use Webkul\Category\Models\Category;
@ -17,7 +17,7 @@ class DatabaseLogicCest
private $localeEn;
/** @var Locale $localeDe */
private $localeDe;
public function _before(UnitTester $I)
{
$this->faker = Factory::create();
@ -45,7 +45,7 @@ class DatabaseLogicCest
]);
$parentCategoryName = $this->faker->word;
$parentCategoryAttributes = [
'parent_id' => $rootCategory->id,
'position' => 1,
@ -68,7 +68,7 @@ class DatabaseLogicCest
$rootCategory->prependNode($parentCategory);
$I->assertNotNull($parentCategory);
$categoryName = $this->faker->word;
$categoryName = $this->faker->word;
$categoryAttributes = [
'position' => 1,
'status' => 1,

View File

@ -1,6 +1,6 @@
<?php
namespace Tests\Unit\Shop;
namespace Tests\Trigger\Shop;
use Faker\Factory;
use UnitTester;

View File

@ -1,6 +1,6 @@
<?php
namespace Tests\Unit\Category;
namespace Tests\Unit\CartRule;
use UnitTester;
use Codeception\Example;
@ -36,7 +36,7 @@ class cartRuleWithCoupon
class expectedCartItem
{
public const ITEM_DISCOUNT_AMOUNT_PRECISION = 2;
public const ITEM_DISCOUNT_AMOUNT_PRECISION = 4;
public const ITEM_TAX_AMOUNT_PRECISION = 4;
public $cart_id;
@ -138,11 +138,15 @@ class expectedCart
{
$this->sub_total = round($this->sub_total, self::CART_TOTAL_PRECISION);
$this->tax_total = round($this->tax_total, self::CART_TOTAL_PRECISION);
$this->grand_total = round($this->sub_total + $this->tax_total - $this->discount_amount, self::CART_TOTAL_PRECISION);
$this->discount_amount = round($this->discount_amount, self::CART_TOTAL_PRECISION);
$this->grand_total = round($this->sub_total + $this->tax_total - $this->discount_amount,
self::CART_TOTAL_PRECISION);
$this->base_sub_total = round($this->base_sub_total, self::CART_TOTAL_PRECISION);
$this->base_tax_total = round($this->base_tax_total, self::CART_TOTAL_PRECISION);
$this->base_grand_total = round($this->base_sub_total + $this->base_tax_total - $this->base_discount_amount, self::CART_TOTAL_PRECISION);
$this->base_discount_amount = round($this->base_discount_amount, self::CART_TOTAL_PRECISION);
$this->base_grand_total = round($this->base_sub_total + $this->base_tax_total - $this->base_discount_amount,
self::CART_TOTAL_PRECISION);
}
public function toArray(): array
@ -579,6 +583,102 @@ class CartRuleCest
}
}
public function checkExampleCase(UnitTester $I)
{
config(['app.default_country' => 'DE']);
$faker = Factory::create();
$customer = $I->have(Customer::class);
auth()->guard('customer')->loginUsingId($customer->id);
Event::dispatch('customer.after.login', $customer['email']);
$this->sessionToken = $faker->uuid;
session(['_token' => $this->sessionToken]);
$tax = $I->have(TaxRate::class, [
'country' => 'DE',
'tax_rate' => 19.0,
]);
$taxCategorie = $I->have(TaxCategory::class);
$I->have(TaxMap::class, [
'tax_rate_id' => $tax->id,
'tax_category_id' => $taxCategorie->id,
]);
$productConfig = [
'attributeValues' => [
'price' => 23.92,
'tax_category_id' => $taxCategorie->id,
],
];
$product = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT, $productConfig);
$ruleConfig = [
'action_type' => self::ACTION_TYPE_PERCENTAGE,
'discount_amount' => 100,
'conditions' => [
[
'attribute' => 'product|sku',
'value' => $product->sku,
'operator' => '==',
'attribute_type' => 'text',
],
],
];
$cartRule = $I->have(CartRule::class, $ruleConfig);
DB::table('cart_rule_channels')->insert([
'cart_rule_id' => $cartRule->id,
'channel_id' => core()->getCurrentChannel()->id,
]);
$guestCustomerGroup = $I->grabRecord('customer_groups', ['code' => 'guest']);
DB::table('cart_rule_customer_groups')->insert([
'cart_rule_id' => $cartRule->id,
'customer_group_id' => $guestCustomerGroup['id'],
]);
$generalCustomerGroup = $I->grabRecord('customer_groups', ['code' => 'general']);
DB::table('cart_rule_customer_groups')->insert([
'cart_rule_id' => $cartRule->id,
'customer_group_id' => $generalCustomerGroup['id'],
]);
$coupon = $I->have(CartRuleCoupon::class, [
'code' => 'AWESOME',
'cart_rule_id' => $cartRule->id,
]);
$data = [
'_token' => session('_token'),
'product_id' => $product->id,
'quantity' => 1,
];
cart()->addProduct($product->id, $data);
cart()->setCouponCode('AWESOME')->collectTotals();
$cart = cart()->getCart();
$cartItem = $cart->items()->first();
$I->assertEquals('AWESOME', $cartItem['coupon_code']);
$I->assertEquals(23.92, $cartItem['price']);
$I->assertEquals(19.0, $cartItem['tax_percent']);
$I->assertEquals(4.5448, $cartItem['tax_amount']);
$I->assertEquals(28.4648, $cartItem['discount_amount']);
$I->assertEquals('AWESOME', $cart->coupon_code);
$I->assertEquals(23.92, $cart->sub_total);
$I->assertEquals(4.54, $cart->tax_total);
$I->assertEquals(28.46, $cart->discount_amount);
// 23.92 + 4.54 - 28.46 = 0.00
$I->assertEquals(0.00, $cart->grand_total);
}
/**
* @param \Codeception\Example $scenario
* @param \Tests\Unit\Category\cartRuleWithCoupon $cartRuleWithCoupon
@ -586,19 +686,15 @@ class CartRuleCest
*
* @return array
*/
private function getExpectedCartItems(
Example $scenario,
?cartRuleWithCoupon $cartRuleWithCoupon,
int $cartID
): array {
private function getExpectedCartItems(Example $scenario, ?cartRuleWithCoupon $cartRuleWithCoupon, int $cartID): array
{
$cartItems = [];
foreach ($scenario['productSequence'] as $key => $item) {
$pos = $this->array_find(
'product_id',
$this->products[$scenario['productSequence'][$key]]->id,
$cartItems,
true
$cartItems
);
if ($pos === null) {
@ -793,11 +889,8 @@ class CartRuleCest
*
* @return \Tests\Unit\Category\expectedCart
*/
private function getExpectedCart(
int $cartId,
array $expectedCartItems,
?cartRuleWithCoupon $cartRuleWithCoupon
): expectedCart {
private function getExpectedCart(int $cartId, array $expectedCartItems, ?cartRuleWithCoupon $cartRuleWithCoupon): expectedCart
{
$cart = new expectedCart(
$cartId,
auth()->guard('customer')->user()->id

View File

@ -17,7 +17,6 @@ class TaxCest
private const PRODUCT2_QTY = 7;
private const CART_TOTAL_PRECISION = 2;
private const TAX_AMOUNT_PRECISION = 2;
public function _before(UnitTester $I)
{
@ -73,16 +72,17 @@ class TaxCest
'quantity' => self::PRODUCT2_QTY,
]);
// rounded by precision of 2 because this are sums of corresponding tax categories
$expectedTaxAmount1 = round(
round(self::PRODUCT1_QTY * $product1->price, self::CART_TOTAL_PRECISION)
* $tax1->tax_rate / 100,
self::TAX_AMOUNT_PRECISION
self::CART_TOTAL_PRECISION
);
$expectedTaxAmount2 = round(
round(self::PRODUCT2_QTY * $product2->price, self::CART_TOTAL_PRECISION)
* $tax2->tax_rate / 100,
self::TAX_AMOUNT_PRECISION
self::CART_TOTAL_PRECISION
);
$this->scenario = [
@ -92,7 +92,7 @@ class TaxCest
(string)round((float)$tax2->tax_rate, 4) => $expectedTaxAmount2,
],
'expectedTaxTotal' =>
round($expectedTaxAmount1 + $expectedTaxAmount2, self::TAX_AMOUNT_PRECISION),
round($expectedTaxAmount1 + $expectedTaxAmount2, self::CART_TOTAL_PRECISION),
];
}