Fiz algumas alterações mais profundas, seguindo o que o Jaime apresentou:
function TACBrBancoBrasil.FormataNossoNumero(const ACBrTitulo :TACBrTitulo): String;
var
ANossoNumero, AConvenio : string;
aCarteira: LongInt;
begin
with ACBrTitulo do
begin
AConvenio := ACBrBoleto.Cedente.Convenio;
ANossoNumero := OnlyNumber(NossoNumero);
aCarteira := StrToIntDef(Carteira,0);
// CCCCNNNNNNN-X
if (Length(AConvenio) <= 4) and (fpTamanhoMaximoNossoNum = 7) then
ANossoNumero := padR(AConvenio, 4, '0') + padR(ANossoNumero, 7, '0')
// CCCCCCNNNNN-X
else if (Length(AConvenio) > 4) and (Length(AConvenio) <= 6) and (fpTamanhoMaximoNossoNum = 5) then
ANossoNumero := padR(AConvenio, 6, '0') + padR(ANossoNumero, 5, '0')
// CCCCCCCNNNNNNNNNN
else if (Length(AConvenio) = 7) and (fpTamanhoMaximoNossoNum = 10) then
ANossoNumero := padR(AConvenio, 7, '0') + padR(ANossoNumero, 10, '0')
// NNNNNNNNNNNNNNNNN
else if (Length(AConvenio) > 4) and (Length(AConvenio) <= 6) and (fpTamanhoMaximoNossoNum = 17)
and ((ACBrTitulo.Carteira = '16') or (ACBrTitulo.Carteira = '18')) then
ANossoNumero := padR(ANossoNumero, 17, '0');
end;
Result := ANossoNumero;
end;
Removi o 1° if que validava as carteiras, pois a única excessão que achei na documentação é quando o nosso número tem 17 posições (anexo 5), e ai o convênio deve ser 6 posições e as carteiras só 16 ou 18. Pros demais não achei nada de diferente..
A mesma coisa pro método MontarCodigoBarras():
function TACBrBancoBrasil.MontarCodigoBarras(const ACBrTitulo : TACBrTitulo): String;
var
CodigoBarras, FatorVencimento, DigitoCodBarras :String;
a, ANossoNumero, AConvenio: string;
begin
AConvenio := ACBrTitulo.ACBrBoleto.Cedente.Convenio;
ANossoNumero := FormataNossoNumero(ACBrTitulo);
{Codigo de Barras}
with ACBrTitulo.ACBrBoleto do
begin
FatorVencimento := CalcularFatorVencimento(ACBrTitulo.Vencimento);
if ((ACBrTitulo.Carteira = '18') or (ACBrTitulo.Carteira = '16')) and
(Length(AConvenio) = 6) and (fpTamanhoMaximoNossoNum = 17) then
begin
CodigoBarras := IntToStrZero(Banco.Numero, 3) +
'9' +
FatorVencimento +
IntToStrZero(Round(ACBrTitulo.ValorDocumento * 100), 10) +
AConvenio + ANossoNumero + '21';
end
else
begin
CodigoBarras := IntToStrZero(Banco.Numero, 3) +
'9' +
FatorVencimento +
IntToStrZero(Round(ACBrTitulo.ValorDocumento * 100), 10) +
IfThen((Length(AConvenio) = 7), '000000', '') +
ANossoNumero +
IfThen((Length(AConvenio) < 7), padR(Cedente.Agencia, 4, '0'), '') +
IfThen((Length(AConvenio) < 7), padR(Cedente.Conta, 8, '0'), '') +
ACBrTitulo.Carteira;
end;
DigitoCodBarras := CalcularDigitoCodigoBarras(CodigoBarras);
end;
Result:= copy( CodigoBarras, 1, 4) + DigitoCodBarras + copy( CodigoBarras, 5, 44) ;
end;
Assim acho que cobre todas as opções.. testei aqui e agora estou tentando resolver o problema da conta do cedente, que mesmo estando setada para tamanho 5, é alterada para 10 (com zeros precedendo a conta) e no momento da geração do cód. de barras, ela sai errado.
Um detalhe muito importante: como não conseguimos alterar o valor da propriedade TamanhoMaximoNossoNum, esse valor tem que ser definido dentro da classe ACBrBancoBrasil.pas... não precisa nem dizer que isso é tosco mas não sei como acertar essa questão da propriedade..