add CRUD Api client, client localisation, crud contact,
This commit is contained in:
parent
94eeb3e3d3
commit
215f4c4071
156
thanasoft-back/app/Http/Controllers/Api/ClientController.php
Normal file
156
thanasoft-back/app/Http/Controllers/Api/ClientController.php
Normal file
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\StoreClientRequest;
|
||||
use App\Http\Requests\UpdateClientRequest;
|
||||
use App\Http\Resources\Client\ClientResource;
|
||||
use App\Repositories\ClientRepositoryInterface;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class ClientController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ClientRepositoryInterface $clientRepository
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of clients.
|
||||
*/
|
||||
public function index(): AnonymousResourceCollection|JsonResponse
|
||||
{
|
||||
try {
|
||||
$clients = $this->clientRepository->all();
|
||||
return ClientResource::collection($clients);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error fetching clients: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la récupération des clients.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created client.
|
||||
*/
|
||||
public function store(StoreClientRequest $request): ClientResource|JsonResponse
|
||||
{
|
||||
try {
|
||||
$client = $this->clientRepository->create($request->validated());
|
||||
return new ClientResource($client);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error creating client: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'data' => $request->validated(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la création du client.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified client.
|
||||
*/
|
||||
public function show(string $id): ClientResource|JsonResponse
|
||||
{
|
||||
try {
|
||||
$client = $this->clientRepository->find($id);
|
||||
|
||||
if (!$client) {
|
||||
return response()->json([
|
||||
'message' => 'Client non trouvé.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
return new ClientResource($client);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error fetching client: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'client_id' => $id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la récupération du client.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified client.
|
||||
*/
|
||||
public function update(UpdateClientRequest $request, string $id): ClientResource|JsonResponse
|
||||
{
|
||||
try {
|
||||
$updated = $this->clientRepository->update($id, $request->validated());
|
||||
|
||||
if (!$updated) {
|
||||
return response()->json([
|
||||
'message' => 'Client non trouvé ou échec de la mise à jour.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
$client = $this->clientRepository->find($id);
|
||||
return new ClientResource($client);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error updating client: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'client_id' => $id,
|
||||
'data' => $request->validated(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la mise à jour du client.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified client.
|
||||
*/
|
||||
public function destroy(string $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
$deleted = $this->clientRepository->delete($id);
|
||||
|
||||
if (!$deleted) {
|
||||
return response()->json([
|
||||
'message' => 'Client non trouvé ou échec de la suppression.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Client supprimé avec succès.',
|
||||
], 200);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error deleting client: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'client_id' => $id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la suppression du client.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\StoreClientGroupRequest;
|
||||
use App\Http\Requests\UpdateClientGroupRequest;
|
||||
use App\Http\Resources\Client\ClientGroupResource;
|
||||
use App\Repositories\ClientGroupRepositoryInterface;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class ClientGroupController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ClientGroupRepositoryInterface $clientGroupRepository
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of client groups.
|
||||
*/
|
||||
public function index(): AnonymousResourceCollection|JsonResponse
|
||||
{
|
||||
try {
|
||||
$clientGroups = $this->clientGroupRepository->all();
|
||||
return ClientGroupResource::collection($clientGroups);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error fetching client groups: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la récupération des groupes de clients.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created client group.
|
||||
*/
|
||||
public function store(StoreClientGroupRequest $request): ClientGroupResource|JsonResponse
|
||||
{
|
||||
try {
|
||||
$clientGroup = $this->clientGroupRepository->create($request->validated());
|
||||
return new ClientGroupResource($clientGroup);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error creating client group: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'data' => $request->validated(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la création du groupe de clients.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified client group.
|
||||
*/
|
||||
public function show(string $id): ClientGroupResource|JsonResponse
|
||||
{
|
||||
try {
|
||||
$clientGroup = $this->clientGroupRepository->find($id);
|
||||
|
||||
if (!$clientGroup) {
|
||||
return response()->json([
|
||||
'message' => 'Groupe de clients non trouvé.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
return new ClientGroupResource($clientGroup);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error fetching client group: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'client_group_id' => $id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la récupération du groupe de clients.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified client group.
|
||||
*/
|
||||
public function update(UpdateClientGroupRequest $request, string $id): ClientGroupResource|JsonResponse
|
||||
{
|
||||
try {
|
||||
$updated = $this->clientGroupRepository->update($id, $request->validated());
|
||||
|
||||
if (!$updated) {
|
||||
return response()->json([
|
||||
'message' => 'Groupe de clients non trouvé ou échec de la mise à jour.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
$clientGroup = $this->clientGroupRepository->find($id);
|
||||
return new ClientGroupResource($clientGroup);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error updating client group: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'client_group_id' => $id,
|
||||
'data' => $request->validated(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la mise à jour du groupe de clients.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified client group.
|
||||
*/
|
||||
public function destroy(string $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
$deleted = $this->clientGroupRepository->delete($id);
|
||||
|
||||
if (!$deleted) {
|
||||
return response()->json([
|
||||
'message' => 'Groupe de clients non trouvé ou échec de la suppression.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Groupe de clients supprimé avec succès.',
|
||||
], 200);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error deleting client group: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'client_group_id' => $id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la suppression du groupe de clients.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\StoreClientLocationRequest;
|
||||
use App\Http\Requests\UpdateClientLocationRequest;
|
||||
use App\Http\Resources\Client\ClientLocationResource;
|
||||
use App\Repositories\ClientLocationRepositoryInterface;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class ClientLocationController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ClientLocationRepositoryInterface $clientLocationRepository
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of client locations.
|
||||
*/
|
||||
public function index(): AnonymousResourceCollection|JsonResponse
|
||||
{
|
||||
try {
|
||||
$clientLocations = $this->clientLocationRepository->all();
|
||||
return ClientLocationResource::collection($clientLocations);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error fetching client locations: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la récupération des lieux clients.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created client location.
|
||||
*/
|
||||
public function store(StoreClientLocationRequest $request): ClientLocationResource|JsonResponse
|
||||
{
|
||||
try {
|
||||
$clientLocation = $this->clientLocationRepository->create($request->validated());
|
||||
return new ClientLocationResource($clientLocation);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error creating client location: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'data' => $request->validated(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la création du lieu client.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified client location.
|
||||
*/
|
||||
public function show(string $id): ClientLocationResource|JsonResponse
|
||||
{
|
||||
try {
|
||||
$clientLocation = $this->clientLocationRepository->find($id);
|
||||
|
||||
if (!$clientLocation) {
|
||||
return response()->json([
|
||||
'message' => 'Lieu client non trouvé.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
return new ClientLocationResource($clientLocation);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error fetching client location: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'client_location_id' => $id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la récupération du lieu client.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified client location.
|
||||
*/
|
||||
public function update(UpdateClientLocationRequest $request, string $id): ClientLocationResource|JsonResponse
|
||||
{
|
||||
try {
|
||||
$updated = $this->clientLocationRepository->update($id, $request->validated());
|
||||
|
||||
if (!$updated) {
|
||||
return response()->json([
|
||||
'message' => 'Lieu client non trouvé ou échec de la mise à jour.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
$clientLocation = $this->clientLocationRepository->find($id);
|
||||
return new ClientLocationResource($clientLocation);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error updating client location: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'client_location_id' => $id,
|
||||
'data' => $request->validated(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la mise à jour du lieu client.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified client location.
|
||||
*/
|
||||
public function destroy(string $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
$deleted = $this->clientLocationRepository->delete($id);
|
||||
|
||||
if (!$deleted) {
|
||||
return response()->json([
|
||||
'message' => 'Lieu client non trouvé ou échec de la suppression.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Lieu client supprimé avec succès.',
|
||||
], 200);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error deleting client location: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'client_location_id' => $id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la suppression du lieu client.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
156
thanasoft-back/app/Http/Controllers/Api/ContactController.php
Normal file
156
thanasoft-back/app/Http/Controllers/Api/ContactController.php
Normal file
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\StoreContactRequest;
|
||||
use App\Http\Requests\UpdateContactRequest;
|
||||
use App\Http\Resources\Contact\ContactResource;
|
||||
use App\Repositories\ContactRepositoryInterface;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class ContactController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ContactRepositoryInterface $contactRepository
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of contacts.
|
||||
*/
|
||||
public function index(): AnonymousResourceCollection|JsonResponse
|
||||
{
|
||||
try {
|
||||
$contacts = $this->contactRepository->all();
|
||||
return ContactResource::collection($contacts);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error fetching contacts: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la récupération des contacts.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created contact.
|
||||
*/
|
||||
public function store(StoreContactRequest $request): ContactResource|JsonResponse
|
||||
{
|
||||
try {
|
||||
$contact = $this->contactRepository->create($request->validated());
|
||||
return new ContactResource($contact);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error creating contact: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'data' => $request->validated(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la création du contact.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified contact.
|
||||
*/
|
||||
public function show(string $id): ContactResource|JsonResponse
|
||||
{
|
||||
try {
|
||||
$contact = $this->contactRepository->find($id);
|
||||
|
||||
if (!$contact) {
|
||||
return response()->json([
|
||||
'message' => 'Contact non trouvé.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
return new ContactResource($contact);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error fetching contact: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'contact_id' => $id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la récupération du contact.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified contact.
|
||||
*/
|
||||
public function update(UpdateContactRequest $request, string $id): ContactResource|JsonResponse
|
||||
{
|
||||
try {
|
||||
$updated = $this->contactRepository->update($id, $request->validated());
|
||||
|
||||
if (!$updated) {
|
||||
return response()->json([
|
||||
'message' => 'Contact non trouvé ou échec de la mise à jour.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
$contact = $this->contactRepository->find($id);
|
||||
return new ContactResource($contact);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error updating contact: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'contact_id' => $id,
|
||||
'data' => $request->validated(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la mise à jour du contact.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified contact.
|
||||
*/
|
||||
public function destroy(string $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
$deleted = $this->contactRepository->delete($id);
|
||||
|
||||
if (!$deleted) {
|
||||
return response()->json([
|
||||
'message' => 'Contact non trouvé ou échec de la suppression.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Contact supprimé avec succès.',
|
||||
], 200);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error deleting contact: ' . $e->getMessage(), [
|
||||
'exception' => $e,
|
||||
'trace' => $e->getTraceAsString(),
|
||||
'contact_id' => $id,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Une erreur est survenue lors de la suppression du contact.',
|
||||
'error' => config('app.debug') ? $e->getMessage() : null,
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
40
thanasoft-back/app/Http/Requests/StoreClientGroupRequest.php
Normal file
40
thanasoft-back/app/Http/Requests/StoreClientGroupRequest.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreClientGroupRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|max:191|unique:client_groups,name',
|
||||
'description' => 'nullable|string',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'name.required' => 'Le nom du groupe est obligatoire.',
|
||||
'name.string' => 'Le nom du groupe doit être une chaîne de caractères.',
|
||||
'name.max' => 'Le nom du groupe ne peut pas dépasser 191 caractères.',
|
||||
'name.unique' => 'Un groupe avec ce nom existe déjà.',
|
||||
'description.string' => 'La description doit être une chaîne de caractères.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreClientLocationRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'client_id' => 'required|exists:clients,id',
|
||||
'name' => 'nullable|string|max:191',
|
||||
'address_line1' => 'nullable|string|max:255',
|
||||
'address_line2' => 'nullable|string|max:255',
|
||||
'postal_code' => 'nullable|string|max:20',
|
||||
'city' => 'nullable|string|max:191',
|
||||
'country_code' => 'nullable|string|size:2',
|
||||
'gps_lat' => 'nullable|numeric|between:-90,90',
|
||||
'gps_lng' => 'nullable|numeric|between:-180,180',
|
||||
'is_default' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'client_id.required' => 'Le client est obligatoire.',
|
||||
'client_id.exists' => 'Le client sélectionné n\'existe pas.',
|
||||
'name.max' => 'Le nom ne peut pas dépasser 191 caractères.',
|
||||
'address_line1.max' => 'L\'adresse ne peut pas dépasser 255 caractères.',
|
||||
'address_line2.max' => 'Le complément d\'adresse ne peut pas dépasser 255 caractères.',
|
||||
'postal_code.max' => 'Le code postal ne peut pas dépasser 20 caractères.',
|
||||
'city.max' => 'La ville ne peut pas dépasser 191 caractères.',
|
||||
'country_code.size' => 'Le code pays doit contenir 2 caractères.',
|
||||
'gps_lat.numeric' => 'La latitude doit être un nombre.',
|
||||
'gps_lat.between' => 'La latitude doit être comprise entre -90 et 90.',
|
||||
'gps_lng.numeric' => 'La longitude doit être un nombre.',
|
||||
'gps_lng.between' => 'La longitude doit être comprise entre -180 et 180.',
|
||||
'is_default.boolean' => 'Le statut par défaut doit être vrai ou faux.',
|
||||
];
|
||||
}
|
||||
|
||||
public function withValidator($validator)
|
||||
{
|
||||
$validator->after(function ($validator) {
|
||||
if (empty($this->address_line1) && empty($this->postal_code) && empty($this->city)) {
|
||||
$validator->errors()->add(
|
||||
'general',
|
||||
'Au moins un champ d\'adresse (adresse, code postal ou ville) doit être renseigné.'
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
70
thanasoft-back/app/Http/Requests/StoreClientRequest.php
Normal file
70
thanasoft-back/app/Http/Requests/StoreClientRequest.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreClientRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
|
||||
'type' => 'required|in:pompes_funebres,famille,entreprise,collectivite,autre',
|
||||
'name' => 'required|string|max:255',
|
||||
'vat_number' => 'nullable|string|max:32',
|
||||
'siret' => 'nullable|string|max:20',
|
||||
'email' => 'nullable|email|max:191',
|
||||
'phone' => 'nullable|string|max:50',
|
||||
'billing_address_line1' => 'nullable|string|max:255',
|
||||
'billing_address_line2' => 'nullable|string|max:255',
|
||||
'billing_postal_code' => 'nullable|string|max:20',
|
||||
'billing_city' => 'nullable|string|max:191',
|
||||
'billing_country_code' => 'nullable|string|size:2',
|
||||
'group_id' => 'nullable|exists:client_groups,id',
|
||||
'notes' => 'nullable|string',
|
||||
'is_active' => 'boolean',
|
||||
'default_tva_rate_id' => 'nullable|exists:tva_rates,id',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'company_id.required' => 'La société est obligatoire.',
|
||||
'company_id.exists' => 'La société sélectionnée n\'existe pas.',
|
||||
'type.required' => 'Le type de client est obligatoire.',
|
||||
'type.in' => 'Le type de client sélectionné est invalide.',
|
||||
'name.required' => 'Le nom du client est obligatoire.',
|
||||
'name.string' => 'Le nom du client doit être une chaîne de caractères.',
|
||||
'name.max' => 'Le nom du client ne peut pas dépasser 255 caractères.',
|
||||
'vat_number.max' => 'Le numéro de TVA ne peut pas dépasser 32 caractères.',
|
||||
'siret.max' => 'Le SIRET ne peut pas dépasser 20 caractères.',
|
||||
'email.email' => 'L\'adresse email doit être valide.',
|
||||
'email.max' => 'L\'adresse email ne peut pas dépasser 191 caractères.',
|
||||
'phone.max' => 'Le téléphone ne peut pas dépasser 50 caractères.',
|
||||
'billing_address_line1.max' => 'L\'adresse ne peut pas dépasser 255 caractères.',
|
||||
'billing_address_line2.max' => 'Le complément d\'adresse ne peut pas dépasser 255 caractères.',
|
||||
'billing_postal_code.max' => 'Le code postal ne peut pas dépasser 20 caractères.',
|
||||
'billing_city.max' => 'La ville ne peut pas dépasser 191 caractères.',
|
||||
'billing_country_code.size' => 'Le code pays doit contenir 2 caractères.',
|
||||
'group_id.exists' => 'Le groupe de clients sélectionné n\'existe pas.',
|
||||
'is_active.boolean' => 'Le statut actif doit être vrai ou faux.',
|
||||
'default_tva_rate_id.exists' => 'Le taux de TVA sélectionné n\'existe pas.',
|
||||
];
|
||||
}
|
||||
}
|
||||
28
thanasoft-back/app/Http/Requests/StoreContactRequest.php
Normal file
28
thanasoft-back/app/Http/Requests/StoreContactRequest.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreContactRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateClientGroupRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$clientGroupId = $this->route('client_group') ? $this->route('client_group')->id : $this->route('id');
|
||||
|
||||
return [
|
||||
'name' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:191',
|
||||
Rule::unique('client_groups', 'name')->ignore($clientGroupId)
|
||||
],
|
||||
'description' => 'nullable|string',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'name.required' => 'Le nom du groupe est obligatoire.',
|
||||
'name.string' => 'Le nom du groupe doit être une chaîne de caractères.',
|
||||
'name.max' => 'Le nom du groupe ne peut pas dépasser 191 caractères.',
|
||||
'name.unique' => 'Un groupe avec ce nom existe déjà.',
|
||||
'description.string' => 'La description doit être une chaîne de caractères.',
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateClientLocationRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'client_id' => 'required|exists:clients,id',
|
||||
'name' => 'nullable|string|max:191',
|
||||
'address_line1' => 'nullable|string|max:255',
|
||||
'address_line2' => 'nullable|string|max:255',
|
||||
'postal_code' => 'nullable|string|max:20',
|
||||
'city' => 'nullable|string|max:191',
|
||||
'country_code' => 'nullable|string|size:2',
|
||||
'gps_lat' => 'nullable|numeric|between:-90,90',
|
||||
'gps_lng' => 'nullable|numeric|between:-180,180',
|
||||
'is_default' => 'boolean',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'client_id.required' => 'Le client est obligatoire.',
|
||||
'client_id.exists' => 'Le client sélectionné n\'existe pas.',
|
||||
'name.max' => 'Le nom ne peut pas dépasser 191 caractères.',
|
||||
'address_line1.max' => 'L\'adresse ne peut pas dépasser 255 caractères.',
|
||||
'address_line2.max' => 'Le complément d\'adresse ne peut pas dépasser 255 caractères.',
|
||||
'postal_code.max' => 'Le code postal ne peut pas dépasser 20 caractères.',
|
||||
'city.max' => 'La ville ne peut pas dépasser 191 caractères.',
|
||||
'country_code.size' => 'Le code pays doit contenir 2 caractères.',
|
||||
'gps_lat.numeric' => 'La latitude doit être un nombre.',
|
||||
'gps_lat.between' => 'La latitude doit être comprise entre -90 et 90.',
|
||||
'gps_lng.numeric' => 'La longitude doit être un nombre.',
|
||||
'gps_lng.between' => 'La longitude doit être comprise entre -180 et 180.',
|
||||
'is_default.boolean' => 'Le statut par défaut doit être vrai ou faux.',
|
||||
];
|
||||
}
|
||||
}
|
||||
68
thanasoft-back/app/Http/Requests/UpdateClientRequest.php
Normal file
68
thanasoft-back/app/Http/Requests/UpdateClientRequest.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateClientRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'type' => 'required|in:pompes_funebres,famille,entreprise,collectivite,autre',
|
||||
'name' => 'required|string|max:255',
|
||||
'vat_number' => 'nullable|string|max:32',
|
||||
'siret' => 'nullable|string|max:20',
|
||||
'email' => 'nullable|email|max:191',
|
||||
'phone' => 'nullable|string|max:50',
|
||||
'billing_address_line1' => 'nullable|string|max:255',
|
||||
'billing_address_line2' => 'nullable|string|max:255',
|
||||
'billing_postal_code' => 'nullable|string|max:20',
|
||||
'billing_city' => 'nullable|string|max:191',
|
||||
'billing_country_code' => 'nullable|string|size:2',
|
||||
'group_id' => 'nullable|exists:client_groups,id',
|
||||
'notes' => 'nullable|string',
|
||||
'is_active' => 'boolean',
|
||||
'default_tva_rate_id' => 'nullable|exists:tva_rates,id',
|
||||
];
|
||||
}
|
||||
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'company_id.required' => 'La société est obligatoire.',
|
||||
'company_id.exists' => 'La société sélectionnée n\'existe pas.',
|
||||
'type.required' => 'Le type de client est obligatoire.',
|
||||
'type.in' => 'Le type de client sélectionné est invalide.',
|
||||
'name.required' => 'Le nom du client est obligatoire.',
|
||||
'name.string' => 'Le nom du client doit être une chaîne de caractères.',
|
||||
'name.max' => 'Le nom du client ne peut pas dépasser 255 caractères.',
|
||||
'vat_number.max' => 'Le numéro de TVA ne peut pas dépasser 32 caractères.',
|
||||
'siret.max' => 'Le SIRET ne peut pas dépasser 20 caractères.',
|
||||
'email.email' => 'L\'adresse email doit être valide.',
|
||||
'email.max' => 'L\'adresse email ne peut pas dépasser 191 caractères.',
|
||||
'phone.max' => 'Le téléphone ne peut pas dépasser 50 caractères.',
|
||||
'billing_address_line1.max' => 'L\'adresse ne peut pas dépasser 255 caractères.',
|
||||
'billing_address_line2.max' => 'Le complément d\'adresse ne peut pas dépasser 255 caractères.',
|
||||
'billing_postal_code.max' => 'Le code postal ne peut pas dépasser 20 caractères.',
|
||||
'billing_city.max' => 'La ville ne peut pas dépasser 191 caractères.',
|
||||
'billing_country_code.size' => 'Le code pays doit contenir 2 caractères.',
|
||||
'group_id.exists' => 'Le groupe de clients sélectionné n\'existe pas.',
|
||||
'is_active.boolean' => 'Le statut actif doit être vrai ou faux.',
|
||||
'default_tva_rate_id.exists' => 'Le taux de TVA sélectionné n\'existe pas.',
|
||||
];
|
||||
}
|
||||
}
|
||||
28
thanasoft-back/app/Http/Requests/UpdateContactRequest.php
Normal file
28
thanasoft-back/app/Http/Requests/UpdateContactRequest.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateContactRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class ClientCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @return array<int|string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'data' => $this->collection,
|
||||
'meta' => [
|
||||
'total' => $this->total(),
|
||||
'per_page' => $this->perPage(),
|
||||
'current_page' => $this->currentPage(),
|
||||
'last_page' => $this->lastPage(),
|
||||
'from' => $this->firstItem(),
|
||||
'to' => $this->lastItem(),
|
||||
'stats' => [
|
||||
'active' => $this->collection->where('is_active', true)->count(),
|
||||
'inactive' => $this->collection->where('is_active', false)->count(),
|
||||
'by_type' => $this->collection->groupBy('type')->map->count(),
|
||||
],
|
||||
],
|
||||
'links' => [
|
||||
'first' => $this->url(1),
|
||||
'last' => $this->url($this->lastPage()),
|
||||
'prev' => $this->previousPageUrl(),
|
||||
'next' => $this->nextPageUrl(),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function with(Request $request): array
|
||||
{
|
||||
return [
|
||||
'status' => 'success',
|
||||
'message' => 'Clients récupérés avec succès',
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class ClientGroupCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @return array<int|string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'data' => $this->collection,
|
||||
'meta' => [
|
||||
'total' => $this->total(),
|
||||
'per_page' => $this->perPage(),
|
||||
'current_page' => $this->currentPage(),
|
||||
'last_page' => $this->lastPage(),
|
||||
'from' => $this->firstItem(),
|
||||
'to' => $this->lastItem(),
|
||||
],
|
||||
'links' => [
|
||||
'first' => $this->url(1),
|
||||
'last' => $this->url($this->lastPage()),
|
||||
'prev' => $this->previousPageUrl(),
|
||||
'next' => $this->nextPageUrl(),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function with(Request $request): array
|
||||
{
|
||||
return [
|
||||
'status' => 'success',
|
||||
'message' => 'Groupes de clients récupérés avec succès',
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\Client;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class ClientGroupResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'description' => $this->description ?? null,
|
||||
'created_at' => $this->created_at?->format('Y-m-d H:i:s'),
|
||||
'updated_at' => $this->updated_at?->format('Y-m-d H:i:s'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\Client;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class ClientLocationCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @return array<int|string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'data' => $this->collection,
|
||||
'meta' => [
|
||||
'total' => $this->total(),
|
||||
'per_page' => $this->perPage(),
|
||||
'current_page' => $this->currentPage(),
|
||||
'last_page' => $this->lastPage(),
|
||||
'from' => $this->firstItem(),
|
||||
'to' => $this->lastItem(),
|
||||
'stats' => [
|
||||
'default_locations' => $this->collection->where('is_default', true)->count(),
|
||||
'with_gps' => $this->collection->filter(fn($location) => $location->gps_lat && $location->gps_lng)->count(),
|
||||
],
|
||||
],
|
||||
'links' => [
|
||||
'first' => $this->url(1),
|
||||
'last' => $this->url($this->lastPage()),
|
||||
'prev' => $this->previousPageUrl(),
|
||||
'next' => $this->nextPageUrl(),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function with(Request $request): array
|
||||
{
|
||||
return [
|
||||
'status' => 'success',
|
||||
'message' => 'Lieux clients récupérés avec succès',
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\Client;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class ClientLocationResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
||||
62
thanasoft-back/app/Http/Resources/Client/ClientResource.php
Normal file
62
thanasoft-back/app/Http/Resources/Client/ClientResource.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\Client;
|
||||
|
||||
use App\Http\Resources\Contact\ContactResource;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class ClientResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
//'company_id' => $this->company_id,
|
||||
'type' => $this->type,
|
||||
'type_label' => $this->getTypeLabel(),
|
||||
'name' => $this->name,
|
||||
'vat_number' => $this->vat_number,
|
||||
'siret' => $this->siret,
|
||||
'email' => $this->email,
|
||||
'phone' => $this->phone,
|
||||
'billing_address' => [
|
||||
'line1' => $this->billing_address_line1,
|
||||
'line2' => $this->billing_address_line2,
|
||||
'postal_code' => $this->billing_postal_code,
|
||||
'city' => $this->billing_city,
|
||||
'country_code' => $this->billing_country_code,
|
||||
'full_address' => $this->billing_address,
|
||||
],
|
||||
'group_id' => $this->group_id,
|
||||
'notes' => $this->notes,
|
||||
'is_active' => $this->is_active,
|
||||
// 'default_tva_rate_id' => $this->default_tva_rate_id,
|
||||
'created_at' => $this->created_at?->format('Y-m-d H:i:s'),
|
||||
'updated_at' => $this->updated_at?->format('Y-m-d H:i:s'),
|
||||
|
||||
// Counts
|
||||
'contacts_count' => $this->whenCounted('contacts'),
|
||||
'locations_count' => $this->whenCounted('locations'),
|
||||
// 'interventions_count' => $this->whenCounted('interventions'),
|
||||
// 'quotes_count' => $this->whenCounted('quotes'),
|
||||
// 'invoices_count' => $this->whenCounted('invoices'),
|
||||
|
||||
// Relations
|
||||
// 'company' => new CompanyResource($this->whenLoaded('company')),
|
||||
'group' => new ClientGroupResource($this->whenLoaded('group')),
|
||||
// 'default_tva_rate' => new TvaRateResource($this->whenLoaded('defaultTvaRate')),
|
||||
'contacts' => ContactResource::collection($this->whenLoaded('contacts')),
|
||||
'locations' => ClientLocationResource::collection($this->whenLoaded('locations')),
|
||||
// 'price_lists' => PriceListResource::collection($this->whenLoaded('priceLists')),
|
||||
// 'interventions' => InterventionResource::collection($this->whenLoaded('interventions')),
|
||||
// 'quotes' => QuoteResource::collection($this->whenLoaded('quotes')),
|
||||
// 'invoices' => InvoiceResource::collection($this->whenLoaded('invoices')),
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\Contact;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class ContactCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @return array<int|string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return [
|
||||
'data' => $this->collection,
|
||||
'meta' => [
|
||||
'total' => $this->total(),
|
||||
'per_page' => $this->perPage(),
|
||||
'current_page' => $this->currentPage(),
|
||||
'last_page' => $this->lastPage(),
|
||||
'from' => $this->firstItem(),
|
||||
'to' => $this->lastItem(),
|
||||
],
|
||||
'links' => [
|
||||
'first' => $this->url(1),
|
||||
'last' => $this->url($this->lastPage()),
|
||||
'prev' => $this->previousPageUrl(),
|
||||
'next' => $this->nextPageUrl(),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function with(Request $request): array
|
||||
{
|
||||
return [
|
||||
'status' => 'success',
|
||||
'message' => 'Contacts récupérés avec succès',
|
||||
];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources\Contact;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class ContactResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return parent::toArray($request);
|
||||
}
|
||||
}
|
||||
60
thanasoft-back/app/Models/Client.php
Normal file
60
thanasoft-back/app/Models/Client.php
Normal file
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Client extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'type',
|
||||
'name',
|
||||
'vat_number',
|
||||
'siret',
|
||||
'email',
|
||||
'phone',
|
||||
'billing_address_line1',
|
||||
'billing_address_line2',
|
||||
'billing_postal_code',
|
||||
'billing_city',
|
||||
'billing_country_code',
|
||||
'group_id',
|
||||
'notes',
|
||||
'is_active',
|
||||
'default_tva_rate_id',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the human-readable label for the client type.
|
||||
*/
|
||||
public function getTypeLabel(): string
|
||||
{
|
||||
return match($this->type) {
|
||||
'pompes_funebres' => 'Pompes funèbres',
|
||||
'famille' => 'Famille',
|
||||
'entreprise' => 'Entreprise',
|
||||
'collectivite' => 'Collectivité',
|
||||
'autre' => 'Autre',
|
||||
default => $this->type,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full billing address as a string.
|
||||
*/
|
||||
public function getBillingAddressAttribute(): ?string
|
||||
{
|
||||
$parts = array_filter([
|
||||
$this->billing_address_line1,
|
||||
$this->billing_address_line2,
|
||||
$this->billing_postal_code ? $this->billing_postal_code . ' ' . $this->billing_city : $this->billing_city,
|
||||
$this->billing_country_code,
|
||||
]);
|
||||
|
||||
return !empty($parts) ? implode(', ', $parts) : null;
|
||||
}
|
||||
}
|
||||
10
thanasoft-back/app/Models/ClientContact.php
Normal file
10
thanasoft-back/app/Models/ClientContact.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ClientContact extends Model
|
||||
{
|
||||
//
|
||||
}
|
||||
13
thanasoft-back/app/Models/ClientGroup.php
Normal file
13
thanasoft-back/app/Models/ClientGroup.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ClientGroup extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'description',
|
||||
];
|
||||
}
|
||||
27
thanasoft-back/app/Models/ClientLocation.php
Normal file
27
thanasoft-back/app/Models/ClientLocation.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ClientLocation extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'client_id',
|
||||
'name',
|
||||
'address_line1',
|
||||
'address_line2',
|
||||
'postal_code',
|
||||
'city',
|
||||
'country_code',
|
||||
'gps_lat',
|
||||
'gps_lng',
|
||||
'is_default',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'is_default' => 'boolean',
|
||||
'gps_lat' => 'decimal:8',
|
||||
'gps_lng' => 'decimal:8',
|
||||
];
|
||||
}
|
||||
23
thanasoft-back/app/Models/Contact.php
Normal file
23
thanasoft-back/app/Models/Contact.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Contact extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'first_name',
|
||||
'last_name',
|
||||
'email',
|
||||
'phone',
|
||||
'mobile',
|
||||
'position',
|
||||
'notes',
|
||||
'is_primary',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'is_primary' => 'boolean',
|
||||
];
|
||||
}
|
||||
@ -11,7 +11,26 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
//
|
||||
// Repository interface to implementation bindings
|
||||
$this->app->bind(\App\Repositories\ClientRepositoryInterface::class, function ($app) {
|
||||
return new \App\Repositories\ClientRepository($app->make(\App\Models\Client::class));
|
||||
});
|
||||
|
||||
$this->app->bind(\App\Repositories\ClientGroupRepositoryInterface::class, function ($app) {
|
||||
return new \App\Repositories\ClientGroupRepository($app->make(\App\Models\ClientGroup::class));
|
||||
});
|
||||
|
||||
$this->app->bind(\App\Repositories\ClientContactRepositoryInterface::class, function ($app) {
|
||||
return new \App\Repositories\ClientContactRepository($app->make(\App\Models\ClientContact::class));
|
||||
});
|
||||
|
||||
$this->app->bind(\App\Repositories\ContactRepositoryInterface::class, function ($app) {
|
||||
return new \App\Repositories\ContactRepository($app->make(\App\Models\Contact::class));
|
||||
});
|
||||
|
||||
$this->app->bind(\App\Repositories\ClientLocationRepositoryInterface::class, function ($app) {
|
||||
return new \App\Repositories\ClientLocationRepository($app->make(\App\Models\ClientLocation::class));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
72
thanasoft-back/app/Repositories/BaseRepository.php
Normal file
72
thanasoft-back/app/Repositories/BaseRepository.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Base repository implementation using Eloquent models.
|
||||
*/
|
||||
class BaseRepository implements BaseRepositoryInterface
|
||||
{
|
||||
public function __construct(protected Model $model)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, string> $columns
|
||||
* @return Collection<int, Model>
|
||||
*/
|
||||
public function all(array $columns = ['*']): Collection
|
||||
{
|
||||
return $this->model->newQuery()->get($columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $id
|
||||
* @param array<int, string> $columns
|
||||
*/
|
||||
public function find(int|string $id, array $columns = ['*']): ?Model
|
||||
{
|
||||
return $this->model->newQuery()->find($id, $columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $attributes
|
||||
*/
|
||||
public function create(array $attributes): Model
|
||||
{
|
||||
// Uses mass assignment; ensure $fillable is set on the model
|
||||
return $this->model->newQuery()->create($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $id
|
||||
* @param array<string, mixed> $attributes
|
||||
*/
|
||||
public function update(int|string $id, array $attributes): bool
|
||||
{
|
||||
$instance = $this->find($id);
|
||||
if (! $instance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $instance->fill($attributes)->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|string $id
|
||||
*/
|
||||
public function delete(int|string $id): bool
|
||||
{
|
||||
$instance = $this->find($id);
|
||||
if (! $instance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) $instance->delete();
|
||||
}
|
||||
}
|
||||
52
thanasoft-back/app/Repositories/BaseRepositoryInterface.php
Normal file
52
thanasoft-back/app/Repositories/BaseRepositoryInterface.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Base repository contract for simple CRUD operations using Eloquent models.
|
||||
*/
|
||||
interface BaseRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* Get all records.
|
||||
*
|
||||
* @param array<int, string> $columns
|
||||
* @return Collection<int, Model>
|
||||
*/
|
||||
public function all(array $columns = ['*']): Collection;
|
||||
|
||||
/**
|
||||
* Find a record by its primary key.
|
||||
*
|
||||
* @param int|string $id
|
||||
* @param array<int, string> $columns
|
||||
*/
|
||||
public function find(int|string $id, array $columns = ['*']): ?Model;
|
||||
|
||||
/**
|
||||
* Create a new record with the given attributes.
|
||||
*
|
||||
* @param array<string, mixed> $attributes
|
||||
*/
|
||||
public function create(array $attributes): Model;
|
||||
|
||||
/**
|
||||
* Update an existing record by id with the given attributes.
|
||||
*
|
||||
* @param int|string $id
|
||||
* @param array<string, mixed> $attributes
|
||||
*/
|
||||
public function update(int|string $id, array $attributes): bool;
|
||||
|
||||
/**
|
||||
* Delete a record by its primary key.
|
||||
*
|
||||
* @param int|string $id
|
||||
*/
|
||||
public function delete(int|string $id): bool;
|
||||
}
|
||||
15
thanasoft-back/app/Repositories/ClientContactRepository.php
Normal file
15
thanasoft-back/app/Repositories/ClientContactRepository.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Models\ClientContact;
|
||||
|
||||
class ClientContactRepository extends BaseRepository implements ClientContactRepositoryInterface
|
||||
{
|
||||
public function __construct(ClientContact $model)
|
||||
{
|
||||
parent::__construct($model);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
interface ClientContactRepositoryInterface extends BaseRepositoryInterface
|
||||
{
|
||||
// Add ClientContact-specific methods here later if needed
|
||||
}
|
||||
15
thanasoft-back/app/Repositories/ClientGroupRepository.php
Normal file
15
thanasoft-back/app/Repositories/ClientGroupRepository.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Models\ClientGroup;
|
||||
|
||||
class ClientGroupRepository extends BaseRepository implements ClientGroupRepositoryInterface
|
||||
{
|
||||
public function __construct(ClientGroup $model)
|
||||
{
|
||||
parent::__construct($model);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
interface ClientGroupRepositoryInterface extends BaseRepositoryInterface
|
||||
{
|
||||
// Add ClientGroup-specific methods here later if needed
|
||||
}
|
||||
15
thanasoft-back/app/Repositories/ClientLocationRepository.php
Normal file
15
thanasoft-back/app/Repositories/ClientLocationRepository.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Models\ClientLocation;
|
||||
|
||||
class ClientLocationRepository extends BaseRepository implements ClientLocationRepositoryInterface
|
||||
{
|
||||
public function __construct(ClientLocation $model)
|
||||
{
|
||||
parent::__construct($model);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
interface ClientLocationRepositoryInterface extends BaseRepositoryInterface
|
||||
{
|
||||
// Add ClientLocation-specific methods here later if needed
|
||||
}
|
||||
15
thanasoft-back/app/Repositories/ClientRepository.php
Normal file
15
thanasoft-back/app/Repositories/ClientRepository.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Models\Client;
|
||||
|
||||
class ClientRepository extends BaseRepository implements ClientRepositoryInterface
|
||||
{
|
||||
public function __construct(Client $model)
|
||||
{
|
||||
parent::__construct($model);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
interface ClientRepositoryInterface extends BaseRepositoryInterface
|
||||
{
|
||||
// Add Client-specific methods here later if needed
|
||||
}
|
||||
15
thanasoft-back/app/Repositories/ContactRepository.php
Normal file
15
thanasoft-back/app/Repositories/ContactRepository.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
use App\Models\Contact;
|
||||
|
||||
class ContactRepository extends BaseRepository implements ContactRepositoryInterface
|
||||
{
|
||||
public function __construct(Contact $model)
|
||||
{
|
||||
parent::__construct($model);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repositories;
|
||||
|
||||
interface ContactRepositoryInterface extends BaseRepositoryInterface
|
||||
{
|
||||
// Add Contact-specific methods here later if needed
|
||||
}
|
||||
@ -12,7 +12,7 @@ return Application::configure(basePath: dirname(__DIR__))
|
||||
health: '/up',
|
||||
)
|
||||
->withMiddleware(function (Middleware $middleware): void {
|
||||
//
|
||||
$middleware->statefulApi();
|
||||
})
|
||||
->withExceptions(function (Exceptions $exceptions): void {
|
||||
//
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('personal_access_tokens', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->morphs('tokenable');
|
||||
$table->text('name');
|
||||
$table->string('token', 64)->unique();
|
||||
$table->text('abilities')->nullable();
|
||||
$table->timestamp('last_used_at')->nullable();
|
||||
$table->timestamp('expires_at')->nullable()->index();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('personal_access_tokens');
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('client_groups', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name', 191)->unique();
|
||||
$table->text('description')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('client_groups');
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('clients', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->enum('type', [
|
||||
'pompes_funebres',
|
||||
'famille',
|
||||
'entreprise',
|
||||
'collectivite',
|
||||
'autre'
|
||||
])->default('pompes_funebres');
|
||||
$table->string('name', 255);
|
||||
$table->string('vat_number', 32)->nullable();
|
||||
$table->string('siret', 20)->nullable();
|
||||
$table->string('email', 191)->nullable();
|
||||
$table->string('phone', 50)->nullable();
|
||||
$table->string('billing_address_line1', 255)->nullable();
|
||||
$table->string('billing_address_line2', 255)->nullable();
|
||||
$table->string('billing_postal_code', 20)->nullable();
|
||||
$table->string('billing_city', 191)->nullable();
|
||||
$table->char('billing_country_code', 2)->default('FR');
|
||||
$table->foreignId('group_id')->nullable()->constrained('client_groups')->onDelete('set null');
|
||||
$table->text('notes')->nullable();
|
||||
$table->boolean('is_active')->default(true);
|
||||
//$table->foreignId('default_tva_rate_id')->nullable()->constrained('tva_rates')->onDelete('set null');
|
||||
$table->timestamps();
|
||||
|
||||
$table->index(['group_id']);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('clients');
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('contacts', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('contacts');
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('client_locations', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('client_id')->constrained()->onDelete('cascade');
|
||||
$table->string('name', 191)->nullable();
|
||||
$table->string('address_line1', 255)->nullable();
|
||||
$table->string('address_line2', 255)->nullable();
|
||||
$table->string('postal_code', 20)->nullable();
|
||||
$table->string('city', 191)->nullable();
|
||||
$table->char('country_code', 2)->default('FR');
|
||||
$table->double('gps_lat')->nullable();
|
||||
$table->double('gps_lng')->nullable();
|
||||
$table->boolean('is_default')->default(false);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('client_locations');
|
||||
}
|
||||
};
|
||||
@ -2,6 +2,10 @@
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use App\Http\Controllers\Api\AuthController;
|
||||
use App\Http\Controllers\Api\ClientController;
|
||||
use App\Http\Controllers\Api\ClientGroupController;
|
||||
use App\Http\Controllers\Api\ClientLocationController;
|
||||
use App\Http\Controllers\Api\ContactController;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@ -25,3 +29,14 @@ Route::prefix('auth')->group(function () {
|
||||
Route::post('/logout-all', [AuthController::class, 'logoutAll']);
|
||||
});
|
||||
});
|
||||
|
||||
// Protected API routes
|
||||
Route::middleware('auth:sanctum')->group(function () {
|
||||
// Client management
|
||||
Route::apiResource('clients', ClientController::class);
|
||||
Route::apiResource('client-groups', ClientGroupController::class);
|
||||
Route::apiResource('client-locations', ClientLocationController::class);
|
||||
|
||||
// Contact management
|
||||
Route::apiResource('contacts', ContactController::class);
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user