Merge branch 'master' into quick-view
This commit is contained in:
commit
6a8f86a494
|
|
@ -1,6 +1,6 @@
|
|||
APP_NAME=Bagisto
|
||||
APP_ENV=local
|
||||
APP_VERSION=1.2.0-BETA1
|
||||
APP_VERSION=1.2.0
|
||||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
APP_NAME=Laravel
|
||||
APP_ENV=local
|
||||
APP_VERSION=1.2.0-BETA1
|
||||
APP_VERSION=1.2.0
|
||||
APP_KEY=base64:G4KY3tUsTaY9ONo1n/QyJvVLQZdJDgbIkSJswFK01HE=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/docker-compose-collection
|
||||
/storage/dcc-data/
|
||||
/node_modules
|
||||
/public/hot
|
||||
/public/storage
|
||||
|
|
@ -23,4 +24,5 @@ yarn.lock
|
|||
.php_cs.cache
|
||||
storage/*.key
|
||||
/docker-compose-collection/
|
||||
/resources/themes/velocity/*
|
||||
/resources/themes/velocity/*
|
||||
/resources/lang/vendor/webkul/admin/*
|
||||
|
|
@ -2,6 +2,56 @@
|
|||
|
||||
#### This changelog consists the bug & security fixes and new features being included in the releases listed below.
|
||||
|
||||
## **v1.2.0 (7th of September 2020)** - *Release*
|
||||
|
||||
* #1257 [fixed] - Getting issue in install of v0.1.6
|
||||
|
||||
* #3643 [fixed] - Invoices should contain the company/store data
|
||||
|
||||
* #3772 [fixed] - Unable to add more than 4 products in related products
|
||||
|
||||
* #3781 [fixed] - Getting exception on frontend after installation.
|
||||
|
||||
* #3782 [fixed] - Getting error on running php artisan migrate if db_prefix contains decimal value
|
||||
|
||||
* #3783 [fixed] - Correct the product name alignment in compare list of default theme.
|
||||
|
||||
* #3784 [fixed] - Responsive issue on iPad
|
||||
|
||||
* #3786 [fixed] - Default advertisement images should display in images section.
|
||||
|
||||
* #3789 [fixed] - Filter conditions need to be change according to Boolean in newsletter subscription grid for subscribed column
|
||||
|
||||
* #3791 [fixed] - validation message showing for wrong field while editing user from admin end
|
||||
|
||||
* #3792 [fixed] - Recently viewed product is not working for Locales other than default.
|
||||
|
||||
* #3799 [fixed] - Featured Products and New Products should not display on front end if admin has set 0 in velocity meta data
|
||||
|
||||
* #3800 [fixed] - Header Content Count field should convert the value into 0 if given anything apart from valid data(numeric value)
|
||||
|
||||
* #3802 [fixed] - Layout issue while adding linked products
|
||||
|
||||
* #3804 [fixed] - uploading image on search is not resulting in any keywords
|
||||
|
||||
* #3811 [fixed] - Velocity cms page url should be added by default
|
||||
|
||||
* #3819 [fixed] - Export Function not working in Firefox/Linux
|
||||
|
||||
* #3822 [fixed] - Publish translations from Webkul\Admin
|
||||
|
||||
* #3828 [fixed] - success alert is not visible while removing product from wishlist as guest
|
||||
|
||||
* #3831 [fixed] - social icons are not visible in footer
|
||||
|
||||
* #3852 [fixed] - Product copy functionality is not working properly for configurable products
|
||||
|
||||
* #3854 [fixed] - Fix reset password alert message
|
||||
|
||||
* #3861 [fixed] - Payment Instruction is not implemented for velocity theme
|
||||
|
||||
|
||||
|
||||
## **v1.2.0-BETA1 (18th of August 2020)** - *Release*
|
||||
|
||||
* [feature] - Customer group price for products implemented
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -64,7 +64,7 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'admin_url' => env('APP_ADMIN_URL', 'admin'),
|
||||
'admin_url' => env('APP_ADMIN_URL', 'admin'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
@ -128,7 +128,7 @@ return [
|
|||
| Here you may specify the base currency code for your application.
|
||||
|
|
||||
*/
|
||||
|
||||
|
||||
'currency' => env('APP_CURRENCY', 'USD'),
|
||||
|
||||
/*
|
||||
|
|
@ -263,6 +263,7 @@ return [
|
|||
Webkul\Category\Providers\CategoryServiceProvider::class,
|
||||
Webkul\Attribute\Providers\AttributeServiceProvider::class,
|
||||
Webkul\Core\Providers\CoreServiceProvider::class,
|
||||
Webkul\Core\Providers\EnvValidatorServiceProvider::class,
|
||||
Webkul\Shop\Providers\ShopServiceProvider::class,
|
||||
Webkul\Customer\Providers\CustomerServiceProvider::class,
|
||||
Webkul\Inventory\Providers\InventoryServiceProvider::class,
|
||||
|
|
|
|||
|
|
@ -5,71 +5,75 @@ namespace Webkul\API\Http\Resources\Checkout;
|
|||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
use Webkul\API\Http\Resources\Core\Channel as ChannelResource;
|
||||
use Webkul\API\Http\Resources\Customer\Customer as CustomerResource;
|
||||
use Webkul\Tax\Helpers\Tax;
|
||||
|
||||
class Cart extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request
|
||||
* @param \Illuminate\Http\Request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
public function toArray($request): array
|
||||
{
|
||||
$taxes = \Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($this, false);
|
||||
$baseTaxes = \Webkul\Tax\Helpers\Tax::getTaxRatesWithAmount($this, true);
|
||||
$taxes = Tax::getTaxRatesWithAmount($this, false);
|
||||
$baseTaxes = Tax::getTaxRatesWithAmount($this, true);
|
||||
|
||||
$formatedTaxes = $this->formatTaxAmounts($taxes, false);
|
||||
$formatedBaseTaxes = $this->formatTaxAmounts($baseTaxes, true);
|
||||
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'customer_email' => $this->customer_email,
|
||||
'customer_first_name' => $this->customer_first_name,
|
||||
'customer_last_name' => $this->customer_last_name,
|
||||
'shipping_method' => $this->shipping_method,
|
||||
'coupon_code' => $this->coupon_code,
|
||||
'is_gift' => $this->is_gift,
|
||||
'items_count' => $this->items_count,
|
||||
'items_qty' => $this->items_qty,
|
||||
'exchange_rate' => $this->exchange_rate,
|
||||
'global_currency_code' => $this->global_currency_code,
|
||||
'base_currency_code' => $this->base_currency_code,
|
||||
'channel_currency_code' => $this->channel_currency_code,
|
||||
'cart_currency_code' => $this->cart_currency_code,
|
||||
'grand_total' => $this->grand_total,
|
||||
'formated_grand_total' => core()->formatPrice($this->grand_total, $this->cart_currency_code),
|
||||
'base_grand_total' => $this->base_grand_total,
|
||||
'formated_base_grand_total' => core()->formatBasePrice($this->base_grand_total),
|
||||
'sub_total' => $this->sub_total,
|
||||
'formated_sub_total' => core()->formatPrice($this->sub_total, $this->cart_currency_code),
|
||||
'base_sub_total' => $this->base_sub_total,
|
||||
'formated_base_sub_total' => core()->formatBasePrice($this->base_sub_total),
|
||||
'tax_total' => $this->tax_total,
|
||||
'formated_tax_total' => core()->formatPrice($this->tax_total, $this->cart_currency_code),
|
||||
'base_tax_total' => $this->base_tax_total,
|
||||
'formated_base_tax_total' => core()->formatBasePrice($this->base_tax_total),
|
||||
'discount' => $this->discount_amount,
|
||||
'formated_discount' => core()->formatPrice($this->discount_amount, $this->cart_currency_code),
|
||||
'base_discount' => $this->base_discount_amount,
|
||||
'formated_base_discount' => core()->formatBasePrice($this->base_discount_amount),
|
||||
'checkout_method' => $this->checkout_method,
|
||||
'is_guest' => $this->is_guest,
|
||||
'is_active' => $this->is_active,
|
||||
'conversion_time' => $this->conversion_time,
|
||||
'customer' => $this->when($this->customer_id, new CustomerResource($this->customer)),
|
||||
'channel' => $this->when($this->channel_id, new ChannelResource($this->channel)),
|
||||
'items' => CartItem::collection($this->items),
|
||||
'selected_shipping_rate' => new CartShippingRate($this->selected_shipping_rate),
|
||||
'payment' => new CartPayment($this->payment),
|
||||
'billing_address' => new CartAddress($this->billing_address),
|
||||
'shipping_address' => new CartAddress($this->shipping_address),
|
||||
'created_at' => $this->created_at,
|
||||
'updated_at' => $this->updated_at,
|
||||
'taxes' => json_encode($taxes, JSON_FORCE_OBJECT),
|
||||
'formated_taxes' => json_encode($formatedTaxes, JSON_FORCE_OBJECT),
|
||||
'base_taxes' => json_encode($baseTaxes, JSON_FORCE_OBJECT),
|
||||
'formated_base_taxes' => json_encode($formatedBaseTaxes, JSON_FORCE_OBJECT),
|
||||
'id' => $this->id,
|
||||
'customer_email' => $this->customer_email,
|
||||
'customer_first_name' => $this->customer_first_name,
|
||||
'customer_last_name' => $this->customer_last_name,
|
||||
'shipping_method' => $this->shipping_method,
|
||||
'coupon_code' => $this->coupon_code,
|
||||
'is_gift' => $this->is_gift,
|
||||
'items_count' => $this->items_count,
|
||||
'items_qty' => $this->items_qty,
|
||||
'exchange_rate' => $this->exchange_rate,
|
||||
'global_currency_code' => $this->global_currency_code,
|
||||
'base_currency_code' => $this->base_currency_code,
|
||||
'channel_currency_code' => $this->channel_currency_code,
|
||||
'cart_currency_code' => $this->cart_currency_code,
|
||||
'grand_total' => $this->grand_total,
|
||||
'formated_grand_total' => core()->formatPrice($this->grand_total, $this->cart_currency_code),
|
||||
'base_grand_total' => $this->base_grand_total,
|
||||
'formated_base_grand_total' => core()->formatBasePrice($this->base_grand_total),
|
||||
'sub_total' => $this->sub_total,
|
||||
'formated_sub_total' => core()->formatPrice($this->sub_total, $this->cart_currency_code),
|
||||
'base_sub_total' => $this->base_sub_total,
|
||||
'formated_base_sub_total' => core()->formatBasePrice($this->base_sub_total),
|
||||
'tax_total' => $this->tax_total,
|
||||
'formated_tax_total' => core()->formatPrice($this->tax_total, $this->cart_currency_code),
|
||||
'base_tax_total' => $this->base_tax_total,
|
||||
'formated_base_tax_total' => core()->formatBasePrice($this->base_tax_total),
|
||||
'discount' => $this->discount_amount,
|
||||
'formated_discount' => core()->formatPrice($this->discount_amount, $this->cart_currency_code),
|
||||
'base_discount' => $this->base_discount_amount,
|
||||
'formated_base_discount' => core()->formatBasePrice($this->base_discount_amount),
|
||||
'checkout_method' => $this->checkout_method,
|
||||
'is_guest' => $this->is_guest,
|
||||
'is_active' => $this->is_active,
|
||||
'conversion_time' => $this->conversion_time,
|
||||
'customer' => $this->when($this->customer_id, new CustomerResource($this->customer)),
|
||||
'channel' => $this->when($this->channel_id, new ChannelResource($this->channel)),
|
||||
'items' => CartItem::collection($this->items),
|
||||
'selected_shipping_rate' => new CartShippingRate($this->selected_shipping_rate),
|
||||
'payment' => new CartPayment($this->payment),
|
||||
'billing_address' => new CartAddress($this->billing_address),
|
||||
'shipping_address' => new CartAddress($this->shipping_address),
|
||||
'created_at' => $this->created_at,
|
||||
'updated_at' => $this->updated_at,
|
||||
'taxes' => json_encode($taxes, JSON_FORCE_OBJECT),
|
||||
'formated_taxes' => json_encode($formatedTaxes, JSON_FORCE_OBJECT),
|
||||
'base_taxes' => json_encode($baseTaxes, JSON_FORCE_OBJECT),
|
||||
'formated_base_taxes' => json_encode($formatedBaseTaxes, JSON_FORCE_OBJECT),
|
||||
'formated_discounted_sub_total' => core()->formatPrice($this->sub_total - $this->discount_amount, $this->cart_currency_code),
|
||||
'formated_base_discounted_sub_total' => core()->formatPrice($this->base_sub_total - $this->base_discount_amount, $this->cart_currency_code),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ class Order extends JsonResource
|
|||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'increment_id' => $this->increment_id,
|
||||
'status' => $this->status,
|
||||
'status_label' => $this->status_label,
|
||||
'channel_name' => $this->channel_name,
|
||||
|
|
@ -103,7 +104,6 @@ class Order extends JsonResource
|
|||
'items' => OrderItem::collection($this->items),
|
||||
'invoices' => Invoice::collection($this->invoices),
|
||||
'shipments' => Shipment::collection($this->shipments),
|
||||
'downloadable_links' => $this->downloadable_link_purchased,
|
||||
'updated_at' => $this->updated_at,
|
||||
'created_at' => $this->created_at,
|
||||
];
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ class OrderItem extends JsonResource
|
|||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request
|
||||
* @param \Illuminate\Http\Request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
|
|
@ -75,6 +76,7 @@ class OrderItem extends JsonResource
|
|||
'formated_grant_total' => core()->formatPrice($this->total + $this->tax_amount, $this->order->order_currency_code),
|
||||
'base_grant_total' => $this->base_total + $this->base_tax_amount,
|
||||
'formated_base_grant_total' => core()->formatPrice($this->base_total + $this->base_tax_amount, $this->order->order_currency_code),
|
||||
'downloadable_links' => $this->downloadable_link_purchased,
|
||||
'additional' => is_array($this->resource->additional)
|
||||
? $this->resource->additional
|
||||
: json_decode($this->resource->additional, true),
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,22 +1,22 @@
|
|||
/*!
|
||||
* Sizzle CSS Selector Engine v2.3.4
|
||||
* Sizzle CSS Selector Engine v2.3.5
|
||||
* https://sizzlejs.com/
|
||||
*
|
||||
* Copyright JS Foundation and other contributors
|
||||
* Released under the MIT license
|
||||
* https://js.foundation/
|
||||
*
|
||||
* Date: 2019-04-08
|
||||
* Date: 2020-03-14
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Vue.js v2.6.11
|
||||
* (c) 2014-2019 Evan You
|
||||
* Vue.js v2.6.12
|
||||
* (c) 2014-2020 Evan You
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* jQuery JavaScript Library v3.4.1
|
||||
* jQuery JavaScript Library v3.5.1
|
||||
* https://jquery.com/
|
||||
*
|
||||
* Includes Sizzle.js
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
* Released under the MIT license
|
||||
* https://jquery.org/license
|
||||
*
|
||||
* Date: 2019-05-01T21:04Z
|
||||
* Date: 2020-05-04T22:49Z
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"/js/admin.js": "/js/admin.js?id=a14c779523092ac32b88",
|
||||
"/css/admin.css": "/css/admin.css?id=56c882a611bdf3c058cb"
|
||||
"/js/admin.js": "/js/admin.js?id=b022291aa1cad7dfcc84",
|
||||
"/css/admin.css": "/css/admin.css?id=8f4fcca5914f5370ddda"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,6 +88,25 @@ return [
|
|||
'channel_based' => true,
|
||||
],
|
||||
],
|
||||
], [
|
||||
'key' => 'general.content.custom_scripts',
|
||||
'name' => 'admin::app.admin.system.custom-scripts',
|
||||
'sort' => 1,
|
||||
'fields' => [
|
||||
[
|
||||
'name' => 'custom_css',
|
||||
'title' => 'admin::app.admin.system.custom-css',
|
||||
'type' => 'textarea',
|
||||
'channel_based' => true,
|
||||
'locale_based' => false,
|
||||
], [
|
||||
'name' => 'custom_javascript',
|
||||
'title' => 'admin::app.admin.system.custom-javascript',
|
||||
'type' => 'textarea',
|
||||
'channel_based' => true,
|
||||
'locale_based' => false,
|
||||
]
|
||||
],
|
||||
], [
|
||||
'key' => 'general.design',
|
||||
'name' => 'admin::app.admin.system.design',
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ class CartRuleDataGrid extends DataGrid
|
|||
'title' => trans('admin::app.datagrid.copy'),
|
||||
'method' => 'GET',
|
||||
'route' => 'admin.cart-rules.copy',
|
||||
'icon' => 'icon note-icon',
|
||||
'icon' => 'icon copy-icon',
|
||||
]);
|
||||
|
||||
$this->addAction([
|
||||
|
|
|
|||
|
|
@ -13,7 +13,11 @@ class NewsLetterDataGrid extends DataGrid
|
|||
|
||||
public function prepareQueryBuilder()
|
||||
{
|
||||
$queryBuilder = DB::table('subscribers_list')->addSelect('id', 'is_subscribed', 'email');
|
||||
|
||||
|
||||
$queryBuilder = DB::table('subscribers_list')->select('subscribers_list.id', 'subscribers_list.is_subscribed as status', 'subscribers_list.email');
|
||||
|
||||
$this->addFilter('status', 'subscribers_list.is_subscribed');
|
||||
|
||||
$this->setQueryBuilder($queryBuilder);
|
||||
}
|
||||
|
|
@ -30,14 +34,14 @@ class NewsLetterDataGrid extends DataGrid
|
|||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'is_subscribed',
|
||||
'index' => 'status',
|
||||
'label' => trans('admin::app.datagrid.subscribed'),
|
||||
'type' => 'string',
|
||||
'searchable' => false,
|
||||
'type' => 'boolean',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'filterable' => true,
|
||||
'wrapper' => function($value) {
|
||||
if ($value->is_subscribed == 1) {
|
||||
'wrapper' => function ($value) {
|
||||
if ($value->status === 1) {
|
||||
return trans('admin::app.datagrid.true');
|
||||
} else {
|
||||
return trans('admin::app.datagrid.false');
|
||||
|
|
|
|||
|
|
@ -45,19 +45,6 @@ class OrderInvoicesDataGrid extends DataGrid
|
|||
'filterable' => true,
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'created_at',
|
||||
'label' => trans('admin::app.datagrid.invoice-date'),
|
||||
'type' => 'string',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'filterable' => true,
|
||||
'closure' => true,
|
||||
'wrapper' => function ($value) {
|
||||
return \Carbon\Carbon::parse($value->created_at)->format('d-m-Y');
|
||||
}
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'base_grand_total',
|
||||
'label' => trans('admin::app.datagrid.grand-total'),
|
||||
|
|
@ -68,22 +55,12 @@ class OrderInvoicesDataGrid extends DataGrid
|
|||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'state',
|
||||
'label' => trans('admin::app.datagrid.state'),
|
||||
'type' => 'string',
|
||||
'closure' => true,
|
||||
'index' => 'created_at',
|
||||
'label' => trans('admin::app.datagrid.invoice-date'),
|
||||
'type' => 'datetime',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'filterable' => true,
|
||||
'wrapper' => function ($value) {
|
||||
if ($value->state == 'paid') {
|
||||
return '<span class="badge badge-md badge-success">'. trans('admin::app.sales.orders.invoice-status-paid') .'</span>';
|
||||
} elseif ($value->state == "pending") {
|
||||
return '<span class="badge badge-md badge-warning">'. trans('admin::app.sales.orders.invoice-status-pending') .'</span>';
|
||||
} elseif ($value->state == "overdue") {
|
||||
return '<span class="badge badge-md badge-danger">'. trans('admin::app.sales.orders.invoice-status-overdue') . '</span>';
|
||||
}
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Webkul\Admin\DataGrids;
|
||||
|
||||
use Webkul\Core\Models\Locale;
|
||||
use Webkul\Ui\DataGrid\DataGrid;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Webkul\Core\Models\Channel;
|
||||
|
|
@ -34,15 +35,27 @@ class ProductDataGrid extends DataGrid
|
|||
/* channel */
|
||||
$this->channel = request()->get('channel') ?? 'all';
|
||||
|
||||
/* finding channel name */
|
||||
/* finding channel code */
|
||||
if ($this->channel !== 'all') {
|
||||
$this->channel = Channel::find($this->channel);
|
||||
$this->channel = Channel::query()->find($this->channel);
|
||||
$this->channel = $this->channel ? $this->channel->code : 'all';
|
||||
}
|
||||
}
|
||||
|
||||
public function prepareQueryBuilder()
|
||||
{
|
||||
if ($this->channel === 'all') {
|
||||
$whereInChannels = Channel::query()->pluck('code')->toArray();
|
||||
} else {
|
||||
$whereInChannels = [$this->channel];
|
||||
}
|
||||
|
||||
if ($this->locale === 'all') {
|
||||
$whereInLocales = Locale::query()->pluck('code')->toArray();
|
||||
} else {
|
||||
$whereInLocales = [$this->locale];
|
||||
}
|
||||
|
||||
/* query builder */
|
||||
$queryBuilder = DB::table('product_flat')
|
||||
->leftJoin('products', 'product_flat.product_id', '=', 'products.id')
|
||||
|
|
@ -61,9 +74,11 @@ class ProductDataGrid extends DataGrid
|
|||
DB::raw('SUM(DISTINCT ' . DB::getTablePrefix() . 'product_inventories.qty) as quantity')
|
||||
);
|
||||
|
||||
$queryBuilder->groupBy('product_flat.product_id', 'product_flat.locale', 'product_flat.channel');
|
||||
$queryBuilder->where('locale', $this->locale !== 'all' ? $this->locale : 'en');
|
||||
$queryBuilder->where('channel', $this->channel !== 'all' ? $this->channel : 'default');
|
||||
$queryBuilder->groupBy('product_flat.product_id', 'product_flat.channel');
|
||||
|
||||
$queryBuilder->whereIn('product_flat.locale', $whereInLocales);
|
||||
$queryBuilder->whereIn('product_flat.channel', $whereInChannels);
|
||||
$queryBuilder->whereNotNull('product_flat.name');
|
||||
|
||||
$this->addFilter('product_id', 'product_flat.product_id');
|
||||
$this->addFilter('product_name', 'product_flat.name');
|
||||
|
|
@ -191,7 +206,7 @@ class ProductDataGrid extends DataGrid
|
|||
'title' => trans('admin::app.datagrid.copy'),
|
||||
'method' => 'GET',
|
||||
'route' => 'admin.catalog.products.copy',
|
||||
'icon' => 'icon note-icon',
|
||||
'icon' => 'icon copy-icon',
|
||||
]);
|
||||
|
||||
$this->addMassAction([
|
||||
|
|
|
|||
|
|
@ -2,12 +2,9 @@
|
|||
|
||||
namespace Webkul\Admin\Http\Controllers\Sales;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use Webkul\Admin\Http\Controllers\Controller;
|
||||
use Webkul\Sales\Repositories\OrderRepository;
|
||||
use Webkul\Sales\Repositories\InvoiceRepository;
|
||||
|
||||
use PDF;
|
||||
|
||||
class InvoiceController extends Controller
|
||||
|
|
@ -148,24 +145,4 @@ class InvoiceController extends Controller
|
|||
|
||||
return $pdf->download('invoice-' . $invoice->created_at->format('d-m-Y') . '.pdf');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the invoice state.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function updateState($id, Request $request)
|
||||
{
|
||||
$invoice = $this->invoiceRepository->findOrFail($id);
|
||||
$task = $this->invoiceRepository->updateInvoiceState($invoice, $request->state);
|
||||
|
||||
if ($task){
|
||||
session()->flash('success', trans('admin::app.sales.orders.invoice-status-confirmed'));
|
||||
} else {
|
||||
session()->flash('success', trans('admin::app.sales.orders.invoice-status-error'));
|
||||
}
|
||||
|
||||
return back();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,10 +211,6 @@ Route::group(['middleware' => ['web']], function () {
|
|||
'view' => 'admin::sales.invoices.print',
|
||||
])->name('admin.sales.invoices.print');
|
||||
|
||||
Route::post('/invoices/update/state/{order_id}', 'Webkul\Admin\Http\Controllers\Sales\InvoiceController@updateState')->defaults('_config', [
|
||||
'redirect' => 'admin.sales.orders.view',
|
||||
])->name('admin.sales.invoices.update.state');
|
||||
|
||||
|
||||
// Sales Shipments Routes
|
||||
Route::get('/shipments', 'Webkul\Admin\Http\Controllers\Sales\ShipmentController@index')->defaults('_config', [
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ class AdminServiceProvider extends ServiceProvider
|
|||
$this->loadRoutesFrom(__DIR__ . '/../Http/routes.php');
|
||||
|
||||
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'admin');
|
||||
$this->publishes([__DIR__.'/../Resources/lang' => resource_path('lang/vendor/webkul/admin')]);
|
||||
|
||||
$this->publishes([
|
||||
__DIR__ . '/../../publishable/assets' => public_path('vendor/webkul/admin/assets'),
|
||||
|
|
|
|||
|
|
@ -14,3 +14,31 @@
|
|||
@import "partials/rtl";
|
||||
|
||||
@import "partials/ui/components";
|
||||
|
||||
.ellipsis {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.do-not-cross-arrow {
|
||||
width: 85%;
|
||||
}
|
||||
|
||||
.linked-product-filter-tag {
|
||||
text-transform: capitalize;
|
||||
margin-top: 10px;
|
||||
margin-right: 0px;
|
||||
justify-content: flex-start;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.linked-product-wrapper {
|
||||
margin-left: 0px !important;
|
||||
margin-right: 10px !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
.do-not-cross-linked-product-arrow {
|
||||
width: 95%;
|
||||
}
|
||||
|
|
@ -384,6 +384,7 @@ return [
|
|||
'title' => 'الفواتير',
|
||||
'id' => 'Id',
|
||||
'invoice-id' => 'هوية صوتية',
|
||||
'invoice' => 'فاتورة',
|
||||
'date' => 'تاريخ الفاتورة',
|
||||
'order-id' => 'Id طلب',
|
||||
'customer-name' => 'اسم الزبون',
|
||||
|
|
@ -1344,7 +1345,16 @@ return [
|
|||
'show-sku' => 'Show SKU',
|
||||
'categories' => 'Categories',
|
||||
'show-sku' => 'Show SKU',
|
||||
'show-search-input-field' => 'Show Search Input Field'
|
||||
'show-search-input-field' => 'Show Search Input Field',
|
||||
'store-name' => 'اسم المتجر',
|
||||
'vat-number' => 'ظريبه الشراء',
|
||||
'contact-number' => 'رقم الاتصال',
|
||||
'bank-details' => 'التفاصيل المصرفية',
|
||||
'mailing-address' => 'Send Check to',
|
||||
'instructions' => 'Instructions',
|
||||
'custom-scripts' => 'Custom Scripts',
|
||||
'custom-css' => 'Custom CSS',
|
||||
'custom-javascript' => 'Custom Javascript'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -320,14 +320,6 @@ return [
|
|||
'invoice-btn-title' => 'Invoice',
|
||||
'info' => 'Information',
|
||||
'invoices' => 'Invoices',
|
||||
'invoices-change-title' => 'Change invoice state',
|
||||
'invoices-change-state-desc' => 'Please select the new invoice state:',
|
||||
'invoice-status-paid' => 'Paid',
|
||||
'invoice-status-pending' => 'Pending',
|
||||
'invoice-status-overdue' => 'Overdue',
|
||||
'invoice-status-update' => 'Save changes',
|
||||
'invoice-status-confirmed' => 'The invoice state has been changed.',
|
||||
'invoice-status-error' => 'Could not update the invoice state. ',
|
||||
'shipments' => 'Shipments',
|
||||
'order-and-account' => 'Order and Account',
|
||||
'order-info' => 'Order Information',
|
||||
|
|
@ -392,6 +384,7 @@ return [
|
|||
'invoices' => [
|
||||
'title' => 'Invoices',
|
||||
'id' => 'Id',
|
||||
'invoice' => 'Invoice',
|
||||
'invoice-id' => 'Invoice Id',
|
||||
'date' => 'Invoice Date',
|
||||
'order-id' => 'Order Id',
|
||||
|
|
@ -1357,7 +1350,16 @@ return [
|
|||
'show-offers' => 'Show Offers',
|
||||
'show-sku' => 'Show SKU',
|
||||
'categories' => 'Categories',
|
||||
'show-search-input-field' => 'Show Search Input Field'
|
||||
'show-search-input-field' => 'Show Search Input Field',
|
||||
'store-name' => 'Store Name',
|
||||
'vat-number' => 'Vat Number',
|
||||
'contact-number' => 'Contact Number',
|
||||
'bank-details' => 'Bank Details',
|
||||
'mailing-address' => 'Send Check to',
|
||||
'instructions' => 'Instructions',
|
||||
'custom-scripts' => 'Custom Scripts',
|
||||
'custom-css' => 'Custom CSS',
|
||||
'custom-javascript' => 'Custom Javascript'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -377,6 +377,7 @@ return [
|
|||
'title' => 'Facturas',
|
||||
'id' => 'Id',
|
||||
'invoice-id' => 'Factura #',
|
||||
'invoice' => 'Factura',
|
||||
'date' => 'Fecha de factura',
|
||||
'order-id' => 'Pedido #',
|
||||
'customer-name' => 'Nombre del cliente',
|
||||
|
|
@ -1309,7 +1310,16 @@ return [
|
|||
'all-channels' => 'Todos',
|
||||
'all-locales' => 'Todos',
|
||||
'invoice-slip-design' => 'Diseño parte trasera factura',
|
||||
'logo' => 'logo'
|
||||
'logo' => 'logo',
|
||||
'store-name' => 'Nombre de la tienda',
|
||||
'vat-number' => 'Número de valor agregado',
|
||||
'contact-number' => 'Número de contacto',
|
||||
'bank-details' => 'Detalles del banco',
|
||||
'mailing-address' => 'Send Check to',
|
||||
'instructions' => 'Instructions',
|
||||
'custom-scripts' => 'Custom Scripts',
|
||||
'custom-css' => 'Custom CSS',
|
||||
'custom-javascript' => 'Custom Javascript'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -318,14 +318,6 @@ return [
|
|||
'invoice-btn-title' => 'صورت حساب',
|
||||
'info' => 'اطلاعات',
|
||||
'invoices' => 'صورت حساب ها',
|
||||
'invoices-change-title' => 'Change invoice state',
|
||||
'invoices-change-state-desc' => 'Please select the new invoice state:',
|
||||
'invoice-status-paid' => 'Paid',
|
||||
'invoice-status-pending' => 'Pending',
|
||||
'invoice-status-overdue' => 'Overdue',
|
||||
'invoice-status-update' => 'Save changes',
|
||||
'invoice-status-confirmed' => 'The invoice state has been changed.',
|
||||
'invoice-status-error' => 'Could not update the invoice state. ',
|
||||
'shipments' => 'حمل و نقل ها',
|
||||
'order-and-account' => 'سفارش و حساب',
|
||||
'order-info' => 'اطلاعات سفارش',
|
||||
|
|
@ -390,6 +382,7 @@ return [
|
|||
'title' => 'صورت حساب',
|
||||
'id' => 'شناسه',
|
||||
'invoice-id' => 'شناسه صورت حساب',
|
||||
'invoice' => 'صورتحساب',
|
||||
'date' => 'تاریخ صورت حساب',
|
||||
'order-id' => 'شناسه سفارش',
|
||||
'customer-name' => 'نام مشتیر',
|
||||
|
|
@ -1353,7 +1346,16 @@ return [
|
|||
'show-sku' => 'Show SKU',
|
||||
'categories' => 'Categories',
|
||||
'show-sku' => 'Show SKU',
|
||||
'show-search-input-field' => 'Show Search Input Field'
|
||||
'show-search-input-field' => 'Show Search Input Field',
|
||||
'store-name' => 'نام فروشگاه',
|
||||
'vat-number' => 'شماره Vat',
|
||||
'contact-number' => 'شماره تماس',
|
||||
'bank-details' => 'اطلاعات دقیق بانکی',
|
||||
'mailing-address' => 'Send Check to',
|
||||
'instructions' => 'Instructions',
|
||||
'custom-scripts' => 'Custom Scripts',
|
||||
'custom-css' => 'Custom CSS',
|
||||
'custom-javascript' => 'Custom Javascript'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -319,14 +319,6 @@ return [
|
|||
'invoice-btn-title' => 'Fattura',
|
||||
'info' => 'Informazoni',
|
||||
'invoices' => 'Fatture',
|
||||
'invoices-change-title' => 'Change invoice state',
|
||||
'invoices-change-state-desc' => 'Please select the new invoice state:',
|
||||
'invoice-status-paid' => 'Paid',
|
||||
'invoice-status-pending' => 'Pending',
|
||||
'invoice-status-overdue' => 'Overdue',
|
||||
'invoice-status-update' => 'Save changes',
|
||||
'invoice-status-confirmed' => 'The invoice state has been changed.',
|
||||
'invoice-status-error' => 'Could not update the invoice state. ',
|
||||
'shipments' => 'Spedizioni',
|
||||
'order-and-account' => 'Ordine e Account',
|
||||
'order-info' => 'informazioni Ordine',
|
||||
|
|
@ -393,6 +385,7 @@ return [
|
|||
'title' => 'Fatture',
|
||||
'id' => 'Id',
|
||||
'invoice-id' => 'Id Fattura',
|
||||
'invoice' => 'Fattura',
|
||||
'date' => 'Data Fattura',
|
||||
'order-id' => 'Id Ordine',
|
||||
'customer-name' => 'Nome Cliente',
|
||||
|
|
@ -1358,7 +1351,16 @@ return [
|
|||
'show-sku' => 'Show SKU',
|
||||
'categories' => 'Categories',
|
||||
'show-sku' => 'Show SKU',
|
||||
'show-search-input-field' => 'Show Search Input Field'
|
||||
'show-search-input-field' => 'Show Search Input Field',
|
||||
'store-name' => 'Nome del negozio',
|
||||
'vat-number' => 'Partita IVA',
|
||||
'contact-number' => 'Numero di contatto',
|
||||
'bank-details' => 'Coordinate bancarie',
|
||||
'mailing-address' => 'Send Check to',
|
||||
'instructions' => 'Instructions',
|
||||
'custom-scripts' => 'Custom Scripts',
|
||||
'custom-css' => 'Custom CSS',
|
||||
'custom-javascript' => 'Custom Javascript'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -319,14 +319,6 @@ return [
|
|||
'invoice-btn-title' => 'Factuur',
|
||||
'info' => 'Informatie',
|
||||
'invoices' => 'Facturen',
|
||||
'invoices-change-title' => 'Change invoice state',
|
||||
'invoices-change-state-desc' => 'Please select the new invoice state:',
|
||||
'invoice-status-paid' => 'Paid',
|
||||
'invoice-status-pending' => 'Pending',
|
||||
'invoice-status-overdue' => 'Overdue',
|
||||
'invoice-status-update' => 'Save changes',
|
||||
'invoice-status-confirmed' => 'The invoice state has been changed.',
|
||||
'invoice-status-error' => 'Could not update the invoice state. ',
|
||||
'shipments' => 'Verzendingen',
|
||||
'order-and-account' => 'Order and Account',
|
||||
'order-info' => 'Order Information',
|
||||
|
|
@ -391,6 +383,7 @@ return [
|
|||
'title' => 'Facturen',
|
||||
'id' => 'Id',
|
||||
'invoice-id' => 'Factuurnummer',
|
||||
'invoice' => 'Factuur',
|
||||
'date' => 'Factuur datum',
|
||||
'order-id' => 'Bestelnummer',
|
||||
'customer-name' => 'Klantnaam',
|
||||
|
|
@ -1353,7 +1346,16 @@ return [
|
|||
'show-sku' => 'Show SKU',
|
||||
'categories' => 'Categories',
|
||||
'show-sku' => 'Show SKU',
|
||||
'show-search-input-field' => 'Show Search Input Field'
|
||||
'show-search-input-field' => 'Show Search Input Field',
|
||||
'store-name' => 'Winkel naam',
|
||||
'vat-number' => 'Btw-nummer',
|
||||
'contact-number' => 'Contact nummer',
|
||||
'bank-details' => 'Bankgegevens',
|
||||
'mailing-address' => 'Send Check to',
|
||||
'instructions' => 'Instructions',
|
||||
'custom-scripts' => 'Custom Scripts',
|
||||
'custom-css' => 'Custom CSS',
|
||||
'custom-javascript' => 'Custom Javascript'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -317,14 +317,6 @@ return [
|
|||
'invoice-btn-title' => 'Faktura',
|
||||
'info' => 'Informacje',
|
||||
'invoices' => 'Faktury',
|
||||
'invoices-change-title' => 'Change invoice state',
|
||||
'invoices-change-state-desc' => 'Please select the new invoice state:',
|
||||
'invoice-status-paid' => 'Paid',
|
||||
'invoice-status-pending' => 'Pending',
|
||||
'invoice-status-overdue' => 'Overdue',
|
||||
'invoice-status-update' => 'Save changes',
|
||||
'invoice-status-confirmed' => 'The invoice state has been changed.',
|
||||
'invoice-status-error' => 'Could not update the invoice state. ',
|
||||
'shipments' => 'Przesyłki',
|
||||
'order-and-account' => 'Zamówienie i konto',
|
||||
'order-info' => 'Informacje o zamówieniu',
|
||||
|
|
@ -391,6 +383,7 @@ return [
|
|||
'title' => 'Faktury',
|
||||
'id' => 'Id',
|
||||
'invoice-id' => 'Identyfikator faktury',
|
||||
'invoice' => 'Faktura',
|
||||
'date' => 'Data faktury',
|
||||
'order-id' => 'Identyfikator zamówienia',
|
||||
'customer-name' => 'Nazwa klienta',
|
||||
|
|
@ -1342,7 +1335,16 @@ return [
|
|||
'show-sku' => 'Show SKU',
|
||||
'categories' => 'Categories',
|
||||
'show-sku' => 'Show SKU',
|
||||
'show-search-input-field' => 'Show Search Input Field'
|
||||
'show-search-input-field' => 'Show Search Input Field',
|
||||
'store-name' => 'Nazwa sklepu',
|
||||
'vat-number' => 'Numer VAT',
|
||||
'contact-number' => 'Numer kontaktowy',
|
||||
'bank-details' => 'Dane bankowe',
|
||||
'mailing-address' => 'Send Check to',
|
||||
'instructions' => 'Instructions',
|
||||
'custom-scripts' => 'Custom Scripts',
|
||||
'custom-css' => 'Custom CSS',
|
||||
'custom-javascript' => 'Custom Javascript'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
|
@ -318,14 +318,6 @@ return [
|
|||
'invoice-btn-title' => 'Faturar',
|
||||
'info' => 'Informação',
|
||||
'invoices' => 'Faturas',
|
||||
'invoices-change-title' => 'Change invoice state',
|
||||
'invoices-change-state-desc' => 'Please select the new invoice state:',
|
||||
'invoice-status-paid' => 'Paid',
|
||||
'invoice-status-pending' => 'Pending',
|
||||
'invoice-status-overdue' => 'Overdue',
|
||||
'invoice-status-update' => 'Save changes',
|
||||
'invoice-status-confirmed' => 'The invoice state has been changed.',
|
||||
'invoice-status-error' => 'Could not update the invoice state. ',
|
||||
'shipments' => 'Envios',
|
||||
'order-and-account' => 'Pedido e Conta',
|
||||
'order-info' => 'Informação do Pedido',
|
||||
|
|
@ -390,6 +382,7 @@ return [
|
|||
'title' => 'Faturas',
|
||||
'id' => 'Id',
|
||||
'invoice-id' => 'Fatura Id',
|
||||
'invoice' => 'Fatura',
|
||||
'date' => 'Data da Fatura',
|
||||
'order-id' => 'Pedido Id',
|
||||
'customer-name' => 'Nome do Cliente',
|
||||
|
|
@ -1356,7 +1349,16 @@ return [
|
|||
'show-sku' => 'Show SKU',
|
||||
'categories' => 'Categories',
|
||||
'show-sku' => 'Show SKU',
|
||||
'show-search-input-field' => 'Show Search Input Field'
|
||||
'show-search-input-field' => 'Show Search Input Field',
|
||||
'store-name' => 'Nome da loja',
|
||||
'vat-number' => 'Número de IVA',
|
||||
'contact-number' => 'Número de contato',
|
||||
'bank-details' => 'Detalhes bancários',
|
||||
'mailing-address' => 'Send Check to',
|
||||
'instructions' => 'Instructions',
|
||||
'custom-scripts' => 'Custom Scripts',
|
||||
'custom-css' => 'Custom CSS',
|
||||
'custom-javascript' => 'Custom Javascript'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -316,14 +316,6 @@ return [
|
|||
'invoice-btn-title' => 'Fatura',
|
||||
'info' => 'Bilgi',
|
||||
'invoices' => 'Faturalar',
|
||||
'invoices-change-title' => 'Change invoice state',
|
||||
'invoices-change-state-desc' => 'Please select the new invoice state:',
|
||||
'invoice-status-paid' => 'Paid',
|
||||
'invoice-status-pending' => 'Pending',
|
||||
'invoice-status-overdue' => 'Overdue',
|
||||
'invoice-status-update' => 'Save changes',
|
||||
'invoice-status-confirmed' => 'The invoice state has been changed.',
|
||||
'invoice-status-error' => 'Could not update the invoice state. ',
|
||||
'shipments' => 'Kargo',
|
||||
'order-and-account' => 'Sipariş ve Hesap',
|
||||
'order-info' => 'Sipariş Bilgisi',
|
||||
|
|
@ -389,6 +381,7 @@ return [
|
|||
'title' => 'Faturalar',
|
||||
'id' => 'ID',
|
||||
'invoice-id' => 'Fatura No',
|
||||
'invoice' => 'Fatura',
|
||||
'date' => 'Fatura Tarihi',
|
||||
'order-id' => 'Sipariş No',
|
||||
'customer-name' => 'Müşteri Adı',
|
||||
|
|
@ -1339,7 +1332,16 @@ return [
|
|||
'show-offers' => 'Teklifleri Göster',
|
||||
'show-sku' => 'Barkod Göster',
|
||||
'categories' => 'Kategoriler',
|
||||
'show-search-input-field' => 'Arama Giriş Kutusu Göster'
|
||||
'show-search-input-field' => 'Arama Giriş Kutusu Göster',
|
||||
'store-name' => 'Dükkan adı',
|
||||
'vat-number' => 'KDV Numarası',
|
||||
'contact-number' => 'İletişim numarası',
|
||||
'bank-details' => 'Banka detayları',
|
||||
'mailing-address' => 'Send Check to',
|
||||
'instructions' => 'Instructions',
|
||||
'custom-scripts' => 'Custom Scripts',
|
||||
'custom-css' => 'Custom CSS',
|
||||
'custom-javascript' => 'Custom Javascript'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -50,10 +50,12 @@
|
|||
|
||||
<input type="hidden" name="related_products[]" v-for='(product, index) in addedProducts.related_products' v-if="(key == 'related_products') && addedProducts.related_products.length" :value="product.id"/>
|
||||
|
||||
<span class="filter-tag" style="text-transform: capitalize; margin-top: 10px; margin-right: 0px; justify-content: flex-start" v-if="addedProducts[key].length">
|
||||
<span class="wrapper" style="margin-left: 0px; margin-right: 10px;" v-for='(product, index) in addedProducts[key]'>
|
||||
@{{ product.name }}
|
||||
<span class="icon cross-icon" @click="removeProduct(product, key)"></span>
|
||||
<span class="filter-tag linked-product-filter-tag" v-if="addedProducts[key].length">
|
||||
<span class="wrapper linked-product-wrapper " v-for='(product, index) in addedProducts[key]'>
|
||||
<span class="do-not-cross-linked-product-arrow">
|
||||
@{{ product.name }}
|
||||
</span>
|
||||
<span class="icon cross-icon" @click="removeProduct(product, key)"></span>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -130,8 +130,8 @@
|
|||
selector: 'textarea#content',
|
||||
height: 200,
|
||||
width: "100%",
|
||||
plugins: 'image imagetools media wordcount save fullscreen code',
|
||||
toolbar1: 'formatselect | bold italic strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify | numlist bullist outdent indent | removeformat | code',
|
||||
plugins: 'image imagetools media wordcount save fullscreen code table lists link hr',
|
||||
toolbar1: 'formatselect | bold italic strikethrough forecolor backcolor alignleft aligncenter alignright alignjustify | link hr | numlist bullist outdent indent | removeformat | code | table',
|
||||
image_advtab: true,
|
||||
valid_elements : '*[*]'
|
||||
});
|
||||
|
|
|
|||
|
|
@ -213,8 +213,8 @@
|
|||
<img class="item-image" src="{{ $productBaseImage['small_image_url'] }}" />
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
<div class="name">
|
||||
<div class="description do-not-cross-arrow">
|
||||
<div class="name ellipsis">
|
||||
@if (isset($item->name))
|
||||
{{ $item->name }}
|
||||
@endif
|
||||
|
|
@ -265,8 +265,8 @@
|
|||
<span class="icon profile-pic-icon"></span>
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
<div class="name">
|
||||
<div class="description do-not-cross-arrow">
|
||||
<div class="name ellipsis">
|
||||
{{ $item->customer_full_name }}
|
||||
</div>
|
||||
|
||||
|
|
@ -323,8 +323,8 @@
|
|||
<img class="item-image" src="{{ $productBaseImage['small_image_url'] }}" />
|
||||
</div>
|
||||
|
||||
<div class="description">
|
||||
<div class="name">
|
||||
<div class="description do-not-cross-arrow">
|
||||
<div class="name ellipsis">
|
||||
@if (isset($item->product->name))
|
||||
{{ $item->product->name }}
|
||||
@endif
|
||||
|
|
|
|||
|
|
@ -33,9 +33,12 @@
|
|||
|
||||
methods: {
|
||||
onSubmit: function(e) {
|
||||
var this_this = this;
|
||||
e.target.submit();
|
||||
|
||||
this.$root.$set(this.$root.modalIds, 'downloadDataGrid', false);
|
||||
setTimeout(function() {
|
||||
this_this.$root.$set(this_this.$root.modalIds, 'downloadDataGrid', false);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -13,7 +13,10 @@
|
|||
|
||||
<div class="page-action">
|
||||
<div class="export-import" @click="showModal('downloadDataGrid')">
|
||||
<i class="export-icon"></i> <span>{{ __('admin::app.export.export') }}</span>
|
||||
<i class="export-icon"></i>
|
||||
<span>
|
||||
{{ __('admin::app.export.export') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,13 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Cache-control" content="no-cache">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<style type="text/css">
|
||||
* {
|
||||
font-family: DejaVu Sans;
|
||||
}
|
||||
|
||||
body, th, td, h5 {
|
||||
font-size: 12px;
|
||||
color: #000;
|
||||
|
|
@ -72,7 +77,7 @@
|
|||
|
||||
.label {
|
||||
color: #000;
|
||||
font-weight: 600;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.logo {
|
||||
|
|
@ -80,27 +85,56 @@
|
|||
width: 70px;
|
||||
}
|
||||
|
||||
.merchant-details {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.merchant-details-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="background-image: none;background-color: #fff;">
|
||||
<body style="background-image: none; background-color: #fff;">
|
||||
<div class="container">
|
||||
|
||||
<div class="header">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1 class="text-center">{{ __('admin::app.sales.invoices.invoice') }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
@if (core()->getConfigData('sales.orderSettings.invoice_slip_design.logo'))
|
||||
<div class="image">
|
||||
<img class="logo" src="{{ Storage::url(core()->getConfigData('sales.orderSettings.invoice_slip_design.logo')) }}"/>
|
||||
</div>
|
||||
@endif
|
||||
<div class="address">
|
||||
<p>
|
||||
<b> {{ core()->getConfigData('sales.orderSettings.invoice_slip_design.address') }} </b>
|
||||
</p>
|
||||
<div class="merchant-details">
|
||||
<div><span class="merchant-details-title">{{ core()->getConfigData('sales.shipping.origin.store_name') ? core()->getConfigData('sales.shipping.origin.store_name') : '' }}</span></div>
|
||||
<div>{{ core()->getConfigData('sales.shipping.origin.address1') ? core()->getConfigData('sales.shipping.origin.address1') : '' }}</div>
|
||||
<div>
|
||||
<span>{{ core()->getConfigData('sales.shipping.origin.zipcode') ? core()->getConfigData('sales.shipping.origin.zipcode') : '' }}</span>
|
||||
<span>{{ core()->getConfigData('sales.shipping.origin.city') ? core()->getConfigData('sales.shipping.origin.city') : '' }}</span></div>
|
||||
<div>{{ core()->getConfigData('sales.shipping.origin.state') ? core()->getConfigData('sales.shipping.origin.state') : '' }}</div>
|
||||
<div>{{ core()->getConfigData('sales.shipping.origin.country') ? core()->country_name(core()->getConfigData('sales.shipping.origin.country')) : '' }}</div>
|
||||
</div>
|
||||
<div class="merchant-details">
|
||||
@if (core()->getConfigData('sales.shipping.origin.contact'))
|
||||
<div><span class="merchant-details-title">{{ __('admin::app.admin.system.contact-number') }}:</span> {{ core()->getConfigData('sales.shipping.origin.contact') }}</div>
|
||||
@endif
|
||||
@if (core()->getConfigData('sales.shipping.origin.vat_number'))
|
||||
<div><span class="merchant-details-title">{{ __('admin::app.admin.system.vat-number') }}:</span> {{ core()->getConfigData('sales.shipping.origin.vat_number') }}</div>
|
||||
@endif
|
||||
@if (core()->getConfigData('sales.shipping.origin.bank_details'))
|
||||
<div><span class="merchant-details-title">{{ __('admin::app.admin.system.bank-details') }}:</span> {{ core()->getConfigData('sales.shipping.origin.bank_details') }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="invoice-summary">
|
||||
|
||||
<div class="row">
|
||||
<span class="label">{{ __('admin::app.sales.invoices.invoice-id') }} -</span>
|
||||
<span class="value">#{{ $invoice->id }}</span>
|
||||
|
|
@ -112,8 +146,8 @@
|
|||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="label">{{ __('admin::app.sales.invoices.order-date') }} -</span>
|
||||
<span class="value">{{ $invoice->created_at->format('M d, Y') }}</span>
|
||||
<span class="label">{{ __('admin::app.sales.invoices.order-date') }} </span>
|
||||
<span class="value">{{ $invoice->created_at->format('d-m-Y') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="table address">
|
||||
|
|
@ -134,9 +168,9 @@
|
|||
<p>{{ $invoice->order->billing_address->company_name ?? '' }}</p>
|
||||
<p>{{ $invoice->order->billing_address->name }}</p>
|
||||
<p>{{ $invoice->order->billing_address->address1 }}</p>
|
||||
<p>{{ $invoice->order->billing_address->city }}</p>
|
||||
<p>{{ $invoice->order->billing_address->postcode . ' ' .$invoice->order->billing_address->city }} </p>
|
||||
<p>{{ $invoice->order->billing_address->state }}</p>
|
||||
<p>{{ core()->country_name($invoice->order->billing_address->country) }} {{ $invoice->order->billing_address->postcode }}</p>
|
||||
<p>{{ core()->country_name($invoice->order->billing_address->country) }}</p>
|
||||
{{ __('shop::app.checkout.onepage.contact') }} : {{ $invoice->order->billing_address->phone }}
|
||||
</td>
|
||||
@endif
|
||||
|
|
@ -146,9 +180,9 @@
|
|||
<p>{{ $invoice->order->shipping_address->company_name ?? '' }}</p>
|
||||
<p>{{ $invoice->order->shipping_address->name }}</p>
|
||||
<p>{{ $invoice->order->shipping_address->address1 }}</p>
|
||||
<p>{{ $invoice->order->shipping_address->city }}</p>
|
||||
<p>{{ $invoice->order->shipping_address->postcode . ' ' . $invoice->order->shipping_address->city }}</p>
|
||||
<p>{{ $invoice->order->shipping_address->state }}</p>
|
||||
<p>{{ core()->country_name($invoice->order->shipping_address->country) }} {{ $invoice->order->shipping_address->postcode }}</p>
|
||||
<p>{{ core()->country_name($invoice->order->shipping_address->country) }}</p>
|
||||
{{ __('shop::app.checkout.onepage.contact') }} : {{ $invoice->order->shipping_address->phone }}
|
||||
</td>
|
||||
@endif
|
||||
|
|
@ -191,11 +225,11 @@
|
|||
<tr>
|
||||
<th>{{ __('admin::app.sales.orders.SKU') }}</th>
|
||||
<th>{{ __('admin::app.sales.orders.product-name') }}</th>
|
||||
<th>{{ __('admin::app.sales.orders.price') }}</th>
|
||||
<th>{{ __('admin::app.sales.orders.qty') }}</th>
|
||||
<th>{{ __('admin::app.sales.orders.subtotal') }}</th>
|
||||
<th>{{ __('admin::app.sales.orders.tax-amount') }}</th>
|
||||
<th>{{ __('admin::app.sales.orders.grand-total') }}</th>
|
||||
<th class="text-center">{{ __('admin::app.sales.orders.price') }}</th>
|
||||
<th class="text-center">{{ __('admin::app.sales.orders.qty') }}</th>
|
||||
<th class="text-center">{{ __('admin::app.sales.orders.subtotal') }}</th>
|
||||
<th class="text-center">{{ __('admin::app.sales.orders.tax-amount') }}</th>
|
||||
<th class="text-center">{{ __('admin::app.sales.orders.grand-total') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
|
|
@ -218,10 +252,10 @@
|
|||
@endif
|
||||
</td>
|
||||
<td>{{ core()->formatBasePrice($item->base_price) }}</td>
|
||||
<td>{{ $item->qty }}</td>
|
||||
<td>{{ core()->formatBasePrice($item->base_total) }}</td>
|
||||
<td>{{ core()->formatBasePrice($item->base_tax_amount) }}</td>
|
||||
<td>{{ core()->formatBasePrice($item->base_total + $item->base_tax_amount) }}</td>
|
||||
<td class="text-center">{{ $item->qty }}</td>
|
||||
<td class="text-center">{{ core()->formatBasePrice($item->base_total) }}</td>
|
||||
<td class="text-center">{{ core()->formatBasePrice($item->base_tax_amount) }}</td>
|
||||
<td class="text-center">{{ core()->formatBasePrice($item->base_total + $item->base_tax_amount) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
|
|
@ -255,10 +289,10 @@
|
|||
<td>{{ core()->formatBasePrice($invoice->base_discount_amount) }}</td>
|
||||
</tr>
|
||||
|
||||
<tr class="bold">
|
||||
<td>{{ __('admin::app.sales.orders.grand-total') }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ core()->formatBasePrice($invoice->base_grand_total) }}</td>
|
||||
<tr>
|
||||
<td><strong>{{ __('admin::app.sales.orders.grand-total') }}</strong></td>
|
||||
<td><strong>-</strong></td>
|
||||
<td><strong>{{ core()->formatBasePrice($invoice->base_grand_total) }}</strong></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
@extends('admin::layouts.content')
|
||||
@extends('admin::layouts.master')
|
||||
|
||||
@section('page_title')
|
||||
{{ __('admin::app.sales.invoices.view-title', ['invoice_id' => $invoice->id]) }}
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
@section('content-wrapper')
|
||||
|
||||
<?php $order = $invoice->order; ?>
|
||||
|
||||
|
|
@ -15,18 +15,11 @@
|
|||
{!! view_render_event('sales.invoice.title.before', ['order' => $order]) !!}
|
||||
|
||||
<i class="icon angle-left-icon back-link" onclick="history.length > 1 ? history.go(-1) : window.location = '{{ route('admin.dashboard.index') }}';"></i>
|
||||
|
||||
{{ __('admin::app.sales.invoices.view-title', ['invoice_id' => $invoice->id]) }}
|
||||
|
||||
{!! view_render_event('sales.invoice.title.after', ['order' => $order]) !!}
|
||||
</h1>
|
||||
|
||||
@if($invoice->state == 'paid')
|
||||
<small><span class="badge badge-md badge-success">{{ __('admin::app.sales.orders.invoice-status-paid') }}</span></small>
|
||||
@elseif($invoice->state == 'pending')
|
||||
<span class="badge badge-md badge-warning">{{ __('admin::app.sales.orders.invoice-status-pending') }}</span>
|
||||
@else
|
||||
<span class="badge badge-md badge-danger">{{ __('admin::app.sales.orders.invoice-status-overdue') }}</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="page-action">
|
||||
|
|
@ -36,10 +29,6 @@
|
|||
{{ __('admin::app.sales.invoices.print') }}
|
||||
</a>
|
||||
|
||||
@if($invoice->state == "pending" || $invoice->state == "overdue")
|
||||
<a href="#" id="ChangeStatus" class="btn btn-lg btn-primary" @click="showModal('changeInvoiceState')">{{ __('admin::app.sales.orders.invoices-change-title') }}</a>
|
||||
@endif
|
||||
|
||||
{!! view_render_event('sales.invoice.page_action.after', ['order' => $order]) !!}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -48,7 +37,7 @@
|
|||
<div class="sale-container">
|
||||
|
||||
<accordian :title="'{{ __('admin::app.sales.orders.order-and-account') }}'" :active="true">
|
||||
<div slot="body" style="display: flex; overflow:auto;">
|
||||
<div slot="body">
|
||||
|
||||
<div class="sale-section">
|
||||
<div class="secton-title">
|
||||
|
|
@ -57,7 +46,10 @@
|
|||
|
||||
<div class="section-content">
|
||||
<div class="row">
|
||||
<span class="title">{{ __('admin::app.sales.invoices.order-id') }}</span>
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.invoices.order-id') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
<a href="{{ route('admin.sales.orders.view', $order->id) }}">#{{ $order->increment_id }}</a>
|
||||
</span>
|
||||
|
|
@ -66,40 +58,44 @@
|
|||
{!! view_render_event('sales.invoice.increment_id.after', ['order' => $order]) !!}
|
||||
|
||||
<div class="row">
|
||||
<span class="title">{{ __('admin::app.sales.orders.order-date') }}</span>
|
||||
<span class="value">{{ $order->created_at }}</span>
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.order-date') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->created_at }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{!! view_render_event('sales.invoice.created_at.after', ['order' => $order]) !!}
|
||||
|
||||
<div class="row">
|
||||
<span class="title">{{ __('admin::app.sales.orders.order-status') }}</span>
|
||||
<span class="value">{{ $order->status_label }}</span>
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.order-status') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->status_label }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{!! view_render_event('sales.invoice.status_label.after', ['order' => $order]) !!}
|
||||
|
||||
<div class="row">
|
||||
<span class="title">{{ __('admin::app.sales.orders.channel') }}</span>
|
||||
<span class="value">{{ $order->channel_name }}</span>
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.channel') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->channel_name }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{!! view_render_event('sales.invoice.channel_name.after', ['order' => $order]) !!}
|
||||
|
||||
<div class="row">
|
||||
<span class="title">{{ __('admin::app.sales.orders.payment-method') }}</span>
|
||||
<span class="value">{{ core()->getConfigData('sales.paymentmethods.' . $order->payment->method . '.title') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="title">{{ __('admin::app.sales.orders.shipping-method') }}</span>
|
||||
<span class="value">{{ $order->shipping_title }}</span>
|
||||
</div>
|
||||
{!! view_render_event('sales.invoice.shipping-method.after', ['order' => $order]) !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sale-section" style="margin: 0 0 0 300px;">
|
||||
<div class="sale-section">
|
||||
<div class="secton-title">
|
||||
<span>{{ __('admin::app.sales.orders.account-info') }}</span>
|
||||
</div>
|
||||
|
|
@ -184,7 +180,9 @@
|
|||
@foreach ($invoice->items as $item)
|
||||
<tr>
|
||||
<td>{{ $item->getTypeInstance()->getOrderedItem($item)->sku }}</td>
|
||||
<td>{{ $item->name }}
|
||||
|
||||
<td>
|
||||
{{ $item->name }}
|
||||
|
||||
@if (isset($item->additional['attributes']))
|
||||
<div class="item-options">
|
||||
|
|
@ -192,14 +190,19 @@
|
|||
@foreach ($item->additional['attributes'] as $attribute)
|
||||
<b>{{ $attribute['attribute_name'] }} : </b>{{ $attribute['option_label'] }}</br>
|
||||
@endforeach
|
||||
|
||||
</div>
|
||||
@endif
|
||||
</td>
|
||||
|
||||
<td>{{ core()->formatBasePrice($item->base_price) }}</td>
|
||||
|
||||
<td>{{ $item->qty }}</td>
|
||||
|
||||
<td>{{ core()->formatBasePrice($item->base_total) }}</td>
|
||||
|
||||
<td>{{ core()->formatBasePrice($item->base_tax_amount) }}</td>
|
||||
|
||||
@if ($invoice->base_discount_amount > 0)
|
||||
<td>{{ core()->formatBasePrice($item->base_discount_amount) }}</td>
|
||||
@endif
|
||||
|
|
@ -207,6 +210,7 @@
|
|||
<td>{{ core()->formatBasePrice($item->base_total + $item->base_tax_amount - $item->base_discount_amount) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
|
@ -244,61 +248,12 @@
|
|||
<td>{{ core()->formatBasePrice($invoice->base_grand_total) }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<modal id="changeInvoiceState" :is-open="modalIds.changeInvoiceState">
|
||||
<h3 slot="header">{{ __('admin::app.sales.orders.invoices-change-title') }}</h3>
|
||||
<div slot="body">
|
||||
<option-wrapper></option-wrapper>
|
||||
</div>
|
||||
</modal>
|
||||
@stop
|
||||
|
||||
@push('scripts')
|
||||
<script type="text/x-template" id="options-template">
|
||||
<form method="POST" action="{{ route('admin.sales.invoices.update.state', $invoice->id) }}">
|
||||
<div class="page-content">
|
||||
<p>Please select the new invoice state:</p>
|
||||
|
||||
<div class="form-container">
|
||||
@csrf()
|
||||
<div>
|
||||
<input type="radio" name="state" id="paid" value="paid">
|
||||
<label for="paid">{{ __('admin::app.sales.orders.invoice-status-paid') }}</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input type="radio" name="state" id="pending" value="pending" @if($invoice->state == "pending") checked @endif>
|
||||
<label for="pending">{{ __('admin::app.sales.orders.invoice-status-pending') }}</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input type="radio" name="state" id="overdue" value="overdue" @if($invoice->state == "overdue") checked @endif>
|
||||
<label for="overdue">{{ __('admin::app.sales.orders.invoice-status-overdue') }}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<button type="submit" class="btn btn-md btn-primary">{{ __('admin::app.sales.orders.invoice-status-update')}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('option-wrapper', {
|
||||
template: '#options-template',
|
||||
|
||||
methods: {
|
||||
onSubmit: function(e) {
|
||||
// e.target.submit();
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@stop
|
||||
|
|
@ -473,16 +473,8 @@
|
|||
<td>#{{ $invoice->id }}</td>
|
||||
<td>{{ $invoice->created_at }}</td>
|
||||
<td>#{{ $invoice->order->increment_id }}</td>
|
||||
<td>{{ $invoice->order->customer_full_name }}</td>
|
||||
<td>
|
||||
@if($invoice->state == "paid")
|
||||
{{ __('admin::app.sales.orders.invoice-status-paid') }}
|
||||
@elseif($invoice->state == "overdue")
|
||||
{{ __('admin::app.sales.orders.invoice-status-overdue') }}
|
||||
@else
|
||||
{{ __('admin::app.sales.orders.invoice-status-pending') }}
|
||||
@endif
|
||||
</td>
|
||||
<td>{{ $invoice->address->name }}</td>
|
||||
<td>{{ $invoice->status_label }}</td>
|
||||
<td>{{ core()->formatBasePrice($invoice->base_grand_total) }}</td>
|
||||
<td class="action">
|
||||
<a href="{{ route('admin.sales.invoices.view', $invoice->id) }}">
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ class AppointmentSlot extends Booking
|
|||
* @param \Webkul\BookingProduct\Contracts\BookingProduct $bookingProduct
|
||||
* @return bool
|
||||
*/
|
||||
public function haveSufficientQuantity($qty, $bookingProduct)
|
||||
public function haveSufficientQuantity(int $qty, $bookingProduct): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,12 +12,15 @@ use Webkul\BookingProduct\Repositories\BookingProductEventTicketRepository;
|
|||
use Webkul\BookingProduct\Repositories\BookingProductRentalSlotRepository;
|
||||
use Webkul\BookingProduct\Repositories\BookingProductTableSlotRepository;
|
||||
use Webkul\BookingProduct\Repositories\BookingRepository;
|
||||
use Webkul\Product\Datatypes\CartItemValidationResult;
|
||||
use Webkul\Checkout\Models\CartItem;
|
||||
|
||||
|
||||
class Booking
|
||||
{
|
||||
/**
|
||||
* BookingProductRepository
|
||||
*
|
||||
*
|
||||
* @return \Webkul\BookingProduct\Repositories\BookingProductRepository
|
||||
*/
|
||||
protected $bookingProductRepository;
|
||||
|
|
@ -29,7 +32,7 @@ class Booking
|
|||
|
||||
/**
|
||||
* BookingRepository
|
||||
*
|
||||
*
|
||||
* @return \Webkul\BookingProduct\Repositories\BookingRepository
|
||||
*/
|
||||
protected $bookingRepository;
|
||||
|
|
@ -93,7 +96,7 @@ class Booking
|
|||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
public function getTypeHepler($type)
|
||||
public function getTypeHelper($type)
|
||||
{
|
||||
return $this->typeHelpers[$type];
|
||||
}
|
||||
|
|
@ -316,10 +319,10 @@ class Booking
|
|||
|
||||
if ($qty && $currentTime <= $from) {
|
||||
$slots[] = [
|
||||
'from' => $from->format('h:i A'),
|
||||
'to' => $to->format('h:i A'),
|
||||
'timestamp' => $from->getTimestamp() . '-' . $to->getTimestamp(),
|
||||
'qty' => $qty,
|
||||
'from' => $from->format('h:i A'),
|
||||
'to' => $to->format('h:i A'),
|
||||
'timestamp' => $from->getTimestamp() . '-' . $to->getTimestamp(),
|
||||
'qty' => $qty,
|
||||
];
|
||||
}
|
||||
} else {
|
||||
|
|
@ -368,7 +371,7 @@ class Booking
|
|||
public function isSlotExpired($cartItem)
|
||||
{
|
||||
$bookingProduct = $this->bookingProductRepository->findOneByField('product_id', $cartItem['product_id']);
|
||||
|
||||
|
||||
$typeHelper = app($this->typeHelpers[$bookingProduct->type]);
|
||||
|
||||
$slots = $typeHelper->getSlotsByDate($bookingProduct, $cartItem['additional']['booking']['date']);
|
||||
|
|
@ -432,7 +435,7 @@ class Booking
|
|||
'option_label' => Carbon::createFromTimeString($bookingProduct->available_to)->format('d F, Y'),
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case 'rental':
|
||||
|
|
@ -465,7 +468,7 @@ class Booking
|
|||
];
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case 'table':
|
||||
$timestamps = explode('-', $data['booking']['slot']);
|
||||
|
||||
|
|
@ -490,7 +493,7 @@ class Booking
|
|||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
$timestamps = explode('-', $data['booking']['slot']);
|
||||
|
||||
|
|
@ -526,15 +529,24 @@ class Booking
|
|||
/**
|
||||
* Validate cart item product price
|
||||
*
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $item
|
||||
* @return void
|
||||
* @param \Webkul\Checkout\Models\CartItem $item
|
||||
*
|
||||
* @return \Webkul\Product\Datatypes\CartItemValidationResult
|
||||
*/
|
||||
public function validateCartItem($item)
|
||||
public function validateCartItem(CartItem $item): CartItemValidationResult
|
||||
{
|
||||
$result = new CartItemValidationResult();
|
||||
|
||||
if ($this->isCartItemInactive($item)) {
|
||||
$result->itemIsInactive();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$price = $item->product->getTypeInstance()->getFinalPrice($item->quantity);
|
||||
|
||||
if ($price == $item->base_price) {
|
||||
return;
|
||||
return $result;
|
||||
}
|
||||
|
||||
$item->base_price = $price;
|
||||
|
|
@ -544,5 +556,23 @@ class Booking
|
|||
$item->total = core()->convertPrice($price * $item->quantity);
|
||||
|
||||
$item->save();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, if cart item is inactive
|
||||
*
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $item
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCartItemInactive(\Webkul\Checkout\Contracts\CartItem $item): bool
|
||||
{
|
||||
if ($item->product->status === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,8 @@ namespace Webkul\BookingProduct\Helpers;
|
|||
use Illuminate\Support\Facades\DB;
|
||||
use Carbon\Carbon;
|
||||
use Webkul\Checkout\Facades\Cart;
|
||||
use Webkul\Product\Datatypes\CartItemValidationResult;
|
||||
use Webkul\Checkout\Models\CartItem;
|
||||
|
||||
class EventTicket extends Booking
|
||||
{
|
||||
|
|
@ -128,11 +130,20 @@ class EventTicket extends Booking
|
|||
/**
|
||||
* Validate cart item product price
|
||||
*
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $item
|
||||
* @return float
|
||||
* @param \Webkul\Checkout\Models\CartItem $item
|
||||
*
|
||||
* @return \Webkul\Product\Datatypes\CartItemValidationResult
|
||||
*/
|
||||
public function validateCartItem($item)
|
||||
public function validateCartItem(CartItem $item): CartItemValidationResult
|
||||
{
|
||||
$result = new CartItemValidationResult();
|
||||
|
||||
if (parent::isCartItemInactive($item)) {
|
||||
$result->itemIsInactive();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$price = $item->product->getTypeInstance()->getFinalPrice($item->quantity);
|
||||
|
||||
$bookingProduct = $this->bookingProductRepository->findOneByField('product_id', $item->product_id);
|
||||
|
|
@ -140,9 +151,9 @@ class EventTicket extends Booking
|
|||
$ticket = $bookingProduct->event_tickets()->find($item->additional['booking']['ticket_id']);
|
||||
|
||||
if (! $ticket) {
|
||||
Cart::removeItem($item->id);
|
||||
$result->itemIsInactive();
|
||||
|
||||
return true;
|
||||
return $result;
|
||||
}
|
||||
|
||||
if ($this->isInSale($ticket)) {
|
||||
|
|
@ -152,7 +163,7 @@ class EventTicket extends Booking
|
|||
}
|
||||
|
||||
if ($price === $item->base_price) {
|
||||
return;
|
||||
return $result;
|
||||
}
|
||||
|
||||
$item->base_price = $price;
|
||||
|
|
@ -162,6 +173,8 @@ class EventTicket extends Booking
|
|||
$item->total = core()->convertPrice($price * $item->quantity);
|
||||
|
||||
$item->save();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ namespace Webkul\BookingProduct\Helpers;
|
|||
use Illuminate\Support\Facades\DB;
|
||||
use Carbon\Carbon;
|
||||
use Webkul\Checkout\Facades\Cart;
|
||||
use Webkul\Checkout\Models\CartItem;
|
||||
use Webkul\Product\Datatypes\CartItemValidationResult;
|
||||
|
||||
class RentalSlot extends Booking
|
||||
{
|
||||
|
|
@ -159,7 +161,7 @@ class RentalSlot extends Booking
|
|||
return $isExpired;
|
||||
} else {
|
||||
$currentTime = Carbon::now();
|
||||
|
||||
|
||||
$requestedFromDate = Carbon::createFromTimeString($cartItem['additional']['booking']['date_from'] . " 00:00:00");
|
||||
|
||||
$requestedToDate = Carbon::createFromTimeString($cartItem['additional']['booking']['date_to'] . " 23:59:59");
|
||||
|
|
@ -219,11 +221,20 @@ class RentalSlot extends Booking
|
|||
/**
|
||||
* Validate cart item product price
|
||||
*
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $item
|
||||
* @return void|null
|
||||
* @param \Webkul\Checkout\Models\CartItem $item
|
||||
*
|
||||
* @return \Webkul\Product\Datatypes\CartItemValidationResult
|
||||
*/
|
||||
public function validateCartItem($item)
|
||||
public function validateCartItem(CartItem $item): CartItemValidationResult
|
||||
{
|
||||
$result = new CartItemValidationResult();
|
||||
|
||||
if (parent::isCartItemInactive($item)) {
|
||||
$result->itemIsInactive();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$price = $item->product->getTypeInstance()->getFinalPrice($item->quantity);
|
||||
|
||||
$bookingProduct = $this->bookingProductRepository->findOneByField('product_id', $item->product_id);
|
||||
|
|
@ -234,11 +245,11 @@ class RentalSlot extends Booking
|
|||
if (! isset($item->additional['booking']['date_from'])
|
||||
|| ! isset($item->additional['booking']['date_to'])
|
||||
) {
|
||||
Cart::removeItem($item->id);
|
||||
$result->itemIsInactive();
|
||||
|
||||
return true;
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
$from = Carbon::createFromTimeString($item->additional['booking']['date_from'] . " 00:00:00");
|
||||
$to = Carbon::createFromTimeString($item->additional['booking']['date_to'] . " 24:00:00");
|
||||
|
||||
|
|
@ -247,9 +258,9 @@ class RentalSlot extends Booking
|
|||
if (! isset($item->additional['booking']['slot']['from'])
|
||||
|| ! isset($item->additional['booking']['slot']['to'])
|
||||
) {
|
||||
Cart::removeItem($item->id);
|
||||
$result->itemIsInactive();
|
||||
|
||||
return true;
|
||||
return $result;
|
||||
}
|
||||
|
||||
$from = Carbon::createFromTimestamp($item->additional['booking']['slot']['from']);
|
||||
|
|
@ -259,7 +270,7 @@ class RentalSlot extends Booking
|
|||
}
|
||||
|
||||
if ($price == $item->base_price) {
|
||||
return;
|
||||
return $result;
|
||||
}
|
||||
|
||||
$item->base_price = $price;
|
||||
|
|
@ -269,5 +280,7 @@ class RentalSlot extends Booking
|
|||
$item->total = core()->convertPrice($price * $item->quantity);
|
||||
|
||||
$item->save();
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,15 +4,17 @@ namespace Webkul\BookingProduct\Type;
|
|||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Arr;
|
||||
use Webkul\Product\Type\Virtual;
|
||||
use Webkul\Product\Helpers\ProductImage;
|
||||
use Webkul\Product\Repositories\ProductRepository;
|
||||
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||
use Webkul\Product\Repositories\ProductImageRepository;
|
||||
use Webkul\BookingProduct\Helpers\Booking as BookingHelper;
|
||||
use Webkul\Product\Repositories\ProductInventoryRepository;
|
||||
use Webkul\Product\Repositories\ProductAttributeValueRepository;
|
||||
use Webkul\BookingProduct\Repositories\BookingProductRepository;
|
||||
use Webkul\Checkout\Models\CartItem;
|
||||
use Webkul\Product\Datatypes\CartItemValidationResult;
|
||||
use Webkul\Product\Helpers\ProductImage;
|
||||
use Webkul\Product\Repositories\ProductAttributeValueRepository;
|
||||
use Webkul\Product\Repositories\ProductImageRepository;
|
||||
use Webkul\Product\Repositories\ProductInventoryRepository;
|
||||
use Webkul\Product\Repositories\ProductRepository;
|
||||
use Webkul\Product\Type\Virtual;
|
||||
|
||||
class Booking extends Virtual
|
||||
{
|
||||
|
|
@ -152,14 +154,14 @@ class Booking extends Virtual
|
|||
{
|
||||
$bookingProduct = $this->getBookingProduct($this->product->id);
|
||||
|
||||
return app($this->bookingHelper->getTypeHepler($bookingProduct->type))->isItemHaveQuantity($cartItem);
|
||||
return app($this->bookingHelper->getTypeHelper($bookingProduct->type))->isItemHaveQuantity($cartItem);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $qty
|
||||
* @return bool
|
||||
*/
|
||||
public function haveSufficientQuantity($qty)
|
||||
public function haveSufficientQuantity(int $qty): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -198,6 +200,7 @@ class Booking extends Virtual
|
|||
continue;
|
||||
}
|
||||
|
||||
$data['quantity'] = $qty;
|
||||
$data['booking']['ticket_id'] = $ticketId;
|
||||
$cartProducts = parent::prepareForCart($data);
|
||||
|
||||
|
|
@ -211,7 +214,7 @@ class Booking extends Virtual
|
|||
$products = parent::prepareForCart($data);
|
||||
}
|
||||
|
||||
$typeHelper = app($this->bookingHelper->getTypeHepler($bookingProduct->type));
|
||||
$typeHelper = app($this->bookingHelper->getTypeHelper($bookingProduct->type));
|
||||
|
||||
if (! $typeHelper->isSlotAvailable($products)) {
|
||||
return trans('shop::app.checkout.cart.quantity.inventory_warning');
|
||||
|
|
@ -230,17 +233,16 @@ class Booking extends Virtual
|
|||
*/
|
||||
public function compareOptions($options1, $options2)
|
||||
{
|
||||
if ($this->product->id != $options2['product_id']) {
|
||||
if ($this->product->id !== (int) $options2['product_id']) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($options1['booking']) && isset($options2['booking'])) {
|
||||
return $options1['booking'] == $options2['booking'];
|
||||
} elseif (! isset($options1['booking'])) {
|
||||
return false;
|
||||
} elseif (! isset($options2['booking'])) {
|
||||
return false;
|
||||
if (isset($options1['booking'], $options2['booking'])
|
||||
&& $options1['booking']['ticket_id'] === $options2['booking']['ticket_id']) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -257,17 +259,27 @@ class Booking extends Virtual
|
|||
/**
|
||||
* Validate cart item product price
|
||||
*
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $item
|
||||
* @return float
|
||||
* @param \Webkul\Checkout\Models\CartItem $item
|
||||
*
|
||||
* @return \Webkul\Product\Datatypes\CartItemValidationResult
|
||||
*/
|
||||
public function validateCartItem($item)
|
||||
public function validateCartItem(CartItem $item): CartItemValidationResult
|
||||
{
|
||||
$result = new CartItemValidationResult();
|
||||
|
||||
if (parent::isCartItemInactive($item)) {
|
||||
$result->itemIsInactive();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$bookingProduct = $this->getBookingProduct($item->product_id);
|
||||
|
||||
if (! $bookingProduct) {
|
||||
return;
|
||||
$result->cartIsInvalid();
|
||||
return $result;
|
||||
}
|
||||
|
||||
return app($this->bookingHelper->getTypeHepler($bookingProduct->type))->validateCartItem($item);
|
||||
return app($this->bookingHelper->getTypeHelper($bookingProduct->type))->validateCartItem($item);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,27 @@ class CMSPagesTableSeeder extends Seeder
|
|||
'id' => 6,
|
||||
'created_at' => Carbon::now(),
|
||||
'updated_at' => Carbon::now(),
|
||||
]
|
||||
], [
|
||||
'id' => 7,
|
||||
'created_at' => Carbon::now(),
|
||||
'updated_at' => Carbon::now(),
|
||||
], [
|
||||
'id' => 8,
|
||||
'created_at' => Carbon::now(),
|
||||
'updated_at' => Carbon::now(),
|
||||
], [
|
||||
'id' => 9,
|
||||
'created_at' => Carbon::now(),
|
||||
'updated_at' => Carbon::now(),
|
||||
], [
|
||||
'id' => 10,
|
||||
'created_at' => Carbon::now(),
|
||||
'updated_at' => Carbon::now(),
|
||||
], [
|
||||
'id' => 11,
|
||||
'created_at' => Carbon::now(),
|
||||
'updated_at' => Carbon::now(),
|
||||
]
|
||||
]);
|
||||
|
||||
DB::table('cms_page_translations')->insert([
|
||||
|
|
@ -96,7 +116,52 @@ class CMSPagesTableSeeder extends Seeder
|
|||
'meta_title' => 'Contact Us',
|
||||
'meta_description' => '',
|
||||
'meta_keywords' => 'contact, us',
|
||||
]
|
||||
], [
|
||||
'locale' => 'en',
|
||||
'cms_page_id' => 7,
|
||||
'url_key' => 'cutomer-service',
|
||||
'html_content' => '<div class="static-container"><div class="mb-5">Customer service page content</div></div>',
|
||||
'page_title' => 'Customer Service',
|
||||
'meta_title' => 'Customer Service',
|
||||
'meta_description' => '',
|
||||
'meta_keywords' => 'customer, service',
|
||||
], [
|
||||
'locale' => 'en',
|
||||
'cms_page_id' => 8,
|
||||
'url_key' => 'whats-new',
|
||||
'html_content' => '<div class="static-container"><div class="mb-5">What\'s New page content</div></div>',
|
||||
'page_title' => 'What\'s New',
|
||||
'meta_title' => 'What\'s New',
|
||||
'meta_description' => '',
|
||||
'meta_keywords' => 'new',
|
||||
], [
|
||||
'locale' => 'en',
|
||||
'cms_page_id' => 9,
|
||||
'url_key' => 'payment-policy',
|
||||
'html_content' => '<div class="static-container"><div class="mb-5">Payment Policy page content</div></div>',
|
||||
'page_title' => 'Payment Policy',
|
||||
'meta_title' => 'Payment Policy',
|
||||
'meta_description' => '',
|
||||
'meta_keywords' => 'payment, policy',
|
||||
], [
|
||||
'locale' => 'en',
|
||||
'cms_page_id' => 10,
|
||||
'url_key' => 'shipping-policy',
|
||||
'html_content' => '<div class="static-container"><div class="mb-5">Shipping Policy page content</div></div>',
|
||||
'page_title' => 'Shipping Policy',
|
||||
'meta_title' => 'Shipping Policy',
|
||||
'meta_description' => '',
|
||||
'meta_keywords' => 'shipping, policy',
|
||||
], [
|
||||
'locale' => 'en',
|
||||
'cms_page_id' => 11,
|
||||
'url_key' => 'privacy-policy',
|
||||
'html_content' => '<div class="static-container"><div class="mb-5">Privacy Policy page content</div></div>',
|
||||
'page_title' => 'Privacy Policy',
|
||||
'meta_title' => 'Privacy Policy',
|
||||
'meta_description' => '',
|
||||
'meta_keywords' => 'privacy, policy',
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -577,13 +577,13 @@ class CartRule
|
|||
*/
|
||||
public function getCartRuleQuery($customerGroupId, $channelId): \Illuminate\Database\Eloquent\Collection
|
||||
{
|
||||
return $this->cartRuleRepository->scopeQuery(function ($query) use ($customerGroupId) {
|
||||
return $this->cartRuleRepository->scopeQuery(function ($query) use ($customerGroupId, $channelId) {
|
||||
/** @var Builder $query */
|
||||
return $query->leftJoin('cart_rule_customer_groups', 'cart_rules.id', '=',
|
||||
'cart_rule_customer_groups.cart_rule_id')
|
||||
->leftJoin('cart_rule_channels', 'cart_rules.id', '=', 'cart_rule_channels.cart_rule_id')
|
||||
->where('cart_rule_customer_groups.customer_group_id', $customerGroupId)
|
||||
->where('cart_rule_channels.channel_id', core()->getCurrentChannel()->id)
|
||||
->where('cart_rule_channels.channel_id', $channelId)
|
||||
->where(function ($query1) {
|
||||
/** @var Builder $query1 */
|
||||
$query1->where('cart_rules.starts_from', '<=', Carbon::now()->format('Y-m-d'))
|
||||
|
|
@ -602,4 +602,5 @@ class CartRule
|
|||
->orderBy('sort_order', 'asc');
|
||||
})->findWhere(['status' => 1]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,6 +140,10 @@ class Cart
|
|||
|
||||
$product = $this->productRepository->findOneByField('id', $productId);
|
||||
|
||||
if ($product->status === 0) {
|
||||
return ['info' => __('shop::app.checkout.cart.item.inactive-add')];
|
||||
}
|
||||
|
||||
$cartProducts = $product->getTypeInstance()->prepareForCart($data);
|
||||
|
||||
if (is_string($cartProducts)) {
|
||||
|
|
@ -246,6 +250,10 @@ class Cart
|
|||
continue;
|
||||
}
|
||||
|
||||
if ($item->product && $item->product->status === 0) {
|
||||
throw new Exception(__('shop::app.checkout.cart.item.inactive'));
|
||||
}
|
||||
|
||||
if ($quantity <= 0) {
|
||||
$this->removeItem($itemId);
|
||||
|
||||
|
|
@ -285,7 +293,6 @@ class Cart
|
|||
public function getItemByProduct($data)
|
||||
{
|
||||
$items = $this->getCart()->all_items;
|
||||
|
||||
foreach ($items as $item) {
|
||||
if ($item->product->getTypeInstance()->compareOptions($item->additional, $data['additional'])) {
|
||||
if (isset($data['additional']['parent_id'])) {
|
||||
|
|
@ -394,17 +401,20 @@ class Cart
|
|||
*/
|
||||
public function getCart(): ?\Webkul\Checkout\Contracts\Cart
|
||||
{
|
||||
$cart = null;
|
||||
if ($this->getCurrentCustomer()->check()) {
|
||||
return $this->cartRepository->findOneWhere([
|
||||
$cart = $this->cartRepository->findOneWhere([
|
||||
'customer_id' => $this->getCurrentCustomer()->user()->id,
|
||||
'is_active' => 1,
|
||||
]);
|
||||
|
||||
} elseif (session()->has('cart')) {
|
||||
return $this->cartRepository->find(session()->get('cart')->id);
|
||||
$cart = $this->cartRepository->find(session()->get('cart')->id);
|
||||
}
|
||||
|
||||
return null;
|
||||
$this->removeInactiveItems($cart);
|
||||
|
||||
return $cart;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -512,16 +522,14 @@ class Cart
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
public function collectTotals()
|
||||
public function collectTotals(): void
|
||||
{
|
||||
$validated = $this->validateItems();
|
||||
|
||||
if (! $validated) {
|
||||
return false;
|
||||
if (! $this->validateItems()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $cart = $this->getCart()) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
Event::dispatch('checkout.cart.collect.totals.before', $cart);
|
||||
|
|
@ -578,37 +586,41 @@ class Cart
|
|||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validateItems()
|
||||
public function validateItems(): bool
|
||||
{
|
||||
if (! $cart = $this->getCart()) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (count($cart->items) == 0) {
|
||||
if (count($cart->items) === 0) {
|
||||
$this->cartRepository->delete($cart->id);
|
||||
|
||||
return false;
|
||||
} 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;
|
||||
}
|
||||
$isInvalid = false;
|
||||
|
||||
$price = ! is_null($item->custom_price) ? $item->custom_price : $item->base_price;
|
||||
foreach ($cart->items as $item) {
|
||||
$validationResult = $item->product->getTypeInstance()->validateCartItem($item);
|
||||
|
||||
$this->cartItemRepository->update([
|
||||
'price' => core()->convertPrice($price),
|
||||
'base_price' => $price,
|
||||
'total' => core()->convertPrice($price * $item->quantity),
|
||||
'base_total' => $price * $item->quantity,
|
||||
], $item->id);
|
||||
if ($validationResult->isItemInactive()) {
|
||||
$this->removeItem($item->id);
|
||||
$isInvalid = true;
|
||||
session()->flash('info', __('shop::app.checkout.cart.item.inactive'));
|
||||
}
|
||||
|
||||
return true;
|
||||
$price = ! is_null($item->custom_price) ? $item->custom_price : $item->base_price;
|
||||
|
||||
$this->cartItemRepository->update([
|
||||
'price' => core()->convertPrice($price),
|
||||
'base_price' => $price,
|
||||
'total' => core()->convertPrice($price * $item->quantity),
|
||||
'base_total' => $price * $item->quantity,
|
||||
], $item->id);
|
||||
|
||||
$isInvalid |= $validationResult->isCartInvalid();
|
||||
}
|
||||
|
||||
return ! $isInvalid;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -681,8 +693,8 @@ class Cart
|
|||
|
||||
if ($haveTaxRate) {
|
||||
$item->tax_percent = $rate->tax_rate;
|
||||
$item->tax_amount = ($item->total * $rate->tax_rate) / 100;
|
||||
$item->base_tax_amount = ($item->base_total * $rate->tax_rate) / 100;
|
||||
$item->tax_amount = round(($item->total * $rate->tax_rate) / 100, 4);
|
||||
$item->base_tax_amount = round(($item->base_total * $rate->tax_rate) / 100, 4);
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -734,7 +746,13 @@ class Cart
|
|||
*/
|
||||
public function isItemsHaveSufficientQuantity(): bool
|
||||
{
|
||||
foreach ($this->getCart()->items as $item) {
|
||||
$cart = cart()->getCart();
|
||||
|
||||
if (! $cart) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($cart->items as $item) {
|
||||
if (! $this->isItemHaveQuantity($item)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -743,6 +761,41 @@ class Cart
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove cart items, whose product is inactive
|
||||
*
|
||||
* @param \Webkul\Checkout\Models\Cart|null $cart
|
||||
*
|
||||
* @return \Webkul\Checkout\Models\Cart|null
|
||||
*/
|
||||
public function removeInactiveItems(CartModel $cart = null): ?CartModel
|
||||
{
|
||||
if (! $cart) {
|
||||
return $cart;
|
||||
}
|
||||
|
||||
foreach ($cart->items as $item) {
|
||||
if ($this->isCartItemInactive($item)) {
|
||||
|
||||
$this->cartItemRepository->delete($item->id);
|
||||
|
||||
if ($cart->items()->get()->count() == 0) {
|
||||
$this->cartRepository->delete($cart->id);
|
||||
|
||||
if (session()->has('cart')) {
|
||||
session()->forget('cart');
|
||||
}
|
||||
}
|
||||
|
||||
session()->flash('info', __('shop::app.checkout.cart.item.inactive'));
|
||||
}
|
||||
}
|
||||
|
||||
$cart->save();
|
||||
|
||||
return $cart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if all cart items have sufficient quantity.
|
||||
*
|
||||
|
|
@ -1031,6 +1084,17 @@ class Cart
|
|||
return $cart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, if cart item is inactive
|
||||
*
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $item
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isCartItemInactive(\Webkul\Checkout\Contracts\CartItem $item): bool {
|
||||
return $item->product->getTypeInstance()->isCartItemInactive($item);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $user
|
||||
*
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace Webkul\Checkout\Repositories;
|
||||
|
||||
use Webkul\Core\Eloquent\Repository;
|
||||
use Webkul\Checkout\Contracts\CartItem;
|
||||
|
||||
class CartItemRepository extends Repository
|
||||
{
|
||||
|
|
@ -18,16 +19,19 @@ class CartItemRepository extends Repository
|
|||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param int $id
|
||||
* @param string $attribute
|
||||
* @return \Webkul\Checkout\Contracts\CartItem
|
||||
* @param array $data
|
||||
* @param $id
|
||||
* @param string $attribute
|
||||
*
|
||||
* @return \Webkul\Checkout\Contracts\CartItem|null
|
||||
*/
|
||||
public function update(array $data, $id, $attribute = "id")
|
||||
public function update(array $data, $id, $attribute = "id"): ?CartItem
|
||||
{
|
||||
$item = $this->find($id);
|
||||
|
||||
$item->update($data);
|
||||
if ($item) {
|
||||
$item->update($data);
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,20 @@ namespace Webkul\Core\Helpers;
|
|||
|
||||
use Faker\Factory;
|
||||
use Codeception\Module\Laravel5;
|
||||
use Webkul\Attribute\Models\Attribute;
|
||||
use Webkul\Attribute\Models\AttributeOption;
|
||||
use Webkul\BookingProduct\Models\BookingProduct;
|
||||
use Webkul\BookingProduct\Models\BookingProductEventTicket;
|
||||
use Webkul\Checkout\Models\Cart;
|
||||
use Webkul\Checkout\Models\CartAddress;
|
||||
use Webkul\Checkout\Models\CartItem;
|
||||
use Webkul\Customer\Models\Customer;
|
||||
use Webkul\Product\Models\Product;
|
||||
use Webkul\Attribute\Models\Attribute;
|
||||
use Webkul\Checkout\Models\CartAddress;
|
||||
use Webkul\Product\Models\ProductInventory;
|
||||
use Webkul\Customer\Models\CustomerAddress;
|
||||
use Webkul\Attribute\Models\AttributeOption;
|
||||
use Webkul\Product\Models\Product;
|
||||
use Webkul\Product\Models\ProductAttributeValue;
|
||||
use Webkul\Product\Models\ProductDownloadableLink;
|
||||
use Webkul\Product\Models\ProductDownloadableLinkTranslation;
|
||||
use Webkul\Product\Models\ProductInventory;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
|
||||
|
|
@ -212,7 +212,7 @@ class Laravel5Helper extends Laravel5
|
|||
|
||||
$product = $I->createProduct($configs['productAttributes'] ?? [], $productStates);
|
||||
|
||||
$I->createAttributeValues($product->id, $configs['attributeValues'] ?? []);
|
||||
$I->createAttributeValues($product, $configs['attributeValues'] ?? []);
|
||||
|
||||
$I->createInventory($product->id, $configs['productInventory'] ?? []);
|
||||
|
||||
|
|
@ -228,7 +228,7 @@ class Laravel5Helper extends Laravel5
|
|||
|
||||
$product = $I->createProduct($configs['productAttributes'] ?? [], $productStates);
|
||||
|
||||
$I->createAttributeValues($product->id, $configs['attributeValues'] ?? []);
|
||||
$I->createAttributeValues($product, $configs['attributeValues'] ?? []);
|
||||
|
||||
$I->createInventory($product->id, $configs['productInventory'] ?? []);
|
||||
|
||||
|
|
@ -244,7 +244,7 @@ class Laravel5Helper extends Laravel5
|
|||
|
||||
$product = $I->createProduct($configs['productAttributes'] ?? [], $productStates);
|
||||
|
||||
$I->createAttributeValues($product->id, $configs['attributeValues'] ?? []);
|
||||
$I->createAttributeValues($product, $configs['attributeValues'] ?? []);
|
||||
|
||||
$I->createDownloadableLink($product->id);
|
||||
|
||||
|
|
@ -260,7 +260,7 @@ class Laravel5Helper extends Laravel5
|
|||
|
||||
$product = $I->createProduct($configs['productAttributes'] ?? [], $productStates);
|
||||
|
||||
$I->createAttributeValues($product->id, $configs['attributeValues'] ?? []);
|
||||
$I->createAttributeValues($product, $configs['attributeValues'] ?? []);
|
||||
|
||||
$I->createBookingEventProduct($product->id);
|
||||
|
||||
|
|
@ -305,7 +305,7 @@ class Laravel5Helper extends Laravel5
|
|||
]);
|
||||
}
|
||||
|
||||
private function createAttributeValues(int $productId, array $attributeValues = []): void
|
||||
private function createAttributeValues(Product $product, array $attributeValues = []): void
|
||||
{
|
||||
$I = $this;
|
||||
|
||||
|
|
@ -313,7 +313,7 @@ class Laravel5Helper extends Laravel5
|
|||
|
||||
$brand = Attribute::query()
|
||||
->where(['code' => 'brand'])
|
||||
->first(); // usually 25
|
||||
->firstOrFail(); // usually 25
|
||||
|
||||
if (! AttributeOption::query()
|
||||
->where(['attribute_id' => $brand->id])
|
||||
|
|
@ -331,10 +331,10 @@ class Laravel5Helper extends Laravel5
|
|||
* If you do not want this, this defaults can be overriden by $attributeValues.
|
||||
*/
|
||||
$defaultAttributeValues = [
|
||||
'name' => $faker->word,
|
||||
'name' => $faker->words(3, true),
|
||||
'description' => $faker->sentence,
|
||||
'short_description' => $faker->sentence,
|
||||
'sku' => $faker->word,
|
||||
'sku' => $product->sku,
|
||||
'url_key' => $faker->slug,
|
||||
'status' => true,
|
||||
'guest_checkout' => true,
|
||||
|
|
@ -357,7 +357,7 @@ class Laravel5Helper extends Laravel5
|
|||
|
||||
foreach ($possibleAttributeValues as $attributeSet) {
|
||||
$data = [
|
||||
'product_id' => $productId,
|
||||
'product_id' => $product->id,
|
||||
'attribute_id' => $attributeSet->id,
|
||||
];
|
||||
|
||||
|
|
@ -365,7 +365,78 @@ class Laravel5Helper extends Laravel5
|
|||
|
||||
$data[$fieldName] = $attributeValues[$attributeSet->code] ?? null;
|
||||
|
||||
$data = $this->appendAttributeDependencies($attributeSet->code, $data);
|
||||
|
||||
$I->have(ProductAttributeValue::class, $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $attributeCode
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function appendAttributeDependencies(string $attributeCode, array $data): array
|
||||
{
|
||||
$locale = core()->getCurrentLocale()->code;
|
||||
$channel = core()->getCurrentChannelCode();
|
||||
|
||||
$attributeSetDependencies = [
|
||||
'name' => [
|
||||
'locale',
|
||||
'channel',
|
||||
],
|
||||
'tax_category_id' => [
|
||||
'channel',
|
||||
],
|
||||
'short_description' => [
|
||||
'locale',
|
||||
'channel',
|
||||
],
|
||||
'description' => [
|
||||
'locale',
|
||||
'channel',
|
||||
],
|
||||
'cost' => [
|
||||
'channel',
|
||||
],
|
||||
'special_price_from' => [
|
||||
'channel',
|
||||
],
|
||||
'special_price_to' => [
|
||||
'channel',
|
||||
],
|
||||
'meta_title' => [
|
||||
'locale',
|
||||
'channel',
|
||||
],
|
||||
'meta_keywords' => [
|
||||
'locale',
|
||||
'channel',
|
||||
],
|
||||
'meta_description' => [
|
||||
'locale',
|
||||
'channel',
|
||||
],
|
||||
'custom_sale_badge' => [
|
||||
'locale',
|
||||
],
|
||||
];
|
||||
|
||||
if (array_key_exists($attributeCode, $attributeSetDependencies)) {
|
||||
foreach ($attributeSetDependencies[$attributeCode] as $key) {
|
||||
if ($key === 'locale') {
|
||||
$data['locale'] = $locale;
|
||||
}
|
||||
|
||||
if ($key === 'channel') {
|
||||
$data['channel'] = $channel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Core\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Dotenv\Exception\InvalidFileException;
|
||||
use Symfony\Component\Console\Output\ConsoleOutput;
|
||||
|
||||
class EnvValidatorServiceProvider extends ServiceProvider
|
||||
{
|
||||
/*
|
||||
* Set environment variable rules.
|
||||
*/
|
||||
protected $rules = [
|
||||
'DB_PREFIX' => 'not_regex:/[^A-Za-z0-9]/'
|
||||
];
|
||||
|
||||
/*
|
||||
* Set environment variable error messages.
|
||||
*/
|
||||
protected $messages = [
|
||||
'not_regex' => 'DB_PREFIX ENV is not valid.'
|
||||
];
|
||||
|
||||
/**
|
||||
* Bootstrap services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->validateEnvVariables();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate environment variables.
|
||||
*/
|
||||
private function validateEnvVariables()
|
||||
{
|
||||
$validator = Validator::make($_ENV, $this->rules, $this->messages);
|
||||
|
||||
if ($validator->fails()) {
|
||||
$errorKey = collect($validator->errors()->keys())->first();
|
||||
$errorValue = env($errorKey);
|
||||
|
||||
$this->writeErrorAndDie(new InvalidFileException(
|
||||
$this->getErrorMessage('some invalid values', $errorValue)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a friendly error message.
|
||||
*
|
||||
* @param string $cause
|
||||
* @param string $subject
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getErrorMessage($cause, $subject)
|
||||
{
|
||||
return sprintf(
|
||||
'Failed to parse dotenv file due to %s. Failed at [%s].',
|
||||
$cause,
|
||||
strtok($subject, "\n")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the error information to the screen and exit.
|
||||
*
|
||||
* @param \Dotenv\Exception\InvalidFileException $e
|
||||
* @return void
|
||||
*/
|
||||
private function writeErrorAndDie(InvalidFileException $e)
|
||||
{
|
||||
$output = (new ConsoleOutput)->getErrorOutput();
|
||||
|
||||
$output->writeln('The environment file is invalid!');
|
||||
$output->writeln($e->getMessage());
|
||||
|
||||
die(1);
|
||||
}
|
||||
}
|
||||
|
|
@ -53,7 +53,7 @@ class ForgotPasswordController extends Controller
|
|||
);
|
||||
|
||||
if ($response == Password::RESET_LINK_SENT) {
|
||||
session()->flash('success', trans($response));
|
||||
session()->flash('success', trans('customer::app.forget_password.reset_link_sent'));
|
||||
|
||||
return back();
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ class ForgotPasswordController extends Controller
|
|||
return back()
|
||||
->withInput(request(['email']))
|
||||
->withErrors([
|
||||
'email' => trans($response),
|
||||
'email' => trans('customer::app.forget_password.email_not_exist'),
|
||||
]);
|
||||
} catch (\Swift_RfcComplianceException $e) {
|
||||
session()->flash('success', trans('customer::app.forget_password.reset_link_sent'));
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ return [
|
|||
'empty' => 'You have not reviewed any of product yet'
|
||||
],
|
||||
'forget_password' => [
|
||||
'reset_link_sent' => 'We have e-mailed your reset password link.'
|
||||
'reset_link_sent' => 'We have e-mailed your reset password link.',
|
||||
'email_not_exist' => "We can't find a user with that e-mail address"
|
||||
]
|
||||
];
|
||||
|
|
@ -34,6 +34,12 @@ return [
|
|||
'validation' => 'required',
|
||||
'channel_based' => false,
|
||||
'locale_based' => true,
|
||||
], [
|
||||
'name' => 'instructions',
|
||||
'title' => 'admin::app.admin.system.instructions',
|
||||
'type' => 'textarea',
|
||||
'channel_based' => false,
|
||||
'locale_based' => true,
|
||||
], [
|
||||
'name' => 'sort',
|
||||
'title' => 'admin::app.admin.system.sort_order',
|
||||
|
|
@ -80,6 +86,12 @@ return [
|
|||
'validation' => 'required',
|
||||
'channel_based' => false,
|
||||
'locale_based' => true,
|
||||
], [
|
||||
'name' => 'mailing_address',
|
||||
'title' => 'admin::app.admin.system.mailing-address',
|
||||
'type' => 'textarea',
|
||||
'channel_based' => false,
|
||||
'locale_based' => true,
|
||||
], [
|
||||
'name' => 'sort',
|
||||
'title' => 'admin::app.admin.system.sort_order',
|
||||
|
|
|
|||
|
|
@ -68,4 +68,17 @@ class Payment
|
|||
|
||||
return $payment->getRedirectUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns payment method additional information
|
||||
*
|
||||
* @param string $code
|
||||
* @return array
|
||||
*/
|
||||
public static function getAdditionalDetails($code)
|
||||
{
|
||||
$paymentMethodClass = app(Config::get('paymentmethods.' . $code . '.class'));
|
||||
|
||||
return $paymentMethodClass->getAdditionalDetails();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,4 +15,23 @@ class MoneyTransfer extends Payment
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns payment method additional information
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAdditionalDetails()
|
||||
{
|
||||
if (! $this->getConfigData('mailing_address')
|
||||
|| $this->getConfigData('mailing_address') == ''
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'title' => trans('admin::app.admin.system.mailing-address'),
|
||||
'value' => $this->getConfigData('mailing_address'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -121,4 +121,23 @@ abstract class Payment
|
|||
{
|
||||
return $this->getConfigData('sort');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns payment method additional information
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAdditionalDetails()
|
||||
{
|
||||
if (! $this->getConfigData('instructions')
|
||||
|| $this->getConfigData('instructions') == ''
|
||||
) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'title' => trans('admin::app.admin.system.instructions'),
|
||||
'value' => $this->getConfigData('instructions'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -106,8 +106,6 @@ class Ipn
|
|||
|
||||
if ($this->order->canInvoice()) {
|
||||
$invoice = $this->invoiceRepository->create($this->prepareInvoiceData());
|
||||
|
||||
$this->invoiceRepository->updateInvoiceState($invoice, "paid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Product\Datatypes;
|
||||
|
||||
class CartItemValidationResult
|
||||
{
|
||||
/** @var bool $cartIsInvalid */
|
||||
private $cartIsInvalid = false;
|
||||
|
||||
/** @var bool $itemIsInactive */
|
||||
private $itemIsInactive = false;
|
||||
|
||||
/**
|
||||
* Function to check if cart is invalid
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCartInvalid(): bool
|
||||
{
|
||||
return $this->cartIsInvalid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to check if item is inactive
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isItemInactive(): bool
|
||||
{
|
||||
return $this->itemIsInactive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to set if item is inactive
|
||||
*/
|
||||
public function itemIsInactive(): void
|
||||
{
|
||||
$this->itemIsInactive = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to set if cart is invalid
|
||||
*/
|
||||
public function cartIsInvalid(): void
|
||||
{
|
||||
$this->cartIsInvalid = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -272,11 +272,11 @@ class Product extends Model implements ProductContract
|
|||
}
|
||||
|
||||
/**
|
||||
* @param integer $qty
|
||||
* @param int $qty
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function haveSufficientQuantity($qty)
|
||||
public function haveSufficientQuantity(int $qty): bool
|
||||
{
|
||||
return $this->getTypeInstance()->haveSufficientQuantity($qty);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,11 +99,11 @@ class ProductFlat extends Model implements ProductFlatContract
|
|||
}
|
||||
|
||||
/**
|
||||
* @param integer $qty
|
||||
* @param int $qty
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function haveSufficientQuantity($qty)
|
||||
public function haveSufficientQuantity(int $qty): bool
|
||||
{
|
||||
return $this->product->haveSufficientQuantity($qty);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,8 +155,19 @@ class ProductRepository extends Repository
|
|||
$qb->where('product_flat.visible_individually', 1);
|
||||
}
|
||||
|
||||
if (isset($params['search']))
|
||||
if (isset($params['search'])) {
|
||||
$qb->where('product_flat.name', 'like', '%' . urldecode($params['search']) . '%');
|
||||
}
|
||||
|
||||
/* added for api as per the documentation */
|
||||
if (isset($params['name'])) {
|
||||
$qb->where('product_flat.name', 'like', '%' . urldecode($params['name']) . '%');
|
||||
}
|
||||
|
||||
/* added for api as per the documentation */
|
||||
if (isset($params['url_key'])) {
|
||||
$qb->where('product_flat.url_key', 'like', '%' . urldecode($params['url_key']) . '%');
|
||||
}
|
||||
|
||||
# sort direction
|
||||
$orderDirection = 'asc';
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
namespace Webkul\Product\Type;
|
||||
|
||||
use Webkul\Checkout\Facades\Cart;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||
use Webkul\Checkout\Facades\Cart;
|
||||
use Webkul\Product\Datatypes\CartItemValidationResult;
|
||||
use Webkul\Product\Helpers\ProductImage;
|
||||
use Webkul\Product\Models\ProductAttributeValue;
|
||||
use Webkul\Product\Repositories\ProductRepository;
|
||||
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||
use Webkul\Product\Repositories\ProductImageRepository;
|
||||
use Webkul\Product\Repositories\ProductInventoryRepository;
|
||||
use Webkul\Product\Repositories\ProductAttributeValueRepository;
|
||||
|
|
@ -127,12 +128,13 @@ abstract class AbstractType
|
|||
/**
|
||||
* Create a new product type instance.
|
||||
*
|
||||
* @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
|
||||
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
|
||||
* @param \Webkul\Product\Repositories\ProductAttributeValueRepository $attributeValueRepository
|
||||
* @param \Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository
|
||||
* @param \Webkul\Product\Repositories\ProductImageRepository $productImageRepository
|
||||
* @param \Webkul\Product\Helpers\ProductImage $productImageHelper
|
||||
* @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
|
||||
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
|
||||
* @param \Webkul\Product\Repositories\ProductAttributeValueRepository $attributeValueRepository
|
||||
* @param \Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository
|
||||
* @param \Webkul\Product\Repositories\ProductImageRepository $productImageRepository
|
||||
* @param \Webkul\Product\Helpers\ProductImage $productImageHelper
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
|
|
@ -142,8 +144,7 @@ abstract class AbstractType
|
|||
ProductInventoryRepository $productInventoryRepository,
|
||||
ProductImageRepository $productImageRepository,
|
||||
ProductImage $productImageHelper
|
||||
)
|
||||
{
|
||||
) {
|
||||
$this->attributeRepository = $attributeRepository;
|
||||
|
||||
$this->productRepository = $productRepository;
|
||||
|
|
@ -194,7 +195,7 @@ abstract class AbstractType
|
|||
$data[$attribute->code] = isset($data[$attribute->code]) && $data[$attribute->code] ? 1 : 0;
|
||||
}
|
||||
|
||||
if (! isset($data[$attribute->code])) {
|
||||
if (!isset($data[$attribute->code])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -213,7 +214,7 @@ abstract class AbstractType
|
|||
if ($attribute->type == 'image' || $attribute->type == 'file') {
|
||||
$data[$attribute->code] = gettype($data[$attribute->code]) == 'object'
|
||||
? request()->file($attribute->code)->store('product/' . $product->id)
|
||||
: NULL;
|
||||
: null;
|
||||
}
|
||||
|
||||
$attributeValue = $this->attributeValueRepository->findOneWhere([
|
||||
|
|
@ -223,7 +224,7 @@ abstract class AbstractType
|
|||
'locale' => $attribute->value_per_locale ? $data['locale'] : null,
|
||||
]);
|
||||
|
||||
if (! $attributeValue) {
|
||||
if (!$attributeValue) {
|
||||
$this->attributeValueRepository->create([
|
||||
'product_id' => $product->id,
|
||||
'attribute_id' => $attribute->id,
|
||||
|
|
@ -233,7 +234,7 @@ abstract class AbstractType
|
|||
]);
|
||||
} else {
|
||||
$this->attributeValueRepository->update([
|
||||
ProductAttributeValue::$attributeTypeFields[$attribute->type] => $data[$attribute->code]
|
||||
ProductAttributeValue::$attributeTypeFields[$attribute->type] => $data[$attribute->code],
|
||||
], $attributeValue->id
|
||||
);
|
||||
|
||||
|
|
@ -262,7 +263,8 @@ abstract class AbstractType
|
|||
|
||||
$this->productImageRepository->uploadImages($data, $product);
|
||||
|
||||
app('Webkul\Product\Repositories\ProductCustomerGroupPriceRepository')->saveCustomerGroupPrices($data, $product);
|
||||
app('Webkul\Product\Repositories\ProductCustomerGroupPriceRepository')->saveCustomerGroupPrices($data,
|
||||
$product);
|
||||
}
|
||||
|
||||
return $product;
|
||||
|
|
@ -271,7 +273,8 @@ abstract class AbstractType
|
|||
/**
|
||||
* Specify type instance product
|
||||
*
|
||||
* @param \Webkul\Product\Contracts\Product $product
|
||||
* @param \Webkul\Product\Contracts\Product $product
|
||||
*
|
||||
* @return \Webkul\Product\Type\AbstractType
|
||||
*/
|
||||
public function setProduct($product)
|
||||
|
|
@ -308,7 +311,7 @@ abstract class AbstractType
|
|||
*/
|
||||
public function isSaleable()
|
||||
{
|
||||
if (! $this->product->status) {
|
||||
if (!$this->product->status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -356,10 +359,11 @@ abstract class AbstractType
|
|||
}
|
||||
|
||||
/**
|
||||
* @param int $qty
|
||||
* @param int $qty
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function haveSufficientQuantity($qty)
|
||||
public function haveSufficientQuantity(int $qty): bool
|
||||
{
|
||||
return $this->haveSufficientQuantity;
|
||||
}
|
||||
|
|
@ -375,7 +379,8 @@ abstract class AbstractType
|
|||
}
|
||||
|
||||
/**
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $cartItem
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $cartItem
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isItemHaveQuantity($cartItem)
|
||||
|
|
@ -415,7 +420,8 @@ abstract class AbstractType
|
|||
/**
|
||||
* Return true if item can be moved to cart from wishlist
|
||||
*
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $item
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $item
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canBeMovedFromWishlistToCart($item)
|
||||
|
|
@ -426,18 +432,21 @@ abstract class AbstractType
|
|||
/**
|
||||
* Retrieve product attributes
|
||||
*
|
||||
* @param \Webkul\Attribute\Contracts\Group $group
|
||||
* @param bool $skipSuperAttribute
|
||||
* @param \Webkul\Attribute\Contracts\Group $group
|
||||
* @param bool $skipSuperAttribute
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function getEditableAttributes($group = null, $skipSuperAttribute = true)
|
||||
{
|
||||
if ($skipSuperAttribute) {
|
||||
$this->skipAttributes = array_merge($this->product->super_attributes->pluck('code')->toArray(), $this->skipAttributes);
|
||||
$this->skipAttributes = array_merge($this->product->super_attributes->pluck('code')->toArray(),
|
||||
$this->skipAttributes);
|
||||
}
|
||||
|
||||
if (! $group) {
|
||||
return $this->product->attribute_family->custom_attributes()->whereNotIn('attributes.code', $this->skipAttributes)->get();
|
||||
if (!$group) {
|
||||
return $this->product->attribute_family->custom_attributes()->whereNotIn('attributes.code',
|
||||
$this->skipAttributes)->get();
|
||||
}
|
||||
|
||||
return $group->custom_attributes()->whereNotIn('code', $this->skipAttributes)->get();
|
||||
|
|
@ -466,7 +475,8 @@ abstract class AbstractType
|
|||
/**
|
||||
* Get product minimal price
|
||||
*
|
||||
* @param int $qty
|
||||
* @param int $qty
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getMinimalPrice($qty = null)
|
||||
|
|
@ -491,7 +501,8 @@ abstract class AbstractType
|
|||
/**
|
||||
* Get product minimal price
|
||||
*
|
||||
* @param int $qty
|
||||
* @param int $qty
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getFinalPrice($qty = null)
|
||||
|
|
@ -502,7 +513,8 @@ abstract class AbstractType
|
|||
/**
|
||||
* Returns the product's minimal price
|
||||
*
|
||||
* @param int $qty
|
||||
* @param int $qty
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getSpecialPrice($qty = null)
|
||||
|
|
@ -511,7 +523,8 @@ abstract class AbstractType
|
|||
}
|
||||
|
||||
/**
|
||||
* @param int $qty
|
||||
* @param int $qty
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function haveSpecialPrice($qty = null)
|
||||
|
|
@ -520,8 +533,8 @@ abstract class AbstractType
|
|||
|
||||
$rulePrice = app('Webkul\CatalogRule\Helpers\CatalogRuleProductPrice')->getRulePrice($this->product);
|
||||
|
||||
if ((is_null($this->product->special_price) || ! (float) $this->product->special_price)
|
||||
&& ! $rulePrice
|
||||
if ((is_null($this->product->special_price) || !(float)$this->product->special_price)
|
||||
&& !$rulePrice
|
||||
&& $customerGroupPrice == $this->product->price
|
||||
) {
|
||||
return false;
|
||||
|
|
@ -529,7 +542,7 @@ abstract class AbstractType
|
|||
|
||||
$haveSpecialPrice = false;
|
||||
|
||||
if (! (float) $this->product->special_price) {
|
||||
if (!(float)$this->product->special_price) {
|
||||
if ($rulePrice && $rulePrice->price < $this->product->price) {
|
||||
$this->product->special_price = $rulePrice->price;
|
||||
|
||||
|
|
@ -541,7 +554,8 @@ abstract class AbstractType
|
|||
|
||||
$haveSpecialPrice = true;
|
||||
} else {
|
||||
if (core()->isChannelDateInInterval($this->product->special_price_from, $this->product->special_price_to)) {
|
||||
if (core()->isChannelDateInInterval($this->product->special_price_from,
|
||||
$this->product->special_price_to)) {
|
||||
$haveSpecialPrice = true;
|
||||
} elseif ($rulePrice) {
|
||||
$this->product->special_price = $rulePrice->price;
|
||||
|
|
@ -554,7 +568,7 @@ abstract class AbstractType
|
|||
if ($haveSpecialPrice) {
|
||||
$this->product->special_price = min($this->product->special_price, $customerGroupPrice);
|
||||
} else {
|
||||
if ($customerGroupPrice != $this->product->price) {
|
||||
if ($customerGroupPrice !== $this->product->price) {
|
||||
$haveSpecialPrice = true;
|
||||
$this->product->special_price = $customerGroupPrice;
|
||||
}
|
||||
|
|
@ -592,7 +606,7 @@ abstract class AbstractType
|
|||
}
|
||||
)->get();
|
||||
|
||||
if (! $customerGroupPrices->count()) {
|
||||
if (!$customerGroupPrices->count()) {
|
||||
return $product->price;
|
||||
}
|
||||
|
||||
|
|
@ -653,7 +667,7 @@ abstract class AbstractType
|
|||
'final_price' => [
|
||||
'price' => core()->convertPrice($this->getMinimalPrice()),
|
||||
'formated_price' => core()->currency($this->getMinimalPrice()),
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -678,7 +692,8 @@ abstract class AbstractType
|
|||
/**
|
||||
* Add product. Returns error message if can't prepare product.
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function prepareForCart($data)
|
||||
|
|
@ -708,7 +723,7 @@ abstract class AbstractType
|
|||
'base_total_weight' => ($this->product->weight ?? 0) * $data['quantity'],
|
||||
'type' => $this->product->type,
|
||||
'additional' => $this->getAdditionalOptions($data),
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
return $products;
|
||||
|
|
@ -717,7 +732,8 @@ abstract class AbstractType
|
|||
/**
|
||||
* Get request quantity
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getQtyRequest($data)
|
||||
|
|
@ -731,8 +747,9 @@ abstract class AbstractType
|
|||
|
||||
/**
|
||||
*
|
||||
* @param array $options1
|
||||
* @param array $options2
|
||||
* @param array $options1
|
||||
* @param array $options2
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function compareOptions($options1, $options2)
|
||||
|
|
@ -746,9 +763,9 @@ abstract class AbstractType
|
|||
} else {
|
||||
return false;
|
||||
}
|
||||
} elseif (isset($options1['parent_id']) && ! isset($options2['parent_id'])) {
|
||||
} elseif (isset($options1['parent_id']) && !isset($options2['parent_id'])) {
|
||||
return false;
|
||||
} elseif (isset($options2['parent_id']) && ! isset($options1['parent_id'])) {
|
||||
} elseif (isset($options2['parent_id']) && !isset($options1['parent_id'])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -759,7 +776,8 @@ abstract class AbstractType
|
|||
/**
|
||||
* Returns additional information for items
|
||||
*
|
||||
* @param array $data
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAdditionalOptions($data)
|
||||
|
|
@ -770,7 +788,8 @@ abstract class AbstractType
|
|||
/**
|
||||
* Get actual ordered item
|
||||
*
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $item
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $item
|
||||
*
|
||||
* @return \Webkul\Checkout\Contracts\CartItem|\Webkul\Sales\Contracts\OrderItem|\Webkul\Sales\Contracts\InvoiceItem|\Webkul\Sales\Contracts\ShipmentItem|\Webkul\Customer\Contracts\Wishlist
|
||||
*/
|
||||
public function getOrderedItem($item)
|
||||
|
|
@ -781,7 +800,8 @@ abstract class AbstractType
|
|||
/**
|
||||
* Get product base image
|
||||
*
|
||||
* @param \Webkul\Customer\Contracts\CartItem|\Webkul\Checkout\Contracts\CartItem $item
|
||||
* @param \Webkul\Customer\Contracts\CartItem|\Webkul\Checkout\Contracts\CartItem $item
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBaseImage($item)
|
||||
|
|
@ -790,17 +810,26 @@ abstract class AbstractType
|
|||
}
|
||||
|
||||
/**
|
||||
* Validate cart item product price
|
||||
* Validate cart item product price and other things
|
||||
*
|
||||
* @param \Webkul\Customer\Contracts\CartItem $item
|
||||
* @return void
|
||||
* @param \Webkul\Checkout\Models\CartItem $item
|
||||
*
|
||||
* @return \Webkul\Product\Datatypes\CartItemValidationResult
|
||||
*/
|
||||
public function validateCartItem($item)
|
||||
public function validateCartItem(\Webkul\Checkout\Models\CartItem $item): CartItemValidationResult
|
||||
{
|
||||
$result = new CartItemValidationResult();
|
||||
|
||||
if ($this->isCartItemInactive($item)) {
|
||||
$result->itemIsInactive();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$price = $item->product->getTypeInstance()->getFinalPrice($item->quantity);
|
||||
|
||||
if ($price == $item->base_price) {
|
||||
return;
|
||||
return $result;
|
||||
}
|
||||
|
||||
$item->base_price = $price;
|
||||
|
|
@ -810,6 +839,8 @@ abstract class AbstractType
|
|||
$item->total = core()->convertPrice($price * $item->quantity);
|
||||
|
||||
$item->save();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
//get product options
|
||||
|
|
@ -817,4 +848,37 @@ abstract class AbstractType
|
|||
{
|
||||
return $this->productOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, if cart item is inactive
|
||||
*
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $item
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCartItemInactive(\Webkul\Checkout\Contracts\CartItem $item): bool
|
||||
{
|
||||
if ($item->product->status === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch ($item->product->type) {
|
||||
case 'bundle':
|
||||
foreach ($item->children as $child) {
|
||||
if ($child->product->status === 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'configurable':
|
||||
if ($item->child && $item->child->product->status === 0) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
namespace Webkul\Product\Type;
|
||||
|
||||
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||
use Webkul\Product\Datatypes\CartItemValidationResult;
|
||||
use Webkul\Product\Repositories\ProductRepository;
|
||||
use Webkul\Product\Repositories\ProductAttributeValueRepository;
|
||||
use Webkul\Product\Repositories\ProductInventoryRepository;
|
||||
|
|
@ -11,6 +12,7 @@ use Webkul\Product\Repositories\ProductBundleOptionRepository;
|
|||
use Webkul\Product\Repositories\ProductBundleOptionProductRepository;
|
||||
use Webkul\Product\Helpers\ProductImage;
|
||||
use Webkul\Product\Helpers\BundleOption;
|
||||
use Webkul\Checkout\Models\CartItem;
|
||||
|
||||
class Bundle extends AbstractType
|
||||
{
|
||||
|
|
@ -677,23 +679,39 @@ class Bundle extends AbstractType
|
|||
}
|
||||
|
||||
/**
|
||||
* Validate cart item product price
|
||||
* Validate cart item product price and other things
|
||||
*
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $item
|
||||
* @return void
|
||||
* @param \Webkul\Checkout\Models\CartItem $item
|
||||
*
|
||||
* @return \Webkul\Product\Datatypes\CartItemValidationResult
|
||||
*/
|
||||
public function validateCartItem($item)
|
||||
public function validateCartItem(CartItem $item): CartItemValidationResult
|
||||
{
|
||||
$result = new CartItemValidationResult();
|
||||
$price = 0;
|
||||
|
||||
if (parent::isCartItemInactive($item)) {
|
||||
$result->itemIsInactive();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
foreach ($item->children as $childItem) {
|
||||
$childItem->product->getTypeInstance()->validateCartItem($childItem);
|
||||
$childResult = $childItem->product->getTypeInstance()->validateCartItem($childItem);
|
||||
|
||||
if ($childResult->isItemInactive()) {
|
||||
$result->itemIsInactive();
|
||||
}
|
||||
|
||||
if ($childResult->isCartInvalid()) {
|
||||
$result->cartIsInvalid();
|
||||
}
|
||||
|
||||
$price += $childItem->base_price * $childItem->quantity;
|
||||
}
|
||||
|
||||
if ($price == $item->base_price) {
|
||||
return;
|
||||
return $result;
|
||||
}
|
||||
|
||||
$item->base_price = $price;
|
||||
|
|
@ -705,6 +723,8 @@ class Bundle extends AbstractType
|
|||
$item->additional = $this->getAdditionalOptions($item->additional);
|
||||
|
||||
$item->save();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -722,7 +742,7 @@ class Bundle extends AbstractType
|
|||
* @param int $qty
|
||||
* @return bool
|
||||
*/
|
||||
public function haveSufficientQuantity($qty)
|
||||
public function haveSufficientQuantity(int $qty): bool
|
||||
{
|
||||
# to consider a bundle in stock we need to check that at least one product from each required group is available for the given quantity
|
||||
foreach ($this->product->bundle_options as $option) {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,13 @@
|
|||
|
||||
namespace Webkul\Product\Type;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Webkul\Product\Models\ProductFlat;
|
||||
use Webkul\Customer\Contracts\CartItem;
|
||||
use Webkul\Product\Datatypes\CartItemValidationResult;
|
||||
use Webkul\Product\Models\ProductAttributeValue;
|
||||
use Webkul\Product\Models\ProductFlat;
|
||||
use Illuminate\Support\Str;
|
||||
use Webkul\Checkout\Models\CartItem as CartItemModel;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class Configurable extends AbstractType
|
||||
{
|
||||
|
|
@ -541,15 +544,24 @@ class Configurable extends AbstractType
|
|||
/**
|
||||
* Validate cart item product price
|
||||
*
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $item
|
||||
* @return float
|
||||
* @param \Webkul\Product\Type\CartItem $item
|
||||
*
|
||||
* @return \Webkul\Product\Datatypes\CartItemValidationResult
|
||||
*/
|
||||
public function validateCartItem($item)
|
||||
public function validateCartItem(CartItemModel $item): CartItemValidationResult
|
||||
{
|
||||
$result = new CartItemValidationResult();
|
||||
|
||||
if ($this->isCartItemInactive($item)) {
|
||||
$result->itemIsInactive();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$price = $item->child->product->getTypeInstance()->getFinalPrice($item->quantity);
|
||||
|
||||
if ($price == $item->base_price) {
|
||||
return;
|
||||
return $result;
|
||||
}
|
||||
|
||||
$item->base_price = $price;
|
||||
|
|
@ -559,9 +571,17 @@ class Configurable extends AbstractType
|
|||
$item->total = core()->convertPrice($price * $item->quantity);
|
||||
|
||||
$item->save();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
//product options
|
||||
/**
|
||||
* Get product options.
|
||||
*
|
||||
* @param string $product
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getProductOptions($product = "")
|
||||
{
|
||||
$configurableOption = app('Webkul\Product\Helpers\ConfigurableOption');
|
||||
|
|
@ -574,7 +594,7 @@ class Configurable extends AbstractType
|
|||
* @param int $qty
|
||||
* @return bool
|
||||
*/
|
||||
public function haveSufficientQuantity($qty)
|
||||
public function haveSufficientQuantity(int $qty): bool
|
||||
{
|
||||
$backorders = core()->getConfigData('catalog.inventory.stock_options.backorders');
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace Webkul\Product\Type;
|
||||
|
||||
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||
use Webkul\Product\Datatypes\CartItemValidationResult;
|
||||
use Webkul\Product\Repositories\ProductRepository;
|
||||
use Webkul\Product\Repositories\ProductAttributeValueRepository;
|
||||
use Webkul\Product\Repositories\ProductInventoryRepository;
|
||||
|
|
@ -230,11 +231,20 @@ class Downloadable extends AbstractType
|
|||
/**
|
||||
* Validate cart item product price
|
||||
*
|
||||
* @param \Webkul\Checkout\Contracts\CartItem $item
|
||||
* @return float
|
||||
* @param \Webkul\Checkout\Models\CartItem $item
|
||||
*
|
||||
* @return \Webkul\Product\Datatypes\CartItemValidationResult
|
||||
*/
|
||||
public function validateCartItem($item)
|
||||
public function validateCartItem(CartItem $item): CartItemValidationResult
|
||||
{
|
||||
$result = new CartItemValidationResult();
|
||||
|
||||
if (parent::isCartItemInactive($item)) {
|
||||
$result->itemIsInactive();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
$price = $item->product->getTypeInstance()->getFinalPrice($item->quantity);
|
||||
|
||||
foreach ($item->product->downloadable_links as $link) {
|
||||
|
|
@ -246,7 +256,7 @@ class Downloadable extends AbstractType
|
|||
}
|
||||
|
||||
if ($price == $item->base_price) {
|
||||
return;
|
||||
return $result;
|
||||
}
|
||||
|
||||
$item->base_price = $price;
|
||||
|
|
@ -256,5 +266,7 @@ class Downloadable extends AbstractType
|
|||
$item->total = core()->convertPrice($price * $item->quantity);
|
||||
|
||||
$item->save();
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
@ -106,7 +106,7 @@ class Grouped extends AbstractType
|
|||
*/
|
||||
public function getChildrenIds()
|
||||
{
|
||||
return array_unique($this->product->grouped_products()->pluck('product_id')->toArray());
|
||||
return array_unique($this->product->grouped_products()->pluck('associated_product_id')->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -139,6 +139,22 @@ class Grouped extends AbstractType
|
|||
return min($minPrices);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isSaleable()
|
||||
{
|
||||
if (!$this->product->status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ProductFlat::query()->select('id')->whereIn('product_id', $this->getChildrenIds())->where('status', 0)->first()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get group product special price
|
||||
*
|
||||
|
|
|
|||
|
|
@ -53,12 +53,12 @@ class Simple extends AbstractType
|
|||
* @param int $qty
|
||||
* @return bool
|
||||
*/
|
||||
public function haveSufficientQuantity($qty)
|
||||
public function haveSufficientQuantity(int $qty): bool
|
||||
{
|
||||
$backorders = core()->getConfigData('catalog.inventory.stock_options.backorders');
|
||||
|
||||
$backorders = ! is_null ($backorders) ? $backorders : false;
|
||||
|
||||
|
||||
return $qty <= $this->totalQuantity() ? true : $backorders;
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@ class Virtual extends AbstractType
|
|||
|
||||
/**
|
||||
* These blade files will be included in product edit page
|
||||
*
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $additionalViews = [
|
||||
|
|
@ -60,7 +60,7 @@ class Virtual extends AbstractType
|
|||
* @param int $qty
|
||||
* @return bool
|
||||
*/
|
||||
public function haveSufficientQuantity($qty)
|
||||
public function haveSufficientQuantity(int $qty): bool
|
||||
{
|
||||
return $qty <= $this->totalQuantity() ? true : false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,12 +55,6 @@ return [
|
|||
'validation' => 'mimes:jpeg,bmp,png,jpg',
|
||||
'channel_based' => true,
|
||||
],
|
||||
[
|
||||
'name' => 'address',
|
||||
'title' => 'admin::app.admin.system.address',
|
||||
'type' => 'textarea',
|
||||
'channel_based' => true,
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
|
|
@ -282,12 +282,6 @@ class Order extends Model implements OrderContract
|
|||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->invoices as $item) {
|
||||
if ($item->state == 'pending' || $item->state == 'overdue') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->items as $item) {
|
||||
if ($item->qty_to_refund > 0 && $item->order->status !== self::STATUS_CLOSED) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ class InvoiceRepository extends Repository
|
|||
$invoice = $this->model->create([
|
||||
'order_id' => $order->id,
|
||||
'total_qty' => $totalQty,
|
||||
'state' => 'pending',
|
||||
'state' => 'paid',
|
||||
'base_currency_code' => $order->base_currency_code,
|
||||
'channel_currency_code' => $order->channel_currency_code,
|
||||
'order_currency_code' => $order->order_currency_code,
|
||||
|
|
@ -192,8 +192,11 @@ class InvoiceRepository extends Repository
|
|||
}
|
||||
|
||||
$this->collectTotals($invoice);
|
||||
|
||||
$this->orderRepository->collectTotals($order);
|
||||
|
||||
$this->orderRepository->updateOrderStatus($order);
|
||||
|
||||
Event::dispatch('sales.invoice.save.after', $invoice);
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
|
|
@ -253,21 +256,4 @@ class InvoiceRepository extends Repository
|
|||
|
||||
return $invoice;
|
||||
}
|
||||
|
||||
/*
|
||||
* @param \Webkul\Sales\Contracts\Invoice $invoice
|
||||
* @return void
|
||||
*/
|
||||
public function updateInvoiceState($invoice, $status)
|
||||
{
|
||||
$invoice->state = $status;
|
||||
$invoice->save();
|
||||
|
||||
if ($status == 'paid'){
|
||||
$order = $this->orderRepository->findOrFail($invoice->order->id);
|
||||
$this->orderRepository->updateOrderStatus($order);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -156,5 +156,28 @@ class OrderItemRepository extends Repository
|
|||
}
|
||||
|
||||
$orderedInventory->update(['qty' => $qty]);
|
||||
|
||||
if ($orderItem->getTypeInstance()->isStockable()) {
|
||||
$shipmentItems = $orderItem->parent ? $orderItem->parent->shipment_items : $orderItem->shipment_items;
|
||||
|
||||
if ($shipmentItems) {
|
||||
foreach ($shipmentItems as $shipmentItem) {
|
||||
if ($orderItem->parent) {
|
||||
$shippedQty = $orderItem->qty_ordered
|
||||
? ($orderItem->qty_ordered / $orderItem->parent->qty_ordered) * $shipmentItem->qty
|
||||
: $orderItem->parent->qty_ordered;
|
||||
} else {
|
||||
$shippedQty = $shipmentItem->qty;
|
||||
}
|
||||
|
||||
$inventory = $orderItem->product->inventories()
|
||||
// ->where('vendor_id', $data['vendor_id'])
|
||||
->where('inventory_source_id', $shipmentItem->shipment->inventory_source_id)
|
||||
->first();
|
||||
|
||||
$inventory->update(['qty' => $inventory->qty + $shippedQty]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -107,6 +107,13 @@ return [
|
|||
'validation' => 'required',
|
||||
'channel_based' => true,
|
||||
'locale_based' => true,
|
||||
], [
|
||||
'name' => 'city',
|
||||
'title' => 'admin::app.admin.system.city',
|
||||
'type' => 'text',
|
||||
'validation' => 'required',
|
||||
'channel_based' => true,
|
||||
'locale_based' => false,
|
||||
], [
|
||||
'name' => 'address1',
|
||||
'title' => 'admin::app.admin.system.street-address',
|
||||
|
|
@ -122,12 +129,25 @@ return [
|
|||
'channel_based' => true,
|
||||
'locale_based' => false,
|
||||
], [
|
||||
'name' => 'city',
|
||||
'title' => 'admin::app.admin.system.city',
|
||||
'name' => 'store_name',
|
||||
'title' => 'admin::app.admin.system.store-name',
|
||||
'type' => 'text',
|
||||
'validation' => 'required',
|
||||
'channel_based' => true,
|
||||
'locale_based' => false,
|
||||
], [
|
||||
'name' => 'vat_number',
|
||||
'title' => 'admin::app.admin.system.vat-number',
|
||||
'type' => 'text',
|
||||
'channel_based' => true,
|
||||
], [
|
||||
'name' => 'contact',
|
||||
'title' => 'admin::app.admin.system.contact-number',
|
||||
'type' => 'text',
|
||||
'channel_based' => true,
|
||||
], [
|
||||
'name' => 'bank_details',
|
||||
'title' => 'admin::app.admin.system.bank-details',
|
||||
'type' => 'textarea',
|
||||
'channel_based' => true,
|
||||
]
|
||||
]
|
||||
]
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"/js/shop.js": "/js/shop.js?id=d64fdfe9e3fe3e4b9ee4",
|
||||
"/css/shop.css": "/css/shop.css?id=8ef1aa65dda3180b66ee"
|
||||
"/css/shop.css": "/css/shop.css?id=dbbe4951362b3f0ea3e2"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,9 +69,7 @@ class CartController extends Controller
|
|||
try {
|
||||
$result = Cart::addProduct($id, request()->all());
|
||||
|
||||
if ($this->onWarningAddingToCart($result)) {
|
||||
session()->flash('warning', $result['warning']);
|
||||
|
||||
if ($this->onFailureAddingToCart($result)) {
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
|
|
@ -89,7 +87,7 @@ class CartController extends Controller
|
|||
}
|
||||
}
|
||||
} catch(\Exception $e) {
|
||||
session()->flash('error', __($e->getMessage()));
|
||||
session()->flash('warning', __($e->getMessage()));
|
||||
|
||||
$product = $this->productRepository->find($id);
|
||||
|
||||
|
|
@ -209,13 +207,25 @@ class CartController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true, if result of adding product to cart is an array and contains a key "warning"
|
||||
* Returns true, if result of adding product to cart
|
||||
* is an array and contains a key "warning" or "info"
|
||||
*
|
||||
* @param array $result
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function onWarningAddingToCart($result): bool
|
||||
private function onFailureAddingToCart($result): bool
|
||||
{
|
||||
return is_array($result) && isset($result['warning']);
|
||||
if (is_array($result) && isset($result['warning'])) {
|
||||
session()->flash('warning', $result['warning']);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_array($result) && isset($result['info'])) {
|
||||
session()->flash('info', $result['info']);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2830,6 +2830,23 @@ section.cart {
|
|||
.control-info {
|
||||
margin-left: 28px;
|
||||
}
|
||||
|
||||
.instructions {
|
||||
margin-top: 10px;
|
||||
margin-left: 30px;
|
||||
|
||||
label {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
font-size: 14px;
|
||||
color: #777777;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.address-summary {
|
||||
|
|
@ -4101,6 +4118,11 @@ section.review {
|
|||
margin-left: 0px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.downloadable-container .link-list ul li a {
|
||||
float: left;
|
||||
margin-top: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4596,6 +4618,14 @@ body {
|
|||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.mt-0 {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.desc > p {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.comparison-component > h1 {
|
||||
display: inline-block;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -484,6 +484,8 @@ return [
|
|||
'success' => 'تم بنجاح إضافة العنصر إلى العربة',
|
||||
'success-remove' => 'تم إزالة العنصر بنجاح من العربة',
|
||||
'error-add' => 'لا يمكن إضافة العنصر إلى العربة ، رجاء حاول مرة أخرى ',
|
||||
'inactive' => 'An item is inactive and was removed from cart',
|
||||
'inactive-add' => 'Inactive item cannot be added to cart',
|
||||
],
|
||||
'quantity-error' => 'الكمية المطلوبة غير متوفرة',
|
||||
'cart-subtotal' => 'المجموع الفرعي للمشتريات',
|
||||
|
|
|
|||
|
|
@ -481,6 +481,8 @@ return [
|
|||
'success' => 'Artikel wurde erfolgreich zum Warenkorb hinzugefügt',
|
||||
'success-remove' => 'Artikel wurde erfolgreich aus dem Warenkorb entfernt',
|
||||
'error-add' => 'Artikel kann nicht zum Warenkorb hinzugefügt werden. Bitte versuchen Sie es später erneut',
|
||||
'inactive' => 'Ein Artikel ist inaktiv und wurde aus dem Warenkorb entfernt.',
|
||||
'inactive-add' => 'Ein inaktiver Artikel kann nicht zum Warenkorb hinzugefügt werde.',
|
||||
],
|
||||
'quantity-error' => 'Die angeforderte Menge ist nicht verfügbar',
|
||||
'cart-subtotal' => 'Warenkorb Zwischensumme',
|
||||
|
|
|
|||
|
|
@ -484,6 +484,8 @@ return [
|
|||
'success' => 'Item was successfully added to cart.',
|
||||
'success-remove' => 'Item was removed successfully from the cart.',
|
||||
'error-add' => 'Item cannot be added to cart, please try again later.',
|
||||
'inactive' => 'An item is inactive and was removed from cart.',
|
||||
'inactive-add' => 'Inactive item cannot be added to cart.',
|
||||
],
|
||||
'quantity-error' => 'Requested quantity is not available.',
|
||||
'cart-subtotal' => 'Cart Subtotal',
|
||||
|
|
|
|||
|
|
@ -451,6 +451,8 @@ return [
|
|||
'success' => 'El artículp se añadió a la cesta',
|
||||
'success-remove' => 'El artículo se eliminó de la cesta',
|
||||
'error-add' => 'El artículo no se puede añadir a la cesta, inténtelo más tarde',
|
||||
'inactive' => 'An item is inactive and was removed from cart',
|
||||
'inactive-add' => 'Inactive item cannot be added to cart',
|
||||
],
|
||||
'quantity-error' => 'La cantidad solicitada no está disponible',
|
||||
'cart-subtotal' => 'Total parcial',
|
||||
|
|
|
|||
|
|
@ -483,6 +483,8 @@ return [
|
|||
'success' => 'مورد با موفقیت به سبد خرید اضافه شد',
|
||||
'success-remove' => 'مورد با موفقیت از سبد خرید حذف شد',
|
||||
'error-add' => 'لطفاً موردی را به سبد خرید اضافه نکرد ، لطفا بعداً دوباره امتحان کنید',
|
||||
'inactive' => 'An item is inactive and was removed from cart',
|
||||
'inactive-add' => 'Inactive item cannot be added to cart',
|
||||
],
|
||||
|
||||
'quantity-error' => 'مقدار درخواستی در دسترس نیست',
|
||||
|
|
|
|||
|
|
@ -481,6 +481,8 @@ return [
|
|||
'success' => 'Prodotto aggiunto al carrello.',
|
||||
'success-remove' => 'Prodotto rimosso dal carrello.',
|
||||
'error-add' => 'Il prodotto non può essere aggiunto al carrello, prova ancora.',
|
||||
'inactive' => 'An item is inactive and was removed from cart.',
|
||||
'inactive-add' => 'Inactive item cannot be added to cart.',
|
||||
],
|
||||
'quantity-error' => 'La quantità richiesta non è disponibile.',
|
||||
'cart-subtotal' => 'Subtotale Carrello',
|
||||
|
|
|
|||
|
|
@ -445,6 +445,8 @@ return [
|
|||
'success' => 'アイテムがカートに追加されました。',
|
||||
'success-remove' => 'アイテムがカートから削除されました。',
|
||||
'error-add' => 'アイテムをカートに追加できません。しばらくしてから再度お試し下さい。',
|
||||
'inactive' => 'An item is inactive and was removed from cart',
|
||||
'inactive-add' => 'Inactive item cannot be added to cart',
|
||||
],
|
||||
'quantity-error' => 'ご希望の数量の在庫が現在ございません。',
|
||||
'cart-subtotal' => '小計',
|
||||
|
|
|
|||
|
|
@ -488,6 +488,8 @@ return [
|
|||
'success' => 'Artikel is succesvol toegevoegd aan winkelwagen.',
|
||||
'success-remove' => 'Item is met succes uit de winkelwagen verwijderd.',
|
||||
'error-add' => 'Item kan niet aan winkelwagen worden toegevoegd. Probeer het later opnieuw.',
|
||||
'inactive' => 'An item is inactive and was removed from cart.',
|
||||
'inactive-add' => 'Inactive item cannot be added to cart.',
|
||||
],
|
||||
'quantity-error' => 'Gevraagde hoeveelheid is niet beschikbaar.',
|
||||
'cart-subtotal' => 'Subtotaal',
|
||||
|
|
|
|||
|
|
@ -481,6 +481,8 @@ return [
|
|||
'success' => 'Produkt został pomyślnie dodany do koszyka.',
|
||||
'success-remove' => 'Produkt został pomyślnie usunięty z koszyka.',
|
||||
'error-add' => 'Nie można dodać produktu do koszyka, spróbuj ponownie później.',
|
||||
'inactive' => 'An item is inactive and was removed from cart.',
|
||||
'inactive-add' => 'Inactive item cannot be added to cart.',
|
||||
],
|
||||
'quantity-error' => 'Żądana ilość nie jest dostępna.',
|
||||
'cart-subtotal' => 'Suma częściowa koszyka',
|
||||
|
|
|
|||
|
|
@ -473,6 +473,8 @@ return [
|
|||
'success' => 'Item foi adicionado com sucesso ao carrinho',
|
||||
'success-remove' => 'Item foi removido com sucesso do carrinho',
|
||||
'error-add' => 'Item não pode ser adicionado ao carrinho, por favor, tente novamente mais tarde',
|
||||
'inactive' => 'An item is inactive and was removed from cart',
|
||||
'inactive-add' => 'Inactive item cannot be added to cart',
|
||||
],
|
||||
'quantity-error' => 'Quantidade solicitada não está disponível',
|
||||
'cart-subtotal' => 'Subtotal do carrinho',
|
||||
|
|
|
|||
|
|
@ -481,6 +481,8 @@ return [
|
|||
'success' => 'Ürün başarıyla sepete eklendi.',
|
||||
'success-remove' => 'Ürün sepetten başarıyla kaldırıldı.',
|
||||
'error-add' => 'Ürün sepete eklenirken hata oluştu, lütfen tekrar deneyin.',
|
||||
'inactive' => 'An item is inactive and was removed from cart.',
|
||||
'inactive-add' => 'Inactive item cannot be added to cart.',
|
||||
],
|
||||
'quantity-error' => 'Girilen miktar mevcut değil.',
|
||||
'cart-subtotal' => 'Sepet Ara Toplam',
|
||||
|
|
|
|||
|
|
@ -26,6 +26,15 @@
|
|||
<div class="line-two mt-5">
|
||||
<span class="method-summary">{{ __($payment['description']) }}</span>
|
||||
</div>
|
||||
|
||||
<?php $additionalDetails = \Webkul\Payment\Payment::getAdditionalDetails($payment['method']); ?>
|
||||
|
||||
@if (! empty($additionalDetails))
|
||||
<div class="instructions" v-show="payment.method == '{{$payment['method']}}'">
|
||||
<label>{{ $additionalDetails['title'] }}</label>
|
||||
<p>{{ $additionalDetails['value'] }}</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{!! view_render_event('bagisto.shop.checkout.payment-method.after', ['payment' => $payment]) !!}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
<div class="account-layout">
|
||||
<div class="account-head mb-15">
|
||||
<span class="back-icon"><a href="{{ route('customer.account.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
<span class="back-icon"><a href="{{ route('customer.address.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
<span class="account-heading">{{ __('shop::app.customer.account.address.create.title') }}</span>
|
||||
<span></span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
<div class="account-layout">
|
||||
|
||||
<div class="account-head mb-15">
|
||||
<span class="back-icon"><a href="{{ route('customer.account.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
<span class="back-icon"><a href="{{ route('customer.address.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
<span class="account-heading">{{ __('shop::app.customer.account.address.edit.title') }}</span>
|
||||
<span></span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -13,8 +13,7 @@
|
|||
<div class="account-layout">
|
||||
|
||||
<div class="account-head">
|
||||
<span class="back-icon"><a href="{{ route('customer.account.index') }}"><i
|
||||
class="icon icon-menu-back"></i></a></span>
|
||||
<span class="back-icon"><a href="{{ route('customer.profile.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
<span
|
||||
class="account-heading">{{ __('shop::app.customer.account.address.index.title') }}</span>
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
<div class="account-layout">
|
||||
|
||||
<div class="account-head mb-10">
|
||||
<span class="back-icon"><a href="{{ route('customer.account.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
<span class="back-icon"><a href="{{ route('customer.profile.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
<span class="account-heading">
|
||||
{{ __('shop::app.customer.account.downloadable_products.title') }}
|
||||
</span>
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
<div class="account-table-content">
|
||||
|
||||
{!! app('Webkul\Shop\DataGrids\DownloadableProductDataGrid')->render() !!}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
<div class="account-layout">
|
||||
|
||||
<div class="account-head mb-10">
|
||||
<span class="back-icon"><a href="{{ route('customer.account.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
<span class="back-icon"><a href="{{ route('customer.profile.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
<span class="account-heading">
|
||||
{{ __('shop::app.customer.account.order.index.title') }}
|
||||
</span>
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
<div class="account-table-content">
|
||||
|
||||
{!! app('Webkul\Shop\DataGrids\OrderDataGrid')->render() !!}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,13 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Cache-control" content="no-cache">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
|
||||
<style type="text/css">
|
||||
* {
|
||||
font-family: DejaVu Sans;
|
||||
}
|
||||
|
||||
body, th, td, h5 {
|
||||
font-size: 12px;
|
||||
color: #000;
|
||||
|
|
@ -48,7 +53,6 @@
|
|||
border-left: solid 1px #d3d3d3;
|
||||
color: #3A3A3A;
|
||||
vertical-align: middle;
|
||||
font-family: DejaVu Sans; sans-serif;
|
||||
}
|
||||
|
||||
.table tbody td p {
|
||||
|
|
@ -66,17 +70,15 @@
|
|||
|
||||
.sale-summary tr td {
|
||||
padding: 3px 5px;
|
||||
font-family: DejaVu Sans; sans-serif;
|
||||
}
|
||||
|
||||
.sale-summary tr.bold {
|
||||
font-family: DejaVu Sans; sans-serif;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.label {
|
||||
color: #000;
|
||||
font-weight: 600;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.logo {
|
||||
|
|
@ -84,6 +86,17 @@
|
|||
width: 70px;
|
||||
}
|
||||
|
||||
.merchant-details {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.merchant-details-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
|
|
@ -91,16 +104,35 @@
|
|||
<div class="container">
|
||||
|
||||
<div class="header">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<h1 class="text-center">{{ __('admin::app.sales.invoices.invoice') }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
@if (core()->getConfigData('sales.orderSettings.invoice_slip_design.logo'))
|
||||
<div class="image">
|
||||
<img class="logo" src="{{ Storage::url(core()->getConfigData('sales.orderSettings.invoice_slip_design.logo')) }}"/>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="address">
|
||||
<p>
|
||||
<b> {{ core()->getConfigData('sales.orderSettings.invoice_slip_design.address') }} </b>
|
||||
</p>
|
||||
<div class="merchant-details">
|
||||
<div><span class="merchant-details-title">{{ core()->getConfigData('sales.shipping.origin.store_name') ? core()->getConfigData('sales.shipping.origin.store_name') : '' }}</span></div>
|
||||
<div>{{ core()->getConfigData('sales.shipping.origin.address1') ? core()->getConfigData('sales.shipping.origin.address1') : '' }}</div>
|
||||
<div>
|
||||
<span>{{ core()->getConfigData('sales.shipping.origin.zipcode') ? core()->getConfigData('sales.shipping.origin.zipcode') : '' }}</span>
|
||||
<span>{{ core()->getConfigData('sales.shipping.origin.city') ? core()->getConfigData('sales.shipping.origin.city') : '' }}</span></div>
|
||||
<div>{{ core()->getConfigData('sales.shipping.origin.state') ? core()->getConfigData('sales.shipping.origin.state') : '' }}</div>
|
||||
<div>{{ core()->getConfigData('sales.shipping.origin.country') ? core()->country_name(core()->getConfigData('sales.shipping.origin.country')) : '' }}</div>
|
||||
</div>
|
||||
<div class="merchant-details">
|
||||
@if (core()->getConfigData('sales.shipping.origin.contact'))
|
||||
<div><span class="merchant-details-title">{{ __('admin::app.admin.system.contact-number') }}:</span> {{ core()->getConfigData('sales.shipping.origin.contact') }}</div>
|
||||
@endif
|
||||
@if (core()->getConfigData('sales.shipping.origin.vat_number'))
|
||||
<div><span class="merchant-details-title">{{ __('admin::app.admin.system.vat-number') }}:</span> {{ core()->getConfigData('sales.shipping.origin.vat_number') }}</div>
|
||||
@endif
|
||||
@if (core()->getConfigData('sales.shipping.origin.bank_details'))
|
||||
<div><span class="merchant-details-title">{{ __('admin::app.admin.system.bank-details') }}:</span> {{ core()->getConfigData('sales.shipping.origin.bank_details') }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -108,17 +140,17 @@
|
|||
|
||||
<div class="row">
|
||||
<span class="label">{{ __('shop::app.customer.account.order.view.invoice-id') }} -</span>
|
||||
<span class="value">{{ $invoice->id }}</span>
|
||||
<span class="value">#{{ $invoice->id }}</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="label">{{ __('shop::app.customer.account.order.view.order-id') }} -</span>
|
||||
<span class="value">{{ $invoice->order->increment_id }}</span>
|
||||
<span class="value">#{{ $invoice->order->increment_id }}</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="label">{{ __('shop::app.customer.account.order.view.order-date') }} -</span>
|
||||
<span class="value">{{ core()->formatDate($invoice->order->created_at, 'M d, Y') }}</span>
|
||||
<span class="value">{{ core()->formatDate($invoice->order->created_at, 'd-m-Y') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="table address">
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
<div class="account-layout">
|
||||
|
||||
<div class="account-head">
|
||||
<span class="back-icon"><a href="{{ route('customer.account.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
<span class="back-icon"><a href="{{ route('customer.orders.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
|
||||
<span class="account-heading">
|
||||
{{ __('shop::app.customer.account.order.view.page-tile', ['order_id' => $order->increment_id]) }}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
<div class="account-layout">
|
||||
|
||||
<div class="account-head mb-10">
|
||||
<span class="back-icon"><a href="{{ route('customer.account.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
<span class="back-icon"><a href="{{ route('customer.profile.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
|
||||
<span class="account-heading">{{ __('shop::app.customer.account.profile.edit-profile.title') }}</span>
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
<div class="account-head">
|
||||
|
||||
<span class="back-icon"><a href="{{ route('customer.account.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
<span class="back-icon"><a href="{{ route('customer.profile.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
|
||||
<span class="account-heading">{{ __('shop::app.customer.account.profile.index.title') }}</span>
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
<div class="account-layout">
|
||||
|
||||
<div class="account-head">
|
||||
<span class="back-icon"><a href="{{ route('customer.account.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
<span class="back-icon"><a href="{{ route('customer.profile.index') }}"><i class="icon icon-menu-back"></i></a></span>
|
||||
|
||||
<span class="account-heading">{{ __('shop::app.customer.account.review.index.title') }}</span>
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue