interim fix for drop downs, BROKEN FIX, interinm fix
This commit is contained in:
@@ -4,6 +4,7 @@ namespace Modules\Company\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Modules\Company\Models\Company;
|
||||
@@ -16,12 +17,24 @@ class CompanyController extends Controller
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$counts = ['users', 'warehouses', 'licenseKeys'];
|
||||
|
||||
if (Schema::hasTable('company_divisions')) {
|
||||
$counts[] = 'divisions';
|
||||
}
|
||||
|
||||
$companies = Company::query()
|
||||
->with(['country'])
|
||||
->withCount($counts)
|
||||
->orderBy('name')
|
||||
->paginate(20);
|
||||
|
||||
$companies->getCollection()->each(function (Company $company): void {
|
||||
$company->setAttribute('divisions_count', $company->getAttribute('divisions_count') ?? 0);
|
||||
});
|
||||
|
||||
return view('company::index', [
|
||||
'companies' => Company::query()
|
||||
->with(['address.country', 'country'])
|
||||
->withCount(['users', 'warehouses', 'licenseKeys', 'divisions'])
|
||||
->orderBy('name')
|
||||
->paginate(20),
|
||||
'companies' => $companies,
|
||||
'countries' => $this->countries(),
|
||||
]);
|
||||
}
|
||||
@@ -57,16 +70,20 @@ class CompanyController extends Controller
|
||||
*/
|
||||
public function show(Company $company)
|
||||
{
|
||||
$company->load([
|
||||
'address.country',
|
||||
'divisions.address.country',
|
||||
'divisions.warehouses',
|
||||
'divisions.users',
|
||||
'warehouses.address.country',
|
||||
'warehouses.division',
|
||||
'directorAssignments.user',
|
||||
'directorAssignments.division',
|
||||
])->loadCount(['users', 'warehouses', 'licenseKeys', 'payments', 'divisions']);
|
||||
$loads = ['country'];
|
||||
$counts = ['users', 'warehouses', 'licenseKeys', 'payments'];
|
||||
|
||||
if (Schema::hasTable('company_divisions')) {
|
||||
$loads[] = 'divisions';
|
||||
$counts[] = 'divisions';
|
||||
}
|
||||
|
||||
if (Schema::hasTable('company_director_assignments')) {
|
||||
$loads[] = 'directorAssignments.user';
|
||||
}
|
||||
|
||||
$company->load($loads)->loadCount($counts);
|
||||
$company->setAttribute('divisions_count', $company->getAttribute('divisions_count') ?? 0);
|
||||
|
||||
return view('company::show', [
|
||||
'company' => $company,
|
||||
@@ -74,8 +91,6 @@ class CompanyController extends Controller
|
||||
'recentWarehouses' => $company->warehouses()->latest('id')->limit(5)->get(),
|
||||
'recentLicenseKeys' => $company->licenseKeys()->latest('id')->limit(5)->get(),
|
||||
'countries' => $this->countries(),
|
||||
'companyUsers' => $company->users()->orderBy('name')->get(['id', 'name', 'email', 'company_id']),
|
||||
'unassignedWarehouses' => $company->warehouses()->whereNull('division_id')->orderBy('name')->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -85,7 +100,7 @@ class CompanyController extends Controller
|
||||
public function edit(Company $company)
|
||||
{
|
||||
return view('company::edit', [
|
||||
'company' => $company->loadMissing(['address.country', 'country']),
|
||||
'company' => $company->loadMissing('country'),
|
||||
'countries' => $this->countries(),
|
||||
]);
|
||||
}
|
||||
@@ -125,10 +140,14 @@ class CompanyController extends Controller
|
||||
'country_id' => ['nullable', Rule::exists('countries', 'id')->where('is_active', true)],
|
||||
]);
|
||||
|
||||
$data['slug'] = Str::slug($data['name']);
|
||||
$data['timezone'] = $company?->timezone ?: 'Europe/London';
|
||||
|
||||
return $data;
|
||||
return [
|
||||
'name' => $data['name'],
|
||||
'billing_email' => $data['billing_email'] ?? null,
|
||||
'status' => $data['status'],
|
||||
'country_id' => $data['country_id'] ?? null,
|
||||
'slug' => Str::slug($data['name']),
|
||||
'timezone' => $company?->timezone ?: 'Europe/London',
|
||||
];
|
||||
}
|
||||
|
||||
private function countries()
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Company\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
use Modules\Countries\Models\Country;
|
||||
|
||||
class CompanyAddress extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
|
||||
protected $casts = [
|
||||
'is_primary' => 'boolean',
|
||||
];
|
||||
|
||||
public function addressable(): MorphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
public function country(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Country::class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Company\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class CompanyDirectorAssignment extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
|
||||
public function company(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Company::class);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function division(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CompanyDivision::class, 'company_division_id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Company\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphOne;
|
||||
use Modules\Warehouse\app\Models\Warehouse;
|
||||
|
||||
class CompanyDivision extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
|
||||
public function company(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Company::class);
|
||||
}
|
||||
|
||||
public function address(): MorphOne
|
||||
{
|
||||
return $this->morphOne(CompanyAddress::class, 'addressable');
|
||||
}
|
||||
|
||||
public function warehouses(): HasMany
|
||||
{
|
||||
return $this->hasMany(Warehouse::class, 'division_id');
|
||||
}
|
||||
|
||||
public function users(): HasMany
|
||||
{
|
||||
return $this->hasMany(User::class, 'division_id');
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
id="name"
|
||||
name="name"
|
||||
value="{{ old('name', $company->name) }}"
|
||||
class="mt-2 w-full rounded-xl border-zinc-300 dark:border-zinc-700 dark:bg-zinc-950 dark:text-white"
|
||||
class="mt-2 h-12 w-full rounded-xl border-zinc-300 bg-white px-4 text-sm text-zinc-900 shadow-sm outline-none transition focus:border-blue-500 focus:ring-2 focus:ring-blue-500/30 dark:border-zinc-700 dark:bg-zinc-950 dark:text-white"
|
||||
required
|
||||
>
|
||||
@error('name')
|
||||
@@ -23,7 +23,7 @@
|
||||
name="billing_email"
|
||||
value="{{ old('billing_email', $company->billing_email) }}"
|
||||
placeholder="billing@example.com"
|
||||
class="mt-2 w-full rounded-xl border-zinc-300 dark:border-zinc-700 dark:bg-zinc-950 dark:text-white"
|
||||
class="mt-2 h-12 w-full rounded-xl border-zinc-300 bg-white px-4 text-sm text-zinc-900 shadow-sm outline-none transition focus:border-blue-500 focus:ring-2 focus:ring-blue-500/30 dark:border-zinc-700 dark:bg-zinc-950 dark:text-white"
|
||||
>
|
||||
@error('billing_email')
|
||||
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||||
@@ -35,7 +35,7 @@
|
||||
<select
|
||||
id="status"
|
||||
name="status"
|
||||
class="mt-2 w-full rounded-xl border-zinc-300 dark:border-zinc-700 dark:bg-zinc-950 dark:text-white"
|
||||
class="mt-2 h-12 w-full rounded-xl border-zinc-300 bg-white px-4 text-sm text-zinc-900 shadow-sm outline-none transition focus:border-blue-500 focus:ring-2 focus:ring-blue-500/30 dark:border-zinc-700 dark:bg-zinc-950 dark:text-white"
|
||||
required
|
||||
>
|
||||
<option value="active" @selected(old('status', $company->status) === 'active')>Active</option>
|
||||
@@ -54,12 +54,12 @@
|
||||
name="country_id"
|
||||
data-wms-select2
|
||||
data-placeholder="Search and select a country"
|
||||
class="mt-2 w-full rounded-xl border-zinc-300 dark:border-zinc-700 dark:bg-zinc-950 dark:text-white"
|
||||
class="w-full"
|
||||
>
|
||||
<option value="">Search and select a country</option>
|
||||
<option value=""></option>
|
||||
@foreach ($countries as $country)
|
||||
<option value="{{ $country->id }}" @selected((int) old('country_id', $company->country_id ?? $company->address?->country_id) === $country->id)>
|
||||
{{ $country->effective_name ?? $country->name }}
|
||||
<option value="{{ $country->id }}" @selected((int) old('country_id', $company->country_id) === $country->id)>
|
||||
{{ $country->display_name ?: $country->common_name ?: $country->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@@ -70,7 +70,7 @@
|
||||
</div>
|
||||
|
||||
<div class="mt-6 flex flex-wrap items-center gap-3">
|
||||
<button class="rounded-xl bg-zinc-900 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-zinc-700 dark:bg-white dark:text-zinc-900">
|
||||
<button class="rounded-xl bg-green-600 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-green-500 focus:outline-none focus:ring-2 focus:ring-green-500/40">
|
||||
Save company
|
||||
</button>
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<x-layouts::app :title="__('Create company')">
|
||||
<div class="space-y-6">
|
||||
<x-wms.page-hero
|
||||
eyebrow="Platform Administration"
|
||||
title="Create company"
|
||||
description="Add a new tenant company and assign its country."
|
||||
icon="fa-solid fa-building-circle-plus"
|
||||
/>
|
||||
|
||||
<div class="rounded-3xl bg-white p-6 shadow-sm ring-1 ring-zinc-200 dark:bg-zinc-900 dark:ring-zinc-800">
|
||||
<form method="POST" action="{{ route('platform.companies.store') }}">
|
||||
@include('company::_form')
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</x-layouts::app>
|
||||
@@ -0,0 +1,17 @@
|
||||
<x-layouts::app :title="__('Edit company')">
|
||||
<div class="space-y-6">
|
||||
<x-wms.page-hero
|
||||
eyebrow="Platform Administration"
|
||||
title="Edit company"
|
||||
description="Update company details and country assignment."
|
||||
icon="fa-solid fa-building"
|
||||
/>
|
||||
|
||||
<div class="rounded-3xl bg-white p-6 shadow-sm ring-1 ring-zinc-200 dark:bg-zinc-900 dark:ring-zinc-800">
|
||||
<form method="POST" action="{{ route('platform.companies.update', $company) }}">
|
||||
@method('PUT')
|
||||
@include('company::_form')
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</x-layouts::app>
|
||||
@@ -86,11 +86,11 @@
|
||||
name="country_id"
|
||||
data-wms-select2
|
||||
data-placeholder="Search and select country"
|
||||
class="mt-2 w-full"
|
||||
class="w-full"
|
||||
>
|
||||
<option value="">Search and select country</option>
|
||||
@foreach ($countries as $country)
|
||||
<option value="{{ $country->id }}" @selected((int) old('country_id') === $country->id)>
|
||||
<option value=""></option>
|
||||
@foreach($countries as $country)
|
||||
<option value="{{ $country->id }}" @selected(old('country_id') == $country->id)>
|
||||
{{ $country->display_name ?: $country->common_name ?: $country->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
@@ -127,23 +127,10 @@
|
||||
<td class="p-4 font-semibold text-zinc-900 dark:text-white">
|
||||
{{ $company->name }}
|
||||
</td>
|
||||
|
||||
<td class="p-4 text-zinc-700 dark:text-zinc-300">
|
||||
{{ $company->users_count }}
|
||||
</td>
|
||||
|
||||
<td class="p-4 text-zinc-700 dark:text-zinc-300">
|
||||
{{ $company->divisions_count }}
|
||||
</td>
|
||||
|
||||
<td class="p-4 text-zinc-700 dark:text-zinc-300">
|
||||
{{ $company->warehouses_count }}
|
||||
</td>
|
||||
|
||||
<td class="p-4 text-zinc-700 dark:text-zinc-300">
|
||||
{{ $company->license_keys_count }}
|
||||
</td>
|
||||
|
||||
<td class="p-4 text-zinc-700 dark:text-zinc-300">{{ $company->users_count }}</td>
|
||||
<td class="p-4 text-zinc-700 dark:text-zinc-300">{{ $company->divisions_count ?? 0 }}</td>
|
||||
<td class="p-4 text-zinc-700 dark:text-zinc-300">{{ $company->warehouses_count }}</td>
|
||||
<td class="p-4 text-zinc-700 dark:text-zinc-300">{{ $company->license_keys_count }}</td>
|
||||
<td class="p-4">
|
||||
<span class="inline-flex rounded-full px-2.5 py-1 text-xs font-semibold
|
||||
@if ($company->is_system_company)
|
||||
@@ -157,38 +144,16 @@
|
||||
{{ $company->is_system_company ? 'System' : ucfirst($company->status) }}
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td class="p-4">
|
||||
<div class="flex justify-end gap-2">
|
||||
<a
|
||||
href="{{ route('platform.companies.show', $company) }}"
|
||||
class="rounded-lg border border-zinc-300 px-3 py-1.5 text-xs font-semibold text-zinc-700 hover:bg-zinc-50 dark:border-zinc-700 dark:text-zinc-200 dark:hover:bg-zinc-800"
|
||||
>
|
||||
View
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="{{ route('platform.companies.edit', $company) }}"
|
||||
class="rounded-lg bg-blue-600 px-3 py-1.5 text-xs font-semibold text-white hover:bg-blue-700"
|
||||
>
|
||||
Edit
|
||||
</a>
|
||||
<a href="{{ route('platform.companies.show', $company) }}" class="rounded-lg border border-zinc-300 px-3 py-1.5 text-xs font-semibold text-zinc-700 hover:bg-zinc-50 dark:border-zinc-700 dark:text-zinc-200 dark:hover:bg-zinc-800">View</a>
|
||||
<a href="{{ route('platform.companies.edit', $company) }}" class="rounded-lg bg-blue-600 px-3 py-1.5 text-xs font-semibold text-white hover:bg-blue-700">Edit</a>
|
||||
|
||||
@unless ($company->is_system_company)
|
||||
<form
|
||||
method="POST"
|
||||
action="{{ route('platform.companies.destroy', $company) }}"
|
||||
onsubmit="return confirm('Delete this company? This cannot be undone.');"
|
||||
>
|
||||
<form method="POST" action="{{ route('platform.companies.destroy', $company) }}" onsubmit="return confirm('Delete this company? This cannot be undone.');">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="rounded-lg bg-red-600 px-3 py-1.5 text-xs font-semibold text-white hover:bg-red-700"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
<button type="submit" class="rounded-lg bg-red-600 px-3 py-1.5 text-xs font-semibold text-white hover:bg-red-700">Delete</button>
|
||||
</form>
|
||||
@endunless
|
||||
</div>
|
||||
@@ -196,9 +161,7 @@
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="p-8 text-center text-zinc-500 dark:text-zinc-400">
|
||||
No companies found.
|
||||
</td>
|
||||
<td colspan="7" class="p-8 text-center text-zinc-500 dark:text-zinc-400">No companies found.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
<x-layouts::app :title="$company->name">
|
||||
<div class="space-y-6">
|
||||
<x-wms.page-hero
|
||||
eyebrow="Platform Administration"
|
||||
:title="$company->name"
|
||||
description="Company tenant overview."
|
||||
icon="fa-solid fa-building"
|
||||
/>
|
||||
|
||||
@if (session('status'))
|
||||
<div class="rounded-2xl bg-green-50 p-4 text-sm font-semibold text-green-700 ring-1 ring-green-200 dark:bg-green-950 dark:text-green-300 dark:ring-green-900">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="grid gap-4 md:grid-cols-4">
|
||||
<div class="rounded-2xl bg-white p-5 shadow-sm ring-1 ring-zinc-200 dark:bg-zinc-900 dark:ring-zinc-800">
|
||||
<p class="text-xs font-bold uppercase tracking-wide text-zinc-500">Users</p>
|
||||
<p class="mt-2 text-2xl font-bold text-zinc-900 dark:text-white">{{ $company->users_count ?? 0 }}</p>
|
||||
</div>
|
||||
<div class="rounded-2xl bg-white p-5 shadow-sm ring-1 ring-zinc-200 dark:bg-zinc-900 dark:ring-zinc-800">
|
||||
<p class="text-xs font-bold uppercase tracking-wide text-zinc-500">Divisions</p>
|
||||
<p class="mt-2 text-2xl font-bold text-zinc-900 dark:text-white">{{ $company->divisions_count ?? 0 }}</p>
|
||||
</div>
|
||||
<div class="rounded-2xl bg-white p-5 shadow-sm ring-1 ring-zinc-200 dark:bg-zinc-900 dark:ring-zinc-800">
|
||||
<p class="text-xs font-bold uppercase tracking-wide text-zinc-500">Warehouses</p>
|
||||
<p class="mt-2 text-2xl font-bold text-zinc-900 dark:text-white">{{ $company->warehouses_count ?? 0 }}</p>
|
||||
</div>
|
||||
<div class="rounded-2xl bg-white p-5 shadow-sm ring-1 ring-zinc-200 dark:bg-zinc-900 dark:ring-zinc-800">
|
||||
<p class="text-xs font-bold uppercase tracking-wide text-zinc-500">Licences</p>
|
||||
<p class="mt-2 text-2xl font-bold text-zinc-900 dark:text-white">{{ $company->license_keys_count ?? 0 }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rounded-3xl bg-white p-6 shadow-sm ring-1 ring-zinc-200 dark:bg-zinc-900 dark:ring-zinc-800">
|
||||
<div class="flex flex-wrap items-start justify-between gap-4">
|
||||
<div>
|
||||
<h2 class="text-lg font-bold text-zinc-900 dark:text-white">Company details</h2>
|
||||
<dl class="mt-4 grid gap-4 text-sm md:grid-cols-2">
|
||||
<div>
|
||||
<dt class="font-semibold text-zinc-500">Billing email</dt>
|
||||
<dd class="mt-1 text-zinc-900 dark:text-white">{{ $company->billing_email ?: 'Not set' }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="font-semibold text-zinc-500">Country</dt>
|
||||
<dd class="mt-1 text-zinc-900 dark:text-white">{{ $company->country?->display_name ?: $company->country?->common_name ?: $company->country?->name ?: 'Not set' }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="font-semibold text-zinc-500">Status</dt>
|
||||
<dd class="mt-1 text-zinc-900 dark:text-white">{{ ucfirst($company->status) }}</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="font-semibold text-zinc-500">Timezone</dt>
|
||||
<dd class="mt-1 text-zinc-900 dark:text-white">{{ $company->timezone }}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<a href="{{ route('platform.companies.edit', $company) }}" class="rounded-xl bg-blue-600 px-4 py-2 text-sm font-semibold text-white hover:bg-blue-700">Edit</a>
|
||||
<a href="{{ route('platform.companies.index') }}" class="rounded-xl border border-zinc-300 px-4 py-2 text-sm font-semibold text-zinc-700 hover:bg-zinc-50 dark:border-zinc-700 dark:text-zinc-200 dark:hover:bg-zinc-800">Back</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-layouts::app>
|
||||
@@ -24,10 +24,8 @@ Route::middleware(['auth', 'verified', 'tenant.assigned', 'platform.admin'])
|
||||
Route::post('/licenses', [LicenseKeyController::class, 'store'])->name('licenses.store');
|
||||
Route::get('/payments', [PaymentController::class, 'index'])->name('payments.index');
|
||||
Route::post('/payments', [PaymentController::class, 'store'])->name('payments.store');
|
||||
if (! Route::has('platform.companies.index')) {
|
||||
Route::resource('/companies', CompanyController::class);
|
||||
}
|
||||
Route::resource('/prices', PlatformPriceController::class)->except(['show']);
|
||||
Route::resource('/companies', CompanyController::class);
|
||||
});
|
||||
|
||||
Route::post('/stripe/webhook', StripeWebhookController::class)->name('stripe.webhook');
|
||||
|
||||
Reference in New Issue
Block a user