1use crate::{cobranca::{Cobranca, CodBarras, CodigoMoeda, CodBanco}, utils::date_to_fator_vencimento};
2use chrono::NaiveDate;
3
4impl Cobranca {
5 pub fn builder() -> CobrancaBuilder<NoCodBanco, NoCodMoeda> {
6 CobrancaBuilder::new()
7 }
8}
9
10pub struct NoCodMoeda;
11pub struct NoCodBanco;
12
13
14pub struct CobrancaBuilder<CB, CM> {
15 pub cod_banco: CB,
16 pub cod_moeda: CM,
17 pub data_vencimento: Option<NaiveDate>,
18 pub valor: Option<f64>,
19}
20
21impl CobrancaBuilder<NoCodBanco, NoCodMoeda> {
22 pub fn new() -> CobrancaBuilder<NoCodBanco, NoCodMoeda> {
23 Self {
24 cod_banco: NoCodBanco,
25 cod_moeda: NoCodMoeda,
26 data_vencimento: None,
27 valor: None,
28 }
29 }
30}
31
32impl<CM> CobrancaBuilder<NoCodBanco, CM> {
33 pub fn cod_banco(self, cod_banco: CodBanco) -> CobrancaBuilder<CodBanco, CM> {
34 CobrancaBuilder {
35 cod_banco: cod_banco,
36 cod_moeda: self.cod_moeda,
37 data_vencimento: self.data_vencimento,
38 valor: self.valor,
39 }
40 }
41}
42
43impl<CB> CobrancaBuilder<CB, NoCodMoeda> {
44 pub fn cod_moeda(self, cod_moeda: CodigoMoeda) -> CobrancaBuilder<CB, CodigoMoeda> {
45 CobrancaBuilder {
46 cod_banco: self.cod_banco,
47 cod_moeda: cod_moeda,
48 data_vencimento: self.data_vencimento,
49 valor: self.valor,
50 }
51 }
52}
53
54impl<CB, CM> CobrancaBuilder<CB, CM> {
55 pub fn data_vencimento(self, data_vencimento: NaiveDate) -> CobrancaBuilder<CB, CM> {
56 CobrancaBuilder {
57 cod_banco: self.cod_banco,
58 cod_moeda: self.cod_moeda,
59 data_vencimento: Some(data_vencimento),
60 valor: self.valor,
61 }
62 }
63}
64
65impl<CB, CM> CobrancaBuilder<CB, CM> {
66 pub fn valor(self, valor: f64) -> CobrancaBuilder<CB, CM> {
67 CobrancaBuilder {
68 cod_banco: self.cod_banco,
69 cod_moeda: self.cod_moeda,
70 data_vencimento: self.data_vencimento,
71 valor: Some(valor),
72 }
73 }
74}
75
76impl CobrancaBuilder<CodBanco, CodigoMoeda> {
77 pub fn build(self) -> Cobranca {
78 let cobranca = {
79 let mut result = [b'0'; 44];
80
81 let fator_vencimento = if let Some(data_vencimento) = self.data_vencimento {
82 date_to_fator_vencimento(data_vencimento).unwrap_or(0u16)
83 } else {
84 0u16
85 };
86
87 let valor = if let Some(valor) = self.valor {
88 (valor * 100.0).trunc() as u64
89 } else {
90 0u64
91 };
92
93 result[0..3].copy_from_slice(format!("{:03}", self.cod_banco.0).as_ref());
94 result[3] = self.cod_moeda.into();
95 result[5..9].copy_from_slice(format!("{:04}", fator_vencimento).as_ref());
96 result[9..19].copy_from_slice(format!("{:010}", valor).as_ref());
97
98 let mut cobranca = CodBarras::new(&result).unwrap();
99 cobranca.update_dv();
100
101 cobranca
102 };
103
104 Cobranca::new(cobranca.as_bytes()).unwrap()
105 }
106}