added full module support
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Platform\app\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
use Modules\Platform\app\Models\Company;
|
||||
|
||||
class CompanyController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display companies.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('platform::companies.index', [
|
||||
'companies' => Company::withCount(['users', 'warehouses', 'licenseKeys'])->orderBy('name')->paginate(20),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a company tenant.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'billing_email' => ['nullable', 'email', 'max:255'],
|
||||
'status' => ['required', 'in:active,suspended'],
|
||||
]);
|
||||
|
||||
Company::create([
|
||||
...$data,
|
||||
'slug' => Str::slug($data['name']),
|
||||
'timezone' => 'Europe/London',
|
||||
]);
|
||||
|
||||
return back()->with('status', 'Company created.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Platform\app\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\Platform\app\Models\Company;
|
||||
use Modules\Platform\app\Models\LicenseKey;
|
||||
|
||||
class LicenseKeyController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display licence keys.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('platform::licenses.index', [
|
||||
'companies' => Company::orderBy('name')->get(),
|
||||
'licenses' => LicenseKey::with('company')->latest()->paginate(20),
|
||||
'plainKey' => session('plain_license_key'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Issue a new licence key.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'company_id' => ['required', 'exists:companies,id'],
|
||||
'label' => ['required', 'string', 'max:255'],
|
||||
'plan' => ['required', 'in:standard,professional,enterprise'],
|
||||
'max_users' => ['required', 'integer', 'min:1', 'max:10000'],
|
||||
]);
|
||||
|
||||
$company = Company::findOrFail($data['company_id']);
|
||||
$plainKey = LicenseKey::issueFor($company, $data['label'], $data['plan'], (int) $data['max_users']);
|
||||
|
||||
return back()->with('plain_license_key', $plainKey)->with('status', 'Licence key issued. Copy it now.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Platform\app\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\Platform\app\Models\Company;
|
||||
use Modules\Platform\app\Models\Payment;
|
||||
|
||||
class PaymentController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display company payments.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('platform::payments.index', [
|
||||
'companies' => Company::orderBy('name')->get(),
|
||||
'payments' => Payment::with('company')->latest()->paginate(20),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a manual payment or admin override record.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$data = $request->validate([
|
||||
'company_id' => ['required', 'exists:companies,id'],
|
||||
'amount' => ['required', 'integer', 'min:0'],
|
||||
'currency' => ['required', 'string', 'size:3'],
|
||||
'status' => ['required', 'in:pending,paid,failed,refunded,override'],
|
||||
'description' => ['nullable', 'string', 'max:255'],
|
||||
]);
|
||||
|
||||
Payment::create([
|
||||
...$data,
|
||||
'paid_at' => in_array($data['status'], ['paid', 'override'], true) ? now() : null,
|
||||
'metadata' => ['source' => 'manual_admin'],
|
||||
]);
|
||||
|
||||
return back()->with('status', 'Payment record created.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Platform\app\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Modules\Platform\app\Models\Company;
|
||||
use Modules\Platform\app\Models\LicenseKey;
|
||||
use Modules\Platform\app\Models\Payment;
|
||||
use Modules\Warehouse\app\Models\Warehouse;
|
||||
|
||||
class PlatformDashboardController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the platform administration dashboard.
|
||||
*/
|
||||
public function __invoke()
|
||||
{
|
||||
return view('platform::dashboard.index', [
|
||||
'companiesCount' => Company::count(),
|
||||
'activeCompaniesCount' => Company::where('status', 'active')->count(),
|
||||
'licensesCount' => LicenseKey::count(),
|
||||
'paymentsTotal' => Payment::where('status', 'paid')->sum('amount'),
|
||||
'warehousesCount' => Warehouse::count(),
|
||||
'companies' => Company::withCount(['users', 'warehouses', 'licenseKeys'])->latest()->limit(8)->get(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Platform\app\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\Platform\app\Models\Company;
|
||||
use Modules\Platform\app\Models\Payment;
|
||||
|
||||
class StripeWebhookController extends Controller
|
||||
{
|
||||
/**
|
||||
* Receive a Stripe webhook event.
|
||||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
$payload = $request->all();
|
||||
$eventType = data_get($payload, 'type');
|
||||
|
||||
if ($eventType === 'payment_intent.succeeded') {
|
||||
$intent = data_get($payload, 'data.object', []);
|
||||
$company = Company::where('stripe_customer_id', data_get($intent, 'customer'))->first();
|
||||
|
||||
if ($company) {
|
||||
Payment::updateOrCreate(
|
||||
['stripe_payment_intent_id' => data_get($intent, 'id')],
|
||||
[
|
||||
'company_id' => $company->id,
|
||||
'amount' => (int) data_get($intent, 'amount_received', 0),
|
||||
'currency' => (string) data_get($intent, 'currency', 'gbp'),
|
||||
'status' => 'paid',
|
||||
'description' => 'Stripe payment received',
|
||||
'paid_at' => now(),
|
||||
'metadata' => $intent,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json(['received' => true]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Platform\app\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class EnsureLicensedTenant
|
||||
{
|
||||
/**
|
||||
* Ensure the current company has an active licence unless it is the MPBA platform tenant.
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
$user = $request->user();
|
||||
$company = $user?->company;
|
||||
|
||||
abort_if(! $company, 403, 'No company is assigned to this account.');
|
||||
|
||||
if ($user->isMpbaPlatformAdmin()) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
abort_unless($company->hasActiveLicense(), 402, 'Payment Required');
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Platform\app\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class EnsurePlatformAdmin
|
||||
{
|
||||
/**
|
||||
* Ensure the current user is an MPBA platform administrator.
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
abort_unless($request->user()?->isMpbaPlatformAdmin(), 403);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Platform\app\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class EnsureTenantAssigned
|
||||
{
|
||||
/**
|
||||
* Ensure the authenticated user belongs to a company tenant.
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
abort_if(! $user || ! $user->company_id, 403, 'No company is assigned to this account.');
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user