Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 65 additions & 47 deletions Controller/NewServicioAT.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
use FacturaScripts\Dinamic\Model\MaquinaAT;
use FacturaScripts\Dinamic\Model\RoleAccess;
use FacturaScripts\Dinamic\Model\ServicioAT;
use Throwable;

/**
* Description of NewServicioAT
Expand Down Expand Up @@ -123,10 +124,6 @@ public function privateCore(&$response, $user, $permissions)
}

switch ($action) {
case 'checkDuplicateCustomer':
$data = $this->checkDuplicateCustomerAction();
break;

case 'findCustomer':
$data = $this->findCustomerAction();
break;
Expand Down Expand Up @@ -164,34 +161,6 @@ public function privateCore(&$response, $user, $permissions)
}
}

protected function checkDuplicateCustomerAction(): array
{
$wheres = [];
$name = $this->request->get('name', '');
$cifnif = $this->request->get('cifnif', '');

if (false === empty($name)) {
$wheres[] = 'LOWER(nombre) = ' . $this->dataBase->var2str(strtolower($name));
$wheres[] = 'LOWER(razonsocial) = ' . $this->dataBase->var2str(strtolower($name));
}

if (false === empty($cifnif)) {
$wheres[] = 'LOWER(cifnif) = ' . $this->dataBase->var2str(strtolower($cifnif));
}

if (empty($wheres)) {
return ['checkDuplicateCustomer' => false];
}

$sql = 'SELECT codcliente'
. ' FROM clientes'
. ' WHERE ' . implode(' OR ', $wheres);

return count($this->dataBase->select($sql)) > 0
? ['checkDuplicateCustomer' => true]
: ['checkDuplicateCustomer' => false];
}

protected function checkMachine(): bool
{
if (empty($this->idmaquina)) {
Expand Down Expand Up @@ -311,10 +280,33 @@ protected function saveNewCustomerAction(): array
return ['saveNewCustomer' => false];
}

$name = trim($this->request->get('name', ''));
if ($name === '') {
Tools::log()->warning('invalid-request');
return ['saveNewCustomer' => false];
}

// si el cifnif ya existe en otro cliente avisamos, pero permitimos crearlo igualmente
$cifnif = trim($this->request->get('cifnif', ''));
$confirmed = $this->request->get('cifnif_confirmed', '0') === '1';
if ($cifnif !== '' && false === $confirmed) {
$duplicated = $this->findCustomersByCifnif($cifnif);
if (false === empty($duplicated)) {
return [
'saveNewCustomer' => false,
'duplicatedCifnif' => true,
'duplicatedCifnifMessage' => Tools::trans('duplicated-cifnif-customer', [
'%cifnif%' => $cifnif,
'%customers%' => implode(', ', $duplicated)
]),
];
}
}

// creamos el cliente
$customer = new Cliente();
$customer->nombre = $this->request->get('name');
$customer->cifnif = $this->request->get('cifnif', '');
$customer->nombre = $name;
$customer->cifnif = $cifnif;
$customer->email = $this->request->get('email');
$customer->telefono1 = $this->request->get('phone1');
$customer->telefono2 = $this->request->get('phone2');
Expand All @@ -324,20 +316,34 @@ protected function saveNewCustomerAction(): array
$customer = $resultExtension;
}

if (false === $customer->save()) {
Tools::log()->error('save-error');
return ['saveNewCustomer' => false];
}
$this->dataBase->beginTransaction();
try {
if (false === $customer->save()) {
$this->dataBase->rollback();
Tools::log()->error('save-error');
return ['saveNewCustomer' => false];
}

// modificamos la dirección
foreach ($customer->getAddresses() as $address) {
$address->direccion = $this->request->get('address');
$address->codpostal = $this->request->get('zip');
$address->ciudad = $this->request->get('city');
$address->provincia = $this->request->get('province');
$address->codpais = $this->request->get('country');
$address->save();
break;
// modificamos la dirección
foreach ($customer->getAddresses() as $address) {
$address->direccion = $this->request->get('address');
$address->codpostal = $this->request->get('zip');
$address->ciudad = $this->request->get('city');
$address->provincia = $this->request->get('province');
$address->codpais = $this->request->get('country');
if (false === $address->save()) {
$this->dataBase->rollback();
Tools::log()->error('save-error');
return ['saveNewCustomer' => false];
}
break;
}

$this->dataBase->commit();
} catch (Throwable $e) {
$this->dataBase->rollback();
Tools::log()->error($e->getMessage());
return ['saveNewCustomer' => false];
}

return [
Expand All @@ -346,6 +352,18 @@ protected function saveNewCustomerAction(): array
];
}

/** Devuelve los clientes que ya tienen este cifnif, como 'código - nombre'. */
private function findCustomersByCifnif(string $cifnif): array
{
$names = [];
$where = [Where::eq('cifnif', $cifnif)];
foreach (Cliente::all($where, ['LOWER(nombre)' => 'ASC'], 0, 5) as $customer) {
$names[] = $customer->codcliente . ' - ' . $customer->nombre;
}

return $names;
}

