merge sync
This commit is contained in:
commit
a9bb0ca129
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
## **v0.1.7 (17th of September, 2019)** - *Release*
|
||||
|
||||
* [feature] - New product types added - Virtual, Downloadable and Group.
|
||||
|
||||
* [feature] - Fiterable attributes according to category.
|
||||
|
||||
* [feature] - New module CMS added for adding static pages.
|
||||
|
|
|
|||
|
|
@ -8,30 +8,30 @@
|
|||
"license": "MIT",
|
||||
"type": "project",
|
||||
"require": {
|
||||
"php": "^7.1.3",
|
||||
"ext-curl": "*",
|
||||
"ext-intl": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-pdo": "*",
|
||||
"ext-pdo_mysql": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"barryvdh/laravel-dompdf": "0.8.3",
|
||||
"dimsav/laravel-translatable": "^9.0",
|
||||
"doctrine/dbal": "2.9.2",
|
||||
"fideloper/proxy": "^4.0",
|
||||
"flynsarmy/db-blade-compiler": "*",
|
||||
"guzzlehttp/guzzle": "~6.0",
|
||||
"intervention/image": "^2.4",
|
||||
"intervention/imagecache": "^2.3",
|
||||
"kalnoy/nestedset": "^4.3",
|
||||
"konekt/concord": "^1.2",
|
||||
"laravel/framework": "5.6.*",
|
||||
"laravel/tinker": "^1.0",
|
||||
"maatwebsite/excel": "3.1.11",
|
||||
"nwidart/laravel-modules": "^3.2",
|
||||
"prettus/l5-repository": "2.6.32",
|
||||
"tymon/jwt-auth": "1.0.0-rc.4"
|
||||
"php": "^7.1.3",
|
||||
"ext-curl": "*",
|
||||
"ext-intl": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-pdo": "*",
|
||||
"ext-pdo_mysql": "*",
|
||||
"ext-tokenizer": "*",
|
||||
"astrotomic/laravel-translatable": "^11.0.0",
|
||||
"barryvdh/laravel-dompdf": "0.8.3",
|
||||
"doctrine/dbal": "2.9.2",
|
||||
"fideloper/proxy": "^4.0",
|
||||
"flynsarmy/db-blade-compiler": "*",
|
||||
"guzzlehttp/guzzle": "~6.0",
|
||||
"intervention/image": "^2.4",
|
||||
"intervention/imagecache": "^2.3",
|
||||
"kalnoy/nestedset": "^4.3",
|
||||
"konekt/concord": "^1.2",
|
||||
"laravel/framework": "5.6.*",
|
||||
"laravel/tinker": "^1.0",
|
||||
"maatwebsite/excel": "3.1.11",
|
||||
"nwidart/laravel-modules": "^3.2",
|
||||
"prettus/l5-repository": "2.6.32",
|
||||
"tymon/jwt-auth": "1.0.0-rc.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-debugbar": "^3.1",
|
||||
|
|
@ -123,4 +123,4 @@
|
|||
"optimize-autoloader": true
|
||||
},
|
||||
"minimum-stability": "dev"
|
||||
}
|
||||
}
|
||||
|
|
@ -202,7 +202,7 @@ return [
|
|||
* Package Service Providers...
|
||||
*/
|
||||
|
||||
Dimsav\Translatable\TranslatableServiceProvider::class,
|
||||
Astrotomic\Translatable\TranslatableServiceProvider::class,
|
||||
|
||||
/*
|
||||
* Application Service Providers...
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class WishlistController extends Controller
|
|||
auth()->setDefaultDriver($this->guard);
|
||||
|
||||
$this->middleware('auth:' . $this->guard);
|
||||
|
||||
|
||||
$this->wishlistRepository = $wishlistRepository;
|
||||
|
||||
$this->productRepository = $productRepository;
|
||||
|
|
|
|||
|
|
@ -31,8 +31,13 @@ return [
|
|||
'route' => 'admin.sales.invoices.index',
|
||||
'sort' => 3,
|
||||
'icon-class' => ''
|
||||
],
|
||||
[
|
||||
], [
|
||||
'key' => 'sales.refunds',
|
||||
'name' => 'admin::app.layouts.refunds',
|
||||
'route' => 'admin.sales.refunds.index',
|
||||
'sort' => 4,
|
||||
'icon-class' => ''
|
||||
], [
|
||||
'key' => 'catalog',
|
||||
'name' => 'admin::app.layouts.catalog',
|
||||
'route' => 'admin.catalog.products.index',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Admin\DataGrids;
|
||||
|
||||
use Webkul\Ui\DataGrid\DataGrid;
|
||||
use DB;
|
||||
|
||||
/**
|
||||
* OrderRefundDataGrid Class
|
||||
*
|
||||
* @author Prashant Singh <jitendra@webkul.com>
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class OrderRefundDataGrid extends DataGrid
|
||||
{
|
||||
protected $index = 'id';
|
||||
|
||||
protected $sortOrder = 'desc'; //asc or desc
|
||||
|
||||
public function prepareQueryBuilder()
|
||||
{
|
||||
$queryBuilder = DB::table('refunds')
|
||||
->select('refunds.id', 'refunds.order_id', 'refunds.state', 'refunds.base_grand_total', 'refunds.created_at')
|
||||
->leftJoin('orders', 'refunds.order_id', '=', 'orders.id')
|
||||
->leftJoin('order_address as order_address_billing', function($leftJoin) {
|
||||
$leftJoin->on('order_address_billing.order_id', '=', 'orders.id')
|
||||
->where('order_address_billing.address_type', 'billing');
|
||||
})
|
||||
->addSelect(DB::raw('CONCAT(order_address_billing.first_name, " ", order_address_billing.last_name) as billed_to'));
|
||||
|
||||
$this->addFilter('billed_to', DB::raw('CONCAT(order_address_billing.first_name, " ", order_address_billing.last_name)'));
|
||||
$this->addFilter('id', 'refunds.id');
|
||||
$this->addFilter('order_id', 'refunds.order_id');
|
||||
$this->addFilter('state', 'refunds.state');
|
||||
$this->addFilter('base_grand_total', 'refunds.base_grand_total');
|
||||
$this->addFilter('created_at', 'refunds.created_at');
|
||||
|
||||
$this->setQueryBuilder($queryBuilder);
|
||||
}
|
||||
|
||||
public function addColumns()
|
||||
{
|
||||
$this->addColumn([
|
||||
'index' => 'id',
|
||||
'label' => trans('admin::app.datagrid.id'),
|
||||
'type' => 'number',
|
||||
'searchable' => false,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'order_id',
|
||||
'label' => trans('admin::app.datagrid.order-id'),
|
||||
'type' => 'number',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'base_grand_total',
|
||||
'label' => trans('admin::app.datagrid.refunded'),
|
||||
'type' => 'price',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'billed_to',
|
||||
'label' => trans('admin::app.datagrid.billed-to'),
|
||||
'type' => 'string',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
|
||||
$this->addColumn([
|
||||
'index' => 'created_at',
|
||||
'label' => trans('admin::app.datagrid.refund-date'),
|
||||
'type' => 'datetime',
|
||||
'searchable' => true,
|
||||
'sortable' => true,
|
||||
'filterable' => true
|
||||
]);
|
||||
}
|
||||
|
||||
public function prepareActions() {
|
||||
$this->addAction([
|
||||
'title' => 'Order Refund View',
|
||||
'method' => 'GET', // use GET request only for redirect purposes
|
||||
'route' => 'admin.sales.refunds.view',
|
||||
'icon' => 'icon eye-icon'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Admin\Http\Controllers\Sales;
|
||||
|
||||
use Webkul\Admin\Http\Controllers\Controller;
|
||||
use Webkul\Sales\Repositories\OrderRepository;
|
||||
use Webkul\Sales\Repositories\OrderItemRepository;
|
||||
use Webkul\Sales\Repositories\RefundRepository;
|
||||
|
||||
/**
|
||||
* Sales Refund controller
|
||||
*
|
||||
* @author Jitendra Singh <jitendra@webkul.com>
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class RefundController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
/**
|
||||
* OrderRepository object
|
||||
*
|
||||
* @var Object
|
||||
*/
|
||||
protected $orderRepository;
|
||||
|
||||
/**
|
||||
* OrderItemRepository object
|
||||
*
|
||||
* @var Object
|
||||
*/
|
||||
protected $orderItemRepository;
|
||||
|
||||
/**
|
||||
* RefundRepository object
|
||||
*
|
||||
* @var Object
|
||||
*/
|
||||
protected $refundRepository;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @param \Webkul\Sales\Repositories\OrderRepository $orderRepository
|
||||
* @param \Webkul\Sales\Repositories\OrderItemRepository $orderItemRepository
|
||||
* @param \Webkul\Sales\Repositories\RefundRepository $refundRepository
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
OrderRepository $orderRepository,
|
||||
OrderItemRepository $orderItemRepository,
|
||||
RefundRepository $refundRepository
|
||||
)
|
||||
{
|
||||
$this->middleware('admin');
|
||||
|
||||
$this->_config = request('_config');
|
||||
|
||||
$this->orderRepository = $orderRepository;
|
||||
|
||||
$this->orderItemRepository = $orderItemRepository;
|
||||
|
||||
$this->refundRepository = $refundRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view($this->_config['view']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param int $orderId
|
||||
* @return \Illuminate\Http\View
|
||||
*/
|
||||
public function create($orderId)
|
||||
{
|
||||
$order = $this->orderRepository->findOrFail($orderId);
|
||||
|
||||
return view($this->_config['view'], compact('order'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param int $orderId
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store($orderId)
|
||||
{
|
||||
$order = $this->orderRepository->findOrFail($orderId);
|
||||
|
||||
if (! $order->canRefund()) {
|
||||
session()->flash('error', trans('admin::app.sales.refunds.creation-error'));
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
$this->validate(request(), [
|
||||
'refund.items.*' => 'required|numeric|min:0'
|
||||
]);
|
||||
|
||||
$data = request()->all();
|
||||
|
||||
$totals = $this->refundRepository->getOrderItemsRefundSummary($data['refund']['items'], $orderId);
|
||||
|
||||
$maxRefundAmount = $totals['grand_total']['price'] - $order->refunds()->sum('base_adjustment_refund');
|
||||
|
||||
$refundAmount = $totals['grand_total']['price'] - $totals['shipping']['price'] + $data['refund']['shipping'] + $data['refund']['adjustment_refund'] - $data['refund']['adjustment_fee'];
|
||||
|
||||
if (! $refundAmount) {
|
||||
session()->flash('error', trans('admin::app.sales.refunds.invalid-refund-amount-error'));
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
if ($refundAmount > $maxRefundAmount) {
|
||||
session()->flash('error', trans('admin::app.sales.refunds.refund-limit-error', ['amount' => core()->formatBasePrice($maxRefundAmount)]));
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
$this->refundRepository->create(array_merge($data, ['order_id' => $orderId]));
|
||||
|
||||
session()->flash('success', trans('admin::app.response.create-success', ['name' => 'Refund']));
|
||||
|
||||
return redirect()->route($this->_config['redirect'], $orderId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param int $orderId
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function updateQty($orderId)
|
||||
{
|
||||
$data = $this->refundRepository->getOrderItemsRefundSummary(request()->all(), $orderId);
|
||||
|
||||
if (! $data)
|
||||
return response('');
|
||||
|
||||
return response()->json($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the view for the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\View
|
||||
*/
|
||||
public function view($id)
|
||||
{
|
||||
$refund = $this->refundRepository->findOrFail($id);
|
||||
|
||||
return view($this->_config['view'], compact('refund'));
|
||||
}
|
||||
}
|
||||
|
|
@ -196,6 +196,28 @@ Route::group(['middleware' => ['web']], function () {
|
|||
Route::get('/shipments/view/{id}', 'Webkul\Admin\Http\Controllers\Sales\ShipmentController@view')->defaults('_config', [
|
||||
'view' => 'admin::sales.shipments.view'
|
||||
])->name('admin.sales.shipments.view');
|
||||
|
||||
|
||||
// Sales Redunds Routes
|
||||
Route::get('/refunds', 'Webkul\Admin\Http\Controllers\Sales\RefundController@index')->defaults('_config', [
|
||||
'view' => 'admin::sales.refunds.index'
|
||||
])->name('admin.sales.refunds.index');
|
||||
|
||||
Route::get('/refunds/create/{order_id}', 'Webkul\Admin\Http\Controllers\Sales\RefundController@create')->defaults('_config', [
|
||||
'view' => 'admin::sales.refunds.create'
|
||||
])->name('admin.sales.refunds.create');
|
||||
|
||||
Route::post('/refunds/create/{order_id}', 'Webkul\Admin\Http\Controllers\Sales\RefundController@store')->defaults('_config', [
|
||||
'redirect' => 'admin.sales.orders.view'
|
||||
])->name('admin.sales.refunds.store');
|
||||
|
||||
Route::post('/refunds/update-qty/{order_id}', 'Webkul\Admin\Http\Controllers\Sales\RefundController@updateQty')->defaults('_config', [
|
||||
'redirect' => 'admin.sales.orders.view'
|
||||
])->name('admin.sales.refunds.update_qty');
|
||||
|
||||
Route::get('/refunds/view/{id}', 'Webkul\Admin\Http\Controllers\Sales\RefundController@view')->defaults('_config', [
|
||||
'view' => 'admin::sales.refunds.view'
|
||||
])->name('admin.sales.refunds.view');
|
||||
});
|
||||
|
||||
// Catalog Routes
|
||||
|
|
|
|||
|
|
@ -556,6 +556,7 @@ body {
|
|||
tr {
|
||||
td {
|
||||
padding: 5px 8px;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
&.bold {
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ return [
|
|||
'role' => 'الدور',
|
||||
'sub-total' => 'المجموع الفرعي',
|
||||
'no-of-products' => 'عدد المنتجات',
|
||||
'refunded' => 'Refunded'
|
||||
],
|
||||
'account' => [
|
||||
'title' => 'حسابي',
|
||||
|
|
@ -262,6 +263,7 @@ return [
|
|||
'item-invoice' => '3-الفواتير (:qty_invoiced)',
|
||||
'item-shipped' => 'شحنت (:qty_shipped)',
|
||||
'item-canceled' => 'ملغاة (:qty_canceled)',
|
||||
'item-refunded' => 'Refunded (:qty_refunded)',
|
||||
'price' => 'Price',
|
||||
'total' => 'المجموع',
|
||||
'subtotal' => 'المجموع الفرعي',
|
||||
|
|
@ -276,7 +278,9 @@ return [
|
|||
'total-paid' => 'المجموع المدفوع',
|
||||
'total-refunded' => 'مجموع المبالغ المستردة',
|
||||
'total-due' => 'المجموع المستحق',
|
||||
'cancel-confirm-msg' => 'هل أنت متأكد من أنك تريد إلغاء هذا الطلب ؟'
|
||||
'cancel-confirm-msg' => 'هل أنت متأكد من أنك تريد إلغاء هذا الطلب ؟',
|
||||
'refunds' => 'Refunds',
|
||||
'refunded' => 'Refunded'
|
||||
],
|
||||
'invoices' => [
|
||||
'title' => 'الفواتير',
|
||||
|
|
@ -301,6 +305,7 @@ return [
|
|||
'creation-error' => 'لا يسمح بإنشاء الفواتير.',
|
||||
'product-error' => 'ولا يمكن إعداد الفاتورة بدون منتجات.'
|
||||
],
|
||||
|
||||
'shipments' => [
|
||||
'title' => 'الشحنات',
|
||||
'id' => 'Id',
|
||||
|
|
@ -325,6 +330,29 @@ return [
|
|||
'creation-error' => 'لا يمكن إنشاء الشحنة لهذا الطلب.',
|
||||
'order-error' => 'لا يسمح بإنشاء شحنة الطلب.',
|
||||
'quantity-invalid' => 'الكمية المطلوبة غير صالحة أو غير متاحة.',
|
||||
],
|
||||
|
||||
'refunds' => [
|
||||
'title' => 'Refunds',
|
||||
'id' => 'Id',
|
||||
'add-title' => 'Create Refund',
|
||||
'save-btn-title' => 'Refund',
|
||||
'order-id' => 'Order Id',
|
||||
'qty-ordered' => 'Qty Ordered',
|
||||
'qty-to-refund' => 'Qty To Refund',
|
||||
'refund-shipping' => 'Refund Shipping',
|
||||
'adjustment-refund' => 'Adjustment Refund',
|
||||
'adjustment-fee' => 'Adjustment Fee',
|
||||
'update-qty' => 'Update Quantities',
|
||||
'invalid-qty' => 'Found invalid quantity for return items.',
|
||||
'refund-limit-error' => 'The most money available to refund is :amount.',
|
||||
'refunded' => 'Refunded',
|
||||
'date' => 'Refund Date',
|
||||
'customer-name' => 'Customer Name',
|
||||
'status' => 'Status',
|
||||
'action' => 'Action',
|
||||
'view-title' => 'Refund #:refund_id',
|
||||
'invalid-refund-amount-error' => 'Refund amount should be non zero.'
|
||||
]
|
||||
],
|
||||
'catalog' => [
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ return [
|
|||
'orders' => 'Orders',
|
||||
'shipments' => 'Shipments',
|
||||
'invoices' => 'Invoices',
|
||||
'refunds' => 'Refunds',
|
||||
'catalog' => 'Catalog',
|
||||
'products' => 'Products',
|
||||
'categories' => 'Categories',
|
||||
|
|
@ -131,7 +132,7 @@ return [
|
|||
'order-count' => ':count Orders',
|
||||
'revenue' => 'Revenue :total',
|
||||
'stock-threshold' => 'Stock Threshold',
|
||||
'qty-left' => ':qty Left',
|
||||
'qty-left' => ':qty Left'
|
||||
],
|
||||
|
||||
'datagrid' => [
|
||||
|
|
@ -198,7 +199,9 @@ return [
|
|||
'per-cust' => 'Per Customer',
|
||||
'usage-throttle' => 'Usage Times',
|
||||
'for-guest' => 'For Guest',
|
||||
'order_number' => 'Order Number'
|
||||
'order_number' => 'Order Number',
|
||||
'refund-date' => 'Refund Date',
|
||||
'refunded' => 'Refunded'
|
||||
],
|
||||
|
||||
'account' => [
|
||||
|
|
@ -321,6 +324,7 @@ return [
|
|||
'item-invoice' => 'Invoiced (:qty_invoiced)',
|
||||
'item-shipped' => 'shipped (:qty_shipped)',
|
||||
'item-canceled' => 'Canceled (:qty_canceled)',
|
||||
'item-refunded' => 'Refunded (:qty_refunded)',
|
||||
'price' => 'Price',
|
||||
'total' => 'Total',
|
||||
'subtotal' => 'Subtotal',
|
||||
|
|
@ -335,7 +339,9 @@ return [
|
|||
'total-paid' => 'Total Paid',
|
||||
'total-refunded' => 'Total Refunded',
|
||||
'total-due' => 'Total Due',
|
||||
'cancel-confirm-msg' => 'Are you sure you want to cancel this order ?'
|
||||
'cancel-confirm-msg' => 'Are you sure you want to cancel this order ?',
|
||||
'refund-btn-title' => 'Refund',
|
||||
'refunds' => 'Refunds'
|
||||
],
|
||||
|
||||
'invoices' => [
|
||||
|
|
@ -386,6 +392,30 @@ return [
|
|||
'creation-error' => 'Shipment can not be created for this order.',
|
||||
'order-error' => 'Order shipment creation is not allowed.',
|
||||
'quantity-invalid' => 'Requested quantity is invalid or not available.',
|
||||
],
|
||||
|
||||
'refunds' => [
|
||||
'title' => 'Refunds',
|
||||
'id' => 'Id',
|
||||
'add-title' => 'Create Refund',
|
||||
'save-btn-title' => 'Refund',
|
||||
'order-id' => 'Order Id',
|
||||
'qty-ordered' => 'Qty Ordered',
|
||||
'qty-to-refund' => 'Qty To Refund',
|
||||
'refund-shipping' => 'Refund Shipping',
|
||||
'adjustment-refund' => 'Adjustment Refund',
|
||||
'adjustment-fee' => 'Adjustment Fee',
|
||||
'update-qty' => 'Update Quantities',
|
||||
'invalid-qty' => 'Found invalid quantity for return items.',
|
||||
'refund-limit-error' => 'The most money available to refund is :amount.',
|
||||
'refunded' => 'Refunded',
|
||||
'date' => 'Refund Date',
|
||||
'customer-name' => 'Customer Name',
|
||||
'status' => 'Status',
|
||||
'action' => 'Action',
|
||||
'view-title' => 'Refund #:refund_id',
|
||||
'invalid-refund-amount-error' => 'Refund amount should be non zero.'
|
||||
|
||||
]
|
||||
],
|
||||
|
||||
|
|
|
|||
|
|
@ -166,7 +166,8 @@ return [
|
|||
'action_type' => 'نوع عملیات',
|
||||
'disc_quantity' => 'مقدار استفاده نشده',
|
||||
'disc_threshold' => 'آستانه استفاده نشده',
|
||||
'use_coupon' => 'استافده از کوپن'
|
||||
'use_coupon' => 'استافده از کوپن',
|
||||
'refunded' => 'Refunded'
|
||||
],
|
||||
|
||||
'account' => [
|
||||
|
|
@ -289,6 +290,7 @@ return [
|
|||
'item-invoice' => 'صورت حساب (:qty_invoiced)',
|
||||
'item-shipped' => 'حمل شده (:qty_shipped)',
|
||||
'item-canceled' => 'لغو شده (:qty_canceled)',
|
||||
'item-refunded' => 'Refunded (:qty_refunded)',
|
||||
'price' => 'قیمت',
|
||||
'total' => 'کل',
|
||||
'subtotal' => 'فرعی',
|
||||
|
|
@ -302,7 +304,9 @@ return [
|
|||
'total-paid' => 'کل پرداخت شده',
|
||||
'total-refunded' => 'بازپرداخت کل',
|
||||
'total-due' => 'بدهی کل',
|
||||
'cancel-confirm-msg' => 'مطمئن هستید که می خواهید این سفارش را لغو کنید ؟'
|
||||
'cancel-confirm-msg' => 'مطمئن هستید که می خواهید این سفارش را لغو کنید ؟',
|
||||
'refunds' => 'Refunds',
|
||||
'refunded' => 'Refunded'
|
||||
],
|
||||
|
||||
'invoices' => [
|
||||
|
|
@ -353,6 +357,29 @@ return [
|
|||
'creation-error' => 'حمل و نقل برای این سفارش ایجاد نمی شود.',
|
||||
'order-error' => 'ایجاد محموله سفارش مجاز نیست.',
|
||||
'quantity-invalid' => 'مقدار درخواستی نامعتبر است یا در دسترس نیست.',
|
||||
],
|
||||
|
||||
'refunds' => [
|
||||
'title' => 'Refunds',
|
||||
'id' => 'Id',
|
||||
'add-title' => 'Create Refund',
|
||||
'save-btn-title' => 'Refund',
|
||||
'order-id' => 'Order Id',
|
||||
'qty-ordered' => 'Qty Ordered',
|
||||
'qty-to-refund' => 'Qty To Refund',
|
||||
'refund-shipping' => 'Refund Shipping',
|
||||
'adjustment-refund' => 'Adjustment Refund',
|
||||
'adjustment-fee' => 'Adjustment Fee',
|
||||
'update-qty' => 'Update Quantities',
|
||||
'invalid-qty' => 'Found invalid quantity for return items.',
|
||||
'refund-limit-error' => 'The most money available to refund is :amount.',
|
||||
'refunded' => 'Refunded',
|
||||
'date' => 'Refund Date',
|
||||
'customer-name' => 'Customer Name',
|
||||
'status' => 'Status',
|
||||
'action' => 'Action',
|
||||
'view-title' => 'Refund #:refund_id',
|
||||
'invalid-refund-amount-error' => 'Refund amount should be non zero.'
|
||||
]
|
||||
],
|
||||
|
||||
|
|
|
|||
|
|
@ -154,7 +154,8 @@ return [
|
|||
'ends-till' => 'Termina Até',
|
||||
'per-cust' => 'Por cliente',
|
||||
'usage-throttle' => 'Tempos de uso',
|
||||
'for-guest' => 'Para convidados'
|
||||
'for-guest' => 'Para convidados',
|
||||
'refunded' => 'Refunded'
|
||||
],
|
||||
'account' => [
|
||||
'title' => 'Minha Conta',
|
||||
|
|
@ -270,6 +271,7 @@ return [
|
|||
'item-invoice' => 'Faturado(s) (:qty_invoiced)',
|
||||
'item-shipped' => 'Enviado(s) (:qty_shipped)',
|
||||
'item-canceled' => 'Cancelado(s) (:qty_canceled)',
|
||||
'item-refunded' => 'Refunded (:qty_refunded)',
|
||||
'price' => 'Preço',
|
||||
'total' => 'Total',
|
||||
'subtotal' => 'Subtotal',
|
||||
|
|
@ -284,7 +286,9 @@ return [
|
|||
'total-paid' => 'Total Pago',
|
||||
'total-refunded' => 'Total Estornado',
|
||||
'total-due' => 'Total Devido',
|
||||
'cancel-confirm-msg' => 'Tem certeza que deseja cancelar esse pedido ?'
|
||||
'cancel-confirm-msg' => 'Tem certeza que deseja cancelar esse pedido ?',
|
||||
'refunds' => 'Refunds',
|
||||
'refunded' => 'Refunded'
|
||||
],
|
||||
'invoices' => [
|
||||
'title' => 'Faturas',
|
||||
|
|
@ -309,6 +313,7 @@ return [
|
|||
'creation-error' => 'A criação de fatura de pedido não é permitida.',
|
||||
'product-error' => 'A fatura não pode ser criada sem produtos.'
|
||||
],
|
||||
|
||||
'shipments' => [
|
||||
'title' => 'Entregas',
|
||||
'id' => 'Id',
|
||||
|
|
@ -333,6 +338,29 @@ return [
|
|||
'creation-error' => 'A expedição não pode ser criada para este pedido.',
|
||||
'order-error' => 'A criação de remessa de pedidos não é permitida.',
|
||||
'quantity-invalid' => 'A quantidade solicitada é inválida ou não está disponível.'
|
||||
],
|
||||
|
||||
'refunds' => [
|
||||
'title' => 'Refunds',
|
||||
'id' => 'Id',
|
||||
'add-title' => 'Create Refund',
|
||||
'save-btn-title' => 'Refund',
|
||||
'order-id' => 'Order Id',
|
||||
'qty-ordered' => 'Qty Ordered',
|
||||
'qty-to-refund' => 'Qty To Refund',
|
||||
'refund-shipping' => 'Refund Shipping',
|
||||
'adjustment-refund' => 'Adjustment Refund',
|
||||
'adjustment-fee' => 'Adjustment Fee',
|
||||
'update-qty' => 'Update Quantities',
|
||||
'invalid-qty' => 'Found invalid quantity for return items.',
|
||||
'refund-limit-error' => 'The most money available to refund is :amount.',
|
||||
'refunded' => 'Refunded',
|
||||
'date' => 'Refund Date',
|
||||
'customer-name' => 'Customer Name',
|
||||
'status' => 'Status',
|
||||
'action' => 'Action',
|
||||
'view-title' => 'Refund #:refund_id',
|
||||
'invalid-refund-amount-error' => 'Refund amount should be non zero.'
|
||||
]
|
||||
],
|
||||
'catalog' => [
|
||||
|
|
|
|||
|
|
@ -31,6 +31,12 @@
|
|||
</a>
|
||||
@endif
|
||||
|
||||
@if ($order->canRefund())
|
||||
<a href="{{ route('admin.sales.refunds.create', $order->id) }}" class="btn btn-lg btn-primary">
|
||||
{{ __('admin::app.sales.orders.refund-btn-title') }}
|
||||
</a>
|
||||
@endif
|
||||
|
||||
@if ($order->canShip())
|
||||
<a href="{{ route('admin.sales.shipments.create', $order->id) }}" class="btn btn-lg btn-primary">
|
||||
{{ __('admin::app.sales.orders.shipment-btn-title') }}
|
||||
|
|
@ -274,6 +280,10 @@
|
|||
{{ $item->qty_shipped ? __('admin::app.sales.orders.item-shipped', ['qty_shipped' => $item->qty_shipped]) : '' }}
|
||||
</span>
|
||||
|
||||
<span class="qty-row">
|
||||
{{ $item->qty_refunded ? __('admin::app.sales.orders.item-refunded', ['qty_refunded' => $item->qty_refunded]) : '' }}
|
||||
</span>
|
||||
|
||||
<span class="qty-row">
|
||||
{{ $item->qty_canceled ? __('admin::app.sales.orders.item-canceled', ['qty_canceled' => $item->qty_canceled]) : '' }}
|
||||
</span>
|
||||
|
|
@ -440,6 +450,50 @@
|
|||
</div>
|
||||
|
||||
</tab>
|
||||
|
||||
<tab name="{{ __('admin::app.sales.orders.refunds') }}">
|
||||
|
||||
<div class="table" style="padding: 20px 0">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ __('admin::app.sales.refunds.id') }}</th>
|
||||
<th>{{ __('admin::app.sales.refunds.date') }}</th>
|
||||
<th>{{ __('admin::app.sales.refunds.order-id') }}</th>
|
||||
<th>{{ __('admin::app.sales.refunds.customer-name') }}</th>
|
||||
<th>{{ __('admin::app.sales.refunds.status') }}</th>
|
||||
<th>{{ __('admin::app.sales.refunds.refunded') }}</th>
|
||||
<th>{{ __('admin::app.sales.refunds.action') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
@foreach ($order->refunds as $refund)
|
||||
<tr>
|
||||
<td>#{{ $refund->id }}</td>
|
||||
<td>{{ $refund->created_at }}</td>
|
||||
<td>#{{ $refund->order->id }}</td>
|
||||
<td>{{ $refund->order->customer_full_name }}</td>
|
||||
<td>{{ __('admin::app.sales.refunds.refunded') }}</td>
|
||||
<td>{{ core()->formatBasePrice($refund->base_grand_total) }}</td>
|
||||
<td class="action">
|
||||
<a href="{{ route('admin.sales.refunds.view', $refund->id) }}">
|
||||
<i class="icon eye-icon"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
@if (! $order->refunds->count())
|
||||
<tr>
|
||||
<td class="empty" colspan="7">{{ __('admin::app.common.no-result-found') }}</td>
|
||||
<tr>
|
||||
@endif
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</tab>
|
||||
</tabs>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,404 @@
|
|||
@extends('admin::layouts.master')
|
||||
|
||||
@section('page_title')
|
||||
{{ __('admin::app.sales.refunds.add-title') }}
|
||||
@stop
|
||||
|
||||
@section('content-wrapper')
|
||||
<div class="content full-page">
|
||||
<form method="POST" action="{{ route('admin.sales.refunds.store', $order->id) }}" @submit.prevent="onSubmit">
|
||||
@csrf()
|
||||
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>
|
||||
<i class="icon angle-left-icon back-link" onclick="history.length > 1 ? history.go(-1) : window.location = '{{ url('/admin/dashboard') }}';"></i>
|
||||
|
||||
{{ __('admin::app.sales.refunds.add-title') }}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="page-action">
|
||||
<button type="submit" class="btn btn-lg btn-primary">
|
||||
{{ __('admin::app.sales.refunds.save-btn-title') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="sale-container">
|
||||
|
||||
<accordian :title="'{{ __('admin::app.sales.orders.order-and-account') }}'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
<div class="sale-section">
|
||||
<div class="secton-title">
|
||||
<span>{{ __('admin::app.sales.orders.order-info') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="section-content">
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.refunds.order-id') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
<a href="{{ route('admin.sales.orders.view', $order->id) }}">#{{ $order->increment_id }}</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.order-date') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->created_at }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.order-status') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->status_label }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.channel') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->channel_name }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sale-section">
|
||||
<div class="secton-title">
|
||||
<span>{{ __('admin::app.sales.orders.account-info') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="section-content">
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.customer-name') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->customer_full_name }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.email') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->customer_email }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :title="'{{ __('admin::app.sales.orders.address') }}'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
<div class="sale-section">
|
||||
<div class="secton-title">
|
||||
<span>{{ __('admin::app.sales.orders.billing-address') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="section-content">
|
||||
|
||||
@include ('admin::sales.address', ['address' => $order->billing_address])
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($order->shipping_address)
|
||||
<div class="sale-section">
|
||||
<div class="secton-title">
|
||||
<span>{{ __('admin::app.sales.orders.shipping-address') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="section-content">
|
||||
|
||||
@include ('admin::sales.address', ['address' => $order->shipping_address])
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :title="'{{ __('admin::app.sales.orders.payment-and-shipping') }}'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
<div class="sale-section">
|
||||
<div class="secton-title">
|
||||
<span>{{ __('admin::app.sales.orders.payment-info') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="section-content">
|
||||
<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.currency') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->order_currency_code }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sale-section">
|
||||
<div class="secton-title">
|
||||
<span>{{ __('admin::app.sales.orders.shipping-info') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="section-content">
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.shipping-method') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->shipping_title }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.shipping-price') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ core()->formatBasePrice($order->base_shipping_amount) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :title="'{{ __('admin::app.sales.orders.products-ordered') }}'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
<refund-items></refund-items>
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@stop
|
||||
|
||||
@push('scripts')
|
||||
<script type="text/x-template" id="refund-items-template">
|
||||
<div>
|
||||
<div class="table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ __('admin::app.sales.orders.SKU') }}</th>
|
||||
<th>{{ __('admin::app.sales.orders.product-name') }}</th>
|
||||
<th>{{ __('admin::app.sales.orders.subtotal') }}</th>
|
||||
<th>{{ __('admin::app.sales.orders.tax-amount') }}</th>
|
||||
@if ($order->base_discount_amount > 0)
|
||||
<th>{{ __('admin::app.sales.orders.discount-amount') }}</th>
|
||||
@endif
|
||||
<th>{{ __('admin::app.sales.orders.grand-total') }}</th>
|
||||
<th>{{ __('admin::app.sales.refunds.qty-ordered') }}</th>
|
||||
<th>{{ __('admin::app.sales.refunds.qty-to-refund') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
@foreach ($order->items as $item)
|
||||
<tr>
|
||||
<td>{{ $item->type == 'configurable' ? $item->child->sku : $item->sku }}</td>
|
||||
|
||||
<td>
|
||||
{{ $item->name }}
|
||||
|
||||
@if ($html = $item->getOptionDetailHtml())
|
||||
<p>{{ $html }}</p>
|
||||
@endif
|
||||
</td>
|
||||
|
||||
<td>{{ core()->formatBasePrice($item->base_price) }}</td>
|
||||
|
||||
<td>{{ core()->formatBasePrice($item->base_tax_amount) }}</td>
|
||||
|
||||
@if ($order->base_discount_amount > 0)
|
||||
<td>{{ core()->formatBasePrice($item->base_discount_amount) }}</td>
|
||||
@endif
|
||||
|
||||
<td>{{ core()->formatBasePrice($item->base_total + $item->base_tax_amount - $item->base_discount_amount) }}</td>
|
||||
|
||||
<td>{{ $item->qty_ordered }}</td>
|
||||
|
||||
<td>
|
||||
<div class="control-group" :class="[errors.has('refund[items][{{ $item->id }}]') ? 'has-error' : '']">
|
||||
<input type="text" v-validate="'required|numeric|min:0'" class="control" id="refund[items][{{ $item->id }}]" name="refund[items][{{ $item->id }}]" v-model="refund.items[{{ $item->id }}]" data-vv-as=""{{ __('admin::app.sales.refunds.qty-to-refund') }}""/>
|
||||
|
||||
<span class="control-error" v-if="errors.has('refund[items][{{ $item->id }}]')">
|
||||
@verbatim
|
||||
{{ errors.first('refund[items][<?php echo $item->id ?>]') }}
|
||||
@endverbatim
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div style="width: 100%; display: inline-block">
|
||||
<button type="button" class="btn btn-lg btn-primary" style="float: right" @click="updateQty">
|
||||
{{ __('admin::app.sales.refunds.update-qty') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<table v-if="refund.summary" class="sale-summary">
|
||||
<tr>
|
||||
<td>{{ __('admin::app.sales.orders.subtotal') }}</td>
|
||||
<td>-</td>
|
||||
<td>@{{ refund.summary.subtotal.formated_price }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>{{ __('admin::app.sales.orders.discount') }}</td>
|
||||
<td>-</td>
|
||||
<td>-@{{ refund.summary.discount.formated_price }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>{{ __('admin::app.sales.refunds.refund-shipping') }}</td>
|
||||
<td>-</td>
|
||||
<td>
|
||||
<div class="control-group" :class="[errors.has('refund[shipping]') ? 'has-error' : '']" style="width: 100px; margin-bottom: 0;">
|
||||
<input type="text" v-validate="'required|min_value:0|max_value:{{$order->base_shipping_invoiced - $order->base_shipping_refunded}}'" class="control" id="refund[shipping]" name="refund[shipping]" v-model="refund.summary.shipping.price" data-vv-as=""{{ __('admin::app.sales.refunds.refund-shipping') }}"" style="width: 100%; margin: 0"/>
|
||||
|
||||
<span class="control-error" v-if="errors.has('refund[shipping]')">
|
||||
@{{ errors.first('refund[shipping]') }}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>{{ __('admin::app.sales.refunds.adjustment-refund') }}</td>
|
||||
<td>-</td>
|
||||
<td>
|
||||
<div class="control-group" :class="[errors.has('refund[adjustment_refund]') ? 'has-error' : '']" style="width: 100px; margin-bottom: 0;">
|
||||
<input type="text" v-validate="'required|min_value:0'" class="control" id="refund[adjustment_refund]" name="refund[adjustment_refund]" value="0" data-vv-as=""{{ __('admin::app.sales.refunds.adjustment-refund') }}"" style="width: 100%; margin: 0"/>
|
||||
|
||||
<span class="control-error" v-if="errors.has('refund[adjustment_refund]')">
|
||||
@{{ errors.first('refund[adjustment_refund]') }}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>{{ __('admin::app.sales.refunds.adjustment-fee') }}</td>
|
||||
<td>-</td>
|
||||
<td>
|
||||
<div class="control-group" :class="[errors.has('refund[adjustment_fee]') ? 'has-error' : '']" style="width: 100px; margin-bottom: 0;">
|
||||
<input type="text" v-validate="'required|min_value:0'" class="control" id="refund[adjustment_fee]" name="refund[adjustment_fee]" value="0" data-vv-as=""{{ __('admin::app.sales.refunds.adjustment-fee') }}"" style="width: 100%; margin: 0"/>
|
||||
|
||||
<span class="control-error" v-if="errors.has('refund[adjustment_fee]')">
|
||||
@{{ errors.first('refund[adjustment_fee]') }}
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr class="border">
|
||||
<td>{{ __('admin::app.sales.orders.tax') }}</td>
|
||||
<td>-</td>
|
||||
<td>@{{ refund.summary.tax.formated_price }}</td>
|
||||
</tr>
|
||||
|
||||
<tr class="bold">
|
||||
<td>{{ __('admin::app.sales.orders.grand-total') }}</td>
|
||||
<td>-</td>
|
||||
<td>@{{ refund.summary.grand_total.formated_price }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('refund-items', {
|
||||
template: '#refund-items-template',
|
||||
|
||||
inject: ['$validator'],
|
||||
|
||||
data: function() {
|
||||
return {
|
||||
refund: {
|
||||
items: {},
|
||||
|
||||
summary: null
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted: function() {
|
||||
@foreach ($order->items as $item)
|
||||
this.refund.items[{{$item->id}}] = {{ $item->qty_to_refund }};
|
||||
@endforeach
|
||||
|
||||
this.updateQty();
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateQty: function() {
|
||||
var this_this = this;
|
||||
|
||||
this.$http.post("{{ route('admin.sales.refunds.update_qty', $order->id) }}", this.refund.items)
|
||||
.then(function(response) {
|
||||
if (! response.data) {
|
||||
window.flashMessages = [{
|
||||
'type': 'alert-error',
|
||||
'message': "{{ __('admin::app.sales.refunds.invalid-qty') }}"
|
||||
}];
|
||||
|
||||
this_this.$root.addFlashMessages()
|
||||
} else {
|
||||
this_this.refund.summary = response.data;
|
||||
}
|
||||
})
|
||||
.catch(function (error) {})
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
@extends('admin::layouts.content')
|
||||
|
||||
@section('page_title')
|
||||
{{ __('admin::app.sales.refunds.title') }}
|
||||
@stop
|
||||
|
||||
@section('content')
|
||||
<div class="content">
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>{{ __('admin::app.sales.refunds.title') }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="page-action">
|
||||
<div class="export-import" @click="showModal('downloadDataGrid')">
|
||||
<i class="export-icon"></i>
|
||||
<span>
|
||||
{{ __('admin::app.export.export') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
@inject('refundGrid', 'Webkul\Admin\DataGrids\OrderRefundDataGrid')
|
||||
|
||||
{!! $refundGrid->render() !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<modal id="downloadDataGrid" :is-open="modalIds.downloadDataGrid">
|
||||
<h3 slot="header">{{ __('admin::app.export.download') }}</h3>
|
||||
<div slot="body">
|
||||
<export-form></export-form>
|
||||
</div>
|
||||
</modal>
|
||||
|
||||
@stop
|
||||
|
||||
@push('scripts')
|
||||
@include('admin::export.export', ['gridName' => $refundGrid])
|
||||
@endpush
|
||||
|
|
@ -0,0 +1,316 @@
|
|||
@extends('admin::layouts.master')
|
||||
|
||||
@section('page_title')
|
||||
{{ __('admin::app.sales.refunds.view-title', ['refund_id' => $refund->id]) }}
|
||||
@stop
|
||||
|
||||
@section('content-wrapper')
|
||||
|
||||
<?php $order = $refund->order; ?>
|
||||
|
||||
<div class="content full-page">
|
||||
<div class="page-header">
|
||||
<div class="page-title">
|
||||
<h1>
|
||||
<i class="icon angle-left-icon back-link" onclick="history.length > 1 ? history.go(-1) : window.location = '{{ url('/admin/dashboard') }}';"></i>
|
||||
|
||||
{{ __('admin::app.sales.refunds.view-title', ['refund_id' => $refund->id]) }}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="page-action">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="page-content">
|
||||
<div class="sale-container">
|
||||
|
||||
<accordian :title="'{{ __('admin::app.sales.orders.order-and-account') }}'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
<div class="sale-section">
|
||||
<div class="secton-title">
|
||||
<span>{{ __('admin::app.sales.orders.order-info') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="section-content">
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.refunds.order-id') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
<a href="{{ route('admin.sales.orders.view', $order->id) }}">#{{ $order->increment_id }}</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.order-date') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->created_at }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.order-status') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->status_label }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.channel') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->channel_name }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sale-section">
|
||||
<div class="secton-title">
|
||||
<span>{{ __('admin::app.sales.orders.account-info') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="section-content">
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.customer-name') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $refund->order->customer_full_name }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.email') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $refund->order->customer_email }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :title="'{{ __('admin::app.sales.orders.address') }}'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
<div class="sale-section">
|
||||
<div class="secton-title">
|
||||
<span>{{ __('admin::app.sales.orders.billing-address') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="section-content">
|
||||
|
||||
@include ('admin::sales.address', ['address' => $order->billing_address])
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($order->shipping_address)
|
||||
<div class="sale-section">
|
||||
<div class="secton-title">
|
||||
<span>{{ __('admin::app.sales.orders.shipping-address') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="section-content">
|
||||
|
||||
@include ('admin::sales.address', ['address' => $order->shipping_address])
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :title="'{{ __('admin::app.sales.orders.payment-and-shipping') }}'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
<div class="sale-section">
|
||||
<div class="secton-title">
|
||||
<span>{{ __('admin::app.sales.orders.payment-info') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="section-content">
|
||||
<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.currency') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->order_currency_code }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sale-section">
|
||||
<div class="secton-title">
|
||||
<span>{{ __('admin::app.sales.orders.shipping-info') }}</span>
|
||||
</div>
|
||||
|
||||
<div class="section-content">
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.shipping-method') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ $order->shipping_title }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<span class="title">
|
||||
{{ __('admin::app.sales.orders.shipping-price') }}
|
||||
</span>
|
||||
|
||||
<span class="value">
|
||||
{{ core()->formatBasePrice($order->base_shipping_amount) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
<accordian :title="'{{ __('admin::app.sales.orders.products-ordered') }}'" :active="true">
|
||||
<div slot="body">
|
||||
|
||||
<div class="table">
|
||||
<table>
|
||||
<thead>
|
||||
<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.discount-amount') }}</th>
|
||||
<th>{{ __('admin::app.sales.orders.grand-total') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
@foreach ($refund->items as $item)
|
||||
<tr>
|
||||
<td>{{ $item->child ? $item->child->sku : $item->sku }}</td>
|
||||
|
||||
<td>
|
||||
{{ $item->name }}
|
||||
|
||||
@if ($html = $item->getOptionDetailHtml())
|
||||
<p>{{ $html }}</p>
|
||||
@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_discount_amount) }}</td>
|
||||
|
||||
<td>{{ core()->formatBasePrice($item->base_total + $item->base_tax_amount - $item->base_discount_amount) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
@if (! $refund->items->count())
|
||||
<tr>
|
||||
<td class="empty" colspan="7">{{ __('admin::app.common.no-result-found') }}</td>
|
||||
<tr>
|
||||
@endif
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<table class="sale-summary">
|
||||
<tr>
|
||||
<td>{{ __('admin::app.sales.orders.subtotal') }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ core()->formatBasePrice($refund->base_sub_total) }}</td>
|
||||
</tr>
|
||||
|
||||
@if ($refund->base_shipping_amount > 0)
|
||||
<tr>
|
||||
<td>{{ __('admin::app.sales.orders.shipping-handling') }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ core()->formatBasePrice($refund->base_shipping_amount) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
@if ($refund->base_tax_amount > 0)
|
||||
<tr>
|
||||
<td>{{ __('admin::app.sales.orders.tax') }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ core()->formatBasePrice($refund->base_tax_amount) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
@if ($refund->base_discount_amount > 0)
|
||||
<tr>
|
||||
<td>{{ __('admin::app.sales.orders.discount') }}</td>
|
||||
<td>-</td>
|
||||
<td>-{{ core()->formatBasePrice($refund->base_discount_amount) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
<tr>
|
||||
<td>{{ __('admin::app.sales.refunds.adjustment-refund') }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ core()->formatBasePrice($refund->base_adjustment_refund) }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>{{ __('admin::app.sales.refunds.adjustment-fee') }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ core()->formatBasePrice($refund->base_adjustment_fee) }}</td>
|
||||
</tr>
|
||||
|
||||
<tr class="bold">
|
||||
<td>{{ __('admin::app.sales.orders.grand-total') }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ core()->formatBasePrice($refund->base_grand_total) }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</accordian>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@stop
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
namespace Webkul\Core\Eloquent;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Dimsav\Translatable\Translatable;
|
||||
use Astrotomic\Translatable\Translatable;
|
||||
use Webkul\Core\Models\Locale;
|
||||
|
||||
class TranslatableModel extends Model
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ class ProductController extends Controller
|
|||
*/
|
||||
public function store()
|
||||
{
|
||||
if (!request()->get('family') && request()->input('type') == 'configurable' && request()->input('sku') != '') {
|
||||
if (! request()->get('family') && request()->input('type') == 'configurable' && request()->input('sku') != '') {
|
||||
return redirect(url()->current() . '?family=' . request()->input('attribute_family_id') . '&sku=' . request()->input('sku'));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class ProductFlatRepository extends Repository
|
|||
// ->where('product_categories.category_id', $categoryId)
|
||||
// ->max('price');
|
||||
|
||||
return $this->model->max('price');
|
||||
return $this->model->max('product_flat.price');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -59,7 +59,7 @@ class ProductFlatRepository extends Repository
|
|||
*/
|
||||
public function getProductMaximumPrice()
|
||||
{
|
||||
return $this->model->max('price');
|
||||
return $this->model->max('product_flat.price');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Sales\Contracts;
|
||||
|
||||
interface Refund
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Sales\Contracts;
|
||||
|
||||
interface RefundItem
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateRefundsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('refunds', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('increment_id')->nullable();
|
||||
$table->string('state')->nullable();
|
||||
$table->boolean('email_sent')->default(0);
|
||||
|
||||
$table->integer('total_qty')->nullable();
|
||||
|
||||
$table->string('base_currency_code')->nullable();
|
||||
$table->string('channel_currency_code')->nullable();
|
||||
$table->string('order_currency_code')->nullable();
|
||||
|
||||
$table->decimal('adjustment_refund', 12, 4)->default(0)->nullable();
|
||||
$table->decimal('base_adjustment_refund', 12, 4)->default(0)->nullable();
|
||||
|
||||
$table->decimal('adjustment_fee', 12, 4)->default(0)->nullable();
|
||||
$table->decimal('base_adjustment_fee', 12, 4)->default(0)->nullable();
|
||||
|
||||
$table->decimal('sub_total', 12, 4)->default(0)->nullable();
|
||||
$table->decimal('base_sub_total', 12, 4)->default(0)->nullable();
|
||||
|
||||
$table->decimal('grand_total', 12, 4)->default(0)->nullable();
|
||||
$table->decimal('base_grand_total', 12, 4)->default(0)->nullable();
|
||||
|
||||
$table->decimal('shipping_amount', 12, 4)->default(0)->nullable();
|
||||
$table->decimal('base_shipping_amount', 12, 4)->default(0)->nullable();
|
||||
|
||||
$table->decimal('tax_amount', 12, 4)->default(0)->nullable();
|
||||
$table->decimal('base_tax_amount', 12, 4)->default(0)->nullable();
|
||||
|
||||
$table->decimal('discount_percent', 12, 4)->default(0)->nullable();
|
||||
$table->decimal('discount_amount', 12, 4)->default(0)->nullable();
|
||||
$table->decimal('base_discount_amount', 12, 4)->default(0)->nullable();
|
||||
|
||||
$table->integer('order_id')->unsigned()->nullable();
|
||||
$table->foreign('order_id')->references('id')->on('orders')->onDelete('cascade');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('refunds');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateRefundItemsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('refund_items', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('name')->nullable();
|
||||
$table->string('description')->nullable();
|
||||
$table->string('sku')->nullable();
|
||||
$table->integer('qty')->nullable();
|
||||
|
||||
$table->decimal('price', 12,4)->default(0);
|
||||
$table->decimal('base_price', 12,4)->default(0);
|
||||
|
||||
$table->decimal('total', 12,4)->default(0);
|
||||
$table->decimal('base_total', 12,4)->default(0);
|
||||
|
||||
$table->decimal('tax_amount', 12,4)->default(0)->nullable();
|
||||
$table->decimal('base_tax_amount', 12,4)->default(0)->nullable();
|
||||
|
||||
$table->decimal('discount_percent', 12, 4)->default(0)->nullable();
|
||||
$table->decimal('discount_amount', 12, 4)->default(0)->nullable();
|
||||
$table->decimal('base_discount_amount', 12, 4)->default(0)->nullable();
|
||||
|
||||
$table->integer('product_id')->unsigned()->nullable();
|
||||
$table->string('product_type')->nullable();
|
||||
|
||||
$table->integer('order_item_id')->unsigned()->nullable();
|
||||
$table->foreign('order_item_id')->references('id')->on('order_items')->onDelete('cascade');
|
||||
|
||||
$table->integer('refund_id')->unsigned()->nullable();
|
||||
$table->foreign('refund_id')->references('id')->on('refunds')->onDelete('cascade');
|
||||
|
||||
$table->integer('parent_id')->unsigned()->nullable();
|
||||
$table->foreign('parent_id')->references('id')->on('refund_items')->onDelete('cascade');
|
||||
|
||||
$table->json('additional')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('refund_items');
|
||||
}
|
||||
}
|
||||
|
|
@ -74,6 +74,14 @@ class Order extends Model implements OrderContract
|
|||
{
|
||||
return $this->hasMany(InvoiceProxy::modelClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the order refunds record associated with the order.
|
||||
*/
|
||||
public function refunds()
|
||||
{
|
||||
return $this->hasMany(RefundProxy::modelClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the customer record associated with the order.
|
||||
|
|
@ -148,9 +156,8 @@ class Order extends Model implements OrderContract
|
|||
return false;
|
||||
|
||||
foreach ($this->items as $item) {
|
||||
if ($item->qty_to_ship > 0) {
|
||||
if ($item->qty_to_ship > 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -165,16 +172,15 @@ class Order extends Model implements OrderContract
|
|||
return false;
|
||||
|
||||
foreach ($this->items as $item) {
|
||||
if ($item->qty_to_invoice > 0) {
|
||||
if ($item->qty_to_invoice > 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if order could can canceled on not
|
||||
* Checks if order can be canceled or not
|
||||
*/
|
||||
public function canCancel()
|
||||
{
|
||||
|
|
@ -182,11 +188,29 @@ class Order extends Model implements OrderContract
|
|||
return false;
|
||||
|
||||
foreach ($this->items as $item) {
|
||||
if ($item->qty_to_cancel > 0) {
|
||||
if ($item->qty_to_cancel > 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if order can be refunded or not
|
||||
*/
|
||||
public function canRefund()
|
||||
{
|
||||
if ($this->status == 'fraud')
|
||||
return false;
|
||||
|
||||
foreach ($this->items as $item) {
|
||||
if ($item->qty_to_refund > 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->base_grand_total_invoiced - $this->base_grand_total_refunded - $this->refunds()->sum('base_adjustment_fee') > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -38,6 +38,14 @@ class OrderItem extends Model implements OrderItemContract
|
|||
return $this->qty_ordered - $this->qty_canceled - $this->qty_invoiced;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get remaining qty for refund.
|
||||
*/
|
||||
public function getQtyToRefundAttribute()
|
||||
{
|
||||
return $this->qty_invoiced - $this->qty_refunded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the order record associated with the order item.
|
||||
*/
|
||||
|
|
@ -78,6 +86,14 @@ class OrderItem extends Model implements OrderItemContract
|
|||
return $this->hasMany(ShipmentItemProxy::modelClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the refund items record associated with the order item.
|
||||
*/
|
||||
public function refund_items()
|
||||
{
|
||||
return $this->hasMany(RefundItemProxy::modelClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns configurable option html
|
||||
*/
|
||||
|
|
@ -94,4 +110,22 @@ class OrderItem extends Model implements OrderItemContract
|
|||
return implode(', ', $labels);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
$array = parent::toArray();
|
||||
|
||||
$array['qty_to_ship'] = $this->qty_to_ship;
|
||||
|
||||
$array['qty_to_invoice'] = $this->qty_to_invoice;
|
||||
|
||||
$array['qty_to_cancel'] = $this->qty_to_cancel;
|
||||
|
||||
$array['qty_to_refund'] = $this->qty_to_refund;
|
||||
|
||||
return $array;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Sales\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Sales\Contracts\Refund as RefundContract;
|
||||
|
||||
class Refund extends Model implements RefundContract
|
||||
{
|
||||
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||
|
||||
protected $statusLabel = [
|
||||
];
|
||||
|
||||
/**
|
||||
* Returns the status label from status code
|
||||
*/
|
||||
public function getStatusLabelAttribute()
|
||||
{
|
||||
return isset($this->statusLabel[$this->state]) ? $this->statusLabel[$this->state] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the order that belongs to the Refund.
|
||||
*/
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(OrderProxy::modelClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Refund items record associated with the Refund.
|
||||
*/
|
||||
public function items() {
|
||||
return $this->hasMany(RefundItemProxy::modelClass())->whereNull('parent_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the customer record associated with the Refund.
|
||||
*/
|
||||
public function customer()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channel record associated with the Refund.
|
||||
*/
|
||||
public function channel()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the addresses for the shipment.
|
||||
*/
|
||||
public function address()
|
||||
{
|
||||
return $this->belongsTo(OrderAddressProxy::modelClass(), 'order_address_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Sales\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Webkul\Sales\Contracts\RefundItem as RefundItemContract;
|
||||
|
||||
class RefundItem extends Model implements RefundItemContract
|
||||
{
|
||||
protected $guarded = ['id', 'created_at', 'updated_at'];
|
||||
|
||||
protected $casts = [
|
||||
'additional' => 'array',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the Refund record associated with the Refund item.
|
||||
*/
|
||||
public function refund()
|
||||
{
|
||||
return $this->belongsTo(RefundProxy::modelClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the order item record associated with the Refund item.
|
||||
*/
|
||||
public function order_item()
|
||||
{
|
||||
return $this->belongsTo(OrderItemProxy::modelClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Refund record associated with the Refund item.
|
||||
*/
|
||||
public function product()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the child item record associated with the Refund item.
|
||||
*/
|
||||
public function child()
|
||||
{
|
||||
return $this->hasOne(RefundItemProxy::modelClass(), 'parent_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns configurable option html
|
||||
*/
|
||||
public function getOptionDetailHtml()
|
||||
{
|
||||
|
||||
if ($this->type == 'configurable' && isset($this->additional['attributes'])) {
|
||||
$labels = [];
|
||||
|
||||
foreach ($this->additional['attributes'] as $attribute) {
|
||||
$labels[] = $attribute['attribute_name'] . ' : ' . $attribute['option_label'];
|
||||
}
|
||||
|
||||
return implode(', ', $labels);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Sales\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class RefundItemProxy extends ModelProxy
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Sales\Models;
|
||||
|
||||
use Konekt\Concord\Proxies\ModelProxy;
|
||||
|
||||
class RefundProxy extends ModelProxy
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -15,5 +15,7 @@ class ModuleServiceProvider extends BaseModuleServiceProvider
|
|||
\Webkul\Sales\Models\InvoiceItem::class,
|
||||
\Webkul\Sales\Models\Shipment::class,
|
||||
\Webkul\Sales\Models\ShipmentItem::class,
|
||||
\Webkul\Sales\Models\Refund::class,
|
||||
\Webkul\Sales\Models\RefundItem::class,
|
||||
];
|
||||
}
|
||||
|
|
@ -98,9 +98,7 @@ class InvoiceRepository extends Repository
|
|||
'base_currency_code' => $order->base_currency_code,
|
||||
'channel_currency_code' => $order->channel_currency_code,
|
||||
'order_currency_code' => $order->order_currency_code,
|
||||
'order_address_id' => $order->billing_address->id,
|
||||
"discount_amount" => $order->discount_amount,
|
||||
"base_discount_amount" => $order->base_discount_amount,
|
||||
'order_address_id' => $order->billing_address->id
|
||||
]);
|
||||
|
||||
foreach ($data['invoice']['items'] as $itemId => $qty) {
|
||||
|
|
@ -174,51 +172,40 @@ class InvoiceRepository extends Repository
|
|||
|
||||
return $invoice;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param mixed $invoice
|
||||
* @return mixed
|
||||
*/
|
||||
public function collectTotals($invoice)
|
||||
{
|
||||
$subTotal = $baseSubTotal = 0;
|
||||
$taxAmount = $baseTaxAmount = 0;
|
||||
$discountAmount = $baseDiscountAmount = 0;
|
||||
$invoice->sub_total = $invoice->base_sub_total = 0;
|
||||
$invoice->tax_amount = $invoice->base_tax_amount = 0;
|
||||
$invoice->discount_amount = $invoice->base_discount_amount = 0;
|
||||
|
||||
foreach ($invoice->items as $invoiceItem) {
|
||||
$subTotal += $invoiceItem->total;
|
||||
$baseSubTotal += $invoiceItem->base_total;
|
||||
$invoice->sub_total += $invoiceItem->total;
|
||||
$invoice->base_sub_total += $invoiceItem->base_total;
|
||||
|
||||
$taxAmount += $invoiceItem->tax_amount;
|
||||
$baseTaxAmount += $invoiceItem->base_tax_amount;
|
||||
$invoice->tax_amount += $invoiceItem->tax_amount;
|
||||
$invoice->base_tax_amount += $invoiceItem->base_tax_amount;
|
||||
|
||||
$discountAmount += $invoiceItem->discount_amount;
|
||||
$baseDiscountAmount += $invoiceItem->base_discount_amount;
|
||||
$invoice->discount_amount += $invoiceItem->discount_amount;
|
||||
$invoice->base_discount_amount += $invoiceItem->base_discount_amount;
|
||||
}
|
||||
|
||||
$shippingAmount = $invoice->order->shipping_amount;
|
||||
$baseShippingAmount = $invoice->order->base_shipping_amount;
|
||||
$invoice->shipping_amount = $invoice->order->shipping_amount;
|
||||
$invoice->base_shipping_amount = $invoice->order->base_shipping_amount;
|
||||
|
||||
if ($invoice->order->shipping_amount) {
|
||||
foreach ($invoice->order->invoices as $prevInvoice) {
|
||||
if ((float) $prevInvoice->shipping_amount) {
|
||||
$shippingAmount = 0;
|
||||
$baseShippingAmount = 0;
|
||||
}
|
||||
if ((float) $prevInvoice->shipping_amount)
|
||||
$invoice->shipping_amount = $invoice->base_shipping_amount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$invoice->sub_total = $subTotal;
|
||||
$invoice->base_sub_total = $baseSubTotal;
|
||||
|
||||
$invoice->shipping_amount = $shippingAmount;
|
||||
$invoice->base_shipping_amount = $baseShippingAmount;
|
||||
|
||||
$invoice->tax_amount = $taxAmount;
|
||||
$invoice->base_tax_amount = $baseTaxAmount;
|
||||
|
||||
$invoice->grand_total = $subTotal + $taxAmount + $shippingAmount - $discountAmount;
|
||||
$invoice->base_grand_total = $baseSubTotal + $baseTaxAmount + $baseShippingAmount - $baseDiscountAmount;
|
||||
$invoice->grand_total = $invoice->sub_total + $invoice->tax_amount + $invoice->shipping_amount - $invoice->discount_amount;
|
||||
$invoice->base_grand_total = $invoice->base_sub_total + $invoice->base_tax_amount + $invoice->base_shipping_amount - $invoice->base_discount_amount;
|
||||
|
||||
$invoice->save();
|
||||
|
||||
|
|
|
|||
|
|
@ -47,9 +47,13 @@ class OrderItemRepository extends Repository
|
|||
*/
|
||||
public function collectTotals($orderItem)
|
||||
{
|
||||
$qtyShipped = $qtyInvoiced = 0;
|
||||
$qtyShipped = $qtyInvoiced = $qtyRefunded = 0;
|
||||
|
||||
$totalInvoiced = $baseTotalInvoiced = 0;
|
||||
$taxInvoiced = $baseTaxInvoiced = 0;
|
||||
|
||||
$totalRefunded = $baseTotalRefunded = 0;
|
||||
$taxRefunded = $baseTaxRefunded = 0;
|
||||
|
||||
foreach ($orderItem->invoice_items as $invoiceItem) {
|
||||
$qtyInvoiced += $invoiceItem->qty;
|
||||
|
|
@ -65,8 +69,19 @@ class OrderItemRepository extends Repository
|
|||
$qtyShipped += $shipmentItem->qty;
|
||||
}
|
||||
|
||||
foreach ($orderItem->refund_items as $refundItem) {
|
||||
$qtyRefunded += $refundItem->qty;
|
||||
|
||||
$totalRefunded += $refundItem->total;
|
||||
$baseTotalRefunded += $refundItem->base_total;
|
||||
|
||||
$taxRefunded += $refundItem->tax_amount;
|
||||
$baseTaxRefunded += $refundItem->base_tax_amount;
|
||||
}
|
||||
|
||||
$orderItem->qty_shipped = $qtyShipped;
|
||||
$orderItem->qty_invoiced = $qtyInvoiced;
|
||||
$orderItem->qty_refunded = $qtyRefunded;
|
||||
|
||||
$orderItem->total_invoiced = $totalInvoiced;
|
||||
$orderItem->base_total_invoiced = $baseTotalInvoiced;
|
||||
|
|
@ -74,6 +89,12 @@ class OrderItemRepository extends Repository
|
|||
$orderItem->tax_amount_invoiced = $taxInvoiced;
|
||||
$orderItem->base_tax_amount_invoiced = $baseTaxInvoiced;
|
||||
|
||||
$orderItem->amount_refunded = $totalRefunded;
|
||||
$orderItem->base_amount_refunded = $baseTotalRefunded;
|
||||
|
||||
$orderItem->tax_amount_refunded = $taxRefunded;
|
||||
$orderItem->base_tax_amount_refunded = $baseTaxRefunded;
|
||||
|
||||
$orderItem->save();
|
||||
|
||||
return $orderItem;
|
||||
|
|
@ -114,7 +135,7 @@ class OrderItemRepository extends Repository
|
|||
/**
|
||||
* Returns qty to product inventory after order cancelation
|
||||
*
|
||||
* @param mixed $orderItem
|
||||
* @param OrderItem $orderItem
|
||||
* @return void
|
||||
*/
|
||||
public function returnQtyToProductInventory($orderItem)
|
||||
|
|
@ -129,9 +150,8 @@ class OrderItemRepository extends Repository
|
|||
if (! $orderedInventory)
|
||||
return ;
|
||||
|
||||
if (($qty = $orderedInventory->qty - $orderItem->qty_to_cancel) < 0) {
|
||||
if (($qty = $orderedInventory->qty - $quantity) < 0)
|
||||
$qty = 0;
|
||||
}
|
||||
|
||||
$orderedInventory->update([
|
||||
'qty' => $qty
|
||||
|
|
|
|||
|
|
@ -265,9 +265,11 @@ class OrderRepository extends Repository
|
|||
*/
|
||||
public function collectTotals($order)
|
||||
{
|
||||
//Order invoice total
|
||||
$order->sub_total_invoiced = $order->base_sub_total_invoiced = 0;
|
||||
$order->shipping_invoiced = $order->base_shipping_invoiced = 0;
|
||||
$order->tax_amount_invoiced = $order->base_tax_amount_invoiced = 0;
|
||||
$order->discount_invoiced = $order->base_discount_invoiced = 0;
|
||||
|
||||
foreach ($order->invoices as $invoice) {
|
||||
$order->sub_total_invoiced += $invoice->sub_total;
|
||||
|
|
@ -286,6 +288,32 @@ class OrderRepository extends Repository
|
|||
$order->grand_total_invoiced = $order->sub_total_invoiced + $order->shipping_invoiced + $order->tax_amount_invoiced - $order->discount_invoiced;
|
||||
$order->base_grand_total_invoiced = $order->base_sub_total_invoiced + $order->base_shipping_invoiced + $order->base_tax_amount_invoiced - $order->base_discount_invoiced;
|
||||
|
||||
//Order refund total
|
||||
$order->sub_total_refunded = $order->base_sub_total_refunded = 0;
|
||||
$order->shipping_refunded = $order->base_shipping_refunded = 0;
|
||||
$order->tax_amount_refunded = $order->base_tax_amount_refunded = 0;
|
||||
$order->grand_total_refunded = $order->base_grand_total_refunded = 0;
|
||||
|
||||
foreach ($order->refunds as $refund) {
|
||||
$order->sub_total_refunded += $refund->sub_total;
|
||||
$order->base_sub_total_refunded += $refund->base_sub_total;
|
||||
|
||||
$order->shipping_refunded += $refund->shipping_amount;
|
||||
$order->base_shipping_refunded += $refund->base_shipping_amount;
|
||||
|
||||
$order->tax_amount_refunded += $refund->tax_amount;
|
||||
$order->base_tax_amount_refunded += $refund->base_tax_amount;
|
||||
|
||||
$order->discount_refunded += $refund->discount_amount;
|
||||
$order->base_discount_refunded += $refund->base_discount_amount;
|
||||
|
||||
$order->grand_total_refunded += $refund->adjustment_refund - $refund->adjustment_fee;
|
||||
$order->base_grand_total_refunded += $refund->base_adjustment_refund - $refund->base_adjustment_fee;
|
||||
}
|
||||
|
||||
$order->grand_total_refunded += $order->sub_total_refunded + $order->shipping_refunded + $order->tax_amount_refunded - $order->discount_refunded;
|
||||
$order->base_grand_total_refunded += $order->base_sub_total_refunded + $order->base_shipping_refunded + $order->base_tax_amount_refunded - $order->base_discount_refunded;
|
||||
|
||||
$order->save();
|
||||
|
||||
return $order;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Sales\Repositories;
|
||||
|
||||
use Illuminate\Container\Container as App;
|
||||
use Webkul\Core\Eloquent\Repository;
|
||||
use Webkul\Sales\Contracts\RefundItem;
|
||||
|
||||
/**
|
||||
* Refund Item Reposotory
|
||||
*
|
||||
* @author Jitendra Singh <jitendra@webkul.com>
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
|
||||
class RefundItemRepository extends Repository
|
||||
{
|
||||
/**
|
||||
* Specify Model class name
|
||||
*
|
||||
* @return Mixed
|
||||
*/
|
||||
|
||||
function model()
|
||||
{
|
||||
return RefundItem::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns qty to product inventory after order refund
|
||||
*
|
||||
* @param RefundItem $refundItem
|
||||
* @param integer $quantity
|
||||
* @return void
|
||||
*/
|
||||
public function returnQtyToProductInventory($refundItem, $quantity)
|
||||
{
|
||||
return;
|
||||
if (! $product = $refundItem->product)
|
||||
return;
|
||||
|
||||
if ($qtyShipped = $refundItem->order_item->qty_shipped) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
$orderedInventory = $product->ordered_inventories()
|
||||
->where('channel_id', $refundItem->order->channel->id)
|
||||
->first();
|
||||
|
||||
if ($orderedInventory) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
if (($qty = $orderedInventory->qty - $quantity) < 0)
|
||||
$qty = 0;
|
||||
|
||||
$orderedInventory->update([
|
||||
'qty' => $qty
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,259 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Sales\Repositories;
|
||||
|
||||
use Illuminate\Container\Container as App;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Webkul\Sales\Contracts\Refund;
|
||||
use Webkul\Core\Eloquent\Repository;
|
||||
|
||||
/**
|
||||
* Refund Reposotory
|
||||
*
|
||||
* @author Jitendra Singh <jitendra@webkul.com>
|
||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||
*/
|
||||
class RefundRepository extends Repository
|
||||
{
|
||||
/**
|
||||
* OrderRepository object
|
||||
*
|
||||
* @var Object
|
||||
*/
|
||||
protected $orderRepository;
|
||||
|
||||
/**
|
||||
* OrderItemRepository object
|
||||
*
|
||||
* @var Object
|
||||
*/
|
||||
protected $orderItemRepository;
|
||||
|
||||
/**
|
||||
* RefundItemRepository object
|
||||
*
|
||||
* @var Object
|
||||
*/
|
||||
protected $refundItemRepository;
|
||||
|
||||
/**
|
||||
* Create a new repository instance.
|
||||
*
|
||||
* @param \Webkul\Sales\Repositories\OrderRepository $orderRepository
|
||||
* @param \Webkul\Sales\Repositories\OrderItemRepository $orderItemRepository
|
||||
* @param \Webkul\Sales\Repositories\RefundItemRepository $refundItemRepository
|
||||
* @param \Illuminate\Container\Container $app
|
||||
*/
|
||||
public function __construct(
|
||||
OrderRepository $orderRepository,
|
||||
OrderItemRepository $orderItemRepository,
|
||||
RefundItemRepository $refundItemRepository,
|
||||
App $app
|
||||
)
|
||||
{
|
||||
$this->orderRepository = $orderRepository;
|
||||
|
||||
$this->orderItemRepository = $orderItemRepository;
|
||||
|
||||
$this->refundItemRepository = $refundItemRepository;
|
||||
|
||||
parent::__construct($app);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify Model class name
|
||||
*
|
||||
* @return Mixed
|
||||
*/
|
||||
function model()
|
||||
{
|
||||
return Refund::class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
*/
|
||||
public function create(array $data)
|
||||
{
|
||||
DB::beginTransaction();
|
||||
|
||||
try {
|
||||
Event::fire('sales.refund.save.before', $data);
|
||||
|
||||
$order = $this->orderRepository->find($data['order_id']);
|
||||
|
||||
$totalQty = array_sum($data['refund']['items']);
|
||||
|
||||
$refund = parent::create([
|
||||
'order_id' => $order->id,
|
||||
'total_qty' => $totalQty,
|
||||
'state' => 'refunded',
|
||||
'base_currency_code' => $order->base_currency_code,
|
||||
'channel_currency_code' => $order->channel_currency_code,
|
||||
'order_currency_code' => $order->order_currency_code,
|
||||
'adjustment_refund' => core()->convertPrice($data['refund']['adjustment_refund'], $order->order_currency_code),
|
||||
'base_adjustment_refund' => $data['refund']['adjustment_refund'],
|
||||
'adjustment_fee' => core()->convertPrice($data['refund']['adjustment_fee'], $order->order_currency_code),
|
||||
'base_adjustment_fee' => $data['refund']['adjustment_fee'],
|
||||
'shipping_amount' => core()->convertPrice($data['refund']['shipping'], $order->order_currency_code),
|
||||
'base_shipping_amount' => $data['refund']['shipping']
|
||||
]);
|
||||
|
||||
foreach ($data['refund']['items'] as $itemId => $qty) {
|
||||
if (! $qty)
|
||||
continue;
|
||||
|
||||
$orderItem = $this->orderItemRepository->find($itemId);
|
||||
|
||||
if ($qty > $orderItem->qty_to_refund)
|
||||
$qty = $orderItem->qty_to_refund;
|
||||
|
||||
$refundItem = $this->refundItemRepository->create([
|
||||
'refund_id' => $refund->id,
|
||||
'order_item_id' => $orderItem->id,
|
||||
'name' => $orderItem->name,
|
||||
'sku' => $orderItem->sku,
|
||||
'qty' => $qty,
|
||||
'price' => $orderItem->price,
|
||||
'base_price' => $orderItem->base_price,
|
||||
'total' => $orderItem->price * $qty,
|
||||
'base_total' => $orderItem->base_price * $qty,
|
||||
'tax_amount' => ( ($orderItem->tax_amount / $orderItem->qty_ordered) * $qty ),
|
||||
'base_tax_amount' => ( ($orderItem->base_tax_amount / $orderItem->qty_ordered) * $qty ),
|
||||
'discount_amount' => ( ($orderItem->discount_amount / $orderItem->qty_ordered) * $qty ),
|
||||
'base_discount_amount' => ( ($orderItem->base_discount_amount / $orderItem->qty_ordered) * $qty ),
|
||||
'product_id' => $orderItem->product_id,
|
||||
'product_type' => $orderItem->product_type,
|
||||
'additional' => $orderItem->additional
|
||||
]);
|
||||
|
||||
if ($orderItem->type == 'configurable' && $orderItem->child) {
|
||||
$childOrderItem = $orderItem->child;
|
||||
|
||||
$refundItem->child = $this->refundItemRepository->create([
|
||||
'refund_id' => $refund->id,
|
||||
'order_item_id' => $childOrderItem->id,
|
||||
'parent_id' => $refundItem->id,
|
||||
'name' => $childOrderItem->name,
|
||||
'sku' => $childOrderItem->sku,
|
||||
'qty' => $qty,
|
||||
'price' => $childOrderItem->price,
|
||||
'base_price' => $childOrderItem->base_price,
|
||||
'total' => $childOrderItem->price * $qty,
|
||||
'base_total' => $childOrderItem->base_price * $qty,
|
||||
'tax_amount' => 0,
|
||||
'base_tax_amount' => 0,
|
||||
'discount_amount' => 0,
|
||||
'base_discount_amount' => 0,
|
||||
'product_id' => $childOrderItem->product_id,
|
||||
'product_type' => $childOrderItem->product_type,
|
||||
'additional' => $childOrderItem->additional
|
||||
]);
|
||||
|
||||
$this->refundItemRepository->returnQtyToProductInventory($childOrderItem, $qty);
|
||||
} else {
|
||||
$this->refundItemRepository->returnQtyToProductInventory($orderItem, $qty);
|
||||
}
|
||||
|
||||
$this->orderItemRepository->collectTotals($orderItem);
|
||||
}
|
||||
|
||||
$this->collectTotals($refund);
|
||||
|
||||
$this->orderRepository->collectTotals($order);
|
||||
|
||||
$this->orderRepository->updateOrderStatus($order);
|
||||
|
||||
Event::fire('sales.refund.save.after', $refund);
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
return $refund;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Refund $refund
|
||||
* @return mixed
|
||||
*/
|
||||
public function collectTotals($refund)
|
||||
{
|
||||
$refund->sub_total = $refund->base_sub_total = 0;
|
||||
$refund->tax_amount = $refund->base_tax_amount = 0;
|
||||
$refund->discount_amount = $refund->base_discount_amount = 0;
|
||||
|
||||
foreach ($refund->items as $refundItem) {
|
||||
$refund->sub_total += $refundItem->total;
|
||||
$refund->base_sub_total += $refundItem->base_total;
|
||||
|
||||
$refund->tax_amount += $refundItem->tax_amount;
|
||||
$refund->base_tax_amount += $refundItem->base_tax_amount;
|
||||
|
||||
$refund->discount_amount += $refundItem->discount_amount;
|
||||
$refund->base_discount_amount += $refundItem->base_discount_amount;
|
||||
}
|
||||
|
||||
$refund->grand_total = $refund->sub_total + $refund->tax_amount + $refund->shipping_amount + $refund->adjustment_refund - $refund->adjustment_fee - $refund->discount_amount;
|
||||
$refund->base_grand_total = $refund->base_sub_total + $refund->base_tax_amount + $refund->base_shipping_amount + $refund->base_adjustment_refund - $refund->adjustment_fee - $refund->base_discount_amount;
|
||||
|
||||
$refund->save();
|
||||
|
||||
return $refund;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param integer $orderId
|
||||
* @return array
|
||||
*/
|
||||
public function getOrderItemsRefundSummary($data, $orderId)
|
||||
{
|
||||
$order = $this->orderRepository->find($orderId);
|
||||
|
||||
$summary = [
|
||||
'subtotal' => ['price' => 0],
|
||||
'discount' => ['price' => 0],
|
||||
'tax' => ['price' => 0],
|
||||
'shipping' => ['price' => 0],
|
||||
'grand_total' => ['price' => 0]
|
||||
];
|
||||
|
||||
foreach ($data as $orderItemId => $qty) {
|
||||
if (! $qty)
|
||||
continue;
|
||||
|
||||
$orderItem = $this->orderItemRepository->find($orderItemId);
|
||||
|
||||
if ($qty > $orderItem->qty_to_refund)
|
||||
return false;
|
||||
|
||||
$summary['subtotal']['price'] += $orderItem->base_price * $qty;
|
||||
|
||||
$summary['discount']['price'] += ($orderItem->base_discount_amount / $orderItem->qty_ordered) * $qty;
|
||||
|
||||
$summary['tax']['price'] += ($orderItem->tax_amount / $orderItem->qty_ordered) * $qty;
|
||||
}
|
||||
|
||||
$summary['shipping']['price'] += $order->base_shipping_invoiced - $order->base_shipping_refunded;
|
||||
|
||||
$summary['grand_total']['price'] += $summary['subtotal']['price'] + $summary['tax']['price'] + $summary['shipping']['price'] - $summary['discount']['price'];
|
||||
|
||||
$summary['subtotal']['formated_price'] = core()->formatBasePrice($summary['subtotal']['price']);
|
||||
|
||||
$summary['discount']['formated_price'] = core()->formatBasePrice($summary['discount']['price']);
|
||||
|
||||
$summary['tax']['formated_price'] = core()->formatBasePrice($summary['tax']['price']);
|
||||
|
||||
$summary['shipping']['formated_price'] = core()->formatBasePrice($summary['shipping']['price']);
|
||||
|
||||
$summary['grand_total']['formated_price'] = core()->formatBasePrice($summary['grand_total']['price']);
|
||||
|
||||
return $summary;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,8 @@ return [
|
|||
],
|
||||
|
||||
'common' => [
|
||||
'error' => 'حدث شيء خاطئ ، رجاء حاول ثانية لاحقا.'
|
||||
'error' => 'حدث شيء خاطئ ، رجاء حاول ثانية لاحقا.',
|
||||
'no-result-found' => 'We could not find any records.'
|
||||
],
|
||||
|
||||
'home' => [
|
||||
|
|
@ -249,6 +250,7 @@ return [
|
|||
'item-invoice' => '3-الفواتير(:qty_invoiced)',
|
||||
'item-shipped' => 'شحنت(:qty_shipped)',
|
||||
'item-canceled' => 'ملغاة(:qty_canceled)',
|
||||
'item-refunded' => 'Refunded (:qty_refunded)',
|
||||
'price' => 'السعر',
|
||||
'total' => 'المجموع',
|
||||
'subtotal' => 'المجموع الفرعي',
|
||||
|
|
@ -274,7 +276,11 @@ return [
|
|||
'order-date' => 'تاريخ الطلب',
|
||||
'bill-to' => 'بيل إلى',
|
||||
'ship-to' => 'السفينة إلى',
|
||||
'contact' => 'Contact'
|
||||
'contact' => 'Contact',
|
||||
'refunds' => 'Refunds',
|
||||
'individual-refund' => 'Refund #:refund_id',
|
||||
'adjustment-refund' => 'Adjustment Refund',
|
||||
'adjustment-fee' => 'Adjustment Fee',
|
||||
]
|
||||
],
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ return [
|
|||
],
|
||||
|
||||
'common' => [
|
||||
'error' => 'Something went wrong, please try again later.'
|
||||
'error' => 'Something went wrong, please try again later.',
|
||||
'no-result-found' => 'We could not find any records.'
|
||||
],
|
||||
|
||||
'home' => [
|
||||
|
|
@ -258,6 +259,7 @@ return [
|
|||
'item-invoice' => 'Invoiced (:qty_invoiced)',
|
||||
'item-shipped' => 'shipped (:qty_shipped)',
|
||||
'item-canceled' => 'Canceled (:qty_canceled)',
|
||||
'item-refunded' => 'Refunded (:qty_refunded)',
|
||||
'price' => 'Price',
|
||||
'total' => 'Total',
|
||||
'subtotal' => 'Subtotal',
|
||||
|
|
@ -283,7 +285,11 @@ return [
|
|||
'order-date' => 'Order Date',
|
||||
'bill-to' => 'Bill to',
|
||||
'ship-to' => 'Ship to',
|
||||
'contact' => 'Contact'
|
||||
'contact' => 'Contact',
|
||||
'refunds' => 'Refunds',
|
||||
'individual-refund' => 'Refund #:refund_id',
|
||||
'adjustment-refund' => 'Adjustment Refund',
|
||||
'adjustment-fee' => 'Adjustment Fee',
|
||||
]
|
||||
],
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ return [
|
|||
],
|
||||
|
||||
'common' => [
|
||||
'error' => 'مشکلی رخ داده است. لطفا بعدا دوباره امتحان کنید.'
|
||||
'error' => 'مشکلی رخ داده است. لطفا بعدا دوباره امتحان کنید.',
|
||||
'no-result-found' => 'We could not find any records.'
|
||||
],
|
||||
|
||||
'home' => [
|
||||
|
|
@ -256,6 +257,7 @@ return [
|
|||
'item-invoice' => 'صورتحساب (:qty_invoiced)',
|
||||
'item-shipped' => 'حمل شده (:qty_shipped)',
|
||||
'item-canceled' => 'لغو شد (:qty_canceled)',
|
||||
'item-refunded' => 'Refunded (:qty_refunded)',
|
||||
'price' => 'قیمت',
|
||||
'total' => 'جمع',
|
||||
'subtotal' => 'فرعی',
|
||||
|
|
@ -281,7 +283,11 @@ return [
|
|||
'order-date' => 'تاریخ سفارش',
|
||||
'bill-to' => 'بیل به',
|
||||
'ship-to' => 'حمل به',
|
||||
'contact' => 'تماس'
|
||||
'contact' => 'تماس',
|
||||
'refunds' => 'Refunds',
|
||||
'individual-refund' => 'Refund #:refund_id',
|
||||
'adjustment-refund' => 'Adjustment Refund',
|
||||
'adjustment-fee' => 'Adjustment Fee',
|
||||
]
|
||||
],
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ return [
|
|||
],
|
||||
|
||||
'common' => [
|
||||
'error' => 'Algo deu errado, por favor, tente novamente mais tarde.'
|
||||
'error' => 'Algo deu errado, por favor, tente novamente mais tarde.',
|
||||
'no-result-found' => 'We could not find any records.'
|
||||
],
|
||||
|
||||
'home' => [
|
||||
|
|
@ -251,6 +252,7 @@ return [
|
|||
'item-invoice' => 'Faturados (:qty_invoiced)',
|
||||
'item-shipped' => 'enviados (:qty_shipped)',
|
||||
'item-canceled' => 'Cancelados (:qty_canceled)',
|
||||
'item-refunded' => 'Refunded (:qty_refunded)',
|
||||
'price' => 'Preço',
|
||||
'total' => 'Total',
|
||||
'subtotal' => 'Subtotal',
|
||||
|
|
@ -276,7 +278,11 @@ return [
|
|||
'order-date' => 'Pedido Date',
|
||||
'bill-to' => 'Cobrança de',
|
||||
'ship-to' => 'Enviar para',
|
||||
'contact' => 'Contato'
|
||||
'contact' => 'Contato',
|
||||
'refunds' => 'Refunds',
|
||||
'individual-refund' => 'Refund #:refund_id',
|
||||
'adjustment-refund' => 'Adjustment Refund',
|
||||
'adjustment-fee' => 'Adjustment Fee',
|
||||
]
|
||||
],
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@
|
|||
<td data-value="{{ __('shop::app.customer.account.order.view.SKU') }}">
|
||||
{{ $item->type == 'configurable' ? $item->child->sku : $item->sku }}
|
||||
</td>
|
||||
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.product-name') }}">
|
||||
{{ $item->name }} <br>
|
||||
@if (isset($item['additional']['attributes']))
|
||||
|
|
@ -76,7 +77,11 @@
|
|||
@endforeach
|
||||
@endif
|
||||
</td>
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.price') }}">{{ core()->formatPrice($item->price, $order->order_currency_code) }}</td>
|
||||
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.price') }}">
|
||||
{{ core()->formatPrice($item->price, $order->order_currency_code) }}
|
||||
</td>
|
||||
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.item-status') }}">
|
||||
<span class="qty-row">
|
||||
{{ __('shop::app.customer.account.order.view.item-ordered', ['qty_ordered' => $item->qty_ordered]) }}
|
||||
|
|
@ -90,14 +95,30 @@
|
|||
{{ $item->qty_shipped ? __('shop::app.customer.account.order.view.item-shipped', ['qty_shipped' => $item->qty_shipped]) : '' }}
|
||||
</span>
|
||||
|
||||
<span class="qty-row">
|
||||
{{ $item->qty_refunded ? __('shop::app.customer.account.order.view.item-refunded', ['qty_refunded' => $item->qty_refunded]) : '' }}
|
||||
</span>
|
||||
|
||||
<span class="qty-row">
|
||||
{{ $item->qty_canceled ? __('shop::app.customer.account.order.view.item-canceled', ['qty_canceled' => $item->qty_canceled]) : '' }}
|
||||
</span>
|
||||
</td>
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.subtotal') }}">{{ core()->formatPrice($item->total, $order->order_currency_code) }}</td>
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.tax-percent') }}">{{ number_format($item->tax_percent, 2) }}%</td>
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.tax-amount') }}">{{ core()->formatPrice($item->tax_amount, $order->order_currency_code) }}</td>
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.grand-total') }}">{{ core()->formatPrice($item->total + $item->tax_amount, $order->order_currency_code) }}</td>
|
||||
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.subtotal') }}">
|
||||
{{ core()->formatPrice($item->total, $order->order_currency_code) }}
|
||||
</td>
|
||||
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.tax-percent') }}">
|
||||
{{ number_format($item->tax_percent, 2) }}%
|
||||
</td>
|
||||
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.tax-amount') }}">
|
||||
{{ core()->formatPrice($item->tax_amount, $order->order_currency_code) }}
|
||||
</td>
|
||||
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.grand-total') }}">
|
||||
{{ core()->formatPrice($item->total + $item->tax_amount - $item->discount_amount, $order->order_currency_code) }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
|
|
@ -297,6 +318,113 @@
|
|||
|
||||
</tab>
|
||||
@endif
|
||||
|
||||
@if ($order->refunds->count())
|
||||
<tab name="{{ __('shop::app.customer.account.order.view.refunds') }}">
|
||||
|
||||
@foreach ($order->refunds as $refund)
|
||||
|
||||
<div class="sale-section">
|
||||
<div class="secton-title">
|
||||
<span>{{ __('shop::app.customer.account.order.view.individual-refund', ['refund_id' => $refund->id]) }}</span>
|
||||
</div>
|
||||
|
||||
<div class="section-content">
|
||||
<div class="table">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ __('shop::app.customer.account.order.view.SKU') }}</th>
|
||||
<th>{{ __('shop::app.customer.account.order.view.product-name') }}</th>
|
||||
<th>{{ __('shop::app.customer.account.order.view.price') }}</th>
|
||||
<th>{{ __('shop::app.customer.account.order.view.qty') }}</th>
|
||||
<th>{{ __('shop::app.customer.account.order.view.subtotal') }}</th>
|
||||
<th>{{ __('shop::app.customer.account.order.view.tax-amount') }}</th>
|
||||
<th>{{ __('shop::app.customer.account.order.view.grand-total') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
@foreach ($refund->items as $item)
|
||||
<tr>
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.SKU') }}">{{ $item->child ? $item->child->sku : $item->sku }}</td>
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.product-name') }}">{{ $item->name }}</td>
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.price') }}">{{ core()->formatPrice($item->price, $order->order_currency_code) }}</td>
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.qty') }}">{{ $item->qty }}</td>
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.subtotal') }}">{{ core()->formatPrice($item->total, $order->order_currency_code) }}</td>
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.tax-amount') }}">{{ core()->formatPrice($item->tax_amount, $order->order_currency_code) }}</td>
|
||||
<td data-value="{{ __('shop::app.customer.account.order.view.grand-total') }}">{{ core()->formatPrice($item->total + $item->tax_amount, $order->order_currency_code) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
@if (! $refund->items->count())
|
||||
<tr>
|
||||
<td class="empty" colspan="7">{{ __('admin::app.common.no-result-found') }}</td>
|
||||
<tr>
|
||||
@endif
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="totals">
|
||||
<table class="sale-summary">
|
||||
<tr>
|
||||
<td>{{ __('shop::app.customer.account.order.view.subtotal') }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ core()->formatPrice($refund->sub_total, $order->order_currency_code) }}</td>
|
||||
</tr>
|
||||
|
||||
@if ($refund->shipping_amount > 0)
|
||||
<tr>
|
||||
<td>{{ __('shop::app.customer.account.order.view.shipping-handling') }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ core()->formatPrice($refund->shipping_amount, $order->order_currency_code) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
@if ($refund->discount_amount > 0)
|
||||
<tr>
|
||||
<td>{{ __('shop::app.customer.account.order.view.discount') }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ core()->formatPrice($order->discount_amount, $order->order_currency_code) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
@if ($refund->tax_amount > 0)
|
||||
<tr>
|
||||
<td>{{ __('shop::app.customer.account.order.view.tax') }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ core()->formatPrice($refund->tax_amount, $order->order_currency_code) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
|
||||
<tr>
|
||||
<td>{{ __('shop::app.customer.account.order.view.adjustment-refund') }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ core()->formatPrice($refund->adjustment_refund, $order->order_currency_code) }}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>{{ __('shop::app.customer.account.order.view.adjustment-fee') }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ core()->formatPrice($refund->adjustment_fee, $order->order_currency_code) }}</td>
|
||||
</tr>
|
||||
|
||||
<tr class="bold">
|
||||
<td>{{ __('shop::app.customer.account.order.view.grand-total') }}</td>
|
||||
<td>-</td>
|
||||
<td>{{ core()->formatPrice($refund->grand_total, $order->order_currency_code) }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endforeach
|
||||
|
||||
</tab>
|
||||
@endif
|
||||
</tabs>
|
||||
|
||||
<div class="sale-section">
|
||||
|
|
|
|||
Loading…
Reference in New Issue