Compare commits

...

3 Commits

Author SHA1 Message Date
73baa2f153 Added API stub configuration
All checks were successful
Create Docker Image / Build Docker Image (x86_64) (push) Successful in 33s
Create Docker Image / Final Docker Image Manifest (push) Successful in 10s
2024-07-26 12:34:35 +10:00
9380850395 Move charge actions to ChargeController, implemented charge delete 2024-07-26 12:33:42 +10:00
756f550b43 Cosmetic code changes, no functional changes 2024-07-25 14:44:09 +10:00
26 changed files with 156 additions and 120 deletions

View File

@ -0,0 +1,69 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\ChargeAdd;
use App\Models\Charge;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Gate;
use Illuminate\View\View;
class ChargeController extends Controller
{
/**
* Add a charge to a service/account
*
* @param ChargeAdd $request
* @return RedirectResponse
*/
public function addedit(ChargeAdd $request): RedirectResponse
{
$o = Charge::findOrNew(Arr::get($request->validated(),'id'));
// Dont update processed charges
if ($o->processed)
abort(403);
$o->forceFill(array_merge(Arr::except($request->validated(),['id']),['active'=>TRUE]));
$o->save();
return redirect()
->back()
->with('success',sprintf('Charge %s #%d',$o->wasRecentlyCreated ? 'Created' : 'Updated',$o->id));
}
public function delete(Charge $o): array
{
if (Gate::allows('delete',$o)) {
$o->delete();
return ['ok'];
} else {
abort(401,'Not Allowed');
}
}
/**
* Add a charge to a service/account
*
* @param Request $request
* @return View
*/
public function edit(Request $request): View
{
$o = Charge::where('processed',FALSE)
->where('id',$request->id)
->firstOrFail();
if (Gate::allows('update',$o)) {
return view('theme.backend.adminlte.charge.widget.addedit')
->with('o',$o)
->with('so',$o->service);
}
abort(403);
}
}

View File

