Analysis Pattern: Regra Secundária de Lançamento (Secondary Posting Rule)

O que é

Detalhes de funcionamento

Quando deve ser usado

Código exemplo

class Testador {
...
public void configuraClienteNormal() {
cam = new Cliente("Cafe A Margot");
AcordoServico padrao = new AcordoServico();
...
padrao.addRegraLancamento(
TipoEvento.IMPOSTO,
new RegraFormulaSimples(
0.055,
Money.reais(0),
TipoLancamento.IMPOSTO),
criaCalendar(2003, 10, 1));

cam.setAcordoServico(padrao);
}
}
class RegraLancamento {
...
public void processa(EventoContabil evento) {
facaLancamento(evento, calculaValor(evento));
if (isTributavel()) {
new EventoTributo(evento, calculaValor(evento)).processa();
}
}
}
class RegraLancamento {
...
private boolean isTributavel() {
return !(tipo == TipoLancamento.IMPOSTO);
}
}

class EventoImposto extends EventoMonetario {
private EventoContabil base;
public EventoImposto(EventoContabil base, Money valorTributavel) {
super(
valorTributavel,
TipoEvento.IMPOSTO,
base.getQuandoOcorreu(),
base.getWhenNoticed(),
base.getCliente());
this.base = base;
assert(base.getTipoEvento() != getTipoEvento());// Provavel recursao infinita
}
}

Mantendo o Rastreio de Eventos

Código exemplo

class EventoImposto {
...
public EventoImposto(EventoContabil base, Money valorTributavel) {
super(
valorTributavel,
TipoEvento.IMPOSTO,
base.getQuandoOcorreu(),
base.getQuandoObservado(),
base.getCliente());
this.base = base;
base.addEventoSecundario(this);
assert(base.getTipoEvento() != getTipoEvento());// Provavel recursao infinita
...
}
}
class EventoContabil {
...
private List eventosSecundarios = new ArrayList();
void addEventoSecundario(EventoContabil arg) {
//so deve ser chamado pelo metodo set do evento secundario
eventosSecundarios.add(arg);
}
}
class EventoContabil {
...
Set getTodosLancamentosResultantes() {
Set resultado = new HashSet();
resultado.addAll(lancamentosResultantes);
Iterator it = eventosSecundarios.iterator();
while (it.hasNext()) {
EventoContabil evento = (EventoContabil) it.next();
result.addAll(evento.getlancamentosResultantes());
}
return result;
}
}
class Tester public void testConsumo() {
Consumo evento =
new Consumo(
Unit.KWH.valor(50),
criaCalendar(2003, 10, 1),
criaCalendar(2003, 10, 1),
cam);
evento.processa();
Lancamento lancamentoConsumo = getLancamento(cam, 0);
Lancamento lancamentoImposto = getLancamento(cam, 1);
assertEquals(Money.reais(500), lancamentoConsumo.getValor());
assertEquals(TipoLancamento.CONSUMO_BASICO, lancamentoConsumo.getTipo()); assertEquals(Money.reais(27.5), lancamentoImposto.getValor());
assertEquals(TipoLancamento.IMPOSTO, lancamentoImposto.getTipo());
assert(evento.getlancamentosResultantes().contains(lancamentoConsumo));
assert(evento.getTodosLancamentosResultantes().contains(lancamentoImposto));
}

programa