trytonpsk-hotel/invoice.py

184 lines
6.5 KiB
Python

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from datetime import date
from trytond.pool import PoolMeta, Pool
from trytond.model import fields
class Invoice(metaclass=PoolMeta):
__name__ = 'account.invoice'
def auto_reconcile(self):
reconcile_lines = []
Reconciliation = Pool().get('account.move.reconciliation')
account_reconcile_id = self.account.id
balance = []
for ml in self.payment_lines:
if not ml.reconciliation and ml.account.id == account_reconcile_id:
reconcile_lines.append(ml)
balance.append(ml.debit - ml.credit)
for ml in self.move.lines:
if ml.account.id == account_reconcile_id:
reconcile_lines.append(ml)
balance.append(ml.debit - ml.credit)
if sum(balance) != 0:
return
if reconcile_lines:
Reconciliation.create([{
'lines': [('add', reconcile_lines)],
'date': date.today(),
}])
@classmethod
def create_commissions(cls, invoices):
"""
This set Off set move in commission model from channel commission
in booking
"""
commissions = super(Invoice, cls).create_commissions(invoices)
for commission in commissions:
if commission.origin.__name__ == 'account.invoice.line':
inv_line = commission.origin
if inv_line.offset_move_line:
commission.offset_move_line = inv_line.offset_move_line.id
commission.save()
@classmethod
def _get_folio_origin(cls, line):
if line.origin and line.origin.__name__ == 'hotel.folio':
return line.origin
@classmethod
def process_offset_move(cls, invoice):
"""
This method create the offset move in the booking, for to cross
in the future with account move related to supplier invoice of
agent in module commissions
"""
Folio = Pool().get('hotel.folio')
folios_target = []
lines_ids = []
bk = None
for line in invoice.lines:
folio = cls._get_folio_origin(line)
if not folio:
return
folios_target.append((folio, line))
bk = folio.booking
if bk.channel and bk.collection_mode == 'anticipated':
lines_ids = Folio.set_offset_commission_move(folios_target, bk)
return lines_ids
def _add_commission_payment(self):
pool = Pool()
Commission = pool.get('commission')
MoveLine = pool.get('account.move.line')
lines_ids = [line.id for line in self.lines]
commissions = Commission.search([
('invoice_line', 'in', lines_ids)
])
payment_lines = []
to_reconcile = []
for comm in commissions:
if not comm.invoice_line or not comm.offset_move_line:
return
payment_lines.append(comm.offset_move_line.id)
invoice = comm.invoice_line.invoice
self.write([invoice], {'payment_lines': [
('add', payment_lines)
]})
to_reconcile.append(comm.offset_move_line)
for line in self.move.lines:
if line.account == self.account and not line.reconciliation:
to_reconcile.append(line)
if invoice.amount_to_pay == 0 and to_reconcile:
MoveLine.reconcile(to_reconcile)
@classmethod
def _post(cls, invoices):
for invoice in invoices:
lines_ids = None
if invoice.type == 'in':
super()._post([invoice])
continue
if invoice.type == 'out' and invoice.agent:
lines_ids = cls.process_offset_move(invoice)
super()._post([invoice])
if lines_ids:
cls.write([invoice], {'payment_lines': [('add', lines_ids)]})
if invoice.type == 'in':
invoice._add_commission_payment()
cls.set_booking_payments(invoice)
if not invoice.move.origin:
return
invoice.auto_reconcile()
@classmethod
def _add_payment(cls, inv, record, lines_ids):
balance = 0
for as_line in record.payments:
if as_line.move and as_line.party == inv.party:
balance += as_line.amount
if as_line.amount > inv.total_amount or balance > inv.total_amount:
break
for mline in as_line.move.lines:
if mline.account.id == inv.account.id and not mline.reconciliation:
lines_ids.append(mline.id)
@classmethod
def set_booking_payments(cls, invoice):
lines_ids = []
booking = None
for line in invoice.lines:
if line.origin and line.origin.__name__ == 'hotel.folio':
folio = line.origin
booking = folio.booking
cls._add_payment(invoice, folio, lines_ids)
if booking:
cls._add_payment(invoice, booking, lines_ids)
if lines_ids:
cls.write([invoice], {'payment_lines': [('add', lines_ids)]})
@classmethod
def set_advances_from_origin(cls, invoice):
vouchers = []
for line in invoice.lines:
if line.origin and line.origin.__name__ == 'hotel.booking':
booking = line.origin
if booking.vouchers:
for voucher in booking.vouchers:
if invoice.party.id == voucher.party.id:
vouchers.append(voucher)
# FIXME must pass lines of move
if vouchers:
invoice.create_move_advance(set(vouchers))
class InvoiceLine(metaclass=PoolMeta):
__name__ = 'account.invoice.line'
offset_move_line = fields.Many2One('account.move.line', 'Offset Move Line')
@classmethod
def _get_origin(cls):
return super(InvoiceLine, cls)._get_origin() + [
'hotel.booking', 'hotel.folio'
]
def get_move_lines(self):
Config = Pool().get('hotel.configuration')
config = Config.get_configuration()
lines = super().get_move_lines()
if config.accounting_revenue == 'recognise_revenue':
for line in lines:
line.account = config.recognise_account.id
return lines