Skip to content

Commit c856a07

Browse files
committed
[WIP] refactor codigo para mejor legibilidad
1 parent 5d8ab5c commit c856a07

File tree

1 file changed

+84
-80
lines changed

1 file changed

+84
-80
lines changed

account_interests/models/res_company_interest.py

+84-80
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,19 @@ def _cron_recurring_interests_invoices(self):
9696
error_message = _("We couldn't run interest invoices cron job in the following companies: %s.") % company_names
9797
raise UserError(error_message)
9898

99+
def _calculate_date_deltas(self, rule_type, interval):
100+
"""
101+
Calcula los intervalos de fechas para la generación de intereses.
102+
"""
103+
deltas = {
104+
'daily': relativedelta(days=interval),
105+
'weekly': relativedelta(weeks=interval),
106+
'monthly': relativedelta(months=interval),
107+
'yearly': relativedelta(years=interval),
108+
}
109+
return deltas.get(rule_type, relativedelta(months=interval))
110+
111+
99112
def create_interest_invoices(self):
100113
for rec in self:
101114
_logger.info(
@@ -108,18 +121,8 @@ def create_interest_invoices(self):
108121
rule_type = rec.rule_type
109122
interval = rec.interval
110123

111-
if rule_type == 'daily':
112-
next_delta = relativedelta(days=+interval)
113-
from_date_delta = relativedelta(days=-interval)
114-
elif rule_type == 'weekly':
115-
next_delta = relativedelta(weeks=+interval)
116-
from_date_delta = relativedelta(weeks=-interval)
117-
elif rule_type == 'monthly':
118-
next_delta = relativedelta(months=+interval)
119-
from_date_delta = relativedelta(months=-interval)
120-
else:
121-
next_delta = relativedelta(years=+interval)
122-
from_date_delta = relativedelta(years=-interval)
124+
next_delta = self._calculate_date_deltas(rule_type, interval)
125+
from_date_delta = self._calculate_date_deltas(rule_type, -interval)
123126

124127
from_date = to_date + from_date_delta
125128

@@ -140,44 +143,22 @@ def _get_move_line_domains(self):
140143
]
141144
return move_line_domain
142145

143-
def create_invoices(self, from_date, to_date, groupby=['partner_id']):
146+
def _update_deuda(self, deuda, partner, key, value):
144147
"""
145-
tengo deudas viejas por 2000 (super viejas)
146-
el 1 facturo 1000 que vencen el 20
147-
el 25 pagó 400.
148-
Detalle de cálculo de intereses:
149-
* interés por todo lo viejo (2000) x el rate
150-
* interés de todo lo que venció en el último período ($600) x días que estuvo vencido (10 días)
151-
* si además marcó "latest payment intereset" se agrega interés por los días que pagó tarde, es decir $400 x 5 días
148+
Actualiza el diccionario de deuda para un partner específico.
149+
Si el partner no existe en la deuda, lo inicializa.
150+
Si la clave no existe para el partner, la agrega.
152151
"""
153-
self.ensure_one()
154-
155-
journal = self.env['account.journal'].search([
156-
('type', '=', 'sale'),
157-
('company_id', '=', self.company_id.id)], limit=1)
152+
if partner not in deuda:
153+
deuda[partner] = {}
154+
deuda[partner][key] = deuda[partner].get(key, 0) + value
158155

