public void Excluir(Unidade unidade)
        {
            var zap = this.FetchZapUnidade();
            var fullHierarquia = unidade.GetFullLevelHierarquia() + '%';

            //deleta a undidade
            this.Db.Delete(unidade);

            //deleta os arquivos da unidade
            this.Db.Execute("DELETE UnidadeAnexo, Arquivo FROM UnidadeAnexo INNER JOIN Arquivo ON Arquivo.Id = UnidadeAnexo.AnexoId WHERE UnidadeAnexo.UnidadeId = @0", unidade.Id);

            //deleta todos os usuarios da unidade
            this.Db.Execute("DELETE FROM Usuario WHERE Usuario.UnidadeId = @0", unidade.Id);

            //deleta todas as unidades vinculadas
            this.Db.Execute("DELETE FROM Unidade WHERE Hierarquia LIKE @0", fullHierarquia);

            //deleta todos os arquivos das unidades vinculadas
            this.Db.Execute(PetaPoco.Sql.Builder.Append("DELETE UnidadeAnexo, Arquivo")
                                                .Append("FROM UnidadeAnexo")
                                                .Append("INNER JOIN Arquivo ON Arquivo.Id = UnidadeAnexo.AnexoId")
                                                .Append("INNER JOIN Unidade ON Unidade.Id = UnidadeAnexo.UnidadeId")
                                                .Append("WHERE Unidade.Hierarquia LIKE @0", fullHierarquia));

            //deleta todos os usuarios das unidades vinculadas
            this.Db.Execute(PetaPoco.Sql.Builder.Append("DELETE Usuario")
                                                .Append("FROM Usuario")
                                                .Append("INNER JOIN Unidade ON Unidade.Id = Usuario.UnidadeId")
                                                .Append("WHERE Unidade.Hierarquia LIKE @0", fullHierarquia));
        }
        public decimal TotalPorUnidade(Unidade unidadePai, int mes, int ano)
        {
            var sql = PetaPoco.Sql.Builder.Append("SELECT IF(SUM(Receita.Total) IS NULL, 0, SUM(Receita.Total)) as Total ")
                                          .Append("FROM Receita")
                                          .Append("INNER JOIN Unidade ON Unidade.Id = Receita.UnidadeId")
                                          .Append("WHERE (Unidade.Hierarquia LIKE @0 OR Unidade.Id = @1) AND Receita.Mes = @2 AND Receita.Ano = @3", unidadePai.GetFullLevelHierarquia() + '%', unidadePai.Id, mes, ano);

            return this.Db.ExecuteScalar<decimal>(sql);
        }
        public List<Agenda> Search(DateTime start, DateTime end, Unidade unidade)
        {
            var sql = PetaPoco.Sql.Builder.Append("SELECT Agenda.*")
                                          .Append("FROM Agenda")
                                          .Append("INNER JOIN Unidade ON Unidade.Id = Agenda.UnidadeId")
                                          .Append("WHERE Agenda.Data BETWEEN @0 AND @1", start, end)
                                          .Append("AND (Unidade.Hierarquia LIKE @0 OR Unidade.Id = @1)", unidade.GetFullLevelHierarquia() + "%", unidade.Id);

            return this.Db.Fetch<Agenda>(sql);
        }
        public List<DespesaCentroCusto> DespesaUnidadesByCentral(Unidade central, int mes, int ano)
        {
            var sql = PetaPoco.Sql.Builder.Append("SELECT Unidade.Nome, SUM(Despesa.Total) as Total")
                                          .Append("FROM Despesa")
                                          .Append("INNER JOIN Unidade ON Unidade.Id = Despesa.UnidadeId")
                                          .Append("WHERE Unidade.Hierarquia LIKE @0", central.GetFullLevelHierarquia() + '%')
                                          .Append("AND Despesa.Status = @0", DespesaStatus.AUTORIZADA)
                                          .Append("AND MONTH(Despesa.Data) = @0 AND YEAR(Despesa.Data) = @1", mes + 1, ano)
                                          .Append("GROUP BY Unidade.Nome");

            return this.Db.Fetch<DespesaCentroCusto>(sql);
        }
        public List<Receita> ReceitasUnidadesFilhas(Unidade central, int mes, int ano)
        {
            var sql = PetaPoco.Sql.Builder.Append("SELECT Receita.*, Unidade.*")
                                          .Append("FROM Receita")
                                          .Append("INNER JOIN Unidade ON Unidade.Id = Receita.UnidadeId")
                                          .Append("WHERE Receita.Mes = @0 AND Receita.Ano = @1", mes, ano)
                                          .Append("AND Unidade.Hierarquia LIKE @0", central.GetFullLevelHierarquia() + '%')
                                          .Append("ORDER BY Receita.Mes, Receita.Ano, Unidade.Nome");

            return this.Db.Fetch<Receita, Unidade, Receita>((r, u) =>
            {
                r.Unidade = u;
                return r;
            }, sql);
        }
        public List<Historico> Search(DateTime start, DateTime end, Unidade unidade)
        {
            var sql = PetaPoco.Sql.Builder.Append("SELECT Historico.*, Condominio.*")
                                          .Append("FROM Historico")
                                          .Append("INNER JOIN Condominio ON Condominio.Id = Historico.CondominioId")
                                          .Append("INNER JOIN Unidade ON Unidade.Id = Condominio.UnidadeId")
                                          .Append("WHERE Historico.ProximoContato BETWEEN @0 AND @1", start, end)
                                          .Append("AND (Unidade.Hierarquia LIKE @0 OR Unidade.Id = @1)", unidade.GetFullLevelHierarquia() + "%", unidade.Id);

            return this.Db.Fetch<Historico, Condominio, Historico>((h, c)=> {

                h.Condominio = c;

                return h;
            }, sql);
        }
        public void Add(Unidade unidade)
        {
            var zap = this.FetchZapUnidade();

            if (unidade.Cidade != null) {
                unidade.CidadeId = unidade.Cidade.Id;
            }

            unidade.Hierarquia = zap.GetLevelHierarquia();

            this.Db.Insert(unidade);

            this.SetHierarquia(unidade.GetFullLevelHierarquia(), unidade.Unidades);

            var usuarioRepositorio = new UsuarioRepositorio();
            usuarioRepositorio.UpdateUnidade(unidade.Usuarios, unidade.Id);
        }
        public List<Usuario> Fetch(string nome, Unidade unidade)
        {
            var sql = PetaPoco.Sql.Builder.Append("SELECT Usuario.*, Unidade.*")
                                          .Append("FROM Usuario")
                                          .Append("INNER JOIN Unidade ON Unidade.Id = Usuario.UnidadeId")
                                          .Append("WHERE (Unidade.Id = @0 OR Unidade.Hierarquia LIKE @1)", unidade.Id, unidade.GetFullLevelHierarquia() + '%')
                                          .Append("AND Usuario.Nome LIKE @0", '%' + nome + '%')
                                          .Append("ORDER BY Usuario.Nome");

            return this.Db.Fetch<Usuario, Unidade, Usuario>((u, un) =>
            {

                u.Unidade = un;

                return u;
            }, sql).ToList();
        }
        public List<Usuario> FetchUsuariosByUnidade(Unidade unidade, bool all)
        {
            var sql = PetaPoco.Sql.Builder.Append("SELECT Usuario.*, Unidade.*")
                                          .Append("FROM Usuario")
                                          .Append("INNER JOIN Unidade ON Unidade.Id = Usuario.UnidadeId")
                                          .Append("WHERE Unidade.Id = @0", unidade.Id);

            if (all) {
                sql.Append("OR Unidade.Hierarquia LIKE @0", unidade.GetFullLevelHierarquia() + '%');
            }

            return this.Db.Fetch<Usuario, Unidade, Usuario>((u, un) =>
            {

                u.Unidade = un;

                return u;
            }, sql).ToList();
        }
        //public List<Receita> ReceitasPorCentral(int mes, int ano, Unidade central)
        //{
        //    var sql = PetaPoco.Sql.Builder.Append("SELECT Unidade.Id, Unidade.Nome, SUM(Receita.Total) as Total")
        //                                  .Append("FROM Unidade")
        //                                  .Append("INNER JOIN Unidade ON Unidade.Id = Receita.UnidadeId")
        //                                  .Append("INNER JOIN Unidade AS Filha ON INSTR(Filha.Hierarquia, CONCAT(Unidade.Id, '.')) > 0")
        //                                  .Append("INNER JOIN Receita ON Receita.UnidadeId = Filha.Id")
        //                                  .Append("WHERE Receita.Mes = @0 AND Receita.Ano = @1", mes, ano)
        //                                  .Append("AND Unidade.Tipo = @0", UnidadeTipo.CENTRAL)
        //                                  .Append("GROUP BY Unidade.Nome")
        //                                  .Append("ORDER BY Receita.Mes, Receita.Ano, Unidade.Nome");
        //    return this.Db.Fetch<Receita, Unidade, Receita>((r, u) =>
        //    {
        //        r.Unidade = u;
        //        return r;
        //    }, sql);
        //}
        public decimal TotalPorCentral(Unidade central, int mes, int ano)
        {
            var sql = PetaPoco.Sql.Builder.Append("SELECT IF(SUM(Receita.Total) IS NULL, 0, SUM(Receita.Total)) as Total ")
                                          .Append("FROM Receita")
                                          .Append("INNER JOIN Unidade ON Unidade.Id = Receita.UnidadeId")
                                          .Append("WHERE Unidade.Hierarquia LIKE @2 AND Receita.Mes = @0 AND Receita.Ano = @1", mes, ano, central.GetFullLevelHierarquia() + '%');

            return this.Db.ExecuteScalar<decimal>(sql);
        }
        public List<Receita> FetchAll(Unidade unidade)
        {
            var sql = PetaPoco.Sql.Builder.Append("SELECT Receita.*, (SELECT SUM(Valor) FROM ReceitaItem WHERE ReceitaItem.ReceitaId = Receita.Id) as Total, Unidade.*")
                                          .Append("FROM Receita")
                                          .Append("INNER JOIN Unidade ON Unidade.Id = Receita.UnidadeId")
                                          .Append("WHERE Unidade.Hierarquia LIKE @0 OR Unidade.Id = @1", unidade.GetFullLevelHierarquia() + '%', unidade.Id)
                                          .Append("ORDER BY Receita.Mes, Receita.Ano, Unidade.Nome");

            return this.Db.Fetch<Receita, Unidade, Receita>((r, u) =>
            {
                r.Unidade = u;
                return r;
            }, sql);
        }
        public List<Despesa> Fetch(DespesaPesquisa parametro, Unidade unidade, Paging paging)
        {
            var sql = PetaPoco.Sql.Builder.Append("SELECT SQL_CALC_FOUND_ROWS Despesa.*, Fornecedor.*, Usuario.*, Unidade.*")
                                          .Append("FROM Despesa")
                                          .Append("INNER JOIN Fornecedor ON Fornecedor.Id = Despesa.FornecedorId")
                                          .Append("INNER JOIN Usuario ON Usuario.Id = Despesa.UsuarioId")
                                          .Append("INNER JOIN Unidade ON Unidade.Id = Despesa.UnidadeId")
                                          .Append("WHERE (Unidade.Hierarquia LIKE @0 OR Unidade.Id = @1)", unidade.GetFullLevelHierarquia() + "%", unidade.Id);

            //5 TODOS
            if (parametro.Status != 5) {
                sql.Append(" AND Despesa.Status = @0", parametro.Status);
            }

            if (parametro.Usuario != null) {
                sql.Append(" AND Despesa.UsuarioId = @0", parametro.Usuario.Id);
            }

            if (parametro.Unidade != null) {
                sql.Append(" AND Despesa.UnidadeId = @0", parametro.Unidade.Id);
            }

            if (parametro.Fornecedor != null) {
                sql.Append(" AND Despesa.FornecedorId = @0", parametro.Fornecedor.Id);
            }

            if (parametro.Numero != null)
            {
                sql.Append(" AND Despesa.Numero = @0", parametro.Numero);
            }

            if (parametro.ValorMenor > 0 && parametro.ValorMaior > 0) {
                sql.Append(" AND Despesa.Total >= @0 AND Despesa.Total <= @1", parametro.ValorMenor, parametro.ValorMaior);
            } else if (parametro.ValorMenor > 0){
                sql.Append(" AND Despesa.Total >= @0", parametro.ValorMenor);
            } else if (parametro.ValorMaior > 0){
                sql.Append(" AND Despesa.Total <= @0", parametro.ValorMaior);
            }

            var dataNull = new DateTime(1, 1, 1, 0, 0, 0);
            if (parametro.DataInicio > dataNull && parametro.DataFim > dataNull) {
                sql.Append(" AND Despesa.Data >= @0 AND Despesa.Data <= @1", parametro.DataInicio, parametro.DataFim);
            } else if (parametro.DataInicio > dataNull)
            {
                sql.Append(" AND Despesa.Data >= @0", parametro.DataInicio);
            } else if (parametro.DataFim > dataNull)
            {
                sql.Append(" AND Despesa.Data <= @0", parametro.DataFim);
            }

            sql.Append("ORDER BY Despesa.Data DESC");
            sql.Append("LIMIT @0, @1", paging.LimitDown, paging.LimitUp);

            this.Db.BeginTransaction();

            var despesas = this.Db.Fetch<Despesa, Fornecedor, Usuario, Unidade, Despesa>((d, f, us, un) =>
            {

                d.Fornecedor = f;
                d.Usuario = us;
                d.Unidade = un;

                return d;
            }, sql);

            paging.total = this.Db.ExecuteScalar<int>("SELECT FOUND_ROWS()");

            this.Db.CompleteTransaction();

            return despesas;
        }
        public List<Unidade> FetchUnidadesFilhas(Unidade unidade)
        {
            var sql = PetaPoco.Sql.Builder.Append("SELECT Unidade.*, Cidade.*")
                                          .Append("FROM Unidade")
                                          .Append("LEFT JOIN Cidade ON Cidade.Id = Unidade.CidadeId")
                                          .Append("WHERE Unidade.Hierarquia LIKE @0", unidade.GetFullLevelHierarquia() + "%")
                                          .Append("ORDER BY Unidade.Nome");

            return this.Db.Fetch<Unidade, Cidade, Unidade>((u, c) =>
            {
                u.Cidade = c;

                return u;
            }, sql).ToList();
        }
        public List<Condominio> Search(CondominioSearch param, Unidade unidade)
        {
            var sql = PetaPoco.Sql.Builder.Append("SELECT Condominio.*, Endereco.*, Cidade.*, Unidade.*")
                                          .Append("FROM Condominio")
                                          .Append("INNER JOIN Endereco ON Endereco.Id = Condominio.EnderecoId")
                                          .Append("LEFT JOIN Cidade ON Cidade.Id = Endereco.CidadeId")
                                          .Append("INNER JOIN Unidade ON Unidade.Id = Condominio.UnidadeId")
                                          .Append("AND (Unidade.Hierarquia LIKE @0 OR Unidade.Id = @1)", unidade.GetFullLevelHierarquia() + "%", unidade.Id);

            if (param.Rank > 0)
            {
                sql.Where("Condominio.Rank = @0", param.Rank);
            }

            if(param.Nome != null && param.Nome.Length > 0)
            {
                sql.Where("Condominio.Nome LIKE @0", "%" + param.Nome + "%");
            }

            if (param.Administradora != null)
            {
                sql.Where("Condominio.AdministradoraId = @0", param.Administradora.Id);
            }

            if (param.Unidade != null)
            {
                sql.Where("Condominio.UnidadeId = @0", param.Unidade.Id);
            }

            if (param.Endereco != null)
            {

                if (param.Endereco.Cep != null && param.Endereco.Cep.Length > 0)
                {
                    sql.Where("Endereco.Cep LIKE @0", "%" + param.Endereco.Cep + "%");
                }

                if (param.Endereco.Numero != null && param.Endereco.Numero.Length > 0)
                {
                    sql.Where("Endereco.Numero LIKE @0", "%" + param.Endereco.Numero + "%");
                }

                if (param.Endereco.Rua!=null && param.Endereco.Rua.Length > 0)
                {
                    sql.Where("Endereco.Rua LIKE @0", "%" + param.Endereco.Rua + "%");
                }

                if (param.Endereco.Bairro != null && param.Endereco.Bairro.Length > 0)
                {
                    sql.Where("Endereco.Bairro LIKE @0", "%" + param.Endereco.Bairro + "%");
                }

                if (param.Endereco.Cidade != null)
                {
                    sql.Where("Endereco.CidadeId = @0", param.Endereco.Cidade.Id);
                }
            }

            return this.Db.Fetch<Condominio, Endereco, Cidade, Unidade, Condominio>((c, e, cd, u)=> {

                c.Endereco = e;
                c.Endereco.Cidade = cd;
                c.Unidade = u;

                return c;
            }, sql);
        }
        public List<Unidade> GetUnidadesFilhas(Unidade unidade)
        {
            var sql = PetaPoco.Sql.Builder.Append("SELECT Unidade.*")
                                          .Append("FROM Unidade")
                                          .Append("WHERE Unidade.Hierarquia LIKE @0", unidade.GetFullLevelHierarquia() + "%")
                                          .Append("ORDER BY Unidade.Nome");

            return this.Db.Fetch<Unidade>(sql).ToList();
        }
        public void Update(Unidade unidade)
        {
            if (unidade.Cidade != null)
            {
                unidade.CidadeId = unidade.Cidade.Id;
            }

            unidade.Hierarquia = this.Fetch(unidade.Id).Hierarquia;

            this.Db.Update(unidade);

            this.SetHierarquia(unidade.GetFullLevelHierarquia(), unidade.Unidades);

            var usuarioRepositorio = new UsuarioRepositorio();
            usuarioRepositorio.UpdateUnidade(unidade.Usuarios, unidade.Id);
        }
 public List<Unidade> Search(string nome, Unidade unidade, UnidadeTipo tipo)
 {
     return this.Db.Fetch<Unidade>("SELECT * FROM Unidade WHERE (Unidade.Id = @0 OR Unidade.Hierarquia LIKE @1) AND (Unidade.Tipo = @3 OR @3 = @4) AND Unidade.Nome LIKE @2 ORDER BY Unidade.Nome", unidade.Id, unidade.GetFullLevelHierarquia() + '%', '%' + nome + '%', tipo, UnidadeTipo.TODOS).ToList();
 }
 public bool IsUnidadeFilha(Unidade pai, Unidade filha)
 {
     return this.Db.ExecuteScalar<bool>("SELECT COUNT(*) FROM Unidade WHERE Hierarquia LIKE @0 AND Unidade.Id = @1", pai.GetFullLevelHierarquia() + '%', filha.Id);
 }