public static short DocCab_getMes(VgTipoDoc myTipoDoc, DateTime myDate)
 {
     if (myTipoDoc.temNumMensal == true)
     {
         return((short)myDate.Month);
     }
     else
     {
         return(0);
     }
 }
        /// <summary>
        /// Assina o documento
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="encodingPageNumber">por defeiro: "Windows-1252"</param>
        /// <returns></returns>
        public int AssinaDoc(IDbConnection connection, int encodingPageNumber = RSAEncriptionHelpers.VGEST_ENCODING_PAGE)
        {
            int    result    = -1;
            string errorText = "";

            try
            {
                VgTipoDoc myTipoDoc = connection.QueryFirstOrDefault <VgTipoDoc>("SELECT * FROM TipoDoc WHERE TipoDoc = @TipoDoc", new { TipoDoc = TipoDoc });

                string myTipoDocID = myTipoDoc.TipoDoc;
                string td          = TipoDoc;
                int    ad          = Ano;
                short  md          = Mes;
                int    nd          = NumDoc;


                using (IDbTransaction transaction = connection.BeginTransaction())
                {
                    DocCab ultDocAssinado = connection.QueryFirstOrDefault <DocCab>(
                        "SELECT TOP 1 * from DocCab WHERE TipoDoc = @TipoDoc AND Ano = @Ano AND Assinatura != '' AND Assinatura IS NOT NULL " +
                        "ORDER BY AssinadoEm DESC, NumDoc DESC"
                        , new { TipoDoc = myTipoDocID, Ano = ad }, transaction);

                    string chaveAnt = "";
                    int    newAD    = ad;
                    int    newND    = nd;
                    short  newMD    = md;


                    DateTime dataAssina   = connection.QuerySingle <DateTime>("SELECT GETDATE()", transaction: transaction);
                    DateTime ultDatAssina = dataAssina;
                    int      ultNumAssina = 0;

                    if (ultDocAssinado != null)
                    {
                        chaveAnt     = ultDocAssinado.Assinatura;
                        ultNumAssina = ultDocAssinado.NumDoc;
                        ultDatAssina = ultDocAssinado.AssinadoEm == null ? DateTime.Now : ultDocAssinado.AssinadoEm.Value;

                        if (ultDocAssinado.DataDoc > DataDoc)
                        {
                            DataDoc = ultDocAssinado.DataDoc;
                            newAD   = ultDocAssinado.Ano;
                            newMD   = ultDocAssinado.Mes;
                        }
                    }

                    if (nd < 0)
                    {
                        TDSerie thisSerie = connection.QueryFirstOrDefault <TDSerie>("SELECT * FROM TDSerie WHERE TipoDoc = @TipoDoc AND Ano = @Ano AND Mes = @Mes",
                                                                                     new { TipoDoc = myTipoDocID, Ano = newAD, Mes = newMD }, transaction);

                        newND = (thisSerie.UltNumero >= 0 ? thisSerie.UltNumero.Value : 0) + 1;
                        if (newND != ultNumAssina + 1)
                        {
                            errorText = "Problemas na sequência de numeração dos documentos";
                            result    = 0;
                        }

                        int newDocAssinado = connection.QueryFirstOrDefault <int>(
                            "SELECT recno FROM DocCab WHERE TipoDoc = @TipoDoc AND Ano = @Ano AND Mes = @Mes AND NumDoc = @NumDoc",
                            new { TipoDoc = TipoDoc, Ano = newAD, Mes = newMD, NumDoc = newND }, transaction);

                        if (newDocAssinado != 0)
                        {
                            errorText = "Problemas na sequência de numeração dos documentos (" + newAD.ToString() + newMD.ToString() + "/" + newND.ToString() + " = " + newDocAssinado.ToString() + ")";
                            result    = 0;
                        }
                        if (dataAssina < ultDatAssina)
                        {
                            errorText = "Data de assinatura do último documento posterior à data actual";
                            result    = 0;
                        }

                        if (result != 0)
                        {
                            if (DataDoc > thisSerie.UltData)
                            {
                                thisSerie.UltData = DataDoc;
                            }
                            thisSerie.UltNumero = newND;
                            connection.Update(thisSerie, transaction: transaction);
                        }
                    }
                    if (result != 0)
                    {
                        string assMessage = "";
                        Assinatura  = SetAssinatura(TipoDoc, newAD, newMD, newND, DataDoc, DtUpdate, HrUpdate, TotalDoc, chaveAnt, ref assMessage, encodingPageNumber);
                        AssinadoPor = CriadoPor;
                        AssinadoMsg = assMessage;
                        AssinadoEm  = dataAssina;
                        AssinaVGest = SetAssinaturaVisualGest(TipoDoc, newAD, newMD, newND, Classe, Terceiro, Nome, MoradaDoc, NIF, TotalDoc.HasValue ? TotalDoc.Value : 0, encodingPageNumber);
                        VersaoChave = vgChaveVersao;
                        Certificado = vgCertificado;

                        if (myTipoDoc.Tipologia == 7)
                        {
                            //documento manual
                            if (DocOrig == null || DocOrig == "")
                            {
                                DocOrig = newND.ToString().PadLeft((myTipoDoc.NumDigitos.HasValue ? myTipoDoc.NumDigitos.Value : 0), '0');
                            }
                            VersaoChave = vgChaveVersao + "-" + myTipoDoc.InvoiceType + "M" + " " + DocOrig;
                        }
                        else
                        {
                            //if (thisDocCab.DocOrig == "")
                            if (DocOrig == null || DocOrig == "")
                            {
                                DocOrig = FmtDocID((myTipoDoc.NumDigitos.HasValue ? myTipoDoc.NumDigitos.Value : (short)0), false);
                            }

                            if (myTipoDoc.TemDesNum == true)
                            {
                                DesMov = myTipoDoc.DesMov + " " + DocOrig;
                            }
                        }

                        // TODO: GENERATE QR CODE2
                        //thisDocCab.QrCode = GetQrCode2(fmtDocID(thisDocCab.TipoDoc, newAD, newMD, newND, getShort(myTipoDoc.NumDigitos), true), scale: 2);
                        int docRecno = connection.QueryFirstOrDefault <int>(
                            "select recno from DocCab where TipoDoc = @TipoDoc and Ano = @Ano and Mes = @Mes and NumDoc = @NumDoc",
                            new { TipoDoc = TipoDoc, Ano = Ano, Mes = Mes, NumDoc = NumDoc }, transaction: transaction);

                        //QrCode = GetQrCode2("90" + String.Format("{0:000000}", docRecno));

                        //throw new Exception("not implemented TransactionScope myTranScope = new TransactionScope");
                        //using (TransactionScope myTranScope = new TransactionScope())
                        //{
                        try
                        {
                            var queryParameters = new DynamicParameters();
                            queryParameters.Add("@TipoDoc", myTipoDoc.TipoDoc);
                            queryParameters.Add("@AnoDoc", Ano);
                            queryParameters.Add("@AnoNew", newAD);
                            queryParameters.Add("@MesDoc", Mes);
                            queryParameters.Add("@MesNew", newMD);
                            queryParameters.Add("@NumDoc", NumDoc);
                            queryParameters.Add("@NumNew", newND);

                            connection.Execute(
                                $@"UPDATE DocCab SET 
                                    DataDoc = @DataDoc,
                                    Assinatura = @Assinatura,
                                    AssinadoPor = @AssinadoPor,
                                    AssinadoMsg = @AssinadoMsg,
                                    AssinadoEm = @AssinadoEm,
                                    AssinaVGest = @AssinaVGest,
                                    VersaoChave = @VersaoChave,
                                    Certificado = @Certificado,
                                    DocOrig = @DocOrig,
                                    DesMov = @DesMov
                                WHERE TipoDoc = @TipoDoc and Ano = @Ano and Mes = @Mes and NumDoc = @NumDoc",
                                new {
                                TipoDoc     = TipoDoc,
                                Ano         = Ano,
                                Mes         = Mes,
                                NumDoc      = NumDoc,
                                DataDoc     = DataDoc,
                                Assinatura  = Assinatura,
                                AssinadoPor = AssinadoPor,
                                AssinadoMsg = AssinadoMsg,
                                AssinadoEm  = AssinadoEm,
                                AssinaVGest = AssinaVGest,
                                VersaoChave = VersaoChave,
                                Certificado = Certificado,
                                DocOrig     = DocOrig,
                                DesMov      = DesMov
                            }, transaction: transaction);

                            var affectedRows = connection.Execute("UpdtDocCabKey", queryParameters,
                                                                  commandType: CommandType.StoredProcedure, transaction: transaction);

                            transaction.Commit();

                            Ano    = newAD;
                            Mes    = newMD;
                            NumDoc = newND;
                        }
                        catch (Exception ex)
                        {
                            string exMessage = ex.InnerException != null ? ex.InnerException.Message : ex.Message;
                            errorText   = "Problemas na atribuição do número definitivo ao documento.\r\nTente assinar novamente.\r\n" + exMessage;
                            Assinatura  = "";
                            AssinadoPor = null;
                            AssinadoMsg = "";
                            AssinadoEm  = null;
                            AssinaVGest = "";
                            VersaoChave = null;
                            Certificado = null;
                            result      = 0;
                        }
                    }
                }
                return(result);
            }
            catch (Exception ex)
            {
                errorText = ex.Message;
                return(0);
            }
        }
        public bool GeraNumeração(IDbConnection connection, IDbTransaction transaction)
        {
            VgTipoDoc tipoDocObj = connection.QueryFirstOrDefault <VgTipoDoc>(
                @"select TipoDoc, temNumMensal, temAssinatura from TipoDoc where TipoDoc = @TipoDoc",
                new { TipoDoc = TipoDoc },
                transaction);

            if (tipoDocObj == null)
            {
                return(false);
            }

            bool numeroProvisorio = tipoDocObj.temAssinatura == true && string.IsNullOrEmpty(Assinatura);

            if (DataDoc == null)
            {
                DataDoc = DateTime.Now;
            }
            Ano = DataDoc.Value.Year;
            if (tipoDocObj.temNumMensal == true)
            {
                Mes = Convert.ToInt16(DataDoc.Value.Month);
            }
            else
            {
                Mes = 0;
            }

            TDSerie docSerie = connection.QueryFirstOrDefault <TDSerie>(
                @"select [TipoDoc]
                        ,[Ano]
                        ,[Mes]
                        ,[Sequencial]
                        ,[Radical]
                        , ISNULL([PriNumero], 0) as [PriNumero]
                        ,[PriData]
                        , ISNULL([UltNumero], 0) as [UltNumero]
                        ,[UltData]
                        ,[Prefixo]
                        ,[Sufixo]
                        ,ISNULL([ContaDocs], 0) as [ContaDocs]
                        ,ISNULL([PriProvisorio], 0) as [PriProvisorio]
                        ,ISNULL([UltProvisorio], 0) as [UltProvisorio]
                        ,ISNULL([ContaProv], 0) as [ContaProv]  
                from TDSerie where TipoDoc = @TipoDoc and Ano = @Ano and Mes = @Mes",
                new { TipoDoc = TipoDoc, Ano = Ano, Mes = Mes },
                transaction);

            if (docSerie == null)
            {
                docSerie = new TDSerie
                {
                    TipoDoc       = TipoDoc,
                    Ano           = Ano,
                    Mes           = Mes,
                    UltNumero     = 0,
                    UltProvisorio = 0,
                    PriNumero     = 0,
                    PriProvisorio = 0,
                    Sequencial    = Mes > 1,
                    ContaDocs     = 0,
                    ContaProv     = 0
                };

                connection.Insert(docSerie, transaction: transaction);
            }

            if (docSerie.ContaDocs == null)
            {
                docSerie.ContaDocs = 0;
            }
            if (docSerie.ContaProv == null)
            {
                docSerie.ContaProv = 0;
            }

            // verifica se existem documentos na serie atual
            if (docSerie.ContaDocs + docSerie.ContaProv == 0)
            {
                //1º doc do mês
                docSerie.PriData = DataDoc;
                if (docSerie.Sequencial == true)
                {
                    TDSerie prevSerie = connection.QueryFirstOrDefault <TDSerie>(
                        @"select TOP 1 
                                [TipoDoc]
                                ,[Ano]
                                ,[Mes]
                                ,[Sequencial]
                                ,[Radical]
                                , ISNULL([PriNumero], 0) as [PriNumero]
                                ,[PriData]
                                , ISNULL([UltNumero], 0) as [UltNumero]
                                ,[UltData]
                                ,[Prefixo]
                                ,[Sufixo]
                                ,ISNULL([ContaDocs], 0) as [ContaDocs]
                                ,ISNULL([PriProvisorio], 0) as [PriProvisorio]
                                ,ISNULL([UltProvisorio], 0) as [UltProvisorio]
                                ,ISNULL([ContaProv], 0) as [ContaProv] 
                            from TDSerie 
                            where TipoDoc = @TipoDoc and ((Ano = @Ano and Mes < @Mes) or Ano < @Ano) order by Ano, Mes DESC",
                        new { TipoDoc = TipoDoc, Ano = Ano, Mes = Mes },
                        transaction);

                    docSerie.UltNumero     = prevSerie.UltNumero;
                    docSerie.UltProvisorio = prevSerie.UltProvisorio;
                }
                else
                {
                    docSerie.UltNumero     = docSerie.PriNumero;
                    docSerie.UltProvisorio = docSerie.PriProvisorio;
                }
                docSerie.PriNumero     = docSerie.UltNumero + 1;
                docSerie.PriProvisorio = docSerie.UltProvisorio + 1;
            }

            docSerie.UltData = DataDoc;

            int ultNum = 0;

            int docNum = Math.Abs(NumDoc);

            if (numeroProvisorio)
            {
                if (docSerie.UltProvisorio == null)
                {
                    docSerie.UltProvisorio = 0;
                }
                ultNum = docSerie.UltProvisorio.Value + 1;
                //compara com o nº do documento para detetar colisões na numeração
                if (docNum >= ultNum)
                {
                    ultNum = docNum + 1;
                }
                docSerie.UltProvisorio = ultNum;
                docSerie.ContaProv     = 1 + docSerie.UltProvisorio - docSerie.PriProvisorio;
                ultNum = -ultNum;
            }
            else
            {
                ultNum = docSerie.UltNumero.Value + 1;
                //compara com o nº do documento para detetar colisões na numeração
                if (docNum >= ultNum)
                {
                    ultNum = docNum + 1;
                }
                docSerie.UltNumero = ultNum;
                docSerie.ContaDocs = 1 + docSerie.UltNumero - docSerie.PriNumero;
            }
            NumDoc = ultNum;

            connection.Update(docSerie, transaction: transaction);

            return(true);
        }
 public VgTipoDoc getTipoDoc(IDbConnection connection, IDbTransaction transaction = null)
 {
     return(VgTipoDoc.findByKey(TipoDoc, connection, transaction));
 }