Resolved conflicts

This commit is contained in:
Pranshu Tomar 2020-05-08 21:50:06 +05:30
commit 527affe741
101 changed files with 3212 additions and 543 deletions

59
composer.lock generated
View File

@ -4096,16 +4096,16 @@
},
{
"name": "symfony/http-foundation",
"version": "v4.4.5",
"version": "v4.4.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "7e41b4fcad4619535f45f8bfa7744c4f384e1648"
"reference": "62f92509c9abfd1f73e17b8cf1b72c0bdac6611b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/7e41b4fcad4619535f45f8bfa7744c4f384e1648",
"reference": "7e41b4fcad4619535f45f8bfa7744c4f384e1648",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/62f92509c9abfd1f73e17b8cf1b72c0bdac6611b",
"reference": "62f92509c9abfd1f73e17b8cf1b72c0bdac6611b",
"shasum": ""
},
"require": {
@ -4147,7 +4147,7 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
"time": "2020-02-13T19:40:01+00:00"
"time": "2020-03-30T14:07:33+00:00"
},
{
"name": "symfony/http-kernel",
@ -4241,16 +4241,16 @@
},
{
"name": "symfony/mime",
"version": "v5.0.5",
"version": "v5.0.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/mime.git",
"reference": "9b3e5b5e58c56bbd76628c952d2b78556d305f3c"
"reference": "481b7d6da88922fb1e0d86a943987722b08f3955"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/mime/zipball/9b3e5b5e58c56bbd76628c952d2b78556d305f3c",
"reference": "9b3e5b5e58c56bbd76628c952d2b78556d305f3c",
"url": "https://api.github.com/repos/symfony/mime/zipball/481b7d6da88922fb1e0d86a943987722b08f3955",
"reference": "481b7d6da88922fb1e0d86a943987722b08f3955",
"shasum": ""
},
"require": {
@ -4299,7 +4299,7 @@
"mime",
"mime-type"
],
"time": "2020-02-04T09:41:09+00:00"
"time": "2020-03-27T16:56:45+00:00"
},
{
"name": "symfony/polyfill-ctype",
@ -4420,16 +4420,16 @@
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.14.0",
"version": "v1.15.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "6842f1a39cf7d580655688069a03dd7cd83d244a"
"reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/6842f1a39cf7d580655688069a03dd7cd83d244a",
"reference": "6842f1a39cf7d580655688069a03dd7cd83d244a",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf",
"reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf",
"shasum": ""
},
"require": {
@ -4443,7 +4443,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.14-dev"
"dev-master": "1.15-dev"
}
},
"autoload": {
@ -4478,20 +4478,20 @@
"portable",
"shim"
],
"time": "2020-01-17T12:01:36+00:00"
"time": "2020-03-09T19:04:49+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.14.0",
"version": "v1.15.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "34094cfa9abe1f0f14f48f490772db7a775559f2"
"reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/34094cfa9abe1f0f14f48f490772db7a775559f2",
"reference": "34094cfa9abe1f0f14f48f490772db7a775559f2",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
"reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
"shasum": ""
},
"require": {
@ -4503,7 +4503,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.14-dev"
"dev-master": "1.15-dev"
}
},
"autoload": {
@ -4537,7 +4537,7 @@
"portable",
"shim"
],
"time": "2020-01-13T11:15:53+00:00"
"time": "2020-03-09T19:04:49+00:00"
},
{
"name": "symfony/polyfill-php56",
@ -4597,16 +4597,16 @@
},
{
"name": "symfony/polyfill-php72",
"version": "v1.14.0",
"version": "v1.15.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "46ecacf4751dd0dc81e4f6bf01dbf9da1dc1dadf"
"reference": "37b0976c78b94856543260ce09b460a7bc852747"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/46ecacf4751dd0dc81e4f6bf01dbf9da1dc1dadf",
"reference": "46ecacf4751dd0dc81e4f6bf01dbf9da1dc1dadf",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/37b0976c78b94856543260ce09b460a7bc852747",
"reference": "37b0976c78b94856543260ce09b460a7bc852747",
"shasum": ""
},
"require": {
@ -4615,7 +4615,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.14-dev"
"dev-master": "1.15-dev"
}
},
"autoload": {
@ -4648,7 +4648,7 @@
"portable",
"shim"
],
"time": "2020-01-13T11:15:53+00:00"
"time": "2020-02-27T09:26:54+00:00"
},
{
"name": "symfony/polyfill-php73",
@ -7770,6 +7770,5 @@
"ext-pdo_mysql": "*",
"ext-tokenizer": "*"
},
"platform-dev": [],
"plugin-api-version": "1.1.0"
"platform-dev": []
}

View File

@ -14,6 +14,8 @@ use Webkul\Checkout\Http\Requests\CustomerAddressForm;
use Webkul\Sales\Repositories\OrderRepository;
use Illuminate\Support\Str;
use Cart;
use Exception;
use Webkul\Shop\Http\Controllers\OnepageController;
class CheckoutController extends Controller
{
@ -197,26 +199,10 @@ class CheckoutController extends Controller
/**
* Validate order before creation
*
* @return mixed
* @throws Exception
*/
public function validateOrder()
public function validateOrder(): void
{
$cart = Cart::getCart();
if (! $cart->shipping_address) {
throw new \Exception(trans('Please check shipping address.'));
}
if (! $cart->billing_address) {
throw new \Exception(trans('Please check billing address.'));
}
if (! $cart->selected_shipping_rate) {
throw new \Exception(trans('Please specify shipping method.'));
}
if (! $cart->payment) {
throw new \Exception(trans('Please specify payment method.'));
}
app(OnepageController::class)->validateOrder();
}
}

View File

