using betrace_carfi_erp_driver.Primavera10.Engine;
using IntBE100;
using CmpBE100;
using VndBE100;
using GprBE100;
using InvBE100;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static betrace_carfi_erp_driver.Components.Document;
using betrace_carfi_erp_driver.Components;
using static StdPlatBS100.StdBSTipos;
using BasBE100;
using betrace_carfi_erp_driver.Common;
using Serilog;
using Serilog.Events;
using Newtonsoft.Json;

namespace betrace_carfi_erp_driver
{
    class ConnectorPrimavera10 : IConnectorERP
    {
        public LoggerConfiguration logger = new LoggerConfiguration();
        public ConnectorPrimavera10() {
           
            //logger.WriteTo.File("log.txt");
            //logger.CreateLogger();
            //Log.Information("TESTE");
        }
     
       
           
public bool UpdateDocument(Cab cab, List<Lin> lines, ref string docNumber)
        {
            string cabTipo = cab.TypeDoc;
            if (cabTipo.Length >= 3) 
            {
            cabTipo = cabTipo.Substring(0, 3);
            }
          
           
            switch (cabTipo)
            {
                case "VGE":
                    UpdateDocumentBuy(cab, lines, ref docNumber);
                    break;
                case "GE":
                    UpdateDocumentSell(cab, lines, ref docNumber);
                    break;
                case "SSC":
                    UpdateDocumentInternal_SS(cab, lines, ref docNumber);
                    break;
                case "SSA":
                    UpdateDocumentInternal_SS(cab, lines, ref docNumber);
                    break;
                case "ESC":
                    UpdateDocumentInternal_ES(cab, lines, ref docNumber);
                    break;
                case "ES":
                    UpdateDocumentInternal_ES(cab, lines, ref docNumber);
                    break;
                case "SQU":
                    UpdateDocumentInternal_SQ(cab, lines, ref docNumber);
                    break;
                case "PRO":
                    UpdateDocumentProduction(cab, lines, ref docNumber);
                    break;
                case "TRA":
                    UpdateDocumentTransfer(cab, lines, ref docNumber);
                    break;
                default:
                    UpdateDocumentInternal(cab, lines, ref docNumber);
                    break;
            }
            return true;
        }
      
