none
Modelagem de BD RRS feed

  • Pergunta

  • Pessoal preciso de uma orientação para resolver uma questão.

    Tenho a seguinte demanda para atender, desenvolver um módulo para controle de notas promissórias.

    • O sistema deverá emitir uma nota promissória ou várias para um determinado cliente;
    • O valor total das promissórias é igual ao valor total da venda;
    • A medida que o cliente for pagando, o sistema vai dando baixa nas promissórias

    Como desenho a base de dados para isso e como controlo com segurança as transações?



    quarta-feira, 22 de janeiro de 2020 02:08

Todas as Respostas

  • Flávio, quais atributos você já definiu para a entidade PROMISSORIA?

    De imediato parece que serão criadas duas tabelas: PROMISSORIA e PARCELA_PROMISSORIA, sendo que a tabela PROMISSORIA terá chaves estrangeiras das tabelas CLIENTE e VENDA.

    ---

    -- código #1
    CREATE TABLE PROMISSORIA (
      Id_Promissoria
      Id_venda references VENDA
    Data_emissao   Cod_cliente references CLIENTE
    Valor Qtde_parcelas Quitada?
    ); CREATE TABLE PARCELA_PROMISSORIA ( Id_Promissoria references PROMISSORIA Seq_Parcela Valor_parcela Data_vencimento Data_pago Encargos_pago Valor_pago );
     

    No caso acima, há uma relação 1:N entre as tabelas PROMISSORIA e PARCELA_PROMISSORIA.

    Na tabela PROMISSORIA o conteúdo das colunas Data_emissao, Cod_cliente e Valor são opcionais pois presumo que essas informações possam ser obtidas na tabela VENDA. Entretanto, à custa de um relacionamento adicional. Se quiser, elas podem ficar na tabela, como redundância controlada.

    ---

    É claro que, dependendo do caso, pode-se agrupar as duas tabelas em uma única tabela, PROMISSORIA, denormalizando para melhor performance.

     


    José Diz     Belo Horizonte, MG - Brasil     [ Retirando acentuação com a função TRANSLATE ]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz sexta-feira, 24 de janeiro de 2020 23:12
    quarta-feira, 22 de janeiro de 2020 10:13
  • Flávio,

    Complementando o que foi proposto, quando se referimos a Venda, estamos diretamente fazendo uma alusão ao fato que envolve: Produtos, Fornecedores, Clientes, Pedidos, Compras, Vendas, enfim, entre outros elementos.

    Em seu banco de dados, existe todas estas entidades ("Tabelas")?

    --------------------

    Respondendo a sua pergunta:

    Como desenho a base de dados para isso?

    Vou tentar responder citando algumas das diversas possibilidades.

    1 - O desenho pode variar de diversas formas e técnicas, desde o conceito como já foi destacado de trabalhar com uma estrutura Desnormalizada, sendo considerada, uma tabela Fato para armazenar todos os dados em um único local, bem como, fazendo uso das técnicas tradicionais de estruturas Normalizadas até a 3FN (Terceira Forma Normal) ou 4FN (Quarta Forma Normal). 

    2 - Podemos adotar o conceito de trabalhar com relacionamentos físicos entre as entidades, o qual vai existir de forma física as chaves primárias e chaves estrangeiras propriamente criadas nas respectivas tabelas mediante as regras de negócios, esta é uma das formas mais tradicionais, que garante a integridade referencial e lógica dos dados mas acaba tornando a estrutura mas "engessada" e consequentemente os relacionamentos podem impactar um pouco nas questões de performance no momento em que os dados são consultados.

    3 - Podemos fazer uso do conceito de relacionamento entre tabelas, mas trabalhando da forma relacionamento lógicos, ou seja, existem as chaves primárias criadas em cada tabela, mas a chave estrangeira ela propriamente é definida como um atributo que não possui fisicamente o relacionamento, ou seja, de uma maneira que ao bater o olho você reconhece que aquele atributo (coluna) faz referência a uma outra entidade, mas fisicamente não esta ligada "relacionada", esta é uma técnica mais aplicada em ambientes de sistemas ERP, para tentar diminuir o impacto dos relacionamentos no momento das pesquisas e buscas dos dados, mas ela não garante de forma alguma a integridade referencial e lógica dos dados.

    Tudo vai depender de como você deseja estabelecer a relação entre os dados e garantir que sua estrutura de banco possa ser estabelecida mediante a sua regra de negócio.

    ------------------------------

    "Como controlo com segurança as transações?"
    Quando você se refere a segurança, gostaria de entender melhor se esta pensando na forma de acesso ou armazenamento.

    Os SGBDs tem este papel de gerenciar e controlar a concorrência, o isolamento, atomicidade e disponibilidade dos dados e objetos existem no ambiente de banco de dados mediante ao tipo de transação, query ou processamento que esta sendo realizado.

    Precisamos entender melhor a sua colocação para tentarmos te ajudar neste ponto relacionado a segurança.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    quarta-feira, 22 de janeiro de 2020 15:34
    Moderador
  • José até o momento, tinha feito a seguinte modelagem:

    CREATE TABLE IF NOT EXISTS `gfinan`.`tbPromissorias` (
      `idPromissoria` INT NOT NULL AUTO_INCREMENT,
      `idvenda` INT NOT NULL,
      `Emissao` DATE NULL,
      `Vencimento` DATE NULL,
      `Valor` DECIMAL(10,2) NULL,
      `Credor` VARCHAR(45) NULL,
      `Cpf_credor` CHAR(11) NULL,
      `Devedor` VARCHAR(45) NULL,
      `Cpf_devedor` CHAR(11) NULL,
      PRIMARY KEY (`idPromissoria`),
      INDEX `fk_tbPromissorias_tbVendas1_idx` (`idvenda` ASC),
      CONSTRAINT `fk_tbPromissorias_tbVendas1`
        FOREIGN KEY (`idvenda`)
        REFERENCES `gfinan`.`tbVendas` (`idvenda`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB

    CREATE TABLE IF NOT EXISTS `gfinan`.`tbVendas` (
      `idvenda` INT NOT NULL AUTO_INCREMENT,
      `data` DATETIME NULL,
      `idusuario` INT NOT NULL,
      `idcliente` INT NOT NULL,
      `idveiculo` INT NOT NULL,
      `valor` DECIMAL(2) NULL,
      `pagamento` INT NULL,
      `status` CHAR(1) NULL,
      PRIMARY KEY (`idvenda`),
      INDEX `fk_tbVendas_tbClientes1_idx` (`idcliente` ASC),
      INDEX `fk_tbVendas_tbVeiculos1_idx` (`idveiculo` ASC),
      INDEX `fk_tbVendas_tbUsuarios1_idx` (`idusuario` ASC),
      CONSTRAINT `fk_tbVendas_tbClientes1`
        FOREIGN KEY (`idcliente`)
        REFERENCES `gfinan`.`tbClientes` (`idcliente`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_tbVendas_tbVeiculos1`
        FOREIGN KEY (`idveiculo`)
        REFERENCES `gfinan`.`tbVeiculos` (`idVeiculo`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_tbVendas_tbUsuarios1`
        FOREIGN KEY (`idusuario`)
        REFERENCES `gfinan`.`tbUsuarios` (`idUsuario`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB

    CREATE TABLE IF NOT EXISTS `gfinan`.`tbClientes` (
      `idcliente` INT NOT NULL AUTO_INCREMENT,
      `nome` VARCHAR(100) NULL,
      `cpf` CHAR(11) NULL,
      `identidade` VARCHAR(10) NULL,
      `cnh` VARCHAR(45) NULL,
      `tipo_logradouro` VARCHAR(45) NULL,
      `logradouro` VARCHAR(45) NULL,
      `numero` INT NULL,
      `complemento` VARCHAR(45) NULL,
      `cep` CHAR(8) NULL,
      `bairro` VARCHAR(45) NULL,
      `idUF` INT NOT NULL,
      `idCidade` INT NOT NULL,
      `telefone` CHAR(11) NULL,
      `celular` CHAR(11) NULL,
      `email` VARCHAR(100) NULL,
      `data` DATETIME NOT NULL,
      `status` TINYINT NOT NULL,
      PRIMARY KEY (`idcliente`),
      INDEX `fk_tbClientes_tbCidades1_idx` (`idCidade` ASC),
      INDEX `fk_tbClientes_tbUF1_idx` (`idUF` ASC),
      CONSTRAINT `fk_tbClientes_tbCidades1`
        FOREIGN KEY (`idCidade`)
        REFERENCES `gfinan`.`tbCidades` (`idCidade`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_tbClientes_tbUF1`
        FOREIGN KEY (`idUF`)
        REFERENCES `gfinan`.`tbUF` (`idUF`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB

    CREATE TABLE IF NOT EXISTS `gfinan`.`tbVeiculos` (
      `idVeiculo` INT NOT NULL AUTO_INCREMENT,
      `cor` VARCHAR(45) NULL,
      `placa` VARCHAR(45) NULL,
      `anofab` VARCHAR(45) NULL,
      `anomod` VARCHAR(45) NULL,
      `chassi` VARCHAR(45) NULL,
      `renavam` VARCHAR(45) NULL,
      `tbTipos_id_tipo` INT NOT NULL,
      `tbMarcas_id_marca` INT NOT NULL,
      `tbModelos_id_modelo` INT NOT NULL,
      `tbAlimentacao_id` INT NOT NULL,
      PRIMARY KEY (`idVeiculo`, `tbTipos_id_tipo`, `tbMarcas_id_marca`, `tbModelos_id_modelo`, `tbAlimentacao_id`),
      INDEX `fk_tbVeiculos_tbTipos1_idx` (`tbTipos_id_tipo` ASC),
      INDEX `fk_tbVeiculos_tbMarcas1_idx` (`tbMarcas_id_marca` ASC),
      INDEX `fk_tbVeiculos_tbModelos1_idx` (`tbModelos_id_modelo` ASC),
      INDEX `fk_tbVeiculos_tbAlimentacao1_idx` (`tbAlimentacao_id` ASC),
      CONSTRAINT `fk_tbVeiculos_tbTipos1`
        FOREIGN KEY (`tbTipos_id_tipo`)
        REFERENCES `gfinan`.`tbTipos` (`id_tipo`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_tbVeiculos_tbMarcas1`
        FOREIGN KEY (`tbMarcas_id_marca`)
        REFERENCES `gfinan`.`tbMarcas` (`id_marca`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_tbVeiculos_tbModelos1`
        FOREIGN KEY (`tbModelos_id_modelo`)
        REFERENCES `gfinan`.`tbModelos` (`id_modelo`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_tbVeiculos_tbAlimentacao1`
        FOREIGN KEY (`tbAlimentacao_id`)
        REFERENCES `gfinan`.`tbAlimentacao` (`id`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB

    CREATE TABLE IF NOT EXISTS `gfinan`.`tbUsuarios` (
      `idUsuario` INT NOT NULL AUTO_INCREMENT,
      `primeironome` VARCHAR(20) NULL,
      `sobrenome` VARCHAR(20) NULL,
      `email` VARCHAR(100) NULL,
      `senha` VARCHAR(16) NULL,
      `status` TINYINT NULL,
      PRIMARY KEY (`idUsuario`))
    ENGINE = InnoDB

    Logicamente que ainda é um esboço, nada definitivo ou 100% correto.

    sexta-feira, 24 de janeiro de 2020 02:22
  • João, o tópico 3 das suas considerações é muito interessante.

    Com relação a minha preocupação de Como controlo com segurança as transações?

    Creio que na verdade, ainda não consegui imaginar a coisa funcionando na prática com a camada de entrada de dados do usuário, ou seja, o cara efetuou uma venda a ser paga em 12 promissórias, essas promissórias podem ser inseridas na tabela no ato do cadastro da venda e a medida que forem sendo pagas, uma baixa ocorre? Seria isso?

    sexta-feira, 24 de janeiro de 2020 02:34
  • Creio que na verdade, ainda não consegui imaginar a coisa funcionando na prática com a camada de entrada de dados do usuário, ou seja, o cara efetuou uma venda a ser paga em 12 promissórias, essas promissórias podem ser inseridas na tabela no ato do cadastro da venda e a medida que forem sendo pagas, uma baixa ocorre? Seria isso?

    Isso mesmo, Flávio.

    No ato da venda e com o cliente optando pelo pagamento em notas promissórias são gerados n registros na tabela de promissórias com os dados da promissória, um registro para cada promissória. À medida que o cliente paga as promissórias são atualizadas as informações do pagamento da nota promissória: data do pagamento, encargos pagos, valor total pago.

    Para obter o conjunto de promissórias associadas a uma venda basta pesquisar pela coluna Id_venda.

     


    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz sexta-feira, 24 de janeiro de 2020 23:13
    sexta-feira, 24 de janeiro de 2020 11:19
  • José até o momento, tinha feito a seguinte modelagem:
    ...

    Olá Flávio.

    Observe que falta registrar quando a nota promissória foi paga, se houve pagamento de encargos por atraso no pagamento (multa, juros) e o valor total pago (valor nominal mais encargos).

    Como comentei anteriormente, há duas opções: criar tabelas PROMISSORIA e PARCELA_PROMISSORIA ou criar uma única tabela PROMISSORIA. Embora uma nota promissória não possua parcelas e qualquer vinculação com o evento que gerou a dívida, na abordagem do código #1 optou-se pelo conceito de "parcela" para criar vinculação entre um conjunto de notas promissórias associadas a um mesmo evento devedor.  Assim, me parece que falta avaliar se irá criar (ou não) uma tabela para cadastrar as parcelas de cada promissória, conforme consta no código #1, que está normalizada na terceira forma normal.

    Optando pela estrutura do código #1, no ato da venda e com o cliente optando pelo pagamento em notas promissórias, é gerado um registro na tabela de promissórias com os dados gerais da promissória e na tabela de parcelas de promissórias são gerados n registros, um para cada parcela da promissória com o valor da parcela bem como a data de vencimento da parcela. À medida que o cliente paga as promissórias, a respectiva parcela é atualizada na tabela de parcelas de promissórias. Quando o cliente pagar todas as parcelas, na tabela de promissórias a coluna "Quitada?" é atualizada, de modo a indicar que a dívida está quitada.

    A outra solução, registrar tudo em uma única tabela, no ato da venda e com o cliente optando pelo pagamento em notas promissórias são gerados n registros na tabela de promissórias com os dados gerais das promissórias e também com os dados individuais. Caso opte por esta solução, é necessário que acrescente colunas para registrar a data de pagamento, o valor pago, se houve pagamento de encargos, etc.

    -- código #2
    CREATE TABLE PROMISSORIA (
      Id_Promissoria
      Id_venda references VENDA
      Cod_cliente references CLIENTE Data_emissao Credor
    CPF_credor
    Devedor
    CPF_devedor
      Data_vencimento
    Valor_nominal   Data_pago
      Encargos_pago
      Valor_pago
    );
     

    À medida que o devedor paga as promissórias são atualizadas as informações do pagamento da nota promissória: data do pagamento, encargos pagos, valor total pago.

     

    Lembre-se de marcar esta resposta se ela te ajudou a resolver o problema.


    José Diz     Belo Horizonte, MG - Brasil     [ Uso da função STRING_AGG para concatenar faixa de linhas de uma coluna ]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz sexta-feira, 24 de janeiro de 2020 13:43
    • Sugerido como Resposta José Diz sexta-feira, 24 de janeiro de 2020 23:09
    sexta-feira, 24 de janeiro de 2020 12:00
  • Exatamente José, esqueci de mencionar, mas tenho uma tabela chamada MOVTOFINANCEIRO que controla toda a movimentação de entrada de dinheiro e inspirado em um outro sistema aqui na empresa, estou pensando em ter essa opção também, o que acha?

    Nessa tabela são lançados os recebimentos das parcelas, além de outras formas de pagamento como a vista.

    É apenas uma ideia.

    sexta-feira, 24 de janeiro de 2020 12:25
  • Exatamente José, esqueci de mencionar, mas tenho uma tabela chamada MOVTOFINANCEIRO que controla toda a movimentação de entrada de dinheiro e inspirado em um outro sistema aqui na empresa, estou pensando em ter essa opção também, o que acha?

    Nessa tabela são lançados os recebimentos das parcelas, além de outras formas de pagamento como a vista.

    Flávio, se a tabela existe então de alguma forma o recebimento de uma nota promissória terá que ser registrado na tabela de movimentação financeira. Você pode optar por uma redundância controlada, onde o evento "recebimento de nota promissória" atualiza o registro na tabela de promissórias e também inclui registro na tabela de movimentos financeiros ou pode optar para que o evento "recebimento de nota promissória" somente inclua registro na tabela de movimentação financeira e que na tabela de notas promissórias fique um ponteiro para esse pagamento.

    O ideal, me parece, é seguir a mesma lógica que seja empregada nas demais formas de recebimento de créditos do sistema.

    No segundo caso a tabela de notas promissórias teria o seguinte esboço:

    -- código #2 v2
    CREATE TABLE PROMISSORIA (
      Id_Promissoria
      Id_venda references VENDA
      Cod_cliente references CLIENTE
      Data_emissao
      Credor
      CPF_credor
      Devedor
      CPF_devedor
      Data_vencimento
      Valor_nominal
      idMovFinanceiro references MOVTOFINANCEIRO
    );

    onde idMovFinanceiro aponta para o registro da tabela MOVTOFINANCEIRO que corresponda ao recebimento da nota promissória. Se estiver sem informação (NULL), significa que ainda não foi paga.

    Flávio, são somente sugestões pois para tomar decisões é necessário conhecer o contexto completo.


    José Diz     Belo Horizonte, MG - Brasil     [ Apagar conjunto de linhas em tabelas enormes ]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz sexta-feira, 24 de janeiro de 2020 13:45
    sexta-feira, 24 de janeiro de 2020 13:32
  • João, o tópico 3 das suas considerações é muito interessante.

    Com relação a minha preocupação de Como controlo com segurança as transações?

    Creio que na verdade, ainda não consegui imaginar a coisa funcionando na prática com a camada de entrada de dados do usuário, ou seja, o cara efetuou uma venda a ser paga em 12 promissórias, essas promissórias podem ser inseridas na tabela no ato do cadastro da venda e a medida que forem sendo pagas, uma baixa ocorre? Seria isso?

    Flávio,

    Certo, sim seria isso!!!

    De alguma maneira você deverá ter este controle estabelecido em uma tabela que vai armazenar inicialmente:

    • Número do Cliente,
    • Número da Nota Promissória,
    • Número da Parcela,
    • Data de Pagamento, sabendo que para um melhor controle seria interessante ter duas datas de pagamento, aquela que estava definida na promissória e a que realmente foi realizada, com isso você poderá até mesmo ter uma ideia de cálculo de juros.

    Esta será uma tabela considerada como tabela de relacionamento, o qual terá as chaves primárias de cliente e promissórias definidas como estrangeira e você poderá uma chave primária que poderá ser definida caso você queira como uma Surrogate Key, ou chave primária artificial, conhecida como chave primária autonumerada.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    sexta-feira, 24 de janeiro de 2020 13:43
    Moderador
  • Flávio,

    Fiquei com algumas curiosidades em relação a parte financeira:

    1 - O controle financeiro é de responsabilidade de quem?

    2 - Sua aplicação a princípio terá este módulo financeiro ou você pensa em estabelecer regras diretamente no banco de dados para realizar os controles?

    ---------------

    Analise a sugestão que o José Diz apresentou em relação a tabela Promissoria, eu pensaria na possibilidade de não colocar o IdMovFinanceiro nesta tabela, analisaria a possibilidade de criar uma tabela que contenho justamente todas as movimentações financeiras de cada cliente ao longo do tempo e suas respectivas promissórias.

    Concordo com a frase do José, estas são somente sugestões, não conhecemos suas regras de negócio e necessidades diárias.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]


    sexta-feira, 24 de janeiro de 2020 13:47
    Moderador
  • Flávio,

    Fiquei com algumas curiosidades em relação a parte financeira:

    1 - O controle financeiro é de responsabilidade de quem?

    2 - Sua aplicação a princípio terá este módulo financeiro ou você pensa em estabelecer regras diretamente no banco de dados para realizar os controles?

    ---------------

    Analise a sugestão que o José Diz apresentou em relação a tabela Promissoria, eu pensaria na possibilidade de não colocar o IdMovFinanceiro nesta tabela, analisaria a possibilidade de criar uma tabela que contenho justamente todas as movimentações financeiras de cada cliente ao longo do tempo e suas respectivas promissórias.

    Concordo com a frase do José, estas são somente sugestões, não conhecemos suas regras de negócio e necessidades diárias.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]


    Sim Júnior, teremos um módulo de Financeiro, onde os recebimentos e baixas serão realizados. Essa tarefa vai ficar a cargo de um dos donos.
    sexta-feira, 24 de janeiro de 2020 15:06
  • Pessoal preciso de uma orientação para resolver uma questão.

    Tenho a seguinte demanda para atender, desenvolver um módulo para controle de notas promissórias.

    • O sistema deverá emitir uma nota promissória ou várias para um determinado cliente;
    • O valor total das promissórias é igual ao valor total da venda;
    • A medida que o cliente for pagando, o sistema vai dando baixa nas promissórias

    Como desenho a base de dados para isso e como controlo com segurança as transações?



    Agora um detalhe, cada parcela é considerada uma nota promissória independente correto?

    Ou a forma correta perante a lei é uma nota promissória (MÃE) com várias parcelas (FILHAS)?

    sexta-feira, 24 de janeiro de 2020 15:12
  • Agora um detalhe, cada parcela é considerada uma nota promissória independente correto?
    Ou a forma correta perante a lei é uma nota promissória (MÃE) com várias parcelas (FILHAS)?

    Flávio, isso foi comentado anteriormente mas talvez não tenha ficado destacado, por isso repito aqui: “Embora uma nota promissória não possua parcelas e qualquer vinculação com o evento que gerou a dívida, na abordagem do código #1 optou-se pelo conceito de "parcela" para criar vinculação entre um conjunto de notas promissórias associadas a um mesmo evento devedor”.

    Ainda na mesma resposta é citado que “A outra solução, registrar tudo em uma única tabela, no ato da venda e com o cliente optando pelo pagamento em notas promissórias são gerados n registros na tabela de promissórias com os dados gerais das promissórias”. No código #2 cada nota promissória é uma linha na tabela de promissórias, sem o conceito de "parcela".

    O que se tem é uma venda e cuja forma de pagamento pelo cliente é diversa: à vista, financiamento, carta de crédito, notas promissórias etc. A questão atual é: como fica registrada a forma de pagamento no sistema?

    O tópico iniciou diretamente na forma de pagamento pelo cliente por "notas promissórias"; nesse caso, na sua tabela tbPromissorias somente falta acrescentar a forma de registrar o recebimento da nota promissória.

    ---

    A respeito do que é uma nota promissória "perante a lei", deixo essa questão para advogados e outros profissionais do Direito. Mas, se tiver curiosidade, consulte Nota Promissória: o que é e como cobrá-la.

     

    Lembre-se de marcar esta resposta se ela te ajudou a resolver o problema.


    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz sexta-feira, 24 de janeiro de 2020 17:57
    • Sugerido como Resposta José Diz sexta-feira, 24 de janeiro de 2020 23:09
    sexta-feira, 24 de janeiro de 2020 15:54
  • ok... ok...

    Vou fazer a coisa toda nessa linha de trabalho aqui:

    Ainda na mesma resposta é citado que “A outra solução, registrar tudo em uma única tabela, no ato da venda e com o cliente optando pelo pagamento em notas promissórias são gerados n registros na tabela de promissórias com os dados gerais das promissórias”. No código #2 cada nota promissória é uma linha na tabela de promissórias, sem o conceito de "parcela".

    sexta-feira, 24 de janeiro de 2020 17:55
  • Flávio, estava aqui relendo as respostas e somente agora atentei para um detalhe: eu acho que não existem encargos (multa, juros) para nota promissória. Enquanto encargos constem em boletos bancários, por exemplo, não me lembro de ter visto isto em notas promissórias. Aliás, nem sabia que nota promissória ainda era utilizada como termo de pagamento. Antigamente, muito antigamente, era um meio muito comum, principalmente porque os devedores honravam os compromissos financeiros. Nem existia SPC...

    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz sexta-feira, 24 de janeiro de 2020 18:08
    sexta-feira, 24 de janeiro de 2020 18:04
  • Flávio,

    Fiquei com algumas curiosidades em relação a parte financeira:

    1 - O controle financeiro é de responsabilidade de quem?

    2 - Sua aplicação a princípio terá este módulo financeiro ou você pensa em estabelecer regras diretamente no banco de dados para realizar os controles?

    ---------------

    Analise a sugestão que o José Diz apresentou em relação a tabela Promissoria, eu pensaria na possibilidade de não colocar o IdMovFinanceiro nesta tabela, analisaria a possibilidade de criar uma tabela que contenho justamente todas as movimentações financeiras de cada cliente ao longo do tempo e suas respectivas promissórias.

    Concordo com a frase do José, estas são somente sugestões, não conhecemos suas regras de negócio e necessidades diárias.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]


    Sim Júnior, teremos um módulo de Financeiro, onde os recebimentos e baixas serão realizados. Essa tarefa vai ficar a cargo de um dos donos.

    Flávio,

    Ótimo, então teoricamente ele poderá ser a pessoa mais indicada a definir a maneira que as notas promissórias serão controladas.

    Uma outra pergunta:

    1 - Existe algum limite de números de notas promissórias que um cliente poderá ter?


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    sexta-feira, 24 de janeiro de 2020 19:49
    Moderador
  • Flávio, estava aqui relendo as respostas e somente agora atentei para um detalhe: eu acho que não existem encargos (multa, juros) para nota promissória. Enquanto encargos constem em boletos bancários, por exemplo, não me lembro de ter visto isto em notas promissórias. Aliás, nem sabia que nota promissória ainda era utilizada como termo de pagamento. Antigamente, muito antigamente, era um meio muito comum, principalmente porque os devedores honravam os compromissos financeiros. Nem existia SPC...

    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    José,

    Concordo com sua observação.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    sexta-feira, 24 de janeiro de 2020 19:49
    Moderador
  • E venda de veículos. Geralmente são 24 promissórias no máximo...
    sexta-feira, 24 de janeiro de 2020 20:26
  • sábado, 25 de janeiro de 2020 01:09
  • José mais uma dúvida, foge um pouco do escopo do tópico mas creio ser coisa simples.

    Após ser gerada a venda na tabela VENDAS e o cliente optar pelo pagamento em 10 promissórias, na tabela PROMISSÓRIAS serão inseridos 10 registros referentes a cada uma das promissórias.

    Esse processo de inserção na segunda tabela deve ser realizado via Trigger ou Stored Procedure diretamente pelo SGBD ou é aconselhável que seja realizado pela camada da aplicação por uma questão de desempenho e/ou segurança?

    Ou até mesmo por não ser uma aplicação muito complexa, tanto faz a forma de fazer?


    sábado, 25 de janeiro de 2020 11:31
  • Esse processo de inserção na segunda tabela deve ser realizado via Trigger ou Stored Procedure diretamente pelo SGBD ou é aconselhável que seja realizado pela camada da aplicação por uma questão de desempenho e/ou segurança?

    Flávio, as vendas são somente através de notas promissórias ou podem existir outras formas de pagamento (à vista, financiamento externo, cartão de crédito, etc)?

    Para utilizar como gatilho é necessário que exista um evento; o fato de uma linha ser incluída na tabela de vendas significa que a venda terá notas promissórias como forma de pagamento?


    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz sábado, 25 de janeiro de 2020 11:43
    sábado, 25 de janeiro de 2020 11:41
  • Esse processo de inserção na segunda tabela deve ser realizado via Trigger ou Stored Procedure diretamente pelo SGBD ou é aconselhável que seja realizado pela camada da aplicação por uma questão de desempenho e/ou segurança?

    Flávio, as vendas são somente através de notas promissórias ou podem existir outras formas de pagamento (à vista, financiamento externo, cartão de crédito, etc)?

    Para utilizar como gatilho é necessário que exista um evento; o fato de uma linha ser incluída na tabela de vendas significa que a venda terá notas promissórias como forma de pagamento?


    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita. Incluiu na tabela vendas gera promissória ou não, tem um campo que controla a forma de pagamento.

    As vendas podem ser a vista em dinheiro e através de promissórias.
    sábado, 25 de janeiro de 2020 11:56
  • Flávio,

    Gostei da sua modelagem, se atente para o campo Senha trocaria o tipo de dados de Varchar() para Varbinary() justamente para aplicar criptografia diretamente no dado que será armazenado.

    Ressalto que esta sugestão do tipo de dados se aplica ao SQL Server.

    Outra sugestão que eu gostaria de destacar se relaciona com a Data do Pagamento, você tem na tabela Promissória a coluna Vencimento que representa a data que a promissória vai vencer e deverá ser paga.

    Mas se o cliente não pagar na data de vencimento, independente de juros, eu pensaria em ter uma coluna que representa a data real de pagamento, não sei que esta coluna deveria ser adicionada a tabela Promissória ou MovFinanceiro.

    O que você acha?


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]



    sábado, 25 de janeiro de 2020 12:16
    Moderador
  • José mais uma dúvida, foge um pouco do escopo do tópico mas creio ser coisa simples.

    Após ser gerada a venda na tabela VENDAS e o cliente optar pelo pagamento em 10 promissórias, na tabela PROMISSÓRIAS serão inseridos 10 registros referentes a cada uma das promissórias.

    Esse processo de inserção na segunda tabela deve ser realizado via Trigger ou Stored Procedure diretamente pelo SGBD ou é aconselhável que seja realizado pela camada da aplicação por uma questão de desempenho e/ou segurança?

    Ou até mesmo por não ser uma aplicação muito complexa, tanto faz a forma de fazer?


    Flávio,

    Sei que você direcionou a dúvida ao José, mas gostaria de contribuir em relação a este questionamento.

    Você pode implementar este tipo de cenário tanto via Trigger, Stored Procedure ou até mesmo Function, deixando toda esta lógica e controle diretamente no Banco de Dados, bem como, pode via aplicação fazer uso da Stored Procedure ou Function que realizam o processamento no seu Servidor de Banco de Dados.

    Gosto da possibilidade de combinar o uso de Trigger em conjunto com Stored Procedure, alias, você pode criar uma Trigger de acordo com o evento desejado, no seu caso o Insert para armazenar as parcelas que chama uma Stored Procedure justamente definida para este tipo de implementação.

    Recentemente em um dos cenários de estudo nas minhas aulas de Banco de Dados, tivemos uma temática muito próxima a sua necessidade, vou compartilhar um esboço do código utilizado que realiza o parcelamento, que pode ser adotado via Trigger ou Stored Procedure.

    Veja abaixo o exemplo:

    USE AULA6 GO Create TABLE PARCELAMENTO (CODIGO INT IDENTITY(1,1) PRIMARY KEY, CODVENDA INT NOT NULL, NUMEROPARCELA TINYINT NOT NULL, VALORPARCELA FLOAT NOT NULL, PorcentagemJuros Float Not Null, DataVencimento Date Not Null, ValorTotal Float Null) GO Create TRIGGER T_INSERIR_PARCELAMENTO ON VENDAS AFTER INSERT AS Begin Set NoCount On IF (SELECT QTDEPARCELAS FROM INSERTED) > 1 Begin Declare @Contador TinyInt, @CodVenda Int, @PorcentagemJuros Float Set @Contador = 1 Set @CodVenda = (Select Codigo from inserted) Set @PorcentagemJuros=10 While @Contador <= (Select QTDEPARCELAS FROM inserted) Begin Insert Into PARCELAMENTO(CODVENDA, NUMEROPARCELA, VALORPARCELA, PorcentagemJuros, DataVencimento) Select Codigo, @Contador, dbo.F_CalcularPorcentagem(VALORVENDA,QTDEPARCELAS,@PorcentagemJuros), @PorcentagemJuros, DATEADD(MONTH,@Contador,GETDATE()) From Inserted Set @Contador += 1 End Exec P_AtualizarValorTotalParcelamento @CodVenda End End Go Create Procedure P_AtualizarValorTotalParcelamento(@CodVenda Int = 1) As Begin Set NoCount On Update Parcelamento Set ValorTotal = (Select SUM(ValorParcela) From PARCELAMENTO Where CODVENDA = @CodVenda) Output inserted.CODVENDA, inserted.NUMEROPARCELA, inserted.VALORPARCELA, inserted.PorcentagemJuros, inserted.ValorTotal Where CODVENDA = @CodVenda End Go Insert Into Vendas(CodEmpresa, CodCliente, CODPRODUTO, VALORVENDA, QTDEPARCELAS) Values(3,2,1,5000,10)

    Go


    Claro que este código precisa ser melhorado, existem ajustes e até mesmo alterações a serem aplicadas, mas acredito que possa te ajudar a entender como poderíamos aplicar este tipo de solução.

    Uma outra possibilidade que pode ser interessante é o uso de Function, ainda mais você dentro da sua aplicação fazendo a chamada para que este recurso seja executado mediante a sua regra de negócio, da mesma forma que uma Stored Procedure.

    Vou compartilhar um exemplo de código de uma Função Scalar que realizar o cálculo de Juros dos valores de parcelas de um determinado produto, ressalto também que é um esboço de código que pode server como base ou sugestão de utilização no seu ambiente:

    -- Criando a Function --
    Create Function F_CalcularPorcentagem (@ValorVenda Float, @QTDEParcelas Int, @Juros Int)
    Returns Int
    As
    Begin
     Declare @ValorAtualizadoVenda Float
    
     Set @ValorAtualizadoVenda=(IsNull(@ValorVenda,1)/IsNull(@QTDEParcelas,1))
    
     Set @ValorAtualizadoVenda=@ValorAtualizadoVenda+(@ValorAtualizadoVenda*IsNull(@Juros,1))/100
    
     Return(@ValorAtualizadoVenda)
    End
    
    -- Executando --
    Select dbo.F_CalcularPorcentagem(5000, 5, 10)
    Go

    Mais uma vez destaco que não estou levando em consideração suas regras de negócio, enfatizo que o código necessita de alguns alterações e ajustes.

    Espero ter ajudado.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    sábado, 25 de janeiro de 2020 12:26
    Moderador
  • E venda de veículos. Geralmente são 24 promissórias no máximo...

    Flávio,

    Ok, obrigado.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    sábado, 25 de janeiro de 2020 12:26
    Moderador
  • Flávio,

    Neste caso, acredito que seria interessante você criar uma tabela que justamente contenha os tipos de pagamentos que podem se realizados para a Nota Promissória, e mediante ao pagamento realizado, eu armazenaria justamente na tabela MovFinanceiro o IDTipoPagamento.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    sábado, 25 de janeiro de 2020 12:29
    Moderador
  • Flávio,

    Gostei da sua modelagem, se atente para o campo Senha trocaria o tipo de dados de Varchar() para Varbinary() justamente para aplicar criptografia diretamente no dado que será armazenado.

    Ressalto que esta sugestão do tipo de dados se aplica ao SQL Server.

    Outra sugestão que eu gostaria de destacar se relaciona com a Data do Pagamento, você tem na tabela Promissória a coluna Vencimento que representa a data que a promissória vai vencer e deverá ser paga.

    Mas se o cliente não pagar na data de vencimento, independente de juros, eu pensaria em ter uma coluna que representa a data real de pagamento, não sei que esta coluna deveria ser adicionada a tabela Promissória ou MovFinanceiro.

    O que você acha?


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]



    Júnior, se você perceber na tabela movfinanceiro verá que temos um campo chamado datamov. Esse campo representa exatamente a data efetiva do pagamento de um título, no caso a promissória. No ato da geração da promissória, temos na tabela promissoria, os campos emissao e vencimento. Assim o controle fica a cargo da tabela movfinanceiro.

    Com relação a alteração do tipo de campo da senha, sugestão aceita...

    sábado, 25 de janeiro de 2020 12:45
  • Flávio,

    Gostei da sua modelagem, se atente para o campo Senha trocaria o tipo de dados de Varchar() para Varbinary() justamente para aplicar criptografia diretamente no dado que será armazenado.

    Ressalto que esta sugestão do tipo de dados se aplica ao SQL Server.

    Outra sugestão que eu gostaria de destacar se relaciona com a Data do Pagamento, você tem na tabela Promissória a coluna Vencimento que representa a data que a promissória vai vencer e deverá ser paga.

    Mas se o cliente não pagar na data de vencimento, independente de juros, eu pensaria em ter uma coluna que representa a data real de pagamento, não sei que esta coluna deveria ser adicionada a tabela Promissória ou MovFinanceiro.

    O que você acha?


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]



    Júnior, se você perceber na tabela movfinanceiro verá que temos um campo chamado datamov. Esse campo representa exatamente a data efetiva do pagamento de um título, no caso a promissória. No ato da geração da promissória, temos na tabela promissoria, os campos emissao e vencimento. Assim o controle fica a cargo da tabela movfinanceiro.

    Com relação a alteração do tipo de campo da senha, sugestão aceita...

    Flávio,

    Ok, perfeito, eu havia entendido de outra maneira, que a tabela Promissória conteria os dados gerais da promissória e não de cada parcela existente a ela.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]


    sábado, 25 de janeiro de 2020 12:48
    Moderador
  • Esse processo de inserção na segunda tabela deve ser realizado via Trigger ou Stored Procedure diretamente pelo SGBD ou é aconselhável que seja realizado pela camada da aplicação
    ---
    As vendas podem ser a vista em dinheiro e através de promissórias.

    Me parece que o mais simples é que a rotina de vendas faça tudo: inclua a informação na tabela de vendas e, dependendo da forma de pagamento, faça as demais ações necessárias. Por exemplo, no caso de opção pelo pagamento através de notas promissórias, a própria rotina de vendas gera n linhas na tabela de promissórias, uma para cada promissória, a partir de informações coletadas na tela da rotina de vendas.

    Fique atento que nem sempre os valores das promissórias são idênticos. Por exemplo, no caso de venda no valor de R$ 10.000,00 e para pagar em 3 notas promissórias, não há como utilizar o valor R$ 3.333,3333... para cada promissória, pois a somatória das notas promissórias deve ser o mesmo do valor da venda. No caso desse exemplo, a solução usual é emitir a primeira promissória no valor de R$ 3.333,34 e as demais no valor de R$ 3.333,33.

    Não é possível implementar através de procedimento de gatilho, pois na tabela de vendas não existem as informações necessárias para gerar as promissórias.

     


    José Diz     Belo Horizonte, MG - Brasil     [ Particionamento de tabela na edição Express ]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz sábado, 25 de janeiro de 2020 15:06
    sábado, 25 de janeiro de 2020 14:34
  • José,

    Me parece que o mais simples é que a rotina de vendas faça tudo: inclua a informação na tabela de vendas e, dependendo da forma de pagamento, faça as demais ações necessárias. Por exemplo, no caso de opção pelo pagamento através de notas promissórias, a própria rotina de vendas gera n linhas na tabela de promissórias, uma para cada promissória, a partir de informações coletadas na tela da rotina de vendas.

    Esta sendo desenhado dessa forma. Na tabela VENDAS temos um campo chamado pagamento. Esse campo controla a forma de pagamento realizada pelo cliente, a vista, 4 vezes na promissória, 6 vezes na promissória, 10 vezes na promissória, etc...

    Fique atento que nem sempre os valores das promissórias são idênticos. Por exemplo, no caso de venda no valor de R$ 10.000,00 e para pagar em 3 notas promissórias, não há como utilizar o valor R$ 3.333,3333... para cada promissória, pois a somatória das notas promissórias deve ser o mesmo do valor da venda. No caso desse exemplo, a solução usual é emitir a primeira promissória no valor de R$ 3.333,34 e as demais no valor de R$ 3.333,33.

    Tinha pensado nisso mesmo, tarefa para a aplicação. Creio que via código consiga resolver isso, mas é alerta sim.

    Não é possível implementar através de procedimento de gatilho, pois na tabela de vendas não existem as informações necessárias para gerar as promissórias.

    Quais as informações necessárias?


    sábado, 25 de janeiro de 2020 17:23
  • Sei que você direcionou a dúvida ao José, mas gostaria de contribuir em relação a este questionamento.

    Desculpe pela indelicadeza, não foi a minha intenção.

    Preciso de um final de semana para estudar o que você passou, para dar pelo menos uma mísera opinião (kkkkkkkkk) afinal isso foi uma aula também...

    sábado, 25 de janeiro de 2020 17:30
  • José,

    Me parece que o mais simples é que a rotina de vendas faça tudo: inclua a informação na tabela de vendas e, dependendo da forma de pagamento, faça as demais ações necessárias. Por exemplo, no caso de opção pelo pagamento através de notas promissórias, a própria rotina de vendas gera n linhas na tabela de promissórias, uma para cada promissória, a partir de informações coletadas na tela da rotina de vendas.

    Esta sendo desenhado dessa forma. Na tabela VENDAS temos um campo chamado pagamento. Esse campo controla a forma de pagamento realizada pelo cliente, a vista, 4 vezes na promissória, 6 vezes na promissória, 10 vezes na promissória, etc...

    Ótimo.

    Não é possível implementar através de procedimento de gatilho, pois na tabela de vendas não existem as informações necessárias para gerar as promissórias.

    Quais as informações necessárias?

    Flávio, como sabe o nome do devedor na nota promissória não é necessariamente o nome de quem comprou o veículo. No modelo de dados que postou em outra resposta observa-se que nem o nome do devedor e nem o nome do CPF do devedor constam na tabela de vendas, provavemente porque essas informações só existem quando a venda é financiada de alguma forma (nota promissória, cheque pré-datado etc). Quanto ao nome do credor e o CPF deste, pode vir de algum arquivo de configuração do sistema, pois é uma informação específica da empresa. Outra questão é o número de vezes, ou seja, o número de notas promissórias que serão emitidas. Tem ainda a questão das datas de vencimento das notas promissórias. Na tela da aplicação, na rotina de fechamento de vendas, essas informações podem ser solicitadas e então utilizadas para gerar as linhas na tabela de notas promissórias.

    Um procedimento de gatilho não pode exibir uma tela para solicitar as informações que faltam. Por isso que anteriomente comentei que “Não é possível implementar através de procedimento de gatilho, pois na tabela de vendas não existem as informações necessárias para gerar as promissórias”.

    Aproveite e verifique com o seu cliente se ele costuma realizar operações de desconto de notas promissórias com bancos.


    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Editado José Diz sábado, 25 de janeiro de 2020 20:21
    sábado, 25 de janeiro de 2020 18:08

  •  Outra questão é o número de vezes, ou seja, o número de notas promissórias que serão emitidas. Tem ainda a questão das datas de vencimento das notas promissórias. Na tela da aplicação, na rotina de fechamento de vendas, essas informações podem ser solicitadas e então utilizadas para gerar as linhas na tabela de notas promissórias.


    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    José,

    Justamente por esta questão que você apontou acima, eu anteriormente havia destacado e levantado a possibilidade do Flávio analisar a questão da data de vencimento:

    Eu acredito que ele deveria repensar esta lógica, eu teria uma tabela para controlar a promissória e outra tabela para controlar as parcelas de promissórias, entendo que a parte Financeira é uma área que controla tudo isso, mas não exatamente a tabela MovFinanceiro seria o cenário a ser utilizado.

    Bom, este foi o meu entendimento.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    domingo, 26 de janeiro de 2020 18:34
    Moderador
  • Outra questão é o número de vezes, ou seja, o número de notas promissórias que serão emitidas. Tem ainda a questão das datas de vencimento das notas promissórias. Na tela da aplicação, na rotina de fechamento de vendas, essas informações podem ser solicitadas e então utilizadas para gerar as linhas na tabela de notas promissórias.


    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    José,

    Justamente por esta questão que você apontou acima, eu anteriormente havia destacado e levantado a possibilidade do Flávio analisar a questão da data de vencimento:

    Eu acredito que ele deveria repensar esta lógica, eu teria uma tabela para controlar a promissória e outra tabela para controlar as parcelas de promissórias, entendo que a parte Financeira é uma área que controla tudo isso, mas não exatamente a tabela MovFinanceiro seria o cenário a ser utilizado.

    Bom, este foi o meu entendimento.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    Prezados,

    Da minha parte, está sendo um verdadeiro aprendizado esse tópico.

    Com relação às mensagens acima, seguem algumas considerações daquilo que imaginamos em termos de funcionamento do sistema na prática, fazendo uma inferência com tudo aquilo que me foi ensinado e/ou proposto até esse momento.

    tbVendas

    CREATE TABLE IF NOT EXISTS `picinin`.`tbVendas` (
      `idVenda` INT NOT NULL AUTO_INCREMENT,
      `idCliente` INT NOT NULL,
      `idVeiculo` INT NOT NULL,
      `Pagamento` CHAR(1) NOT NULL,
      `Data` DATETIME NOT NULL,
      `Status` CHAR(1) NOT NULL,
      `idUsuario` INT NOT NULL,
      PRIMARY KEY (`idVenda`),
      INDEX `fk_tbVendas_tbUsuarios_idx` (`idUsuario` ASC),
      INDEX `fk_tbVendas_tbVeiculos_idx` (`idVeiculo` ASC),
      INDEX `fk_tbVendas_tbClientes_idx` (`idCliente` ASC),
      CONSTRAINT `fk_tbVendas_tbUsuarios`
        FOREIGN KEY (`idUsuario`)
        REFERENCES `picinin`.`tbUsuarios` (`idUsuario`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_tbVendas_tbVeiculos`
        FOREIGN KEY (`idVeiculo`)
        REFERENCES `picinin`.`tbVeiculos` (`idVeiculo`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_tbVendas_tbClientes`
        FOREIGN KEY (`idCliente`)
        REFERENCES `picinin`.`tbClientes` (`idCliente`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB

    Essa tabela irá armazenar apenas os dados da venda. O campo <Pagamento> irá determinar o número de promissórias geradas, segundo a consultoria advocatícia da empresa, uma promissória não possui parcelas, vc emite N promissórias para compor o valor total de uma venda.

    A título de exemplo, faremos uma venda de R$ 48.000,00 divididos em 20 promissórias de R$ 2.400,00 cada.

    tbPromissorias

    CREATE TABLE IF NOT EXISTS `picinin`.`tbPromissorias` (
      `idPromissoria` INT NOT NULL AUTO_INCREMENT,
      `Vencimento` DATE NOT NULL,
      `Valor` DECIMAL(10,2) NOT NULL,
      `idEmpresa` INT NOT NULL,
      `idCliente` INT NOT NULL,
      `Emissao` DATE NOT NULL,
      `idVenda` INT NOT NULL,
      `Status` CHAR(1) NOT NULL DEFAULT 'A',
      PRIMARY KEY (`idPromissoria`),
      INDEX `fk_tbPromissorias_tbVendas_idx` (`idVenda` ASC),
      INDEX `fk_tbPromissorias_tbClientes_idx` (`idCliente` ASC),
      INDEX `fk_tbPromissorias_tbEmpresa_idx` (`idEmpresa` ASC),
      CONSTRAINT `fk_tbPromissorias_tbVendas`
        FOREIGN KEY (`idVenda`)
        REFERENCES `picinin`.`tbVendas` (`idVenda`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_tbPromissorias_tbClientes`
        FOREIGN KEY (`idCliente`)
        REFERENCES `picinin`.`tbClientes` (`idCliente`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION,
      CONSTRAINT `fk_tbPromissorias_tbEmpresa`
        FOREIGN KEY (`idEmpresa`)
        REFERENCES `picinin`.`tbEmpresa` (`idEmpresa`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB

    No ato da confirmação da venda <insert>, seja através da aplicação (código) ou banco de dados (Trigger), serão criados 20 registros na tabela <tbPromissorias> com todas as informações referentes a cada uma das promissórias. Com relação às datas, nesse momento temos a data de emissão da promissória, bem como a data de vencimento da mesma, essa não será efetivamente a data de pagamento, pois o cliente pode antecipar ou atrasar o seu pagamento.

    tbMovFinan

    CREATE TABLE IF NOT EXISTS `picinin`.`tbMovFinan` (
      `idMovFinan` INT NOT NULL AUTO_INCREMENT,
      `idPromissoria` INT NOT NULL,
      `Data` DATETIME NOT NULL,
      `Valor` DECIMAL(10,2) NOT NULL,
      PRIMARY KEY (`idMovFinan`),
      INDEX `fk_tbMovFinan_tbPromissorias1_idx` (`idPromissoria` ASC),
      CONSTRAINT `fk_tbMovFinan_tbPromissorias1`
        FOREIGN KEY (`idPromissoria`)
        REFERENCES `picinin`.`tbPromissorias` (`idPromissoria`)
        ON DELETE NO ACTION
        ON UPDATE NO ACTION)
    ENGINE = InnoDB

    No dia que o cliente for a loja para fazer o resgate (pagamento) de uma promissória, essa operação ficará registrada na tabela (tbMovFinan), nessa sim, teremos o campo <Data> que representa a data efetiva do pagamento.

    Nesse momento entendo que não consigo fazer a inclusão dos registros na tabela tbPromissorias através de uma Trigger, pois conforme foi dito pelo José, "...Não é possível implementar através de procedimento de gatilho, pois na tabela de vendas não existem as informações necessárias para gerar as promissórias...". Assim sendo, isso ficará a cargo da aplicação.

    Embora o único travamento seja a ausência do campo <Valor> na tabela <tbVenda>, essa informação na verdade fica na tabela <tbVeiculos>, mas isso pode de certa forma ser contornado pela seguinte solução: o veículo ter um valor de anúncio, mas ter outro valor efetivo de venda.

    Dessa forma eu teria todas as informações para gerar os inserts através de uma trigger?

    Espero estar alinhado um mínimo que seja, com todos os ensinamentos que vocês tão passando.


    domingo, 26 de janeiro de 2020 20:23
  • Flávio,

    Sim, esta muito bem direcionado, acredito que o melhor agora é você realizar a análise mediante ao mapeamento dos processos da sua empresa, identificando as necessidades e validando as regras de negócio.

    Uma boa modelagem de banco de dados tem que ilustrar, apresentar e refletir de uma forma simples todo fluxo de dados trocado pelas áreas da empresa, incluindo os processos que provavelmente hoje são realizados manualmente e posteriormente serão substituídos por processos informatizados.

    Muito dos dados que serão armazenados nestas tabelas, podem servir como fonte de conhecimento ou elemento de tomada de decisão, este é um detalhe que você tem que analisar no momento que esta estruturando seu modelo, nem sempre o menos é mais, tente levantar e elencar o que realmente é necessário ser armazenado, penso nos possíveis relatórios ou arquivos que podem ser gerados de acordo com o que você tem armazenado em suas tabelas.

    Não se esqueça que um relatório, ficha, planilha ou gráfico poderá ser resultado do que você esta coletando e armazenando.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    segunda-feira, 27 de janeiro de 2020 00:49
    Moderador
  • Pessoal, estamos avaliando a possibilidade de termos duas formas de pagamento:

    - Notas Promissórias;

    - Cheques;

    Mantendo a linha de modelagem até agora, teríamos duas tabelas, uma para cheques e outra para promissórias, nessas seriam cadastrados tanto as promissórias geradas para um cliente quanto os cheques que outro mesmo emitiu de acordo com a forma de pagamento escolhida.

    Em uma terceira tabela, nós faríamos o controle dos recebimentos tanto das promissórias quanto das compensações dos cheques.

    Como trabalho a questão das FK na tabela de recebimento? Inicialmente nós teríamos apenas o código da promissória cadastrada na tabela promissória para o controle da transação, mas agora preciso ter a possibilidade de um cliente optar pelo pagamento em cheques, assim o código do cheque cadastrado na tabela de cheques seria mais uma FK e não tem como ter duas FK em uma tabela.

    Porém caso o cliente pague com promissórias, quando eu for lançar o pagamento de uma promissória, vou ter problema com a chave que aponta para a tabela cheque.

    O que fazer?

    segunda-feira, 10 de fevereiro de 2020 13:56
  • De forma bem simplificada seria isso, mas sabemos que na prática não vai funcionar.

    segunda-feira, 10 de fevereiro de 2020 16:25
  • Flávio,

    Levando-se em consideração a sua representação, inicialmente eu pensaria da seguinte forma:

    1 - Uma entidade responsável em armazenar todos os tipos e formas de pagamento;

    2 - Uma entidade que efetivamente vai guardar os detalhes e dados de pagamento;

    3 - Uma entidade que armazena que poderia ser considerada o fato relacionado ao pagamento, tendo como base:

    • O Pagamento;
    • A forma de Pagamento;
    • O Tipo do Pagamento; e
    • Quem pagou.

    Ou seja, esta entidade que podemos considerar como sendo o fato a ser relacionado, iria consistir as relações entre Cliente, Promissória, Pagamento e Tipo de Pagamento.

    Ao que se assemelha com a sua entidade TbMovimentacoes.

    Pois bem, esse foi um pensamento rápido que veio a minha mente, como sempre gosto de dizer não conheço as suas regras de negócio e suas realidades do dia a dia.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    segunda-feira, 10 de fevereiro de 2020 17:25
    Moderador