@ -266,49 +266,6 @@ class ServiceController extends Controller
} }
} }
/**
* Add a charge to a service/account
*
* @param ChargeAdd $request
* @return RedirectResponse
*/
public function charge_addedit(ChargeAdd $request): RedirectResponse
{
$o = Charge::findOrNew(Arr::get($request->validated(),'id'));
// Dont update processed charges
if ($o->processed)
abort(403);
$o->forceFill(array_merge(Arr::except($request->validated(),['id']),['active'=>TRUE]));
$o->save();
return redirect()
->back()
->with('success',sprintf('Charge %s #%d',$o->wasRecentlyCreated ? 'Created' : 'Updated',$o->id));
}
/**
* Add a charge to a service/account
*
* @param Request $request
* @return View
*/
public function charge_edit(Request $request): View
{
$o = Charge::where('processed',FALSE)
->where('id',$request->id)
->firstOrFail();
if (Gate::allows('update',$o)) {
return view('theme.backend.adminlte.charge.widget.addedit')
->with('o',$o)
->with('so',$o->service);
}
abort(403);
}
/** /**
* List all the domains managed by the user * List all the domains managed by the user
* *

View File

@ -70,7 +70,7 @@ class Charge extends Model
/* ATTRIBUTES */ /* ATTRIBUTES */
public function getNameAttribute() public function getNameAttribute(): string
{ {
return sprintf('%s %s', return sprintf('%s %s',
$this->description, $this->description,
@ -93,4 +93,14 @@ class Charge extends Model
{ {
return Arr::get(InvoiceItem::type,$this->type); return Arr::get(InvoiceItem::type,$this->type);
} }
/**
* Is this charge processable
*
* @return bool
*/
public function getUnprocessedAttribute(): bool
{
return $this->active && (! $this->processed);
}
} }

View File

@ -1275,7 +1275,7 @@ class Service extends Model implements IDs
if ((($future == TRUE) OR (($future == FALSE) AND ($this->invoice_to >= $billdate))) if ((($future == TRUE) OR (($future == FALSE) AND ($this->invoice_to >= $billdate)))
AND ! $this->invoice_items->filter(function($item) { return $item->module_id == 30 AND ! $item->exists; })->count()) AND ! $this->invoice_items->filter(function($item) { return $item->module_id == 30 AND ! $item->exists; })->count())
{ {
foreach ($this->charges->filter(function($item) { return ! $item->processed; }) as $oo) { foreach ($this->charges->filter(function($item) { return $item->unprocessed; }) as $oo) {
$o = new InvoiceItem; $o = new InvoiceItem;
$o->active = TRUE; $o->active = TRUE;
$o->service_id = $oo->service_id; $o->service_id = $oo->service_id;

View File

@ -10,6 +10,7 @@ use App\Http\Middleware\{Role,SetSite};
return Application::configure(basePath: dirname(__DIR__)) return Application::configure(basePath: dirname(__DIR__))
->withRouting( ->withRouting(
web: __DIR__.'/../routes/web.php', web: __DIR__.'/../routes/web.php',
//api: __DIR__.'/../routes/api.php',
commands: __DIR__.'/../routes/console.php', commands: __DIR__.'/../routes/console.php',
health: '/up', health: '/up',
) )

18
composer.lock generated
View File

@ -3056,11 +3056,11 @@
}, },
{ {
"name": "leenooks/laravel", "name": "leenooks/laravel",
"version": "11.1.5", "version": "11.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://gitea.dege.au/laravel/leenooks.git", "url": "https://gitea.dege.au/laravel/leenooks.git",
"reference": "4a4cf3c5bf32f50dcdc8fdc6c3ff680d7f15d90d" "reference": "628fbac8f9ce60c5124ee83b288733ae24e48b63"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -3093,7 +3093,7 @@
"laravel", "laravel",
"leenooks" "leenooks"
], ],
"time": "2024-07-25T03:52:29+00:00" "time": "2024-07-26T02:26:31+00:00"
}, },
{ {
"name": "leenooks/passkey", "name": "leenooks/passkey",
@ -9995,16 +9995,16 @@
}, },
{ {
"name": "spatie/error-solutions", "name": "spatie/error-solutions",
"version": "1.1.0", "version": "1.1.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/spatie/error-solutions.git", "url": "https://github.com/spatie/error-solutions.git",
"reference": "a014da18f2675ea15af0ba97f7e9aee59e13964f" "reference": "ae7393122eda72eed7cc4f176d1e96ea444f2d67"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/spatie/error-solutions/zipball/a014da18f2675ea15af0ba97f7e9aee59e13964f", "url": "https://api.github.com/repos/spatie/error-solutions/zipball/ae7393122eda72eed7cc4f176d1e96ea444f2d67",
"reference": "a014da18f2675ea15af0ba97f7e9aee59e13964f", "reference": "ae7393122eda72eed7cc4f176d1e96ea444f2d67",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -10057,7 +10057,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/spatie/error-solutions/issues", "issues": "https://github.com/spatie/error-solutions/issues",
"source": "https://github.com/spatie/error-solutions/tree/1.1.0" "source": "https://github.com/spatie/error-solutions/tree/1.1.1"
}, },
"funding": [ "funding": [
{ {
@ -10065,7 +10065,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2024-07-22T08:18:22+00:00" "time": "2024-07-25T11:06:04+00:00"
}, },
{ {
"name": "spatie/flare-client-php", "name": "spatie/flare-client-php",

View File

@ -40,6 +40,12 @@ return [
'driver' => 'session', 'driver' => 'session',
'provider' => 'users', 'provider' => 'users',
], ],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
], ],
/* /*

View File

@ -43,7 +43,6 @@
@section('page-styles') @section('page-styles')
@css(datatables,bootstrap4) @css(datatables,bootstrap4)
@append @append
@section('page-scripts') @section('page-scripts')
@js(datatables,bootstrap4) @js(datatables,bootstrap4)

View File

@ -40,7 +40,6 @@
@section('page-styles') @section('page-styles')
@css(datatables,bootstrap4|rowgroup) @css(datatables,bootstrap4|rowgroup)
@append @append
@section('page-scripts') @section('page-scripts')
@js(datatables,bootstrap4|rowgroup) @js(datatables,bootstrap4|rowgroup)

View File

@ -50,7 +50,6 @@
@section('page-styles') @section('page-styles')
@css(datatables,bootstrap4|rowgroup) @css(datatables,bootstrap4|rowgroup)
@append @append
@section('page-scripts') @section('page-scripts')
@js(datatables,bootstrap4|rowgroup) @js(datatables,bootstrap4|rowgroup)

View File

@ -1,7 +1,8 @@
@php <!-- $o=User::class -->
use App\Models\{Account,Service}; @php($acts=$o->accounts_all->pluck('id'))
$acts = $o->accounts_all->pluck('id');
@endphp @use(App\Models\Account)
@use(App\Models\Service)
@if($user->isReseller() && ($o->accounts->count() <= 2) && ($x=$o->accounts->pluck('providers')->flatten())->count()) @if($user->isReseller() && ($o->accounts->count() <= 2) && ($x=$o->accounts->pluck('providers')->flatten())->count())
<div class="col-12 col-sm-4 col-md-2"> <div class="col-12 col-sm-4 col-md-2">

View File

@ -57,8 +57,10 @@
</div> </div>
@endsection @endsection
@section('page-scripts') @section('page-styles')
@css(datatables,bootstrap4) @css(datatables,bootstrap4)
@append
@section('page-scripts')
@js(datatables,bootstrap4) @js(datatables,bootstrap4)
<script type="text/javascript"> <script type="text/javascript">

View File

@ -1,8 +1,7 @@
@php
use App\Models\{Checkout,Service};
@endphp
<!-- $o=Invoice::class --> <!-- $o=Invoice::class -->
@use(App\Models\Checkout)
@use(App\Models\Service)
@extends('adminlte::layouts.app') @extends('adminlte::layouts.app')
@section('htmlheader_title') @section('htmlheader_title')

View File

@ -32,7 +32,6 @@
@section('page-styles') @section('page-styles')
@css(datatables,bootstrap4|rowgroup) @css(datatables,bootstrap4|rowgroup)
@append @append
@section('page-scripts') @section('page-scripts')
@js(datatables,bootstrap4|rowgroup) @js(datatables,bootstrap4|rowgroup)

View File

@ -27,7 +27,6 @@
@section('page-styles') @section('page-styles')
@css(datatables,bootstrap4|rowgroup) @css(datatables,bootstrap4|rowgroup)
@append @append
@section('page-scripts') @section('page-scripts')
@js(datatables,bootstrap4|rowgroup) @js(datatables,bootstrap4|rowgroup)

View File

@ -1,7 +1,4 @@
@php @use(App\Models\Service)
use App\Models\Service;
@endphp
<!-- Show client movements --> <!-- Show client movements -->
<div class="card card-dark"> <div class="card card-dark">
<div class="card-header"> <div class="card-header">
@ -62,7 +59,6 @@ use App\Models\Service;
@section('page-styles') @section('page-styles')
@css(datatables,bootstrap4|rowgroup) @css(datatables,bootstrap4|rowgroup)
@append @append
@section('page-scripts') @section('page-scripts')
@js(datatables,bootstrap4|rowgroup) @js(datatables,bootstrap4|rowgroup)

View File

@ -28,7 +28,6 @@
@section('page-styles') @section('page-styles')
@css(datatables,bootstrap4) @css(datatables,bootstrap4)
@append @append
@section('page-scripts') @section('page-scripts')
@js(datatables,bootstrap4) @js(datatables,bootstrap4)

View File

@ -41,8 +41,8 @@
{{ $oo->processed ? 'YES' : 'NO' }} {{ $oo->processed ? 'YES' : 'NO' }}
@if(! $oo->processed) @if(! $oo->processed)
<span class="float-right"> <span class="float-right">
<a class="charge_edit" id="{{ $oo->id }}" href="#"><i class="fas fa-fw fa-edit"></i></a> <a class="charge_edit" data-id="{{ $oo->id }}" href="#"><i class="fas fa-fw fa-edit"></i></a>
<a class="charge_delete" id="{{ $oo->id }}" href="#"><i class="fas fa-fw fa-trash"></i></a> <a class="charge_delete" data-id="{{ $oo->id }}" href="{{ url('/r/charge/delete',$oo->id) }}"><i class="fas fa-fw fa-trash"></i></a>
</span> </span>
@endif @endif
</td> </td>
@ -59,7 +59,7 @@
</div> </div>
</div> </div>
<x-leenooks::modal.delete trigger="charge_delete"/> <x-leenooks::modal.delete hide="row" trigger="charge_delete"/>
@section('page-scripts') @section('page-scripts')
<script type="text/javascript"> <script type="text/javascript">
@ -70,33 +70,31 @@
$(document).ready(function() { $(document).ready(function() {
var loaded = []; var loaded = [];
$('.charge_edit').on('click',function(item) { $('.charge_edit').on('click',function() {
// Open our charge add tab automatically var that = $(this);
$('.nav-item a[href="#charge_add"]').tab('show');
if (loaded[item.currentTarget.id]) if (loaded[that.data('id')])
return false; return false;
console.log(item.currentTarget.id);
// Prepopulate with the details of the charge // Prepopulate with the details of the charge
$.ajax({ $.ajax({
url: '{{ url('r/charge/edit') }}', url: '{{ url('r/charge/edit') }}',
method: 'POST', method: 'POST',
data: { id: item.currentTarget.id }, data: { id: that.data('id') },
dataType: 'html', dataType: 'html',
}).done(function(html) { }).done(function(html) {
// Open our charge add tab aut1omatically
$('.nav-item a[href="#charge_add"]').tab('show');
$('div[id="charge_add"]').empty().append(html); $('div[id="charge_add"]').empty().append(html);
loaded[item.currentTarget.id] = true; loaded[that.data('id')] = true;
}).fail(function() { }).fail(function() {
alert('Failed'); alert('Hmm, that didnt work?');
}); });
return false; return false;
}); });
}); });
//<a href="{{ url('/api/charge/delete',$o->id) }}">
</script> </script>
@append @append

View File

@ -1,12 +1,12 @@
<?php <?php
use Illuminate\Support\Facades\Route;
use Intuit\Controllers\Webhook; use Intuit\Controllers\Webhook;
use App\Http\Controllers\{AccountingController, use App\Http\Controllers\{AccountingController,
AdminController, AdminController,
CheckoutController, CheckoutController,
ProductController, ProductController};
ResellerServicesController};
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View File

@ -7,6 +7,7 @@ use Leenooks\Controllers\SwitchUserController;
use App\Http\Controllers\{AdminController, use App\Http\Controllers\{AdminController,
Auth\LoginController, Auth\LoginController,
Auth\SocialLoginController, Auth\SocialLoginController,
ChargeController,
CheckoutController, CheckoutController,
HomeController, HomeController,
InvoiceController, InvoiceController,
@ -145,15 +146,17 @@ Route::group(['middleware'=>['auth','role:reseller'],'prefix'=>'r'],function() {
->name('switch.start'); ->name('switch.start');
// Reseller Reports // Reseller Reports
Route::group(['middleware'=>['auth','role:reseller'],'prefix'=>'report'],function() { Route::group(['prefix'=>'report'],function() {
Route::get('domain',[ServiceController::class,'domain_list']); Route::get('domain',[ServiceController::class,'domain_list']);
Route::get('email',[ServiceController::class,'email_list']); Route::get('email',[ServiceController::class,'email_list']);
Route::get('hosting',[ServiceController::class,'hosting_list']); Route::get('hosting',[ServiceController::class,'hosting_list']);
}); });
// Charges // Charges
Route::post('charge/addedit',[ServiceController::class,'charge_addedit']); Route::post('charge/addedit',[ChargeController::class,'addedit']);
Route::post('charge/edit',[ServiceController::class,'charge_edit']); Route::post('charge/delete/{o}',[ChargeController::class,'delete'])
->where('o','[0-9]+');
Route::post('charge/edit',[ChargeController::class,'edit']);
// Reseller API calls // Reseller API calls
Route::post('service_change_charges/{o}',[ServiceController::class,'service_change_charges_display']) Route::post('service_change_charges/{o}',[ServiceController::class,'service_change_charges_display'])