{*******************************************************************************
Title: T2Ti ERP
Description: Controller do lado Cliente relacionado à tabela [NFE_CABECALHO]

The MIT License

Copyright: Copyright (C) 2017 T2Ti.COM

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

       The author may be contacted at:
           t2ti.com@gmail.com

@author Albert Eije (t2ti.com@gmail.com)
@version 1.0
*******************************************************************************}
unit NfeCabecalhoController;

interface

uses
  Classes, Dialogs, SysUtils, DBClient, DB,  Windows, Forms, Controller, Rtti,
  Atributos,

  Generics.Collections,

  NfeCabecalhoDTO, NfeDetalheDTO,

  SynCommons,          // framework core
  mORMot,              // RESTful server & ORM
  mORMotHttpClient     // HTTP client to a mORMot RESTful server
  ;


type
  TNfeCabecalhoController = class(TController)
  private
    class var FDataSet: TClientDataSet;
  public
    class procedure Consulta(pCampos, pValores: String; pPagina: String);
    class function ConsultaDTO(pId: TId): TNfe_Cabecalho;

    class function Insere(pObjeto: TNfe_Cabecalho): Boolean;
    class function Altera(pObjeto: TNfe_Cabecalho): Boolean;

    class function Exclui(pId: Integer): Boolean;
    class function ExcluiCobranca(pId: Integer): Boolean;
    class function ExcluiReferenciado(pId: Integer): Boolean;
    class function ExcluiEntregaRetirada(pId: Integer): Boolean;
    class function ExcluiTransporte(pId: Integer): Boolean;
    class function ExcluiItem(pId: Integer): Boolean;

    class function GetDataSet: TClientDataSet; override;
    class procedure SetDataSet(pDataSet: TClientDataSet); override;
  end;

implementation

uses
    //
    NfeReferenciadaDTO, NfeEmitenteDTO, NfeLocalEntregaDTO, NfeLocalRetiradaDTO,
    NfeTransporteDTO, NfeFaturaDTO, NfeDuplicataDTO,
    NfeCupomFiscalReferenciadoDTO, NfeDetalheImpostoCofinsDTO, NfeDetalheImpostoIcmsDTO,
    NfeDetalheImpostoPisDTO, NfeDetalheImpostoIiDTO, NfeDetalheImpostoIssqnDTO,
    NfeDetalheImpostoIpiDTO, NfeDeclaracaoImportacaoDTO, NfeImportacaoDetalheDTO,
    NfeDetEspecificoVeiculoDTO, NfeDetEspecificoCombustivelDTO, NfeDetEspecificoMedicamentoDTO,
    NfeDetEspecificoArmamentoDTO, NfeNfReferenciadaDTO, NfeCteReferenciadoDTO,
    NfeProdRuralReferenciadaDTO, NfeTransporteReboqueDTO, NfeTransporteVolumeDTO,
    TributOperacaoFiscalDTO, EmpresaDTO, NfeNumeroDTO, NfeProcessoReferenciadoDTO,
    NfeFormaPagamentoDTO, NfeExportacaoDTO, NfeDestinatarioDTO, NfeConfiguracaoDTO,
    //
    ControleEstoqueController;

class procedure TNfeCabecalhoController.Consulta(pCampos, pValores: String; pPagina: String);
var
  Retorno: TObjectList<TNfe_Cabecalho>;
  RetornoNfe: TNfe_Cabecalho;

  Client: TSQLRest;
  aModel: TSQLModel;
begin
  try
    aModel := TSQLModel.Create(
    [
      TEmpresa,
      TNfe_Transporte_Reboque,
      TNfe_Transporte,
      TNfe_Referenciada,
      TNfe_Prod_Rural_Referenciada,
      TNfe_Processo_Referenciado,
      TNfe_Numero,
      TNfe_Nf_Referenciada,
      TNfe_Local_Retirada,
      TNfe_Local_Entrega,
      TNfe_Importacao_Detalhe,
      TNfe_Forma_Pagamento,
      TNfe_Fatura,
      TNfe_Exportacao,
      TNfe_Emitente,
      TNfe_Duplicata,
      TNfe_Det_Especifico_Veiculo,
      TNfe_Det_Especifico_Medicamento,
      TNfe_Det_Especifico_Combustivel,
      TNfe_Det_Especifico_Armamento,
      TNfe_Detalhe_Imposto_Pis,
      TNfe_Detalhe_Imposto_Issqn,
      TNfe_Detalhe_Imposto_Ipi,
      TNfe_Detalhe_Imposto_Ii,
      TNfe_Detalhe_Imposto_Icms,
      TNfe_Detalhe_Imposto_Cofins,
      TNfe_Detalhe,
      TNfe_Destinatario,
      TNfe_Declaracao_Importacao,
      TNfe_Cupom_Fiscal_Referenciado,
      TNfe_Cte_Referenciado,
      TNfe_Configuracao,
      TNfe_Cabecalho,
      TNfe_Transporte_Volume
    ], 'root');

    Client := TSQLHttpClientWinHTTP.Create('34.230.92.11','888',aModel);

    Retorno := Client.RetrieveList<TNfe_Cabecalho>(pCampos, [pValores]);

    for RetornoNfe in Retorno do
      RetornoNfe.PK := RetornoNfe.GetID;

    if Assigned(Retorno) then
      TratarRetorno<TNfe_Cabecalho>(Retorno);
  finally
  end;
end;

class function TNfeCabecalhoController.ConsultaDTO(pId: TId): TNfe_Cabecalho;
var
  RetornoNfe: TNfe_Cabecalho;
  RetornoDetalhe: TNfe_Detalhe;
  Client: TSQLRest;
  aModel: TSQLModel;
