Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
- Added : refund receipt for orders
- Fixed: issue while removing permissions
- Added: enhanced refunds
  • Loading branch information
Blair2004 committed Jul 30, 2021
1 parent 7ad9dc9 commit 1fb6719
Show file tree
Hide file tree
Showing 25 changed files with 413 additions and 26 deletions.
22 changes: 22 additions & 0 deletions app/Crud/OrderCrud.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Exception;
use App\Models\Order;
use App\Services\OrdersService;
use Illuminate\Support\Facades\DB;

class OrderCrud extends CrudService
{
Expand Down Expand Up @@ -508,6 +509,27 @@ public function setActions( $entry, $namespace )
]
];

/**
* We'll check if the order has refunds
* to add a refund receipt for printing
*/
$refundCount = DB::table( Hook::filter( 'ns-model-table', 'nexopos_orders_refunds' ) )
->where( 'order_id', $entry->id )
->count();

$hasRefunds = $refundCount > 0;

if ( $hasRefunds ) {
array_splice( $entry->{ '$actions' }, 3, 0, [
[
'label' => '<i class="mr-2 las la-receipt"></i> ' . __( 'Refund Receipt' ),
'type' => 'POPUP',
'namespace' => 'ns.order-refunds',
'url' => ns()->url( '/dashboard/' . 'orders' . '/refund-receipt/' . $entry->id ),
]
]);
}

return $entry;
}

Expand Down
28 changes: 28 additions & 0 deletions app/Http/Controllers/Dashboard/OrdersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use App\Crud\PaymentTypeCrud;
use App\Exceptions\NotAllowedException;
use App\Models\OrderInstalment;
use App\Models\OrderRefund;
use App\Models\PaymentType;
use Modules\NsMultiStore\Models\Store;

Expand Down Expand Up @@ -122,6 +123,7 @@ public function getOrders( Order $id = null ) {
$id->load( 'shipping_address' );
$id->load( 'billing_address' );
$id->load( 'products.unit' );
$id->load( 'refundedProducts.unit', 'refundedProducts.product' );
return $id;
}

Expand Down Expand Up @@ -193,6 +195,22 @@ public function orderInvoice( Order $order )
]);
}

public function orderRefundReceipt( OrderRefund $refund )
{
$refund->load( 'order.customer', 'order.refundedProducts', 'order.refund.author', 'order.shipping_address', 'order.billing_address', 'order.user' );
$refund->load( 'refunded_products.product', 'refunded_products.unit' );

$refund->refunded_products = Hook::filter( 'ns-refund-receipt-products', $refund->refunded_products );

return $this->view( 'pages.dashboard.orders.templates.refund-receipt', [
'refund' => $refund,
'ordersService' => app()->make( OrdersService::class ),
'billing' => ( new CustomerCrud() )->getForm()[ 'tabs' ][ 'billing' ][ 'fields' ],
'shipping' => ( new CustomerCrud() )->getForm()[ 'tabs' ][ 'shipping' ][ 'fields' ],
'title' => sprintf( __( 'Order Refund Receipt &mdash; %s' ), $refund->order->code )
]);
}

public function orderReceipt( Order $order )
{
$order->load( 'customer' );
Expand Down Expand Up @@ -334,5 +352,15 @@ public function updatePaymentType( PaymentType $paymentType )
{
return PaymentTypeCrud::form( $paymentType );
}

public function getOrderProductsRefunded( Request $request, Order $order )
{
return $this->ordersService->getOrderRefundedProducts( $order );
}

public function getOrderRefunds( Request $request, Order $order )
{
return $this->ordersService->getOrderRefunds( $order );
}
}

