diff --git a/app/Http/Controllers/ServiceController.php b/app/Http/Controllers/ServiceController.php index 4a6a87f..b607fcc 100644 --- a/app/Http/Controllers/ServiceController.php +++ b/app/Http/Controllers/ServiceController.php @@ -19,6 +19,26 @@ class ServiceController extends Controller public function update(Request $request,Service $o) { switch ($o->order_status) { + case 'CANCEL-REQUEST': + if ($request->post()) { + if (! $request->post('date_end')) + return redirect()->back()->withErrors('Cancellation Date not provided'); + + $o->date_end = $request->post('date_end'); + + foreach (['cancel_notes'] as $key) { + if ($request->post($key)) + $o->setOrderInfo($key,$request->post($key)); + } + + $o->order_status='CANCEL-PENDING'; + $o->save(); + + return redirect()->to(url('u/service',$o->id))->with('updated','Service cancellation submitted.'); + } + + return $this->update_request_cancel($o); + case 'ORDER-SENT': if ($request->post()) { foreach (['reference','notes'] as $key) { @@ -43,6 +63,11 @@ class ServiceController extends Controller } } + private function update_request_cancel(Service $o) + { + return View('u.service.order.cancel',['o'=>$o]); + } + private function update_order_status(Service $o) { return View('r.service.order.sent',['o'=>$o]); diff --git a/app/Models/Service.php b/app/Models/Service.php index 14cfacc..a6dd968 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -165,6 +165,34 @@ class Service extends Model ], // Order Confirmed by Supplier 'ORDERED' => ['update_reference'=>'ORDER-SENT'], + 'ACTIVE' => [ + 'fail'=>FALSE, + 'next'=>[ + 'UPGRADE-REQUEST'=>['customer'], + 'CANCEL-REQUEST'=>['customer'], + ], + 'system'=>FALSE, + 'method'=>'action_active', + 'title'=>'Service Active', + ], + 'UPGRADE-REQUEST' => [ + 'fail'=>FALSE, + 'next'=>[ + 'UPGRADE-PENDING'=>[], + ], + 'system'=>FALSE, + 'method'=>FALSE, + 'title'=>'Upgrade Service', + ], + 'CANCEL-REQUEST' => [ + 'fail'=>FALSE, + 'next'=>[ + 'CANCEL-PENDING'=>[], + ], + 'system'=>FALSE, + 'method'=>'action_cancel_request', + 'title'=>'Cancel Service', + ], ]; /** @@ -467,6 +495,10 @@ class Service extends Model default: throw new Exception('Unknown recur_schedule'); } + // If the invoice has an end date, our invoice period shouldnt be greater than that. + if ($this->date_end AND $date > $this->date_end) + $date = $this->date_end; + return $date; } @@ -789,6 +821,28 @@ class Service extends Model // The action methods will return: NULL for no progress|FALSE for a failed status|next stage name. + /** + * Action required before order can leave the ACTIVE status. + * + * @return bool + */ + private function action_active(): ?bool + { + // N/A + return TRUE; + } + + /** + * Request cancellation for an order when status ACTIVE stage. + * This method should have the client confirm/accept the cancellation, if it was placed by a reseller/wholesaler. + * + * @return bool + */ + private function action_cancel_request(): ?bool + { + throw new HttpException(301,url('u/service/cancel',$this->id)); + } + /** * Process for an order when status ORDER-ACCEPT stage. * This method should have the client confirm/accept the order, if it was placed by a reseller/wholesaler. @@ -962,7 +1016,7 @@ class Service extends Model } else { // Cant do anything, dont have a method to check if we can leave $stage = NULL; - abort(500,'NO Method Cannot Proceed to leave this stage: '.$next['method']); + abort(500,'NO Method Cannot Proceed to leave this stage: '.$current['method']); } // If valid, call the method to start the next stage @@ -1092,9 +1146,13 @@ class Service extends Model // If the service is active, there will be service charges if ((! $this->invoice_items->filter(function($item) { return $item->item_type==0 AND ! $item->exists; })->count()) AND ($this->active OR $this->isPending()) - AND ($future == TRUE OR ($future == FALSE AND ($this->invoice_to < Carbon::now()->addDays(30))))) + AND ( + ($future == TRUE AND $this->invoice_next < $this->invoice_next_end) OR + ($future == FALSE AND ($this->invoice_to < ($this->date_end ?: Carbon::now()->addDays(30)))) + )) { do { + dump(['next'=>$this->invoice_next,'stop'=>$this->invoice_next_end]); $o = new InvoiceItem; $o->active = TRUE; $o->service_id = $this->id; @@ -1111,7 +1169,7 @@ class Service extends Model $o->addTaxes($this->account->country->taxes); $this->invoice_items->push($o); - } while ($future == FALSE AND ($this->invoice_to < Carbon::now()->addDays(30))); + } while ($future == FALSE AND ($this->invoice_to < ($this->date_end ?: Carbon::now()->addDays(30)))); } // Add additional charges diff --git a/resources/views/theme/backend/adminlte/common/service/widget/error.blade.php b/resources/views/theme/backend/adminlte/common/service/widget/error.blade.php new file mode 100644 index 0000000..ce3990d --- /dev/null +++ b/resources/views/theme/backend/adminlte/common/service/widget/error.blade.php @@ -0,0 +1,12 @@ + +
+
+ +
Whoops!
+ +
+
\ No newline at end of file diff --git a/resources/views/theme/backend/adminlte/u/service/order/cancel.blade.php b/resources/views/theme/backend/adminlte/u/service/order/cancel.blade.php new file mode 100644 index 0000000..fddfdd8 --- /dev/null +++ b/resources/views/theme/backend/adminlte/u/service/order/cancel.blade.php @@ -0,0 +1,100 @@ +@extends('adminlte::layouts.app') + +@section('htmlheader_title') + {{ $o->sid }} +@endsection +@section('page_title') + {{ $o->sid }} +@endsection + +@section('contentheader_title') + Service: {{ $o->sid }} {{ $o->product->name }} +@endsection +@section('contentheader_description') + {{ $o->sname }}: {{ $o->sdesc }} +@endsection + +@section('main-content') +
+
+
+
+
Cancelling Service
+
+ + + @if ($errors->any()) + @include('common.service.widget.error') + @endif + +
+ {{ csrf_field() }} + +
+
+ +
+
+
+ +
+ +
+
+
+ + {{-- + @includeIf('u.service.widgets.'.$o->stype.'.order',['o'=>$o->type]) + --}} + +
+ +
+ +
+
+
+ + + +
+
+
+
+@endsection + +@section('page-scripts') + @css('//cdnjs.cloudflare.com/ajax/libs/summernote/0.8.12/summernote-bs4.css','summernote-css') + @js('//cdnjs.cloudflare.com/ajax/libs/summernote/0.8.12/summernote-bs4.js','summernote-js') + @js('//cdn.jsdelivr.net/momentjs/latest/moment.min.js','moment-js') + @js('//cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js','daterange-js') + @css('//cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css','daterange-css') + + +@append \ No newline at end of file diff --git a/resources/views/theme/backend/adminlte/u/service/widgets/information.blade.php b/resources/views/theme/backend/adminlte/u/service/widgets/information.blade.php index 5d0827f..21c5688 100644 --- a/resources/views/theme/backend/adminlte/u/service/widgets/information.blade.php +++ b/resources/views/theme/backend/adminlte/u/service/widgets/information.blade.php @@ -21,6 +21,12 @@ Status {!! $o->status_html !!} + @if ($o->date_end) + + Cancellation Date + {{ $o->date_end->format('Y-m-d') }} + + @endif @if (($o->active OR $o->isPending()) AND ! $o->external_billing) Billed diff --git a/routes/web.php b/routes/web.php index 2daa03e..93d04ba 100644 --- a/routes/web.php +++ b/routes/web.php @@ -66,6 +66,9 @@ Route::group(['middleware'=>['theme:adminlte-be','auth'],'prefix'=>'u'],function Route::get('service/{o}','UserHomeController@service') ->where('o','[0-9]+') ->middleware('can:view,o'); + Route::get('service/cancel/{o}','ServiceController@update') + ->where('o','[0-9]+') + ->middleware('can:update,o'); Route::get('service/progress/{o}/{status}','UserHomeController@service_progress') ->where('o','[0-9]+') ->middleware('can:progress,o,status');