protected function saveNewMachineAction(): array
{
if (false === $this->user->can('EditMaquinaAT', 'update')) {
Expand Down
173 changes: 173 additions & 0 deletions Test/main/NewServicioAtTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<?php
/**
* This file is part of Servicios plugin for FacturaScripts
* Copyright (C) 2020-2025 Carlos Garcia Gomez <carlos@facturascripts.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

namespace FacturaScripts\Test\Plugins;

use FacturaScripts\Core\Base\ControllerPermissions;
use FacturaScripts\Core\Request;
use FacturaScripts\Core\Response;
use FacturaScripts\Dinamic\Model\Cliente;
use FacturaScripts\Dinamic\Model\Page;
use FacturaScripts\Dinamic\Model\User;
use FacturaScripts\Plugins\Servicios\Controller\NewServicioAT;
use FacturaScripts\Test\Traits\DefaultSettingsTrait;
use FacturaScripts\Test\Traits\LogErrorsTrait;
use FacturaScripts\Test\Traits\RandomDataTrait;
use PHPUnit\Framework\TestCase;

final class NewServicioAtTest extends TestCase
{
use DefaultSettingsTrait;
use LogErrorsTrait;
use RandomDataTrait;

public static function setUpBeforeClass(): void
{
self::setDefaultSettings();

// la página NewServicioAT se registra normalmente al desplegar el plugin;
// la creamos aquí si el entorno de test no la tiene ya instalada
$page = new Page();
if (false === $page->load('NewServicioAT')) {
$page->name = 'NewServicioAT';
$page->title = 'NewServicioAT';
$page->menu = 'sales';
$page->showonmenu = false;
$page->save();
}
}

public function testSaveNewCustomerCreatesCustomer(): void
{
$user = $this->getRandomUser();
$user->admin = true;
$this->assertTrue($user->save());

$codcliente = null;
try {
$data = $this->saveNewCustomer($user, [
'name' => 'Cliente nuevo test',
'cifnif' => '',
'address' => 'Calle Test 1',
]);

$this->assertTrue($data['saveNewCustomer'] ?? false);
$this->assertArrayNotHasKey('duplicatedCifnif', $data);

$codcliente = $data['codcliente'];
$customer = new Cliente();
$this->assertTrue($customer->load($codcliente));
$this->assertEquals('Cliente nuevo test', $customer->nombre);
} finally {
if ($codcliente !== null) {
$customer = new Cliente();
if ($customer->load($codcliente)) {
$this->assertTrue($customer->delete());
}
}
$this->assertTrue($user->delete());
}
}

public function testSaveNewCustomerRejectsEmptyName(): void
{
$user = $this->getRandomUser();
$user->admin = true;
$this->assertTrue($user->save());

try {
$data = $this->saveNewCustomer($user, [
'name' => ' ',
'cifnif' => '',
]);

$this->assertFalse($data['saveNewCustomer'] ?? true);
$this->assertArrayNotHasKey('codcliente', $data);
} finally {
$this->assertTrue($user->delete());
}
}

public function testSaveNewCustomerDetectsDuplicatedCifnif(): void
{
$user = $this->getRandomUser();
$user->admin = true;
$this->assertTrue($user->save());

$existing = $this->getRandomCustomer();
$existing->cifnif = 'B' . mt_rand(1, 999999);
$this->assertTrue($existing->save());

try {
// sin confirmar, con un cifnif ya usado, no debe crear el cliente
$data = $this->saveNewCustomer($user, [
'name' => 'Cliente duplicado test',
'cifnif' => $existing->cifnif,
'cifnif_confirmed' => '0',
]);

$this->assertFalse($data['saveNewCustomer'] ?? true);
$this->assertTrue($data['duplicatedCifnif'] ?? false);
$this->assertStringContainsString($existing->cifnif, $data['duplicatedCifnifMessage']);

// confirmando, sí debe crear el cliente aunque el cifnif esté duplicado
$data = $this->saveNewCustomer($user, [
'name' => 'Cliente duplicado test',
'cifnif' => $existing->cifnif,
'cifnif_confirmed' => '1',
]);

$this->assertTrue($data['saveNewCustomer'] ?? false);
$this->assertArrayNotHasKey('duplicatedCifnif', $data);

$newCustomer = new Cliente();
$this->assertTrue($newCustomer->load($data['codcliente']));
$this->assertEquals($existing->cifnif, $newCustomer->cifnif);

$this->assertTrue($newCustomer->delete());
} finally {
$this->assertTrue($existing->delete());
$this->assertTrue($user->delete());
}
}

protected function tearDown(): void
{
$this->logErrors();
}

private function saveNewCustomer(User $user, array $request): array
{
$controller = new NewServicioAT('NewServicioAT', '/NewServicioAT');
$controller->request = new Request([
'request' => array_merge([
'action' => 'saveNewCustomer',
'ajax' => true,
], $request),
]);

$permissions = new ControllerPermissions();
$permissions->set(true, 99, true, true);

$response = new Response();
$controller->privateCore($response, $user, $permissions);

return json_decode($response->getContent(), true) ?? [];
}
}
Loading