9 changes: 4 additions & 5 deletions app/Http/Controllers/Dashboard/ProductsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -519,13 +519,12 @@ public function createAdjustment( Request $request )
public function searchUsingArgument( $reference )
{
$procurementProduct = ProcurementProduct::barcode( $reference )->first();
$productUnitQuantity = ProductUnitQuantity::barcode( $reference )->first();
$productUnitQuantity = ProductUnitQuantity::barcode( $reference )->with( 'unit' )->first();
$product = Product::barcode( $reference )
->searchable()
->first();

if ( $procurementProduct instanceof ProcurementProduct ) {

$product = $procurementProduct->product;

/**
Expand All @@ -547,20 +546,20 @@ public function searchUsingArgument( $reference )
$product->procurement_product_id = $procurementProduct->id;

} else if ( $productUnitQuantity instanceof ProductUnitQuantity ) {

/**
* if a product unit quantity is loaded. Then we make sure to return the parent
* product with the selected unit quantity.
*/
$productUnitQuantity->load( 'unit' );

$product = Product::find( $productUnitQuantity->product_id );
$product->load( 'unit_quantities' );
$product->load( 'unit_quantities.unit' );
$product->selectedUnitQuantity = $productUnitQuantity;

} else if ( $product instanceof Product ) {

$product->load( 'unit_quantities' );
$product->load( 'unit_quantities.unit' );

if ( $product->accurate_tracking ) {
throw new NotAllowedException( __( 'Unable to add a product that has accurate tracking enabled, using an ordinary barcode.' ) );
Expand Down
16 changes: 16 additions & 0 deletions app/Models/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,32 @@ public function products()
);
}

public function refundedProducts()
{
return $this->hasMany(
OrderProductRefund::class,
'order_id'
);
}

public function user()
{
return $this->hasOne( User::class, 'id', 'author' );
}

/**
* @deprecated
*/
public function refund()
{
return $this->hasMany( OrderRefund::class, 'order_id', 'id' );
}

public function refunds()
{
return $this->hasMany( OrderRefund::class, 'order_id', 'id' );
}

public function payments()
{
return $this->hasMany( OrderPayment::class, 'order_id' );
Expand Down
7 changes: 6 additions & 1 deletion app/Models/OrderRefund.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@ class OrderRefund extends NsModel

public function refunded_products()
{
return $this->hasMany( OrderProductRefund::class, 'refund_order_id', 'id' );
return $this->hasMany( OrderProductRefund::class, 'order_refund_id', 'id' );
}

public function order()
{
return $this->belongsTo( Order::class, 'order_id', 'id' );
}

public function author()
{
return $this->belongsTo( User::class, 'author', 'id' );
}
}
2 changes: 1 addition & 1 deletion app/Models/Role.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ private static function __createRelation( $role, $permission, $silent = true )
public function removePermissions( $permissionNamespace )
{
if ( $permissionNamespace instanceof Collection ) {
$permissionNamespace->each( fn( $permission ) => $this->removePermissions( $permission->namespace ) );
$permissionNamespace->each( fn( $permission ) => $this->removePermissions( $permission instanceof Permission ? $permission->namespace : $permission ) );
} else {
$permission = Permission::where([ 'namespace' => $permissionNamespace ])
->first();
Expand Down
36 changes: 33 additions & 3 deletions app/Services/OrdersService.php
Original file line number Diff line number Diff line change
Expand Up @@ -1465,7 +1465,7 @@ public function refundOrder( Order $order, $fields )
$results = [];

foreach( $fields[ 'products' ] as $product ) {
$results[] = $this->refundSingleProduct( $order, OrderProduct::find( $product[ 'id' ] ), $product );
$results[] = $this->refundSingleProduct( $order, $orderRefund, OrderProduct::find( $product[ 'id' ] ), $product );
}

/**
Expand Down Expand Up @@ -1504,7 +1504,7 @@ public function refundOrder( Order $order, $fields )
* @param int product id
* @param string status : sold, returned, defective
*/
public function refundSingleProduct( Order $order, OrderProduct $orderProduct, $details )
public function refundSingleProduct( Order $order, OrderRefund $orderRefund, OrderProduct $orderProduct, $details )
{
if ( ! in_array( $details[ 'condition' ], [
OrderProductRefund::CONDITION_DAMAGED,
Expand Down Expand Up @@ -1534,17 +1534,24 @@ public function refundSingleProduct( Order $order, OrderProduct $orderProduct, $
$this->computeOrderProduct( $orderProduct );
$orderProduct->save();

/**
* Let's store a reference of
* the refunded product
*/
$productRefund = new OrderProductRefund;
$productRefund->condition = $details[ 'condition' ];
$productRefund->description = $details[ 'description' ];
$productRefund->unit_price = $details[ 'unit_price' ];
$productRefund->unit_id = $orderProduct->unit_id;
$productRefund->total_price = $this->currencyService->getRaw( $productRefund->unit_price * floatval( $details[ 'quantity' ] ) );
$productRefund->total_price = $this->currencyService
->getRaw( $productRefund->unit_price * floatval( $details[ 'quantity' ] ) );
$productRefund->quantity = $details[ 'quantity' ];
$productRefund->author = Auth::id();
$productRefund->order_id = $order->id;
$productRefund->order_refund_id = $orderRefund->id;
$productRefund->order_product_id = $orderProduct->id;
$productRefund->product_id = $orderProduct->product_id;
$productRefund->save();

event( new OrderAfterProductRefundedEvent( $order, $orderProduct ) );

Expand Down Expand Up @@ -2457,4 +2464,27 @@ public function getPaymentTypesReport( $startRange, $endRange )
'entries' => $payments
];
}

/**
* Will return the product that
* that has been refunded
* @param Order $order
* @return array
*/
public function getOrderRefundedProducts( Order $order )
{
return $order->refundedProducts;
}

/**
* Will return the order refund along
* with the product refunded
* @param Order $order
* @return OrderRefund
*/
public function getOrderRefunds( Order $order )
{
$order->load( 'refunds.refunded_products.product', 'refunds.refunded_products.unit', 'refunds.author' );
return $order;
}
}
15 changes: 13 additions & 2 deletions resources/ts/pages/dashboard/orders/ns-order-details.vue
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,23 @@
<div class="mb-2">
<h3 class="font-semibold text-gray-800 pb-2 border-b border-blue-400">{{ __( 'Products' ) }}</h3>
</div>
<div :key="product.id" v-for="product of order.products" class="p-2 flex justify-between items-start bg-gray-200">
<div :key="product.id" v-for="product of order.products" class="p-2 flex justify-between items-start bg-gray-200 mb-2">
<div>
<h4 class="text-semibold text-gray-700">{{ product.name }} (x{{ product.quantity }})</h4>
<p class="text-gray-600 text-sm">{{ product.unit.name || 'N/A' }}</p>
</div>
<div class="font-semibold text-gray-800">{{ product.unit_price | currency }}</div>
<div class="font-semibold text-gray-800">{{ product.total_price | currency }}</div>
</div>

<div class="mb-2">
<h3 class="font-semibold text-gray-800 pb-2 border-b border-blue-400">{{ __( 'Refunded Products' ) }}</h3>
</div>
<div :key="product.id" v-for="product of order.refunded_products" class="p-2 flex justify-between items-start bg-gray-200 mb-2">
<div>
<h4 class="text-semibold text-gray-700">{{ product.product.name }} (x{{ product.quantity }})</h4>
<p class="text-gray-600 text-sm">{{ product.unit.name || 'N/A' }} | <span class="rounded-full px-2" :class="product.condition === 'damaged' ? 'bg-red-400 text-white' : 'bg-blue-400 text-white'">{{ product.condition }}</span></p>
</div>
<div class="font-semibold text-gray-800">{{ product.total_price | currency }}</div>
</div>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions resources/ts/pages/dashboard/orders/ns-order-refund.vue
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ export default {
nsHttpClient.post( `/api/nexopos/v4/orders/${this.order.id}/refund`, data )
.subscribe( result => {
this.isSubmitting = false;
this.$emit( 'updated', true );
this.$emit( 'changed', true );
nsSnackBar.success( result.message ).subscribe();
}, error => {
this.isSubmitting = false;
Expand Down Expand Up @@ -335,7 +335,7 @@ export default {
nsHttpClient.get( '/api/nexopos/v4/orders/payments' )
.subscribe( paymentField => {
this.paymentField = paymentField;
})
});
}
}
</script>
2 changes: 2 additions & 0 deletions resources/ts/popups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { default as nsConfirmPopup } from '@/popups/ns-pos-confirm-popup.vue';
import { default as nsPromptPopup } from '@/popups/ns-prompt-popup.vue';
import { default as nsMediaPopup } from '@/pages/dashboard/ns-media.vue';
import { default as nsProcurementQuantity } from '@/popups/ns-procurement-quantity.vue';
import { default as nsOrdersRefund } from '@/popups/ns-orders-refund-popup.vue';

const popups = {
nsOrderPreview,
Expand All @@ -14,6 +15,7 @@ const popups = {
nsPromptPopup,
nsMediaPopup,
nsProcurementQuantity,
nsOrdersRefund,
};

for( let index in popups ) {
Expand Down
10 changes: 5 additions & 5 deletions resources/ts/popups/ns-orders-preview-popup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ const nsOrderPreviewPopup = {
nsHttpClient.get( `/api/nexopos/v4/orders/${orderId}/payments` ),
])
.subscribe( result => {
this.order = result[0];
this.products = result[1];
this.payments = result[2];
this.order = result[0];
this.products = result[1];
this.payments = result[2];
});
},
deleteOrder() {
Expand Down Expand Up @@ -200,10 +200,10 @@ export default nsOrderPreviewPopup;
</ns-button>
</div>
<div>
<ns-button @click="printOrder()" type="info">
<!-- <ns-button @click="printOrder()" type="info">
<i class="las la-print"></i>
{{ __( 'Print' ) }}
</ns-button>
</ns-button> -->
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit 1fb6719

Please sign in to comment.