        public bool UpdateDocumentBuy(Cab cab, List<Lin> lines, ref string docNumber)
        {
            try
            {
                CmpBEDocumentoCompra objDocCompra = new CmpBEDocumentoCompra();

                objDocCompra.Tipodoc = cab.TypeDoc;
                objDocCompra.TipoEntidade = "F";
                objDocCompra.Entidade = cab.Entity;
                objDocCompra.Serie = PriEngine.Engine.Base.Series.DaSerieDefeito("C", cab.TypeDoc, cab.Date); // cab.Date.ToString("yyyy");  // cab.Serie;
                objDocCompra.DataDoc = cab.Date;
                objDocCompra.NumDocExterno = cab.Id.ToString();
                PriEngine.Engine.Compras.Documentos.PreencheDadosRelacionados(objDocCompra);
                objDocCompra.DataDoc = cab.Date;
                objDocCompra.DataGravacao = cab.Date;
                objDocCompra.DataIntroducao = cab.DueDate; // DateTime.Now;
                objDocCompra.DataUltimaActualizacao = DateTime.Now;
                objDocCompra.Observacoes = "Ref. BeTrace: " + cab.DocBeTrace + " Obs: " + cab.Observations;

                string strAvisos = string.Empty;

                if (lines.Count > 0)
                {
                    foreach (Lin item in lines)
                    {
                        CmpBELinhaDocumentoCompra linha = new CmpBELinhaDocumentoCompra();
                        PriEngine.Engine.Compras.Documentos.AdicionaLinha(objDocCompra, item.Article, ref item.Quantity);

                        String unidadeBase = PriEngine.Engine.Base.Artigos.DaValorAtributo(item.Article, "UnidadeBase");
                        linha = objDocCompra.Linhas.GetEdita(objDocCompra.Linhas.NumItens);
                        linha.Armazem = item.Warehouse;
                        linha.Localizacao = item.Warehouse;
                        linha.Quantidade = item.Quantity;


                        if (item.Unity.ToUpper()  != unidadeBase.ToUpper())
                        {
                            if (PriEngine.Engine.Base.UnidadesConversao.Existe(item.Unity, unidadeBase))
                            {
                                linha.FactorConv = PriEngine.Engine.Base.UnidadesConversao.DaValorAtributo(item.Unity, unidadeBase, "FactorConversao");
                            }
                        }
                        else
                            linha.FactorConv = 1;

                            linha.PrecUnit = item.Price;// * linha.FactorConv; 
                            linha.Desconto1 = item.Discount;
                            linha.Unidade = item.Unity;
                            linha.DataStock = cab.Date;
                    }
                }
                else throw new Exception("No lines found ID: " + cab.Id + ". ");

                CmpBETabCompra tabCompra = PriEngine.Engine.Compras.TabCompras.Edita(objDocCompra.Tipodoc);

                if (PriEngine.Engine.Compras.Documentos.ValidaActualizacao(objDocCompra, tabCompra, ref strAvisos))
                {
                    strAvisos = String.Empty;
                    PriEngine.Engine.Compras.Documentos.Actualiza(objDocCompra, ref strAvisos);

      
                    try
                    {
                        if (SystemInfo.LogDev == "1")
                        {
                            Log.Warning("----------GRAVA---------");
                            Log.Information(JsonConvert.SerializeObject(objDocCompra));
                            Log.Information(JsonConvert.SerializeObject(objDocCompra.Linhas));
                            //Tipos de Mensagem possiveis. Tem de ser colocadas manualmente
                        }
                    }
                    catch (Exception ex)
                    {
                   
                    }
                    finally
                    {
                       
                    }
                    regravarDocumentoCompra(objDocCompra.ID, cab.Date);
                    if (SystemInfo.LogDev == "1")
                    {
                        Log.Warning("----------REGRAVA---------");
                        Log.Information(JsonConvert.SerializeObject(objDocCompra));
                        Log.Information(JsonConvert.SerializeObject(objDocCompra.Linhas));
                    }
                    docNumber = objDocCompra.Documento;
                    if (strAvisos.Length > 0)
                    {
                        Logger.WriteEntry("Error writing document ID: " + cab.Id + " - ERP Code: " + objDocCompra.Documento + ". \n" + strAvisos, EventLogEntryType.Warning);
                    }
                }
                else
                {
                    if (strAvisos.Length > 0)
                    {
                        throw new Exception("Error writing document ID: " + cab.Id + ". \n" + strAvisos);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            return true;
        }
        private string regravarDocumentoCompra(String id, DateTime date) {

           CmpBEDocumentoCompra objDocCompra;
           objDocCompra = PriEngine.Engine.Compras.Documentos.EditaID(id);
           objDocCompra.DataDoc = date;
           objDocCompra.DataGravacao = date;
           objDocCompra.DataIntroducao = date;


            foreach (CmpBELinhaDocumentoCompra item in objDocCompra.Linhas)
            {
                item.DataStock = date;
            }

            string strAvisos="";

            PriEngine.Engine.Compras.Documentos.Actualiza(objDocCompra, ref strAvisos);
            return strAvisos;

        }
      
        public bool UpdateDocumentSell(Cab cab, List<Lin> lines, ref string docNumber)
        {
           
            try
            {
                VndBEDocumentoVenda objDocVenda = new VndBEDocumentoVenda();
                objDocVenda.Tipodoc = cab.TypeDoc;
                objDocVenda.Entidade = cab.Entity;
                objDocVenda.TipoEntidade = "C";
                objDocVenda.Serie = PriEngine.Engine.Base.Series.DaSerieDefeito("V", cab.TypeDoc, cab.Date);//cab.Date.ToString("yyyy");//cab.Serie;
                objDocVenda.DataDoc = cab.Date;
                PriEngine.Engine.Vendas.Documentos.PreencheDadosRelacionados(objDocVenda);
                objDocVenda.DataGravacao = cab.Date;
                objDocVenda.DataUltimaActualizacao = cab.Date;
                objDocVenda.Observacoes = "Ref. BeTrace: " + cab.DocBeTrace + " Obs: " + cab.Observations;

                string strAvisos = string.Empty;

                if (lines.Count > 0)
                {
                    foreach (Lin item in lines)
                    {
                        Database ArmazemErp = new Database();
                        VndBELinhaDocumentoVenda linha = new VndBELinhaDocumentoVenda();
                        PriEngine.Engine.Vendas.Documentos.AdicionaLinha(objDocVenda, item.Article, ref item.Quantity);

                        String unidadeBase = PriEngine.Engine.Base.Artigos.DaValorAtributo(item.Article, "UnidadeBase");
                        linha = objDocVenda.Linhas.GetEdita(objDocVenda.Linhas.NumItens);
                        linha.Armazem = item.Warehouse;
                        linha.Localizacao = item.Warehouse; //ArmazemErp.GetArmazemERP(item.Article);
                        linha.Lote = "<L01>";
                        linha.Quantidade = item.Quantity;
                        linha.EstadoOrigem = "DISP";

                         // CDU_descritivoextra -> Quando existir preenchido, deve sobrepor-se ao Descritivo no documento.
                        string descritivoExtra = PriEngine.Engine.Base.Artigos.DaValorAtributo(item.Article, "CDU_descritivoextra");
                        if (descritivoExtra != "")
                        {
                        linha.Descricao = descritivoExtra;
                        }

                        linha.CamposUtil["CDU_LinVar1ENC"].Valor = item.DocExterno;

                        if (item.Unity.ToUpper() != unidadeBase.ToUpper())
                        {
                            if (PriEngine.Engine.Base.UnidadesConversao.Existe(item.Unity, unidadeBase))
                            {
                                linha.FactorConv = PriEngine.Engine.Base.UnidadesConversao.DaValorAtributo(item.Unity, unidadeBase, "FactorConversao");
                            }
                        }
                        else
                            linha.FactorConv = 1;
                            linha.PrecUnit = item.Price * linha.FactorConv;
                            linha.Unidade = item.Unity;
                            linha.DataStock = cab.Date;


                    }
                }
                else throw new Exception("No lines found ID: " + cab.Id + ". ");

                PriEngine.Engine.Vendas.Documentos.CalculaValoresTotais(objDocVenda);
                VndBETabVenda tabVenda = PriEngine.Engine.Vendas.TabVendas.Edita(objDocVenda.Tipodoc);

                if (PriEngine.Engine.Vendas.Documentos.ValidaActualizacao(objDocVenda, tabVenda, ref cab.Serie, ref strAvisos))
                {
                    strAvisos = String.Empty;
                    PriEngine.Engine.Vendas.Documentos.Actualiza(objDocVenda, ref strAvisos);
                    if (SystemInfo.LogDev == "1")
                    {
                        Log.Warning("----------GRAVA---------");
                        Log.Information(JsonConvert.SerializeObject(objDocVenda));
                        Log.Information(JsonConvert.SerializeObject(objDocVenda.Linhas));
                    }
                    regravarDocumentoVenda(objDocVenda.ID, cab.Date);

                    if (SystemInfo.LogDev == "1")
                    {
                        Log.Warning("----------REGRAVA---------");
                        Log.Information(JsonConvert.SerializeObject(objDocVenda));
                        Log.Information(JsonConvert.SerializeObject(objDocVenda.Linhas));
                    }
                    docNumber = objDocVenda.Documento;
                    if (strAvisos.Length > 0)
                    {
                        Logger.WriteEntry("Error writing document ID: " + cab.Id + " - ERP Code: " + objDocVenda.Documento + ". \n" + strAvisos, EventLogEntryType.Warning);
                    }
                }
                else
                {
                    if (strAvisos.Length > 0)
                    {
                        throw new Exception("Error writing document ID: " + cab.Id + ". \n" + strAvisos);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return true;
        }
        private string regravarDocumentoVenda(String id, DateTime date)
        {

            VndBEDocumentoVenda objDocVenda;
            objDocVenda = PriEngine.Engine.Vendas.Documentos.EditaID(id);
            objDocVenda.DataDoc = date;
            objDocVenda.DataGravacao = date;
           
            foreach (VndBELinhaDocumentoVenda item in objDocVenda.Linhas)
            {
                item.DataStock  = date;               
            }

            string strAvisos = "";

            PriEngine.Engine.Vendas.Documentos.Actualiza(objDocVenda, ref strAvisos);
            return strAvisos;

        }

        public bool UpdateDocumentProduction(Cab cab, List<Lin> lines, ref string docNumber) 
        {
            try
            {
                InvBEDocumentoComposicao objDocProducao = new InvBEDocumentoComposicao();

                objDocProducao.Tipodoc = cab.TypeDoc;
                objDocProducao.Serie = cab.Date.ToString("yyyy");//cab.Serie;
                PriEngine.Engine.Inventario.Composicoes.PreencheDadosRelacionados(objDocProducao);
                objDocProducao.Data = cab.Date;
                objDocProducao.DataUltimaActualizacao = cab.Date;
                objDocProducao.Observacoes = "Ref. BeTrace: " + cab.DocBeTrace + " Obs: " + cab.Observations;

                string strAvisos = string.Empty;
                Database ArmazemErp = new Database();

                InvBELinhaComposto composto = new InvBELinhaComposto();
                PriEngine.Engine.Inventario.Composicoes.AdicionaLinhaComposto(objDocProducao, cab.Article);

                String unidadeBase = PriEngine.Engine.Base.Artigos.DaValorAtributo(cab.Article, "UnidadeBase");
                String unidadeComposto = "UN";

                composto = objDocProducao.LinhasCompostos.GetEdita(objDocProducao.LinhasCompostos.NumItens);
              
                composto.Armazem = ArmazemErp.GetArmazemERP(composto.Artigo); 
                composto.Localizacao = composto.Armazem;
                composto.Quantidade = cab.Quantity;
                if (cab.TypeDoc == "PROD")
                    composto.INV_EstadoOrigem = "DISP";
                else
                    composto.INV_EstadoDestino = "DISP";

             //   composto.TipoComposto = 0;

                if (unidadeComposto != unidadeBase.ToUpper())
                {
                    if (PriEngine.Engine.Base.UnidadesConversao.Existe(unidadeComposto, unidadeBase))
                    {
                        composto.FactorConv = PriEngine.Engine.Base.UnidadesConversao.DaValorAtributo(unidadeComposto, unidadeBase, "FactorConversao");
                    }
                }
                else
                    composto.FactorConv = 1;
               // composto.PrecUnit = composto.PrecUnit;
                composto.PrecUnit = composto.PrecUnit * composto.FactorConv;

                composto.Unidade = unidadeComposto;
                composto.DataStock = cab.Date;


                if (lines.Count > 0)
                {
                    foreach (Lin item in lines)
                    {
                        InvBELinhaComponente linha = new InvBELinhaComponente();
                        PriEngine.Engine.Inventario.Composicoes.AdicionaLinhaComponente(objDocProducao, composto, item.Article, item.Quantity);
                        Database Armazem = new Database();

                        String unidadeBaseComponente = PriEngine.Engine.Base.Artigos.DaValorAtributo(item.Article, "UnidadeBase");
                        linha = composto.LinhasComponentes.GetEdita(composto.LinhasComponentes.NumItens);

                        linha.TipoCusto = BasBETipos.EnumTipoCustoComponentesArtigos.tcCustoManual;

                        linha.Armazem = Armazem.GetArmazemERP(linha.Artigo);
                        linha.Localizacao = linha.Armazem;
                        linha.Quantidade = item.Quantity;
                        if (cab.TypeDoc == "PROD")
                            linha.INV_EstadoDestino = "DISP";
                        else
                            linha.INV_EstadoOrigem = "DISP";
                       // linha.TipoComposto = 1;

                        if (item.Unity.ToUpper() != unidadeBaseComponente.ToUpper())
                        {
                            if (PriEngine.Engine.Base.UnidadesConversao.Existe(item.Unity, unidadeBaseComponente))
                            {
                                linha.FactorConv = PriEngine.Engine.Base.UnidadesConversao.DaValorAtributo(item.Unity, unidadeBaseComponente, "FactorConversao");
                            }
                        }
                        else
                            linha.FactorConv = 1;
                            linha.PrecUnit = PriEngine.Engine.Base.Artigos.DaValorAtributo(linha.Artigo, "PCMedio");
                            linha.PrecUnit = linha.PrecUnit * linha.FactorConv;
                            linha.Unidade = item.Unity;
                            linha.DataStock = cab.Date;
                    }

                    //double precTotal = 0;
                    //foreach (InvBELinhaComponente linhac in composto.LinhasComponentes)
                    //{
                    //    precTotal += linhac.PrecUnit * linhac.Quantidade;
                    //}
                    //     composto.PrecUnit = precTotal;

                    composto.PrecUnit = PriEngine.Engine.Base.Artigos.DaValorAtributo(composto.Artigo, "PCPadrao");


                 }
                else throw new Exception("No lines found ID: " + cab.Id + ". ");

                if (PriEngine.Engine.Inventario.Composicoes.ValidaActualizacao(objDocProducao, ref strAvisos))
                {
                    strAvisos = String.Empty;
                    PriEngine.Engine.Inventario.Composicoes.Actualiza(objDocProducao, ref strAvisos);
                    if (SystemInfo.LogDev == "1")
                    {
                        Log.Warning("----------GRAVA---------");
                        Log.Information(JsonConvert.SerializeObject(objDocProducao));
                        Log.Information(JsonConvert.SerializeObject(composto.LinhasComponentes));
                    }
                    if (cab.TypeDoc == "PROD")
                        regravarDocumentoProducao(objDocProducao.ID, cab.Date,10, composto.PrecUnit);
                    else
                        regravarDocumentoProducao(objDocProducao.ID, cab.Date,-10, composto.PrecUnit);
                    if (SystemInfo.LogDev == "1")
                    {
                        Log.Warning("----------REGRAVA---------");

                        Log.Information(JsonConvert.SerializeObject(objDocProducao));
                        Log.Information(JsonConvert.SerializeObject(composto.LinhasComponentes));
                    }
                    docNumber = objDocProducao.NumDoc.ToString();
                    if (strAvisos.Length > 0)
                    {
                        Logger.WriteEntry("Error writing document ID: " + cab.Id + " - ERP Code: " + objDocProducao.NumDoc + ". \n" + strAvisos, EventLogEntryType.Warning);
                    }
                }
                else
                {
                    if (strAvisos.Length > 0)
                    {
                        throw new Exception("Error writing document ID: " + cab.Id + ". \n" + strAvisos);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return true;
        }
        private string regravarDocumentoProducao(String id, DateTime date, double seconds, double Preco)
        {

            InvBEDocumentoComposicao objDocProducao;
            objDocProducao = PriEngine.Engine.Inventario.Composicoes.EditaID(id);
            objDocProducao.Data = date;
            

            foreach (InvBELinhaComposto item in objDocProducao.LinhasCompostos)
            {
                item.Data = date;
                item.DataStock = date;

                foreach (InvBELinhaComponente itemComponente in item.LinhasComponentes)
                {   
                    itemComponente.Data = date.AddSeconds(seconds) ;
                    itemComponente.DataStock = date.AddSeconds(seconds);
                }
                item.PrecUnit = Preco;
            }

            string strAvisos = "";

            PriEngine.Engine.Inventario.Composicoes.Actualiza(objDocProducao, ref strAvisos);
            return strAvisos;

        }

        public bool UpdateDocumentTransfer(Cab cab, List<Lin> lines, ref string docNumber) 
        {
            try
            {
                InvBETabTransferencia tabTransfer = PriEngine.Engine.Inventario.TabTransferencias.Edita(cab.TypeDoc);

                InvBEDocumentoTransf objDocTransf = new InvBEDocumentoTransf();

                string strAvisos = string.Empty;

                objDocTransf.Tipodoc = cab.TypeDoc;
                objDocTransf.Serie = cab.Date.ToString("yyyy");//cab.Serie;
                objDocTransf.DataUltimaActualizacao = cab.Date;
                objDocTransf.Observacoes = "Ref. BeTrace: " + cab.DocBeTrace + " Obs: " + cab.Observations;
                objDocTransf.Data = cab.Date;
                PriEngine.Engine.Inventario.Transferencias.PreencheDadosRelacionados(objDocTransf);
                objDocTransf.Data = cab.Date;

                if (SystemInfo.LogDev == "1")
                {
                    Log.Warning("----------GRAVA---------");
                    Log.Information(JsonConvert.SerializeObject(objDocTransf));
                    Log.Information(JsonConvert.SerializeObject(objDocTransf.LinhasOrigem));
                }
                if (lines.Count > 0)
                {
                    foreach (Lin item in lines)
                    {
                        InvBELinhaOrigemTransf origem = new InvBELinhaOrigemTransf();
                        InvBELinhaDestinoTransf destino = new InvBELinhaDestinoTransf();

                        PriEngine.Engine.Inventario.Transferencias.AdicionaLinhaOrigem(objDocTransf, item.Article, item.Warehouse, item.Warehouse, "DISP", item.Quantity);
                        origem = objDocTransf.LinhasOrigem.GetEdita(objDocTransf.LinhasOrigem.NumItens);

                        origem.Armazem = Convert.ToString(item.Warehouse);
                        origem.Localizacao = origem.Armazem;
                        origem.Artigo = Convert.ToString(item.Article);
                        origem.Quantidade = Convert.ToDouble(item.Quantity);
                        origem.INV_EstadoOrigem = "DISP";


                        String unidadeBase = PriEngine.Engine.Base.Artigos.DaValorAtributo(item.Article, "UnidadeBase");


                        if (item.Unity.ToUpper() != unidadeBase.ToUpper())
                        {
                            if (PriEngine.Engine.Base.UnidadesConversao.Existe(item.Unity, unidadeBase))
                            {
                                origem.FactorConv = PriEngine.Engine.Base.UnidadesConversao.DaValorAtributo(item.Unity, unidadeBase, "FactorConversao");
                            }
                        }
                        else
                            origem.FactorConv = 1;

                        origem.Unidade = item.Unity;
                        origem.PrecUnit = origem.PrecUnit * origem.FactorConv;

                        destino = origem.LinhasDestino.GetEdita(origem.LinhasDestino.NumItens);
                        destino.Armazem = Convert.ToString(item.WarehouseTarget);
                        destino.Localizacao = destino.Armazem;
                        destino.Quantidade = Convert.ToDouble(item.Quantity);
                        destino.INV_EstadoDestino = "DISP";

                        unidadeBase= PriEngine.Engine.Base.Artigos.DaValorAtributo(item.Article, "UnidadeBase");

                        if (item.Unity.ToUpper() != unidadeBase.ToUpper())
                        {
                            if (PriEngine.Engine.Base.UnidadesConversao.Existe(item.Unity, unidadeBase))
                            {
                                destino.FactorConv = PriEngine.Engine.Base.UnidadesConversao.DaValorAtributo(item.Unity, unidadeBase, "FactorConversao");
                            }
                        }
                        else
                            destino.FactorConv = 1;

                        destino.Unidade = item.Unity;
                        destino.PrecUnit = destino.PrecUnit * destino.FactorConv;


                    }
                }
                else throw new Exception("No lines found ID: " + cab.Id + ". ");

  
                
                if (PriEngine.Engine.Inventario.Transferencias.ValidaActualizacao(objDocTransf, tabTransfer, ref strAvisos))
                {
                    strAvisos = String.Empty;
                    PriEngine.Engine.Inventario.Transferencias.Actualiza(objDocTransf, ref strAvisos);

                    regravarDocumentoTransferencia(objDocTransf.ID, cab.Date,10);
                    if (SystemInfo.LogDev == "1")
                    {
                        Log.Warning("----------Regrava---------");
                        Log.Information(JsonConvert.SerializeObject(objDocTransf));
                        Log.Information(JsonConvert.SerializeObject(objDocTransf.ID));
                    }
                    docNumber = objDocTransf.NumDoc.ToString();
                    if (strAvisos.Length > 0)
                    {
                        Logger.WriteEntry("Error writing document ID: " + cab.Id + " - ERP Code: " + objDocTransf.NumDoc + ". \n" + strAvisos, EventLogEntryType.Warning);
                    }
                }
                else
                {
                    if (strAvisos.Length > 0)
                    {
                        throw new Exception("Error writing document ID: " + cab.Id + ". \n" + strAvisos);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return true;
        }
        private string regravarDocumentoTransferencia(String id, DateTime date, double seconds)
        {

            InvBEDocumentoTransf objDocTransf;
            objDocTransf = PriEngine.Engine.Inventario.Transferencias.EditaID(id);
            objDocTransf.Data = date;


            foreach (InvBELinhaOrigemTransf item in objDocTransf.LinhasOrigem)
            {
                item.DataStock = date;

                foreach (InvBELinhaDestinoTransf itemDestino in item.LinhasDestino)
                {
                    itemDestino.DataStock = date.AddSeconds(seconds) ;

                }
            }

            string strAvisos = "";

            PriEngine.Engine.Inventario.Transferencias.Actualiza(objDocTransf, ref strAvisos);
            return strAvisos;

        }

        public bool UpdateDocumentInternal(Cab cab, List<Lin> lines, ref string docNumber)
        {
            try
            {
                IntBEDocumentoInterno objDocInterno = new IntBEDocumentoInterno();

                objDocInterno.Tipodoc = cab.TypeDoc;
                PriEngine.Engine.Internos.Documentos.PreencheDadosRelacionados(objDocInterno);
                objDocInterno.Serie = cab.Serie;
                objDocInterno.Data = cab.Date;
                objDocInterno.DataUltimaActualizacao = cab.Date;
                objDocInterno.DataVencimento = cab.DueDate;
                objDocInterno.Observacoes = "Ref. BeTrace: " + cab.DocBeTrace + " Obs: " + cab.Observations;

                string strAvisos = string.Empty;

              

                if (lines.Count > 0)
                {
                    foreach (Lin item in lines)
                    {
                        Database Armazem = new Database();
                        IntBELinhaDocumentoInterno linha = new IntBELinhaDocumentoInterno();
                        PriEngine.Engine.Internos.Documentos.AdicionaLinha(objDocInterno, item.Article, item.Warehouse, item.Warehouse);

                        if (SystemInfo.LogDev == "1")
                        {
                            Log.Warning("----------GRAVA---------");
                            Log.Information(JsonConvert.SerializeObject(objDocInterno));
                            Log.Information(JsonConvert.SerializeObject(objDocInterno.Linhas));
                        }
                        linha = objDocInterno.Linhas.GetEdita(objDocInterno.Linhas.NumItens);
                        linha.Quantidade = item.Quantity;
                        linha.Lote = "<L01>";
                        //linha.Armazem = Armazem.GetArmazemERP(linha.Artigo);
                        linha.Armazem = item.Warehouse;
                        linha.Localizacao = item.Warehouse;

                        if (linha.Unidade.ToUpper() != item.Unity.ToUpper())
                        {
                            
                            if (PriEngine.Engine.Base.UnidadesConversao.Existe(item.Unity, linha.Unidade))
                            {
                                BasBEUnidadeConversao ac = PriEngine.Engine.Base.UnidadesConversao.Edita(item.Unity, linha.Unidade);
                                linha.FactorConv = ac.FactorConversao; //PriEngine.Engine.Base.UnidadesConversao.DaValorAtributo(item.Unity, linha.Unidade, "FactorConversao");
                            }

                            linha.Unidade = item.Unity;
                            //     linha.PrecUnit = linha.PrecUnit* linha.FactorConv;
                            //     linha.PrecUnit = PriEngine.Engine.Base.Artigos.DaValorAtributo(item.Article, "PCPadrao"); //Pedido de alteração feito pela carfi ticket #799415

                        }
                            linha.PrecUnit = PriEngine.Engine.Base.Artigos.DaValorAtributo(item.Article, "PCMedio")* linha.FactorConv;



                        //string strArtigo = Convert.ToString(item.Article);
                        //string strArmazem = Convert.ToString(item.Warehouse);
                        //double dblQtd = Convert.ToDouble(item.Quantity);
                        //string strLote = "<L01>";
                        //
                        //PriEngine.Engine.Internos.Documentos.AdicionaLinha(objDocInterno, strArtigo, strArmazem, Quantidade: dblQtd, Lote: strLote);
                    }
                }
                else throw new Exception("No lines found ID: " + cab.Id + ". ");

                if (PriEngine.Engine.Internos.Documentos.ValidaActualizacao(objDocInterno, ref strAvisos))
                {
                    strAvisos = String.Empty;
                    PriEngine.Engine.Internos.Documentos.Actualiza(objDocInterno, ref strAvisos);

                    regravarDocumentoInterno(objDocInterno.ID, cab.Date);
                    if (SystemInfo.LogDev == "1")
                    {
                        Log.Warning("----------REGRAVA---------");
                        Log.Information(JsonConvert.SerializeObject(objDocInterno));
                        Log.Information(JsonConvert.SerializeObject(objDocInterno.Linhas));
                    }
                    docNumber = objDocInterno.Tipodoc +" "+ objDocInterno.Serie;
                    if (strAvisos.Length > 0)
                    {
                        Logger.WriteEntry("Error writing document ID: " + cab.Id + " - ERP Code: " + objDocInterno.Documento + ". \n" + strAvisos, EventLogEntryType.Warning);
                    }
                }
                else
                {
                    if (strAvisos.Length > 0)
                    {
                        throw new Exception("Error writing document ID: " + cab.Id + ". \n" + strAvisos);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return true;
        }
        private string regravarDocumentoInterno(String id, DateTime date)
        {

            IntBEDocumentoInterno objDocInterno;
            objDocInterno = PriEngine.Engine.Internos.Documentos.EditaID(id);
            objDocInterno.Data = date;
            objDocInterno.DataEntrega = date;
          


            foreach (IntBELinhaDocumentoInterno item in objDocInterno.Linhas)
            {
                item.DataStock = date;
            }

            string strAvisos = "";

            PriEngine.Engine.Internos.Documentos.Actualiza(objDocInterno, ref strAvisos);
            return strAvisos;

        }

        public bool UpdateDocumentInternal_SS(Cab cab, List<Lin> lines, ref string docNumber)
        {
            try
            {
                IntBEDocumentoInterno objDocInterno = new IntBEDocumentoInterno();

                objDocInterno.Tipodoc = cab.TypeDoc;
                PriEngine.Engine.Internos.Documentos.PreencheDadosRelacionados(objDocInterno);
                objDocInterno.Serie = cab.Serie;
                objDocInterno.Data = cab.Date;
                objDocInterno.DataUltimaActualizacao = cab.Date;
                objDocInterno.DataVencimento = cab.DueDate;
                objDocInterno.Observacoes = "Ref. BeTrace: " + cab.DocBeTrace + " Obs: " + cab.Observations;

                string strAvisos = string.Empty;



                if (lines.Count > 0)
                {
                    foreach (Lin item in lines)
                    {
                        Database Armazem = new Database();
                        IntBELinhaDocumentoInterno linha = new IntBELinhaDocumentoInterno();
                        PriEngine.Engine.Internos.Documentos.AdicionaLinha(objDocInterno, item.Article, item.Warehouse, item.Warehouse);

                        if (SystemInfo.LogDev == "1")
                        {
                            Log.Warning("----------GRAVA---------");
                            Log.Information(JsonConvert.SerializeObject(objDocInterno));
                            Log.Information(JsonConvert.SerializeObject(objDocInterno.Linhas));
                        }
                        linha = objDocInterno.Linhas.GetEdita(objDocInterno.Linhas.NumItens);
                        linha.Quantidade = item.Quantity;
                        linha.Lote = "<L01>";
                        //linha.Armazem = Armazem.GetArmazemERP(linha.Artigo);
                        linha.Armazem = item.Warehouse;
                        linha.Localizacao = item.Warehouse;

                        if (linha.Unidade.ToUpper() != item.Unity.ToUpper())
                        {

                            if (PriEngine.Engine.Base.UnidadesConversao.Existe(item.Unity, linha.Unidade))
                            {
                                //Exemplo Ricardo...
                                //fatorConversao = PrimaveraService.BSO.Base.Artigos.DaFactorConversao(linha.Artigo, unidadeBase, linha.Unidade);
                                linha.FactorConv = PriEngine.Engine.Base.UnidadesConversao.DaValorAtributo(item.Unity, linha.Unidade, "FactorConversao");
                                //BasBEUnidadeConversao ac = PriEngine.Engine.Base.UnidadesConversao.Edita(item.Unity, linha.Unidade);

                                //linha.FactorConv = ac.FactorConversao; //PriEngine.Engine.Base.UnidadesConversao.DaValorAtributo(item.Unity, linha.Unidade, "FactorConversao");
                            }

                            linha.Unidade = item.Unity;
                            //     linha.PrecUnit = linha.PrecUnit* linha.FactorConv;
                            //     linha.PrecUnit = PriEngine.Engine.Base.Artigos.DaValorAtributo(item.Article, "PCPadrao"); //Pedido de alteração feito pela carfi ticket #799415

                        }

                            linha.PrecUnit = PriEngine.Engine.Base.Artigos.DaValorAtributo(item.Article, "PCMedio") * linha.FactorConv;


                        //string strArtigo = Convert.ToString(item.Article);
                        //string strArmazem = Convert.ToString(item.Warehouse);
                        //double dblQtd = Convert.ToDouble(item.Quantity);
                        //string strLote = "<L01>";
                        //
                        //PriEngine.Engine.Internos.Documentos.AdicionaLinha(objDocInterno, strArtigo, strArmazem, Quantidade: dblQtd, Lote: strLote);
                    }
                }
                else throw new Exception("No lines found ID: " + cab.Id + ". ");

                if (PriEngine.Engine.Internos.Documentos.ValidaActualizacao(objDocInterno, ref strAvisos))
                {
                    strAvisos = String.Empty;
                    PriEngine.Engine.Internos.Documentos.Actualiza(objDocInterno, ref strAvisos);

                    regravarDocumentoInterno_SS(objDocInterno.ID, cab.Date);
                    if (SystemInfo.LogDev == "1")
                    {
                        Log.Warning("----------REGRAVA---------");
                        Log.Information(JsonConvert.SerializeObject(objDocInterno));
                        Log.Information(JsonConvert.SerializeObject(objDocInterno.Linhas));
                    }
                    docNumber = objDocInterno.Tipodoc + " " + objDocInterno.Serie;
                    if (strAvisos.Length > 0)
                    {
                        Logger.WriteEntry("Error writing document ID: " + cab.Id + " - ERP Code: " + objDocInterno.Documento + ". \n" + strAvisos, EventLogEntryType.Warning);
                    }
                }
                else
                {
                    if (strAvisos.Length > 0)
                    {
                        throw new Exception("Error writing document ID: " + cab.Id + ". \n" + strAvisos);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return true;
        }
        private string regravarDocumentoInterno_SS(String id, DateTime date)
        {

            IntBEDocumentoInterno objDocInterno;
            objDocInterno = PriEngine.Engine.Internos.Documentos.EditaID(id);
            objDocInterno.Data = date;
            objDocInterno.DataEntrega = date;



            foreach (IntBELinhaDocumentoInterno item in objDocInterno.Linhas)
            {
                item.DataStock = date;
            }

            string strAvisos = "";

            PriEngine.Engine.Internos.Documentos.Actualiza(objDocInterno, ref strAvisos);
            return strAvisos;

        }

        public bool UpdateDocumentInternal_ES(Cab cab, List<Lin> lines, ref string docNumber)
        {
            try
            {
                IntBEDocumentoInterno objDocInterno = new IntBEDocumentoInterno();

                objDocInterno.Tipodoc = cab.TypeDoc;
                PriEngine.Engine.Internos.Documentos.PreencheDadosRelacionados(objDocInterno);
                objDocInterno.Serie = cab.Serie;
                objDocInterno.Data = cab.Date;
                objDocInterno.DataUltimaActualizacao = cab.Date;
                objDocInterno.DataVencimento = cab.DueDate;
                objDocInterno.Observacoes = "Ref. BeTrace: " + cab.DocBeTrace + " Obs: " + cab.Observations;

                string strAvisos = string.Empty;



                if (lines.Count > 0)
                {
                    foreach (Lin item in lines)
                    {
                        Database Armazem = new Database();
                        IntBELinhaDocumentoInterno linha = new IntBELinhaDocumentoInterno();
                        PriEngine.Engine.Internos.Documentos.AdicionaLinha(objDocInterno, item.Article, item.Warehouse, item.Warehouse);

                        if (SystemInfo.LogDev == "1")
                        {
                            Log.Warning("----------GRAVA---------");
                            Log.Information(JsonConvert.SerializeObject(objDocInterno));
                            Log.Information(JsonConvert.SerializeObject(objDocInterno.Linhas));
                        }
                        linha = objDocInterno.Linhas.GetEdita(objDocInterno.Linhas.NumItens);
                        linha.Quantidade = item.Quantity;
                        linha.Lote = "<L01>";
                        //linha.Armazem = Armazem.GetArmazemERP(linha.Artigo);
                        linha.Armazem = item.Warehouse;
                        linha.Localizacao = item.Warehouse;

                        if (linha.Unidade.ToUpper() != item.Unity.ToUpper())
                        {

                            if (PriEngine.Engine.Base.UnidadesConversao.Existe(item.Unity, linha.Unidade))
                            {
                                BasBEUnidadeConversao ac = PriEngine.Engine.Base.UnidadesConversao.Edita(item.Unity, linha.Unidade);
                                linha.FactorConv = ac.FactorConversao; //PriEngine.Engine.Base.UnidadesConversao.DaValorAtributo(item.Unity, linha.Unidade, "FactorConversao");
                            }

                            linha.Unidade = item.Unity;
                            //     linha.PrecUnit = linha.PrecUnit* linha.FactorConv;
                            //     linha.PrecUnit = PriEngine.Engine.Base.Artigos.DaValorAtributo(item.Article, "PCPadrao"); //Pedido de alteração feito pela carfi ticket #799415
                           

                        }

                        linha.PrecUnit = PriEngine.Engine.Base.Artigos.DaValorAtributo(item.Article, "PCMedio") * linha.FactorConv;

                        //string strArtigo = Convert.ToString(item.Article);
                        //string strArmazem = Convert.ToString(item.Warehouse);
                        //double dblQtd = Convert.ToDouble(item.Quantity);
                        //string strLote = "<L01>";
                        //
                        //PriEngine.Engine.Internos.Documentos.AdicionaLinha(objDocInterno, strArtigo, strArmazem, Quantidade: dblQtd, Lote: strLote);
                    }
                }
                else throw new Exception("No lines found ID: " + cab.Id + ". ");

                if (PriEngine.Engine.Internos.Documentos.ValidaActualizacao(objDocInterno, ref strAvisos))
                {
                    strAvisos = String.Empty;
                    PriEngine.Engine.Internos.Documentos.Actualiza(objDocInterno, ref strAvisos);

                    regravarDocumentoInterno_ES(objDocInterno.ID, cab.Date);
                    if (SystemInfo.LogDev == "1")
                    {
                        Log.Warning("----------REGRAVA---------");
                        Log.Information(JsonConvert.SerializeObject(objDocInterno));
                        Log.Information(JsonConvert.SerializeObject(objDocInterno.Linhas));
                    }
                    docNumber = objDocInterno.Tipodoc + " " + objDocInterno.Serie;
                    if (strAvisos.Length > 0)
                    {
                        Logger.WriteEntry("Error writing document ID: " + cab.Id + " - ERP Code: " + objDocInterno.Documento + ". \n" + strAvisos, EventLogEntryType.Warning);
                    }
                }
                else
                {
                    if (strAvisos.Length > 0)
                    {
                        throw new Exception("Error writing document ID: " + cab.Id + ". \n" + strAvisos);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return true;
        }
        private string regravarDocumentoInterno_ES(String id, DateTime date)
        {

            IntBEDocumentoInterno objDocInterno;
            objDocInterno = PriEngine.Engine.Internos.Documentos.EditaID(id);
            objDocInterno.Data = date;
            objDocInterno.DataEntrega = date;



            foreach (IntBELinhaDocumentoInterno item in objDocInterno.Linhas)
            {
                item.DataStock = date;
            }

            string strAvisos = "";

            PriEngine.Engine.Internos.Documentos.Actualiza(objDocInterno, ref strAvisos);
            return strAvisos;

        }

        public bool UpdateDocumentInternal_SQ(Cab cab, List<Lin> lines, ref string docNumber)
        {
            try
            {
                IntBEDocumentoInterno objDocInterno = new IntBEDocumentoInterno();

                objDocInterno.Tipodoc = cab.TypeDoc;
                PriEngine.Engine.Internos.Documentos.PreencheDadosRelacionados(objDocInterno);
                objDocInterno.Serie = cab.Serie;
                objDocInterno.Data = cab.Date;
                objDocInterno.DataUltimaActualizacao = cab.Date;
                objDocInterno.DataVencimento = cab.DueDate;
                objDocInterno.Observacoes = "Ref. BeTrace: " + cab.DocBeTrace + " Obs: " + cab.Observations;

                string strAvisos = string.Empty;



                if (lines.Count > 0)
                {
                    foreach (Lin item in lines)
                    {
                        Database Armazem = new Database();
                        IntBELinhaDocumentoInterno linha = new IntBELinhaDocumentoInterno();
                        PriEngine.Engine.Internos.Documentos.AdicionaLinha(objDocInterno, item.Article, item.Warehouse, item.Warehouse);

                        if (SystemInfo.LogDev == "1")
                        {
                            Log.Warning("----------GRAVA---------");
                            Log.Information(JsonConvert.SerializeObject(objDocInterno));
                            Log.Information(JsonConvert.SerializeObject(objDocInterno.Linhas));
                        }
                        linha = objDocInterno.Linhas.GetEdita(objDocInterno.Linhas.NumItens);
                        linha.Quantidade = item.Quantity;
                        linha.Lote = "<L01>";
                        //linha.Armazem = Armazem.GetArmazemERP(linha.Artigo);
                        linha.Armazem = item.Warehouse;
                        linha.Localizacao = item.Warehouse;

                        if (linha.Unidade.ToUpper() != item.Unity.ToUpper())
                        {

                            if (PriEngine.Engine.Base.UnidadesConversao.Existe(item.Unity, linha.Unidade))
                            {
                                BasBEUnidadeConversao ac = PriEngine.Engine.Base.UnidadesConversao.Edita(item.Unity, linha.Unidade);
                                linha.FactorConv = ac.FactorConversao; //PriEngine.Engine.Base.UnidadesConversao.DaValorAtributo(item.Unity, linha.Unidade, "FactorConversao");
                            }

                            linha.Unidade = item.Unity;
                            //     linha.PrecUnit = linha.PrecUnit* linha.FactorConv;
                           // linha.PrecUnit = PriEngine.Engine.Base.Artigos.DaValorAtributo(item.Article, "PCMedio") * linha.FactorConv;

                        }
                               linha.PrecUnit = PriEngine.Engine.Base.Artigos.DaValorAtributo(item.Article, "PCPadrao"); 



                        //string strArtigo = Convert.ToString(item.Article);
                        //string strArmazem = Convert.ToString(item.Warehouse);
                        //double dblQtd = Convert.ToDouble(item.Quantity);
                        //string strLote = "<L01>";
                        //
                        //PriEngine.Engine.Internos.Documentos.AdicionaLinha(objDocInterno, strArtigo, strArmazem, Quantidade: dblQtd, Lote: strLote);
                    }
                }
                else throw new Exception("No lines found ID: " + cab.Id + ". ");

                if (PriEngine.Engine.Internos.Documentos.ValidaActualizacao(objDocInterno, ref strAvisos))
                {
                    strAvisos = String.Empty;
                    PriEngine.Engine.Internos.Documentos.Actualiza(objDocInterno, ref strAvisos);

                    regravarDocumentoInterno_SQ(objDocInterno.ID, cab.Date);
                    if (SystemInfo.LogDev == "1")
                    {
                        Log.Warning("----------REGRAVA---------");
                        Log.Information(JsonConvert.SerializeObject(objDocInterno));
                        Log.Information(JsonConvert.SerializeObject(objDocInterno.Linhas));
                    }
                    docNumber = objDocInterno.Tipodoc + " " + objDocInterno.Serie;
                    if (strAvisos.Length > 0)
                    {
                        Logger.WriteEntry("Error writing document ID: " + cab.Id + " - ERP Code: " + objDocInterno.Documento + ". \n" + strAvisos, EventLogEntryType.Warning);
                    }
                }
                else
                {
                    if (strAvisos.Length > 0)
                    {
                        throw new Exception("Error writing document ID: " + cab.Id + ". \n" + strAvisos);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return true;
        }
        private string regravarDocumentoInterno_SQ(String id, DateTime date)
        {

            IntBEDocumentoInterno objDocInterno;
            objDocInterno = PriEngine.Engine.Internos.Documentos.EditaID(id);
            objDocInterno.Data = date;
            objDocInterno.DataEntrega = date;



            foreach (IntBELinhaDocumentoInterno item in objDocInterno.Linhas)
            {
                item.DataStock = date;
            }

            string strAvisos = "";

            PriEngine.Engine.Internos.Documentos.Actualiza(objDocInterno, ref strAvisos);
            return strAvisos;

        }

        public bool UpdateArticle(Article article)
        {
            try
            {
                BasBEArtigo objArticle = new BasBEArtigo();

                if (PriEngine.Engine.Base.Artigos.Existe(article.ArticleCode))
                {
                    objArticle = PriEngine.Engine.Base.Artigos.Edita(article.ArticleCode);
                    objArticle.EmModoEdicao = true; 
                }
                else
                {
                    objArticle = PriEngine.Engine.Base.Artigos.PreencheDadosRelacionados(objArticle);
                    objArticle.EmModoEdicao = false; 
                    objArticle.Descricao = article.ArticleName;
                    objArticle.TrataLotes = false; //article.GenerateLots;
                    objArticle.MovStock = article.MovStock ? "S" : "N";
                    objArticle.TrataNumerosSerie = false; //article.GenerateSerialNumbers;
                    objArticle.UnidadeBase = article.UnityGlobal;
                    objArticle.UnidadeEntrada = article.UnityIn;
                    objArticle.UnidadeSaida = article.UnityOut;
                  
                }
                 
                objArticle.Artigo = article.ArticleCode;
                objArticle.CodBarras = article.BarCode;
                objArticle.UnidadeCompra = article.UnityBuy;
                objArticle.UnidadeVenda = article.UnitySale;
                objArticle.Desconto = article.Discount;
                objArticle.FornecedorPrincipal = article.Provider;
                objArticle.Anulado = article.Deleted;
                objArticle.SujeitoRetencao = article.Retention;
                objArticle.SujeitoDevolucao = article.Devolution;
                objArticle.Observacoes = article.Observations;
                objArticle.DataUltimaActualizacao = article.ModificationDate;
                objArticle.DescricaoAbrev = article.Abreviation;
                objArticle.Familia = article.Family;
                objArticle.TipoArtigo = article.ArticleType;
                
                string strAvisos = string.Empty;

                PriEngine.Engine.Base.Artigos.DaValorAtributo("AA0001", "PCMEDIO");
                
                PriEngine.Engine.Base.Artigos.Actualiza(objArticle, ref strAvisos);


                if (strAvisos.Length > 0)
                {
                    throw new Exception("Error writing article ID: " + article.Id + " Code: " + article.ArticleCode + ". \n" + strAvisos);
                }

                BasBEArtigoMoeda artigoMoeda;

                if (PriEngine.Engine.Base.ArtigosPrecos.Existe(article.ArticleCode, "EUR", article.UnityGlobal))
                {
                    artigoMoeda = PriEngine.Engine.Base.ArtigosPrecos.Edita(article.ArticleCode, "EUR", article.UnityGlobal);
                }   
                else
                {
                    artigoMoeda = new BasBEArtigoMoeda();
                }


                artigoMoeda.Artigo = article.ArticleCode;
                artigoMoeda.Moeda = "EUR";
                artigoMoeda.Unidade = article.UnityGlobal;
                //artigoMoeda.PVP1 = article.PVP1;
                //artigoMoeda.PVP2 = article.PVP2;
                //artigoMoeda.PVP3 = article.PVP3;
                //artigoMoeda.PVP4 = article.PVP4;
                //artigoMoeda.PVP5 = article.PVP5;
                //artigoMoeda.PVP6 = article.PVP6;

                PriEngine.Engine.Base.ArtigosPrecos.Actualiza(artigoMoeda);

              
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            return true;
        }
       
    }
}