begin
  try
    aModel := TSQLModel.Create(
    [
      TEmpresa,
      TNfe_Transporte_Reboque,
      TNfe_Transporte,
      TNfe_Referenciada,
      TNfe_Prod_Rural_Referenciada,
      TNfe_Processo_Referenciado,
      TNfe_Numero,
      TNfe_Nf_Referenciada,
      TNfe_Local_Retirada,
      TNfe_Local_Entrega,
      TNfe_Importacao_Detalhe,
      TNfe_Forma_Pagamento,
      TNfe_Fatura,
      TNfe_Exportacao,
      TNfe_Emitente,
      TNfe_Duplicata,
      TNfe_Det_Especifico_Veiculo,
      TNfe_Det_Especifico_Medicamento,
      TNfe_Det_Especifico_Combustivel,
      TNfe_Det_Especifico_Armamento,
      TNfe_Detalhe_Imposto_Pis,
      TNfe_Detalhe_Imposto_Issqn,
      TNfe_Detalhe_Imposto_Ipi,
      TNfe_Detalhe_Imposto_Ii,
      TNfe_Detalhe_Imposto_Icms,
      TNfe_Detalhe_Imposto_Cofins,
      TNfe_Detalhe,
      TNfe_Destinatario,
      TNfe_Declaracao_Importacao,
      TNfe_Cupom_Fiscal_Referenciado,
      TNfe_Cte_Referenciado,
      TNfe_Configuracao,
      TNfe_Cabecalho,
      TNfe_Transporte_Volume,
      TTribut_Operacao_Fiscal
    ], 'root');

    Client := TSQLHttpClientWinHTTP.Create('34.230.92.11','888',aModel);

    RetornoNfe := TNfe_Cabecalho.Create;
    Client.Retrieve(pId, RetornoNfe);
    RetornoNfe.PK := pId;

    // Objetos
    RetornoNfe.NfeDestinatarioDTO := TNfe_Destinatario.Create;
    Client.Retrieve('IdNfeCabecalho = ' + IntToStr(pId), RetornoNfe.NfeDestinatarioDTO);

    RetornoNfe.NfeLocalRetiradaDTO := TNfe_Local_Retirada.Create;
    Client.Retrieve('IdNfeCabecalho = ' + IntToStr(pId), RetornoNfe.NfeLocalRetiradaDTO);

    RetornoNfe.NfeLocalEntregaDTO := TNfe_Local_Entrega.Create;
    Client.Retrieve('IdNfeCabecalho = ' + IntToStr(pId), RetornoNfe.NfeLocalEntregaDTO);

    RetornoNfe.NfeFaturaDTO := TNfe_Fatura.Create;
    Client.Retrieve('IdNfeCabecalho = ' + IntToStr(pId), RetornoNfe.NfeFaturaDTO);

    RetornoNfe.NfeTransporteDTO := TNfe_Transporte.Create;
    Client.Retrieve('IdNfeCabecalho = ' + IntToStr(pId), RetornoNfe.NfeTransporteDTO);
    /// EXERCICIO
    ///  Busque as listas vinculadas ao Transporte
    RetornoNfe.NfeTransporteDTO.ListaNfeTransporteReboqueDTO := Client.RetrieveList<TNfe_Transporte_Reboque>('IdNfeTransporte = ?', [pId]);
    RetornoNfe.NfeTransporteDTO.ListaNfeTransporteVolumeDTO := Client.RetrieveList<TNfe_Transporte_Volume>('IdNfeTransporte = ?', [pId]);

    RetornoNfe.TributOperacaoFiscalDTO := TTribut_Operacao_Fiscal.Create;
    Client.Retrieve('Id = ' + IntToStr(RetornoNfe.IdTributOperacaoFiscal), RetornoNfe.TributOperacaoFiscalDTO);

    // Listas
    RetornoNfe.ListaNfeReferenciadaDTO := Client.RetrieveList<TNfe_Referenciada>('IdNfeCabecalho = ?', [pId]);
    RetornoNfe.ListaNfeNfReferenciadaDTO := Client.RetrieveList<TNfe_Nf_Referenciada>('IdNfeCabecalho = ?', [pId]);
    RetornoNfe.ListaNfeProdRuralReferenciadaDTO := Client.RetrieveList<TNfe_Prod_Rural_Referenciada>('IdNfeCabecalho = ?', [pId]);
    RetornoNfe.ListaNfeCteReferenciadoDTO := Client.RetrieveList<TNfe_Cte_Referenciado>('IdNfeCabecalho = ?', [pId]);
    RetornoNfe.ListaNfeCupomFiscalReferenciadoDTO := Client.RetrieveList<TNfe_Cupom_Fiscal_Referenciado>('IdNfeCabecalho = ?', [pId]);

    RetornoNfe.ListaNfeDuplicataDTO := Client.RetrieveList<TNfe_Duplicata>('IdNfeCabecalho = ?', [pId]);

    RetornoNfe.ListaNfeDetalheDTO := Client.RetrieveList<TNfe_Detalhe>('IdNfeCabecalho = ?', [pId]);
    for RetornoDetalhe in RetornoNfe.ListaNfeDetalheDTO do
    begin
      RetornoDetalhe.PK := RetornoDetalhe.Id;

      RetornoDetalhe.NfeDetalheImpostoIcmsDTO := TNfe_Detalhe_Imposto_Icms.Create;
      Client.Retrieve('IdNfeDetalhe = ' + IntToStr(RetornoDetalhe.Id), RetornoDetalhe.NfeDetalheImpostoIcmsDTO);
      //
      RetornoDetalhe.NfeDetalheImpostoIpiDTO := TNfe_Detalhe_Imposto_Ipi.Create;
      Client.Retrieve('IdNfeDetalhe = ' + IntToStr(RetornoDetalhe.Id), RetornoDetalhe.NfeDetalheImpostoIpiDTO);
      //
      RetornoDetalhe.NfeDetalheImpostoIiDTO := TNfe_Detalhe_Imposto_Ii.Create;
      Client.Retrieve('IdNfeDetalhe = ' + IntToStr(RetornoDetalhe.Id), RetornoDetalhe.NfeDetalheImpostoIiDTO);
      //
      RetornoDetalhe.NfeDetalheImpostoIssqnDTO := TNfe_Detalhe_Imposto_Issqn.Create;
      Client.Retrieve('IdNfeDetalhe = ' + IntToStr(RetornoDetalhe.Id), RetornoDetalhe.NfeDetalheImpostoIssqnDTO);
      //
      RetornoDetalhe.NfeDetalheImpostoPisDTO := TNfe_Detalhe_Imposto_Pis.Create;
      Client.Retrieve('IdNfeDetalhe = ' + IntToStr(RetornoDetalhe.Id), RetornoDetalhe.NfeDetalheImpostoPisDTO);
      //
      RetornoDetalhe.NfeDetalheImpostoCofinsDTO := TNfe_Detalhe_Imposto_Cofins.Create;
      Client.Retrieve('IdNfeDetalhe = ' + IntToStr(RetornoDetalhe.Id), RetornoDetalhe.NfeDetalheImpostoCofinsDTO);
    end;


    Result := RetornoNfe;
  finally
  end;
end;

