Merge branch 'master' into quick-view

This commit is contained in:
vishal-webkul 2020-09-04 11:53:04 +05:30 committed by GitHub
commit 6a8f86a494
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
152 changed files with 3923 additions and 2011 deletions

View File

@ -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

View File

@ -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

4
.gitignore vendored
View File

@ -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/*

View File

@ -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

832
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -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,

View File

@ -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),
];
}

View File

@ -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,
];

View File

@ -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

View File

@ -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
*/
/**

View File

@ -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"
}

View File

@ -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',

View File

@ -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([

View File

@ -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');

View File

@ -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>';
}
}
]);
}

View File

@ -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([

View File

@ -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();
}
}

View File

@ -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', [

View File

@ -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'),

View File

@ -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%;
}

View File

@ -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

View File

@ -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'
]
]
];

View File

@ -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'
]
]
];

View File

@ -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'
]
]
];

View File

@ -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'
]
]
];

View File

@ -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'
]
]
];

View File

@ -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'
]
]
];

View File

@ -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'
]
]
];

View File

@ -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'
]
]
];

View File

@ -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>

View File

@ -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 : '*[*]'
});

View File

@ -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

View File

@ -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);
}
}
});

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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) }}">

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}
/**

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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',
]
]);
}
}

View File

@ -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]);
}
}
}

View File

@ -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
*

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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'));

View File

@ -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"
]
];

View File

@ -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',

View File

@ -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();
}
}

View File

@ -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'),
];
}
}

View File

@ -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'),
];
}
}

View File

@ -106,8 +106,6 @@ class Ipn
if ($this->order->canInvoice()) {
$invoice = $this->invoiceRepository->create($this->prepareInvoiceData());
$this->invoiceRepository->updateInvoiceState($invoice, "paid");
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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';

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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');

View File

@ -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;
}
}

View File

@ -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
*

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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,
]
]
]
];

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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]);
}
}
}
}
}

View File

@ -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

View File

@ -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"
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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' => 'المجموع الفرعي للمشتريات',

View File

@ -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',

View File

@ -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',

View File

@ -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',

View File

@ -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' => 'مقدار درخواستی در دسترس نیست',

View File

@ -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',

View File

@ -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' => '小計',

View File

@ -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',

View File

@ -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',

View File

@ -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',

View File

@ -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',

View File

@ -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]) !!}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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">

View File

@ -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]) }}

View File

@ -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>

View File

@ -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>

View File

@ -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