Closed eduardokum closed 9 years ago
Segue exemplo com base no código do meu ERP para geração do ECD do ano de 2014.
Infelizmente meu ERP não está pronto e nem possuirá código aberto (a principio).
Este código possui diversas coisas hard code para maquiar parametros que ainda não existem no meu ERP.
Com o código abaixo, o ECD foi entregue gerado pelo sistema (tendo que ser validado e assinado no PVA) sem nenhum erro ou aviso.
O python-sped não exime o programador de conhecer a legislação do SPED e seguir sua documentação, ele apenas faz com que os arquivos sejam gerados sem erros de inconsistências. Validações mais elaboradas ficam a cargo do programador e/ou contador no PVA.
def sped_ecd(request):
start_date = date(2014, 1, 1)
end_date = date(2014, 12, 31)
periods = Period.objects.filter(start_date__gte=start_date, end_date__lte=end_date).order_by('start_date')
accounts = Account.objects.all().order_by('code')
first_period = periods.first()
last_period = periods.last()
PeriodicBalance.calculate_for(last_period, True)
#
# Abertura do Arquivo
#
arquivo = ArquivoDigital()
registro_abertura = arquivo._registro_abertura
registro_abertura.DT_INI = start_date
registro_abertura.DT_FIN = end_date
registro_abertura.NOME = 'SUA EMPRESA LTDA'
registro_abertura.CNPJ = '00000000000000'
registro_abertura.UF = 'PR'
registro_abertura.COD_MUN = 4106902
registro_abertura.IM = '00000'
registro_abertura.IND_SIT_INI_PER = '3'
registro_abertura.IND_NIRE = '1'
registro_abertura.IND_FIN_ESC = '0'
registro_abertura.IND_GRANDE_PORTE = '0'
registro_abertura.TIP_ECD = '0'
bloco_0 = arquivo._blocos['0']
registro_0007 = Registro0007()
registro_0007.COD_ENT_REF = '00'
bloco_0.add(registro_0007)
bloco_i = arquivo._blocos['I']
registro_i010 = RegistroI010()
registro_i010.IND_ESC = 'G' # Livro Diário Completo
registro_i010.COD_VER_LC = '3.00'
bloco_i.add(registro_i010)
registro_i030 = RegistroI030()
registro_i030.DNRC_ABERT = 'TERMO DE ABERTURA'
registro_i030.NUM_ORD = 5
registro_i030.NAT_LIVR = 'DIÁRIO GERAL'
registro_i030.NOME = arquivo._registro_abertura.NOME
registro_i030.NIRE = '000000'
registro_i030.CNPJ = arquivo._registro_abertura.CNPJ
registro_i030.DT_ARQ = date(2014, 1, 10)
registro_i030.DESC_MUN = 'CURITIBA'
registro_i030.DT_EX_SOCIAL = end_date
bloco_i.add(registro_i030)
for account in accounts:
if not account.data['reference_account']:
continue
registro_i050 = RegistroI050()
registro_i050.DT_ALT = start_date
# TODO: Cadastrar a natureza na conta
account_nature = '%02d' % (4 if int(account.get_root().code[0]) == 3 else int(account.get_root().code[0]))
registro_i050.COD_NAT = account_nature
registro_i050.IND_CTA = account.type
registro_i050.NIVEL = account.level + 1
registro_i050.COD_CTA = account.code
if account.parent is not None:
registro_i050.COD_CTA_SUP = account.parent.code
registro_i050.CTA = account.name
bloco_i.add(registro_i050)
if account.type == Account.ANALYTICAL:
registro_i051 = RegistroI051()
registro_i051.COD_ENT_REF = '2' # PJ Lucro Presumido
registro_i051.COD_CTA_REF = account.data['reference_account']
bloco_i.add(registro_i051)
registro_i052 = RegistroI052()
registro_i052.COD_AGL = account.code
bloco_i.add(registro_i052)
for period in periods:
registro_i150 = RegistroI150()
registro_i150.DT_INI = period.start_date
registro_i150.DT_FIN = period.end_date
bloco_i.add(registro_i150)
for account in accounts.filter(type=Account.ANALYTICAL):
periodic_balance = PeriodicBalance.objects.filter(period=period, account=account).first()
if not periodic_balance:
continue
if not periodic_balance.initial_balance and \
not periodic_balance.debit_value and \
not periodic_balance.credit_value and \
not periodic_balance.final_balance:
continue
registro_i155 = RegistroI155()
registro_i155.COD_CTA = account.code
registro_i155.VL_SLD_INI = abs(periodic_balance.initial_balance)
registro_i155.IND_DC_INI = 'C' if periodic_balance.initial_balance > 0 else 'D'
registro_i155.VL_DEB = abs(periodic_balance.debit_value)
registro_i155.VL_CRED = abs(periodic_balance.credit_value)
registro_i155.VL_SLD_FIN = abs(periodic_balance.final_balance)
registro_i155.IND_DC_FIN = 'C' if periodic_balance.final_balance > 0 else 'D'
bloco_i.add(registro_i155)
for entry in Entry.objects.filter(date__gte=start_date,
date__lte=end_date):
registro_i200 = RegistroI200()
registro_i200.NUM_LCTO = str(entry.id)
registro_i200.DT_LCTO = entry.date
registro_i200.VL_LCTO = entry.value
if entry.memo == 'APURAÇÃO RESULTADO 12/2014':
registro_i200.IND_LCTO = 'E' # N or E
else:
registro_i200.IND_LCTO = 'N' # N or E
bloco_i.add(registro_i200)
for item in entry.items.all():
registro_i250 = RegistroI250()
registro_i250.COD_CTA = item.account.code
registro_i250.VL_DC = abs(item.credit_value or item.debit_value)
registro_i250.IND_DC = 'C' if item.credit_value else 'D'
registro_i250.HIST = entry.memo
bloco_i.add(registro_i250)
registro = RegistroI350()
registro.DT_RES = end_date
bloco_i.add(registro)
PeriodicBalance.calculate_for(last_period, False)
for account in accounts.filter(code__startswith='3', type=Account.ANALYTICAL):
periodic_balance = PeriodicBalance.objects.filter(period=last_period, account=account).first()
if not periodic_balance:
continue
registro_i355 = RegistroI355()
registro_i355.COD_CTA = account.code
registro_i355.VL_CTA = abs(periodic_balance.final_balance)
registro_i355.IND_DC = account.nature
bloco_i.add(registro_i355)
bloco_j = arquivo._blocos['J']
registro_j005 = RegistroJ005()
registro_j005.DT_INI = start_date
registro_j005.DT_FIN = end_date
registro_j005.ID_DEM = 1
bloco_j.add(registro_j005)
#
# Calculo Balanco Patrimonial
#
PeriodicBalance.calculate_for(last_period, True)
for account in accounts.filter(Q(code__startswith='1') | Q(code__startswith='2')):
first_balance = PeriodicBalance.objects.filter(period=first_period, account=account).first()
last_balance = PeriodicBalance.objects.filter(period=last_period, account=account).first()
if not first_balance.initial_balance and not last_balance.final_balance:
continue
registro_j100 = RegistroJ100()
registro_j100.COD_AGL = account.code
registro_j100.NIVEL_AGL = account.level + 1
registro_j100.DESCR_COD_AGL = account.name
registro_j100.IND_GRP_BAL = account.code[:1]
registro_j100.VL_CTA_INI = abs(first_balance.initial_balance)
registro_j100.IND_DC_BAL_INI = 'C' if first_balance.initial_balance >= 0 else 'D'
registro_j100.VL_CTA = abs(last_balance.final_balance)
registro_j100.IND_DC_BAL = 'C' if last_balance.final_balance >= 0 else 'D'
bloco_j.add(registro_j100)
#
# Calculo Resultado (DRE)
#
res = dict([(account, Decimal(0)) for account in accounts.filter(code__startswith='3')])
for item in EntryItem.all_objects.filter(entry__memo='APURAÇÃO RESULTADO 12/2014', account__code__startswith='3'):
account = item.account
while account:
res[account] += (item.credit_value - item.debit_value)
account = account.parent
for account in accounts.filter(Q(level=2) | Q(level=4), code__startswith='3').order_by('code'):
registro_j150 = RegistroJ150()
if account.nature == Account.ANALYTICAL:
registro_j150.COD_AGL = account.code
registro_j150.NIVEL_AGL = account.level + 1
registro_j150.DESCR_COD_AGL = account.name
if not res[account]:
continue
registro_j150.VL_CTA = abs(res[account])
if res[account] >= Decimal(0):
registro_j150.IND_VL = 'D' if account.nature == Account.ANALYTICAL else 'N'
else:
registro_j150.IND_VL = 'R' if account.nature == Account.ANALYTICAL else 'P'
bloco_j.add(registro_j150)
#
# Encerramento
#
registro_j900 = RegistroJ900()
registro_j900.DNRC_ENCER = 'TERMO DE ENCERRAMENTO'
registro_j900.NUM_ORD = 5
registro_j900.NAT_LIVRO = 'DIÁRIO GERAL'
registro_j900.NOME = 'SUA EMPRESA LTDA'
registro_j900.DT_INI_ESCR = start_date
registro_j900.DT_FIN_ESCR = end_date
bloco_j.add(registro_j900)
# Dados do Socio
registro_j930 = RegistroJ930()
registro_j930.IDENT_NOM = 'ADMINSTRADOR DA SILVA'
registro_j930.IDENT_CPF = '0000000000000'
registro_j930.IDENT_QUALIF = 'Administrador'
registro_j930.COD_ASSIN = '205'
registro_j930.EMAIL = 'voce@suaempresa.com.br'
registro_j930.FONE = '00000'
bloco_j.add(registro_j930)
# Dados do Contador
registro_j930 = RegistroJ930()
registro_j930.IDENT_NOM = 'CONTADOR DA SILVA'
registro_j930.IDENT_CPF = '0000000000000'
registro_j930.IDENT_QUALIF = 'Contador'
registro_j930.COD_ASSIN = '900'
registro_j930.EMAIL = 'contador@suaempresa.com.br'
registro_j930.FONE = '00000'
registro_j930.IND_CRC = '00000/O'
registro_j930.UF_CRC = 'PR'
registro_j930.NUM_SEQ_CRC = 'PR/2015/000000'
registro_j930.DT_CRC = date(2015, 6, 30)
bloco_j.add(registro_j930)
response = HttpResponse(content_type='text/plain; charset=iso-8859-1')
response['Content-Disposition'] = 'attachment; filename="sped.txt"'
arquivo.prepare()
registro_i030.QTD_LIN = arquivo._registro_fechamento[2]
registro_j900.QTD_LIN = arquivo._registro_fechamento[2]
arquivo.write_to(response)
return response
Olá amigo, estou vendo seu projeto, estou pensando em utiliza-lo, integrando com meu ERP em php, você tem algum arquivo de exemplo de utilização?
Obrigado