Pular para conteúdo

Investigação - Task NH-96

Data: 30/10/2025 Tipo: Análise Técnica Profunda Status: ✅ Concluída


📋 Sumário Executivo

Problema Identificado

A coluna "Kg Cortado" na tela de listagem de ordens de serviço (http://localhost:8000/servico/listagem-ordem-servico) está sempre mostrando 0,000, mesmo para ordens de serviço finalizadas.

Objetivo da Investigação

Entender a origem dos dados do campo "Kg Cortado" e identificar por que ele está sempre zerado.


🎯 Descrição do Problema

Contexto

  • URL: http://localhost:8000/servico/listagem-ordem-servico
  • Coluna Afetada: "Kg Cortado"
  • Comportamento Atual: Sempre exibe 0,000
  • Comportamento Esperado: Deveria exibir o peso (em quilogramas) do material cortado

Evidências Visuais

As imagens dos artefatos mostraram claramente: - tasks/2025-10-30_14-25.png: Tela de listagem com coluna "Kg Cortado" destacada - tasks/ac3f6fa4-710d-4451-a51a-3041573e70cc.png: Visão de produção mostrando o mesmo problema


🔍 Análise Técnica Completa

1. Camada de Apresentação (View)

Arquivo: src/Nelmetais.SGE.WebApp/Areas/Servico/Views/OrdemServico/Index.cshtml

Linha 146: Define o cabeçalho da coluna

<th class="align-middle">Kg Cortado</th>

Linha 174: Renderiza o valor da coluna

<td class="align-middle">@item.Quantidade?.ToString("N3")</td>

Análise: A view está corretamente configurada para exibir o campo Quantidade do ViewModel com formatação numérica de 3 casas decimais.


2. Camada de ViewModel

Arquivo: src/Nelmetais.SGE.WebApp/Areas/Servico/ViewModels/OrdemServicoIndexItemViewModel.cs

Linha 18: Propriedade que armazena o peso cortado

public decimal? Quantidade { get; set; }

Análise: O ViewModel possui uma propriedade nullable Quantidade do tipo decimal, apropriada para armazenar valores monetários ou quantidades precisas.


3. Camada de Controller (Lógica de Negócio)

Arquivo: src/Nelmetais.SGE.WebApp/Areas/Servico/Controllers/OrdemServicoController.cs

3.1 Método Index (POST) - Linha 78-96

[HttpPost("listagem-ordem-servico")]
[AuthorizeCustom(PermissaoTypeEnum.OrdemServico, PermissaoValueEnum.Listar)]
public async Task<IActionResult> Index(OrdemServicoIndexViewModel viewModel)
{
    if (ModelState.IsValid)
    {
        var filtro = _mapper.Map<OrdemServicoFiltroDto>(viewModel);

        var itens = await _ordemServicoItemRepository.ObterOrdemServicoPorFiltro(filtro);

        viewModel.Itens = await MapperOrdemServicoItem(itens, viewModel.SituacaoFaturado);

        ModelState.Clear();
    }

    await PopularListasDropDownFiltro(viewModel);

    return View(viewModel);
}

3.2 Método MapperOrdemServicoItem - Linha 299-361

private async Task<List<OrdemServicoIndexItemViewModel>> MapperOrdemServicoItem(
    List<OrdemServicoItem>? itens,
    bool? filtroFaturado)
{
    var lista = new List<OrdemServicoIndexItemViewModel>();

    if (itens == null || !itens.Any())
        return lista;

    var tipoPedidoAnalises = new List<int>() { (int)TipoPedidoAnaliseEnum.CreditoVenda };

    foreach (var i in itens)
    {
        // ... código omitido para brevidade ...

        lista.Add(new OrdemServicoIndexItemViewModel()
        {
            // ... outras propriedades ...
            Quantidade = i.OrdemServicoItemResultado?.Sum(x => x.PesoFinalEmKg),  // ⭐ LINHA CRÍTICA 351
            // ... outras propriedades ...
        });
    }

    return lista;
}

🎯 DESCOBERTA CRÍTICA: - Linha 351: O campo Quantidade (exibido como "Kg Cortado") é calculado como a soma de PesoFinalEmKg de todos os itens em OrdemServicoItemResultado - Se OrdemServicoItemResultado for null ou vazio, o resultado será null (exibido como 0,000)


4. Camada de Modelo de Domínio

4.1 Entidade OrdemServicoItem

Arquivo: src/Nelmetais.SGE.Business/Models/Servico/OrdemServicoItem.cs

Linha 31: Relacionamento com os resultados

public ICollection<OrdemServicoItemResultado>? OrdemServicoItemResultado { get; set; }

4.2 Entidade OrdemServicoItemResultado

Arquivo: src/Nelmetais.SGE.Business/Models/Servico/OrdemServicoItemResultado.cs

Estrutura completa:

public class OrdemServicoItemResultado : BaseEntity
{
    public int OrdemServicoItemId { get; set; }
    public OrdemServicoItem? OrdemServicoItem { get; set; }

    // Dados Originais
    public decimal? QuantidadeOriginal { get; set; }
    public int? ComprimentoOriginalEmMM { get; set; }
    public int? LarguraOriginalEmMM { get; set; }
    public decimal? PesoOriginalEmKg { get; set; }
    public int? UnidadeMedidaOriginalId { get; set; }

    // Dados Finais
    public decimal? QuantidadeFinal { get; set; }
    public int? ComprimentoFinalEmMM { get; set; }
    public int? LarguraFinalEmMM { get; set; }
    public decimal? PesoFinalEmKg { get; set; }  // ⭐ CAMPO FONTE DOS DADOS - Linha 23
    public int? UnidadeMedidaFinalId { get; set; }

    // Dados de Sobra
    public decimal? QuantidadeSobra { get; set; }
    public int? ComprimentoSobraEmMM { get; set; }
    public int? LarguraSobraEmMM { get; set; }
    public decimal? PesoSobraEmKg { get; set; }
    public int? UnidadeMedidaSobraId { get; set; }
    public DestinoSobraOrdemServicoEnum? DestinoSobra { get; set; }
    public OrigemEstoqueOrdemServicoEnum? OrigemEstoque { get; set; }
    public bool? UtilizadaSobra { get; set; }
    public decimal? PesoSucataEmKg { get; set; }
    public string? Observacao { get; set; }
}

Análise: - A entidade OrdemServicoItemResultado representa o resultado de um corte/processamento - O campo PesoFinalEmKg (linha 23) é a fonte do dado exibido como "Kg Cortado" - Cada ordem de serviço pode ter múltiplos resultados (por isso a soma)


5. Camada de Serviço (Regras de Negócio)

Arquivo: src/Nelmetais.SGE.Business/Services/Servico/OrdemServicoItemService.cs

5.1 Método Liberar - Linha 64-90

public async Task Liberar(OrdemServicoItem ordemServicoItem)
{
    var ordemServicoItemDb = await _ordemServicoItemRepository.GetById(ordemServicoItem.Id);

    if (ordemServicoItemDb is null)
    {
        Notify("Item de Ordem de Serviço não encontrado.");
        return;
    }

    if (await ValidarPedidoAnaliseCredito(ordemServicoItem.Id) is false)
    {
        Notify($"O Item de Ordem de Serviço possui pedido com análise de \"{TipoPedidoAnaliseEnum.CreditoVenda.GetDisplayName()}\" pendente.");
        return;
    }

    if (ordemServicoItem.OrdemServicoItemResultado?.Count > 0
        && ValidarItemResultado(ordemServicoItem.OrdemServicoItemResultado) is false)
        return;

    ordemServicoItemDb.OrdemServicoItemResultado = ordemServicoItem.OrdemServicoItemResultado;  // ⭐ LINHA 84
    ordemServicoItemDb.SituacaoLiberado = ordemServicoItem.SituacaoLiberado;
    ordemServicoItemDb.DataLiberado = DateTime.Now;
    ordemServicoItemDb.UsuarioLiberado = _applicationUserService.GetUsuarioId();

    await _ordemServicoItemRepository.Atualizar(ordemServicoItemDb);
}

5.2 Método Finalizar - Linha 92-113

public async Task Finalizar(OrdemServicoItem ordemServicoItem)
{
    var ordemServicoItemDb = await _ordemServicoItemRepository.GetById(ordemServicoItem.Id);

    if (ordemServicoItemDb is null)
    {
        Notify("Item de Ordem de Serviço não encontrado.");
        return;
    }

    if (ordemServicoItem.OrdemServicoItemResultado?.Count > 0
        && ValidarItemResultado(ordemServicoItem.OrdemServicoItemResultado) is false)
        return;

    ordemServicoItemDb.OrdemServicoItemResultado = ordemServicoItem.OrdemServicoItemResultado;  // ⭐ LINHA 106
    ordemServicoItemDb.SituacaoFinalizado = ordemServicoItem.SituacaoFinalizado;
    ordemServicoItemDb.DataFinalizado = DateTime.Now;
    ordemServicoItemDb.UsuarioFinalizado = _applicationUserService.GetUsuarioId();

    await _ordemServicoItemRepository.Atualizar(ordemServicoItemDb);
    await FinalizarOrdemServico(ordemServicoItemDb.OrdemServicoId);
}

Análise: - Os OrdemServicoItemResultado são atribuídos em dois momentos: 1. Quando o usuário Libera uma ordem de serviço (linha 84) 2. Quando o usuário Finaliza uma ordem de serviço (linha 106) - Em ambos os casos, os resultados vêm do parâmetro ordemServicoItem.OrdemServicoItemResultado - Existe validação via ValidarItemResultado() antes de salvar


🐛 Causa Raiz do Problema

Com base na análise técnica completa, o campo "Kg Cortado" está zerado porque uma ou mais das seguintes situações está ocorrendo:

Hipótese 1: Registros Não Criados

Os OrdemServicoItemResultado não estão sendo criados quando o usuário libera ou finaliza a OS.

Possíveis causas: - Formulários de Liberar/Finalizar não possuem interface para inserir os resultados - JavaScript não está criando os objetos de resultado antes do submit - Dados não estão sendo enviados no POST

Hipótese 2: Campo PesoFinalEmKg Não Preenchido

Os OrdemServicoItemResultado estão sendo criados, mas o campo PesoFinalEmKg não está sendo preenchido.

Possíveis causas: - Campo não é obrigatório no formulário - Campo não é visível/editável - Usuário não sabe que precisa preencher - Validação está falhando silenciosamente

Hipótese 3: Problema de Relacionamento (Lazy Loading)

Os registros existem no banco de dados, mas o relacionamento não está sendo carregado corretamente.

Possíveis causas: - Repositório não está fazendo .Include(x => x.OrdemServicoItemResultado) - Lazy loading desabilitado (configuração do DbContext) - Problema de N+1 queries

Hipótese 4: Dados Não Persistidos

Os dados são preenchidos no formulário, mas não estão sendo persistidos no banco.

Possíveis causas: - Transação não é commitada - Erro silencioso durante o save - Model binding não funciona corretamente


🔬 Verificação no Sistema Real

Teste Realizado

  1. Acessou http://localhost:8000/servico/listagem-ordem-servico
  2. Clicou no botão "Buscar" sem filtros
  3. Encontrou registro:
  4. Ordem de Serviço: #1
  5. Item: #1
  6. Status: Finalizada em 22/10/2025 14:36:21
  7. Kg Cortado: 0,000

Conclusão do Teste

  • A OS foi finalizada com sucesso (possui data de finalização)
  • O campo "Kg Cortado" está zerado, confirmando o problema
  • Isso indica que os OrdemServicoItemResultado provavelmente não foram criados ou o campo PesoFinalEmKg está vazio

💡 Plano de Ação Recomendado

Ação 1: Investigar Formulários de Interface ⭐ PRIORITÁRIO

Objetivo: Verificar se o usuário tem como informar o peso final

Arquivos a verificar: - src/Nelmetais.SGE.WebApp/Areas/Servico/Views/OrdemServico/EditLiberar.cshtml - src/Nelmetais.SGE.WebApp/Areas/Servico/Views/OrdemServico/EditFinalizar.cshtml

O que procurar: - Campos para adicionar/editar OrdemServicoItemResultado - Input para PesoFinalEmKg - JavaScript que manipula a collection de resultados - Validação no frontend

Ação 2: Verificar Consulta do Repositório

Objetivo: Confirmar que o relacionamento está sendo carregado

Arquivo: src/Nelmetais.SGE.Data/Repositories/Servico/OrdemServicoItemRepository.cs

Método: ObterOrdemServicoPorFiltro

O que verificar:

// Deve conter algo assim:
.Include(x => x.OrdemServicoItemResultado)

Ação 3: Consulta Direta ao Banco de Dados

Objetivo: Verificar se os registros existem

Query SQL:

-- Verificar se existem resultados para o item #1 da OS #1
SELECT * FROM "OrdemServicoItemResultado" WHERE "OrdemServicoItemId" = 1;

-- Se existirem, verificar se PesoFinalEmKg está preenchido
SELECT
    "Id",
    "OrdemServicoItemId",
    "PesoFinalEmKg",
    "QuantidadeFinal",
    "ComprimentoFinalEmMM",
    "LarguraFinalEmMM"
FROM "OrdemServicoItemResultado"
WHERE "OrdemServicoItemId" = 1;

Ação 4: Verificar ViewModels das Telas de Edição

Objetivo: Confirmar se os ViewModels possuem a propriedade de resultados

Arquivo: src/Nelmetais.SGE.WebApp/Areas/Servico/ViewModels/OrdemServicoItemViewModel.cs

O que verificar:

public ICollection<OrdemServicoItemResultadoViewModel>? OrdemServicoItemResultado { get; set; }

Ação 5: Verificar Mapeamento do AutoMapper

Objetivo: Confirmar que o AutoMapper está mapeando corretamente os resultados

Arquivo: Procurar por CreateMap<OrdemServicoItem, OrdemServicoItemViewModel>()


📊 Diagrama de Fluxo de Dados

┌─────────────────────────────────────────────────────────┐
│ 1. Usuário acessa tela de Liberar/Finalizar OS         │
└────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 2. Usuário preenche dados de resultado?                │
│    - PesoFinalEmKg                                      │
│    - Outras dimensões                                   │
└────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 3. Submit do formulário                                 │
│    POST /servico/liberar-ordem-servico/{id}            │
│    ou POST /servico/finalizar-ordem-servico/{id}       │
└────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 4. Controller recebe OrdemServicoItemViewModel          │
│    com OrdemServicoItemResultado preenchido?           │
└────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 5. AutoMapper mapeia para OrdemServicoItem             │
└────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 6. Service (Liberar/Finalizar) atribui resultados     │
│    ordemServicoItemDb.OrdemServicoItemResultado =      │
│    ordemServicoItem.OrdemServicoItemResultado          │
└────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 7. Repository salva no banco de dados                  │
└────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 8. Listagem consulta com                               │
│    Quantidade = Sum(PesoFinalEmKg)                     │
└─────────────────────────────────────────────────────────┘

❌ PROBLEMA: Em algum ponto deste fluxo, os dados não estão
   sendo criados/preenchidos/persistidos/carregados

🔍 Checklist de Diagnóstico

Frontend

  • [ ] Formulários EditLiberar.cshtml e EditFinalizar.cshtml possuem campos para resultados?
  • [ ] Existe interface de usuário para adicionar múltiplos resultados?
  • [ ] JavaScript está funcionando corretamente?
  • [ ] Model binding está configurado corretamente?

Backend

  • [ ] ViewModel possui propriedade OrdemServicoItemResultado?
  • [ ] AutoMapper está mapeando OrdemServicoItemResultado?
  • [ ] Service está recebendo os resultados preenchidos?
  • [ ] Validação não está bloqueando o save?

Banco de Dados

  • [ ] Tabela OrdemServicoItemResultado existe?
  • [ ] Existem registros para as OS finalizadas?
  • [ ] Campo PesoFinalEmKg está preenchido nos registros?
  • [ ] Foreign key está correta?

Consulta

  • [ ] Repositório faz .Include() do relacionamento?
  • [ ] Query está retornando os resultados?
  • [ ] Lazy loading não está interferindo?
  • [ ] Tracking do EF Core não está causando problema?

📈 Impacto do Problema

Impacto Funcional

  • Severidade: MÉDIA-ALTA
  • Usuários Afetados: Todos que utilizam a funcionalidade de ordens de serviço
  • Funcionalidade Impactada: Não é possível visualizar o peso do material cortado na listagem

Impacto no Negócio

  • Perda de visibilidade sobre produtividade
  • Dificuldade em rastrear consumo de material
  • Impossibilidade de calcular desperdício
  • Relatórios de produção ficam incompletos

📝 Conclusão

O campo "Kg Cortado" na listagem de ordens de serviço representa a soma do peso final (em Kg) de todos os resultados (OrdemServicoItemResultado.PesoFinalEmKg) associados a uma ordem de serviço.

Através desta investigação, foi possível mapear completamente o fluxo de dados desde a interface até o banco de dados, identificando os pontos críticos onde o problema pode estar ocorrendo.

As próximas etapas devem focar em: 1. Verificar se os formulários de Liberar/Finalizar permitem preencher os resultados 2. Consultar o banco de dados para verificar se os registros existem 3. Confirmar que o repositório está carregando o relacionamento corretamente


📎 Referências

Arquivos Analisados

  • src/Nelmetais.SGE.WebApp/Areas/Servico/Views/OrdemServico/Index.cshtml
  • src/Nelmetais.SGE.WebApp/Areas/Servico/Controllers/OrdemServicoController.cs
  • src/Nelmetais.SGE.WebApp/Areas/Servico/ViewModels/OrdemServicoIndexItemViewModel.cs
  • src/Nelmetais.SGE.Business/Models/Servico/OrdemServicoItem.cs
  • src/Nelmetais.SGE.Business/Models/Servico/OrdemServicoItemResultado.cs
  • src/Nelmetais.SGE.Business/Services/Servico/OrdemServicoItemService.cs

Artefatos

  • tasks/task-NH-96.md: Descrição da task
  • tasks/2025-10-30_14-25.png: Screenshot da tela local
  • tasks/ac3f6fa4-710d-4451-a51a-3041573e70cc.png: Screenshot da tela de produção

🎯 RESULTADO DA INVESTIGAÇÃO - CONCLUSÃO

🔍 Causa Raiz Identificada

O campo "Kg Cortado" na listagem de ordens de serviço está sempre zerado devido ao seguinte problema:

❌ PROBLEMA PRINCIPAL: O campo PesoFinalEmKg NÃO ESTÁ PRESENTE nos formulários de Liberar e Finalizar ordens de serviço.

📊 Evidências Coletadas

1. ✅ Arquitetura Funcional

  • Controller: Calcula corretamente Quantidade = Sum(PesoFinalEmKg) (linha 351 de OrdemServicoController.cs)
  • ViewModel: Possui a propriedade PesoFinalEmKg (linha 42 de OrdemServicoItemResultadoViewModel.cs)
  • Repositório: Faz corretamente .Include(x => x.OrdemServicoItemResultado) (linha 24 de OrdemServicoItemRepository.cs)
  • AutoMapper: Configurado corretamente (linha 315 de AutoMapperConfiguration.cs)
  • Service: Atribui corretamente os resultados nos métodos Liberar/Finalizar

2. ❌ Problema no Formulário

Arquivo: src/Nelmetais.SGE.WebApp/Areas/Servico/Views/OrdemServico/Shared/EditPartial.cshtml

Campos PRESENTES na tabela de resultados:

  • Linha 126-129: Origem Armazenamento
  • Linha 132: Quantidade Original
  • Linha 135: Comprimento Original
  • Linha 138: Peso Original
  • Linha 141: Quantidade Final (presente)
  • Linha 144: Comprimento Final (presente)
  • Linha 147: Quantidade Sobra
  • Linha 150: Comprimento Sobra
  • Linha 153-156: Destino Sobra
  • Linha 159: Peso Sucata

Campo AUSENTE:

  • PesoFinalEmKg - Campo que alimenta o "Kg Cortado" na listagem

3. 🗃️ Verificação no Banco de Dados

SELECT "Id", "OrdemServicoItemId", "PesoFinalEmKg", "QuantidadeFinal", "ComprimentoFinalEmMM"
FROM "OrdemServicoItemResultado";

Resultado:

 Id | OrdemServicoItemId | PesoFinalEmKg | QuantidadeFinal | ComprimentoFinalEmMM
----+--------------------+---------------+-----------------+----------------------
  1 |                  1 |               |           4.000 |                    5

O campo PesoFinalEmKg está NULL/vazio porque o usuário nunca teve oportunidade de preenchê-lo.

🎯 Conclusão Final

O problema ocorre porque:

  1. ✅ A arquitetura do sistema está correta (Controller, Service, Repository, ViewModels, AutoMapper)
  2. ❌ O formulário de edição não possui o campo PesoFinalEmKg para o usuário preencher
  3. ❌ Como o usuário não pode preencher o valor, o campo fica NULL no banco
  4. ❌ Quando a listagem calcula Sum(PesoFinalEmKg), o resultado é NULL (exibido como 0,000)

✅ Checklist Final de Diagnóstico

Frontend

  • [x] Formulários EditLiberar.cshtml e EditFinalizar.cshtml possuem campos para resultados? SIM
  • [x] Existe interface de usuário para adicionar múltiplos resultados? SIM
  • [x] JavaScript está funcionando corretamente? SIM
  • [x] Model binding está configurado corretamente? SIM
  • [x] Campo PesoFinalEmKg está presente no formulário? ❌ NÃO - ESTE É O PROBLEMA

Backend

  • [x] ViewModel possui propriedade OrdemServicoItemResultado? SIM
  • [x] AutoMapper está mapeando OrdemServicoItemResultado? SIM
  • [x] Service está recebendo os resultados preenchidos? SIM
  • [x] Validação não está bloqueando o save? NÃO, está OK

Banco de Dados

  • [x] Tabela OrdemServicoItemResultado existe? SIM
  • [x] Existem registros para as OS finalizadas? SIM
  • [x] Campo PesoFinalEmKg está preenchido nos registros? ❌ NÃO - está NULL
  • [x] Foreign key está correta? SIM

Consulta

  • [x] Repositório faz .Include() do relacionamento? SIM
  • [x] Query está retornando os resultados? SIM
  • [x] Lazy loading não está interferindo? NÃO
  • [x] Tracking do EF Core não está causando problema? NÃO

💡 SOLUÇÃO PROPOSTA

Alteração Necessária

Adicionar campo PesoFinalEmKg no formulário EditPartial.cshtml entre os campos "Comprimento (MM) Resultado Serviço" e "Quantidade Posterior Corte".

Implementação

1. Adicionar Coluna no Header da Tabela

Arquivo: src/Nelmetais.SGE.WebApp/Areas/Servico/Views/OrdemServico/Shared/EditPartial.cshtml

Localização: Após linha 114 (após "Comprimento (MM) Resultado Serviço")

<th class="align-middle" style="min-width: 140px">Peso (Kg) Resultado Serviço</th>

2. Adicionar Campo de Input no Body da Tabela

Localização: Após linha 145 (após o input de ComprimentoFinalEmMM)

<td>
    <input class="form-control" asp-for="@Model.OrdemServicoItemResultado[i].PesoFinalEmKg"
           disabled="@(!isEditFinalizar && !isEditLiberar)" />
</td>

Estrutura Completa da Seção "Descrição do Serviço"

Após a implementação, a seção ficará assim:

<th class="align-middle" colspan="3">Descrição do Serviço</th>

Com as seguintes colunas:

  1. Quantidade Resultado Serviço (QuantidadeFinal)
  2. Comprimento (MM) Resultado Serviço (ComprimentoFinalEmMM)
  3. Peso (Kg) Resultado Serviço (PesoFinalEmKg)NOVO CAMPO

Diagrama do Fluxo Corrigido

┌─────────────────────────────────────────────────────────┐
│ 1. Usuário acessa tela de Liberar/Finalizar OS         │
└────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 2. Usuário preenche dados de resultado                 │
│    ✅ PesoFinalEmKg (NOVO CAMPO)                        │
│    - Outras dimensões                                   │
└────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 3. Submit do formulário                                 │
│    POST /servico/liberar-ordem-servico/{id}            │
│    ou POST /servico/finalizar-ordem-servico/{id}       │
└────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 4. Controller recebe OrdemServicoItemViewModel          │
│    ✅ com PesoFinalEmKg preenchido                      │
└────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 5. AutoMapper mapeia para OrdemServicoItem             │
└────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 6. Service (Liberar/Finalizar) atribui resultados     │
│    ordemServicoItemDb.OrdemServicoItemResultado =      │
│    ordemServicoItem.OrdemServicoItemResultado          │
└────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 7. Repository salva no banco de dados                  │
│    ✅ PesoFinalEmKg com valor preenchido                │
└────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 8. Listagem consulta com                               │
│    Quantidade = Sum(PesoFinalEmKg)                     │
│    ✅ EXIBE VALOR CORRETO na coluna "Kg Cortado"        │
└─────────────────────────────────────────────────────────┘

Impacto da Solução

  • Complexidade: BAIXA
  • Risco: MUITO BAIXO
  • Arquivos Afetados: 1 arquivo apenas (EditPartial.cshtml)
  • Necessita Migration: NÃO (campo já existe no banco)
  • Necessita alteração de backend: NÃO (toda infraestrutura já existe)
  • Compatibilidade: TOTAL (não quebra funcionalidades existentes)

Testes Recomendados

Após implementar a solução:

  1. Teste de Liberação:
  2. Acessar tela de Liberar OS
  3. Verificar se o campo "Peso (Kg) Resultado Serviço" está visível
  4. Preencher o campo com um valor (ex: 15.500)
  5. Salvar
  6. Verificar se o valor foi salvo no banco

  7. Teste de Finalização:

  8. Acessar tela de Finalizar OS
  9. Verificar se o campo "Peso (Kg) Resultado Serviço" está visível
  10. Preencher o campo com um valor (ex: 20.750)
  11. Salvar
  12. Verificar se o valor foi salvo no banco

  13. Teste de Listagem:

  14. Acessar tela de listagem de OS
  15. Verificar se a coluna "Kg Cortado" exibe o valor correto (soma dos PesoFinalEmKg)

  16. Teste de Múltiplos Resultados:

  17. Criar uma OS com 2+ linhas de resultado
  18. Preencher PesoFinalEmKg em cada linha (ex: 10.5 e 8.3)
  19. Verificar se a listagem exibe a soma correta (18.800)

Data: 30 de outubro de 2025 Tipo: Investigação Técnica Detalhada Status da Investigação: ✅ CONCLUÍDA - Causa Raiz Identificada Solução: Proposta e Documentada