@ -99,6 +99,12 @@ return [
'type' => 'image',
'channel_based' => true,
'validation' => 'mimes:jpeg,bmp,png,jpg',
], [
'name' => 'favicon',
'title' => 'admin::app.admin.system.favicon',
'type' => 'image',
'channel_based' => true,
'validation' => 'mimes:jpeg,bmp,png,jpg',
],
],
], [

View File

@ -3,6 +3,7 @@
namespace Webkul\Admin\DataGrids;
use Illuminate\Support\Facades\DB;
use Webkul\Customer\Models\CustomerAddress;
use Webkul\Ui\DataGrid\DataGrid;
use Webkul\Customer\Repositories\CustomerRepository;
@ -43,10 +44,11 @@ class AddressDataGrid extends DataGrid
{
$customer = $this->customerRepository->find(request('id'));
$queryBuilder = DB::table('customer_addresses as ca')
$queryBuilder = DB::table('addresses as ca')
->leftJoin('countries', 'ca.country', '=', 'countries.code')
->leftJoin('customers as c', 'ca.customer_id', '=', 'c.id')
->addSelect('ca.id as address_id', 'ca.company_name', 'ca.address1', 'ca.country', DB::raw('' . DB::getTablePrefix() . 'countries.name as country_name'), 'ca.state', 'ca.city', 'ca.postcode', 'ca.phone', 'ca.default_address')
->where('ca.address_type', CustomerAddress::ADDRESS_TYPE)
->where('c.id', $customer->id);
$queryBuilder = $queryBuilder->leftJoin('country_states', function($qb) {

View File

@ -11,18 +11,51 @@ class CartRuleDataGrid extends DataGrid
protected $sortOrder = 'desc';
protected $customer_group = 'all';
protected $channel = 'all';
public function __construct()
{
parent::__construct();
$this->customer_group = request()->get('customer_group') ?? 'all';
$this->channel = request()->get('channel') ?? 'all';
}
public function prepareQueryBuilder()
{
$queryBuilder = DB::table('cart_rules')
->leftJoin('cart_rule_coupons', function($leftJoin) {
->leftJoin('cart_rule_coupons', function ($leftJoin) {
$leftJoin->on('cart_rule_coupons.cart_rule_id', '=', 'cart_rules.id')
->where('cart_rule_coupons.is_primary', 1);
->where('cart_rule_coupons.is_primary', 1);
})
->addSelect('cart_rules.id', 'name', 'cart_rule_coupons.code as coupon_code', 'status', 'starts_from', 'ends_till', 'sort_order');
->addSelect('cart_rules.id', 'name', 'cart_rule_coupons.code as coupon_code',
'status', 'starts_from', 'ends_till', 'sort_order');
$this->addFilter('id', 'cart_rules.id');
$this->addFilter('coupon_code', 'cart_rule_coupons.code');
if ($this->customer_group !== 'all') {
$queryBuilder->leftJoin(
'cart_rule_customer_groups',
'cart_rule_customer_groups.cart_rule_id',
'=',
'cart_rules.id'
);
$queryBuilder->where('cart_rule_customer_groups.customer_group_id', $this->customer_group);
}
if ($this->channel !== 'all') {
$queryBuilder->leftJoin(
'cart_rule_channels',
'cart_rule_channels.cart_rule_id',
'=',
'cart_rules.id');
$queryBuilder->where('cart_rule_channels.channel_id', $this->channel);
}
$this->setQueryBuilder($queryBuilder);
}
@ -80,7 +113,7 @@ class CartRuleDataGrid extends DataGrid
'searchable' => true,
'sortable' => true,
'filterable' => true,
'wrapper' => function($value) {
'wrapper' => function ($value) {
if ($value->status == 1) {
return trans('admin::app.datagrid.active');
} else {

View File

@ -3,6 +3,7 @@
namespace Webkul\Admin\DataGrids;
use Illuminate\Support\Facades\DB;
use Webkul\Sales\Models\OrderAddress;
use Webkul\Ui\DataGrid\DataGrid;
class OrderDataGrid extends DataGrid
@ -14,13 +15,13 @@ class OrderDataGrid extends DataGrid
public function prepareQueryBuilder()
{
$queryBuilder = DB::table('orders')
->leftJoin('order_address as order_address_shipping', function($leftJoin) {
->leftJoin('addresses as order_address_shipping', function($leftJoin) {
$leftJoin->on('order_address_shipping.order_id', '=', 'orders.id')
->where('order_address_shipping.address_type', 'shipping');
->where('order_address_shipping.address_type', OrderAddress::ADDRESS_TYPE_SHIPPING);
})
->leftJoin('order_address as order_address_billing', function($leftJoin) {
->leftJoin('addresses as order_address_billing', function($leftJoin) {
$leftJoin->on('order_address_billing.order_id', '=', 'orders.id')
->where('order_address_billing.address_type', 'billing');
->where('order_address_billing.address_type', OrderAddress::ADDRESS_TYPE_BILLING);
})
->addSelect('orders.id','orders.increment_id', 'orders.base_sub_total', 'orders.base_grand_total', 'orders.created_at', 'channel_name', 'status')
->addSelect(DB::raw('CONCAT(' . DB::getTablePrefix() . 'order_address_billing.first_name, " ", ' . DB::getTablePrefix() . 'order_address_billing.last_name) as billed_to'))

View File

@ -3,6 +3,7 @@
namespace Webkul\Admin\DataGrids;
use Illuminate\Support\Facades\DB;
use Webkul\Sales\Models\OrderAddress;
use Webkul\Ui\DataGrid\DataGrid;
class OrderRefundDataGrid extends DataGrid
@ -16,9 +17,9 @@ class OrderRefundDataGrid extends DataGrid
$queryBuilder = DB::table('refunds')
->select('refunds.id', 'orders.increment_id', 'refunds.state', 'refunds.base_grand_total', 'refunds.created_at')
->leftJoin('orders', 'refunds.order_id', '=', 'orders.id')
->leftJoin('order_address as order_address_billing', function($leftJoin) {
->leftJoin('addresses as order_address_billing', function($leftJoin) {
$leftJoin->on('order_address_billing.order_id', '=', 'orders.id')
->where('order_address_billing.address_type', 'billing');
->where('order_address_billing.address_type', OrderAddress::ADDRESS_TYPE_BILLING);
})
->addSelect(DB::raw('CONCAT(' . DB::getTablePrefix() . 'order_address_billing.first_name, " ", ' . DB::getTablePrefix() . 'order_address_billing.last_name) as billed_to'));

View File

@ -3,6 +3,7 @@
namespace Webkul\Admin\DataGrids;
use Illuminate\Support\Facades\DB;
use Webkul\Sales\Models\OrderAddress;
use Webkul\Ui\DataGrid\DataGrid;
class OrderShipmentsDataGrid extends DataGrid
@ -14,9 +15,9 @@ class OrderShipmentsDataGrid extends DataGrid
public function prepareQueryBuilder()
{
$queryBuilder = DB::table('shipments')
->leftJoin('order_address as order_address_shipping', function($leftJoin) {
->leftJoin('addresses as order_address_shipping', function($leftJoin) {
$leftJoin->on('order_address_shipping.order_id', '=', 'shipments.order_id')
->where('order_address_shipping.address_type', 'shipping');
->where('order_address_shipping.address_type', OrderAddress::ADDRESS_TYPE_SHIPPING);
})
->leftJoin('orders as ors', 'shipments.order_id', '=', 'ors.id')
->leftJoin('inventory_sources as is', 'shipments.inventory_source_id', '=', 'is.id')

View File

@ -22,7 +22,7 @@ class ProductDataGrid extends DataGrid
parent::__construct();
$this->locale = request()->get('locale') ?? 'all';
$this->channel = request()->get('channel') ?? 'all';
}
@ -119,7 +119,7 @@ class ProductDataGrid extends DataGrid
'sortable' => true,
'searchable' => false,
'filterable' => true,
'wrapper' => function($value) {
'wrapper' => function ($value) {
if ($value->status == 1) {
return trans('admin::app.datagrid.active');
} else {
@ -144,7 +144,7 @@ class ProductDataGrid extends DataGrid
'sortable' => true,
'searchable' => false,
'filterable' => false,
'wrapper' => function($value) {
'wrapper' => function ($value) {
if (is_null($value->quantity)) {
return 0;
} else {
@ -161,7 +161,7 @@ class ProductDataGrid extends DataGrid
'method' => 'GET',
'route' => 'admin.catalog.products.edit',
'icon' => 'icon pencil-lg-icon',
'condition' => function() {
'condition' => function () {
return true;
},
]);

View File

@ -2,6 +2,7 @@
namespace Webkul\Admin\Http\Controllers\Customer;
use Illuminate\Support\Facades\Event;
use Webkul\Admin\Http\Controllers\Controller;
use Webkul\Customer\Repositories\CustomerRepository;
use Webkul\Customer\Repositories\CustomerGroupRepository;
@ -111,8 +112,12 @@ class CustomerController extends Controller
$data['is_verified'] = 1;
Event::dispatch('customer.registration.before');
$customer = $this->customerRepository->create($data);
Event::dispatch('customer.registration.after', $customer);
try {
$configKey = 'emails.general.notifications.emails.general.notifications.customer';
if (core()->getConfigData($configKey)) {
@ -164,7 +169,11 @@ class CustomerController extends Controller
$data['status'] = ! isset($data['status']) ? 0 : 1;
$this->customerRepository->update($data, $id);
Event::dispatch('customer.update.before');
$customer = $this->customerRepository->update($data, $id);
Event::dispatch('customer.update.after', $customer);
session()->flash('success', trans('admin::app.response.update-success', ['name' => 'Customer']));

View File

@ -1323,6 +1323,7 @@ return [
'cheapest-first' => 'Cheapest First',
'expensive-first' => 'Expensive First',
'comma-seperated' => 'Comma Seperated',
'favicon' => 'Favicon'
]
]
];

View File

@ -1313,8 +1313,9 @@ return [
'order-number-suffix' => 'Order Number Suffix',
'default' => 'Default',
'sandbox' => 'Sandbox',
'all-channels' => 'All',
'all-locales' => 'All',
'all-channels' => 'All Channels',
'all-locales' => 'All Locales',
'all-customer-groups' => 'All Customer groups',
'invoice-slip-design' => 'Invoice Slip Design',
'logo' => 'Logo',
'storefront' => 'Storefront',
@ -1330,6 +1331,7 @@ return [
'cheapest-first' => 'Cheapest First',
'expensive-first' => 'Expensive First',
'comma-seperated' => 'Comma Seperated',
'favicon' => 'Favicon'
]
]
];

View File

@ -1329,6 +1329,7 @@ return [
'cheapest-first' => 'Cheapest First',
'expensive-first' => 'Expensive First',
'comma-seperated' => 'Comma Seperated',
'favicon' => 'Favicon'
]
]
];

View File

@ -1328,6 +1328,7 @@ return [
'cheapest-first' => 'Cheapest First',
'expensive-first' => 'Expensive First',
'comma-seperated' => 'Comma Seperated',
'favicon' => 'Favicon'
]
]
];

View File

@ -1248,14 +1248,14 @@ return [
'system' => [
'catalog' => 'Catálogo',
'products' => 'Produtos',
'guest-checkout' => 'Saída do hóspede',
'allow-guest-checkout' => 'Permitir saída do hóspede',
'guest-checkout' => 'Compras sem cadastro?',
'allow-guest-checkout' => 'Permitir compra para clientes sem cadastros?',
'allow-guest-checkout-hint' => 'Dica: se ativada, esta opção pode ser configurada para cada produto especificamente.',
'review' => 'Reveja',
'allow-guest-review' => 'Permitir comentário de convidado',
'review' => 'Avaliações',
'allow-guest-review' => 'Permitir comentários sem cadastro?',
'inventory' => 'Inventário',
'stock-options' => 'Opções de ações',
'allow-backorders' => 'Permitir Pedidos por Admin',
'allow-backorders' => 'Permitir Pedidos pelo Admin',
'customer' => 'Cliente',
'settings' => 'Definições',
'address' => 'Endereço',
@ -1332,6 +1332,7 @@ return [
'cheapest-first' => 'Cheapest First',
'expensive-first' => 'Expensive First',
'comma-seperated' => 'Comma Seperated',
'favicon' => 'Favicon'
]
]
];

View File

@ -13,7 +13,7 @@
<div class="page-action">
<a href="{{ route('admin.catalog.attributes.create') }}" class="btn btn-lg btn-primary">
{{ __('Add Attribute') }}
{{ __('admin::app.catalog.attributes.add-title') }}
</a>
</div>
</div>
@ -28,4 +28,4 @@
{!! view_render_event('bagisto.admin.catalog.attributes.list.after') !!}
</div>
@stop
@stop

View File

@ -19,7 +19,6 @@
</option>
@foreach (core()->getAllChannels() as $channelModel)
<option
value="{{ $channelModel->code }}" {{ (isset($channel) && ($channelModel->code) == $channel) ? 'selected' : '' }}>
{{ $channelModel->name }}
@ -90,6 +89,6 @@
window.location.href = url.href;
}
</script>
@endpush

View File

@ -31,24 +31,32 @@
<div class="form-container">
@csrf()
{!! view_render_event('bagisto.admin.customers.create.before') !!}
<div class="control-group" :class="[errors.has('first_name') ? 'has-error' : '']">
<label for="first_name" class="required">{{ __('admin::app.customers.customers.first_name') }}</label>
<input type="text" class="control" name="first_name" v-validate="'required'" value="{{ old('first_name') }}" data-vv-as="&quot;{{ __('shop::app.customer.signup-form.firstname') }}&quot;">
<span class="control-error" v-if="errors.has('first_name')">@{{ errors.first('first_name') }}</span>
</div>
{!! view_render_event('bagisto.admin.customers.create.first_name.after') !!}
<div class="control-group" :class="[errors.has('last_name') ? 'has-error' : '']">
<label for="last_name" class="required">{{ __('admin::app.customers.customers.last_name') }}</label>
<input type="text" class="control" name="last_name" v-validate="'required'" value="{{ old('last_name') }}" data-vv-as="&quot;{{ __('shop::app.customer.signup-form.lastname') }}&quot;">
<span class="control-error" v-if="errors.has('last_name')">@{{ errors.first('last_name') }}</span>
</div>
{!! view_render_event('bagisto.admin.customers.create.last_name.after') !!}
<div class="control-group" :class="[errors.has('email') ? 'has-error' : '']">
<label for="email" class="required">{{ __('shop::app.customer.signup-form.email') }}</label>
<input type="email" class="control" name="email" v-validate="'required|email'" value="{{ old('email') }}" data-vv-as="&quot;{{ __('shop::app.customer.signup-form.email') }}&quot;">
<span class="control-error" v-if="errors.has('email')">@{{ errors.first('email') }}</span>
</div>
{!! view_render_event('bagisto.admin.customers.create.email.after') !!}
<div class="control-group" :class="[errors.has('gender') ? 'has-error' : '']">
<label for="gender" class="required">{{ __('admin::app.customers.customers.gender') }}</label>
<select name="gender" class="control" v-validate="'required'" data-vv-as="&quot;{{ __('admin::app.customers.customers.gender') }}&quot;">
@ -60,18 +68,24 @@
<span class="control-error" v-if="errors.has('gender')">@{{ errors.first('gender') }}</span>
</div>
{!! view_render_event('bagisto.admin.customers.create.gender.after') !!}
<div class="control-group" :class="[errors.has('date_of_birth') ? 'has-error' : '']">
<label for="dob">{{ __('admin::app.customers.customers.date_of_birth') }}</label>
<input type="date" class="control" name="date_of_birth" v-validate="" value="{{ old('date_of_birth') }}" data-vv-as="&quot;{{ __('admin::app.customers.customers.date_of_birth') }}&quot;">
<span class="control-error" v-if="errors.has('date_of_birth')">@{{ errors.first('date_of_birth') }}</span>
</div>
{!! view_render_event('bagisto.admin.customers.create.date_of_birth.after') !!}
<div class="control-group" :class="[errors.has('phone') ? 'has-error' : '']">
<label for="phone">{{ __('admin::app.customers.customers.phone') }}</label>
<input type="text" class="control" name="phone" value="{{ old('phone') }}" data-vv-as="&quot;{{ __('admin::app.customers.customers.phone') }}&quot;">
<span class="control-error" v-if="errors.has('phone')">@{{ errors.first('phone') }}</span>
</div>
{!! view_render_event('bagisto.admin.customers.create.phone.after') !!}
<div class="control-group">
<label for="customerGroup" >{{ __('admin::app.customers.customers.customer_group') }}</label>
<select class="control" name="customer_group_id">
@ -80,6 +94,8 @@
@endforeach
</select>
</div>
{!! view_render_event('bagisto.admin.customers.create.after') !!}
</div>
</div>
</form>

View File

@ -36,6 +36,8 @@
<accordian :title="'{{ __('admin::app.account.general') }}'" :active="true">
<div slot="body">
{!! view_render_event('bagisto.admin.customer.edit.form.before', ['customer' => $customer]) !!}
<div class="control-group" :class="[errors.has('first_name') ? 'has-error' : '']">
<label for="first_name" class="required"> {{ __('admin::app.customers.customers.first_name') }}</label>
<input type="text" class="control" name="first_name" v-validate="'required'" value="{{old('first_name') ?:$customer->first_name}}"
@ -43,18 +45,24 @@
<span class="control-error" v-if="errors.has('first_name')">@{{ errors.first('first_name') }}</span>
</div>
{!! view_render_event('bagisto.admin.customer.edit.first_name.after', ['customer' => $customer]) !!}
<div class="control-group" :class="[errors.has('last_name') ? 'has-error' : '']">
<label for="last_name" class="required"> {{ __('admin::app.customers.customers.last_name') }}</label>
<input type="text" class="control" name="last_name" v-validate="'required'" value="{{old('last_name') ?:$customer->last_name}}" data-vv-as="&quot;{{ __('shop::app.customer.signup-form.lastname') }}&quot;">
<span class="control-error" v-if="errors.has('last_name')">@{{ errors.first('last_name') }}</span>
</div>
{!! view_render_event('bagisto.admin.customer.edit.last_name.after', ['customer' => $customer]) !!}
<div class="control-group" :class="[errors.has('email') ? 'has-error' : '']">
<label for="email" class="required"> {{ __('admin::app.customers.customers.email') }}</label>
<input type="email" class="control" name="email" v-validate="'required|email'" value="{{old('email') ?:$customer->email}}" data-vv-as="&quot;{{ __('shop::app.customer.signup-form.email') }}&quot;">
<span class="control-error" v-if="errors.has('email')">@{{ errors.first('email') }}</span>
</div>
{!! view_render_event('bagisto.admin.customer.edit.email.after', ['customer' => $customer]) !!}
<div class="control-group" :class="[errors.has('gender') ? 'has-error' : '']">
<label for="gender" class="required">{{ __('admin::app.customers.customers.gender') }}</label>
<select name="gender" class="control" value="{{ $customer->gender }}" v-validate="'required'" data-vv-as="&quot;{{ __('admin::app.customers.customers.gender') }}&quot;">
@ -66,6 +74,8 @@
<span class="control-error" v-if="errors.has('gender')">@{{ errors.first('gender') }}</span>
</div>
{!! view_render_event('bagisto.admin.customer.edit.gender.after', ['customer' => $customer]) !!}
<div class="control-group">
<label for="status" class="required">{{ __('admin::app.customers.customers.status') }}</label>
@ -77,18 +87,24 @@
<span class="control-error" v-if="errors.has('status')">@{{ errors.first('status') }}</span>
</div>
{!! view_render_event('bagisto.admin.customer.edit.status.after', ['customer' => $customer]) !!}
<div class="control-group" :class="[errors.has('date_of_birth') ? 'has-error' : '']">
<label for="dob">{{ __('admin::app.customers.customers.date_of_birth') }}</label>
<input type="date" class="control" name="date_of_birth" value="{{ old('date_of_birth') ?:$customer->date_of_birth }}" v-validate="" data-vv-as="&quot;{{ __('admin::app.customers.customers.date_of_birth') }}&quot;">
<span class="control-error" v-if="errors.has('date_of_birth')">@{{ errors.first('date_of_birth') }}</span>
</div>
{!! view_render_event('bagisto.admin.customer.edit.date_of_birth.after', ['customer' => $customer]) !!}
<div class="control-group" :class="[errors.has('phone') ? 'has-error' : '']">
<label for="phone">{{ __('admin::app.customers.customers.phone') }}</label>
<input type="text" class="control" name="phone" value="{{ $customer->phone }}" data-vv-as="&quot;{{ __('admin::app.customers.customers.phone') }}&quot;">
<span class="control-error" v-if="errors.has('phone')">@{{ errors.first('phone') }}</span>
</div>
{!! view_render_event('bagisto.admin.customer.edit.phone.after', ['customer' => $customer]) !!}
<div class="control-group">
<label for="customerGroup" >{{ __('admin::app.customers.customers.customer_group') }}</label>

View File

@ -7,8 +7,12 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="icon" sizes="16x16" href="{{ asset('vendor/webkul/ui/assets/images/favicon.ico') }}" />
@if ($favicon = core()->getConfigData('general.design.admin_logo.favicon'))
<link rel="icon" sizes="16x16" href="{{ \Illuminate\Support\Facades\Storage::url($favicon) }}" />
@else
<link rel="icon" sizes="16x16" href="{{ asset('vendor/webkul/ui/assets/images/favicon.ico') }}" />
@endif
<link rel="stylesheet" href="{{ asset('vendor/webkul/admin/assets/css/admin.css') }}">
<link rel="stylesheet" href="{{ asset('vendor/webkul/ui/assets/css/ui.css') }}">

View File

@ -6,7 +6,12 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<link rel="icon" sizes="16x16" href="{{ asset('vendor/webkul/ui/assets/images/favicon.ico') }}" />
@if ($favicon = core()->getConfigData('general.design.admin_logo.favicon'))
<link rel="icon" sizes="16x16" href="{{ \Illuminate\Support\Facades\Storage::url($favicon) }}" />
@else
<link rel="icon" sizes="16x16" href="{{ asset('vendor/webkul/ui/assets/images/favicon.ico') }}" />
@endif
<link rel="stylesheet" href="{{ asset('vendor/webkul/ui/assets/css/ui.css') }}">
<link rel="stylesheet" href="{{ asset('vendor/webkul/admin/assets/css/admin.css') }}">

View File

@ -5,14 +5,47 @@
@stop
@section('content')
<div class="content">
<?php $customer_group = request()->get('customer_group') ?: null; ?>
<?php $channel = request()->get('channel') ?: null; ?>
<div class="page-header">
<div class="page-title">
<h1>{{ __('admin::app.promotions.cart-rules.title') }}</h1>
</div>
<div class="page-action">
<div class="control-group">
<select class="control" id="channel-switcher" name="channel" onchange="reloadPage('channel', this.value)" >
<option value="all" {{ ! isset($channel) ? 'selected' : '' }}>
{{ __('admin::app.admin.system.all-channels') }}
</option>
@foreach (core()->getAllChannels() as $channelModel)
<option
value="{{ $channelModel->id }}" {{ (isset($channel) && ($channelModel->id) == $channel) ? 'selected' : '' }}>
{{ $channelModel->name }}
</option>
@endforeach
</select>
</div>
<div class="control-group">
<select class="control" id="customer-group-switcher" name="customer_group" onchange="reloadPage('customer_group', this.value)" >
<option value="all" {{ ! isset($locale) ? 'selected' : '' }}>
{{ __('admin::app.admin.system.all-customer-groups') }}
</option>
@foreach (core()->getAllCustomerGroups() as $customerGroupModel)
<option
value="{{ $customerGroupModel->id }}" {{ (isset($customerGroupModel) && ($customerGroupModel->id) == $customer_group) ? 'selected' : '' }}>
{{ $customerGroupModel->name }}
</option>
@endforeach
</select>
</div>
<a href="{{ route('admin.cart-rules.create') }}" class="btn btn-lg btn-primary">
{{ __('admin::app.promotions.cart-rules.add-title') }}
</a>
@ -24,4 +57,15 @@
{!! $cartRuleGrid->render() !!}
</div>
</div>
@endsection
@endsection
@push('scripts')
<script>
function reloadPage(getVar, getVal) {
let url = new URL(window.location.href);
url.searchParams.set(getVar, getVal);
window.location.href = url.href;
}
</script>
@endpush

View File

@ -26,22 +26,6 @@
<div class="form-container">
@csrf()
<div class="control-group" :class="[errors.has('channel') ? 'has-error' : '']">
<label for="channel" class="required">{{ __('admin::app.configuration.tax-categories.select-channel') }}</label>
<select class="control" name="channel_id">
@foreach (core()->getAllChannels() as $channelModel)
<option value="{{ $channelModel->id }}">
{{ $channelModel->name }}
</option>
@endforeach
</select>
<span class="control-error" v-if="errors.has('channel')">@{{ errors.first('channel') }}</span>
</div>
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
<label for="code" class="required">{{ __('admin::app.configuration.tax-categories.code') }}</label>
@ -67,7 +51,7 @@
</div>
<?php $selectedOptions = old('taxrates') ?: [] ?>
<div class="control-group" :class="[errors.has('taxrates[]') ? 'has-error' : '']">
<label for="taxrates" class="required">{{ __('admin::app.configuration.tax-categories.select-taxrates') }}</label>

View File

@ -27,22 +27,6 @@
<div class="form-container">
@csrf()
@method('PUT')
<div class="control-group" :class="[errors.has('channel') ? 'has-error' : '']">
<label for="channel" class="required">{{ __('admin::app.settings.tax-categories.select-channel') }}</label>
<select class="control" name="channel_id">
@foreach (core()->getAllChannels() as $channelModel)
<option @if ($taxCategory->channel_id == $channelModel->id) selected @endif value="{{ $channelModel->id }}">
{{ $channelModel->name }}
</option>
@endforeach
</select>
<span class="control-error" v-if="errors.has('channel')">@{{ errors.first('channel') }}</span>
</div>
<div class="control-group" :class="[errors.has('code') ? 'has-error' : '']">
<label for="code" class="required">{{ __('admin::app.settings.tax-categories.code') }}</label>

View File

@ -2,8 +2,10 @@
namespace Webkul\BookingProduct\Providers;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Event;
use Webkul\Theme\ViewRenderEventManager;
class EventServiceProvider extends ServiceProvider
{
@ -14,8 +16,10 @@ class EventServiceProvider extends ServiceProvider
*/
public function boot()
{
Event::listen('bagisto.shop.products.view.short_description.after', function($viewRenderEventManager) {
$viewRenderEventManager->addTemplate('bookingproduct::shop.products.view.booking');
Event::listen('bagisto.shop.products.view.short_description.after', static function(ViewRenderEventManager $viewRenderEventManager) {
if (View::exists('bookingproduct::shop.' . core()->getCurrentChannel()->theme . '.products.view.booking')) {
$viewRenderEventManager->addTemplate('bookingproduct::shop.' . core()->getCurrentChannel()->theme . '.products.view.booking');
}
});
Event::listen('checkout.order.save.after', 'Webkul\BookingProduct\Listeners\Order@afterPlaceOrder');

View File

@ -134,11 +134,14 @@ class CartRule
*/
public function getCartRules()
{
static $cartRules;
if ($cartRules) {
return $cartRules;
$staticCartRules = new class() {
public static $cartRules;
public static $cartID;
};
if ($staticCartRules::$cartID === cart()->getCart()->id && $staticCartRules::$cartRules) {
return $staticCartRules::$cartRules;
}
$staticCartRules::$cartID = cart()->getCart()->id;
$customerGroupId = null;
@ -166,6 +169,7 @@ class CartRule
->orderBy('sort_order', 'asc');
})->findWhere(['status' => 1]);
$staticCartRules::$cartRules = $cartRules;
return $cartRules;
}
@ -246,6 +250,10 @@ class CartRule
continue;
}
if ($rule->coupon_code) {
$item->coupon_code = $rule->coupon_code;
}
$quantity = $rule->discount_quantity ? min($item->quantity, $rule->discount_quantity) : $item->quantity;
$discountAmount = $baseDiscountAmount = 0;
@ -254,9 +262,9 @@ class CartRule
case 'by_percent':
$rulePercent = min(100, $rule->discount_amount);
$discountAmount = ($quantity * $item->price - $item->discount_amount) * ($rulePercent / 100);
$discountAmount = ($quantity * $item->price + $item->tax_amount - $item->discount_amount) * ($rulePercent / 100);
$baseDiscountAmount = ($quantity * $item->base_price - $item->base_discount_amount) * ($rulePercent / 100);
$baseDiscountAmount = ($quantity * $item->base_price + $item->base_tax_amount - $item->base_discount_amount) * ($rulePercent / 100);
if (! $rule->discount_quantity || $rule->discount_quantity > $quantity) {
$discountPercent = min(100, $item->discount_percent + $rulePercent);
@ -316,8 +324,16 @@ class CartRule
break;
}
$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);
$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);
$appliedRuleIds[$rule->id] = $rule->id;

View File

@ -19,14 +19,14 @@ class Order
/**
* CartRuleCustomerRepository object
*
* @var Webkul\CartRule\Repositories\\CartRuleCustomerRepository
* @var \Webkul\CartRule\Repositories\CartRuleCustomerRepository
*/
protected $cartRuleCustomerRepository;
/**
* CartRuleCouponRepository object
*
* @var Webkul\CartRule\Repositories\\CartRuleCouponRepository
* @var \Webkul\CartRule\Repositories\CartRuleCouponRepository
*/
protected $cartRuleCouponRepository;
@ -64,7 +64,7 @@ class Order
/**
* Save cart rule and cart rule coupon properties after place order
*
*
* @param \Webkul\Sales\Contracts\Order $order
* @return void
*/
@ -112,7 +112,7 @@ class Order
}
$coupon = $this->cartRuleCouponRepository->findOneByField('code', $order->coupon_code);
if ($coupon) {
$this->cartRuleCouponRepository->update(['times_used' => $coupon->times_used + 1], $coupon->id);

View File

@ -37,7 +37,7 @@ class CartRuleRepository extends Repository
/**
* CartRuleCouponRepository object
*
* @var Webkul\CartRule\Repositories\CartRuleCouponRepository
* @var \Webkul\CartRule\Repositories\CartRuleCouponRepository
*/
protected $cartRuleCouponRepository;

View File

@ -436,20 +436,19 @@ class Cart
*
* @return \Webkul\Checkout\Contracts\Cart|null
*/
public function getCart()
public function getCart(): ?\Webkul\Checkout\Contracts\Cart
{
$cart = null;
if ($this->getCurrentCustomer()->check()) {
$cart = $this->cartRepository->findOneWhere([
return $this->cartRepository->findOneWhere([
'customer_id' => $this->getCurrentCustomer()->user()->id,
'is_active' => 1,
]);
} elseif (session()->has('cart')) {
$cart = $this->cartRepository->find(session()->get('cart')->id);
return $this->cartRepository->find(session()->get('cart')->id);
}
return $cart && $cart->is_active ? $cart : null;
return null;
}
/**
@ -483,7 +482,8 @@ class Cart
*
* @param array $data
*
* @return void is the cart valid
* @return bool
* @throws \Prettus\Validator\Exceptions\ValidatorException
*/
public function saveCustomerAddress($data): bool
{
@ -498,7 +498,7 @@ class Cart
$this->saveAddressesWhenRequested($data, $billingAddressData, $shippingAddressData);
$this->linkAddresses($cart, $billingAddressData, $shippingAddressData);
$this->assignCustomerFields($cart);
$cart->save();
@ -633,6 +633,7 @@ class Cart
} else {
foreach ($cart->items as $item) {
$response = $item->product->getTypeInstance()->validateCartItem($item);
// ToDo: refactoring of all validateCartItem functions, at the moment they return nothing
if ($response) {
return;
@ -662,7 +663,7 @@ class Cart
if (! $cart = $this->getCart()) {
return;
}
Event::dispatch('checkout.cart.calculate.items.tax.before', $cart);
foreach ($cart->items()->get() as $item) {
@ -741,7 +742,7 @@ class Cart
* @param \Webkul\Checkout\Contracts\CartItem $item
* @return \Webkul\Checkout\Contracts\CartItem
*/
protected function setItemTaxToZero(CartItem $item): CartItem
protected function setItemTaxToZero(\Webkul\Checkout\Contracts\CartItem $item): \Webkul\Checkout\Contracts\CartItem
{
$item->tax_percent = 0;
$item->tax_amount = 0;
@ -755,7 +756,7 @@ class Cart
*
* @return bool
*/
public function hasError()
public function hasError(): bool
{
if (! $this->getCart()) {
return true;
@ -773,7 +774,7 @@ class Cart
*
* @return bool
*/
public function isItemsHaveSufficientQuantity()
public function isItemsHaveSufficientQuantity(): bool
{
foreach ($this->getCart()->items as $item) {
if (! $this->isItemHaveQuantity($item)) {
@ -790,7 +791,7 @@ class Cart
* @param \Webkul\Checkout\Contracts\CartItem $item
* @return bool
*/
public function isItemHaveQuantity($item)
public function isItemHaveQuantity($item): bool
{
return $item->product->getTypeInstance()->isItemHaveQuantity($item);
}
@ -800,7 +801,7 @@ class Cart
*
* @return void
*/
public function deActivateCart()
public function deActivateCart(): void
{
if ($cart = $this->getCart()) {
$this->cartRepository->update(['is_active' => false], $cart->id);
@ -816,7 +817,7 @@ class Cart
*
* @return array
*/
public function prepareDataForOrder()
public function prepareDataForOrder(): array
{
$data = $this->toArray();
@ -875,7 +876,7 @@ class Cart
* @param array $data
* @return array
*/
public function prepareDataForOrderItem($data)
public function prepareDataForOrderItem($data): array
{
$finalData = [
'product' => $this->productRepository->find($data['product_id']),
@ -1033,9 +1034,9 @@ class Cart
* 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
* @param \Webkul\Checkout\Contracts\Cart $cart
*/
private function assignCustomerFields(\Webkul\Checkout\Models\Cart $cart): void
private function assignCustomerFields(\Webkul\Checkout\Contracts\Cart $cart): void
{
if ($this->getCurrentCustomer()->check()
&& ($user = $this->getCurrentCustomer()->user())
@ -1190,34 +1191,37 @@ class Cart
{
$billingAddressModel = $cart->billing_address;
if ($billingAddressModel) {
$billingAddressData['address_type'] = CartAddress::ADDRESS_TYPE_BILLING;
$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']) {
$billingAddressData['address_type'] = CartAddress::ADDRESS_TYPE_SHIPPING;
$this->cartAddressRepository->update($billingAddressData, $shippingAddressModel->id);
} else {
$shippingAddressData['address_type'] = CartAddress::ADDRESS_TYPE_SHIPPING;
$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']));
['address_type' => CartAddress::ADDRESS_TYPE_SHIPPING]));
} else {
$this->cartAddressRepository->create(array_merge($shippingAddressData,
['address_type' => 'shipping']));
['address_type' => CartAddress::ADDRESS_TYPE_SHIPPING]));
}
}
}
} else {
$this->cartAddressRepository->create(array_merge($billingAddressData, ['address_type' => 'billing']));
$this->cartAddressRepository->create(array_merge($billingAddressData, ['address_type' => CartAddress::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']));
$this->cartAddressRepository->create(array_merge($billingAddressData, ['address_type' => CartAddress::ADDRESS_TYPE_SHIPPING]));
} else {
$this->cartAddressRepository->create(array_merge($shippingAddressData, ['address_type' => 'shipping']));
$this->cartAddressRepository->create(array_merge($shippingAddressData, ['address_type' => CartAddress::ADDRESS_TYPE_SHIPPING]));
}
}
}

View File

@ -6,14 +6,10 @@ use Faker\Generator as Faker;
use Webkul\Checkout\Models\CartAddress;
$factory->define(CartAddress::class, function (Faker $faker) {
$now = date("Y-m-d H:i:s");
return [
'first_name' => $faker->firstName(),
'last_name' => $faker->lastName,
'email' => $faker->email,
'created_at' => $now,
'updated_at' => $now,
'address_type' => 'billing',
'address_type' => CartAddress::ADDRESS_TYPE_BILLING,
];
});

View File

@ -48,7 +48,7 @@ class Cart extends Model implements CartContract
*/
public function billing_address()
{
return $this->addresses()->where('address_type', 'billing');
return $this->addresses()->where('address_type', CartAddress::ADDRESS_TYPE_BILLING);
}
/**
@ -64,7 +64,7 @@ class Cart extends Model implements CartContract
*/
public function shipping_address()
{
return $this->addresses()->where('address_type', 'shipping');
return $this->addresses()->where('address_type', CartAddress::ADDRESS_TYPE_SHIPPING);
}
/**

View File

@ -2,30 +2,47 @@
namespace Webkul\Checkout\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Webkul\Checkout\Contracts\CartAddress as CartAddressContract;
use Webkul\Core\Models\Address;
class CartAddress extends Model implements CartAddressContract
/**
* Class CartAddress
* @package Webkul\Checkout\Models
*
* @property integer $cart_id
* @property Cart $cart
*
*/
class CartAddress extends Address implements CartAddressContract
{
protected $table = 'cart_address';
public const ADDRESS_TYPE_SHIPPING = 'cart_shipping';
public const ADDRESS_TYPE_BILLING = 'cart_billing';
protected $fillable = [
'first_name',
'last_name',
'email',
'company_name',
'vat_id',
'address1',
'city',
'state',
'postcode',
'country',
'phone',
'address_type',
'cart_id',
'customer_id',
/**
* @var array default values
*/
protected $attributes = [
'address_type' => self::ADDRESS_TYPE_BILLING,
];
/**
* The "booted" method of the model.
*
* @return void
*/
protected static function boot()
{
static::addGlobalScope('address_type', static function (Builder $builder) {
$builder->whereIn('address_type', [
self::ADDRESS_TYPE_BILLING,
self::ADDRESS_TYPE_SHIPPING
]);
});
parent::boot();
}
/**
* Get the shipping rates for the cart address.
*/
@ -35,10 +52,10 @@ class CartAddress extends Model implements CartAddressContract
}
/**
* Get all of the attributes for the attribute groups.
* Get the cart record associated with the address.
*/
public function getNameAttribute()
public function cart()
{
return $this->first_name . ' ' . $this->last_name;
return $this->belongsTo(Cart::class);
}
}

View File

@ -24,6 +24,7 @@ class CartShippingRate extends Model implements CartShippingRateContract
*/
public function shipping_address()
{
return $this->belongsTo(CartAddressProxy::modelClass());
return $this->belongsTo(CartAddressProxy::modelClass(), 'cart_address_id')
->where('address_type', CartAddress::ADDRESS_TYPE_SHIPPING);
}
}

View File

@ -0,0 +1,7 @@
<?php
namespace Webkul\Core\Contracts;
interface Address
{
}

View File

@ -12,6 +12,7 @@ use Webkul\Core\Repositories\ChannelRepository;
use Webkul\Core\Repositories\LocaleRepository;
use Webkul\Core\Repositories\CoreConfigRepository;
use Illuminate\Support\Facades\Config;
use Webkul\Customer\Repositories\CustomerGroupRepository;
class Core
{
@ -57,6 +58,13 @@ class Core
*/
protected $localeRepository;
/**
* CustomerGroupRepository class
*
* @var CustomerGroupRepository
*/
protected $customerGroupRepository;
/**
* CoreConfigRepository class
*
@ -70,13 +78,14 @@ class Core
/**
* Create a new instance.
*
* @param \Webkul\Core\Repositories\ChannelRepository $channelRepository
* @param \Webkul\Core\Repositories\CurrencyRepository $currencyRepository
* @param \Webkul\Core\Repositories\ExchangeRateRepository $exchangeRateRepository
* @param \Webkul\Core\Repositories\CountryRepository $countryRepository
* @param \Webkul\Core\Repositories\CountryStateRepository $countryStateRepository
* @param \Webkul\Core\Repositories\LocaleRepository $localeRepository
* @param \Webkul\Core\Repositories\CoreConfigRepository $coreConfigRepository
* @param \Webkul\Core\Repositories\ChannelRepository $channelRepository
* @param \Webkul\Core\Repositories\CurrencyRepository $currencyRepository
* @param \Webkul\Core\Repositories\ExchangeRateRepository $exchangeRateRepository
* @param \Webkul\Core\Repositories\CountryRepository $countryRepository
* @param \Webkul\Core\Repositories\CountryStateRepository $countryStateRepository
* @param \Webkul\Core\Repositories\LocaleRepository $localeRepository
* @param \Webkul\Core\Repositories\CustomerGroupRepository $customerGroupRepository
* @param \Webkul\Core\Repositories\CoreConfigRepository $coreConfigRepository
*
* @return void
*/
@ -87,6 +96,7 @@ class Core
CountryRepository $countryRepository,
CountryStateRepository $countryStateRepository,
LocaleRepository $localeRepository,
CustomerGroupRepository $customerGroupRepository,
CoreConfigRepository $coreConfigRepository
)
{
@ -102,6 +112,8 @@ class Core
$this->localeRepository = $localeRepository;
$this->customerGroupRepository = $customerGroupRepository;
$this->coreConfigRepository = $coreConfigRepository;
}
@ -247,6 +259,22 @@ class Core
return $locale;
}
/**
* Returns all Customer Groups
*
* @return \Illuminate\Support\Collection
*/
public function getAllCustomerGroups()
{
static $customerGroups;
if ($customerGroups) {
return $customerGroups;
}
return $customerGroups = $this->customerGroupRepository->all();
}
/**
* Returns all currencies
*
@ -376,9 +404,10 @@ class Core
/**
* Converts price
*
* @param float $amount
* @param string $targetCurrencyCode
* @param string $orderCurrencyCode
* @param float $amount
* @param string $targetCurrencyCode
* @param string $orderCurrencyCode
*
* @return string
*/
public function convertPrice($amount, $targetCurrencyCode = null, $orderCurrencyCode = null)
@ -394,16 +423,16 @@ class Core
if (($targetCurrencyCode != $this->lastOrderCode)
&& ($targetCurrencyCode != $orderCurrencyCode)
&& ($orderCurrencyCode != $this->getBaseCurrencyCode())
&& ($orderCurrencyCode != $this->lastCurrencyCode)
&& ($orderCurrencyCode != $this->getBaseCurrencyCode())
&& ($orderCurrencyCode != $this->lastCurrencyCode)
) {
$amount = $this->convertToBasePrice($amount, $orderCurrencyCode);
}
}
$targetCurrency = ! $targetCurrencyCode
? $this->getCurrentCurrency()
: $this->currencyRepository->findOneByField('code', $targetCurrencyCode);
? $this->getCurrentCurrency()
: $this->currencyRepository->findOneByField('code', $targetCurrencyCode);
if (! $targetCurrency) {
return $amount;
@ -429,15 +458,16 @@ class Core
/**
* Converts to base price
*
* @param float $amount
* @param string $targetCurrencyCode
* @param float $amount
* @param string $targetCurrencyCode
*
* @return string
*/
public function convertToBasePrice($amount, $targetCurrencyCode = null)
{
$targetCurrency = ! $targetCurrencyCode
? $this->getCurrentCurrency()
: $this->currencyRepository->findOneByField('code', $targetCurrencyCode);
? $this->getCurrentCurrency()
: $this->currencyRepository->findOneByField('code', $targetCurrencyCode);
if (! $targetCurrency) {
return $amount;
@ -457,7 +487,8 @@ class Core
/**
* Format and convert price with currency symbol
*
* @param float $price
* @param float $price
*
* @return string
*/
public function currency($amount = 0)
@ -472,7 +503,8 @@ class Core
/**
* Return currency symbol from currency code
*
* @param float $price
* @param float $price
*
* @return string
*/
public function currencySymbol($code)
@ -483,17 +515,18 @@ class Core
}
/**
* Format and convert price with currency symbol
*
* @param float $price
* @return string
*/
* Format and convert price with currency symbol
*
* @param float $price
*
* @return string
*/
public function formatPrice($price, $currencyCode)
{
if (is_null($price))
$price = 0;
$formatter = new \NumberFormatter( app()->getLocale(), \NumberFormatter::CURRENCY );
$formatter = new \NumberFormatter(app()->getLocale(), \NumberFormatter::CURRENCY);
return $formatter->formatCurrency($price, $currencyCode);
}
@ -523,7 +556,8 @@ class Core
/**
* Format price with base currency symbol
*
* @param float $price
* @param float $price
*
* @return string
*/
public function formatBasePrice($price)
@ -551,8 +585,9 @@ class Core
* Checks if current date of the given channel (in the channel timezone) is within the range
*
* @param int|string|\Webkul\Core\Contracts\Channel $channel
* @param string|null $dateFrom
* @param string|null $dateTo
* @param string|null $dateFrom
* @param string|null $dateTo
*
* @return bool
*/
public function isChannelDateInInterval($dateFrom = null, $dateTo = null)
@ -583,7 +618,8 @@ class Core
/**
* Get channel timestamp, timstamp will be builded with channel timezone settings
*
* @param \Webkul\Core\Contracts\Channel $channel
* @param \Webkul\Core\Contracts\Channel $channel
*
* @return int
*/
public function channelTimeStamp($channel)
@ -604,7 +640,8 @@ class Core
/**
* Check whether sql date is empty
*
* @param string $date
* @param string $date
*
* @return bool
*/
function is_empty_date($date)
@ -615,8 +652,8 @@ class Core
/**
* Format date using current channel.
*
* @param \Illuminate\Support\Carbon|null $date
* @param string $format
* @param \Illuminate\Support\Carbon|null $date
* @param string $format
*
* @return string
*/
@ -636,9 +673,9 @@ class Core
/**
* Retrieve information from payment configuration
*
* @param string $field
* @param int|string|null $channelId
* @param string|null $locale
* @param string $field
* @param int|string|null $channelId
* @param string|null $locale
*
* @return mixed
*/
@ -707,7 +744,8 @@ class Core
/**
* Retrieve a group of information from the core config table
*
* @param mixed $criteria
* @param mixed $criteria
*
* @return mixed
*/
public function retrieveGroupConfig($criteria)
@ -728,7 +766,8 @@ class Core
/**
* Returns country name by code
*
* @param string $code
* @param string $code
*
* @return string
*/
public function country_name($code)
@ -741,7 +780,8 @@ class Core
/**
* Retrieve all country states
*
* @param string $countryCode
* @param string $countryCode
*
* @return \Illuminate\Support\Collection
*/
public function states($countryCode)
@ -786,8 +826,9 @@ class Core
/**
* Returns time intervals
*
* @param \Illuminate\Support\Carbon $startDate
* @param \Illuminate\Support\Carbon $endDate
* @param \Illuminate\Support\Carbon $startDate
* @param \Illuminate\Support\Carbon $endDate
*
* @return array
*/
public function getTimeInterval($startDate, $endDate)
@ -808,8 +849,8 @@ class Core
$start = Carbon::createFromTimeString($date->format('Y-m-d') . ' 00:00:01');
$end = $totalMonths - 1 == $i
? $endDate
: Carbon::createFromTimeString($date->format('Y-m-d') . ' 23:59:59');
? $endDate
: Carbon::createFromTimeString($date->format('Y-m-d') . ' 23:59:59');
$timeIntervals[] = ['start' => $start, 'end' => $end, 'formatedDate' => $date->format('M')];
}
@ -819,11 +860,11 @@ class Core
$date->addWeeks($i);
$start = $i == 0
? $startDate
: Carbon::createFromTimeString($this->xWeekRange($date, 0) . ' 00:00:01');
? $startDate
: Carbon::createFromTimeString($this->xWeekRange($date, 0) . ' 00:00:01');
$end = $totalWeeks - 1 == $i
? $endDate
: Carbon::createFromTimeString($this->xWeekRange($date, 1) . ' 23:59:59');
? $endDate
: Carbon::createFromTimeString($this->xWeekRange($date, 1) . ' 23:59:59');
$timeIntervals[] = ['start' => $start, 'end' => $end, 'formatedDate' => $date->format('d M')];
}
@ -844,8 +885,9 @@ class Core
/**
*
* @param string $date
* @param int $day
* @param string $date
* @param int $day
*
* @return string
*/
public function xWeekRange($date, $day)
@ -866,7 +908,8 @@ class Core
/**
* Method to sort through the acl items and put them in order
*
* @param array $items
* @param array $items
*
* @return array
*/
public function sortItems($items)
@ -889,7 +932,8 @@ class Core
}
/**
* @param string $fieldName
* @param string $fieldName
*
* @return array
*/
public function getConfigField($fieldName)
@ -908,7 +952,8 @@ class Core
}
/**
* @param array $items
* @param array $items
*
* @return array
*/
public function convertToAssociativeArray($items)
@ -941,9 +986,10 @@ class Core
}
/**
* @param array $items
* @param string $key
* @param string|int|float $value
* @param array $items
* @param string $key
* @param string|int|float $value
*
* @return array
*/
public function array_set(&$array, $key, $value)
@ -977,8 +1023,9 @@ class Core
}
/**
* @param array $array1
* @param array $array2
* @param array $array1
* @param array $array2
*
* @return array
*/
protected function arrayMerge(array &$array1, array &$array2)
@ -997,7 +1044,8 @@ class Core
}
/**
* @param array $array1
* @param array $array1
*
* @return array
*/
public function convertEmptyStringsToNull($array)
@ -1014,7 +1062,8 @@ class Core
/**
* Create singletom object through single facade
*
* @param string $className
* @param string $className
*
* @return object
*/
public function getSingletonInstance($className)
@ -1031,7 +1080,8 @@ class Core
/**
* Returns a string as selector part for identifying elements in views
*
* @param float $taxRate
* @param float $taxRate
*
* @return string
*/
public static function taxRateAsIdentifier(float $taxRate): string
@ -1051,8 +1101,8 @@ class Core
$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,
'name' => $sender_name,
'email' => $sender_email,
];
}
@ -1068,8 +1118,8 @@ class Core
$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,
'name' => $admin_name,
'email' => $admin_email,
];
}
}

View File

@ -0,0 +1,30 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use Faker\Generator as Faker;
use Webkul\CartRule\Models\CartRule;
$factory->define(CartRule::class, function (Faker $faker) {
return [
'name' => $faker->uuid,
'description' => $faker->sentence(),
'starts_from' => null,
'ends_till' => null,
'coupon_type' => '1',
'use_auto_generation' => '0',
'usage_per_customer' => '100',
'uses_per_coupon' => '100',
'times_used' => '0',
'condition_type' => '2',
'end_other_rules' => '0',
'uses_attribute_conditions' => '0',
'discount_quantity' => '0',
'discount_step' => '0',
'apply_to_shipping' => '0',
'free_shipping' => '0',
'sort_order' => '0',
'status' => '1',
'conditions' => null,
];
});

View File

@ -0,0 +1,39 @@
<?php
use Faker\Generator as Faker;
use Webkul\Category\Models\Category;
use Webkul\Core\Models\Channel;
use Webkul\Core\Models\Currency;
use Webkul\Core\Models\Locale;
/** @var \Illuminate\Database\Eloquent\Factory $factory */
$factory->define(Channel::class, function (Faker $faker, array $attributes) {
$seoTitle = $attributes['seo_title'] ?? $faker->word;
$seoDescription = $attributes['seo_description'] ?? $faker->words(10, true);
$seoKeywords = $attributes['seo_keywords'] ?? $faker->words(3, true);
$seoData = [
'meta_title' => $seoTitle,
'meta_description' => $seoDescription,
'meta_keywords' => $seoKeywords,
];
unset($attributes['seo_title'], $attributes['seo_description'], $attributes['seo_keywords']);
return [
'code' => $faker->unique()->word,
'name' => $faker->word,
'default_locale_id' => function () {
return factory(Locale::class)->create()->id;
},
'base_currency_id' => function () {
return factory(Currency::class)->create()->id;
},
'root_category_id' => function () {
return factory(Category::class)->create()->id;
},
'home_seo' => json_encode($seoData),
];
});

View File

@ -0,0 +1,10 @@
<?php
/** @var \Illuminate\Database\Eloquent\Factory $factory */
$factory->define('channel_inventory_sources', function () {
return [
'channel_id' => core()->getCurrentChannel()->id,
'inventory_source_id' => 1,
];
});

View File

@ -0,0 +1,294 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use Webkul\Checkout\Models\CartAddress;
use Webkul\Checkout\Models\CartShippingRate;
use Webkul\Sales\Models\Invoice;
use Webkul\Sales\Models\OrderAddress;
use Webkul\Sales\Models\Shipment;
class AddTableAddresses extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
try {
// transaction is important to prevent loosing data on failure
DB::beginTransaction();
Schema::create('addresses', function (Blueprint $table) {
$table->increments('id');
$table->string('address_type');
$table->unsignedInteger('customer_id')->nullable()->comment('null if guest checkout');
$table->unsignedInteger('cart_id')->nullable()->comment('only for cart_addresses');
$table->unsignedInteger('order_id')->nullable()->comment('only for order_addresses');
$table->string('first_name');
$table->string('last_name');
$table->string('gender')->nullable();
$table->string('company_name')->nullable();
$table->string('address1');
$table->string('address2')->nullable();
$table->string('postcode');
$table->string('city');
$table->string('state');
$table->string('country');
$table->string('email')->nullable();
$table->string('phone')->nullable();
$table->string('vat_id')->nullable();
$table->boolean('default_address')
->default(false)
->comment('only for customer_addresses');
$table->json('additional')->nullable();
$table->timestamps();
$table->foreign(['customer_id'])->references('id')->on('customers')->onDelete('cascade');
$table->foreign(['cart_id'])->references('id')->on('cart')->onDelete('cascade');
$table->foreign(['order_id'])->references('id')->on('orders')->onDelete('cascade');
});
Schema::disableForeignKeyConstraints();
$this->migrateCustomerAddresses();
$this->migrateCartAddresses();
$this->migrateOrderAddresses();
$this->migrateForeignKeys();
Schema::drop('customer_addresses');
Schema::drop('cart_address');
Schema::drop('order_address');
Schema::enableForeignKeyConstraints();
DB::commit();
} catch (Exception $e) {
DB::rollBack();
throw $e;
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
throw new Exception('you cannot revert this migration: data would be lost');
}
private function migrateCustomerAddresses(): void
{
$dbPrefix = DB::getTablePrefix();
$insertCustomerAddresses = <<< SQL
INSERT INTO ${dbPrefix}addresses(
address_type,
customer_id,
first_name,
last_name,
gender,
company_name,
address1,
address2,
postcode,
city,
state,
country,
email,
phone,
default_address,
additional,
created_at,
updated_at
)
SELECT
"customer",
customer_id,
first_name,
last_name,
(SELECT gender FROM customers c WHERE c.id=ca.customer_id),
company_name,
address1,
address2,
postcode,
city,
state,
country,
null,
phone,
default_address,
JSON_INSERT('{}', '$.old_customer_address_id', id),
created_at,
updated_at
FROM customer_addresses ca;
SQL;
DB::unprepared($insertCustomerAddresses);
}
private function migrateCartAddresses(): void
{
$dbPrefix = DB::getTablePrefix();
$insertCustomerAddresses = <<< SQL
INSERT INTO ${dbPrefix}addresses(
address_type,
customer_id,
cart_id,
first_name,
last_name,
gender,
company_name,
address1,
address2,
postcode,
city,
state,
country,
email,
phone,
additional,
created_at,
updated_at
)
SELECT
(CASE WHEN ca.address_type='billing' THEN "cart_billing" ELSE "cart_shipping" END),
customer_id,
cart_id,
first_name,
last_name,
(SELECT gender FROM customers c WHERE c.id=ca.customer_id),
company_name,
address1,
address2,
postcode,
city,
state,
country,
email,
phone,
JSON_INSERT('{}', '$.old_cart_address_id', id),
created_at,
updated_at
FROM cart_address ca;
SQL;
DB::unprepared($insertCustomerAddresses);
}
private function migrateOrderAddresses(): void
{
$dbPrefix = DB::getTablePrefix();
$insertCustomerAddresses = <<< SQL
INSERT INTO ${dbPrefix}addresses(
address_type,
customer_id,
order_id,
first_name,
last_name,
gender,
company_name,
address1,
address2,
postcode,
city,
state,
country,
email,
phone,
additional,
created_at,
updated_at
)
SELECT
(CASE WHEN oa.address_type='billing' THEN "order_billing" ELSE "order_shipping" END),
customer_id,
order_id,
first_name,
last_name,
(SELECT gender FROM customers c WHERE c.id=oa.customer_id),
company_name,
address1,
address2,
postcode,
city,
state,
country,
email,
phone,
JSON_INSERT('{}', '$.old_order_address_id', id),
created_at,
updated_at
FROM order_address oa;
SQL;
DB::unprepared($insertCustomerAddresses);
}
private function migrateForeignKeys(): void
{
Schema::table('cart_shipping_rates', static function (Blueprint $table) {
$table->dropForeign(['cart_address_id']);
CartAddress::query()
->orderBy('id', 'asc') // for some reason each() needs an orderBy in before
->each(static function ($row) {
CartShippingRate::query()
->where('cart_address_id', $row->additional['old_cart_address_id'])
->update(['cart_address_id' => $row->id]);
});
$table->foreign(['cart_address_id'])
->references('id')
->on('addresses')
->onDelete('cascade');
});
Schema::table('invoices', static function (Blueprint $table) {
$table->dropForeign(['order_address_id']);
OrderAddress::query()
->orderBy('id', 'asc') // for some reason each() needs an orderBy in before
->each(static function ($row) {
Invoice::query()
->where('order_address_id', $row->additional['old_order_address_id'])
->update(['order_address_id' => $row->id]);
});
$table->foreign(['order_address_id'])
->references('id')
->on('addresses')
->onDelete('cascade');
});
Schema::table('shipments', static function (Blueprint $table) {
$table->dropForeign(['order_address_id']);
OrderAddress::query()
->orderBy('id', 'asc') // for some reason each() needs an orderBy in before
->each(static function ($row) {
Shipment::query()
->where('order_address_id', $row->additional['old_order_address_id'])
->update(['order_address_id' => $row->id]);
});
$table->foreign(['order_address_id'])
->references('id')
->on('addresses')
->onDelete('cascade');
});
}
}

View File

@ -2,11 +2,16 @@
namespace Webkul\Core\Eloquent;
use Prettus\Repository\Contracts\CacheableInterface;
use Prettus\Repository\Eloquent\BaseRepository;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Container\Container as App;
use Prettus\Repository\Traits\CacheableRepository;
abstract class Repository extends BaseRepository {
abstract class Repository extends BaseRepository implements CacheableInterface {
use CacheableRepository;
/**
* Find data by field and value
@ -18,7 +23,7 @@ abstract class Repository extends BaseRepository {
*/
public function findOneByField($field, $value = null, $columns = ['*'])
{
$model = parent::findByField($field, $value, $columns = ['*']);
$model = $this->findByField($field, $value, $columns = ['*']);
return $model->first();
}
@ -33,7 +38,7 @@ abstract class Repository extends BaseRepository {
*/
public function findOneWhere(array $where, $columns = ['*'])
{
$model = parent::findWhere($where, $columns);
$model = $this->findWhere($where, $columns);
return $model->first();
}
@ -132,4 +137,4 @@ abstract class Repository extends BaseRepository {
{
return $this->model;
}
}
}

View File

@ -312,7 +312,7 @@ class Laravel5Helper extends Laravel5
'special_price_from' => null,
'special_price_to' => null,
'special_price' => null,
'price' => $faker->randomFloat(4, 1, 1000),
'price' => $faker->randomFloat(2, 1, 1000),
'weight' => '1.00', // necessary for shipping
'brand' => AttributeOption::firstWhere('attribute_id', $brand->id)->id,
];

View File

@ -0,0 +1,92 @@
<?php
namespace Webkul\Core\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Webkul\Customer\Models\Customer;
use Webkul\Core\Contracts\Address as AddressContract;
/**
* Class Address
* @package Webkul\Core\Models
*
* @property string $address_type
* @property integer $customer_id
* @property Customer $customer
* @property string $first_name
* @property string $last_name
* @property string $gender
* @property string $company_name
* @property string $address1
* @property string $address2
* @property string $postcode
* @property string $city
* @property string $state
* @property string $country
* @property string $email
* @property string $phone
* @property boolean $default_address
* @property array $additional
*
* @property-read integer $id
* @property-read string $name
* @property-read Carbon $created_at
* @property-read Carbon $updated_at
*
*/
abstract class Address extends Model implements AddressContract
{
protected $table = 'addresses';
protected $guarded = [
'id',
'created_at',
'updated_at',
];
protected $fillable = [
'address_type',
'customer_id',
'cart_id',
'order_id',
'first_name',
'last_name',
'gender',
'company_name',
'address1',
'address2',
'postcode',
'city',
'state',
'country',
'email',
'phone',
'default_address',
'vat_id',
'additional',
];
protected $casts = [
'additional' => 'array',
];
/**
* Get all of the attributes for the attribute groups.
*/
public function getNameAttribute(): string
{
return $this->first_name . ' ' . $this->last_name;
}
/**
* Get the customer record associated with the address.
*/
public function customer(): BelongsTo
{
return $this->belongsTo(Customer::class);
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace Webkul\Core\Models;
use Konekt\Concord\Proxies\ModelProxy;
class AddressProxy extends ModelProxy
{
}

View File

@ -7,8 +7,6 @@ use Webkul\Customer\Models\Customer;
use Webkul\Customer\Models\CustomerAddress;
$factory->define(CustomerAddress::class, function (Faker $faker) {
$now = date("Y-m-d H:i:s");
// use an locale from a country in europe so the vat id can be generated
$fakerIt = \Faker\Factory::create('it_IT');
@ -27,8 +25,7 @@ $factory->define(CustomerAddress::class, function (Faker $faker) {
'postcode' => $faker->postcode,
'phone' => $faker->e164PhoneNumber,
'default_address' => array_random([0, 1]),
'created_at' => $now,
'updated_at' => $now,
'address_type' => CustomerAddress::ADDRESS_TYPE,
];
});

View File

@ -3,6 +3,7 @@
namespace Webkul\Customer\Http\Controllers;
use Hash;
use Illuminate\Support\Facades\Event;
use Webkul\Customer\Repositories\CustomerRepository;
use Webkul\Product\Repositories\ProductReviewRepository;
@ -114,7 +115,12 @@ class CustomerController extends Controller
}
}
if ($this->customerRepository->update($data, $id)) {
Event::dispatch('customer.update.before');
if ($customer = $this->customerRepository->update($data, $id)) {
Event::dispatch('customer.update.after', $customer);
Session()->flash('success', trans('shop::app.customer.account.profile.edit-success'));
return redirect()->route($this->_config['redirect']);

View File

@ -2,34 +2,32 @@
namespace Webkul\Customer\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Webkul\Core\Models\Address;
use Webkul\Customer\Contracts\CustomerAddress as CustomerAddressContract;
class CustomerAddress extends Model implements CustomerAddressContract
class CustomerAddress extends Address implements CustomerAddressContract
{
protected $table = 'customer_addresses';
public const ADDRESS_TYPE = 'customer';
protected $fillable = [
'customer_id',
'company_name',
'vat_id',
'address1',
'address2',
'country',
'state',
'city',
'postcode',
'phone',
'default_address',
'first_name',
'last_name',
/**
* @var array default values
*/
protected $attributes = [
'address_type' => self::ADDRESS_TYPE,
];
/**
* Get the customer address full name.
* The "booted" method of the model.
*
* @return void
*/
public function getNameAttribute()
protected static function boot()
{
return $this->first_name . ' ' . $this->last_name;
static::addGlobalScope('address_type', static function (Builder $builder) {
$builder->where('address_type', self::ADDRESS_TYPE);
});
parent::boot();
}
}

View File

@ -145,14 +145,16 @@ class ProductRepository extends Repository
if (isset($params['sort'])) {
$attribute = $this->attributeRepository->findOneByField('code', $params['sort']);
if ($params['sort'] == 'price') {
if ($attribute->code == 'price') {
$qb->orderBy('min_price', $params['order']);
if ($attribute) {
if ($params['sort'] == 'price') {
if ($attribute->code == 'price') {
$qb->orderBy('min_price', $params['order']);
} else {
$qb->orderBy($attribute->code, $params['order']);
}
} else {
$qb->orderBy($attribute->code, $params['order']);
$qb->orderBy($params['sort'] == 'created_at' ? 'product_flat.created_at' : $attribute->code, $params['order']);
}
} else {
$qb->orderBy($params['sort'] == 'created_at' ? 'product_flat.created_at' : $attribute->code, $params['order']);
}
}
@ -262,7 +264,7 @@ class ProductRepository extends Repository
->where('product_flat.new', 1)
->where('product_flat.channel', $channel)
->where('product_flat.locale', $locale)
->orderBy('product_id', 'desc');
->inRandomOrder();
})->paginate(4);
return $results;
@ -287,7 +289,7 @@ class ProductRepository extends Repository
->where('product_flat.featured', 1)
->where('product_flat.channel', $channel)
->where('product_flat.locale', $locale)
->orderBy('product_id', 'desc');
->inRandomOrder();
})->paginate(4);
return $results;

View File

@ -397,6 +397,7 @@ class Configurable extends AbstractType
public function getPriceHtml()
{
return '<span class="price-label">' . trans('shop::app.products.price-label') . '</span>'
. ' '
. '<span class="final-price">' . core()->currency($this->getMinimalPrice()) . '</span>';
}
@ -523,7 +524,11 @@ class Configurable extends AbstractType
$product = $item->product;
}
} else {
$product = $item->child->product;
if ($item instanceof \Webkul\Customer\Contracts\CartItem) {
$product = $item->child->product;
} else {
$product = $item->product;
}
}
return $this->productImageHelper->getProductBaseImage($product);

View File

@ -147,6 +147,7 @@ class Grouped extends AbstractType
public function getPriceHtml()
{
return '<span class="price-label">' . trans('shop::app.products.starting-at') . '</span>'
. ' '
. '<span class="final-price">' . core()->currency($this->getMinimalPrice()) . '</span>';
}

View File

@ -10,7 +10,7 @@ use Webkul\Sales\Models\OrderAddress;
$factory->define(OrderAddress::class, function (Faker $faker) {
$customer = factory(Customer::class)->create();
$customerAddress = factory(CustomerAddress::class)->create();
$customerAddress = factory(CustomerAddress::class)->make();
return [
'first_name' => $customer->first_name,
@ -22,7 +22,7 @@ $factory->define(OrderAddress::class, function (Faker $faker) {
'city' => $customerAddress->city,
'postcode' => $customerAddress->postcode,
'phone' => $customerAddress->phone,
'address_type' => 'billing',
'address_type' => OrderAddress::ADDRESS_TYPE_BILLING,
'order_id' => function () {
return factory(Order::class)->create()->id;
},
@ -30,5 +30,5 @@ $factory->define(OrderAddress::class, function (Faker $faker) {
});
$factory->state(OrderAddress::class, 'shipping', [
'address_type' => 'shipping',
'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING,
]);

View File

@ -7,10 +7,14 @@ use Webkul\Product\Models\Product;
use Webkul\Sales\Models\Order;
use Webkul\Sales\Models\OrderItem;
$factory->define(OrderItem::class, function (Faker $faker) {
$factory->define(OrderItem::class, function (Faker $faker, array $attributes) {
$now = date("Y-m-d H:i:s");
$product = factory(Product::class, 'simple')->create();
if (isset($attributes['product_id'])) {
$product = Product::where('id', $attributes['product_id'])->first();
} else {
$product = factory(Product::class)->create();
}
return [
'sku' => $product->sku,

View File

@ -34,7 +34,8 @@ class Invoice extends Model implements InvoiceContract
/**
* Get the invoice items record associated with the invoice.
*/
public function items() {
public function items()
{
return $this->hasMany(InvoiceItemProxy::modelClass())->whereNull('parent_id');
}
@ -55,10 +56,11 @@ class Invoice extends Model implements InvoiceContract
}
/**
* Get the addresses for the shipment.
* Get the address for the invoice.
*/
public function address()
{
return $this->belongsTo(OrderAddressProxy::modelClass(), 'order_address_id');
return $this->belongsTo(OrderAddressProxy::modelClass(), 'order_address_id')
->where('address_type', OrderAddress::ADDRESS_TYPE_BILLING);
}
}

View File

@ -8,6 +8,14 @@ use Webkul\Sales\Contracts\Order as OrderContract;
class Order extends Model implements OrderContract
{
public const STATUS_PENDING = 'pending';
public const STATUS_PENDING_PAYMENT = 'pending_payment';
public const STATUS_PROCESSING = 'processing';
public const STATUS_COMPLETED = 'completed';
public const STATUS_CANCELED = 'canceled';
public const STATUS_CLOSED = 'closed';
public const STATUS_FRAUD = 'fraud';
protected $guarded = [
'id',
'items',
@ -21,13 +29,13 @@ class Order extends Model implements OrderContract
];
protected $statusLabel = [
'pending' => 'Pending',
'pending_payment' => 'Pending Payment',
'processing' => 'Processing',
'completed' => 'Completed',
'canceled' => 'Canceled',
'closed' => 'Closed',
'fraud' => 'Fraud',
self::STATUS_PENDING => 'Pending',
self::STATUS_PENDING_PAYMENT => 'Pending Payment',
self::STATUS_PROCESSING => 'Processing',
self::STATUS_COMPLETED => 'Completed',
self::STATUS_CANCELED => 'Canceled',
self::STATUS_CLOSED => 'Closed',
self::STATUS_FRAUD => 'Fraud',
];
/**
@ -147,7 +155,7 @@ class Order extends Model implements OrderContract
*/
public function billing_address()
{
return $this->addresses()->where('address_type', 'billing');
return $this->addresses()->where('address_type', OrderAddress::ADDRESS_TYPE_BILLING);
}
/**
@ -163,7 +171,7 @@ class Order extends Model implements OrderContract
*/
public function shipping_address()
{
return $this->addresses()->where('address_type', 'shipping');
return $this->addresses()->where('address_type', OrderAddress::ADDRESS_TYPE_SHIPPING);
}
/**
@ -187,7 +195,7 @@ class Order extends Model implements OrderContract
*
* @return boolean
*/
public function haveStockableItems()
public function haveStockableItems(): bool
{
foreach ($this->items as $item) {
if ($item->getTypeInstance()->isStockable()) {
@ -200,10 +208,12 @@ class Order extends Model implements OrderContract
/**
* Checks if new shipment is allow or not
*
* @return bool
*/
public function canShip()
public function canShip(): bool
{
if ($this->status == 'fraud') {
if ($this->status === self::STATUS_FRAUD) {
return false;
}
@ -218,10 +228,12 @@ class Order extends Model implements OrderContract
/**
* Checks if new invoice is allow or not
*
* @return bool
*/
public function canInvoice()
public function canInvoice(): bool
{
if ($this->status == 'fraud') {
if ($this->status === self::STATUS_FRAUD) {
return false;
}
@ -236,10 +248,12 @@ class Order extends Model implements OrderContract
/**
* Checks if order can be canceled or not
*
* @return bool
*/
public function canCancel()
public function canCancel(): bool
{
if ($this->status == 'fraud') {
if ($this->status === self::STATUS_FRAUD) {
return false;
}
@ -254,10 +268,12 @@ class Order extends Model implements OrderContract
/**
* Checks if order can be refunded or not
*
* @return bool
*/
public function canRefund()
public function canRefund(): bool
{
if ($this->status == 'fraud') {
if ($this->status === self::STATUS_FRAUD) {
return false;
}

View File

@ -2,47 +2,64 @@
namespace Webkul\Sales\Models;
use Illuminate\Database\Eloquent\Model;
use Webkul\Customer\Models\Customer;
use Webkul\Checkout\Models\CartAddress;
use Webkul\Core\Models\Address;
use Webkul\Sales\Contracts\OrderAddress as OrderAddressContract;
use Illuminate\Database\Eloquent\Builder;
class OrderAddress extends Model implements OrderAddressContract
/**
* Class OrderAddress
* @package Webkul\Sales\Models
*
* @property integer $order_id
* @property Order $order
*
*/
class OrderAddress extends Address implements OrderAddressContract
{
protected $table = 'order_address';
public const ADDRESS_TYPE_SHIPPING = 'order_shipping';
public const ADDRESS_TYPE_BILLING = 'order_billing';
protected $guarded = ['id', 'created_at', 'updated_at'];
protected $fillable = [
'first_name',
'last_name',
'email',
'company_name',
'vat_id',
'address1',
'address2',
'city',
'state',
'postcode',
'country',
'phone',
'address_type',
'cart_id',
'customer_id',
/**
* @var array default values
*/
protected $attributes = [
'address_type' => self::ADDRESS_TYPE_BILLING,
];
/**
* Get of the customer fullname.
* The "booted" method of the model.
*
* @return void
*/
public function getNameAttribute()
protected static function boot()
{
return $this->first_name . ' ' . $this->last_name;
static::addGlobalScope('address_type', function (Builder $builder) {
$builder->whereIn('address_type', [
self::ADDRESS_TYPE_BILLING,
self::ADDRESS_TYPE_SHIPPING
]);
});
static::creating(static function ($address) {
switch ($address->address_type) {
case CartAddress::ADDRESS_TYPE_BILLING:
$address->address_type = self::ADDRESS_TYPE_BILLING;
break;
case CartAddress::ADDRESS_TYPE_SHIPPING:
$address->address_type = self::ADDRESS_TYPE_SHIPPING;
break;
}
});
parent::boot();
}
/**
* Get the customer record associated with the order.
* Get the order record associated with the address.
*/
public function customer()
public function order()
{
return $this->belongsTo(Customer::class);
return $this->belongsTo(Order::class);
}
}

View File

@ -47,10 +47,11 @@ class Shipment extends Model implements ShipmentContract
}
/**
* Get the addresses for the shipment.
* Get the address for the shipment.
*/
public function address()
{
return $this->belongsTo(OrderAddressProxy::modelClass(), 'order_address_id');
return $this->belongsTo(OrderAddressProxy::modelClass(), 'order_address_id')
->where('address_type', OrderAddress::ADDRESS_TYPE_SHIPPING);
}
}

View File

@ -23,7 +23,7 @@ class FlatRate extends AbstractShipping
/**
* Returns rate for flatrate
*
* @return array
* @return CartShippingRate|false
*/
public function calculate()
{

View File

@ -22,7 +22,7 @@ class Free extends AbstractShipping
/**
* Returns rate for flatrate
*
* @return array
* @return CartShippingRate|false
*/
public function calculate()
{

View File

@ -2,6 +2,7 @@
namespace Webkul\Shop\Http\Controllers;
use Illuminate\Support\Facades\Event;
use Webkul\Shop\Http\Controllers\Controller;
use Webkul\Checkout\Facades\Cart;
use Webkul\Shipping\Facades\Shipping;
@ -21,7 +22,7 @@ class OnepageController extends Controller
/**
* customerRepository instance object
*
*
* @var \Webkul\Customer\Repositories\CustomerRepository
*/
protected $customerRepository;
@ -52,6 +53,8 @@ class OnepageController extends Controller
*/
public function index()
{
Event::dispatch('checkout.load.index');
if (! auth()->guard('customer')->check()
&& ! core()->getConfigData('catalog.products.guest-checkout.allow-guest-checkout')) {
return redirect()->route('customer.session.index');

View File

@ -0,0 +1,616 @@
<?php
return [
'security-warning' => 'セキュリティの警告',
'nothing-to-delete' => '削除するアイテムはありません',
'layouts' => [
'my-account' => 'マイアカウント',
'profile' => 'プロフィール',
'address' => 'アドレス',
'reviews' => 'レビュー',
'wishlist' => 'お気に入り',
'orders' => '注文',
'downloadable-products' => 'ダウンロードアイテム'
],
'common' => [
'error' => 'エラーが発生しました。しばらく待ってから、再度アクセスしてください。'
],
'home' => [
'page-title' => config('app.name') . ' - ホーム',
'featured-products' => 'おすすめ',
'new-products' => 'New',
'verify-email' => 'メールアドレスを確認します',
'resend-verify-email' => '確認メールを再送信'
],
'header' => [
'title' => 'アカウント',
'dropdown-text' => 'カート、注文、お気に入りの管理',
'sign-in' => 'ログイン',
'sign-up' => 'アカウント登録',
'account' => 'アカウント',
'cart' => 'カート',
'profile' => 'プロフィール',
'wishlist' => 'お気に入り',
'logout' => 'ログアウト',
'search-text' => 'アイテムを探す'
],
'minicart' => [
'view-cart' => 'カートを見る',
'checkout' => 'レジへ進む',
'cart' => 'カート',
'zero' => '0'
],
'footer' => [
'subscribe-newsletter' => 'メルマガ登録',
'subscribe' => '登録',
'locale' => '言語',
'currency' => '通貨',
],
'subscription' => [
'unsubscribe' => '退会',
'subscribe' => '登録',
'subscribed' => 'メルマガ登録が完了しました',
'not-subscribed' => 'メルマガ登録ができません。しばらく待ってから、再度お試しください。',
'already' => '既にメルマガ登録済です',
'unsubscribed' => '退会しました',
'already-unsub' => '既に退会済です',
'not-subscribed' => 'メールを送信できませんでした。しばらくしてから再度お試しください。'
],
'search' => [
'no-results' => 'お探しの条件に合う検索結果が見つかりませんでした。',
'page-title' => '検索',
'found-results' => '検索結果',
'found-result' => '検索結果'
],
'reviews' => [
'title' => 'レビュー',
'add-review-page-title' => 'レビューを書く',
'write-review' => 'レビューを書く',
'review-title' => 'タイトル',
'product-review-page-title' => 'アイテムのレビュー',
'rating-reviews' => '評価と意見',
'submit' => '送信',
'delete-all' => '全て削除します',
'ratingreviews' => ':rating 評価 & :review レビュー',
'star' => '星',
'percentage' => ':percentage %',
'id-star' => '星',
'name' => '名前'
],
'customer' => [
'signup-text' => [
'account_exists' => '既に登録されております',
'title' => 'アカウント登録'
],
'signup-form' => [
'page-title' => 'アカウント登録',
'title' => 'アカウント登録',
'firstname' => '名',
'lastname' => '姓',
'email' => 'メールアドレス',
'password' => 'パスワード',
'confirm_pass' => 'パスワードを確認',
'button_title' => '登録',
'agree' => '同意',
'terms' => '規約',
'conditions' => '条件',
'using' => 'by using this website',
'agreement' => '承諾',
'success' => 'アカウントが登録されました',
'success-verify' => 'アカウント登録完了の確認メールが送信されました',
'success-verify-email-unsent' => 'アカウント登録が完了されましたが、確認メールが送信ができませんでした',
'failed' => 'アカウント登録ができませんでした しばらくしてから、再度お試しください',
'already-verified' => '既にアカウントをお持ちです 確認メールを再度送信してください',
'verification-not-sent' => '確認メールの送信中に問題が発生しました しばらくしてから、再度お試しください',
'verification-sent' => '確認メールが送信されました',
'verified' => 'アカウント登録が完了しました ログインしてください',
'verify-failed' => 'メールアドレスの確認ができませんでした',
'dont-have-account' => 'アカウント登録がされていません',
'customer-registration' => 'アカウント登録'
],
'login-text' => [
'no_account' => 'アカウントがありません',
'title' => '新規アカウント登録',
],
'login-form' => [
'page-title' => 'ログイン',
'title' => 'ログイン',
'email' => 'メールアドレス',
'password' => 'パスワード',
'forgot_pass' => 'パスワードをお忘れですか',
'button_title' => 'ログイン',
'remember' => 'ログイン状態を保持する',
'footer' => '© Copyright :year Webkul Software, All rights reserved',
'invalid-creds' => 'ログイン情報を確認してください',
'verify-first' => 'メールアドレスを認証してください',
'not-activated' => 'このアカウントは管理者の認証が出来次第、有効になります',
'resend-verification' => 'アカウント確認メールが再送信'
],
'forgot-password' => [
'title' => 'パスワードの再発行',
'email' => 'メールアドレス',
'submit' => 'パスワード再発行メールを送信',
'page_title' => 'パスワードの再発行'
],
'reset-password' => [
'title' => 'パスワードを再発行',
'email' => '登録メールアドレス',
'password' => 'パスワード',
'confirm-password' => 'パスワード確認',
'back-link-title' => '戻る',
'submit-btn-title' => 'パスワードをリセット'
],
'account' => [
'dashboard' => 'プロフィールを編集',
'menu' => 'メニュー',
'profile' => [
'index' => [
'page-title' => 'プロフィール',
'title' => 'プロフィール',
'edit' => '編集',
],
'edit-success' => 'プロフィールが更新されました',
'edit-fail' => 'プロフィールを更新できませんでした しばらくしてから再度お試しください。',
'unmatch' => 'パスワードが一致しません',
'fname' => '名',
'lname' => '姓',
'gender' => '性別',
'other' => 'その他',
'male' => '男性',
'female' => '女性',
'dob' => '生年月日',
'phone' => '電話番号',
'email' => 'メールアドレス',
'opassword' => '前のパスワード',
'password' => 'パスワード',
'cpassword' => 'パスワード確認',
'submit' => '保存する',
'edit-profile' => [
'title' => 'プロフィールの編集',
'page-title' => 'プロフィールの編集'
]
],
'address' => [
'index' => [
'page-title' => '住所',
'title' => '住所',
'add' => '住所を追加',
'edit' => '編集',
'empty' => '住所が登録されておりません 下のリンクから作成してください',
'create' => '住所を作成',
'delete' => '削除',
'make-default' => '既定の住所に設定',
'default' => '既定の住所',
'contact' => '連絡先',
'confirm-delete' => 'この住所を削除しますか?',
'default-delete' => '既定の住所の削除ができません',
'enter-password' => 'パスワードを入力してください',
],
'create' => [
'page-title' => '新規住所登録',
'title' => '住所を追加',
'street-address' => '住所',
'country' => '国',
'state' => '都道府県',
'select-state' => '都道府県を選択してください',
'city' => '市町村',
'postcode' => '郵便番号',
'phone' => '電話番号',
'submit' => '保存する',
'success' => '住所が保存されました',
'error' => '住所の保存に失敗しました。'
],
'edit' => [
'page-title' => '住所を編集',
'title' => '住所を編集',
'street-address' => '住所',
'submit' => '保存する',
'success' => '住所が更新されました',
],
'delete' => [
'success' => '住所が削除されました',
'failure' => '住所の削除に失敗しました。',
'wrong-password' => 'パスワードが正しくありません'
]
],
'order' => [
'index' => [
'page-title' => '注文一覧',
'title' => '注文一覧',
'order_id' => '注文ID',
'date' => '日時',
'status' => '状況',
'total' => '合計',
'order_number' => '注文番号'
],
'view' => [
'page-tile' => '注文 #:order_id',
'info' => '詳細',
'placed-on' => '日時',
'products-ordered' => '注文内容',
'invoices' => '領収書',
'shipments' => '発送',
'SKU' => 'SKU',
'product-name' => 'アイテム番号',
'qty' => '数',
'item-status' => 'アイテム状況',
'item-ordered' => '注文完了 (:qty_ordered)',
'item-invoice' => '領収書発行済 (:qty_invoiced)',
'item-shipped' => '発送済 (:qty_shipped)',
'item-canceled' => 'キャンセル済 (:qty_canceled)',
'price' => '価格',
'total' => '合計',
'subtotal' => '小計',
'shipping-handling' => '送料',
'tax' => '消費税',
'discount' => '割引',
'tax-percent' => '消費税割合',
'tax-amount' => '消費税',
'discount-amount' => '割引',
'grand-total' => '合計',
'total-paid' => '合計金額',
'total-refunded' => '返金額',
'total-due' => '合計',
'shipping-address' => '送付先',
'billing-address' => '領収書宛先',
'shipping-method' => '配送方法',
'payment-method' => '支払い方法',
'individual-invoice' => '領収書 #:invoice_id',
'individual-shipment' => '出荷 #:shipment_id',
'print' => '印刷',
'invoice-id' => '領収書番号',
'order-id' => '注文番号',
'order-date' => '注文日',
'bill-to' => '請求先',
'ship-to' => '送り先',
'contact' => '連絡先',
'refunds' => '返金',
'individual-refund' => '返金 #:refund_id',
'adjustment-refund' => '返金調整',
'adjustment-fee' => '調整手数料',
]
],
'wishlist' => [
'page-title' => 'お気に入り',
'title' => 'お気に入り',
'deleteall' => '全て削除',
'moveall' => '全てのアイテムをカートへ移動する',
'move-to-cart' => 'カートへ移動',
'error' => 'アイテムのお気に入り追加に失敗しました。しばらくしてから再度お試し下さい。',
'add' => 'アイテムをお気に入りに追加',
'remove' => 'アイテムをお気に入りから削除',
'moved' => 'アイテムをカートへ移動しました',
'move-error' => 'アイテムのお気に入り追加に失敗しました。しばらくしてから再度お試し下さい。',
'success' => 'アイテムをお気に入りに追加しました',
'failure' => 'アイテムのお気に入り追加に失敗しました。しばらくしてから再度お試し下さい。',
'already' => 'このアイテムは既にお気に入りに追加されています。',
'removed' => 'アイテムはお気に入りから削除されました。',
'remove-fail' => 'アイテムをお気に入りから削除することができませんでした。しばらくしてから再度お試し下さい。',
'empty' => 'お気に入りにアイテムがありません。',
'remove-all-success' => '全てのアイテムがお気に入りから削除されました。',
],
'downloadable_products' => [
'title' => 'ダウンロードアイテム',
'order-id' => '注文番号',
'date' => '日時',
'name' => 'アイテム名',
'status' => 'ステータス',
'pending' => '処理中',
'available' => 'ダウンロード可能',
'expired' => '期限切れ',
'remaining-downloads' => '残りのダウンロード数',
'unlimited' => '無制限',
'download-error' => 'ダウンロードリンクの有効期限が切れています.'
],
'review' => [
'index' => [
'title' => 'レビュー',
'page-title' => 'レビュー'
],
'view' => [
'page-tile' => 'レビュー #:id',
]
]
]
],
'products' => [
'layered-nav-title' => 'Shop By',
'price-label' => 'As low as',
'remove-filter-link-title' => '全て削除',
'sort-by' => '並び順',
'from-a-z' => 'From A-Z',
'from-z-a' => 'From Z-A',
'newest-first' => '新着順',
'oldest-first' => '古い順',
'cheapest-first' => '価格が安い順',
'expensive-first' => '価格が高い順',
'show' => 'Show',
'pager-info' => ':showing - :total',
'description' => '解説',
'specification' => '仕様',
'total-reviews' => ':全てのレビュー',
'total-rating' => ':total_rating Ratings & :total_reviews Reviews',
'by' => 'By :name',
'up-sell-title' => 'お客様におすすめのアイテム',
'related-product-title' => '関連アイテム',
'cross-sell-title' => 'Más opciones',
'reviews-title' => 'レビュー',
'write-review-btn' => '評価を書いてください',
'choose-option' => 'オプションを選択',
'sale' => 'セール',
'new' => 'new',
'empty' => 'このカテゴリーにアイテムがありません。',
'add-to-cart' => 'カートに追加する',
'buy-now' => '今すぐ購入',
'whoops' => 'すみません!',
'quantity' => '数量',
'in-stock' => '在庫あり',
'out-of-stock' => '在庫なし',
'view-all' => '全て見る',
'select-above-options' => '最初に上記のオプションを選択してください.',
'less-quantity' => '数量1未満は選択できません.'
],
'buynow' => [
'no-options' => 'このアイテムを購入される前にオプションを選択してください'
],
'checkout' => [
'cart' => [
'integrity' => [
'missing_fields' =>'赤くなった項目を入力してください',
'missing_options' => 'Options are missing for this product.',
'missing_links' => 'Downloadable links are missing for this product.',
'qty_missing' => 'Atleast one product should have more than 1 quantity.',
'qty_impossible' => 'Cannot add more than one of these products to cart.'
],
'create-error' => 'カートで問題が発生しました',
'title' => 'カート',
'empty' => 'カートが空です。',
'update-cart' => 'カートを更新する',
'continue-shopping' => '買い物を続ける',
'proceed-to-checkout' => '購入手続きに進む',
'remove' => '削除',
'remove-link' => '削除',
'move-to-wishlist' => 'お気に入りに移動する',
'move-to-wishlist-success' => 'アイテムがお気に入りに追加されました。',
'move-to-wishlist-error' => 'アイテムをお気に入りに追加することができませんでした。しばらくしてから再度お試し下さい。',
'add-config-warning' => 'カートに追加する前にオプションを選択してください',
'quantity' => [
'quantity' => '数量',
'success' => 'カートが更新されました。',
'illegal' => '数量を1以下にすることは出来ません。',
'inventory_warning' => 'ご希望の数量の在庫が現在ございません。しばらくしてから再度お試し下さい。現在在庫がございません。',
'error' => 'アイテムの更新が出来ませんでした。しばらくしてから再度お試し下さい。'
],
'item' => [
'error_remove' => 'カートに削除するアイテムがございません。',
'success' => 'アイテムがカートに追加されました。',
'success-remove' => 'アイテムがカートから削除されました。',
'error-add' => 'アイテムをカートに追加できません。しばらくしてから再度お試し下さい。',
],
'quantity-error' => 'ご希望の数量の在庫が現在ございません。',
'cart-subtotal' => '小計',
'cart-remove-action' => '手続きを進めますか。',
'partial-cart-update' => 'Only some of the product(s) were updated',
'link-missing' => ''
],
'onepage' => [
'title' => 'レジ',
'information' => '詳細',
'shipping' => '発送',
'payment' => '支払い',
'complete' => '完了',
'billing-address' => '領収書宛先',
'sign-in' => 'ログイン',
'first-name' => '名',
'last-name' => '姓',
'email' => 'メールアドレス',
'address1' => '住所',
'city' => '市町村',
'state' => '都道府県',
'select-state' => '地域を選択 都道府県 市町村',
'postcode' => '郵便番号',
'phone' => '電話番号',
'country' => '国',
'order-summary' => '注文内容',
'shipping-address' => '送付先住所',
'use_for_shipping' => 'この住所に送る',
'continue' => '続ける',
'shipping-method' => '発送方法を選択',
'payment-methods' => '支払い方法を選択',
'payment-method' => '支払い方法',
'summary' => '注文内容',
'price' => '金額',
'quantity' => '数量',
'billing-address' => '領収書宛先',
'shipping-address' => '送付先',
'contact' => '連絡先',
'place-order' => '注文を確定する',
'new-address' => '新しい住所を追加する',
'save_as_address' => '住所を保存',
'apply-coupon' => 'クーポンを使用する',
'amt-payable' => 'お支払い金額',
'got' => 'Got',
'free' => '無料',
'coupon-used' => '使用済クーポン',
'applied' => '適用されました',
'back' => '戻る',
'cash-desc' => '現金支払い',
'money-desc' => '銀行振り込み',
'paypal-desc' => 'Paypal',
'free-desc' => '送料無料',
'flat-desc' => '送料一律'
],
'total' => [
'order-summary' => '注文を確定する',
'sub-total' => 'アイテム',
'grand-total' => '合計',
'delivery-charges' => '送料',
'tax' => '税',
'discount' => '割引',
'price' => '金額',
'disc-amount' => '割引額',
'new-grand-total' => '合計',
'coupon' => 'クーポン',
'coupon-applied' => '使用済みクーポン',
'remove-coupon' => 'クーポンを削除',
'cannot-apply-coupon' => 'クーポンを使用することができません'
],
'success' => [
'title' => '注文が正しく完了しました',
'thanks' => 'ご注文ありがとうございます',
'order-id-info' => 'お客様の注文番号 #:order_id',
'info' => 'お客様のご注文詳細と追跡情報をメールアドレスに送ります'
]
],
'mail' => [
'order' => [
'subject' => 'ご注文ありがとうございます',
'heading' => 'ご注文の受付が完了しました。',
'dear' => ':customer_name様',
'dear-admin' => ':admin_name様',
'greeting' => 'この度は当ショップでお買い物いただきありがとうございます。 お客様注文番号 :order_id',
'greeting-admin' => '注文番号 :order_id placed on :created_at',
'summary' => '注文内容',
'shipping-address' => '送付先住所',
'billing-address' => '領収書宛先',
'contact' => '連絡先',
'shipping' => '配送方法',
'payment' => '支払い方法',
'price' => '金額',
'quantity' => '数量',
'subtotal' => '小計',
'shipping-handling' => '送料',
'tax' => '税',
'discount' => '割引',
'grand-total' => '合計',
'final-summary' => '発送手続き完了後、お知らせメールを配信いたしますので、今しばらくお待ちください。',
'help' => 'お問合せなどは下記メールアドレスへご連絡ください。:support_email',
'thanks' => 'Gracias!',
'cancel' => [
'subject' => '注文がキャンセルされました',
'heading' => '注文がキャンセルされました',
'dear' => ':customer_name様',
'greeting' => '注文 #:order_idはキャンセルされました。',
'summary' => '注文内容',
'shipping-address' => '送付先住所',
'billing-address' => '領収書宛先',
'contact' => '連絡先',
'shipping' => '配送方法',
'payment' => '支払い方法',
'subtotal' => '小計',
'shipping-handling' => '送料',
'tax' => '税',
'discount' => '割引',
'grand-total' => '合計',
'final-summary' => '私たちのお店にお越しいただき、ありがとうございます。',
'help' => 'お問合せなどは下記メールアドレスへご連絡ください。 :support_email',
'thanks' => 'Gracias!',
]
],
'invoice' => [
'heading' => '注文 #:order_idの領収書 #:invoice_id',
'subject' => '注文 #:order_idの領収書',
'summary' => '注文内容',
],
'shipment' => [
'heading' => 'El Envío #:shipment_id ha sido generado por el pedido #:order_id',
'inventory-heading' => 'Nuevo envío #:shipment_id ha sido generado por el pedido #:order_id',
'subject' => 'Envío de tu pedido #:order_id',
'inventory-subject' => 'Nuevo envío ha sido generado por el pedido #:order_id',
'summary' => '注文内容',
'carrier' => '配送業者',
'tracking-number' => '追跡番号',
'greeting' => 'El pedido :order_id ha sido enviado a :created_at',
],
'forget-password' => [
'subject' => 'パスワードをリセットする',
'dear' => '様 :name',
'info' => 'お客様のパスワードリセットのリクエストがあったため、ご連絡致します。',
'reset-password' => 'パスワードのリセット',
'final-summary' => 'Si no has solicitado cambiar de contraseña, ninguna acción es requerida por tu parte.',
'thanks' => 'ありがとうございます。'
],
'customer' => [
'new' => [
'dear' => '様 :customer_name',
'username-email' => 'Nombre de usuario/Email',
'subject' => 'Nuevo registro de cliente',
'password' => 'パスワード',
'summary' => 'Tu cuenta ha sido creada en Bassar.
Los detalles de tu cuenta puedes verlos abajo: ',
'thanks' => 'ありがとうございます。',
],
'registration' => [
'subject' => 'Nuevo registro de cliente',
'customer-registration' => 'Cliente registrado exitosamente',
'dear' => '様 :customer_name',
'greeting' => '¡Bienvenido y gracias por registrarte en Bassar!',
'summary' => 'Your account has now been created successfully and you can login using your email address and password credentials. Upon logging in, you will be able to access other services including reviewing past orders, wishlists and editing your account information.',
'thanks' => 'ありがとうございます。',
],
'verification' => [
'heading' => 'Bassar - Verificación por correo',
'subject' => 'メールでの確認',
'verify' => 'アカウント確認',
'summary' => 'このメールは、ご本人様確認のためにお送りしています。下記のリンクからアカウント確認をお願いします。'
],
'subscription' => [
'subject' => 'Subscripción mail',
'greeting' => ' Bienvenido a Bassar - Subscripción por mail',
'unsubscribe' => 'Darse de baja',
'summary' => 'Gracias por ponernos en tu bandeja de entrada. Ha pasado un tiempo desde que leyó el último correo electrónico de Bassar, y no queremos abrumar su bandeja de entrada. Si ya no quiere recibir
las últimas noticias de marketing, haga clic en el botón de abajo.'
]
]
],
'webkul' => [
'copy-right' => '© Copyright :year Webkul Software, All rights reserved',
],
'response' => [
'create-success' => ':name created successfully.',
'update-success' => ':name updated successfully.',
'delete-success' => ':name deleted successfully.',
'submit-success' => ':name submitted successfully.'
],
];

View File

@ -161,6 +161,26 @@
</span>
</div>
<div class="control-group" :class="[errors.has('address-form.billing[country]') ? 'has-error' : '']">
<label for="billing[country]" class="required">
{{ __('shop::app.checkout.onepage.country') }}
</label>
<select type="text" v-validate="'required'" class="control" id="billing[country]" name="billing[country]" v-model="address.billing.country" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.country') }}&quot;">
<option value=""></option>
@foreach (core()->countries() as $country)
<option value="{{ $country->code }}">{{ $country->name }}</option>
@endforeach
</select>
<span class="control-error" v-if="errors.has('address-form.billing[country]')">
@{{ errors.first('address-form.billing[country]') }}
</span>
</div>
<div class="control-group" :class="[errors.has('address-form.billing[state]') ? 'has-error' : '']">
<label for="billing[state]" class="required">
{{ __('shop::app.checkout.onepage.state') }}
@ -195,26 +215,6 @@
</span>
</div>
<div class="control-group" :class="[errors.has('address-form.billing[country]') ? 'has-error' : '']">
<label for="billing[country]" class="required">
{{ __('shop::app.checkout.onepage.country') }}
</label>
<select type="text" v-validate="'required'" class="control" id="billing[country]" name="billing[country]" v-model="address.billing.country" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.country') }}&quot;">
<option value=""></option>
@foreach (core()->countries() as $country)
<option value="{{ $country->code }}">{{ $country->name }}</option>
@endforeach
</select>
<span class="control-error" v-if="errors.has('address-form.billing[country]')">
@{{ errors.first('address-form.billing[country]') }}
</span>
</div>
<div class="control-group" :class="[errors.has('address-form.billing[phone]') ? 'has-error' : '']">
<label for="billing[phone]" class="required">
{{ __('shop::app.checkout.onepage.phone') }}
@ -386,6 +386,24 @@
</span>
</div>
<div class="control-group" :class="[errors.has('address-form.shipping[country]') ? 'has-error' : '']">
<label for="shipping[country]" class="required">
{{ __('shop::app.checkout.onepage.country') }}
</label>
<select type="text" v-validate="'required'" class="control" id="shipping[country]" name="shipping[country]" v-model="address.shipping.country" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.country') }}&quot;">
<option value=""></option>
@foreach (core()->countries() as $country)
<option value="{{ $country->code }}">{{ $country->name }}</option>
@endforeach
</select>
<span class="control-error" v-if="errors.has('address-form.shipping[country]')">
@{{ errors.first('address-form.shipping[country]') }}
</span>
</div>
<div class="control-group" :class="[errors.has('address-form.shipping[state]') ? 'has-error' : '']">
<label for="shipping[state]" class="required">
{{ __('shop::app.checkout.onepage.state') }}
@ -421,24 +439,6 @@
</span>
</div>
<div class="control-group" :class="[errors.has('address-form.shipping[country]') ? 'has-error' : '']">
<label for="shipping[country]" class="required">
{{ __('shop::app.checkout.onepage.country') }}
</label>
<select type="text" v-validate="'required'" class="control" id="shipping[country]" name="shipping[country]" v-model="address.shipping.country" data-vv-as="&quot;{{ __('shop::app.checkout.onepage.country') }}&quot;">
<option value=""></option>
@foreach (core()->countries() as $country)
<option value="{{ $country->code }}">{{ $country->name }}</option>
@endforeach
</select>
<span class="control-error" v-if="errors.has('address-form.shipping[country]')">
@{{ errors.first('address-form.shipping[country]') }}
</span>
</div>
<div class="control-group" :class="[errors.has('address-form.shipping[phone]') ? 'has-error' : '']">
<label for="shipping[phone]" class="required">
{{ __('shop::app.checkout.onepage.phone') }}

View File

@ -38,28 +38,28 @@
<td>{{ $customer->first_name }}</td>
</tr>
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.first_name.after') !!}
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.first_name.after', ['customer' => $customer]) !!}
<tr>
<td>{{ __('shop::app.customer.account.profile.lname') }}</td>
<td>{{ $customer->last_name }}</td>
</tr>
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.last_name.after') !!}
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.last_name.after', ['customer' => $customer]) !!}
<tr>
<td>{{ __('shop::app.customer.account.profile.gender') }}</td>
<td>{{ $customer->gender }}</td>
<td>{{ __($customer->gender) }}</td>
</tr>
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.gender.after') !!}
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.gender.after', ['customer' => $customer]) !!}
<tr>
<td>{{ __('shop::app.customer.account.profile.dob') }}</td>
<td>{{ $customer->date_of_birth }}</td>
</tr>
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.date_of_birth.after') !!}
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.date_of_birth.after', ['customer' => $customer]) !!}
<tr>
<td>{{ __('shop::app.customer.account.profile.email') }}</td>

View File

@ -6,11 +6,14 @@
<?php
$filterAttributes = [];
$maxPrice = 0;
if (isset($category)) {
$products = $productRepository->getAll($category->id);
$filterAttributes = $productFlatRepository->getFilterableAttributes($category, $products);
$maxPrice = core()->convertPrice($productFlatRepository->getCategoryProductMaximumPrice($category));
}
if (! count($filterAttributes) > 0) {
@ -161,7 +164,7 @@
props: ['index', 'attribute', 'appliedFilterValues'],
data: function() {
let maxPrice = '{{ core()->convertPrice($productFlatRepository->getCategoryProductMaximumPrice($category)) }}';
let maxPrice = @json($maxPrice);
maxPrice = maxPrice ? ((parseInt(maxPrice) !== 0 || maxPrice) ? parseInt(maxPrice) : 500) : 500;

View File

@ -7,9 +7,6 @@ use Webkul\Tax\Models\TaxCategory;
$factory->define(TaxCategory::class, function (Faker $faker) {
return [
'channel_id' => function () {
return core()->getCurrentChannel()->id;
},
'code' => $faker->uuid,
'name' => $faker->words(2, true),
'description' => $faker->sentence(10),

View File

@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class RemoveChannelFromTaxCategory extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('tax_categories', function (Blueprint $table) {
$table->dropForeign('tax_categories_channel_id_foreign');
$table->dropColumn('channel_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('tax_categories', function (Blueprint $table) {
$table->integer('channel_id')->unsigned()->after('id');
$table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
});
}
}

View File

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

View File

@ -68,7 +68,6 @@ class TaxCategoryController extends Controller
$data = request()->input();
$this->validate(request(), [
'channel_id' => 'required|numeric',
'code' => 'required|string|unique:tax_categories,code',
'name' => 'required|string',
'description' => 'required|string',
@ -111,7 +110,6 @@ class TaxCategoryController extends Controller
public function update($id)
{
$this->validate(request(), [
'channel_id' => 'required|numeric',
'code' => 'required|string|unique:tax_categories,code,' . $id,
'name' => 'required|string',
'description' => 'required|string',

View File

@ -16,7 +16,6 @@ class TaxCategory extends Model implements TaxCategoryContract
protected $table = 'tax_categories';
protected $fillable = [
'channel_id',
'code',
'name',
'description',

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=08fbd43328947b542230",
"/js/velocity.js": "/js/velocity.js?id=262ea9133f92cd60ee3e",
"/css/velocity-admin.css": "/css/velocity-admin.css?id=612d35e452446366eef7",
"/css/velocity.css": "/css/velocity.css?id=ff0f7ac77c597ee277cb"
"/css/velocity.css": "/css/velocity.css?id=2b9d7cbacb1f71e9f110"
}

View File

@ -130,7 +130,12 @@ class ContentRepository extends Repository
$query = $this->model::orderBy('position', 'ASC');
$contentCollection = $query
->select('velocity_contents.*', 'velocity_contents_translations.*')
->select(
'velocity_contents.content_type',
'velocity_contents_translations.title as title',
'velocity_contents_translations.page_link as page_link',
'velocity_contents_translations.link_target as link_target'
)
->where('velocity_contents.status', 1)
->leftJoin('velocity_contents_translations', 'velocity_contents.id', 'velocity_contents_translations.content_id')
->distinct('velocity_contents_translations.id')

View File

@ -4,6 +4,7 @@ namespace Webkul\Velocity\Repositories\Product;
use Webkul\Core\Eloquent\Repository;
use Illuminate\Container\Container as App;
use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Repositories\ProductFlatRepository;
use Webkul\Attribute\Repositories\AttributeRepository;

View File

@ -11,14 +11,13 @@ window.jQuery = window.$ = require("jquery");
window.BootstrapSass = require("bootstrap-sass");
Vue.use(VueToast);
Vue.use(VeeValidate);
Vue.use(VueCarousel);
Vue.use(BootstrapSass);
Vue.prototype.$http = axios;
Vue.use(VeeValidate, {
dictionary: {
ar: { messages: messagesAr }
ar: messagesAr
}
});

View File

@ -532,6 +532,21 @@
}
}
}
.arrow {
&.left,
&.right {
display: none
}
}
.thumb-list {
.thumb-frame {
> .bg-image {
background-size: contain;
}
}
}
}
.review-page-container {

View File

@ -218,7 +218,6 @@
right: 0;
left: unset;
line-height: 13rem;
pointer-events: none;
}
}

View File

@ -284,6 +284,7 @@ return [
'responsive' => [
'header' => [
'done' => 'Done',
'languages' => 'Languages',
'greeting' => 'Welcome, :customer !',
]

View File

@ -64,7 +64,7 @@
</li>
</ul>
<ul type="none" class="category-wrapper">
<ul type="none" class="category-wrapper" v-if="$root.sharedRootCategories.length > 0">
<li v-for="(category, index) in $root.sharedRootCategories">
<a class="unset" :href="`${$root.baseUrl}/${category.slug}`">
<div class="category-logo">
@ -217,7 +217,7 @@
v-for="(thirdLevelCategory, index) in nestedSubCategory.children">
<a
class="unset"
:href="`${$root.baseUrl}/${nestedSubCategory.slug}`">
:href="`${$root.baseUrl}/${subCategory.slug}/${nestedSubCategory.slug}/${thirdLevelCategory.slug}`">
<div class="category-logo">
<img
@ -331,18 +331,9 @@
<i class="material-icons">search</i>
</a>
@php
$cart = cart()->getCart();
$cartItemsCount = trans('shop::app.minicart.zero');
if ($cart) {
$cartItemsCount = $cart->items->count();
}
@endphp
<a href="{{ route('shop.checkout.cart.index') }}" class="unset">
<div class="badge-wrapper">
<span class="badge">{{ $cartItemsCount }}</span>
<span class="badge">@{{ cartItemsCount }}</span>
</div>
<i class="material-icons text-down-3">shopping_cart</i>
</a>
@ -382,6 +373,16 @@
</header>
</script>
@php
$cart = cart()->getCart();
$cartItemsCount = trans('shop::app.minicart.zero');
if ($cart) {
$cartItemsCount = $cart->items->count();
}
@endphp
<script type="text/javascript">
(() => {
Vue.component('content-header', {
@ -401,6 +402,7 @@
'subCategory': null,
'isSearchbar': false,
'rootCategories': true,
'cartItemsCount': '{{ $cartItemsCount }}',
'isCustomer': '{{ auth()->guard('customer')->user() ? "true" : "false" }}' == "true",
}
},
@ -416,10 +418,15 @@
'$root.headerItemsCount': function () {
this.updateHeaderItemsCount();
},
'$root.miniCartKey': function () {
this.getMiniCartDetails();
}
},
created: function () {
this.getMiniCartDetails();
this.updateHeaderItemsCount();
},
@ -491,7 +498,19 @@
console.log(this.__('error.something_went_wrong'));
});
}
}
},
getMiniCartDetails: function () {
this.$http.get(`${this.$root.baseUrl}/mini-cart`)
.then(response => {
if (response.data.status) {
this.cartItemsCount = response.data.mini_cart.cart_items.length;
}
})
.catch(exception => {
console.log(this.__('error.something_went_wrong'));
});
},
},
});
})()

View File

@ -256,6 +256,7 @@
let elementId = element.id;
if (value == ""
&& element.id != 'sign-btn'
&& element.id != 'billing[company_name]'
&& element.id != 'shipping[company_name]'
) {

View File

@ -16,30 +16,28 @@
<script>
$(document).ready(function() {
window.updateHeight = () => {
let sidebarHeight = $('.customer-sidebar').css('height');
let contentHeight = $('.account-layout').css('height');
setTimeout(() => {
let sidebarHeight = $('.customer-sidebar').css('height');
let contentHeight = $('.account-layout').css('height');
sidebarHeight = parseInt(sidebarHeight.substring(0, sidebarHeight.length - 2));
contentHeight = parseInt(contentHeight.substring(0, contentHeight.length - 2));
sidebarHeight = parseInt(sidebarHeight.substring(0, sidebarHeight.length - 2));
contentHeight = parseInt(contentHeight.substring(0, contentHeight.length - 2));
let height = sidebarHeight > contentHeight ? sidebarHeight + 30 : contentHeight;
height = height + "px";
let height = sidebarHeight > contentHeight ? sidebarHeight + 30 : contentHeight;
height = height + "px";
$('.account-content').css('height', height);
$('.account-content').css('height', height);
}, 0);
}
window.updateHeight();
$('input, select').change(() => {
setTimeout(() => {
window.updateHeight()
}, 0)
window.updateHeight();
});
$('button').click(() => {
setTimeout(() => {
window.updateHeight()
}, 0)
window.updateHeight();
});
$('.accordian-header').click(window.updateHeight);

View File

@ -25,6 +25,14 @@
{{ __('shop::app.customer.account.order.view.page-tile', ['order_id' => $order->increment_id]) }}
</span>
<span></span>
@if ($order->canCancel())
<span class="account-action">
<a href="{{ route('customer.orders.cancel', $order->id) }}" class="theme-btn light unset pull-right" v-alert:message="'{{ __('admin::app.sales.orders.cancel-confirm-msg') }}'" style="float: right">
{{ __('shop::app.customer.account.order.view.cancel-btn-title') }}
</a>
</span>
@endif
</div>
{!! view_render_event('bagisto.shop.customers.account.orders.view.before', ['order' => $order]) !!}

View File

@ -21,6 +21,20 @@
$subMenuCollection['compare'] = $menuItem['children']['compare'];
$subMenuCollection['reviews'] = $menuItem['children']['reviews'];
$subMenuCollection['address'] = $menuItem['children']['address'];
unset(
$menuItem['children']['profile'],
$menuItem['children']['orders'],
$menuItem['children']['downloadables'],
$menuItem['children']['wishlist'],
$menuItem['children']['compare'],
$menuItem['children']['reviews'],
$menuItem['children']['address']
);
foreach ($menuItem['children'] as $key => $remainingChildren) {
$subMenuCollection[$key] = $remainingChildren;
}
} catch (\Exception $exception) {
$subMenuCollection = $menuItem['children'];
}

View File

@ -25,7 +25,7 @@
action="{{ route('customer.profile.edit') }}">
@csrf
{!! view_render_event('bagisto.shop.customers.account.profile.edit.before', ['customer' => $customer]) !!}
{!! view_render_event('bagisto.shop.customers.account.profile.edit_form_controls.before', ['customer' => $customer]) !!}
<div :class="`row ${errors.has('first_name') ? 'has-error' : ''}`">
<label class="col-12 mandatory">
@ -38,7 +38,7 @@
</div>
</div>
{!! view_render_event('bagisto.shop.customers.account.profile.edit.first_name.after') !!}
{!! view_render_event('bagisto.shop.customers.account.profile.edit.first_name.after', ['customer' => $customer]) !!}
<div class="row">
<label class="col-12">
@ -50,7 +50,7 @@
</div>
</div>
{!! view_render_event('bagisto.shop.customers.account.profile.edit.last_name.after') !!}
{!! view_render_event('bagisto.shop.customers.account.profile.edit.last_name.after', ['customer' => $customer]) !!}
<div :class="`row ${errors.has('gender') ? 'has-error' : ''}`">
<label class="col-12 mandatory">
@ -98,7 +98,7 @@
</div>
</div>
{!! view_render_event('bagisto.shop.customers.account.profile.edit.gender.after') !!}
{!! view_render_event('bagisto.shop.customers.account.profile.edit.gender.after', ['customer' => $customer]) !!}
<div :class="`row ${errors.has('date_of_birth') ? 'has-error' : ''}`">
<label class="col-12">
@ -119,7 +119,7 @@
</div>
</div>
{!! view_render_event('bagisto.shop.customers.account.profile.edit.date_of_birth.after') !!}
{!! view_render_event('bagisto.shop.customers.account.profile.edit.date_of_birth.after', ['customer' => $customer]) !!}
<div class="row">
<label class="col-12 mandatory">
@ -132,7 +132,7 @@
</div>
</div>
{!! view_render_event('bagisto.shop.customers.account.profile.edit.email.after') !!}
{!! view_render_event('bagisto.shop.customers.account.profile.edit.email.after', ['customer' => $customer]) !!}
<div class="row">
<label class="col-12">
@ -144,7 +144,7 @@
</div>
</div>
{!! view_render_event('bagisto.shop.customers.account.profile.edit.oldpassword.after') !!}
{!! view_render_event('bagisto.shop.customers.account.profile.edit.oldpassword.after', ['customer' => $customer]) !!}
<div class="row">
<label class="col-12">
@ -164,7 +164,7 @@
</div>
</div>
{!! view_render_event('bagisto.shop.customers.account.profile.edit.password.after') !!}
{!! view_render_event('bagisto.shop.customers.account.profile.edit.password.after', ['customer' => $customer]) !!}
<div class="row">
<label class="col-12">

View File

@ -46,28 +46,28 @@
<td>{{ $customer->first_name }}</td>
</tr>
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.first_name.after') !!}
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.first_name.after', ['customer' => $customer]) !!}
<tr>
<td>{{ __('shop::app.customer.account.profile.lname') }}</td>
<td>{{ $customer->last_name }}</td>
</tr>
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.last_name.after') !!}
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.last_name.after', ['customer' => $customer]) !!}
<tr>
<td>{{ __('shop::app.customer.account.profile.gender') }}</td>
<td>{{ $customer->gender ?? '-' }}</td>
</tr>
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.gender.after') !!}
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.gender.after', ['customer' => $customer]) !!}
<tr>
<td>{{ __('shop::app.customer.account.profile.dob') }}</td>
<td>{{ $customer->date_of_birth ?? '-' }}</td>
</tr>
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.date_of_birth.after') !!}
{!! view_render_event('bagisto.shop.customers.account.profile.view.table.date_of_birth.after', ['customer' => $customer]) !!}
<tr>
<td>{{ __('shop::app.customer.account.profile.email') }}</td>

View File

@ -4,12 +4,15 @@
<?php
$filterAttributes = [];
$maxPrice = 0;
if (isset($category)) {
$products = $productRepository->getAll($category->id);
$filterAttributes = $productFlatRepository->getFilterableAttributes($category, $products);
}
$maxPrice = core()->convertPrice($productFlatRepository->getCategoryProductMaximumPrice($category));
}
if (! count($filterAttributes) > 0) {
$filterAttributes = $attributeRepository->getFilterAttributes();
@ -181,7 +184,7 @@
],
data: function() {
let maxPrice = '{{ core()->convertPrice($productFlatRepository->getCategoryProductMaximumPrice($category)) }}';
let maxPrice = @json($maxPrice);
maxPrice = maxPrice ? ((parseInt(maxPrice) !== 0 || maxPrice) ? parseInt(maxPrice) : 500) : 500;

View File

@ -82,17 +82,28 @@
</div>
<div class="toolbar-wrapper row col-12 remove-padding-margin" v-else>
<div v-if="layeredNavigation" class="nav-container scrollable">
<div
v-if="layeredNavigation"
class="nav-container scrollable"
style="
z-index: 1000;
color: black;
position: relative;
">
<div class="header drawer-section">
<i class="material-icons" @click="toggleLayeredNavigation">keyboard_backspace</i>
<span class="fs24 fw6">
{{ __('velocity::app.shop.general.filter') }}
</span>
{{-- <span class="pull-right link-color" @click="toggleLayeredNavigation">Done</span> --}}
<span class="pull-right link-color" @click="toggleLayeredNavigation">
{{ __('velocity::app.responsive.header.done') }}
</span>
</div>
{{-- @include ('shop::products.list.layered-navigation') --}}
@if (request()->route()->getName() != 'velocity.search.index')
@include ('shop::products.list.layered-navigation')
@endif
</div>
<div class="col-4" @click="toggleLayeredNavigation({event: $event, actionType: 'open'})">

View File

@ -37,7 +37,7 @@
:id="galleryCarouselId"
pagination-enabled="hide"
navigation-enabled="hide"
add-class="product-gallary"
add-class="product-gallery"
:slides-count="thumbs.length">
<slide :slot="`slide-${index}`" v-for="(thumb, index) in thumbs">

View File

@ -27,11 +27,11 @@ $data = array();
if (empty($_POST['host_name']))
$errors['host_name'] = 'Host Name is required.';
if (empty($_POST['database_name']))
$errors['database_name'] = 'Database Name is required.';
// if (empty($_POST['database_name']))
// $errors['database_name'] = 'Database Name is required.';
if (empty($_POST['user_name']))
$errors['user_name'] = 'User Name is required.';
// if (empty($_POST['user_name']))
// $errors['user_name'] = 'User Name is required.';
if (empty($_POST['port_name']))
$errors['port_name'] = 'Port Name is required.';

View File

@ -1,8 +1,9 @@
<?php
$actual_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$cssUrl = $actual_link .'/'. 'css/style.css';
$cssUrl = $actual_link .'/'. 'CSS/style.css';
$logo = $actual_link .'/'. 'Images/logo.svg';
$jsURL = $actual_link .'/'. 'js/script.js';
?>
<!DOCTYPE html>
<html>
@ -115,11 +116,11 @@
include __DIR__ . '/Classes/Requirement.php';
// including php files
include __DIR__ . '/views/environment.blade.php';
include __DIR__ . '/views/migration.blade.php';
include __DIR__ . '/views/admin.blade.php';
include __DIR__ . '/views/email.blade.php';
include __DIR__ . '/views/finish.blade.php';
include __DIR__ . '/Views/environment.blade.php';
include __DIR__ . '/Views/migration.blade.php';
include __DIR__ . '/Views/admin.blade.php';
include __DIR__ . '/Views/email.blade.php';
include __DIR__ . '/Views/finish.blade.php';
// object creation
$requirement = new Requirement();
@ -143,6 +144,7 @@
<a href="https://bagisto.com/" target="_blank">Bagisto</a> a community project by <a href="https://webkul.com/" target="_blank">Webkul</a>
</div>
<script src="js/script.js"></script>
<script src="<?php echo $jsURL; ?>" ></script>
</body>
</html>

4
public/mix-manifest.json Normal file
View File

@ -0,0 +1,4 @@
{
"/js/app.js": "/js/app.js",
"/css/app.css": "/css/app.css"
}

View File

@ -67,13 +67,13 @@ class OrderCest
$I->seeResponseCodeIsSuccessful();
$I->seeRecord(CartAddress::class, array_merge($addressData, [
'address_type' => 'shipping',
'address_type' => CartAddress::ADDRESS_TYPE_SHIPPING,
'cart_id' => $mocks['cart']->id,
'customer_id' => $mocks['customer']->id,
]));
$I->seeRecord(CartAddress::class, array_merge($addressData, [
'address_type' => 'billing',
'address_type' => CartAddress::ADDRESS_TYPE_BILLING,
'cart_id' => $mocks['cart']->id,
'customer_id' => $mocks['customer']->id,
]));
@ -128,13 +128,13 @@ class OrderCest
$I->seeRecord(OrderAddress::class, array_merge($addressData, [
'order_id' => $order->id,
'address_type' => 'shipping',
'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING,
'customer_id' => $mocks['customer']->id,
]));
$I->seeRecord(OrderAddress::class, array_merge($addressData, [
'order_id' => $order->id,
'address_type' => 'billing',
'address_type' => OrderAddress::ADDRESS_TYPE_BILLING,
'customer_id' => $mocks['customer']->id,
]));

View File

@ -16,6 +16,9 @@ class CartTaxesCest
{
public $country;
private const CART_TOTAL_PRECISION = 2;
private const TAX_AMOUNT_PRECISION = 2;
function _before(FunctionalTester $I)
{
$this->country = strtoupper(Config::get('app.default_country')) ?? 'DE';
@ -62,7 +65,7 @@ class CartTaxesCest
$product2 = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT, $config2);
$prod1Quantity = $I->fake()->numberBetween(9, 30);
// quantity of product1 should be not even
// quantity of product1 should be odd
if ($prod1Quantity % 2 !== 0) {
$prod1Quantity -= 1;
}
@ -79,10 +82,15 @@ class CartTaxesCest
'quantity' => 1,
]);
$expectedTaxAmount1 = round(
round(1 * $product1->price, self::CART_TOTAL_PRECISION)
* $tax1->tax_rate / 100,
self::TAX_AMOUNT_PRECISION
);
$I->amOnPage('/checkout/cart');
$I->see('Tax ' . $tax1->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax1->tax_rate));
$I->see(
core()->currency(round($product1->price * $tax1->tax_rate / 100, 2)),
$I->see(core()->currency($expectedTaxAmount1),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax1->tax_rate)
);
@ -92,10 +100,15 @@ class CartTaxesCest
'quantity' => $prod1Quantity,
]);
$expectedTaxAmount1 = round(
round((1 + $prod1Quantity) * $product1->price, self::CART_TOTAL_PRECISION)
* $tax1->tax_rate / 100,
self::TAX_AMOUNT_PRECISION
);
$I->amOnPage('/checkout/cart');
$I->see('Tax ' . $tax1->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax1->tax_rate));
$I->see(
core()->currency(round(($prod1Quantity + 1) * $product1->price * $tax1->tax_rate / 100, 2)),
$I->see(core()->currency($expectedTaxAmount1),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax1->tax_rate)
);
@ -105,38 +118,40 @@ class CartTaxesCest
'quantity' => $prod2Quantity,
]);
$expectedTaxAmount2 = round(
round($prod2Quantity * $product2->price, self::CART_TOTAL_PRECISION)
* $tax2->tax_rate / 100,
self::TAX_AMOUNT_PRECISION
);
$I->amOnPage('/checkout/cart');
$I->see('Tax ' . $tax1->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax1->tax_rate));
$taxAmount1 = round(($prod1Quantity + 1) * $product1->price * $tax1->tax_rate / 100, 2);
$I->see(core()->currency($taxAmount1), '#basetaxamount-' . core()->taxRateAsIdentifier($tax1->tax_rate));
$I->see(core()->currency($expectedTaxAmount1), '#basetaxamount-' . core()->taxRateAsIdentifier($tax1->tax_rate));
$I->see('Tax ' . $tax2->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax2->tax_rate));
$taxAmount2 = round($prod2Quantity * $product2->price * $tax2->tax_rate / 100, 2);
$I->see(core()->currency($taxAmount2), '#basetaxamount-' . core()->taxRateAsIdentifier($tax2->tax_rate));
$I->see(core()->currency($expectedTaxAmount2), '#basetaxamount-' . core()->taxRateAsIdentifier($tax2->tax_rate));
$cart = Cart::getCart();
$I->assertEquals(2, $cart->items_count);
$I->assertEquals((float)($prod1Quantity + 1 + $prod2Quantity), $cart->items_qty);
$I->assertEquals($taxAmount1 + $taxAmount2, $cart->tax_total);
$I->assertEquals(round($expectedTaxAmount1 + $expectedTaxAmount2, self::TAX_AMOUNT_PRECISION), $cart->tax_total);
Cart::removeItem($cart->items[1]->id);
$I->amOnPage('/checkout/cart');
$I->amOnPage('/checkout/cart');
$I->see('Tax ' . $tax1->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax1->tax_rate));
$taxAmount1 = round(($prod1Quantity + 1) * $product1->price * $tax1->tax_rate / 100, 2);
$I->see(core()->currency($taxAmount1), '#basetaxamount-' . core()->taxRateAsIdentifier($tax1->tax_rate));
$I->see(core()->currency($expectedTaxAmount1), '#basetaxamount-' . core()->taxRateAsIdentifier($tax1->tax_rate));
$I->dontSee('Tax ' . $tax2->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax2->tax_rate));
$taxAmount2 = round($prod2Quantity * $product2->price * $tax2->tax_rate / 100, 2);
$I->dontSee(core()->currency($taxAmount2), '#basetaxamount-' . core()->taxRateAsIdentifier($tax2->tax_rate));
$I->dontSee(core()->currency($expectedTaxAmount2), '#basetaxamount-' . core()->taxRateAsIdentifier($tax2->tax_rate));
$cart = Cart::getCart();
$I->assertEquals(1, $cart->items_count);
$I->assertEquals((float)($prod1Quantity + 1), $cart->items_qty);
$I->assertEquals($taxAmount1, $cart->tax_total);
$I->assertEquals($expectedTaxAmount1, $cart->tax_total);
}
public function checkCartWithMultipleZipRangeBasedTaxes(FunctionalTester $I): void
@ -233,6 +248,28 @@ class CartTaxesCest
'quantity' => 1,
]);
$expectedTaxAmount11 = round(
round(1 * $product1->price, self::CART_TOTAL_PRECISION)
* $tax11->tax_rate / 100,
self::TAX_AMOUNT_PRECISION
);
$expectedTaxAmount12 = round(
round(1 * $product1->price, self::CART_TOTAL_PRECISION)
* $tax12->tax_rate / 100,
self::TAX_AMOUNT_PRECISION
);
$expectedTaxAmount21 = round(
round(1 * $product2->price, self::CART_TOTAL_PRECISION)
* $tax21->tax_rate / 100,
self::TAX_AMOUNT_PRECISION
);
$expectedTaxAmount22 = round(
round(1 * $product2->price, self::CART_TOTAL_PRECISION)
* $tax22->tax_rate / 100,
self::TAX_AMOUNT_PRECISION
);
Cart::saveCustomerAddress(
[
'billing' => [
@ -256,26 +293,22 @@ class CartTaxesCest
$I->amOnPage('/checkout/cart');
$I->see('Tax ' . $tax11->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax11->tax_rate));
$I->see(
core()->currency(round($product1->price * $tax11->tax_rate / 100, 2)),
$I->see(core()->currency($expectedTaxAmount11),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax11->tax_rate)
);
$I->dontSee('Tax ' . $tax12->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax12->tax_rate));
$I->dontSee(
core()->currency(round($product1->price * $tax12->tax_rate / 100, 2)),
$I->dontSee(core()->currency($expectedTaxAmount12),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax12->tax_rate)
);
$I->dontSee('Tax ' . $tax21->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax21->tax_rate));
$I->dontSee(
core()->currency(round($product2->price * $tax21->tax_rate / 100, 2)),
$I->dontSee(core()->currency($expectedTaxAmount21),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax21->tax_rate)
);
$I->dontSee('Tax ' . $tax22->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax22->tax_rate));
$I->dontSee(
core()->currency(round($product2->price * $tax22->tax_rate / 100, 2)),
$I->dontSee(core()->currency($expectedTaxAmount22),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax22->tax_rate)
);
@ -288,34 +321,27 @@ class CartTaxesCest
$I->amOnPage('/checkout/cart');
$I->see('Tax ' . $tax11->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax11->tax_rate));
$I->see(
core()->currency(round($product1->price * $tax11->tax_rate / 100, 2)),
$I->see(core()->currency($expectedTaxAmount11),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax11->tax_rate)
);
$I->dontSee('Tax ' . $tax12->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax12->tax_rate));
$I->dontSee(
core()->currency(round($product1->price * $tax12->tax_rate / 100, 2)),
$I->dontSee(core()->currency($expectedTaxAmount12),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax12->tax_rate)
);
$I->see('Tax ' . $tax21->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax21->tax_rate));
$I->see(
core()->currency(round($product2->price * $tax21->tax_rate / 100, 2)),
$I->see(core()->currency($expectedTaxAmount21),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax21->tax_rate)
);
$I->dontSee('Tax ' . $tax22->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax22->tax_rate));
$I->dontSee(
core()->currency(round($product2->price * $tax22->tax_rate / 100, 2)),
$I->dontSee(core()->currency($expectedTaxAmount22),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax22->tax_rate)
);
$taxAmount1 = round($product1->price * $tax11->tax_rate / 100, 2);
$I->see(core()->currency($taxAmount1), '#basetaxamount-' . core()->taxRateAsIdentifier($tax11->tax_rate));
$taxAmount2 = round($product2->price * $tax21->tax_rate / 100, 2);
$I->see(core()->currency($taxAmount2), '#basetaxamount-' . core()->taxRateAsIdentifier($tax21->tax_rate));
$I->see(core()->currency($expectedTaxAmount11), '#basetaxamount-' . core()->taxRateAsIdentifier($tax11->tax_rate));
$I->see(core()->currency($expectedTaxAmount21), '#basetaxamount-' . core()->taxRateAsIdentifier($tax21->tax_rate));
$I->wantToTest('customer address with postcode in range of 50000 - 89999');
@ -349,20 +375,17 @@ class CartTaxesCest
$I->amOnPage('/checkout/cart');
$I->dontSee('Tax ' . $tax11->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax11->tax_rate));
$I->dontSee(
core()->currency(round($product1->price * $tax11->tax_rate / 100, 2)),
$I->dontSee(core()->currency($expectedTaxAmount11),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax11->tax_rate)
);
$I->see('Tax ' . $tax12->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax12->tax_rate));
$I->see(
core()->currency(round($product1->price * $tax12->tax_rate / 100, 2)),
$I->see(core()->currency($expectedTaxAmount12),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax12->tax_rate)
);
$I->dontSee('Tax ' . $tax21->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax21->tax_rate));
$I->dontSee(
core()->currency(round($product2->price * $tax21->tax_rate / 100, 2)),
$I->dontSee(core()->currency($expectedTaxAmount21),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax21->tax_rate)
);
@ -372,11 +395,8 @@ class CartTaxesCest
'#basetaxamount-' . core()->taxRateAsIdentifier($tax22->tax_rate)
);
$taxAmount1 = round($product1->price * $tax12->tax_rate / 100, 2);
$I->see(core()->currency($taxAmount1), '#basetaxamount-' . core()->taxRateAsIdentifier($tax12->tax_rate));
$taxAmount2 = round($product2->price * $tax22->tax_rate / 100, 2);
$I->see(core()->currency($taxAmount2), '#basetaxamount-' . core()->taxRateAsIdentifier($tax22->tax_rate));
$I->see(core()->currency($expectedTaxAmount12), '#basetaxamount-' . core()->taxRateAsIdentifier($tax12->tax_rate));
$I->see(core()->currency($expectedTaxAmount22), '#basetaxamount-' . core()->taxRateAsIdentifier($tax22->tax_rate));
$I->wantToTest('customer address with postcode in range of 90000 - 99000');
$I->wanttoTest('as we dont have any taxes in this zip range');
@ -410,26 +430,22 @@ class CartTaxesCest
$I->amOnPage('/checkout/cart');
$I->dontSee('Tax ' . $tax11->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax11->tax_rate));
$I->dontSee(
core()->currency(round($product1->price * $tax11->tax_rate / 100, 2)),
$I->dontSee(core()->currency($expectedTaxAmount11),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax11->tax_rate)
);
$I->dontSee('Tax ' . $tax12->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax12->tax_rate));
$I->dontSee(
core()->currency(round($product1->price * $tax12->tax_rate / 100, 2)),
$I->dontSee(core()->currency($expectedTaxAmount12),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax12->tax_rate)
);
$I->dontSee('Tax ' . $tax21->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax21->tax_rate));
$I->dontSee(
core()->currency(round($product2->price * $tax21->tax_rate / 100, 2)),
$I->dontSee(core()->currency($expectedTaxAmount21),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax21->tax_rate)
);
$I->dontSee('Tax ' . $tax22->tax_rate . ' %', '#taxrate-' . core()->taxRateAsIdentifier($tax22->tax_rate));
$I->dontSee(
core()->currency(round($product2->price * $tax22->tax_rate / 100, 2)),
$I->dontSee(core()->currency($expectedTaxAmount22),
'#basetaxamount-' . core()->taxRateAsIdentifier($tax22->tax_rate)
);
}

View File

@ -59,9 +59,11 @@ class GuestCheckoutCest
$I->assertEquals($example['globalConfig'],
core()->getConfigData('catalog.products.guest-checkout.allow-guest-checkout'));
$I->amOnRoute('shop.home.index');
$I->see($product->name, '//div[@class="product-information"]/div[@class="product-name"]');
$I->click(__('shop::app.products.add-to-cart'),
'//form[input[@name="product_id"][@value="' . $product->id . '"]]/button');
$I->sendAjaxPostRequest('/checkout/cart/add/' . $product->id, [
'_token' => session('_token'),
'product_id' => $product->id,
'quantity' => 1
]);
$I->amOnRoute('shop.checkout.cart.index');
$I->see('Shopping Cart', '//div[@class="title"]');

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,108 @@
<?php
namespace Tests\Unit\Core;
use UnitTester;
use Webkul\Checkout\Models\Cart;
use Webkul\Checkout\Models\CartAddress;
use Webkul\Checkout\Models\CartShippingRate;
use Webkul\Customer\Models\Customer;
use Webkul\Customer\Models\CustomerAddress;
use Webkul\Sales\Models\Invoice;
use Webkul\Sales\Models\Order;
use Webkul\Sales\Models\OrderAddress;
use Webkul\Sales\Models\Shipment;
use Webkul\Shipping\Carriers\Free;
class AddressCest
{
public function testAddressFilters(UnitTester $I): void
{
$cartAddress = $I->have(CartAddress::class);
$customerAddress = $I->have(CustomerAddress::class);
$orderAddress = $I->have(OrderAddress::class);
$cartAddresses = CartAddress::all();
$I->assertCount(1, $cartAddresses);
$I->assertEquals($cartAddress->id, $cartAddresses[0]->id);
$customerAddresses = CustomerAddress::all();
$I->assertCount(1, $customerAddresses);
$I->assertEquals($customerAddress->id, $customerAddresses[0]->id);
$orderAddresses = OrderAddress::all();
$I->assertCount(1, $orderAddresses);
$I->assertEquals($orderAddress->id, $orderAddresses[0]->id);
}
public function testCustomerAddressRelations(UnitTester $I): void
{
/** @var Customer $customer1 */
$customer1 = $I->have(Customer::class);
CustomerAddress::create(['customer_id' => $customer1->id]);
/** @var Customer $customer2 */
$customer2 = $I->have(Customer::class);
$address1 = CustomerAddress::create(['customer_id' => $customer2->id]);
$customer2->refresh();
$I->assertCount(1, $customer2->addresses);
$I->assertEquals($address1->id, $customer2->addresses[0]->id);
$I->assertNull($customer2->default_address);
$address2 = CustomerAddress::create(['customer_id' => $customer2->id, 'default_address' => true]);
$customer2->refresh();
$I->assertCount(2, $customer2->addresses);
$I->assertEquals($address2->id, $customer2->default_address->id);
}
public function testCartAddressRelations(UnitTester $I): void
{
/** @var Cart $cart */
$cart = $I->have(Cart::class);
$address1 = CartAddress::create(['cart_id' => $cart->id]);
$address2 = CartAddress::create([
'cart_id' => $cart->id,
'address_type' => CartAddress::ADDRESS_TYPE_SHIPPING
]);
$cart->refresh();
$I->assertNotNull($address1->address_type);
$I->assertEquals($address1->id, $cart->billing_address->id);
$I->assertEquals($address2->id, $cart->shipping_address->id);
/** @var CartShippingRate $freeShipping */
$freeShipping = (new Free())->calculate();
$freeShipping->cart_address_id = $address2->id;
$freeShipping->saveOrFail();
$freeShipping->refresh();
$I->assertEquals($address2->id, $freeShipping->shipping_address->id);
}
public function testOrderAddressRelations(UnitTester $I): void
{
/** @var Order $order */
$order = $I->have(Order::class);
$address1 = OrderAddress::create(['order_id' => $order->id]);
$address2 = OrderAddress::create([
'order_id' => $order->id,
'address_type' => OrderAddress::ADDRESS_TYPE_SHIPPING
]);
$order->refresh();
$I->assertNotNull($address1->address_type);
$I->assertEquals($address1->id, $order->billing_address->id);
$I->assertEquals($address2->id, $order->shipping_address->id);
/** @var Shipment $shipment */
$shipment = Shipment::create(['order_address_id' => $address2->id]);
$I->assertEquals($address2->id, $shipment->address->id);
/** @var Invoice $invoice */
$invoice = Invoice::create(['order_id' => $order->id, 'order_address_id' => $address1->id]);
$I->assertEquals($address1->id, $invoice->address->id);
}
}

Some files were not shown because too many files have changed in this diff Show More