Boa tarde a todos,
Antes de inserir o post fiz pesquisas e vários teste e não cheguei ao resultado esperado.
Toda ajuda será bem vinda. Desde já agradeço.
Caso: Incluir registros e atualizar dados da tabela Pai(principal) para tabela filho considerando as seguintes situações:
Processo Contas a Pagar:
- 1 Tabela principal - e501cpa - Registro do contas a pagar.
- 2 Tabela secundária - e501mcp - Registro de movimentos;
Na tabela principal a chave é composta por 3 campos. Numero do Título, Tipo do Título e Código do Fornecedor. Essa tabela será a principal, terá as informações do título (boleto) como data vencimento, situação do título, valor, numero da nota fiscal e assim por diante.
Na tabela secundária a chave também é composta por 4 campos. Numero do Título, Tipo do Título e Código do Fornecedor e Sequencia do Movimento (Chave composta da tabela E501TCP + Sequencia Movimento) . Nesta tabela registra os movimentos que podem ocorrer para o título até a sua liquidação. Quero dizer que um título pode ser pagos em varias formas de pagamento e com datas diferentes (isso é o que acontece no mundo real). Para isso temos essa tabela, tipo para registrar o histórico de pagamentos parciais.
Eventos:
Inserir titulo 1 registro: ao registrar o primeiro registro (título contas a pagar) a tabela principal deverá gravar os dados na tabela secundária(filha). (está fazendo mais creio que não seja a melhor prática).
Alterar título 1 registro: se caso alterar a data de vencimento ou valor deverá ser feito apenas para o primeiro registro desde que não tenha algum movimento na tabela E501MCP que a sequencia seja maior que o primeiro registro.
Excluir título 1 registro: se excluir o título deverá excluir o titulo da tabela E501MCP desde que não tenha movimentos onde a sequencia do movimento seja maior que o primeiro registro.
Inserir Registros parciais de baixa: quando realizar um movimento sequencia 2 (exemplo baixa parcial do titulo, isto é pagamento não integral , realizada por outro processo) a tabela E501TCP não deve restringir a tabela E501MCP.
Então, pessoal, alguém já fez algo semelhante e que poderia dar uma ajuda?
Não sei se a melhor opção é utilizar JoinTable com JoinColumns ou se continuo utilizando o mapeamento ManyToOne persistindo campos chaves.
Código.
Tabela Principal (e501tcp)
@Entity
@Table(name="e501tcp")
@IdClass(value= TituloCPAId.class)
public class TituloCPA implements Serializable {
/**
*
*/
private static final long serialVersionUID = -194728923344243052L;
/*
@EmbeddedId
private TituloCPAId tituloCPAId;
*/
@Id
private String numTitulo;
@Id
private String tipoTitulo;
@Id
private Integer codigoFornecedor;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="codfor", referencedColumnName="codfor", insertable=false, updatable = false, foreignKey=@ForeignKey(name="fk_e501tcp_e095for"))
private Fornecedor fornecedor;
@Column(name="codtns", length=5)
Tabela Secundária (e501mcp)
@Entity
@Table(name="e501mcp")
@IdClass(value= TituloCPAMovtoId.class)
public class TituloCPAMovto implements Serializable {
/**
*
*/
private static final long serialVersionUID = 3608713509129343024L;
@Id
private String numTitulo;
@Id
private String tipoTitulo;
@Id
private Integer codigoFornecedor;
@Id
private int seqMovimento;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="codcfn", referencedColumnName="codcfn", foreignKey=@ForeignKey(name="fk_e501tcp_e000pfn"))
private PlanoFinanceiro planoFinanceiro;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="codccu", referencedColumnName="codccu", foreignKey=@ForeignKey(name="fk_e501tcp_e000ccu"))
private CentroCusto centroCusto;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="codfor", referencedColumnName="codfor", insertable=false, updatable = false, foreignKey=@ForeignKey(name="fk_e501tcp_e095for"))
private Fornecedor fornecedor;
@ManyToOne
@JoinColumn(name="codemp", referencedColumnName="codemp", foreignKey=@ForeignKey(name="fk_e501mcp_e000emp"))
private Empresa empresa;
@ManyToOne
@JoinColumn(name="codigo", referencedColumnName="codigo", foreignKey=@ForeignKey(name="fk_e501mcp_usuario"))
private Usuario usuario;
@Temporal(TemporalType.DATE)
@Column(name="datmov")
private Date dataMovimento;
@Column(name="codtns", length=5)
private String tnsMovimento;
@Column(name="obsmov", length= 160)
private String obsMovimento;
@Temporal(TemporalType.DATE)
Método Salvar
public void salvar(){
//var p msg
String msgNumTitCPA = this.tituloCPA.getNumTitulo();
String msgTipoTitulo = this.tituloCPA.getTipoTitulo();
String msgForTitCPA = this.tituloCPA.getFornecedor().getNomeFornecedor();
BigDecimal msgVlrTitCPA = this.tituloCPA.getValorOriginal();
FacesContext context = FacesContext.getCurrentInstance();
Date dataAtual = new Date(System.currentTimeMillis());
Date vDtaEntrada = tituloCPA.getDataEntrada(); // data de entrada do título
Date vDtaEmissao = tituloCPA.getDataEmissao(); // data de emisso do título
Date vDtaVencimento = tituloCPA.getDataVencimento(); // data de vencimento titulo
Integer vCtaFin = this.tituloCPA.getPlanoFinanceiro().getCodCtaFinanc();
Integer vCtaCcu = this.tituloCPA.getCentroCusto().getCodCentroCusto();
if(vCtaFin == 37){
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN,"Campo Class.Despesas. Falta classificar o tipo de depesa do título!", null));
return ;
}
if(vCtaCcu == 11){
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN,"Campo Aprop.Custos. Falta definir o departamento que absorve o custo!", null));
return ;
}
/* Validação do campo Data entrada
* A data de entrad não pode ser superior à data do dia atual
* */
if(vDtaEntrada.after(dataAtual)){
/* FacesMessage facesMessage = new FacesMessage( "A data de entrada do título deve ser inferior a data do dia atual!");
context.addMessage(null, facesMessage);*/
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN,"Campo Data entrada. O título não pode ser registrado em data futura ao dia atual. Processo não existe!", null));
return ;
}
/* Validação do campo Data emissão
* A data de emissão não pode ser superior à data de entrada do título
* */
if(vDtaEmissao.after(vDtaEntrada)){
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN,"Campo Data emissão. O título não pode ser registrado com a data de emissão superior a data de entrada!", null));
return ;
}
/* Validação do campo Data vencimento
* A data de vencimento não pode ser inferior à data de emissão do título.
* */
if(vDtaVencimento.before(vDtaEmissao)){
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN,"Campo Data vencimento. O título não pode ser registrado com a data de vencimento inferior a data de emissão do título!",null));
return ;
}
//consiste chaves;
this.tituloCPA.setEmpresa(this.contextoBean.getUsuarioLogado().getEmpresa());
this.tituloCPA.setUsuario(this.contextoBean.getUsuarioLogado());
this.tituloCPA.setCodigoFornecedor(this.tituloCPA.getFornecedor().getCodigoFornecedor());
this.tituloCPA.setNumTitulo(this.tituloCPA.getNumTitulo());
this.tituloCPA.setTipoTitulo(this.tituloCPA.getTipoTitulo());
//consiste valor padrao
this.tituloCPA.setTnsTitulo("90500");
this.tituloCPA.setSitTitulo("AB");
this.tituloCPA.setValorAberto(this.tituloCPA.getValorOriginal());
//salvar os dados
TituloCPARN tituloCPARN = new TituloCPARN();
TituloCPA existe = tituloCPARN.buscarPorTituloKey(this.tituloCPA.getEmpresa(),msgNumTitCPA, msgTipoTitulo, this.tituloCPA.getFornecedor());
if(existe != null){
BigDecimal msgVlrTituloRegistrado = existe.getValorOriginal();
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN,"O título já está existe para esse fornecedor! No valor R$" + msgVlrTituloRegistrado , null));
return ;
} else {
// Registra movimento na tabela E501MCP (Tabela de movimento do contas a pagar
TituloCPAMovtoRN tituloCPAMovtRN = new TituloCPAMovtoRN();
this.tituloCPAMovto.setNumTitulo(this.tituloCPA.getNumTitulo());
this.tituloCPAMovto.setTipoTitulo(this.tituloCPA.getTipoTitulo());
this.tituloCPAMovto.setCodigoFornecedor(this.tituloCPA.getFornecedor().getCodigoFornecedor());
this.tituloCPAMovto.setSeqMovimento(1);
this.tituloCPAMovto.setTnsMovimento("90500");
this.tituloCPAMovto.setDataMovimento(this.tituloCPA.getDataEntrada());
this.tituloCPAMovto.setValorMovimento(this.tituloCPA.getValorOriginal());
this.tituloCPAMovto.setEmpresa(this.contextoBean.getUsuarioLogado().getEmpresa());
this.tituloCPAMovto.setUsuario(this.contextoBean.getUsuarioLogado());
this.tituloCPAMovto.setPlanoFinanceiro(this.tituloCPA.getPlanoFinanceiro());
this.tituloCPAMovto.setCentroCusto(this.tituloCPA.getCentroCusto());
tituloCPAMovtRN.salvar(this.tituloCPAMovto);
tituloCPARN.salvar(this.tituloCPA);
//mensagem cadastro realizado
FacesMessage facesMessage = new FacesMessage("O título numero " + msgNumTitCPA + " , do Fornecedor: " + msgForTitCPA + " \n no valor R$ " + msgVlrTitCPA + " \n, foi salvo com sucesso!" );
/*" \nFornecedor: " + msgForTitCPA +*/
context.addMessage(null, facesMessage);
}
/*try{*/
//limpa form
this.tituloCPA = new TituloCPA();
return;
}