Compare commits

...

3 Commits

Author SHA1 Message Date
oscar alvarez a7000eb130 Fix 2023-11-02 22:16:41 -05:00
oscar alvarez ee661d56a3 Add season to price list 2023-11-02 18:13:29 -05:00
oscar alvarez 05a7d332f9 Fix add reconcile booking from invoice 2023-11-02 17:49:55 -05:00
9 changed files with 158 additions and 35 deletions

View File

@ -28,8 +28,7 @@ Al igual que en las OTAS en Tryton Hotel las tarifas son una combinación de pre
• Max antelación
• No OTA
Debe permitir realizar los cambios precios y restricciones por día o periodo o temporada en cada
tarifa existente.
Debe permitir realizar los cambios precios y restricciones por día o periodo o temporada en cada tarifa existente.
Una tarifa (creada por precios y restricciones) está asociada a condiciones y políticas, como:

View File

@ -163,5 +163,6 @@ def register():
sale.SaleTransfer,
party.CreateGuest,
operation.NightAuditWizard,
invoice.InvoiceReconcileBooking,
siat.SiatSyncWizard,
module='hotel', type_='wizard')

View File

@ -364,6 +364,7 @@ class Folio(ModelSQL, ModelView):
'main_guest.address',
'main_guest.addresses',
'room.code',
'room.name',
'product.template.name',
'registration_state',
'arrival_date',

View File

@ -4,6 +4,8 @@ from datetime import date
from trytond.pool import PoolMeta, Pool
from trytond.model import fields
from trytond.wizard import StateTransition, Wizard
from trytond.transaction import Transaction
class Invoice(metaclass=PoolMeta):
@ -100,14 +102,6 @@ class Invoice(metaclass=PoolMeta):
if invoice.amount_to_pay == 0 and to_reconcile:
MoveLine.reconcile(to_reconcile)
@classmethod
def do_move_writeoff_advance(cls, invoices):
# Asiento de cancelacion de los anticipos en la reserva
# Para abono de pago en factura
Config = Pool().get('hotel.configuration')
config = Config.get_configuration()
pass
@classmethod
def _post(cls, invoices):
for invoice in invoices:
@ -131,30 +125,106 @@ class Invoice(metaclass=PoolMeta):
invoice.auto_reconcile()
@classmethod
def _add_payment(cls, inv, record, lines_ids):
def set_booking_payments(cls, invoice):
Config = Pool().get('hotel.configuration')
config = Config.get_configuration()
acc_advance = config.advance_account
booking = None
payments = []
lines_paid = []
for line in invoice.lines:
if line.origin and line.origin.__name__ == 'hotel.folio':
folio = line.origin
booking = folio.booking
payments.append(folio.payments)
if booking:
payments.append(booking.payments)
lines_paid = []
lines_advance = []
for rec in payments:
lines_paid.extend(cls.set_payments_lines(invoice, rec))
lines_advance.extend(
cls.set_payments_lines(invoice, rec, acc_advance))
if lines_paid or lines_advance:
if acc_advance and lines_advance:
lines_paid.extend(
cls.do_move_writeoff_advance(
lines_advance, acc_advance, invoice))
if lines_paid:
lines_paid = [li.id for li in lines_paid]
cls.write([invoice], {'payment_lines': [('add', lines_paid)]})
@classmethod
def set_payments_lines(cls, inv, payments, account=None):
lines_paid = []
balance = 0
for as_line in record.payments:
account_id = account.id if account else inv.account.id
for as_line in 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)
if mline.account.id == account_id and not mline.reconciliation:
lines_paid.append(mline)
return lines_paid
@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)]})
def do_move_writeoff_advance(cls, lines, account, inv):
# Asiento de cancelacion de los anticipos en la reserva
# conciliacion de los anticipos y abono de los pagos en factura
pool = Pool()
Move = pool.get('account.move')
MoveLine = pool.get('account.move.line')
Period = pool.get('account.period')
Journal = pool.get('account.journal')
Reconciliation = pool.get('account.move.reconciliation')
journal, = Journal.search_read([
('type', '=', 'write-off')
], limit=1)
period_id = Period.find(inv.company.id, date=inv.invoice_date)
move, = Move.create([{
'journal': journal['id'],
'period': period_id,
'date': inv.invoice_date,
# 'origin': str(self),
'state': 'draft',
'description': inv.description,
}])
amount = 0
to_debit = []
advance_lines = []
for line in lines:
advance_lines.append(line.id)
amount += line.credit
to_debit.append({
'description': inv.reference,
'party': inv.party.id,
'account': account.id,
'debit': line.credit,
'credit': 0,
'move': move.id,
})
to_credit = [{
'description': inv.description,
'party': inv.party.id,
'account': inv.account.id,
'debit': 0,
'credit': amount,
'move': move.id,
}]
debit_lines = MoveLine.create(to_debit)
lines_ids = MoveLine.create(to_credit)
Reconciliation.create([{
'lines': [('add', debit_lines + advance_lines)],
'date': date.today(),
}])
Move.post([move])
return lines_ids
@classmethod
def set_advances_from_origin(cls, invoice):
@ -170,6 +240,13 @@ class Invoice(metaclass=PoolMeta):
if vouchers:
invoice.create_move_advance(set(vouchers))
@classmethod
def concile_booking_invoice(cls, record):
if record.state != 'posted':
return
cls.set_booking_payments(record)
record.auto_reconcile()
class InvoiceLine(metaclass=PoolMeta):
__name__ = 'account.invoice.line'
@ -189,3 +266,22 @@ class InvoiceLine(metaclass=PoolMeta):
for line in lines:
line.account = config.recognise_account.id
return lines
class InvoiceReconcileBooking(Wizard):
'Invoice Reconcile Booking'
__name__ = 'hotel.invoice_reconcile_booking'
start_state = 'reconcile_'
reconcile_ = StateTransition()
def transition_reconcile_(self):
Invoice = Pool().get('account.invoice')
invoice_ids = Transaction().context['active_ids']
if not invoice_ids:
return 'end'
invoices = Invoice.browse(invoice_ids)
for inv in invoices:
Invoice.concile_booking_invoice(inv)
return 'end'

16
invoice.xml Normal file
View File

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<tryton>
<data>
<record model="ir.action.wizard" id="act_invoice_reconcile_booking">
<field name="name">Reconcile with Booking</field>
<field name="wiz_name">hotel.invoice_reconcile_booking</field>
</record>
<record model="ir.action.keyword" id="act_invoice_reconcile_draft_keyword">
<field name="keyword">form_action</field>
<field name="model">account.invoice,-1</field>
<field name="action" ref="act_invoice_reconcile_booking"/>
</record>
</data>
</tryton>

View File

@ -24,3 +24,8 @@ class Template(metaclass=PoolMeta):
class PriceList(metaclass=PoolMeta):
__name__ = 'product.price_list'
breakfast_included = fields.Boolean('Breakfast Included')
season = fields.Selection([
('high', 'High'),
('low', 'Low'),
('middle', 'Middle'),
], 'Season')

View File

@ -1,5 +1,5 @@
[tryton]
version=6.0.119
version=6.0.120
depends:
party
company
@ -43,4 +43,5 @@ xml:
analytic.xml
rate_plan.xml
housekeeping.xml
invoice.xml
siat.xml

View File

@ -28,8 +28,6 @@ this repository contains the full copyright notices and license terms. -->
<field name="storage_by_default"/>
<label name="payment_term"/>
<field name="payment_term"/>
<label name="offset_journal"/>
<field name="offset_journal"/>
<label name="booking_email"/>
<field name="booking_email"/>
<label name="check_in_email"/>
@ -38,16 +36,20 @@ this repository contains the full copyright notices and license terms. -->
<field name="payments_email"/>
<label name="customer_experience_email"/>
<field name="customer_experience_email"/>
<label name="accounting_revenue"/>
<field name="accounting_revenue"/>
<label name="recognise_account"/>
<field name="recognise_account"/>
<label name="advance_account"/>
<field name="advance_account"/>
<label name="space_booking"/>
<field name="space_booking"/>
<label name="charge_sequence"/>
<field name="charge_sequence"/>
<label name="offset_journal"/>
<field name="offset_journal"/>
<group col="6" string="Accounting" id="account" colspan="4">
<label name="accounting_revenue"/>
<field name="accounting_revenue"/>
<label name="recognise_account"/>
<field name="recognise_account"/>
<label name="advance_account"/>
<field name="advance_account"/>
</group>
<field name="default_charges" colspan="2"/>
<field name="children_policies" colspan="2"/>
<label name="token_siat"/>

View File

@ -5,5 +5,7 @@ this repository contains the full copyright notices and license terms. -->
<xpath expr="/form/field[@name='unit']" position="after">
<label name="breakfast_included"/>
<field name="breakfast_included"/>
<label name="season"/>
<field name="season"/>
</xpath>
</data>