159-
if self.receivable_account_ids != journal.default_account_id:
160-
journal = self.env['account.journal'].search([('default_account_id','in',self.receivable_account_ids.ids)], limit=1) or journal
161-
162-
# vemos todo lo impago que vencia antes del comienzo de este periodo de intereses ya que el interes ahí se calcula sobre el total
163-
# entre from date y to_date tenemos que calcular parciales segun dias cuando vencia comprobante
164-
move_line_domain_previous_periods = self._get_move_line_domains() + [('full_reconcile_id', '=', False), ('date_maturity', '<', from_date)]
165-
# Check if a filter is set
166-
if self.domain:
167-
move_line_domain_previous_periods += safe_eval(self.domain)
168-
169-
# fields = ['id:recordset', 'amount_residual:sum', 'partner_id:recordset', 'account_id:recordset'] descarto esto porque ya no se estan usando la mayoria de valores
170-
fields = ['amount_residual:sum']
171-
172-
move_line = self.env['account.move.line']
173-
# DE ACA VAN A SALIR LAS LINES DE DEUDAS ANTERIORES
174-
previous_grouped_lines = move_line._read_group(
175-
domain=move_line_domain_previous_periods,
176-
groupby=groupby,
177-
aggregates=fields,
178-
)
179-
180-
deuda = {x[0]: {'Deuda periodos anteriores': x[1] * self.rate} for x in previous_grouped_lines}
156+
def _calculate_debts(self, from_date, to_date, groupby=['partner_id']):
157+
"""
158+
Calcula las deudas e intereses por partner.
159+
Retorna un diccionario estructurado con los cálculos.
160+
"""
161+
deuda = {}
181162

182163
interest_rate = {
183164
'daily': 1,
@@ -186,66 +167,85 @@ def create_invoices(self, from_date, to_date, groupby=['partner_id']):
186167
'yearly': 360,
187168
}
188169

189-
# calculamos intereses de facturas del ultimo periodo
190-
last_period_lines = move_line.search(self._get_move_line_domains() + [('amount_residual', '>', 0), ('date_maturity', '>=', from_date), ('date_maturity', '<', to_date)])
191-
for partner, amls in last_period_lines.grouped('partner_id').items():
192-
interest = 0
193-
for move, lines in amls.grouped('move_id').items():
194-
days = (to_date - move.invoice_date_due).days
195-
interest += move.amount_residual * days * (self.rate / interest_rate[self.rule_type])
196-
if partner in deuda:
197-
deuda[partner]['Deuda último periodo'] = interest
198-
else:
199-
deuda[partner] = {'Deuda último periodo': interest}
170+
# Deudas de períodos anteriores
171+
previous_grouped_lines = self.env['account.move.line']._read_group(
172+
domain=self._get_move_line_domains() + [('full_reconcile_id', '=', False), ('date_maturity', '<', from_date)],
173+
groupby=groupby,
174+
aggregates=['amount_residual:sum'],
175+
)
176+
for x in previous_grouped_lines:
177+
self._update_deuda(deuda, x[0], 'Deuda periodos anteriores', x[1] * self.rate)
200178

179+
# Intereses por el último período
180+
last_period_lines = self.env['account.move.line'].search(
181+
self._get_move_line_domains() + [('amount_residual', '>', 0), ('date_maturity', '>=', from_date), ('date_maturity', '<', to_date)]
182+
)
183+
for partner, amls in last_period_lines.grouped('partner_id').items():
184+
interest = sum(
185+
move.amount_residual * (to_date - move.invoice_date_due).days * (self.rate / interest_rate[self.rule_type])
186+
for move, lines in amls.grouped('move_id').items()
187+
)
188+
self._update_deuda(deuda, partner, 'Deuda último periodo', interest)
201189

202-
# Feature de intereses por pago tardio (periodo actual)
190+
# Intereses por pagos tardíos
203191
if self.late_payment_interest:
204192

205193
partials = self.env['account.partial.reconcile'].search([
194+
# lo dejamos para NTH
195+
# debit_move_id. safe eval domain
206196
('debit_move_id.partner_id.active', '=', True),
207197
('debit_move_id.date_maturity', '>=', from_date),
208198
('debit_move_id.date_maturity', '<=', to_date),
209199
('debit_move_id.parent_state', '=', 'posted'),
210-
# lo dejamos para NTH
211-
# debit_move_id. safe eval domain
212200
('debit_move_id.account_id', 'in', self.receivable_account_ids.ids),
213201
('credit_move_id.date', '>=', from_date),
214202
('credit_move_id.date', '<', to_date)]).grouped('debit_move_id')
215203

