diff --git a/app/Http/Controllers/ServiceController.php b/app/Http/Controllers/ServiceController.php index 80c7691..f73cca5 100644 --- a/app/Http/Controllers/ServiceController.php +++ b/app/Http/Controllers/ServiceController.php @@ -17,7 +17,7 @@ use Illuminate\Validation\ValidationException; use Illuminate\View\View; use Symfony\Component\HttpKernel\Exception\HttpException; -use App\Http\Requests\ServiceChangeRequest; +use App\Http\Requests\{ServiceCancel,ServiceChangeRequest}; use App\Mail\{CancelRequest,ChangeRequest}; use App\Models\{Charge,Invoice,Product,Service}; @@ -124,34 +124,29 @@ class ServiceController extends Controller /** * Process a request to cancel a service * - * @param Request $request + * @param ServiceCancel $request * @param Service $o * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|RedirectResponse|\Illuminate\Routing\Redirector */ - public function cancel_request(Request $request,Service $o) + public function cancel_request(ServiceCancel $request,Service $o) { - if ($request->post()) { - $request->validate([ - 'stop_at'=>'required|date', - ]); + if (! $o->order_info) + $o->order_info = collect(); - if (! $o->order_info) - $o->order_info = collect(); + $o->stop_at = $request->stop_at; + $o->order_info->put('cancel_note',$request->validated('notes')); - $o->stop_at = $request->stop_at; - $o->order_info->put('cancel_note',$request->notes); - $o->order_status = 'CANCEL-REQUEST'; - $o->save(); + if ($request->validated('extra_charges')) + $o->order_info->put('cancel_extra_charges_accepted',$request->extra_charges_amount); - //@todo Get email from DB. - Mail::to('help@graytech.net.au') - ->queue((new CancelRequest($o,$request->notes))->onQueue('email')); + $o->order_status = 'CANCEL-REQUEST'; + $o->save(); - return redirect('u/service/'.$o->id)->with('success','Cancellation lodged'); - } + Mail::to(config('osb.ticket_admin')) + ->queue((new CancelRequest($o,$request->notes))->onQueue('email')); - return view('theme.backend.adminlte.service.cancel_request') - ->with('o',$o); + return redirect('u/service/'.$o->id) + ->with('success','Cancellation lodged'); } /** diff --git a/app/Http/Requests/ServiceCancel.php b/app/Http/Requests/ServiceCancel.php new file mode 100644 index 0000000..027e1ee --- /dev/null +++ b/app/Http/Requests/ServiceCancel.php @@ -0,0 +1,54 @@ +route('o')); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + //dd(request()->post()); + return [ + 'stop_at'=> [ + 'required', + 'date', + 'after:today', + 'exclude_unless:extra_charges,null', + function($attribute,$value,$fail) { + if ($this->route('o')->cancel_date->greaterThan($value)) + $fail(sprintf('Service cannot be cancelled before: %s',$this->route('o')->cancel_date->format('Y-m-d'))); + } + ], + 'extra_charges_amount' => [ + 'nullable', + 'exclude_unless:extra_charges,null', + function($attribute,$value,$fail) { + if ($this->route('o')->cancel_date->greaterThan(request('stop_at')) && (request('extra_charges') !== 1)) + $fail('Extra charges must be accepted if cancelling before contract end'); + }, + ], + 'extra_charges' => 'sometimes|required|accepted', + 'notes' => 'nullable|min:5', + ]; + } +} \ No newline at end of file diff --git a/app/Models/Service.php b/app/Models/Service.php index e9b731e..0cff768 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -14,8 +14,9 @@ use Illuminate\Support\Facades\Log; use Symfony\Component\HttpKernel\Exception\HttpException; use Leenooks\Casts\LeenooksCarbon; -use App\Models\Product\Type; use App\Interfaces\IDs; +use App\Models\Product\Type; +use App\Models\Service\Broadband; use App\Traits\{ScopeAccountUserAuthorised,ScopeServiceActive,SiteID}; /** @@ -565,6 +566,26 @@ class Service extends Model implements IDs return Invoice::billing_name($this->getBillingIntervalAttribute()); } + /** + * Return the earliest date that the service can be cancelled + * + * @return Carbon + */ + public function getCancelDateAttribute(): Carbon + { + switch (get_class($this->type)) { + // Broadband needs 30 days notice + case Broadband::class: + $date = Carbon::now()->addMonth(); + break; + + default: + $date = Carbon::now()->addDay(); + } + + return $this->getContractEndAttribute()->lessThan($date) ? $date : $this->getContractEndAttribute(); + } + /** * The date the contract ends * @@ -582,7 +603,7 @@ class Service extends Model implements IDs if (! $this->start_at) return $this->type->expire_at; - $end = $this->start_at->addMonths($this->getContractTermAttribute()); + $end = $this->start_at->clone()->addMonths($this->getContractTermAttribute()); // If we dont have an expire date, use the start date + contract_term if (! $this->type->expire_at) @@ -892,6 +913,27 @@ class Service extends Model implements IDs : $this->price; } + /** + * Provide billing charge to a future date + * + * @param Carbon $date + * @return float + * @throws Exception + */ + public function billing_charge_to(Carbon $date): float + { + // if the date is less than the paid to, but less than the cancel date to, return cancel-paid to charge + // If the date is greater than the paid to, and less than the cancel date to, return cancel-paid to charge + if ($this->getPaidToAttribute()->lessThan($this->getCancelDateAttribute())) { + $max = max($date,$this->getPaidToAttribute())->clone(); + $d = $max->diffInDays($this->getCancelDateAttribute()); + + return $this->account->taxed($d/30*$this->getBillingChargeNormalisedAttribute()); + } + + return 0; + } + /** * Get the stage parameters * diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 8b9e295..0d8005f 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -36,5 +36,6 @@ class AppServiceProvider extends ServiceProvider Route::model('co',\App\Models\Checkout::class); Route::model('po',\App\Models\Payment::class); Route::model('pdo',\App\Models\Product::class); + Route::model('so',\App\Models\Service::class); } } \ No newline at end of file diff --git a/config/osb.php b/config/osb.php index 288ee3e..d846b41 100644 --- a/config/osb.php +++ b/config/osb.php @@ -6,4 +6,5 @@ return [ 'invoice_days' => 30, // Days in Advance to invoice 'invoice_review' => 3, // Days to review an invoice before it is emailed 'admin' => env('APP_ADMIN'), + 'ticket_admin' => env('APP_TICKET_ADMIN',env('APP_ADMIN')), ]; \ No newline at end of file diff --git a/resources/views/mail/admin/service/cancel.blade.php b/resources/views/mail/admin/service/cancel.blade.php index 3694085..a18d6e9 100644 --- a/resources/views/mail/admin/service/cancel.blade.php +++ b/resources/views/mail/admin/service/cancel.blade.php @@ -7,6 +7,7 @@ Please cancel the following... | Logged User | {{ Auth::user()->id ?? 'System' }} | | Account | {{ $service->account->name }} | | Service ID | {{ $service->sid }} | +| Cancel Date | {{ $service->stop_at->format('Y-m-d') }} | | Product | {{ $service->product->name }} | @switch($service->product->category) @case('broadband') diff --git a/resources/views/theme/backend/adminlte/service/cancel_request.blade.php b/resources/views/theme/backend/adminlte/service/cancel_request.blade.php index 9237d82..7cb3007 100644 --- a/resources/views/theme/backend/adminlte/service/cancel_request.blade.php +++ b/resources/views/theme/backend/adminlte/service/cancel_request.blade.php @@ -1,17 +1,19 @@ +@use(Carbon\Carbon) + @extends('adminlte::layouts.app') @section('htmlheader_title') - {{ $o->sid }} + {{ $so->sid }} @endsection @section('page_title') - {{ $o->sid }} + {{ $so->sid }} @endsection @section('contentheader_title') - Service: {{ $o->sid }} {{ $o->product->name }} + Service: {{ $so->sid }} {{ $so->product->name }} @endsection @section('contentheader_description') - {{ $o->name }} + {{ $so->name }} @endsection @section('main-content') @@ -27,14 +29,27 @@
-
- +
+ +
+
+
+ @if(old('stop_at') && Carbon::now()->lessThan(old('stop_at'))) +
+
+ +
+
+ +
+
+ @endif
- +
diff --git a/resources/views/theme/backend/adminlte/service/home.blade.php b/resources/views/theme/backend/adminlte/service/home.blade.php index 58240ac..8c6a2e6 100644 --- a/resources/views/theme/backend/adminlte/service/home.blade.php +++ b/resources/views/theme/backend/adminlte/service/home.blade.php @@ -64,7 +64,7 @@
- @if($x=! ($o->suspend_billing || $o->external_billing) && $o->next_invoice) + @if(($x=! ($o->suspend_billing || $o->external_billing)) && $o->invoice_next)
! (session()->has('service_update') || session()->has('charge_add'))]) id="pending_items"> @include('theme.backend.adminlte.service.widget.invoice')
diff --git a/routes/web.php b/routes/web.php index aa3de39..b0de248 100644 --- a/routes/web.php +++ b/routes/web.php @@ -193,7 +193,9 @@ Route::group(['middleware'=>['auth'],'prefix'=>'u'],function() { Route::get('service/{o}',[ServiceController::class,'home']) ->middleware('can:view,o') ->where('o','[0-9]+'); - Route::match(['get','post'],'service/{o}/cancel-request',[ServiceController::class,'cancel_request']) + Route::view('service/{so}/cancel-request','theme.backend.adminlte.service.cancel_request') + ->where('so','[0-9]+'); + Route::post('service/{o}/cancel-request',[ServiceController::class,'cancel_request']) ->middleware('can:progress,o,"cancel-request"') ->where('o','[0-9]+'); Route::match(['get','post'],'service/{o}/change-request',[ServiceController::class,'change_request'])