Fix broadband plan change update

This commit is contained in:
Deon George 2023-05-03 18:09:29 +10:00
parent fd110f5c6f
commit 4f19da5987
7 changed files with 67 additions and 26 deletions

View File

@ -96,6 +96,7 @@ class ServiceController extends Controller
$co->save(); $co->save();
$o->product_id = Arr::get($request->broadband,'product_id'); $o->product_id = Arr::get($request->broadband,'product_id');
$o->price = Arr::get($request->broadband,'price');
$o->order_status = 'ACTIVE'; $o->order_status = 'ACTIVE';
$o->save(); $o->save();
@ -345,7 +346,7 @@ class ServiceController extends Controller
$co->type = $iio->item_type; $co->type = $iio->item_type;
$co->start_at = $start_at; $co->start_at = $start_at;
$co->stop_at = $iio->stop_at; $co->stop_at = $iio->stop_at;
$co->amount = $po->base_charge; $co->amount = Arr::get($request->broadband,'price') ?: $po->base_charge;
$co->taxable = TRUE; // @todo this should be determined $co->taxable = TRUE; // @todo this should be determined
$co->quantity = $start_at->diff($iio->stop_at)->days/$iio->start_at->diff($iio->stop_at)->days; $co->quantity = $start_at->diff($iio->stop_at)->days/$iio->start_at->diff($iio->stop_at)->days;
$charges->push($co); $charges->push($co);

View File

@ -32,6 +32,7 @@ class ServiceChangeRequest extends FormRequest
return [ return [
'broadband.product_id' => 'required|exists:products,id', 'broadband.product_id' => 'required|exists:products,id',
'broadband.change_fee' => 'nullable|numeric', 'broadband.change_fee' => 'nullable|numeric',
'broadband.price' => 'nullable|numeric',
'broadband.start_at' => 'required|date', // @todo Check that it is not more than 1 billing cycle ago, and not future. 'broadband.start_at' => 'required|date', // @todo Check that it is not more than 1 billing cycle ago, and not future.
]; ];
} }

View File

