Implement duplicate contract code validation with user confirmation
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Models\Contract;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Validator;
|
||||
use Carbon\Carbon;
|
||||
@@ -96,6 +97,31 @@ class ContractRequest extends FormRequest
|
||||
public function withValidator(Validator $validator)
|
||||
{
|
||||
$validator->after(function ($validator) {
|
||||
if ($this->filled('code') && $this->filled('supply_type')) {
|
||||
$contractId = $this->route('id');
|
||||
$existingContract = Contract::query()
|
||||
->with('client:id,name')
|
||||
->where('code', $this->input('code'))
|
||||
->where('supply_type', $this->input('supply_type'))
|
||||
->when($contractId, fn ($query) => $query->where('id', '!=', $contractId))
|
||||
->first();
|
||||
|
||||
if ($existingContract && ! $this->boolean('confirm_duplicate')) {
|
||||
$supplyType = strtoupper($this->input('supply_type'));
|
||||
$clientName = $existingContract->client?->name;
|
||||
$message = "Já existe um contrato {$supplyType} com este código";
|
||||
|
||||
if ($clientName) {
|
||||
$message .= " associado ao cliente {$clientName}";
|
||||
}
|
||||
|
||||
$validator->errors()->add(
|
||||
'duplicate_code',
|
||||
$message . '. Confirme apenas se se trata de uma mudança de titularidade.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (! $this->user()?->can('view_contract_summary')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -635,5 +635,39 @@
|
||||
applyColor('previous_supplier_select');
|
||||
});
|
||||
});
|
||||
|
||||
const duplicateCodeMessage = @json($errors->first('duplicate_code'));
|
||||
if (duplicateCodeMessage) {
|
||||
const form = document.querySelector('form');
|
||||
const submitConfirmed = () => {
|
||||
let confirmation = form.querySelector('input[name="confirm_duplicate"]');
|
||||
if (!confirmation) {
|
||||
confirmation = document.createElement('input');
|
||||
confirmation.type = 'hidden';
|
||||
confirmation.name = 'confirm_duplicate';
|
||||
form.appendChild(confirmation);
|
||||
}
|
||||
confirmation.value = '1';
|
||||
form.submit();
|
||||
};
|
||||
|
||||
if (window.Swal) {
|
||||
Swal.fire({
|
||||
title: 'CPE/CUI já existente',
|
||||
text: duplicateCodeMessage,
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Aceitar e gravar',
|
||||
cancelButtonText: 'Cancelar',
|
||||
reverseButtons: true
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
submitConfirmed();
|
||||
}
|
||||
});
|
||||
} else if (window.confirm(`${duplicateCodeMessage}\n\nDeseja continuar?`)) {
|
||||
submitConfirmed();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@endsection
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Models\Contract;
|
||||
use App\Services\ContractService;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Tests\Support\IsolatedDatabaseTestCase;
|
||||
|
||||
@@ -15,7 +16,38 @@ class ContractPersistenceTest extends IsolatedDatabaseTestCase
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
Schema::table('contracts', fn (Blueprint $table) => $table->decimal('go_ki')->nullable());
|
||||
Schema::table('contracts', function (Blueprint $table) {
|
||||
$table->decimal('go_ki')->nullable();
|
||||
$table->string('code')->nullable();
|
||||
$table->string('supply_type')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
public function test_duplicate_supply_code_requires_explicit_confirmation(): void
|
||||
{
|
||||
$user = $this->authenticate();
|
||||
Contract::create([
|
||||
'client_id' => 1,
|
||||
'code' => 'CPE-123',
|
||||
'supply_type' => 'cpe',
|
||||
]);
|
||||
|
||||
$request = ContractRequest::create('/contract', 'POST', [
|
||||
'code' => 'CPE-123',
|
||||
'supply_type' => 'cpe',
|
||||
]);
|
||||
$request->setUserResolver(fn () => $user);
|
||||
$validator = Validator::make($request->all(), []);
|
||||
$request->withValidator($validator);
|
||||
|
||||
$this->assertFalse($validator->passes());
|
||||
$this->assertArrayHasKey('duplicate_code', $validator->errors()->messages());
|
||||
|
||||
$request->merge(['confirm_duplicate' => '1']);
|
||||
$confirmedValidator = Validator::make($request->all(), []);
|
||||
$request->withValidator($confirmedValidator);
|
||||
|
||||
$this->assertTrue($confirmedValidator->passes());
|
||||
}
|
||||
|
||||
public function test_update_persists_chargeback_and_deducts_it_from_profit(): void
|
||||
|
||||
Reference in New Issue
Block a user