From 328ce7488f651590044b45cd816d5451b271a87d Mon Sep 17 00:00:00 2001 From: Juan Felipe Zapata Moreno Date: Wed, 28 Jan 2026 22:45:22 -0600 Subject: [PATCH] =?UTF-8?q?feat:=20agregar=20soporte=20para=20b=C3=BAsqued?= =?UTF-8?q?a=20de=20clientes=20por=20n=C3=BAmero=20de=20cliente=20y=20actu?= =?UTF-8?q?alizar=20validaciones=20en=20solicitudes=20de=20venta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/App/ClientController.php | 6 ++++- .../Controllers/App/ClientTierController.php | 16 ++++++------- .../Controllers/App/FacturaDataController.php | 2 +- app/Http/Requests/App/SaleStoreRequest.php | 2 ++ app/Services/ClientTierService.php | 1 + app/Services/SaleService.php | 7 +++++- database/seeders/RoleSeeder.php | 24 +++++++++++++++++-- 7 files changed, 45 insertions(+), 13 deletions(-) diff --git a/app/Http/Controllers/App/ClientController.php b/app/Http/Controllers/App/ClientController.php index bcbdb48..9333220 100644 --- a/app/Http/Controllers/App/ClientController.php +++ b/app/Http/Controllers/App/ClientController.php @@ -24,7 +24,11 @@ public function index(Request $request) $query->with($relations); } - if ($request->has('q') && $request->q) { + if ($request->has('client_number') && $request->client_number) { + $query->where('client_number', $request->client_number); + } + + elseif ($request->has('q') && $request->q) { $query->where(function($q) use ($request) { $q->where('name', 'like', "%{$request->q}%") ->orWhere('email', 'like', "%{$request->q}%") diff --git a/app/Http/Controllers/App/ClientTierController.php b/app/Http/Controllers/App/ClientTierController.php index 84b6708..64a1f1c 100644 --- a/app/Http/Controllers/App/ClientTierController.php +++ b/app/Http/Controllers/App/ClientTierController.php @@ -11,13 +11,13 @@ class ClientTierController extends Controller { /** - * Display a listing of client tiers + * Listar todos los tiers */ public function index() { $tiers = ClientTier::withCount('clients') ->orderBy('min_purchase_amount') - ->get(); + ->paginate(config('app.pagination')); return ApiResponse::OK->response([ 'tiers' => $tiers @@ -25,7 +25,7 @@ public function index() } /** - * Store a newly created tier + * Almacenar un nuevo tier */ public function store(ClientTierStoreRequest $request) { @@ -38,7 +38,7 @@ public function store(ClientTierStoreRequest $request) } /** - * Display the specified tier + * Mostrar un tier específico */ public function show(ClientTier $tier) { @@ -50,7 +50,7 @@ public function show(ClientTier $tier) } /** - * Update the specified tier + * Actualizar un tier existente */ public function update(ClientTierUpdateRequest $request, ClientTier $tier) { @@ -63,7 +63,7 @@ public function update(ClientTierUpdateRequest $request, ClientTier $tier) } /** - * Remove the specified tier (soft delete if has clients, else force delete) + * Eliminar un tier */ public function destroy(ClientTier $tier) { @@ -82,7 +82,7 @@ public function destroy(ClientTier $tier) } /** - * Toggle tier active status + * Activar/Desactivar un tier */ public function toggleActive(ClientTier $tier) { @@ -95,7 +95,7 @@ public function toggleActive(ClientTier $tier) } /** - * Get active tiers only + * Seleccionar tiers activos */ public function active() { diff --git a/app/Http/Controllers/App/FacturaDataController.php b/app/Http/Controllers/App/FacturaDataController.php index 69cd204..a18c31f 100644 --- a/app/Http/Controllers/App/FacturaDataController.php +++ b/app/Http/Controllers/App/FacturaDataController.php @@ -81,7 +81,7 @@ public function store(Request $request, string $invoiceNumber) 'razon_social' => 'required|string|max:255', 'regimen_fiscal' => 'required|string|max:100', 'cp_fiscal' => 'required|string|size:5|regex:/^\d{5}$/', - 'uso_cfdi' => 'required|string|max:10', + 'uso_cfdi' => 'required|string|max:100', ], [ 'rfc.regex' => 'El RFC no tiene un formato válido', 'rfc.size' => 'El RFC debe tener 13 caracteres', diff --git a/app/Http/Requests/App/SaleStoreRequest.php b/app/Http/Requests/App/SaleStoreRequest.php index e79b826..e544085 100644 --- a/app/Http/Requests/App/SaleStoreRequest.php +++ b/app/Http/Requests/App/SaleStoreRequest.php @@ -21,6 +21,8 @@ public function rules(): array { return [ // Datos de la venta + 'client_id' => ['nullable', 'exists:clients,id'], + 'client_number' => ['nullable', 'exists:clients,client_number'], 'user_id' => ['required', 'exists:users,id'], 'subtotal' => ['required', 'numeric', 'min:0'], 'tax' => ['required', 'numeric', 'min:0'], diff --git a/app/Services/ClientTierService.php b/app/Services/ClientTierService.php index 916909c..65ff928 100644 --- a/app/Services/ClientTierService.php +++ b/app/Services/ClientTierService.php @@ -137,6 +137,7 @@ public function getClientStats(Client $client): array 'lifetime_returns' => $client->lifetime_returns, 'net_purchases' => $client->net_purchases, 'total_transactions' => $client->total_transactions, + 'last_purchase_at' => $client->last_purchase_at, 'average_purchase' => $client->total_transactions > 0 ? $client->total_purchases / $client->total_transactions : 0, diff --git a/app/Services/SaleService.php b/app/Services/SaleService.php index d76be7b..e5ae628 100644 --- a/app/Services/SaleService.php +++ b/app/Services/SaleService.php @@ -24,7 +24,12 @@ public function createSale(array $data) { return DB::transaction(function () use ($data) { // Obtener cliente si existe - $client = isset($data['client_id']) ? Client::find($data['client_id']) : null; + $client = null; + if (isset($data['client_id'])) { + $client = Client::find($data['client_id']); + } elseif (isset($data['client_number'])) { + $client = Client::where('client_number', $data['client_number'])->first(); + } // Calcular descuento si el cliente tiene tier $discountPercentage = 0; diff --git a/database/seeders/RoleSeeder.php b/database/seeders/RoleSeeder.php index 7fff133..b60ac51 100644 --- a/database/seeders/RoleSeeder.php +++ b/database/seeders/RoleSeeder.php @@ -129,6 +129,18 @@ public function run(): void $clientDestroy ] = $this->onCRUD('clients', $clientsType, 'api'); + // Permisos de Niveles de Clientes (Tiers) + $clientTiersType = PermissionType::create([ + 'name' => 'Niveles de clientes' + ]); + + [ + $clientTierIndex, + $clientTierCreate, + $clientTierEdit, + $clientTierDestroy + ] = $this->onCRUD('client-tiers', $clientTiersType, 'api'); + // ==================== ROLES ==================== @@ -173,7 +185,11 @@ public function run(): void $clientIndex, $clientCreate, $clientEdit, - $clientDestroy + $clientDestroy, + $clientTierIndex, + $clientTierCreate, + $clientTierEdit, + $clientTierDestroy ); //Operador PDV (solo permisos de operación de caja y ventas) @@ -197,7 +213,11 @@ public function run(): void $inventoryEdit, $inventoryDestroy, // Clientes - $clientIndex, // Buscar clientes + $clientIndex, + $clientTierIndex, + $clientTierCreate, + $clientTierEdit, + $clientTierDestroy ); } }