Updates to service updating - broadband

This commit is contained in:
Deon George 2022-08-01 20:34:10 +10:00
parent de3f1a534b
commit 7feec266b8
11 changed files with 234 additions and 73 deletions

View File

@ -10,6 +10,7 @@ use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Validator;
use Illuminate\View\View; use Illuminate\View\View;
use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\HttpException;
@ -409,15 +410,28 @@ class ServiceController extends Controller
* @param Request $request * @param Request $request
* @param Service $o * @param Service $o
* @return RedirectResponse * @return RedirectResponse
* @todo This needs to be reworked, to take into account our different service types
* @todo Add Validation
*/ */
public function update(Request $request,Service $o) public function update(Request $request,Service $o)
{ {
if ($request->post($o->product->category)) { if ($o->type->validation()) {
$o->type->forceFill($request->post($o->product->category))->save(); $validator = Validator::make($x=$request->post($o->category),$o->type->validation());
if ($validator->fails()) {
return redirect()
->back()
->withErrors($validator)
->withInput();
}
$o->type->forceFill(Arr::except($x,['start_at']));
} elseif ($request->post($o->product->category)) {
$o->type->forceFill($request->post($o->product->category));
} }
$o->type->save();
// Also update our service start_at date.
if ($request->post('start_at')) if ($request->post('start_at'))
$o->start_at = $request->start_at; $o->start_at = $request->start_at;

View File

@ -10,6 +10,7 @@ use App\Interfaces\ServiceUsage;
use App\Models\Supplier\Broadband as SupplierBroadband; use App\Models\Supplier\Broadband as SupplierBroadband;
use App\Models\Supplier\Type as SupplierType; use App\Models\Supplier\Type as SupplierType;
use App\Models\Usage\Broadband as UsageBroadband; use App\Models\Usage\Broadband as UsageBroadband;
use App\Rules\IPv6_CIDR;
/** /**
* Class Broadband (Service) * Class Broadband (Service)
@ -81,6 +82,27 @@ class Broadband extends Type implements ServiceUsage
return $value ?: $this->supplied()->technology; return $value ?: $this->supplied()->technology;
} }
/* OVERRIDES */
/**
* Service update validation
*
* @return array
*/
public function validation(): array
{
return [
'service_number' => 'nullable|string|min:10|max:10',
'service_username' => 'nullable|string',
'service_password' => 'nullable|string',
'connect_at' => 'nullable|date',
'start_at' => 'nullable|date',
'expire_at' => 'nullable|date|after:start_at',
'ipaddress' => 'nullable|ipv4',
'ip6address' => ['nullable',new IPv6_CIDR],
];
}
/* METHODS */ /* METHODS */
/** /**

View File

@ -69,13 +69,23 @@ abstract class Type extends Model implements ServiceItem
* @param $value * @param $value
* @return LeenooksCarbon * @return LeenooksCarbon
*/ */
public function getExpireAtAttribute($value): LeenooksCarbon public function getExpireAtAttribute($value): ?LeenooksCarbon
{ {
return LeenooksCarbon::create($value); return $value ? LeenooksCarbon::create($value) : NULL;
} }
/* METHODS */ /* METHODS */
/**
* Validation used to accept form input
*
* @return mixed
*/
public function validation(): array
{
return [];
}
/** /**
* The supplier's service that we provide * The supplier's service that we provide
* *

43
app/Rules/IPv4_CIDR.php Normal file
View File

@ -0,0 +1,43 @@
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class IPv4_CIDR implements Rule
{
private const MAX=32;
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
if (str_contains($value,'/')) {
list($value,$mask) = explode('/',$value);
$m = filter_var($mask,\FILTER_VALIDATE_INT,[
'options' => [
'min_range' => 0,
"max_range" => self::MAX,
]]
);
return $m && filter_var($value,\FILTER_VALIDATE_IP,\FILTER_FLAG_IPV4);
}
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'The :attribute must be a valid IPv4 CIDR range.';
}
}

43
app/Rules/IPv6_CIDR.php Normal file
View File

@ -0,0 +1,43 @@
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class IPv6_CIDR implements Rule
{
private const MAX=128;
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
if (str_contains($value,':') && str_contains($value,'/')) {
list($value,$mask) = explode('/',$value);
$m = filter_var($mask,\FILTER_VALIDATE_INT,[
'options' => [
'min_range' => 0,
"max_range" => self::MAX,
]
]);
return $m && filter_var($value,\FILTER_VALIDATE_IP,\FILTER_FLAG_IPV6);
}
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'The :attribute must be a valid IPv6 CIDR range.';
}
}

View File

@ -20,7 +20,7 @@
"laravel/passport": "^10.1", "laravel/passport": "^10.1",
"laravel/socialite": "^5.2", "laravel/socialite": "^5.2",
"laravel/ui": "^3.2", "laravel/ui": "^3.2",
"leenooks/laravel": "^9.2.0", "leenooks/laravel": "^9.2.2",
"leenooks/laravel-theme": "^v2.0.18", "leenooks/laravel-theme": "^v2.0.18",
"nunomaduro/laravel-console-summary": "^1.8", "nunomaduro/laravel-console-summary": "^1.8",
"paypal/paypal-checkout-sdk": "^1.0", "paypal/paypal-checkout-sdk": "^1.0",

8
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "c41aad3374358724adae9239e88f7a4f", "content-hash": "3306c0a2c799a142669bda57f369316a",
"packages": [ "packages": [
{ {
"name": "asm89/stack-cors", "name": "asm89/stack-cors",
@ -3295,11 +3295,11 @@
}, },
{ {
"name": "leenooks/laravel", "name": "leenooks/laravel",
"version": "9.2.1", "version": "9.2.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://dev.leenooks.net/leenooks/laravel", "url": "https://dev.leenooks.net/leenooks/laravel",
"reference": "9ef7e8e626a9c84bc385350b7261368abcabe16b" "reference": "2e512cc3edc913e59726a93c248e76705ff44daa"
}, },
"require": { "require": {
"creativeorange/gravatar": "^1.0", "creativeorange/gravatar": "^1.0",
@ -3338,7 +3338,7 @@
"laravel", "laravel",
"leenooks" "leenooks"
], ],
"time": "2022-08-01T03:59:01+00:00" "time": "2022-08-01T10:29:57+00:00"
}, },
{ {
"name": "leenooks/laravel-theme", "name": "leenooks/laravel-theme",

View File

@ -16,14 +16,13 @@
@section('main-content') @section('main-content')
<div class="row"> <div class="row">
<!-- Service Details --> <!-- Service Details -->
<div class="col-5"> <div class="col-12 col-md-5">
@includeIf('service.widget.'.$o->product->category.'.details',['o'=>$o->type]) @includeIf('service.widget.'.$o->product->category.'.details',['o'=>$o->type])
@include('service.widget.information') @include('service.widget.information')
</div> </div>
<div class="col-7"> <div class="col-12 col-md-7">
<div class="card"> <div class="card">
<div class="card-header bg-dark d-flex p-0"> <div class="card-header bg-dark d-flex p-0">
<ul class="nav nav-pills w-100 p-2"> <ul class="nav nav-pills w-100 p-2">

View File

@ -1,74 +1,102 @@
<div class="form-group row"> <!-- $o=Service\Broadband::class -->
<label for="reference" class="col-sm-3 col-form-label text-right">Service Number</label> <div class="row">
<div class="col-sm-6"> <div class="col-12 col-sm-9 col-md-6 col-xl-5">
<div class="input-group"> @include('adminlte::widget.form_text',[
<div class="input-group-prepend"> 'label'=>'Service Number',
<span class="input-group-text"><i class="fa fa-fw fa-phone"></i></span> 'icon'=>'fas fa-phone',
</div> 'id'=>'service_number',
<input type="text" class="form-control" name="broadband[service_number]" value="{{ $o->service_number ?? '' }}"> 'old'=>'broadband.service_number',
</div> 'name'=>'broadband[service_number]',
'value'=>$o->service_number ?? '',
])
</div> </div>
</div> </div>
<div class="form-group row"> <div class="row">
<label for="reference" class="col-sm-3 col-form-label text-right">Service Username</label> <div class="col-12 col-sm-9 col-md-12 col-xl-7">
<div class="col-sm-6"> @include('adminlte::widget.form_text',[
<div class="input-group"> 'label'=>'Service Username',
<div class="input-group-prepend"> 'icon'=>'fas fa-user',
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span> 'id'=>'service_username',
</div> 'old'=>'broadband.service_username',
<input type="text" class="form-control" name="broadband[service_username]" value="{{ $o->service_username ?? '' }}"> 'name'=>'broadband[service_username]',
</div> 'value'=>$o->service_username ?? '',
])
</div>
<div class="col-12 col-sm-9 col-md-5 col-xl-5">
@include('adminlte::widget.form_text',[
'label'=>'Service Password',
'icon'=>'fas fa-lock',
'id'=>'service_password',
'old'=>'broadband.service_password',
'name'=>'broadband[service_password]',
'value'=>$o->service_password ?? '',
])
</div> </div>
</div> </div>
<div class="form-group row"> <hr>
<label for="reference" class="col-sm-3 col-form-label text-right">Service Password</label> <p class="h6">Service Dates</p>
<div class="col-sm-6">
<div class="input-group"> <div class="row">
<div class="input-group-prepend"> <div class="col-12 col-sm-9 col-md-6 col-xl-5">
<span class="input-group-text"><i class="fa fa-fw fa-lock"></i></span> @include('adminlte::widget.form_date',[
</div> 'label'=>'Connect Date',
<input type="text" class="form-control" name="broadband[service_password]" value="{{ $o->service_password ?? '' }}"> 'id'=>'connect_at',
</div> 'old'=>'broadband.connect_at',
'name'=>'broadband[connect_at]',
'value'=>$o->connect_at ? $o->connect_at->format('Y-m-d') : '',
])
</div>
<div class="col-12 col-sm-9 col-md-6 col-xl-5">
@include('adminlte::widget.form_date',[
'label'=>'Billing Start Date',
'id'=>'start_at',
'old'=>'broadband.start_at',
'name'=>'broadband[start_at]',
'value'=>$o->start_at ? $o->start_at->format('Y-m-d') : ($o->connect_at ? $o->connect_at->format('Y-m-d') : ''),
])
</div> </div>
</div> </div>
<div class="form-group row"> <div class="row">
<label for="reference" class="col-sm-3 col-form-label text-right">Service Connect Date</label> <div class="col-12 col-sm-9 col-md-6 col-xl-5">
<div class="col-sm-6"> @include('adminlte::widget.form_date',[
<div class="input-group"> 'label'=>'Contract End',
<div class="input-group-prepend"> 'id'=>'expire_at',
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span> 'old'=>'broadband.expire_at',
</div> 'name'=>'broadband[expire_at]',
<input type="date" class="form-control" name="broadband[connect_at]" value="{{ $o->connect_at ? $o->connect_at->format('Y-m-d') : '' }}"> 'value'=>$o->expire_at ? $o->expire_at->format('Y-m-d') : ($o->connect_at ? $o->connect_at->addMonths($o->contract_term)->format('Y-m-d') : ''),
</div> ])
</div> </div>
</div> </div>
<div class="form-group row"> <hr>
<label for="reference" class="col-sm-3 col-form-label text-right">Service Contract Date</label> <p class="h6">IP Address</p>
<div class="col-sm-6"> <div class="row">
<div class="input-group"> <div class="col-12 col-lg-5">
<div class="input-group-prepend"> @include('adminlte::widget.form_text',[
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span> 'label'=>'IPv4 Address',
</div> 'icon'=>'fas fa-map-marker',
<!-- @todo We changed contract_date in the DB, what happened to it and how do we work it out now --> 'id'=>'ipaddress',
<!-- 'old'=>'broadband.ipaddress',
<input type="date" class="form-control" name="broadband[service_contract_date]" value="{{ $o->service_contract_date ? $o->service_contract_date->format('Y-m-d') : '' }}"> 'name'=>'broadband[ipaddress]',
--> 'value'=>$o->ipaddress ?? '',
</div> ])
</div> </div>
</div>
<div class="form-group row"> <div class="col-12 col-lg-7">
<label for="reference" class="col-sm-3 col-form-label text-right">Service Billing Start Date</label> <div class="form-group">
<div class="col-sm-6"> @include('adminlte::widget.form_text',[
<div class="input-group"> 'label'=>'IPv6 Address',
<div class="input-group-prepend"> 'icon'=>'fas fa-map-marker-alt',
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span> 'id'=>'ip6address',
</div> 'old'=>'broadband.ip6address',
<input type="date" class="form-control" name="start_at" value="{{ $o->service->start_at ? $o->service->start_at->format('Y-m-d') : '' }}"> 'name'=>'broadband[ip6address]',
'value'=>$o->ip6address ?? '',
])
</div> </div>
</div> </div>
</div> </div>

View File

@ -2,7 +2,9 @@
<div class="col-12"> <div class="col-12">
<h4>Update Service details</h4> <h4>Update Service details</h4>
<form class="g-0 needs-validation" method="POST" action="{{ url('a/service/edit',[$o->id]) }}"> <form class="g-0 needs-validation" method="POST" action="{{ url('a/service/update',[$o->id]) }}">
@include('adminlte::widget.success')
@csrf @csrf
@includeIf('service.widget.'.$o->product->category.'.update',['o'=>$o->type]) @includeIf('service.widget.'.$o->product->category.'.update',['o'=>$o->type])

View File

@ -105,7 +105,7 @@ Route::group(['middleware'=>['theme:adminlte-be','auth','role:wholesaler'],'pref
// Services // Services
// @todo This should probably go to resellers - implement a change audit log first // @todo This should probably go to resellers - implement a change audit log first
Route::post('service/edit/{o}',[ServiceController::class,'update']) Route::post('service/update/{o}',[ServiceController::class,'update'])
->where('o','[0-9]+'); ->where('o','[0-9]+');
//@deprecated //@deprecated