class function TNfeCabecalhoController.Insere(pObjeto: TNfe_Cabecalho): Boolean;
var
  aModel: TSQLModel;
  Client: TSQLRest;
  //
  NfeReferenciada: TNfe_Referenciada;
  NfeNfReferenciada: TNfe_Nf_Referenciada;
  NfeCteReferenciado: TNfe_Cte_Referenciado;
  NfeCupomFiscalReferenciado: TNfe_Cupom_Fiscal_Referenciado;
  NfeRuralReferenciada: TNfe_Prod_Rural_Referenciada;
  NfeTransporteReboque: TNfe_Transporte_Reboque;
  NfeTransporteVolume: TNfe_Transporte_Volume;
  NfeDuplicata: TNfe_Duplicata;
  //
  NfeDetalhe: TNfe_Detalhe;
  NfeDeclaracaoImportacao: TNfe_Declaracao_Importacao;
  NfeImportacaoDetalhe: TNfe_Importacao_Detalhe;
  NfeDetalheEspecificoMedicamento: TNfe_Det_Especifico_Medicamento;
  NfeDetalheEspecificoArmamento: TNfe_Det_Especifico_Armamento;
  //
  NfeReferenciadaEnumerator: TEnumerator<TNfe_Referenciada>;
  NfReferenciadaEnumerator: TEnumerator<TNfe_Nf_Referenciada>;
  NfeRuralReferenciadaEnumerator: TEnumerator<TNfe_Prod_Rural_Referenciada>;
  NfeCteReferenciadoEnumerator: TEnumerator<TNfe_Cte_Referenciado>;
  NfeCupomFiscalReferenciadoEnumerator: TEnumerator<TNfe_Cupom_Fiscal_Referenciado>;
  NfeTransporteReboqueEnumerator: TEnumerator<TNfe_Transporte_Reboque>;
  NfeTransporteVolumeEnumerator: TEnumerator<TNfe_Transporte_Volume>;
  NfeDuplicataEnumerator: TEnumerator<TNfe_Duplicata>;
  //
  NfeDetalheEnumerator: TEnumerator<TNfe_Detalhe>;
  NfeDeclaracaoImportacaoEnumerator: TEnumerator<TNfe_Declaracao_Importacao>;
  NfeDetalheEspecificoMedicamentoEnumerator: TEnumerator<TNfe_Det_Especifico_Medicamento>;
  NfeDetalheEspecificoArmamentoEnumerator: TEnumerator<TNfe_Det_Especifico_Armamento>;
  NfeImportacaoDetalheEnumerator: TEnumerator<TNfe_Importacao_Detalhe>;