216204
for move_line, parts in partials.items():
217205
due_payments = parts.filtered(lambda x: x.credit_move_id.date > x.debit_move_id.date_maturity)
206+
interest = 0
218207
if due_payments:
219208
due_payments_amount = sum(due_payments.mapped('amount'))
220209
last_date_payment = parts.filtered(lambda x: x.credit_move_id.date > x.debit_move_id.date_maturity).sorted('max_date')[-1].max_date
221210
days = (last_date_payment - move_line.date_maturity).days
222211
interest += due_payments_amount * days * (self.rate / interest_rate[self.rule_type])
223-
partner = move_line.partner_id
224-
if partner in deuda and 'Deuda pagos vencidos' in deuda[partner]:
225-
deuda[partner]['Deuda pagos vencidos'] += interest
226-
elif partner in deuda:
227-
deuda[partner]['Deuda pagos vencidos'] = interest
228-
else:
229-
deuda[partner] = {'Deuda pagos vencidos': interest}
230-
231-
self = self.with_context(
232-
company_id=self.company_id.id,
233-
mail_notrack=True,
234-
prefetch_fields=False).with_company(self.company_id)
212+
self._update_deuda(deuda, move_line.partner_id, 'Deuda pagos vencidos', interest)
213+
214+
return deuda
215+
216+
def create_invoices(self, from_date, to_date):
217+
"""
218+
Crea facturas de intereses a cada partner basadas en los cálculos de deuda.
219+
Ejemplo:
220+
Tengo deudas viejas por 2000 (super viejas)
221+
el 1 facturo 1000 que vencen el 20
222+
el 25 pagó 400.
223+
Detalle de cálculo de intereses:
224+
* interés por todo lo viejo (2000) x el rate
225+
* interés de todo lo que venció en el último período ($600) x días que estuvo vencido (10 días)
226+
* si además marcó "late payment interest" se agrega interés por los días que pagó tarde, es decir $400 x 5 días
227+
"""
228+
self.ensure_one()
229+
230+
# Calcular deudas e intereses
231+
deuda = self._calculate_debts(from_date, to_date)
232+
233+
journal = self.env['account.journal'].search([
234+
('type', '=', 'sale'),
235+
('company_id', '=', self.company_id.id)], limit=1)
235236

236237
total_items = len(deuda)
237238
_logger.info('%s interest invoices will be generated', total_items)
238-
for idx, partner in enumerate(deuda):
239-
move_vals = self._prepare_interest_invoice(partner,
240-
deuda[partner], to_date, journal)
241239

240+
# Crear facturas
241+
for idx, partner in enumerate(deuda):
242+
move_vals = self._prepare_interest_invoice(partner, deuda[partner], to_date, journal)
242243
if not move_vals:
243244
continue
244245

245-
_logger.info('Creating Interest Invoice (%s of %s) with values:\n%s', idx + 1, total_items, partner)
246+
_logger.info('Creating Interest Invoice (%s of %s) for partner ID: %s', idx + 1, total_items, partner.id)
246247

247248
move = self.env['account.move'].create(move_vals)
248-
249249
if self.automatic_validation:
250250
try:
251251
move.action_post()
@@ -256,7 +256,8 @@ def create_invoices(self, from_date, to_date, groupby=['partner_id']):
256256

257257

258258

259-
def prepare_info(self, to_date):
259+
260+
def _prepare_info(self, to_date):
260261
self.ensure_one()
261262

262263
# Format date to customer language
@@ -272,9 +273,12 @@ def prepare_info(self, to_date):
272273
return res
273274

274275
def _prepare_interest_invoice(self, partner, debt, to_date, journal):
276+
"""
277+
Retorna un diccionario con los datos para crear la factura
278+
"""
275279
self.ensure_one()
276280

277-
comment = self.prepare_info(to_date)
281+
comment = self._prepare_info(to_date)
278282
fpos = partner.property_account_position_id
279283
taxes = self.interest_product_id.taxes_id.filtered(
280284
lambda r: r.company_id == self.company_id)

0 commit comments

Comments
 (0)