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
61 changes: 56 additions & 5 deletions app/Http/Controllers/ChamadoController.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,16 +130,18 @@ public function store(ChamadoRequest $request, Fila $fila)
# na criação não precisa
#$request->validate(JSONForms::buildRules($request, $fila));

$extras = $this->normalizeExtrasForStorage($request->extras, $fila);

# transaction para não ter problema de inconsistência do DB
$chamado = \DB::transaction(function () use ($request, $fila) {
$chamado = \DB::transaction(function () use ($request, $fila, $extras) {
$chamado = new Chamado;
$chamado->nro = Chamado::obterProximoNumero();
$chamado->fila_id = $fila->id;
$chamado->assunto = $request->assunto;
$chamado->status = 'Triagem';

$chamado->descricao = $request->descricao;
$chamado->extras = json_encode($request->extras);
$chamado->extras = json_encode($extras);

// vamos salvar sem evento pois o autor ainda não está cadastrado
$chamado->saveQuietly();
Expand Down Expand Up @@ -338,6 +340,7 @@ private function grava(Chamado $chamado, Request $request)
{
$atualizacao = [];
$novo_valor = [];
$extras_request = $this->normalizeExtrasForStorage($request->extras, $chamado->fila);

# assunto
if ($chamado->assunto != $request->assunto && !empty($request->assunto)) {
Expand All @@ -356,11 +359,10 @@ private function grava(Chamado $chamado, Request $request)
}

# formulario (extras)
if ($chamado->extras != json_encode($request->extras) && !empty($request->extras)) {
if ($chamado->extras != json_encode($extras_request) && !empty($extras_request)) {
/* guardando os dados antigos em log para auditoria */
Log::info(' - Edição de chamado - Usuário: ' . \Auth::user()->codpes . ' - ' . \Auth::user()->name . ' - Id Chamado: ' . $chamado->id . ' - Extras antigo: ' . $chamado->extras . ' - Novo extras: ' . json_encode($request->extras));
Log::info(' - Edição de chamado - Usuário: ' . \Auth::user()->codpes . ' - ' . \Auth::user()->name . ' - Id Chamado: ' . $chamado->id . ' - Extras antigo: ' . $chamado->extras . ' - Novo extras: ' . json_encode($extras_request));
$extras_chamados = json_decode($chamado->extras, true);
$extras_request = $request->extras;
/* se não for um chamado novo */
$atualiza_extras = false;
if ($chamado->extras != "null") {
Expand Down Expand Up @@ -417,6 +419,55 @@ private function grava(Chamado $chamado, Request $request)
return $chamado;
}

private function normalizeExtrasForStorage($extras, Fila $fila)
{
if (!is_array($extras)) {
return $extras;
}

$template = json_decode($fila->template);
if (!$template) {
return $extras;
}

foreach ($template as $key => $field) {
if (!isset($field->type) || $field->type !== 'date') {
continue;
}

if (!array_key_exists($key, $extras)) {
continue;
}

$extras[$key] = $this->normalizeDateToStorage($extras[$key]);
}

return $extras;
}

private function normalizeDateToStorage($value)
{
if (!is_string($value) || trim($value) === '') {
return $value;
}

$value = trim($value);

if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
return $value;
}

if (preg_match('/^\d{2}\/\d{2}\/\d{4}$/', $value)) {
try {
return \Carbon\Carbon::createFromFormat('d/m/Y', $value)->format('Y-m-d');
} catch (\Exception $e) {
return $value;
}
}

return $value;
}

/**
* adiciona atendentes. Pode ser mais de um
*
Expand Down
64 changes: 64 additions & 0 deletions app/Utils/JSONForms.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,24 @@

class JSONForms
{
private static function formatDateToBrazilian($value)
{
if (empty($value) || !is_string($value)) {
return $value;
}

if (preg_match('/^\d{2}\/\d{2}\/\d{4}$/', $value)) {
return $value;
}

if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
[$year, $month, $day] = explode('-', $value);
return $day . '/' . $month . '/' . $year;
}

return $value;
}

/**
* Valida os campos do formulário
*
Expand Down Expand Up @@ -59,6 +77,52 @@ protected static function JSON2Form($template, $data, $perfil)
$fieldInput = $fieldInput ->required();
}

$input[] = $fieldInput;
break;
case 'date':
$dateValue = self::formatDateToBrazilian($value);
if (empty($dateValue)) {
$dateValue = date('d/m/Y');
}

$fieldInput = html()->text("extras[$key]", $dateValue)
->class('form-control datepicker date-mask')
->attribute('placeholder', 'dd/mm/aaaa')
->attribute('maxlength', '10')
->attribute('inputmode', 'numeric')
->attribute('autocomplete', 'off');

if (isset($json->validate) && strpos($json->validate, 'required') !== false) {
$fieldInput = $fieldInput->required();
}

$input[] = $fieldInput;
break;
case 'text':
$fieldInput = html()->text("extras[$key]", $value)->class('form-control');

if (isset($json->validate) && strpos($json->validate, 'required') !== false) {
$fieldInput = $fieldInput->required();
}

$input[] = $fieldInput;
break;
case 'number':
$fieldInput = html()->number("extras[$key]", $value)->class('form-control');

if (isset($json->validate) && strpos($json->validate, 'required') !== false) {
$fieldInput = $fieldInput->required();
}

$input[] = $fieldInput;
break;
case 'textarea':
$fieldInput = html()->textarea("extras[$key]", $value)->class('form-control')->rows(3);

if (isset($json->validate) && strpos($json->validate, 'required') !== false) {
$fieldInput = $fieldInput ->required();
}

$input[] = $fieldInput;
break;

Expand Down
17 changes: 17 additions & 0 deletions public/js/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,20 @@ function mudarCampoInputTextarea(campo) {
});
}
}

/* @autor uspdev/alecosta 09/04/2026
* Aplica máscara de data no formato dd/mm/aaaa.
*/
function aplicarMascaraData() {
$('.date-mask').each(function () {
$(this).on('input', function () {
var valor = $(this).val().replace(/\D/g, '').slice(0, 8);
if (valor.length > 4) {
valor = valor.replace(/(\d{2})(\d{2})(\d{1,4})/, '$1/$2/$3');
} else if (valor.length > 2) {
valor = valor.replace(/(\d{2})(\d{1,2})/, '$1/$2');
}
$(this).val(valor);
});
});
}
1 change: 1 addition & 0 deletions resources/views/chamados/create.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class="fas fa-times-circle"></i> Cancelar</button>
* Ao carregar a página ordena todos os campos caixa de seleção adicionados na fila
*/
$(document).ready(function() {
aplicarMascaraData();
// Pega todos os campos extras que são caixa de seleção
$('select[name^="extras"]').each(function () {
var nameField = $(this).prop('name');
Expand Down
5 changes: 4 additions & 1 deletion resources/views/chamados/show/dados-formulario.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
<span class="text-muted">{{ $val->label }}:</span>
@switch($val->type)
@case('date')
<span>{{ Carbon\Carbon::parse($extras->$field)->format('d/m/Y') ?? '' }}</span>
@php
$dateValue = !empty($extras->$field) ? Carbon\Carbon::parse($extras->$field) : null;
@endphp
<span>{{ $dateValue ? ucfirst($dateValue->locale('pt_BR')->translatedFormat('l')) . ', ' . $dateValue->format('d/m/Y') : '' }}</span>
@break
@default
@php
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ function mostraModal() {
* Ao carregar a página ordena todos os campos caixa de seleção adicionados na fila
*/
$(document).ready(function() {
aplicarMascaraData();
// Pega todos os campos extras que são caixa de seleção
$('select[name^="extras"]').each(function () {
var nameField = $(this).prop('name');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
<span class="text-muted">{{ $val->label }}:</span>
@switch($val->type)
@case('date')
<span>{{ Carbon\Carbon::parse($extras->$field)->format('d/m/Y') ?? '' }}</span>
@php
$dateValue = !empty($extras->$field) ? Carbon\Carbon::parse($extras->$field) : null;
@endphp
<span>{{ $dateValue ? ucfirst($dateValue->locale('pt_BR')->translatedFormat('l')) . ', ' . $dateValue->format('d/m/Y') : '' }}</span>
@break
@default
<span>{{ $extras->$field ?? '' }}</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
@case('type')
<select class="form-control col-9" name="new[{{ $field }}]">
<option value='text'>Texto</option>
<option value='textarea'>Caixa de texto</option>
<option value='select'>Caixa de Seleção</option>
<option value='date'>Data</option>
<option value='number'>Número</option>
Expand Down
1 change: 1 addition & 0 deletions resources/views/filas/template.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
@case('type')
<select class="form-control" name="template[{{ $tkey }}][{{ $field }}]" onchange="javascript: mudarCampoInputTextarea(this.name);">
<option value='text' {{ $tvalue[$field] == 'text' ? 'selected' : '' }}>Texto</option>
<option value='textarea' {{ $tvalue[$field] == 'textarea' ? 'selected' : '' }}>Caixa de texto</option>
<option value='select' {{ $tvalue[$field] == 'select' ? 'selected' : '' }}>Caixa de Seleção</option>
<option value='date' {{ $tvalue[$field] == 'date' ? 'selected' : '' }}>Data</option>
<option value='number' {{ $tvalue[$field] == 'number' ? 'selected' : '' }}>Número</option>
Expand Down
53 changes: 53 additions & 0 deletions tests/Unit/JSONFormsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,24 @@ public function testGenerateFormTemplate()
$this->assertStringContainsString("extras[predio]", $form[0][1]->toHtml());
}

public function testGenerateFormTextFieldRendersTextInput()
{
$template = json_encode($this->template);
$fila = Fila::factory()->make(['template' => $template]);
$form = JSONForms::generateForm($fila);
$this->assertStringContainsString('type="text"', $form[0][1]->toHtml());
}

public function testGenerateFormTextareaFieldRendersTextarea()
{
$tmp = $this->template;
$tmp["predio"]["type"] = "textarea";
$template = json_encode($tmp);
$fila = Fila::factory()->make(['template' => $template]);
$form = JSONForms::generateForm($fila);
$this->assertStringContainsString("<textarea", $form[0][1]->toHtml());
}

public function testGenerateFormChamado()
{
$template = json_encode($this->template);
Expand Down Expand Up @@ -128,6 +146,41 @@ public function testGenerateFormSelected()
$this->assertStringContainsString('selected">Admin', $form[0][1]->toHtml());
}

public function testGenerateFormDateFieldUsesMask()
{
$tmp = $this->template;
$tmp["predio"]["type"] = "date";
$template = json_encode($tmp);
$fila = Fila::factory()->make(['template' => $template]);
$form = JSONForms::generateForm($fila);
$this->assertStringContainsString('class="form-control datepicker date-mask"', $form[0][1]->toHtml());
}

public function testGenerateFormDateFieldUsesCurrentDateByDefault()
{
$tmp = $this->template;
$tmp["predio"]["type"] = "date";
$template = json_encode($tmp);
$fila = Fila::factory()->make(['template' => $template]);
$form = JSONForms::generateForm($fila);
$this->assertStringContainsString('value="' . date('d/m/Y') . '"', $form[0][1]->toHtml());
}

public function testGenerateFormDateFieldFormatsValue()
{
$tmp = $this->template;
$tmp["predio"]["type"] = "date";
$template = json_encode($tmp);
$fila = Fila::factory()->create(['template' => $template]);
$chamado = Chamado::factory()->make([
'fila_id' => $fila->id,
'extras' => '{"predio": "2026-04-09"}'
]);

$form = JSONForms::generateForm($fila, $chamado);
$this->assertStringContainsString('value="09/04/2026"', $form[0][1]->toHtml());
}

public function testGenerateFormHelp()
{
$tmp = $this->template;
Expand Down