begin
  Result := false;
  try
    aModel := TSQLModel.Create(
    [
      TEmpresa,
      TNfe_Transporte_Reboque,
      TNfe_Transporte,
      TNfe_Referenciada,
      TNfe_Prod_Rural_Referenciada,
      TNfe_Processo_Referenciado,
      TNfe_Numero,
      TNfe_Nf_Referenciada,
      TNfe_Local_Retirada,
      TNfe_Local_Entrega,
      TNfe_Importacao_Detalhe,
      TNfe_Forma_Pagamento,
      TNfe_Fatura,
      TNfe_Exportacao,
      TNfe_Emitente,
      TNfe_Duplicata,
      TNfe_Det_Especifico_Veiculo,
      TNfe_Det_Especifico_Medicamento,
      TNfe_Det_Especifico_Combustivel,
      TNfe_Det_Especifico_Armamento,
      TNfe_Detalhe_Imposto_Pis,
      TNfe_Detalhe_Imposto_Issqn,
      TNfe_Detalhe_Imposto_Ipi,
      TNfe_Detalhe_Imposto_Ii,
      TNfe_Detalhe_Imposto_Icms,
      TNfe_Detalhe_Imposto_Cofins,
      TNfe_Detalhe,
      TNfe_Destinatario,
      TNfe_Declaracao_Importacao,
      TNfe_Cupom_Fiscal_Referenciado,
      TNfe_Cte_Referenciado,
      TNfe_Configuracao,
      TNfe_Cabecalho,
      TNfe_Transporte_Volume
    ], 'root');
    Client := TSQLHttpClientWinHTTP.Create('34.230.92.11','888',aModel);

    Client.Add(pObjeto, True);

    { Destinatario }
    pObjeto.NfeDestinatarioDTO := TNfe_Destinatario.Create;
    pObjeto.NfeDestinatarioDTO.IdNfeCabecalho := pObjeto.Id;
    Client.Add(pObjeto.NfeDestinatarioDTO, True);

    { Emitente }
    pObjeto.NfeEmitenteDTO := TNfe_Emitente.Create;
    pObjeto.NfeEmitenteDTO.IdNfeCabecalho := pObjeto.Id;
    Client.Add(pObjeto.NfeEmitenteDTO, True);

    (* Grupo de informação dos documentos referenciados *)
    {NF Referenciada}
    if Assigned(pObjeto.ListaNfeNfReferenciadaDTO) then
    begin
      NfReferenciadaEnumerator := pObjeto.ListaNfeNfReferenciadaDTO.GetEnumerator;
      try
        with NfReferenciadaEnumerator do
        begin
          while MoveNext do
          begin
            NfeNfReferenciada := Current;
            NfeNfReferenciada.IdNfeCabecalho := pObjeto.Id;
            Client.Add(NfeNfReferenciada, True);
          end;
        end;
      finally
        NfReferenciadaEnumerator.Free;
      end;
    end;

    {NF Rural Referenciada}
    if Assigned(pObjeto.ListaNfeProdRuralReferenciadaDTO) then
    begin
      NfeRuralReferenciadaEnumerator := pObjeto.ListaNfeProdRuralReferenciadaDTO.GetEnumerator;
      try
        with NfeRuralReferenciadaEnumerator do
        begin
          while MoveNext do
          begin
            NfeRuralReferenciada := Current;
            NfeRuralReferenciada.IdNfeCabecalho := pObjeto.Id;
            Client.Add(NfeRuralReferenciada, True);
          end;
        end;
      finally
        NfeRuralReferenciadaEnumerator.Free;
      end;
    end;

    {CT-e Referenciado}
    if Assigned(pObjeto.ListaNfeCteReferenciadoDTO) then
    begin
      NfeCteReferenciadoEnumerator := pObjeto.ListaNfeCteReferenciadoDTO.GetEnumerator;
      try
        with NfeCteReferenciadoEnumerator do
        begin
          while MoveNext do
          begin
            NfeCteReferenciado := Current;
            NfeCteReferenciado.IdNfeCabecalho := pObjeto.Id;
            Client.Add(NfeCteReferenciado, True);
          end;
        end;
      finally
        NfeCteReferenciadoEnumerator.Free;
      end;
    end;

    {Cupom Fiscal Referenciado}
    if Assigned(pObjeto.ListaNfeCupomFiscalReferenciadoDTO) then
    begin
      NfeCupomFiscalReferenciadoEnumerator := pObjeto.ListaNfeCupomFiscalReferenciadoDTO.GetEnumerator;
      try
        with NfeCupomFiscalReferenciadoEnumerator do
        begin
          while MoveNext do
          begin
            NfeCupomFiscalReferenciado := Current;
            NfeCupomFiscalReferenciado.IdNfeCabecalho := pObjeto.Id;
            Client.Add(NfeCupomFiscalReferenciado, True);
          end;
        end;
      finally
        NfeCupomFiscalReferenciadoEnumerator.Free;
      end;
    end;
    (* Fim Grupo de informação dos documentos referenciados *)

    { Local Entrega }

    pObjeto.NfeLocalEntregaDTO := TNfe_Local_Entrega.Create;
    pObjeto.NfeLocalEntregaDTO.IdNfeCabecalho := pObjeto.Id;
    Client.Add(pObjeto.NfeLocalEntregaDTO, True);

    { Local Retirada }
    pObjeto.NfeLocalRetiradaDTO := TNfe_Local_Retirada.Create;
    pObjeto.NfeLocalRetiradaDTO.IdNfeCabecalho := pObjeto.Id;
    Client.Add(pObjeto.NfeLocalRetiradaDTO, True);

    (* Grupo de Transporte *)
    { Transporte }
    pObjeto.NfeTransporteDTO := TNfe_Transporte.Create;
    pObjeto.NfeTransporteDTO.IdNfeCabecalho := pObjeto.Id;
    Client.Add(pObjeto.NfeTransporteDTO, True);

    { Transporte - Reboque }
    if Assigned(pObjeto.NfeTransporteDTO.ListaNfeTransporteReboqueDTO) then
    begin
      NfeTransporteReboqueEnumerator := pObjeto.NfeTransporteDTO.ListaNfeTransporteReboqueDTO.GetEnumerator;
      try
        with NfeTransporteReboqueEnumerator do
        begin
          while MoveNext do
          begin
            NfeTransporteReboque := Current;
            NfeTransporteReboque.IdNfeTransporte := pObjeto.NfeTransporteDTO.Id;
            Client.Add(NfeTransporteReboque, True);
          end;
        end;
      finally
        NfeTransporteReboqueEnumerator.Free;
      end;
    end;

    { Transporte - Volumes }
    if Assigned(pObjeto.NfeTransporteDTO.ListaNfeTransporteVolumeDTO) then
    begin
      NfeTransporteVolumeEnumerator := pObjeto.NfeTransporteDTO.ListaNfeTransporteVolumeDTO.GetEnumerator;
      try
        with NfeTransporteVolumeEnumerator do
        begin
          while MoveNext do
          begin
            NfeTransporteVolume := Current;
            NfeTransporteVolume.IdNfeTransporte := pObjeto.NfeTransporteDTO.Id;
            Client.Add(NfeTransporteVolume, True);
          end;
        end;
      finally
        NfeTransporteVolumeEnumerator.Free;
      end;
    end;
    (* Fim Grupo de Transporte *)


    (* Grupo de Cobrança *)
    { Fatura }
    pObjeto.NfeFaturaDTO := TNfe_Fatura.Create;
    pObjeto.NfeFaturaDTO.IdNfeCabecalho := pObjeto.Id;
    Client.Add(pObjeto.NfeFaturaDTO, True);

    { Duplicatas }
    if Assigned(pObjeto.ListaNfeDuplicataDTO) then
    begin
      NfeDuplicataEnumerator := pObjeto.ListaNfeDuplicataDTO.GetEnumerator;
      try
        with NfeDuplicataEnumerator do
        begin
          while MoveNext do
          begin
            NfeDuplicata := Current;
            NfeDuplicata.IdNfeCabecalho := pObjeto.Id;
            Client.Add(NfeDuplicata, True);
          end;
        end;
      finally
        NfeDuplicataEnumerator.Free;
      end;
    end;
    (* Fim Grupo de Cobrança *)


    (* Grupo de Detalhes *)
    { NFeDetalhe }
    if Assigned(pObjeto.ListaNfeDetalheDTO) then
    begin
      NFeDetalheEnumerator := pObjeto.ListaNfeDetalheDTO.GetEnumerator;
      try
        with NFeDetalheEnumerator do
        begin
          while MoveNext do
          begin
            NFeDetalhe := Current;
            NFeDetalhe.IdNfeCabecalho := pObjeto.Id;
            Client.Add(NFeDetalhe, True);

            // Atualiza estoque TIPO_OPERACAO ->> 0=Entrada | 1=Saída
            // Exercício: implementar com o mORMot
            {
            if pObjeto.TipoOperacao = 0 then
              TControleEstoqueController.AtualizarEstoque(NFeDetalhe.QuantidadeComercial, NFeDetalhe.IdProduto, pObjeto.IdEmpresa, pObjeto.EmpresaDTO.TipoControleEstoque)
            else
              TControleEstoqueController.AtualizarEstoque(NFeDetalhe.QuantidadeComercial * -1, NFeDetalhe.IdProduto, pObjeto.IdEmpresa, pObjeto.EmpresaDTO.TipoControleEstoque);
            }

            { Detalhe - Imposto - ICMS }
            NFeDetalhe.NfeDetalheImpostoIcmsDTO.IdNfeDetalhe := NFeDetalhe.Id;
            Client.Add(NFeDetalhe.NfeDetalheImpostoIcmsDTO, True);

            { Detalhe - Imposto - IPI }
            NFeDetalhe.NfeDetalheImpostoIpiDTO.IdNfeDetalhe := NFeDetalhe.Id;
            Client.Add(NFeDetalhe.NfeDetalheImpostoIpiDTO, True);

            { Detalhe - Imposto - II }
            NFeDetalhe.NfeDetalheImpostoIiDTO.IdNfeDetalhe := NFeDetalhe.Id;
            Client.Add(NFeDetalhe.NfeDetalheImpostoIiDTO, True);

            { Detalhe - Imposto - PIS }
            NFeDetalhe.NfeDetalheImpostoPisDTO.IdNfeDetalhe := NFeDetalhe.Id;
            Client.Add(NFeDetalhe.NfeDetalheImpostoPisDTO, True);

            { Detalhe - Imposto - COFINS }
            NFeDetalhe.NfeDetalheImpostoCofinsDTO.IdNfeDetalhe := NFeDetalhe.Id;
            Client.Add(NFeDetalhe.NfeDetalheImpostoCofinsDTO, True);

            { Detalhe - Imposto - ISSQN }
            NFeDetalhe.NfeDetalheImpostoIssqnDTO.IdNfeDetalhe := NFeDetalhe.Id;
            Client.Add(NFeDetalhe.NfeDetalheImpostoIssqnDTO, True);

            { Detalhe - Específico - Veículo }
            NFeDetalhe.NfeDetEspecificoVeiculoDTO.IdNfeDetalhe := NFeDetalhe.Id;
            Client.Add(NFeDetalhe.NfeDetEspecificoVeiculoDTO, True);

            { Detalhe - Específico - Combustível }
            NFeDetalhe.NfeDetEspecificoCombustivelDTO.IdNfeDetalhe := NFeDetalhe.Id;
            Client.Add(NFeDetalhe.NfeDetEspecificoCombustivelDTO, True);

            { Detalhe - Específico - Medicamento }
            NfeDetalheEspecificoMedicamentoEnumerator := NFeDetalhe.ListaNfeDetEspecificoMedicamentoDTO.GetEnumerator;
            try
              with NfeDetalheEspecificoMedicamentoEnumerator do
              begin
                while MoveNext do
                begin
                  NfeDetalheEspecificoMedicamento := Current;
                  NfeDetalheEspecificoMedicamento.IdNfeDetalhe := NFeDetalhe.Id;
                  Client.Add(NfeDetalheEspecificoMedicamento, True);
                end;
              end;
            finally
              NfeDetalheEspecificoMedicamentoEnumerator.Free;
            end;

            { Detalhe - Específico - Armamento }
            NfeDetalheEspecificoArmamentoEnumerator := NFeDetalhe.ListaNfeDetEspecificoArmamentoDTO.GetEnumerator;
            try
              with NfeDetalheEspecificoArmamentoEnumerator do
              begin
                while MoveNext do
                begin
                  NfeDetalheEspecificoArmamento := Current;
                  NfeDetalheEspecificoArmamento.IdNfeDetalhe := NFeDetalhe.Id;
                  Client.Add(NfeDetalheEspecificoArmamento, True);
                end;
              end;
            finally
              NfeDetalheEspecificoArmamentoEnumerator.Free;
            end;

            { Detalhe - Declaração de Importação }
            NfeDeclaracaoImportacaoEnumerator := NFeDetalhe.ListaNfeDeclaracaoImportacaoDTO.GetEnumerator;
            try
              with NfeDeclaracaoImportacaoEnumerator do
              begin
                while MoveNext do
                begin
                  NfeDeclaracaoImportacao := Current;
                  NfeDeclaracaoImportacao.IdNfeDetalhe := NFeDetalhe.Id;
                  Client.Add(NfeDeclaracaoImportacao, True);

                  { Detalhe - Declaração de Importação - Adições }
                  NfeImportacaoDetalheEnumerator := NfeDeclaracaoImportacao.ListaNfeImportacaoDetalheDTO.GetEnumerator;
                  try
                    with NfeImportacaoDetalheEnumerator do
                    begin
                      while MoveNext do
                      begin
                        NfeImportacaoDetalhe := Current;
                        NfeImportacaoDetalhe.IdNfeDeclaracaoImportacao := NfeDeclaracaoImportacao.Id;
                        Client.Add(NfeImportacaoDetalhe, True);
                      end;
                    end;
                  finally
                    NfeImportacaoDetalheEnumerator.Free;
                  end;

                end;
              end;
            finally
              NfeDeclaracaoImportacaoEnumerator.Free;
            end;

          end;
        end;
      finally
        NFeDetalheEnumerator.Free;
      end;
    end;
    (* Fim Grupo de Detalhes *)

    Consulta('ID = ?', IntToStr(pObjeto.Id), '0');
    Result := true;
  finally
  end;
