# -*- coding: utf-8 -*- from openerp.http import request as r from openerp.tools import float_round, DEFAULT_SERVER_DATE_FORMAT from dateutil.parser import parse from dateutil.relativedelta import relativedelta as rd def create_invoice_move_lines(invoice_ids, paid_amount, date_today): assert len(invoice_ids) == 1 invoice = r.env['account.invoice'].browse(invoice_ids) is_purchase = False scoped_context = dict(r.context, lang=invoice.partner_id.lang) invoice_move_lines = invoice._get_analytic_lines() decimal_precision = r.env['decimal.precision'].precision_get('Account') compute_taxes = r.env['account.invoice.tax'].compute(invoice.with_context(lang=invoice.partner_id.lang)) invoice.check_tax_lines(compute_taxes) invoice._recompute_tax_amount() invoice_move_lines += r.env['account.invoice.tax'].move_line_get(invoice.id) total, total_currency, invoice_move_lines = invoice.with_context(scoped_context).compute_invoice_totals(invoice.company_id.currency_id, invoice.reference, invoice_move_lines) if total < 0: total = total * -1 is_purchase = True paid_amount = float_round(paid_amount, precision_digits=decimal_precision) paid_percentage = abs(paid_amount / float_round(total, decimal_precision)) distributed_percentage = -(paid_percentage / len(invoice.payment_term.line_ids)) payment_lines = [] for line in invoice.payment_term.line_ids: date_due = (parse(date_today) + rd(days=line.days + line.days2)).strftime(DEFAULT_SERVER_DATE_FORMAT) if paid_percentage and paid_percentage < 1.0: payment_lines.append([date_today, paid_percentage]) paid_percentage = paid_amount = 0 if date_due == date_today and line.value_amount: distributed_percentage = -((payment_lines[0][1] - line.value_amount) / (len(invoice.payment_term.line_ids) - 1)) continue if line.value != 'balance': payment_lines.append([date_due, line.value_amount + distributed_percentage]) continue payment_lines.append([date_due, line.value_amount]) for payment_line in payment_lines: current_price = round(total * payment_line[1], decimal_precision) if current_price < 0.0: continue paid_amount = paid_amount + current_price price = current_price if payment_line[1] else round(total - paid_amount, decimal_precision) or total if is_purchase: price = price * -1 invoice_move_lines.append({ 'type': 'dest', 'name': '/', 'price': price, 'account_id': invoice.account_id.id, 'date_maturity': payment_line[0], 'amount_currency': invoice.company_id.currency_id.compute(payment_line[1], invoice.currency_id) if invoice.currency_id != invoice.company_id.currency_id else False, 'currency_id': invoice.currency_id != invoice.company_id.currency_id and invoice.currency_id.id, 'ref': invoice.type in ('in_invoice', 'in_refund') and invoice.reference or invoice.number }) payment_lines = [] return invoice_move_lines def create_account_move(invoice_ids, invoice_move_lines): assert len(invoice_ids) == 1 invoice = r.env['account.invoice'].browse(invoice_ids) accounting_partner = r.env['res.partner']._find_accounting_partner(invoice.partner_id) move_line_values = [(0, 0, invoice.line_get_convert(line, accounting_partner.id, invoice.date_invoice)) for line in invoice_move_lines] move_line_values = invoice.group_lines(invoice_move_lines, move_line_values) move_line_values = invoice.finalize_invoice_move_lines(move_line_values) ctx = dict(r.context, lang=invoice.partner_id.lang, company_id=invoice.company_id.id) period = invoice.period_id if not period: period = period.with_context(ctx).find(invoice.date_invoice)[:1] if period: for line in move_line_values: line[2]['period_id'] = period.id ctx['invoice'] = invoice ctx_nolang = ctx.copy() ctx_nolang.pop('lang', None) account_move = r.env['account.move'].with_context(ctx_nolang).create({ 'ref': invoice.reference or invoice.name, 'line_id': move_line_values, 'journal_id': invoice.journal_id.with_context(r.context, lang=invoice.partner_id.lang).id, 'date': invoice.date_invoice, 'narration': invoice.comment, 'company_id': invoice.company_id.id, 'period_id': period.id }) invoice.with_context(ctx).write({ 'move_id': account_move.id, 'period_id': account_move.period_id.id, 'move_name': account_move.name, }) account_move.post() return account_move