@ -184,11 +184,11 @@ class Product extends Model implements IDs
/** /**
* Return the type of service is provided. eg: Broadband, Phone. * Return the type of service is provided. eg: Broadband, Phone.
* *
* @return string * @return string|null
*/ */
public function getCategoryAttribute(): string public function getCategoryAttribute(): ?string
{ {
return $this->supplied->getCategoryAttribute(); return $this->supplied ? $this->supplied->getCategoryAttribute() : NULL;
} }
/** /**

View File

@ -35,6 +35,7 @@ use App\Traits\SiteID;
* + billed_to : When this service has been billed to // @todo rename all references to invoice_to * + billed_to : When this service has been billed to // @todo rename all references to invoice_to
* + category : The type of service this is, eg: broadband, phone * + category : The type of service this is, eg: broadband, phone
* + category_name : The type of service this is, eg: Broadband, Telephone (in human friendly) * + category_name : The type of service this is, eg: Broadband, Telephone (in human friendly)
* + isChargedOverride : Has the price been overridden?
* + contract_term : The term that this service must be active * + contract_term : The term that this service must be active
* + contract_end : The date that the contract ends for this service * + contract_end : The date that the contract ends for this service
* + name : Service short name with service address * + name : Service short name with service address
@ -1216,6 +1217,11 @@ class Service extends Model implements IDs
AND ! in_array($this->order_status,array_merge(self::INACTIVE_STATUS,['INACTIVE'])); AND ! in_array($this->order_status,array_merge(self::INACTIVE_STATUS,['INACTIVE']));
} }
public function isChargeOverriden(): bool
{
return (! is_null($this->price)) || (! is_null($this->price_override));
}
/** /**
* Generate a collection of invoice_item objects that will be billed for the next invoice * Generate a collection of invoice_item objects that will be billed for the next invoice
* *

View File

@ -17,7 +17,7 @@
<!-- $o = App\Models\Service::class --> <!-- $o = App\Models\Service::class -->
@section('main-content') @section('main-content')
<div class="row"> <div class="row">
<div class="col-8"> <div class="col-4">
<form role="form" method="POST" enctype="multipart/form-data"> <form role="form" method="POST" enctype="multipart/form-data">
<div class="card card-dark"> <div class="card card-dark">
{{ csrf_field() }} {{ csrf_field() }}
@ -55,8 +55,8 @@
<select class="form-control @error('broadband.product_id') is-invalid @enderror" id="product_id" name="broadband[product_id]" required> <select class="form-control @error('broadband.product_id') is-invalid @enderror" id="product_id" name="broadband[product_id]" required>
<!-- @todo TO DO LIMIT THIS TO OF THE SAME OFFERING TYPE AND SORT BY NAME --> <!-- @todo TO DO LIMIT THIS TO OF THE SAME OFFERING TYPE AND SORT BY NAME -->
@foreach (\App\Models\Product::get() as $po) @foreach (\App\Models\Product::get() as $po)
@if ($po->category !== $o->product->category) @continue @endif @if (! $po->category || ($po->category !== $o->product->category)) @continue @endif
<option value="{{ $po->id }}" {{ $po->id == old('broadband.product_id',$po->exists ? \Illuminate\Support\Arr::get($o->order_info,'change_product_id') : NULL) ? 'selected' : '' }}>{{ $po->name }}</option> <option value="{{ $po->id }}" {{ $po->id == old('broadband.product_id',$po->exists ? Arr::get($o->order_info,'change_product_id') : NULL) ? 'selected' : '' }}>{{ $po->name }}</option>
@endforeach @endforeach
</select> </select>
<span class="invalid-feedback" role="alert"> <span class="invalid-feedback" role="alert">
@ -112,6 +112,24 @@
</div> </div>
</div> </div>
</div> </div>
<div class="col-6">
<!-- NEW PRICE -->
<div class="form-group has-validation">
<label for="price" class="col-form-label text-right">New Price <small>(Override)</small></label>
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-fw fa-dollar-sign"></i></span>
</div>
<input type="text" class="form-control @error('broadband.price_override') is-invalid @enderror" id="price" name="broadband[price]" value="{{ $o->price }}">
<span class="invalid-feedback" role="alert">
@error('broadband.price')
{{ $message }}
@enderror
</span>
</div>
</div>
</div>
</div> </div>
<div class="row"> <div class="row">
@ -126,8 +144,31 @@
</div> </div>
</form> </form>
</div> </div>
<!-- Current Plan -->
<div class="col-4"> <div class="col-4">
@include('service.widget.internal') <div class="card card-dark">
<div class="card-body">
<div class="card-header">
<h3 class="card-title">Current Plan</h3>
</div>
@include('service.widget.internal',['o'=>$o,'p'=>$o->product])
</div>
</div>
</div>
<!-- Proposed Plan -->
<div class="col-4">
<div class="card card-dark">
<div class="card-body">
<div class="card-header">
<h3 class="card-title">Proposed Plan</h3>
</div>
@include('service.widget.internal',['o'=>$o,'p'=>\App\Models\Product::where('id',Arr::get($o->order_info,'change_product_id'))->singleOrFail()])
</div>
</div>
</div> </div>
</div> </div>
<div id="transactions"></div> <div id="transactions"></div>

View File

@ -89,7 +89,7 @@
</div> </div>
@can('wholesaler') @can('wholesaler')
<div class="tab-pane fade" id="internal" role="tabpanel"> <div class="tab-pane fade" id="internal" role="tabpanel">
@include('service.widget.internal') @include('service.widget.internal',['o'=>$o,'p'=>$o->product])
</div> </div>
<div class="tab-pane fade {{ session()->pull('service_update') ? 'active show' : '' }}" id="update" role="tabpanel"> <div class="tab-pane fade {{ session()->pull('service_update') ? 'active show' : '' }}" id="update" role="tabpanel">

View File

@ -1,4 +1,4 @@
<!-- $o = Service::class --> <!-- $o = Service::class, $p = Product::class -->
<table class="table table-sm"> <table class="table table-sm">
<thead> <thead>
<tr> <tr>
@ -19,16 +19,16 @@
@if ($s->exists) @if ($s->exists)
<td>#{{ $s->id }}: {{ $s->name }}</td> <td>#{{ $s->id }}: {{ $s->name }}</td>
@endif @endif
<td>#{{ $o->product->id }}: {{ $o->product->name }}</td> <td>#{{ $p->id }}: {{ $p->name }}</td>
@if ($s->exists) @if ($s->exists)
<td>{{ $o->product->category_name }}</td> <td>{{ $p->category_name }}</td>
@endif @endif
</tr> </tr>
<tr> <tr>
<th>Setup</th> <th>Setup</th>
@if ($s->exists) @if ($s->exists)
<td>${{ number_format($a=\App\Models\Tax::tax_calc($s->setup_cost,$o->account->taxes),2) }}</td> <td>${{ number_format($a=\App\Models\Tax::tax_calc($s->setup_cost,$o->account->taxes),2) }}</td>
<td>${{ number_format($b=\App\Models\Tax::tax_calc($o->product->setup_charge,$o->account->taxes),2) }}</td> <td>${{ number_format($b=\App\Models\Tax::tax_calc($p->setup_charge,$o->account->taxes),2) }}</td>
<td>{!! markup($a,$b) !!}</td> <td>{!! markup($a,$b) !!}</td>
@else @else
<td>-</td> <td>-</td>
@ -47,7 +47,7 @@
<tr> <tr>
<th>Billing Price</th> <th>Billing Price</th>
@if ($s->exists) @if ($s->exists)
<td>${{ number_format($a=\App\Models\Tax::tax_calc($s->base_cost*\App\Models\Invoice::billing_change($s->billing_interval,$o->product->billing_interval),$o->account->taxes),2) }}</td> <td>${{ number_format($a=\App\Models\Tax::tax_calc($s->base_cost*\App\Models\Invoice::billing_change($s->billing_interval,$p->billing_interval),$o->account->taxes),2) }}</td>
@endif @endif
<td>${{ number_format($b=$o->billing_charge,2) }}</td> <td>${{ number_format($b=$o->billing_charge,2) }}</td>
@if ($s->exists) @if ($s->exists)
@ -59,7 +59,7 @@
@if ($s->exists) @if ($s->exists)
<td>${{ number_format($a=\App\Models\Tax::tax_calc($s->base_cost*\App\Models\Invoice::billing_change($s->billing_interval,1),$o->account->taxes),2) }}</td> <td>${{ number_format($a=\App\Models\Tax::tax_calc($s->base_cost*\App\Models\Invoice::billing_change($s->billing_interval,1),$o->account->taxes),2) }}</td>
@endif @endif
<td>${{ number_format($b=$o->billing_monthly_price,2) }}</td> <td @if($x=$o->isChargeOverriden()) class="text-danger" @endif>${{ number_format($b=($x ? $p->base_charge_taxable : $o->billing_monthly_price),2) }}</td>
@if ($s->exists) @if ($s->exists)
<td>{!! markup($a,$b) !!}</td> <td>{!! markup($a,$b) !!}</td>
@endif @endif
@ -69,7 +69,7 @@
@if ($s->exists) @if ($s->exists)
<td>{{ $s->contract_term }} months</td> <td>{{ $s->contract_term }} months</td>
@endif @endif
<td>{{ $o->contract_term }} months</td> <td>{{ $p->contract_term }} months</td>
@if ($s->exists) @if ($s->exists)
<td>&nbsp;</td> <td>&nbsp;</td>
@endif @endif
@ -78,19 +78,11 @@
<th>Min Price</th> <th>Min Price</th>
@if ($s->exists) @if ($s->exists)
<td>${{ number_format($a=\App\Models\Tax::tax_calc($s->min_cost,$o->account->taxes),2) }}</td> <td>${{ number_format($a=\App\Models\Tax::tax_calc($s->min_cost,$o->account->taxes),2) }}</td>
<td>${{ number_format($b=\App\Models\Tax::tax_calc($o->product->getMinChargeAttribute($o->billing_interval),$o->account->taxes),2) }}</td> <td>${{ number_format($b=\App\Models\Tax::tax_calc($p->getMinChargeAttribute($o->billing_interval),$o->account->taxes),2) }}</td>
<td>{!! markup($a,$b) !!}</td> <td>{!! markup($a,$b) !!}</td>
@else @else
<td>-</td> <td>-</td>
@endif @endif
</tr> </tr>
</tbody> </tbody>
</table> </table>
@php
function markup($a,$b) {
return ($a > $b)
? sprintf('<span class="badge bg-danger>">(%3.1f%%)</span>',$a ? ($b-$a)/($b ?: 1)*100 : 100)
: sprintf('<span class="badge">%3.1f%%</span>',$a ? ($b-$a)/($b ?: 1)*100 : ($b ? 100: 0));
}
@endphp