end;

class function TNfeCabecalhoController.Altera(pObjeto: TNfe_Cabecalho): Boolean;
var
  aModel: TSQLModel;
  Client: TSQLRest;
  //
  NfeReferenciadaEnumerator: TEnumerator<TNfe_Referenciada>;
  NfReferenciadaEnumerator: TEnumerator<TNfe_Nf_Referenciada>;
  NfeRuralReferenciadaEnumerator: TEnumerator<TNfe_Prod_Rural_Referenciada>;
  NfeCteReferenciadoEnumerator: TEnumerator<TNfe_Cte_Referenciado>;
  NfeCupomFiscalReferenciadoEnumerator: TEnumerator<TNfe_Cupom_Fiscal_Referenciado>;
  NfeTransporteReboqueEnumerator: TEnumerator<TNfe_Transporte_Reboque>;
  NfeTransporteVolumeEnumerator: TEnumerator<TNfe_Transporte_Volume>;
  NfeDuplicataEnumerator: TEnumerator<TNfe_Duplicata>;
  //
  NfeDetalheEnumerator: TEnumerator<TNfe_Detalhe>;
  NfeDetalheEnumeratorOld: TEnumerator<TNfe_Detalhe>;
  NfeDeclaracaoImportacaoEnumerator: TEnumerator<TNfe_Declaracao_Importacao>;
  NfeDetalheEspecificoMedicamentoEnumerator: TEnumerator<TNfe_Det_Especifico_Medicamento>;
  NfeDetalheEspecificoArmamentoEnumerator: TEnumerator<TNfe_Det_Especifico_Armamento>;
  NfeImportacaoDetalheEnumerator: TEnumerator<TNfe_Importacao_Detalhe>;
  //
  NfeDetalheOld: TNfe_Detalhe;
