Inventory source selection feature added during shipment creation
This commit is contained in:
parent
f4ca5a5b34
commit
2e668c7020
|
|
@ -1,5 +1,12 @@
|
||||||
                       
|
<p align="center">
|
||||||
|
<a href="http://www.bagisto.com"><img src="https://bagisto.com/wp-content/themes/bagisto/images/logo.png" alt="Total Downloads"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://packagist.org/packages/bagisto/bagisto"><img src="https://poser.pugx.org/bagisto/bagisto/d/total.svg" alt="Total Downloads"></a>
|
||||||
|
<a href="https://packagist.org/packages/bagisto/bagisto"><img src="https://poser.pugx.org/bagisto/bagisto/v/stable.svg" alt="Latest Stable Version"></a>
|
||||||
|
<a href="https://packagist.org/packages/bagisto/bagisto"><img src="https://poser.pugx.org/bagisto/bagisto/license.svg" alt="License"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
# Topics
|
# Topics
|
||||||
1. ### Introduction
|
1. ### Introduction
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,12 @@ class OrderShipmentsDataGrid
|
||||||
'primaryKey' => 'ship.order_id',
|
'primaryKey' => 'ship.order_id',
|
||||||
'condition' => '=',
|
'condition' => '=',
|
||||||
'secondaryKey' => 'ors.id',
|
'secondaryKey' => 'ors.id',
|
||||||
|
], [
|
||||||
|
'join' => 'leftjoin',
|
||||||
|
'table' => 'inventory_sources as is',
|
||||||
|
'primaryKey' => 'ship.inventory_source_id',
|
||||||
|
'condition' => '=',
|
||||||
|
'secondaryKey' => 'is.id',
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
@ -82,6 +88,12 @@ class OrderShipmentsDataGrid
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'label' => 'Customer Name',
|
'label' => 'Customer Name',
|
||||||
'sortable' => false,
|
'sortable' => false,
|
||||||
|
], [
|
||||||
|
'name' => 'is.name',
|
||||||
|
'alias' => 'inventorySourceName',
|
||||||
|
'type' => 'string',
|
||||||
|
'label' => 'Inventory Source',
|
||||||
|
'sortable' => true
|
||||||
], [
|
], [
|
||||||
'name' => 'ors.created_at',
|
'name' => 'ors.created_at',
|
||||||
'alias' => 'orscreated',
|
'alias' => 'orscreated',
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,9 @@ namespace Webkul\Admin\Http\Controllers\Sales;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Response;
|
use Illuminate\Http\Response;
|
||||||
use Webkul\Admin\Http\Controllers\Controller;
|
use Webkul\Admin\Http\Controllers\Controller;
|
||||||
use Webkul\Sales\Repositories\OrderRepository as Order;
|
|
||||||
use Webkul\Sales\Repositories\ShipmentRepository as Shipment;
|
use Webkul\Sales\Repositories\ShipmentRepository as Shipment;
|
||||||
|
use Webkul\Sales\Repositories\OrderRepository as Order;
|
||||||
|
use Webkul\Sales\Repositories\OrderItemRepository as OrderItem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sales Shipment controller
|
* Sales Shipment controller
|
||||||
|
|
@ -23,28 +24,40 @@ class ShipmentController extends Controller
|
||||||
*/
|
*/
|
||||||
protected $_config;
|
protected $_config;
|
||||||
|
|
||||||
/**
|
|
||||||
* OrderRepository object
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $order;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ShipmentRepository object
|
* ShipmentRepository object
|
||||||
*
|
*
|
||||||
* @var array
|
* @var mixed
|
||||||
*/
|
*/
|
||||||
protected $shipment;
|
protected $shipment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OrderRepository object
|
||||||
|
*
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
protected $order;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OrderItemRepository object
|
||||||
|
*
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
protected $orderItem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new controller instance.
|
* Create a new controller instance.
|
||||||
*
|
*
|
||||||
* @param Webkul\Sales\Repositories\OrderRepository $order
|
|
||||||
* @param Webkul\Sales\Repositories\ShipmentRepository $shipment
|
* @param Webkul\Sales\Repositories\ShipmentRepository $shipment
|
||||||
|
* @param Webkul\Sales\Repositories\OrderRepository $order
|
||||||
|
* @param Webkul\Sales\Repositories\OrderitemRepository $orderItem
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct(Shipment $shipment, Order $order)
|
public function __construct(
|
||||||
|
Shipment $shipment,
|
||||||
|
Order $order,
|
||||||
|
OrderItem $orderItem
|
||||||
|
)
|
||||||
{
|
{
|
||||||
$this->middleware('admin');
|
$this->middleware('admin');
|
||||||
|
|
||||||
|
|
@ -52,6 +65,8 @@ class ShipmentController extends Controller
|
||||||
|
|
||||||
$this->order = $order;
|
$this->order = $order;
|
||||||
|
|
||||||
|
$this->orderItem = $orderItem;
|
||||||
|
|
||||||
$this->shipment = $shipment;
|
$this->shipment = $shipment;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -76,6 +91,12 @@ class ShipmentController extends Controller
|
||||||
{
|
{
|
||||||
$order = $this->order->find($orderId);
|
$order = $this->order->find($orderId);
|
||||||
|
|
||||||
|
if(!$order->channel || !$order->canShip()) {
|
||||||
|
session()->flash('error', 'Shipment can not be created for this order.');
|
||||||
|
|
||||||
|
return redirect()->back();
|
||||||
|
}
|
||||||
|
|
||||||
return view($this->_config['view'], compact('order'));
|
return view($this->_config['view'], compact('order'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -99,21 +120,14 @@ class ShipmentController extends Controller
|
||||||
$this->validate(request(), [
|
$this->validate(request(), [
|
||||||
'shipment.carrier_title' => 'required',
|
'shipment.carrier_title' => 'required',
|
||||||
'shipment.track_number' => 'required',
|
'shipment.track_number' => 'required',
|
||||||
'shipment.items.*' => 'required|numeric|min:0',
|
'shipment.source' => 'required',
|
||||||
|
'shipment.items.*.*' => 'required|numeric|min:0',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$data = request()->all();
|
$data = request()->all();
|
||||||
|
|
||||||
$haveProductToShip = false;
|
|
||||||
foreach ($data['shipment']['items'] as $itemId => $qty) {
|
|
||||||
if($qty) {
|
|
||||||
$haveProductToShip = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$haveProductToShip) {
|
if(!$this->isInventoryValidate($data)) {
|
||||||
session()->flash('error', 'Shipment can not be created without products.');
|
session()->flash('error', 'Requested quantity is invalid or not available.');
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
@ -125,6 +139,42 @@ class ShipmentController extends Controller
|
||||||
return redirect()->route($this->_config['redirect'], $orderId);
|
return redirect()->route($this->_config['redirect'], $orderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if requested quantity available or not
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function isInventoryValidate(&$data)
|
||||||
|
{
|
||||||
|
$valid = false;
|
||||||
|
|
||||||
|
foreach ($data['shipment']['items'] as $itemId => $inventorySource) {
|
||||||
|
if ($qty = $inventorySource[$data['shipment']['source']]) {
|
||||||
|
$orderItem = $this->orderItem->find($itemId);
|
||||||
|
|
||||||
|
$product = ($orderItem->type == 'configurable')
|
||||||
|
? $orderItem->child->product
|
||||||
|
: $orderItem->product;
|
||||||
|
|
||||||
|
// Check if requested qty is available, if not ship available qty
|
||||||
|
$inventory = $product->inventories()
|
||||||
|
->where('inventory_source_id', $data['shipment']['source'])
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if ($orderItem->qty_to_ship < $qty || $inventory->qty < $qty) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$valid = true;
|
||||||
|
} else {
|
||||||
|
unset($data['shipment']['items'][$itemId]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $valid;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the view for the specified resource.
|
* Show the view for the specified resource.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,5 @@ class Order {
|
||||||
*/
|
*/
|
||||||
public function updateProductInventory($order)
|
public function updateProductInventory($order)
|
||||||
{
|
{
|
||||||
$productListener = app(\Webkul\Admin\Listeners\Product::class);
|
|
||||||
|
|
||||||
foreach ($order->items as $item) {
|
|
||||||
$productListener->afterOrderRecieved($item->product->id, $item->qty_ordered);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -213,20 +213,6 @@ class Product {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the product quantity when the order is received
|
|
||||||
*
|
|
||||||
* @param $productId
|
|
||||||
* @param $itemQuantity
|
|
||||||
*/
|
|
||||||
public function afterOrderRecieved($productId, $itemQuantity) {
|
|
||||||
$productGrid = $this->productGrid->findOneByField('product_id', $productId);
|
|
||||||
|
|
||||||
$productGrid->update(['quantity' => $productGrid->quantity - $itemQuantity]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manually invoke this function when you have created the products by importing or seeding or factory.
|
* Manually invoke this function when you have created the products by importing or seeding or factory.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -481,6 +481,10 @@ body {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.radio {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sale-summary {
|
.sale-summary {
|
||||||
|
|
|
||||||
|
|
@ -191,9 +191,14 @@ return [
|
||||||
'save-btn-title' => 'Save Shipment',
|
'save-btn-title' => 'Save Shipment',
|
||||||
'qty-ordered' => 'Qty Ordered',
|
'qty-ordered' => 'Qty Ordered',
|
||||||
'qty-to-ship' => 'Qty to Ship',
|
'qty-to-ship' => 'Qty to Ship',
|
||||||
|
'available-sources' => 'Available Sources',
|
||||||
|
'source' => 'Source',
|
||||||
|
'select-source' => 'Please Select Source',
|
||||||
|
'qty-available' => 'Qty Available',
|
||||||
|
'inventory-source' => 'Inventory Source',
|
||||||
'carrier-title' => 'Carrier Title',
|
'carrier-title' => 'Carrier Title',
|
||||||
'tracking-number' => 'Tracking Number',
|
'tracking-number' => 'Tracking Number',
|
||||||
'view-title' => 'Shipment #:shipment_id',
|
'view-title' => 'Shipment #:shipment_id'
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
'catalog' => [
|
'catalog' => [
|
||||||
|
|
@ -445,6 +450,7 @@ return [
|
||||||
'default-locale' => 'Default Locale',
|
'default-locale' => 'Default Locale',
|
||||||
'currencies' => 'Currencies',
|
'currencies' => 'Currencies',
|
||||||
'base-currency' => 'Base Currency',
|
'base-currency' => 'Base Currency',
|
||||||
|
'inventory_sources' => 'Inventory Sources',
|
||||||
'design' => 'Design',
|
'design' => 'Design',
|
||||||
'theme' => 'Theme',
|
'theme' => 'Theme',
|
||||||
'home_page_content' => 'Home Page Content',
|
'home_page_content' => 'Home Page Content',
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
</a>
|
</a>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if($order->canShip())
|
@if($order->canShip() && $order->channel)
|
||||||
<a href="{{ route('admin.sales.shipments.create', $order->id) }}" class="btn btn-lg btn-primary">
|
<a href="{{ route('admin.sales.shipments.create', $order->id) }}" class="btn btn-lg btn-primary">
|
||||||
{{ __('admin::app.sales.orders.shipment-btn-title') }}
|
{{ __('admin::app.sales.orders.shipment-btn-title') }}
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -368,6 +368,7 @@
|
||||||
<th>{{ __('admin::app.sales.shipments.order-id') }}</th>
|
<th>{{ __('admin::app.sales.shipments.order-id') }}</th>
|
||||||
<th>{{ __('admin::app.sales.shipments.order-date') }}</th>
|
<th>{{ __('admin::app.sales.shipments.order-date') }}</th>
|
||||||
<th>{{ __('admin::app.sales.shipments.customer-name') }}</th>
|
<th>{{ __('admin::app.sales.shipments.customer-name') }}</th>
|
||||||
|
<th>{{ __('admin::app.sales.shipments.inventory-source') }}</th>
|
||||||
<th>{{ __('admin::app.sales.shipments.total-qty') }}</th>
|
<th>{{ __('admin::app.sales.shipments.total-qty') }}</th>
|
||||||
<th>{{ __('admin::app.sales.shipments.action') }}</th>
|
<th>{{ __('admin::app.sales.shipments.action') }}</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -382,6 +383,9 @@
|
||||||
<td>#{{ $shipment->order->id }}</td>
|
<td>#{{ $shipment->order->id }}</td>
|
||||||
<td>{{ $shipment->order->created_at }}</td>
|
<td>{{ $shipment->order->created_at }}</td>
|
||||||
<td>{{ $shipment->address->name }}</td>
|
<td>{{ $shipment->address->name }}</td>
|
||||||
|
@if ($shipment->inventory_source)
|
||||||
|
<td>{{ $shipment->inventory_source->name }}</td>
|
||||||
|
@endif
|
||||||
<td>{{ $shipment->total_qty }}</td>
|
<td>{{ $shipment->total_qty }}</td>
|
||||||
<td class="action">
|
<td class="action">
|
||||||
<a href="{{ route('admin.sales.shipments.view', $shipment->id) }}">
|
<a href="{{ route('admin.sales.shipments.view', $shipment->id) }}">
|
||||||
|
|
|
||||||
|
|
@ -218,49 +218,7 @@
|
||||||
<accordian :title="'{{ __('admin::app.sales.orders.products-ordered') }}'" :active="true">
|
<accordian :title="'{{ __('admin::app.sales.orders.products-ordered') }}'" :active="true">
|
||||||
<div slot="body">
|
<div slot="body">
|
||||||
|
|
||||||
<div class="table">
|
<order-item-list></order-item-list>
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>{{ __('admin::app.sales.orders.SKU') }}</th>
|
|
||||||
<th>{{ __('admin::app.sales.orders.product-name') }}</th>
|
|
||||||
<th>{{ __('admin::app.sales.shipments.qty-ordered') }}</th>
|
|
||||||
<th>{{ __('admin::app.sales.shipments.qty-to-ship') }}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
|
||||||
|
|
||||||
@foreach ($order->items as $item)
|
|
||||||
@if ($item->qty_to_ship > 0)
|
|
||||||
<tr>
|
|
||||||
<td>{{ $item->type == 'configurable' ? $item->child->sku : $item->sku }}</td>
|
|
||||||
<td>
|
|
||||||
{{ $item->name }}
|
|
||||||
|
|
||||||
@if ($html = $item->getOptionDetailHtml())
|
|
||||||
<p>{{ $html }}</p>
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
<td>{{ $item->qty_ordered }}</td>
|
|
||||||
<td>
|
|
||||||
<div class="control-group" :class="[errors.has('shipment[items][{{ $item->id }}]') ? 'has-error' : '']">
|
|
||||||
<input type="text" v-validate="'required|numeric|min:0'" class="control" id="shipment[items][{{ $item->id }}]" name="shipment[items][{{ $item->id }}]" value="{{ $item->qty_to_ship }}" data-vv-as=""{{ __('admin::app.sales.shipments.qty-to-ship') }}""/>
|
|
||||||
|
|
||||||
<span class="control-error" v-if="errors.has('shipment[items][{{ $item->id }}]')">
|
|
||||||
@verbatim
|
|
||||||
{{ errors.first('shipment[items][<?php echo $item->id ?>]') }}
|
|
||||||
@endverbatim
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
@endif
|
|
||||||
@endforeach
|
|
||||||
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</accordian>
|
</accordian>
|
||||||
|
|
@ -269,4 +227,129 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@stop
|
@stop
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
|
||||||
|
<script type="text/x-template" id="order-item-list-template">
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="control-group" :class="[errors.has('shipment[source]') ? 'has-error' : '']">
|
||||||
|
<label for="shipment[source]" class="required">{{ __('admin::app.sales.shipments.source') }}</label>
|
||||||
|
|
||||||
|
<select v-validate="'required'" class="control" name="shipment[source]" id="shipment[source]" data-vv-as=""{{ __('admin::app.sales.shipments.source') }}"" v-model="source">
|
||||||
|
<option value="">{{ __('admin::app.sales.shipments.select-source') }}</option>
|
||||||
|
|
||||||
|
@foreach ($order->channel->inventory_sources as $key => $inventorySource)
|
||||||
|
<option value="{{ $inventorySource->id }}">{{ $inventorySource->name }}</option>
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<span class="control-error" v-if="errors.has('shipment[source]')">
|
||||||
|
@{{ errors.first('shipment[source]') }}
|
||||||
|
</span>
|
||||||
|
</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.shipments.qty-ordered') }}</th>
|
||||||
|
<th>{{ __('admin::app.sales.shipments.qty-to-ship') }}</th>
|
||||||
|
<th>{{ __('admin::app.sales.shipments.available-sources') }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
@foreach ($order->items as $item)
|
||||||
|
@if ($item->qty_to_ship > 0 && $item->product)
|
||||||
|
<tr>
|
||||||
|
<td>{{ $item->type == 'configurable' ? $item->child->sku : $item->sku }}</td>
|
||||||
|
<td>
|
||||||
|
{{ $item->name }}
|
||||||
|
|
||||||
|
@if ($html = $item->getOptionDetailHtml())
|
||||||
|
<p>{{ $html }}</p>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
|
<td>{{ $item->qty_ordered }}</td>
|
||||||
|
<td>{{ $item->qty_to_ship }}</td>
|
||||||
|
<td>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{ __('admin::app.sales.shipments.source') }}</th>
|
||||||
|
<th>{{ __('admin::app.sales.shipments.qty-available') }}</th>
|
||||||
|
<th>{{ __('admin::app.sales.shipments.qty-to-ship') }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
@foreach ($order->channel->inventory_sources as $key => $inventorySource)
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{ $inventorySource->name }}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<?php
|
||||||
|
if($item->type == 'configurable') {
|
||||||
|
$sourceQty = $item->child->product->inventory_source_qty($inventorySource);
|
||||||
|
} else {
|
||||||
|
$sourceQty = $item->product->inventory_source_qty($inventorySource);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
{{ $sourceQty }}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<?php $inputName = "shipment[items][$item->id][$inventorySource->id]"; ?>
|
||||||
|
|
||||||
|
<div class="control-group" :class="[errors.has('{{ $inputName }}') ? 'has-error' : '']">
|
||||||
|
|
||||||
|
<input type="text" v-validate="'required|numeric|min_value:0|max_value:{{$sourceQty}}'" class="control" id="{{ $inputName }}" name="{{ $inputName }}" value="0" data-vv-as=""{{ __('admin::app.sales.shipments.qty-to-ship') }}"" :disabled="source != '{{ $inventorySource->id }}'"/>
|
||||||
|
|
||||||
|
<span class="control-error" v-if="errors.has('{{ $inputName }}')">
|
||||||
|
@verbatim
|
||||||
|
{{ errors.first('<?php echo $inputName; ?>') }}
|
||||||
|
@endverbatim
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endforeach
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Vue.component('order-item-list', {
|
||||||
|
|
||||||
|
template: '#order-item-list-template',
|
||||||
|
|
||||||
|
inject: ['$validator'],
|
||||||
|
|
||||||
|
data: () => ({
|
||||||
|
source: ""
|
||||||
|
})
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
@endpush
|
||||||
|
|
@ -191,6 +191,18 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if ($shipment->inventory_source)
|
||||||
|
<div class="row">
|
||||||
|
<span class="title">
|
||||||
|
{{ __('admin::app.sales.shipments.inventory-source') }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span class="value">
|
||||||
|
{{ $shipment->inventory_source->name }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="title">
|
<span class="title">
|
||||||
{{ __('admin::app.sales.shipments.carrier-title') }}
|
{{ __('admin::app.sales.shipments.carrier-title') }}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,18 @@
|
||||||
<textarea class="control" id="description" name="description">{{ old('description') }}</textarea>
|
<textarea class="control" id="description" name="description">{{ old('description') }}</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group" :class="[errors.has('inventory_sources[]') ? 'has-error' : '']">
|
||||||
|
<label for="inventory_sources" class="required">{{ __('admin::app.settings.channels.inventory_sources') }}</label>
|
||||||
|
<select v-validate="'required'" class="control" id="inventory_sources" name="inventory_sources[]" data-vv-as=""{{ __('admin::app.settings.channels.inventory_sources') }}"" multiple>
|
||||||
|
@foreach(app('Webkul\Inventory\Repositories\InventorySourceRepository')->all() as $inventorySource)
|
||||||
|
<option value="{{ $inventorySource->id }}" {{ old('inventory_sources') && in_array($inventorySource->id, old('inventory_sources')) ? 'selected' : '' }}>
|
||||||
|
{{ $inventorySource->name }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
<span class="control-error" v-if="errors.has('inventory_sources[]')">@{{ errors.first('inventory_sources[]') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label for="hostname">{{ __('admin::app.settings.channels.hostname') }}</label>
|
<label for="hostname">{{ __('admin::app.settings.channels.hostname') }}</label>
|
||||||
<input class="control" id="hostname" name="hostname" value="{{ old('hostname') }}" placeholder="https://www.example.com"/>
|
<input class="control" id="hostname" name="hostname" value="{{ old('hostname') }}" placeholder="https://www.example.com"/>
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,19 @@
|
||||||
<textarea class="control" id="description" name="description">{{ old('description') ?: $channel->description }}</textarea>
|
<textarea class="control" id="description" name="description">{{ old('description') ?: $channel->description }}</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="control-group" :class="[errors.has('inventory_sources[]') ? 'has-error' : '']">
|
||||||
|
<label for="inventory_sources" class="required">{{ __('admin::app.settings.channels.inventory_sources') }}</label>
|
||||||
|
<?php $selectedOptionIds = old('inventory_sources') ?: $channel->inventory_sources->pluck('id')->toArray() ?>
|
||||||
|
<select v-validate="'required'" class="control" id="inventory_sources" name="inventory_sources[]" data-vv-as=""{{ __('admin::app.settings.channels.inventory_sources') }}"" multiple>
|
||||||
|
@foreach(app('Webkul\Inventory\Repositories\InventorySourceRepository')->all() as $inventorySource)
|
||||||
|
<option value="{{ $inventorySource->id }}" {{ in_array($inventorySource->id, $selectedOptionIds) ? 'selected' : '' }}>
|
||||||
|
{{ $inventorySource->name }}
|
||||||
|
</option>
|
||||||
|
@endforeach
|
||||||
|
</select>
|
||||||
|
<span class="control-error" v-if="errors.has('inventory_sources[]')">@{{ errors.first('inventory_sources[]') }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<label for="hostname">{{ __('admin::app.settings.channels.hostname') }}</label>
|
<label for="hostname">{{ __('admin::app.settings.channels.hostname') }}</label>
|
||||||
<input type="text" class="control" id="hostname" name="hostname" value="{{ $channel->hostname }}" placeholder="https://www.example.com"/>
|
<input type="text" class="control" id="hostname" name="hostname" value="{{ $channel->hostname }}" placeholder="https://www.example.com"/>
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
const { mix } = require("laravel-mix");
|
const { mix } = require("laravel-mix");
|
||||||
require("laravel-mix-merge-manifest");
|
require("laravel-mix-merge-manifest");
|
||||||
|
|
||||||
var publicPath = 'publishable/assets';
|
// var publicPath = 'publishable/assets';
|
||||||
// var publicPath = "../../../public/vendor/webkul/admin/assets";
|
var publicPath = "../../../public/vendor/webkul/admin/assets";
|
||||||
|
|
||||||
mix.setPublicPath(publicPath).mergeManifest();
|
mix.setPublicPath(publicPath).mergeManifest();
|
||||||
mix.disableNotifications();
|
mix.disableNotifications();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreateChannelInventorySourcesTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('channel_inventory_sources', function (Blueprint $table) {
|
||||||
|
$table->integer('channel_id')->unsigned();
|
||||||
|
$table->integer('inventory_source_id')->unsigned();
|
||||||
|
|
||||||
|
$table->unique(['channel_id', 'inventory_source_id']);
|
||||||
|
$table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
|
||||||
|
$table->foreign('inventory_source_id')->references('id')->on('inventory_sources')->onDelete('cascade');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('channel_inventory_sources');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -120,6 +120,7 @@ class ChannelController extends Controller
|
||||||
'code' => ['required', 'unique:channels,code,' . $id, new \Webkul\Core\Contracts\Validations\Code],
|
'code' => ['required', 'unique:channels,code,' . $id, new \Webkul\Core\Contracts\Validations\Code],
|
||||||
'name' => 'required',
|
'name' => 'required',
|
||||||
'locales' => 'required|array|min:1',
|
'locales' => 'required|array|min:1',
|
||||||
|
'inventory_sources' => 'required|array|min:1',
|
||||||
'default_locale_id' => 'required',
|
'default_locale_id' => 'required',
|
||||||
'currencies' => 'required|array|min:1',
|
'currencies' => 'required|array|min:1',
|
||||||
'base_currency_id' => 'required',
|
'base_currency_id' => 'required',
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,10 @@
|
||||||
namespace Webkul\Core\Models;
|
namespace Webkul\Core\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Webkul\Core\Models\Locale;
|
use Webkul\Core\Models\Locale;
|
||||||
use Webkul\Core\Models\Currency;
|
use Webkul\Core\Models\Currency;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Webkul\Inventory\Models\InventorySource;
|
||||||
|
|
||||||
class Channel extends Model
|
class Channel extends Model
|
||||||
{
|
{
|
||||||
|
|
@ -35,6 +36,14 @@ class Channel extends Model
|
||||||
return $this->belongsToMany(Currency::class, 'channel_currencies');
|
return $this->belongsToMany(Currency::class, 'channel_currencies');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the channel inventory sources.
|
||||||
|
*/
|
||||||
|
public function inventory_sources()
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(InventorySource::class, 'channel_inventory_sources');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected $with = ['base_currency'];
|
protected $with = ['base_currency'];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ class ChannelRepository extends Repository
|
||||||
|
|
||||||
$channel->currencies()->sync($data['currencies']);
|
$channel->currencies()->sync($data['currencies']);
|
||||||
|
|
||||||
|
$channel->inventory_sources()->sync($data['inventory_sources']);
|
||||||
|
|
||||||
$this->uploadImages($data, $channel);
|
$this->uploadImages($data, $channel);
|
||||||
|
|
||||||
$this->uploadImages($data, $channel, 'favicon');
|
$this->uploadImages($data, $channel, 'favicon');
|
||||||
|
|
@ -58,6 +60,8 @@ class ChannelRepository extends Repository
|
||||||
|
|
||||||
$channel->currencies()->sync($data['currencies']);
|
$channel->currencies()->sync($data['currencies']);
|
||||||
|
|
||||||
|
$channel->inventory_sources()->sync($data['inventory_sources']);
|
||||||
|
|
||||||
$this->uploadImages($data, $channel);
|
$this->uploadImages($data, $channel);
|
||||||
|
|
||||||
$this->uploadImages($data, $channel, 'favicon');
|
$this->uploadImages($data, $channel, 'favicon');
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
class CreateProductSalableInventoriesTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('product_salable_inventories', function (Blueprint $table) {
|
||||||
|
$table->increments('id');
|
||||||
|
$table->integer('qty')->default(0);
|
||||||
|
$table->integer('sold_qty')->default(0);
|
||||||
|
$table->integer('product_id')->unsigned();
|
||||||
|
$table->integer('channel_id')->unsigned();
|
||||||
|
|
||||||
|
$table->unique(['product_id', 'channel_id']);
|
||||||
|
$table->foreign('product_id')->references('id')->on('products')->onDelete('cascade');
|
||||||
|
$table->foreign('channel_id')->references('id')->on('channels')->onDelete('cascade');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('product_salable_inventories');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -76,6 +76,14 @@ class Product extends Model
|
||||||
return $this->hasMany(ProductInventory::class, 'product_id');
|
return $this->hasMany(ProductInventory::class, 'product_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The salable inventories that belong to the product.
|
||||||
|
*/
|
||||||
|
public function salable_inventories()
|
||||||
|
{
|
||||||
|
return $this->hasMany(ProductSalableInventory::class, 'product_id');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The inventory sources that belong to the product.
|
* The inventory sources that belong to the product.
|
||||||
*/
|
*/
|
||||||
|
|
@ -140,6 +148,16 @@ class Product extends Model
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param integer $qty
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function inventory_source_qty($inventorySource)
|
||||||
|
{
|
||||||
|
return $this->inventories()->where('inventory_source_id', $inventorySource->id)->sum('qty');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param integer $qty
|
* @param integer $qty
|
||||||
*
|
*
|
||||||
|
|
@ -147,15 +165,14 @@ class Product extends Model
|
||||||
*/
|
*/
|
||||||
public function haveSufficientQuantity($qty)
|
public function haveSufficientQuantity($qty)
|
||||||
{
|
{
|
||||||
$inventories = $this->inventory_sources()->orderBy('priority', 'asc')->get();
|
$salableInventories = $this->salable_inventories()->get();
|
||||||
|
|
||||||
$total = 0;
|
$total = 0;
|
||||||
|
|
||||||
foreach($inventories as $inventorySource) {
|
foreach($salableInventories as $inventory) {
|
||||||
if(!$inventorySource->status)
|
if($inventory->channel->id == core()->getCurrentChannel()->id) {
|
||||||
continue;
|
$total += $inventory->qty;
|
||||||
|
}
|
||||||
$total += $inventorySource->pivot->qty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $qty <= $total ? true : false;
|
return $qty <= $total ? true : false;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Product\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Webkul\Inventory\Models\InventorySource;
|
||||||
|
use Webkul\Core\Models\Channel;
|
||||||
|
|
||||||
|
class ProductSalableInventory extends Model
|
||||||
|
{
|
||||||
|
public $timestamps = false;
|
||||||
|
|
||||||
|
protected $fillable = ['qty', 'sold_qty', 'product_id', 'channel_id'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the channel owns the inventory.
|
||||||
|
*/
|
||||||
|
public function channel()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Channel::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Get the inventory source owns the product.
|
||||||
|
// */
|
||||||
|
// public function inventory_source()
|
||||||
|
// {
|
||||||
|
// return $this->belongsTo(InventorySource::class);
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the product that owns the product inventory.
|
||||||
|
*/
|
||||||
|
public function product()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Product::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ namespace Webkul\Product\Repositories;
|
||||||
|
|
||||||
use Illuminate\Container\Container as App;
|
use Illuminate\Container\Container as App;
|
||||||
use Webkul\Core\Eloquent\Repository;
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
use Webkul\Product\Repositories\ProductSalableInventoryRepository as SalableInventoryRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Product Inventory Reposotory
|
* Product Inventory Reposotory
|
||||||
|
|
@ -13,6 +14,30 @@ use Webkul\Core\Eloquent\Repository;
|
||||||
*/
|
*/
|
||||||
class ProductInventoryRepository extends Repository
|
class ProductInventoryRepository extends Repository
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProductSalableInventoryRepository object
|
||||||
|
*
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
protected $salableInventory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new repository instance.
|
||||||
|
*
|
||||||
|
* @param Webkul\Product\Repositories\ProductSalableInventoryRepository $salableInventory
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
SalableInventoryRepository $salableInventory,
|
||||||
|
App $app
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$this->salableInventory = $salableInventory;
|
||||||
|
|
||||||
|
parent::__construct($app);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify Model class name
|
* Specify Model class name
|
||||||
*
|
*
|
||||||
|
|
@ -24,7 +49,7 @@ class ProductInventoryRepository extends Repository
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $inventories
|
* @param array $data
|
||||||
* @param mixed $product
|
* @param mixed $product
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
|
|
@ -61,5 +86,7 @@ class ProductInventoryRepository extends Repository
|
||||||
if($inventorySourceIds->count()) {
|
if($inventorySourceIds->count()) {
|
||||||
$product->inventory_sources()->detach($inventorySourceIds);
|
$product->inventory_sources()->detach($inventorySourceIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->salableInventory->saveInventories($product);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Product\Repositories;
|
||||||
|
|
||||||
|
use Illuminate\Container\Container as App;
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Product Salable Inventory Reposotory
|
||||||
|
*
|
||||||
|
* @author Jitendra Singh <jitendra@webkul.com>
|
||||||
|
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||||
|
*/
|
||||||
|
class ProductSalableInventoryRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Product\Models\ProductSalableInventory';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $product
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function saveInventories($product)
|
||||||
|
{
|
||||||
|
foreach (core()->getAllChannels() as $channel) {
|
||||||
|
$inventorySourceIds = $channel->inventory_sources()->pluck('inventory_source_id');
|
||||||
|
|
||||||
|
$salableQty = 0;
|
||||||
|
|
||||||
|
foreach ($product->inventories()->get() as $productInventory) {
|
||||||
|
if(is_numeric($index = $inventorySourceIds->search($productInventory->inventory_source->id))) {
|
||||||
|
$salableQty += $productInventory->qty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$salableInventory = $this->findOneWhere([
|
||||||
|
'product_id' => $product->id,
|
||||||
|
'channel_id' => $channel->id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
if($salableInventory) {
|
||||||
|
$salableQty -= $salableInventory->sold_qty;
|
||||||
|
|
||||||
|
if ($salableQty < 0)
|
||||||
|
$salableQty = 0;
|
||||||
|
|
||||||
|
$this->update(['qty' => $salableQty], $salableInventory->id);
|
||||||
|
} else {
|
||||||
|
$this->create([
|
||||||
|
'qty' => $salableQty,
|
||||||
|
'product_id' => $product->id,
|
||||||
|
'channel_id' => $channel->id,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Webkul\Sales\Contracts;
|
|
||||||
|
|
||||||
interface OrderItemInventory
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
@ -4,7 +4,7 @@ use Illuminate\Support\Facades\Schema;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
class CreateOrderItemInventories extends Migration
|
class AlterShipmentsTable extends Migration
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Run the migrations.
|
* Run the migrations.
|
||||||
|
|
@ -13,12 +13,9 @@ class CreateOrderItemInventories extends Migration
|
||||||
*/
|
*/
|
||||||
public function up()
|
public function up()
|
||||||
{
|
{
|
||||||
Schema::create('order_item_inventories', function (Blueprint $table) {
|
Schema::table('shipments', function (Blueprint $table) {
|
||||||
$table->increments('id');
|
|
||||||
$table->integer('qty')->default(0);
|
|
||||||
$table->integer('inventory_source_id')->unsigned()->nullable();
|
$table->integer('inventory_source_id')->unsigned()->nullable();
|
||||||
$table->integer('order_item_id')->unsigned()->nullable();
|
$table->foreign('inventory_source_id')->references('id')->on('inventory_sources')->onDelete('set null');
|
||||||
$table->timestamps();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -29,6 +26,6 @@ class CreateOrderItemInventories extends Migration
|
||||||
*/
|
*/
|
||||||
public function down()
|
public function down()
|
||||||
{
|
{
|
||||||
Schema::dropIfExists('order_item_inventories');
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -22,7 +22,8 @@ class Order extends Model implements OrderContract
|
||||||
/**
|
/**
|
||||||
* Get the order items record associated with the order.
|
* Get the order items record associated with the order.
|
||||||
*/
|
*/
|
||||||
public function getCustomerFullNameAttribute() {
|
public function getCustomerFullNameAttribute()
|
||||||
|
{
|
||||||
return $this->customer_first_name . ' ' . $this->customer_last_name;
|
return $this->customer_first_name . ' ' . $this->customer_last_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,21 +54,24 @@ class Order extends Model implements OrderContract
|
||||||
/**
|
/**
|
||||||
* Get the order items record associated with the order.
|
* Get the order items record associated with the order.
|
||||||
*/
|
*/
|
||||||
public function items() {
|
public function items()
|
||||||
|
{
|
||||||
return $this->hasMany(OrderItemProxy::modelClass())->whereNull('parent_id');
|
return $this->hasMany(OrderItemProxy::modelClass())->whereNull('parent_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the order shipments record associated with the order.
|
* Get the order shipments record associated with the order.
|
||||||
*/
|
*/
|
||||||
public function shipments() {
|
public function shipments()
|
||||||
|
{
|
||||||
return $this->hasMany(ShipmentProxy::modelClass());
|
return $this->hasMany(ShipmentProxy::modelClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the order invoices record associated with the order.
|
* Get the order invoices record associated with the order.
|
||||||
*/
|
*/
|
||||||
public function invoices() {
|
public function invoices()
|
||||||
|
{
|
||||||
return $this->hasMany(InvoiceProxy::modelClass());
|
return $this->hasMany(InvoiceProxy::modelClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,21 +17,24 @@ class OrderItem extends Model implements OrderItemContract
|
||||||
/**
|
/**
|
||||||
* Get remaining qty for shipping.
|
* Get remaining qty for shipping.
|
||||||
*/
|
*/
|
||||||
public function getQtyToShipAttribute() {
|
public function getQtyToShipAttribute()
|
||||||
|
{
|
||||||
return $this->qty_ordered - $this->qty_shipped - $this->qty_refunded - $this->qty_canceled;
|
return $this->qty_ordered - $this->qty_shipped - $this->qty_refunded - $this->qty_canceled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get remaining qty for invoice.
|
* Get remaining qty for invoice.
|
||||||
*/
|
*/
|
||||||
public function getQtyToInvoiceAttribute() {
|
public function getQtyToInvoiceAttribute()
|
||||||
|
{
|
||||||
return $this->qty_ordered - $this->qty_invoiced - $this->qty_canceled;
|
return $this->qty_ordered - $this->qty_invoiced - $this->qty_canceled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get remaining qty for cancel.
|
* Get remaining qty for cancel.
|
||||||
*/
|
*/
|
||||||
public function getQtyToCancelAttribute() {
|
public function getQtyToCancelAttribute()
|
||||||
|
{
|
||||||
return $this->qty_ordered - $this->qty_canceled - $this->qty_invoiced;
|
return $this->qty_ordered - $this->qty_canceled - $this->qty_invoiced;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -59,24 +62,19 @@ class OrderItem extends Model implements OrderItemContract
|
||||||
return $this->hasOne(OrderItemProxy::modelClass(), 'parent_id');
|
return $this->hasOne(OrderItemProxy::modelClass(), 'parent_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the inventories record associated with the order item.
|
|
||||||
*/
|
|
||||||
public function inventories() {
|
|
||||||
return $this->hasMany(CartItemInventoryProxy::modelClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the invoice items record associated with the order item.
|
* Get the invoice items record associated with the order item.
|
||||||
*/
|
*/
|
||||||
public function invoice_items() {
|
public function invoice_items()
|
||||||
|
{
|
||||||
return $this->hasMany(InvoiceItemProxy::modelClass());
|
return $this->hasMany(InvoiceItemProxy::modelClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the shipment items record associated with the order item.
|
* Get the shipment items record associated with the order item.
|
||||||
*/
|
*/
|
||||||
public function shipment_items() {
|
public function shipment_items()
|
||||||
|
{
|
||||||
return $this->hasMany(ShipmentItemProxy::modelClass());
|
return $this->hasMany(ShipmentItemProxy::modelClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Webkul\Sales\Models;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Webkul\Sales\Contracts\OrderItemInventory as OrderItemInventoryContract;
|
|
||||||
|
|
||||||
class OrderItemInventory extends Model implements OrderItemInventoryContract
|
|
||||||
{
|
|
||||||
protected $guarded = ['id', 'child', 'created_at', 'updated_at'];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the order item record associated with the order item inventory.
|
|
||||||
*/
|
|
||||||
public function order_item()
|
|
||||||
{
|
|
||||||
return $this->belongsTo(OrderItemProxy::modelClass());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Webkul\Sales\Models;
|
|
||||||
|
|
||||||
use Konekt\Concord\Proxies\ModelProxy;
|
|
||||||
|
|
||||||
class OrderItemInventoryProxy extends ModelProxy
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
namespace Webkul\Sales\Models;
|
namespace Webkul\Sales\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Webkul\Inventory\Models\InventorySource;
|
||||||
use Webkul\Sales\Contracts\Shipment as ShipmentContract;
|
use Webkul\Sales\Contracts\Shipment as ShipmentContract;
|
||||||
|
|
||||||
class Shipment extends Model implements ShipmentContract
|
class Shipment extends Model implements ShipmentContract
|
||||||
|
|
@ -20,10 +21,19 @@ class Shipment extends Model implements ShipmentContract
|
||||||
/**
|
/**
|
||||||
* Get the shipment items record associated with the shipment.
|
* Get the shipment items record associated with the shipment.
|
||||||
*/
|
*/
|
||||||
public function items() {
|
public function items()
|
||||||
|
{
|
||||||
return $this->hasMany(ShipmentItemProxy::modelClass());
|
return $this->hasMany(ShipmentItemProxy::modelClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the inventory source associated with the shipment.
|
||||||
|
*/
|
||||||
|
public function inventory_source()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(InventorySource::class, 'inventory_source_id');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the customer record associated with the shipment.
|
* Get the customer record associated with the shipment.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ class ModuleServiceProvider extends BaseModuleServiceProvider
|
||||||
protected $models = [
|
protected $models = [
|
||||||
\Webkul\Sales\Models\Order::class,
|
\Webkul\Sales\Models\Order::class,
|
||||||
\Webkul\Sales\Models\OrderItem::class,
|
\Webkul\Sales\Models\OrderItem::class,
|
||||||
\Webkul\Sales\Models\OrderItemInventory::class,
|
|
||||||
\Webkul\Sales\Models\OrderAddress::class,
|
\Webkul\Sales\Models\OrderAddress::class,
|
||||||
\Webkul\Sales\Models\OrderPayment::class,
|
\Webkul\Sales\Models\OrderPayment::class,
|
||||||
\Webkul\Sales\Models\Invoice::class,
|
\Webkul\Sales\Models\Invoice::class,
|
||||||
|
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Webkul\Sales\Repositories;
|
|
||||||
|
|
||||||
use Illuminate\Container\Container as App;
|
|
||||||
use Webkul\Core\Eloquent\Repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Order Item Inventory Reposotory
|
|
||||||
*
|
|
||||||
* @author Jitendra Singh <jitendra@webkul.com>
|
|
||||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
|
||||||
*/
|
|
||||||
|
|
||||||
class OrderItemInventoryRepository extends Repository
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Specify Model class name
|
|
||||||
*
|
|
||||||
* @return Mixed
|
|
||||||
*/
|
|
||||||
|
|
||||||
function model()
|
|
||||||
{
|
|
||||||
return 'Webkul\Sales\Contracts\OrderItemInventory';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $data
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function create(array $data)
|
|
||||||
{
|
|
||||||
$orderItem = $data['orderItem'];
|
|
||||||
|
|
||||||
$orderedQuantity = $orderItem->qty_ordered;
|
|
||||||
|
|
||||||
$product = $orderItem->type == 'configurable' ? $orderItem->child->product : $orderItem->product;
|
|
||||||
|
|
||||||
if($product) {
|
|
||||||
$inventories = $product->inventory_sources()->orderBy('priority', 'asc')->get();
|
|
||||||
|
|
||||||
foreach($inventories as $inventorySource) {
|
|
||||||
if(!$orderedQuantity)
|
|
||||||
break;
|
|
||||||
|
|
||||||
$sourceQuantity = $inventorySource->pivot->qty;
|
|
||||||
|
|
||||||
if(!$inventorySource->status || !$sourceQuantity)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if($sourceQuantity >= $orderedQuantity) {
|
|
||||||
$orderItemQuantity = $orderedQuantity;
|
|
||||||
|
|
||||||
$sourceQuantity -= $orderItemQuantity;
|
|
||||||
|
|
||||||
$orderedQuantity = 0;
|
|
||||||
} else {
|
|
||||||
$orderItemQuantity = $sourceQuantity;
|
|
||||||
|
|
||||||
$sourceQuantity = 0;
|
|
||||||
|
|
||||||
$orderedQuantity -= $orderItemQuantity;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->model->create([
|
|
||||||
'qty' => $orderItemQuantity,
|
|
||||||
'order_item_id' => $orderItem->id,
|
|
||||||
'inventory_source_id' => $inventorySource->id,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$inventorySource->pivot->update([
|
|
||||||
'qty' => $sourceQuantity
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -19,7 +19,6 @@ class OrderItemRepository extends Repository
|
||||||
*
|
*
|
||||||
* @return Mixed
|
* @return Mixed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function model()
|
function model()
|
||||||
{
|
{
|
||||||
return 'Webkul\Sales\Contracts\OrderItem';
|
return 'Webkul\Sales\Contracts\OrderItem';
|
||||||
|
|
@ -78,4 +77,34 @@ class OrderItemRepository extends Repository
|
||||||
|
|
||||||
return $orderItem;
|
return $orderItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $orderItem
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function manageStock($orderItem)
|
||||||
|
{
|
||||||
|
if(!$orderedQuantity = $orderItem->qty_ordered)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$product = $orderItem->type == 'configurable' ? $orderItem->child->product : $orderItem->product;
|
||||||
|
|
||||||
|
if(!$product) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$salableInventory = $product->salable_inventories()
|
||||||
|
->where('channel_id', $orderItem->order->channel->id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if($salableInventory) {
|
||||||
|
$soldQty = $salableInventory->sold_qty + $orderItem->qty_ordered;
|
||||||
|
|
||||||
|
$salableInventory->update([
|
||||||
|
'qty' => ($salableInventory->qty - $orderItem->qty_ordered),
|
||||||
|
'sold_qty' => $soldQty
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -8,7 +8,6 @@ use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Webkul\Core\Eloquent\Repository;
|
use Webkul\Core\Eloquent\Repository;
|
||||||
use Webkul\Sales\Repositories\OrderItemRepository;
|
use Webkul\Sales\Repositories\OrderItemRepository;
|
||||||
use Webkul\Sales\Repositories\OrderItemInventoryRepository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Order Reposotory
|
* Order Reposotory
|
||||||
|
|
@ -26,30 +25,19 @@ class OrderRepository extends Repository
|
||||||
*/
|
*/
|
||||||
protected $orderItem;
|
protected $orderItem;
|
||||||
|
|
||||||
/**
|
|
||||||
* OrderItemInventoryRepository object
|
|
||||||
*
|
|
||||||
* @var Object
|
|
||||||
*/
|
|
||||||
protected $orderItemInventory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new repository instance.
|
* Create a new repository instance.
|
||||||
*
|
*
|
||||||
* @param Webkul\Sales\Repositories\OrderItemRepository $orderItem
|
* @param Webkul\Sales\Repositories\OrderItemRepository $orderItem
|
||||||
* @param Webkul\Sales\Repositories\OrderItemInventoryRepository $orderItemInventory
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
OrderItemRepository $orderItem,
|
OrderItemRepository $orderItem,
|
||||||
OrderItemInventoryRepository $orderItemInventory,
|
|
||||||
App $app
|
App $app
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
$this->orderItem = $orderItem;
|
$this->orderItem = $orderItem;
|
||||||
|
|
||||||
$this->orderItemInventory = $orderItemInventory;
|
|
||||||
|
|
||||||
parent::__construct($app);
|
parent::__construct($app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,7 +95,7 @@ class OrderRepository extends Repository
|
||||||
$orderItem->child = $this->orderItem->create(array_merge($item['child'], ['order_id' => $order->id, 'parent_id' => $orderItem->id]));
|
$orderItem->child = $this->orderItem->create(array_merge($item['child'], ['order_id' => $order->id, 'parent_id' => $orderItem->id]));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->orderItemInventory->create(['orderItem' => $orderItem]);
|
$this->orderItem->manageStock($orderItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
Event::fire('checkout.order.save.after', $order);
|
Event::fire('checkout.order.save.after', $order);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Webkul\Sales\Repositories;
|
||||||
|
|
||||||
|
use Illuminate\Container\Container as App;
|
||||||
|
use Webkul\Core\Eloquent\Repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ShipmentItem Reposotory
|
||||||
|
*
|
||||||
|
* @author Jitendra Singh <jitendra@webkul.com>
|
||||||
|
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
||||||
|
*/
|
||||||
|
class ShipmentItemRepository extends Repository
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Specify Model class name
|
||||||
|
*
|
||||||
|
* @return Mixed
|
||||||
|
*/
|
||||||
|
function model()
|
||||||
|
{
|
||||||
|
return 'Webkul\Sales\Contracts\ShipmentItem';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updateProductInventory($data)
|
||||||
|
{
|
||||||
|
$salableInventory = $data['product']->salable_inventories()
|
||||||
|
->where('channel_id', $data['shipment']->order->channel->id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$inventory = $data['product']->inventories()
|
||||||
|
->where('inventory_source_id', $data['shipment']->inventory_source_id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if (($salableQty = $salableInventory->sold_qty - $data['qty']) < 0) {
|
||||||
|
$salableQty = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$salableInventory->update([
|
||||||
|
'sold_qty' => $salableQty
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (($qty = $inventory->qty - $data['qty']) < 0) {
|
||||||
|
$qty = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$inventory->update([
|
||||||
|
'qty' => $data['qty']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -88,31 +88,37 @@ class ShipmentRepository extends Repository
|
||||||
|
|
||||||
$order = $this->order->find($data['order_id']);
|
$order = $this->order->find($data['order_id']);
|
||||||
|
|
||||||
$totalQty = array_sum($data['shipment']['items']);
|
|
||||||
|
|
||||||
$shipment = $this->model->create([
|
$shipment = $this->model->create([
|
||||||
'order_id' => $order->id,
|
'order_id' => $order->id,
|
||||||
'total_qty' => $totalQty,
|
'total_qty' => 0,
|
||||||
'carrier_title' => $data['shipment']['carrier_title'],
|
'carrier_title' => $data['shipment']['carrier_title'],
|
||||||
'track_number' => $data['shipment']['track_number'],
|
'track_number' => $data['shipment']['track_number'],
|
||||||
'customer_id' => $order->customer_id,
|
'customer_id' => $order->customer_id,
|
||||||
'customer_type' => $order->customer_type,
|
'customer_type' => $order->customer_type,
|
||||||
'order_address_id' => $order->shipping_address->id,
|
'order_address_id' => $order->shipping_address->id,
|
||||||
|
'inventory_source_id' => $data['shipment']['source'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
foreach ($data['shipment']['items'] as $itemId => $qty) {
|
$totalQty = 0;
|
||||||
if(!$qty) continue;
|
|
||||||
|
foreach ($data['shipment']['items'] as $itemId => $inventorySource) {
|
||||||
|
$qty = $inventorySource[$data['shipment']['source']];
|
||||||
|
|
||||||
$orderItem = $this->orderItem->find($itemId);
|
$orderItem = $this->orderItem->find($itemId);
|
||||||
|
|
||||||
if($qty > $orderItem->qty_to_ship)
|
$product = ($orderItem->type == 'configurable')
|
||||||
$qty = $orderItem->qty_to_ship;
|
? $orderItem->child->product
|
||||||
|
: $orderItem->product;
|
||||||
|
|
||||||
|
$totalQty += $qty;
|
||||||
|
|
||||||
$shipmentItem = $this->shipmentItem->create([
|
$shipmentItem = $this->shipmentItem->create([
|
||||||
'shipment_id' => $shipment->id,
|
'shipment_id' => $shipment->id,
|
||||||
'order_item_id' => $orderItem->id,
|
'order_item_id' => $orderItem->id,
|
||||||
'name' => $orderItem->name,
|
'name' => $orderItem->name,
|
||||||
'sku' => ($orderItem->type == 'configurable' ? $orderItem->child->sku : $orderItem->sku),
|
'sku' => ($orderItem->type == 'configurable')
|
||||||
|
? $orderItem->child->sku
|
||||||
|
: $orderItem->sku,
|
||||||
'qty' => $qty,
|
'qty' => $qty,
|
||||||
'weight' => $orderItem->weight * $qty,
|
'weight' => $orderItem->weight * $qty,
|
||||||
'price' => $orderItem->price,
|
'price' => $orderItem->price,
|
||||||
|
|
@ -124,9 +130,20 @@ class ShipmentRepository extends Repository
|
||||||
'additional' => $orderItem->additional,
|
'additional' => $orderItem->additional,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$this->shipmentItem->updateProductInventory([
|
||||||
|
'shipment' => $shipment,
|
||||||
|
'shipmentItem' => $shipmentItem,
|
||||||
|
'product' => $product,
|
||||||
|
'qty' => $qty
|
||||||
|
]);
|
||||||
|
|
||||||
$this->orderItem->update(['qty_shipped' => $orderItem->qty_shipped + $qty], $orderItem->id);
|
$this->orderItem->update(['qty_shipped' => $orderItem->qty_shipped + $qty], $orderItem->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$shipment->update([
|
||||||
|
'total_qty' => $totalQty
|
||||||
|
]);
|
||||||
|
|
||||||
$this->order->updateOrderStatus($order);
|
$this->order->updateOrderStatus($order);
|
||||||
|
|
||||||
Event::fire('sales.shipment.save.after', $shipment);
|
Event::fire('sales.shipment.save.after', $shipment);
|
||||||
|
|
@ -140,4 +157,19 @@ class ShipmentRepository extends Repository
|
||||||
|
|
||||||
return $shipment;
|
return $shipment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getTotalQty(array $data)
|
||||||
|
{
|
||||||
|
$qty = 0;
|
||||||
|
|
||||||
|
foreach ($data['shipment']['items'] as $itemId => $inventorySource) {
|
||||||
|
$qty += $inventorySource[$data['shipment']['source']];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $qty;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Webkul\Sales\Repositories;
|
|
||||||
|
|
||||||
use Illuminate\Container\Container as App;
|
|
||||||
use Webkul\Core\Eloquent\Repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ShipmentItem Reposotory
|
|
||||||
*
|
|
||||||
* @author Jitendra Singh <jitendra@webkul.com>
|
|
||||||
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ShipmentItemRepository extends Repository
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Specify Model class name
|
|
||||||
*
|
|
||||||
* @return Mixed
|
|
||||||
*/
|
|
||||||
|
|
||||||
function model()
|
|
||||||
{
|
|
||||||
return 'Webkul\Sales\Contracts\ShipmentItem';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue