use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Nfse {
pub identificacao: IdentificacaoNfse,
pub prestador: PrestadorServico,
pub tomador: Option<TomadorServico>,
pub intermediario: Option<IntermediarioServico>,
pub servico: ServicoNfse,
pub valores: ValoresNfse,
pub informacoes_complementares: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IdentificacaoNfse {
pub numero: u64,
pub codigo_verificacao: String,
pub data_emissao: String,
pub competencia: String,
pub numero_rps: Option<u64>,
pub serie_rps: Option<String>,
pub tipo_rps: Option<u8>,
pub natureza_operacao: NaturezaOperacaoNfse,
pub regime_especial: Option<RegimeEspecialNfse>,
pub optante_simples_nacional: bool,
pub incentivador_cultural: bool,
pub status: StatusNfse,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
#[repr(u8)]
pub enum NaturezaOperacaoNfse {
TributacaoMunicipio = 1,
TributacaoForaMunicipio = 2,
Isencao = 3,
Imune = 4,
SuspensaJudicial = 5,
SuspensaAdministrativo = 6,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
#[repr(u8)]
pub enum RegimeEspecialNfse {
MicroempresaMunicipal = 1,
Estimativa = 2,
SociedadeProfissionais = 3,
Cooperativa = 4,
Mei = 5,
MeEppSimplesNacional = 6,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub enum StatusNfse {
Normal,
Cancelada,
Substituida,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PrestadorServico {
pub cnpj: String,
pub inscricao_municipal: Option<String>,
pub razao_social: String,
pub nome_fantasia: Option<String>,
pub endereco: EnderecoNfse,
pub telefone: Option<String>,
pub email: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TomadorServico {
pub tipo_documento: u8,
pub documento: String,
pub inscricao_municipal: Option<String>,
pub inscricao_estadual: Option<String>,
pub razao_social: String,
pub endereco: Option<EnderecoNfse>,
pub telefone: Option<String>,
pub email: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IntermediarioServico {
pub tipo_documento: u8,
pub documento: String,
pub razao_social: String,
pub inscricao_municipal: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnderecoNfse {
pub logradouro: String,
pub numero: String,
pub complemento: Option<String>,
pub bairro: String,
pub codigo_municipio: String,
pub municipio: String,
pub uf: String,
pub cep: String,
pub codigo_pais: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServicoNfse {
pub codigo_servico: String,
pub codigo_cnae: Option<String>,
pub codigo_servico_municipio: Option<String>,
pub codigo_tributacao_municipio: Option<String>,
pub discriminacao: String,
pub municipio_prestacao: String,
pub codigo_pais: Option<String>,
pub codigo_obra: Option<String>,
pub art: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValoresNfse {
pub valor_servicos: f32,
pub valor_deducoes: f32,
pub valor_pis: f32,
pub valor_cofins: f32,
pub valor_inss: f32,
pub valor_ir: f32,
pub valor_csll: f32,
pub outras_retencoes: f32,
pub valor_iss: f32,
pub aliquota_iss: f32,
pub desconto_incondicionado: f32,
pub desconto_condicionado: f32,
pub base_calculo: f32,
pub valor_liquido: f32,
pub iss_retido: bool,
pub valor_iss_retido: f32,
pub responsavel_retencao: Option<u8>,
}
impl Default for ValoresNfse {
fn default() -> Self {
Self {
valor_servicos: 0.0,
valor_deducoes: 0.0,
valor_pis: 0.0,
valor_cofins: 0.0,
valor_inss: 0.0,
valor_ir: 0.0,
valor_csll: 0.0,
outras_retencoes: 0.0,
valor_iss: 0.0,
aliquota_iss: 0.0,
desconto_incondicionado: 0.0,
desconto_condicionado: 0.0,
base_calculo: 0.0,
valor_liquido: 0.0,
iss_retido: false,
valor_iss_retido: 0.0,
responsavel_retencao: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Rps {
pub identificacao: IdentificacaoRps,
pub data_emissao: String,
pub status: u8,
pub rps_substituido: Option<IdentificacaoRps>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IdentificacaoRps {
pub numero: u64,
pub serie: String,
pub tipo: u8,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoteRps {
pub numero_lote: String,
pub cnpj_prestador: String,
pub inscricao_municipal_prestador: String,
pub quantidade_rps: u32,
pub lista_rps: Vec<RpsCompleto>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RpsCompleto {
pub rps: Rps,
pub prestador: PrestadorServico,
pub tomador: Option<TomadorServico>,
pub servico: ServicoNfse,
pub valores: ValoresNfse,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RespostaConsultaNfse {
pub sucesso: bool,
pub mensagem: Option<String>,
pub nfses: Vec<Nfse>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RespostaEnvioLote {
pub numero_lote: String,
pub protocolo: Option<String>,
pub data_recebimento: Option<String>,
pub situacao: u8,
pub mensagens: Vec<MensagemRetorno>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MensagemRetorno {
pub codigo: String,
pub mensagem: String,
pub correcao: Option<String>,
}
pub fn calcular_valores_nfse(
valor_servicos: f32,
aliquota_iss: f32,
valor_deducoes: f32,
iss_retido: bool,
aliquota_pis: Option<f32>,
aliquota_cofins: Option<f32>,
aliquota_inss: Option<f32>,
aliquota_ir: Option<f32>,
aliquota_csll: Option<f32>,
) -> ValoresNfse {
let base_calculo = valor_servicos - valor_deducoes;
let valor_iss = base_calculo * (aliquota_iss / 100.0);
let valor_pis = aliquota_pis.map(|a| base_calculo * (a / 100.0)).unwrap_or(0.0);
let valor_cofins = aliquota_cofins.map(|a| base_calculo * (a / 100.0)).unwrap_or(0.0);
let valor_inss = aliquota_inss.map(|a| base_calculo * (a / 100.0)).unwrap_or(0.0);
let valor_ir = aliquota_ir.map(|a| base_calculo * (a / 100.0)).unwrap_or(0.0);
let valor_csll = aliquota_csll.map(|a| base_calculo * (a / 100.0)).unwrap_or(0.0);
let valor_iss_retido = if iss_retido { valor_iss } else { 0.0 };
let outras_retencoes = valor_pis + valor_cofins + valor_inss + valor_ir + valor_csll;
let valor_liquido = valor_servicos - valor_iss_retido - outras_retencoes;
ValoresNfse {
valor_servicos,
valor_deducoes,
valor_pis,
valor_cofins,
valor_inss,
valor_ir,
valor_csll,
outras_retencoes,
valor_iss,
aliquota_iss,
desconto_incondicionado: 0.0,
desconto_condicionado: 0.0,
base_calculo,
valor_liquido,
iss_retido,
valor_iss_retido,
responsavel_retencao: if iss_retido { Some(2) } else { None }, }
}