begin
  try
    try
      aModel := TSQLModel.Create(
      [
        TEmpresa,
        TNfe_Transporte_Reboque,
        TNfe_Transporte,
        TNfe_Referenciada,
        TNfe_Prod_Rural_Referenciada,
        TNfe_Processo_Referenciado,
        TNfe_Numero,
        TNfe_Nf_Referenciada,
        TNfe_Local_Retirada,
        TNfe_Local_Entrega,
        TNfe_Importacao_Detalhe,
        TNfe_Forma_Pagamento,
        TNfe_Fatura,
        TNfe_Exportacao,
        TNfe_Emitente,
        TNfe_Duplicata,
        TNfe_Det_Especifico_Veiculo,
        TNfe_Det_Especifico_Medicamento,
        TNfe_Det_Especifico_Combustivel,
        TNfe_Det_Especifico_Armamento,
        TNfe_Detalhe_Imposto_Pis,
        TNfe_Detalhe_Imposto_Issqn,
        TNfe_Detalhe_Imposto_Ipi,
        TNfe_Detalhe_Imposto_Ii,
        TNfe_Detalhe_Imposto_Icms,
        TNfe_Detalhe_Imposto_Cofins,
        TNfe_Detalhe,
        TNfe_Destinatario,
        TNfe_Declaracao_Importacao,
        TNfe_Cupom_Fiscal_Referenciado,
        TNfe_Cte_Referenciado,
        TNfe_Configuracao,
        TNfe_Cabecalho,
        TNfe_Transporte_Volume
      ], 'root');
      Client := TSQLHttpClientWinHTTP.Create('34.230.92.11','888',aModel);

      Result := Client.Update(pObjeto);

      { Destinatario }
      if pObjeto.NfeDestinatarioDTO.Id > 0 then
        Result := Client.Update(pObjeto.NfeDestinatarioDTO)
      else
      begin
        pObjeto.NfeDestinatarioDTO.IdNfeCabecalho := pObjeto.Id;
        Result := Client.Add(pObjeto.NfeDestinatarioDTO, True) > 0;
      end;

      (* Grupo de informação dos documentos referenciados *)
      {NF-e Referenciada}
      NfeReferenciadaEnumerator := pObjeto.ListaNfeReferenciadaDTO.GetEnumerator;
      try
        with NfeReferenciadaEnumerator do
        begin
          while MoveNext do
          begin
            if Current.Id > 0 then
              Result := Client.Update(Current)
            else
            begin
              Current.IdNfeCabecalho := pObjeto.Id;
              Result := Client.Add(Current, True) > 0;
            end;
          end;
        end;
      finally
        NfeReferenciadaEnumerator.Free;
      end;

      {NF Referenciada}
      NfReferenciadaEnumerator := pObjeto.ListaNfeNfReferenciadaDTO.GetEnumerator;
      try
        with NfReferenciadaEnumerator do
        begin
          while MoveNext do
          begin
            if Current.Id > 0 then
              Result := Client.Update(Current)
            else
            begin
              Current.IdNfeCabecalho := pObjeto.Id;
              Result := Client.Add(Current, True) > 0;
            end;
          end;
        end;
      finally
        NfReferenciadaEnumerator.Free;
      end;

      {NF Rural Referenciada}
      NfeRuralReferenciadaEnumerator := pObjeto.ListaNfeProdRuralReferenciadaDTO.GetEnumerator;
      try
        with NfeRuralReferenciadaEnumerator do
        begin
          while MoveNext do
          begin
            if Current.Id > 0 then
              Result := Client.Update(Current)
            else
            begin
              Current.IdNfeCabecalho := pObjeto.Id;
              Result := Client.Add(Current, True) > 0;
            end;
          end;
        end;
      finally
        NfeRuralReferenciadaEnumerator.Free;
      end;

      {CT-e Referenciado}
      NfeCteReferenciadoEnumerator := pObjeto.ListaNfeCteReferenciadoDTO.GetEnumerator;
      try
        with NfeCteReferenciadoEnumerator do
        begin
          while MoveNext do
          begin
            if Current.Id > 0 then
              Result := Client.Update(Current)
            else
            begin
              Current.IdNfeCabecalho := pObjeto.Id;
              Result := Client.Add(Current, True) > 0;
            end;
          end;
        end;
      finally
        NfeCteReferenciadoEnumerator.Free;
      end;

      {Cupom Fiscal Referenciado}
      NfeCupomFiscalReferenciadoEnumerator := pObjeto.ListaNfeCupomFiscalReferenciadoDTO.GetEnumerator;
      try
        with NfeCupomFiscalReferenciadoEnumerator do
        begin
          while MoveNext do
          begin
            if Current.Id > 0 then
              Result := Client.Update(Current)
            else
            begin
              Current.IdNfeCabecalho := pObjeto.Id;
              Result := Client.Add(Current, True) > 0;
            end;
          end;
        end;
      finally
        NfeCupomFiscalReferenciadoEnumerator.Free;
      end;
      (* Fim Grupo de informação dos documentos referenciados *)

      { Local Entrega }
      if pObjeto.NfeLocalEntregaDTO.Id > 0 then
        Result := Client.Update(pObjeto.NfeLocalEntregaDTO)
      else
      begin
        pObjeto.NfeLocalEntregaDTO.IdNfeCabecalho := pObjeto.Id;
        Result := Client.Add(pObjeto.NfeLocalEntregaDTO, True) > 0;
      end;

      { Local Retirada }
      if pObjeto.NfeLocalRetiradaDTO.Id > 0 then
        Result := Client.Update(pObjeto.NfeLocalRetiradaDTO)
      else
      begin
        pObjeto.NfeLocalRetiradaDTO.IdNfeCabecalho := pObjeto.Id;
        Result := Client.Add(pObjeto.NfeLocalRetiradaDTO, True) > 0;
      end;


      (* Grupo de Transporte *)
      { Transporte }
      if pObjeto.NfeTransporteDTO.Id > 0 then
        Result := Client.Update(pObjeto.NfeTransporteDTO)
      else
      begin
        pObjeto.NfeTransporteDTO.IdNfeCabecalho := pObjeto.Id;
        Client.Add(pObjeto.NfeTransporteDTO, True);
      end;

      { Transporte - Reboque }
      NfeTransporteReboqueEnumerator := pObjeto.NfeTransporteDTO.ListaNfeTransporteReboqueDTO.GetEnumerator;
      try
        with NfeTransporteReboqueEnumerator do
        begin
          while MoveNext do
          begin
            if Current.Id > 0 then
              Result := Client.Update(Current)
            else
            begin
              Current.IdNfeTransporte := pObjeto.NfeTransporteDTO.Id;
              Result := Client.Add(Current, True) > 0;
            end;
          end;
        end;
      finally
        NfeTransporteReboqueEnumerator.Free;
      end;

      { Transporte - Volumes }
      NfeTransporteVolumeEnumerator := pObjeto.NfeTransporteDTO.ListaNfeTransporteVolumeDTO.GetEnumerator;
      try
        with NfeTransporteVolumeEnumerator do
        begin
          while MoveNext do
          begin
            if Current.Id > 0 then
              Result := Client.Update(Current)
            else
            begin
              Current.IdNfeTransporte := pObjeto.NfeTransporteDTO.Id;
              Result := Client.Add(Current, True) > 0;
            end;
          end;
        end;
      finally
        NfeTransporteVolumeEnumerator.Free;
      end;
      (* Fim Grupo de Transporte *)


      (* Grupo de Cobrança *)
      { Fatura }
      if pObjeto.NfeFaturaDTO.Id > 0 then
        Result := Client.Update(pObjeto.NfeFaturaDTO)
      else
      begin
        pObjeto.NfeFaturaDTO.IdNfeCabecalho := pObjeto.Id;
        Result := Client.Add(pObjeto.NfeFaturaDTO, True) > 0;
      end;

      { Duplicatas }
      NfeDuplicataEnumerator := pObjeto.ListaNfeDuplicataDTO.GetEnumerator;
      try
        with NfeDuplicataEnumerator do
        begin
          while MoveNext do
          begin
            if Current.Id > 0 then
              Result := Client.Update(Current)
            else
            begin
              Current.IdNfeCabecalho := pObjeto.Id;
              Result := Client.Add(Current, True) > 0;
            end;
          end;
        end;
      finally
        NfeDuplicataEnumerator.Free;
      end;
      (* Fim Grupo de Cobrança *)


      (* Grupo de Detalhes *)
      { NFeDetalhe }
      NFeDetalheEnumerator := pObjeto.ListaNfeDetalheDTO.GetEnumerator;
      try
        with NFeDetalheEnumerator do
        begin
          while MoveNext do
          begin
            if Current.PK > 0 then
              Client.Update(Current)
            else
              Client.Add(Current, True);

            ///EXERCICIO
            // Atualiza estoque TIPO_OPERACAO ->> 0=Entrada | 1=Saída
            {
            if Current.Id > 0 then
            begin
              try
                //Pega o valor atual do detalhe da NFe para verificar se houve alteração na quantidade
                NfeDetalheOld := ConsultaObjetoDetalhe('ID=' + Current.Id.ToString);

                Result := Client.Update(Current);

                if Assigned(NfeDetalheOld) then
                begin
                  if NfeDetalheOld.QuantidadeComercial <> Current.QuantidadeComercial then
                  begin
                    if pObjeto.TipoOperacao = 0 then
                      TControleEstoqueController.AtualizarEstoque(Current.QuantidadeComercial-NfeDetalheOld.QuantidadeComercial, Current.IdProduto, pObjeto.IdEmpresa, pObjeto.EmpresaDTO.TipoControleEstoque)
                    else
                      TControleEstoqueController.AtualizarEstoque((Current.QuantidadeComercial-NfeDetalheOld.QuantidadeComercial) * -1, Current.IdProduto, pObjeto.IdEmpresa, pObjeto.EmpresaDTO.TipoControleEstoque);
                  end;
                end;
              finally
                FreeAndNil(NfeDetalheOld);
              end;
            end
            else
            begin
              Current.IdNfeCabecalho := pObjeto.Id;
              Current.Id := Client.Add(Current);

              // Atualiza estoque TIPO_OPERACAO ->> 0=Entrada | 1=Saída
              if pObjeto.TipoOperacao = 0 then
                TControleEstoqueController.AtualizarEstoque(Current.QuantidadeComercial, Current.IdProduto, pObjeto.IdEmpresa, pObjeto.EmpresaDTO.TipoControleEstoque)
              else
                TControleEstoqueController.AtualizarEstoque(Current.QuantidadeComercial * -1, Current.IdProduto, pObjeto.IdEmpresa, pObjeto.EmpresaDTO.TipoControleEstoque);
            end;
            }

            { Detalhe - Imposto - ICMS }
            if Assigned(Current.NfeDetalheImpostoIcmsDTO) then
            begin
              Current.NfeDetalheImpostoIcmsDTO.IdNfeDetalhe := Current.Id;
              if Current.NfeDetalheImpostoIcmsDTO.Id > 0 then
                Result := Client.Update(Current.NfeDetalheImpostoIcmsDTO)
              else
              begin
                Current.NfeDetalheImpostoIcmsDTO.IdNfeDetalhe := Current.Id;
                Result := Client.Add(Current.NfeDetalheImpostoIcmsDTO, True) > 0;
              end;
            end;

            { Detalhe - Imposto - IPI }
            if Assigned(Current.NfeDetalheImpostoIpiDTO) then
            begin
              Current.NfeDetalheImpostoIpiDTO.IdNfeDetalhe := Current.Id;
              if Current.NfeDetalheImpostoIpiDTO.Id > 0 then
                Result := Client.Update(Current.NfeDetalheImpostoIpiDTO)
              else
              begin
                Current.NfeDetalheImpostoIpiDTO.IdNfeDetalhe := Current.Id;
                Result := Client.Add(Current.NfeDetalheImpostoIpiDTO, True) > 0;
              end;
            end;

            { Detalhe - Imposto - II }
            if Assigned(Current.NfeDetalheImpostoIiDTO) then
            begin
              Current.NfeDetalheImpostoIiDTO.IdNfeDetalhe := Current.Id;
              if Current.NfeDetalheImpostoIiDTO.Id > 0 then
                Result := Client.Update(Current.NfeDetalheImpostoIiDTO)
              else
              begin
                Current.NfeDetalheImpostoIiDTO.IdNfeDetalhe := Current.Id;
                Result := Client.Add(Current.NfeDetalheImpostoIiDTO, True) > 0;
              end;
            end;

            { Detalhe - Imposto - PIS }
            if Assigned(Current.NfeDetalheImpostoPisDTO) then
            begin
              Current.NfeDetalheImpostoPisDTO.IdNfeDetalhe := Current.Id;
              if Current.NfeDetalheImpostoPisDTO.Id > 0 then
                Result := Client.Update(Current.NfeDetalheImpostoPisDTO)
              else
              begin
                Current.NfeDetalheImpostoPisDTO.IdNfeDetalhe := Current.Id;
                Result := Client.Add(Current.NfeDetalheImpostoPisDTO, True) > 0;
              end;
            end;

            { Detalhe - Imposto - COFINS }
            if Assigned(Current.NfeDetalheImpostoCofinsDTO) then
            begin
              Current.NfeDetalheImpostoCofinsDTO.IdNfeDetalhe := Current.Id;
              if Current.NfeDetalheImpostoCofinsDTO.Id > 0 then
                Result := Client.Update(Current.NfeDetalheImpostoCofinsDTO)
              else
              begin
                Current.NfeDetalheImpostoCofinsDTO.IdNfeDetalhe := Current.Id;
                Result := Client.Add(Current.NfeDetalheImpostoCofinsDTO, True) > 0;
              end;
            end;

            { Detalhe - Imposto - ISSQN }
            if Assigned(Current.NfeDetalheImpostoIssqnDTO) then
            begin
              Current.NfeDetalheImpostoIssqnDTO.IdNfeDetalhe := Current.Id;
              if Current.NfeDetalheImpostoIssqnDTO.Id > 0 then
                Result := Client.Update(Current.NfeDetalheImpostoIssqnDTO)
              else
              begin
                Current.NfeDetalheImpostoIssqnDTO.IdNfeDetalhe := Current.Id;
                Result := Client.Add(Current.NfeDetalheImpostoIssqnDTO, True) > 0;
              end;
            end;

            { Detalhe - Específico - Veículo }
            if Assigned(Current.NfeDetEspecificoVeiculoDTO) then
            begin
              Current.NfeDetEspecificoVeiculoDTO.IdNfeDetalhe := Current.Id;
              if Current.NfeDetEspecificoVeiculoDTO.Id > 0 then
                Result := Client.Update(Current.NfeDetEspecificoVeiculoDTO)
              else
              begin
                Current.NfeDetEspecificoVeiculoDTO.IdNfeDetalhe := Current.Id;
                Result := Client.Add(Current.NfeDetEspecificoVeiculoDTO, True) > 0;
              end;
            end;

            { Detalhe - Específico - Combustível }
            if Assigned(Current.NfeDetEspecificoCombustivelDTO) then
            begin
              Current.NfeDetEspecificoCombustivelDTO.IdNfeDetalhe := Current.Id;
              if Current.NfeDetEspecificoCombustivelDTO.Id > 0 then
                Result := Client.Update(Current.NfeDetEspecificoCombustivelDTO)
              else
              begin
                Current.NfeDetEspecificoCombustivelDTO.IdNfeDetalhe := Current.Id;
                Result := Client.Add(Current.NfeDetEspecificoCombustivelDTO, True) > 0;
              end;
            end;

            { Detalhe - Específico - Medicamento }
            if Assigned(Current.ListaNfeDetEspecificoMedicamentoDTO) then
            begin
              NfeDetalheEspecificoMedicamentoEnumerator := Current.ListaNfeDetEspecificoMedicamentoDTO.GetEnumerator;
              try
                with NfeDetalheEspecificoMedicamentoEnumerator do
                begin
                  while MoveNext do
                  begin
                    if Current.Id > 0 then
                      Result := Client.Update(Current)
                    else
                      Result := Client.Add(Current, True) > 0;
                  end;
                end;
              finally
                NfeDetalheEspecificoMedicamentoEnumerator.Free;
              end;
            end;

            { Detalhe - Específico - Armamento }
            if Assigned(Current.ListaNfeDetEspecificoArmamentoDTO) then
            begin
              NfeDetalheEspecificoArmamentoEnumerator := Current.ListaNfeDetEspecificoArmamentoDTO.GetEnumerator;
              try
                with NfeDetalheEspecificoArmamentoEnumerator do
                begin
                  while MoveNext do
                  begin
                    if Current.Id > 0 then
                      Result := Client.Update(Current)
                    else
                      Result := Client.Add(Current, True) > 0;
                  end;
                end;
              finally
                NfeDetalheEspecificoArmamentoEnumerator.Free;
              end;
            end;

            { Detalhe - Declaração de Importação }
            if Assigned(Current.ListaNfeDeclaracaoImportacaoDTO) then
            begin
              NfeDeclaracaoImportacaoEnumerator := Current.ListaNfeDeclaracaoImportacaoDTO.GetEnumerator;
              try
                with NfeDeclaracaoImportacaoEnumerator do
                begin
                  while MoveNext do
                  begin
                    if Current.Id > 0 then
                      Result := Client.Update(Current)
                    else
                      Result := Client.Add(Current, True) > 0;

                    { Detalhe - Declaração de Importação - Adições }
                    NfeImportacaoDetalheEnumerator := Current.ListaNfeImportacaoDetalheDTO.GetEnumerator;
                    try
                      with NfeImportacaoDetalheEnumerator do
                      begin
                        while MoveNext do
                        begin
                          if Current.Id > 0 then
                            Result := Client.Update(Current)
                          else
                            Result := Client.Add(Current, True) > 0;
                        end;
                      end;
                    finally
                      NfeImportacaoDetalheEnumerator.Free;
                    end;

                  end;
                end;
              finally
                NfeDeclaracaoImportacaoEnumerator.Free;
              end;
            end;

          end;
        end;
      finally
        NFeDetalheEnumerator.Free;
      end;
      (* Fim Grupo de Detalhes *)

    finally
    end;
  except
    on E: Exception do
      Application.MessageBox(PChar('Ocorreu um erro na alteração do registro. Informe a mensagem ao Administrador do sistema.' + #13 + #13 + E.Message), 'Erro do sistema', MB_OK + MB_ICONERROR);
  end;
end;

class function TNfeCabecalhoController.Exclui(pId: Integer): Boolean;
begin
  try
    raise Exception.Create('Não é permitido excluir uma NFe.');
  finally
  end;
end;

class function TNfeCabecalhoController.ExcluiCobranca(pId: Integer): Boolean;
var
  RetornoNfe: TNfe_Cabecalho;
  RetornoDetalhe: TNfe_Detalhe;
  Client: TSQLRest;
  aModel: TSQLModel;
begin
  try
    aModel := TSQLModel.Create(
    [
      TNfe_Fatura,
      TNfe_Duplicata
    ], 'root');

    Client := TSQLHttpClientWinHTTP.Create('34.230.92.11','888',aModel);

    Result := Client.Delete(TNfe_Fatura, 'IdNfeCabecalho = ?', [pId]);
    Result := Client.Delete(TNfe_Duplicata, 'IdNfeCabecalho = ?', [pId]);

    TratarRetorno(Result);
  finally
  end;
end;

class function TNfeCabecalhoController.ExcluiReferenciado(pId: Integer): Boolean;
begin
  try
    /// EXERCICIO
    ///  Implemente a(s) exclusão(ões)
    TratarRetorno(Result);
  finally
  end;
end;

class function TNfeCabecalhoController.ExcluiEntregaRetirada(pId: Integer): Boolean;
begin
  try
    /// EXERCICIO
    ///  Implemente a(s) exclusão(ões)
    TratarRetorno(Result);
  finally
  end;
end;

class function TNfeCabecalhoController.ExcluiTransporte(pId: Integer): Boolean;
begin
  try
    /// EXERCICIO
    ///  Implemente a(s) exclusão(ões)
    TratarRetorno(Result);
  finally
  end;
end;

class function TNfeCabecalhoController.ExcluiItem(pId: Integer): Boolean;
begin
  try
    /// EXERCICIO
    ///  Implemente a(s) exclusão(ões)
    TratarRetorno(Result);
  finally
  end;
end;

class function TNfeCabecalhoController.GetDataSet: TClientDataSet;
begin
  Result := FDataSet;
end;

class procedure TNfeCabecalhoController.SetDataSet(pDataSet: TClientDataSet);
begin
  FDataSet := pDataSet;
end;

initialization
  Classes.RegisterClass(TNfeCabecalhoController);

finalization
  Classes.UnRegisterClass(TNfeCabecalhoController);

end.
