diff --git a/hotel/models/__init__.py b/hotel/models/__init__.py
index c68f79c5b..46cfdf7ff 100644
--- a/hotel/models/__init__.py
+++ b/hotel/models/__init__.py
@@ -31,3 +31,4 @@ from . import hotel_service_line
from . import hotel_board_service
from . import hotel_board_service_room_type_line
from . import hotel_board_service_line
+from . import inherited_account_invoice_line
diff --git a/hotel/models/hotel_folio.py b/hotel/models/hotel_folio.py
index 656aab0bb..23cf212a1 100644
--- a/hotel/models/hotel_folio.py
+++ b/hotel/models/hotel_folio.py
@@ -11,6 +11,8 @@ from dateutil.relativedelta import relativedelta
from odoo.exceptions import except_orm, UserError, ValidationError
from odoo.tools import (
misc,
+ float_is_zero,
+ float_compare,
DEFAULT_SERVER_DATETIME_FORMAT,
DEFAULT_SERVER_DATE_FORMAT)
from odoo import models, fields, api, _
@@ -44,9 +46,14 @@ class HotelFolio(models.Model):
def _amount_all(self):
pass
+ @api.model
+ def _get_default_team(self):
+ return self.env['crm.team']._get_default_team_id()
+
#Main Fields--------------------------------------------------------
name = fields.Char('Folio Number', readonly=True, index=True,
default=lambda self: _('New'))
+ client_order_ref = fields.Char(string='Customer Reference', copy=False)
partner_id = fields.Many2one('res.partner',
track_visibility='onchange')
@@ -87,6 +94,7 @@ class HotelFolio(models.Model):
required=True, readonly=True, index=True,
states={'draft': [('readonly', False)], 'sent': [('readonly', False)]},
copy=False, default=fields.Datetime.now)
+ confirmation_date = fields.Datetime(string='Confirmation Date', readonly=True, index=True, help="Date on which the folio is confirmed.", copy=False)
state = fields.Selection([
('draft', 'Quotation'),
('sent', 'Quotation Sent'),
@@ -111,6 +119,7 @@ class HotelFolio(models.Model):
readonly=True)
return_ids = fields.One2many('payment.return', 'folio_id',
readonly=True)
+ payment_term_id = fields.Many2one('account.payment.term', string='Payment Terms', oldname='payment_term')
#Amount Fields------------------------------------------------------
pending_amount = fields.Monetary(compute='compute_amount',
@@ -150,12 +159,13 @@ class HotelFolio(models.Model):
string='Invoice Status',
compute='_compute_invoice_status',
store=True, readonly=True, default='no')
- #~ partner_invoice_id = fields.Many2one('res.partner',
- #~ string='Invoice Address',
- #~ readonly=True, required=True,
- #~ states={'draft': [('readonly', False)],
- #~ 'sent': [('readonly', False)]},
- #~ help="Invoice address for current sales order.")
+ partner_invoice_id = fields.Many2one('res.partner',
+ string='Invoice Address',
+ readonly=True, required=True,
+ states={'draft': [('readonly', False)],
+ 'sent': [('readonly', False)]},
+ help="Invoice address for current sales order.")
+ fiscal_position_id = fields.Many2one('account.fiscal.position', oldname='fiscal_position', string='Fiscal Position')
#WorkFlow Mail Fields-----------------------------------------------
has_confirmed_reservations_to_send = fields.Boolean(
@@ -179,6 +189,7 @@ class HotelFolio(models.Model):
client_order_ref = fields.Char(string='Customer Reference', copy=False)
note = fields.Text('Terms and conditions')
sequence = fields.Integer(string='Sequence', default=10)
+ team_id = fields.Many2one('crm.team', 'Sales Channel', change_default=True, default=_get_default_team, oldname='section_id')
@api.depends('room_lines.price_total','service_ids.price_total')
def _amount_all(self):
@@ -356,7 +367,7 @@ class HotelFolio(models.Model):
if any(f not in vals for f in lfields):
partner = self.env['res.partner'].browse(vals.get('partner_id'))
addr = partner.address_get(['delivery', 'invoice'])
- #~ vals['partner_invoice_id'] = vals.setdefault('partner_invoice_id', addr['invoice'])
+ vals['partner_invoice_id'] = vals.setdefault('partner_invoice_id', addr['invoice'])
vals['pricelist_id'] = vals.setdefault(
'pricelist_id',
partner.property_product_pricelist and partner.property_product_pricelist.id)
@@ -373,11 +384,11 @@ class HotelFolio(models.Model):
- user_id
"""
if not self.partner_id:
- #~ self.update({
- #~ 'partner_invoice_id': False,
- #~ 'payment_term_id': False,
- #~ 'fiscal_position_id': False,
- #~ })
+ self.update({
+ 'partner_invoice_id': False,
+ 'payment_term_id': False,
+ 'fiscal_position_id': False,
+ })
return
addr = self.partner_id.address_get(['invoice'])
pricelist = self.partner_id.property_product_pricelist and \
@@ -438,6 +449,102 @@ class HotelFolio(models.Model):
def advance_invoice(self):
pass
+ @api.multi
+ def _prepare_invoice(self):
+ """
+ Prepare the dict of values to create the new invoice for a sales order. This method may be
+ overridden to implement custom invoice generation (making sure to call super() to establish
+ a clean extension chain).
+ """
+ self.ensure_one()
+ journal_id = self.env['account.invoice'].default_get(['journal_id'])['journal_id']
+ if not journal_id:
+ raise UserError(_('Please define an accounting sales journal for this company.'))
+ import wdb; wdb.set_trace()
+ invoice_vals = {
+ 'name': self.client_order_ref or '',
+ 'origin': self.name,
+ 'type': 'out_invoice',
+ 'account_id': self.partner_invoice_id.property_account_receivable_id.id,
+ 'partner_id': self.partner_invoice_id.id,
+ 'partner_shipping_id': self.partner_id.id,
+ 'journal_id': journal_id,
+ 'currency_id': self.pricelist_id.currency_id.id,
+ 'comment': self.note,
+ 'payment_term_id': self.payment_term_id.id,
+ 'fiscal_position_id': self.fiscal_position_id.id or self.partner_invoice_id.property_account_position_id.id,
+ 'company_id': self.company_id.id,
+ 'user_id': self.user_id and self.user_id.id,
+ 'team_id': self.team_id.id
+ }
+ return invoice_vals
+
+ @api.multi
+ def action_invoice_create(self, grouped=False):
+ """
+ Create the invoice associated to the Folio.
+ :param grouped: if True, invoices are grouped by Folio id. If False, invoices are grouped by
+ (partner_invoice_id, currency)
+ :returns: list of created invoices
+ """
+ inv_obj = self.env['account.invoice']
+ precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
+ invoices = {}
+ references = {}
+ invoices_origin = {}
+ invoices_name = {}
+
+ for folio in self:
+ group_key = folio.id if grouped else (folio.partner_invoice_id.id, folio.currency_id.id)
+ for line in folio.room_lines.sorted(key=lambda l: l.qty_to_invoice < 0):
+ if float_is_zero(line.qty_to_invoice, precision_digits=precision):
+ continue
+ if group_key not in invoices:
+ inv_data = folio._prepare_invoice()
+ invoice = inv_obj.create(inv_data)
+ references[invoice] = folio
+ invoices[group_key] = invoice
+ invoices_origin[group_key] = [invoice.origin]
+ invoices_name[group_key] = [invoice.name]
+ elif group_key in invoices:
+ if folio.name not in invoices_origin[group_key]:
+ invoices_origin[group_key].append(folio.name)
+ if folio.client_order_ref and folio.client_order_ref not in invoices_name[group_key]:
+ invoices_name[group_key].append(folio.client_order_ref)
+
+ if line.qty_to_invoice > 0:
+ line.invoice_line_create(invoices[group_key].id, line.nights)
+
+ if references.get(invoices.get(group_key)):
+ if folio not in references[invoices[group_key]]:
+ references[invoices[group_key]] |= folio
+
+ for group_key in invoices:
+ invoices[group_key].write({'name': ', '.join(invoices_name[group_key]),
+ 'origin': ', '.join(invoices_origin[group_key])})
+
+ if not invoices:
+ raise UserError(_('There is no invoiceable line.'))
+
+ for invoice in invoices.values():
+ if not invoice.invoice_line_ids:
+ raise UserError(_('There is no invoiceable line.'))
+ # If invoice is negative, do a refund invoice instead
+ if invoice.amount_untaxed < 0:
+ invoice.type = 'out_refund'
+ for line in invoice.invoice_line_ids:
+ line.quantity = -line.quantity
+ # Use additional field helper function (for account extensions)
+ for line in invoice.invoice_line_ids:
+ line._set_additional_fields(invoice)
+ # Necessary to force computation of taxes. In account_invoice, they are triggered
+ # by onchanges, which are not triggered when doing a create.
+ invoice.compute_taxes()
+ invoice.message_post_with_view('mail.message_origin_link',
+ values={'self': invoice, 'origin': references[invoice]},
+ subtype_id=self.env.ref('mail.mt_note').id)
+ return [inv.id for inv in invoices.values()]
+
'''
WORKFLOW STATE
'''
@@ -483,7 +590,21 @@ class HotelFolio(models.Model):
@api.multi
def action_confirm(self):
- _logger.info('action_confirm')
+ for folio in self.filtered(lambda folio: folio.partner_id not in folio.message_partner_ids):
+ folio.message_subscribe([folio.partner_id.id])
+ self.write({
+ 'state': 'confirm',
+ 'confirmation_date': fields.Datetime.now()
+ })
+ #~ if self.env.context.get('send_email'):
+ #~ self.force_quotation_send()
+
+ # create an analytic account if at least an expense product
+ #~ if any([expense_policy != 'no' for expense_policy in self.order_line.mapped('product_id.expense_policy')]):
+ #~ if not self.analytic_account_id:
+ #~ self._create_analytic_account()
+
+ return True
"""
diff --git a/hotel/models/hotel_reservation.py b/hotel/models/hotel_reservation.py
index 2a43ded84..0ad40862e 100644
--- a/hotel/models/hotel_reservation.py
+++ b/hotel/models/hotel_reservation.py
@@ -8,6 +8,8 @@ from lxml import etree
from odoo.exceptions import UserError, ValidationError
from odoo.tools import (
misc,
+ float_is_zero,
+ float_compare,
DEFAULT_SERVER_DATE_FORMAT,
DEFAULT_SERVER_DATETIME_FORMAT)
from odoo import models, fields, api, _
@@ -75,6 +77,7 @@ class HotelReservation(models.Model):
return folio.room_lines[0].departure_hour
else:
return default_departure_hour
+
@api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
@@ -115,6 +118,7 @@ class HotelReservation(models.Model):
).days
name = fields.Text('Reservation Description', required=True)
+ sequence = fields.Integer(string='Sequence', default=10)
room_id = fields.Many2one('hotel.room', string='Room')
@@ -230,8 +234,6 @@ class HotelReservation(models.Model):
# order_line = fields.One2many('sale.order.line', 'order_id', string='Order Lines', states={'cancel': [('readonly', True)], 'done': [('readonly', True)]}, copy=True, auto_join=True)
# product_id = fields.Many2one('product.product', related='order_line.product_id', string='Product')
# product_uom = fields.Many2one('product.uom', string='Unit of Measure', required=True)
- # product_uom_qty = fields.Float(string='Quantity', digits=dp.get_precision('Product Unit of Measure'), required=True, default=1.0)
-
currency_id = fields.Many2one('res.currency',
related='pricelist_id.currency_id',
string='Currency', readonly=True, required=True)
@@ -244,12 +246,13 @@ class HotelReservation(models.Model):
tax_id = fields.Many2many('account.tax',
string='Taxes',
domain=['|', ('active', '=', False), ('active', '=', True)])
- # qty_to_invoice = fields.Float(
- # string='To Invoice', store=True, readonly=True,
- # digits=dp.get_precision('Product Unit of Measure'))
- # qty_invoiced = fields.Float(
- # compute='_get_invoice_qty', string='Invoiced', store=True, readonly=True,
- # digits=dp.get_precision('Product Unit of Measure'))
+ qty_to_invoice = fields.Float(
+ compute='_get_to_invoice_qty', string='To Invoice', store=True, readonly=True,
+ digits=dp.get_precision('Product Unit of Measure'))
+ qty_invoiced = fields.Float(
+ compute='_get_invoice_qty', string='Invoiced', store=True, readonly=True,
+ digits=dp.get_precision('Product Unit of Measure'))
+ invoice_lines = fields.Many2many('account.invoice.line', 'sale_order_line_invoice_rel', 'order_line_id', 'invoice_line_id', string='Invoice Lines', copy=False)
# qty_delivered = fields.Float(string='Delivered', copy=False, digits=dp.get_precision('Product Unit of Measure'), default=0.0)
# qty_delivered_updateable = fields.Boolean(compute='_compute_qty_delivered_updateable', string='Can Edit Delivered', readonly=True, default=True)
price_subtotal = fields.Monetary(string='Subtotal',
@@ -275,7 +278,7 @@ class HotelReservation(models.Model):
# FIXME discount per night
discount = fields.Float(string='Discount (%)', digits=dp.get_precision('Discount'), default=0.0)
- # analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tags')
+ analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tags')
@api.model
def create(self, vals):
@@ -1124,3 +1127,91 @@ class HotelReservation(models.Model):
@api.multi
def send_cancel_mail(self):
return self.folio_id.send_cancel_mail()
+
+ """
+ INVOICING PROCESS
+ """
+ @api.depends('qty_invoiced', 'nights', 'folio_id.state')
+ def _get_to_invoice_qty(self):
+ """
+ Compute the quantity to invoice. If the invoice policy is order, the quantity to invoice is
+ calculated from the ordered quantity. Otherwise, the quantity delivered is used.
+ """
+ for line in self:
+ if line.folio_id.state in ['confirm', 'done']:
+ if line.room_type_id.product_id.invoice_policy == 'order':
+ line.qty_to_invoice = line.nights - line.qty_invoiced
+ else:
+ line.qty_to_invoice = line.qty_delivered - line.qty_invoiced
+ else:
+ line.qty_to_invoice = 0
+
+ @api.depends('invoice_lines.invoice_id.state', 'invoice_lines.quantity')
+ def _get_invoice_qty(self):
+ """
+ Compute the quantity invoiced. If case of a refund, the quantity invoiced is decreased. Note
+ that this is the case only if the refund is generated from the SO and that is intentional: if
+ a refund made would automatically decrease the invoiced quantity, then there is a risk of reinvoicing
+ it automatically, which may not be wanted at all. That's why the refund has to be created from the SO
+ """
+ for line in self:
+ qty_invoiced = 0.0
+ for invoice_line in line.invoice_lines:
+ if invoice_line.invoice_id.state != 'cancel':
+ if invoice_line.invoice_id.type == 'out_invoice':
+ qty_invoiced += invoice_line.uom_id._compute_quantity(invoice_line.quantity, line.product_uom)
+ elif invoice_line.invoice_id.type == 'out_refund':
+ qty_invoiced -= invoice_line.uom_id._compute_quantity(invoice_line.quantity, line.product_uom)
+ line.qty_invoiced = qty_invoiced
+
+ @api.multi
+ def _prepare_invoice_line(self, qty):
+ """
+ Prepare the dict of values to create the new invoice line for a reservation.
+
+ :param qty: float quantity to invoice
+ """
+ self.ensure_one()
+ res = {}
+ product = self.env['product.product'].browse(self.room_type_id.product_id.id)
+ account = product.property_account_income_id or product.categ_id.property_account_income_categ_id
+ if not account:
+ raise UserError(_('Please define income account for this product: "%s" (id:%d) - or for its category: "%s".') %
+ (product.name, product.id, product.categ_id.name))
+
+ fpos = self.folio_id.fiscal_position_id or self.folio_id.partner_id.property_account_position_id
+ if fpos:
+ account = fpos.map_account(account)
+
+ res = {
+ 'name': self.name,
+ 'sequence': self.sequence,
+ 'origin': self.folio_id.name,
+ 'account_id': account.id,
+ 'price_unit': self.price_unit,
+ 'quantity': qty,
+ 'discount': self.discount,
+ 'uom_id': self.product_uom.id,
+ 'product_id': product.id or False,
+ 'invoice_line_tax_ids': [(6, 0, self.tax_id.ids)],
+ 'account_analytic_id': self.folio_id.analytic_account_id.id,
+ 'analytic_tag_ids': [(6, 0, self.analytic_tag_ids.ids)],
+ }
+ return res
+
+ @api.multi
+ def invoice_line_create(self, invoice_id, qty):
+ """ Create an invoice line. The quantity to invoice can be positive (invoice) or negative (refund).
+ :param invoice_id: integer
+ :param qty: float quantity to invoice
+ :returns recordset of account.invoice.line created
+ """
+ invoice_lines = self.env['account.invoice.line']
+ precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
+ for line in self:
+ if not float_is_zero(qty, precision_digits=precision):
+ vals = line._prepare_invoice_line(qty=qty)
+ vals.update({'invoice_id': invoice_id, 'reservation_ids': [(6, 0, [line.id])]})
+ invoice_lines |= self.env['account.invoice.line'].create(vals)
+ return invoice_lines
+
diff --git a/hotel/models/hotel_reservation_line.py b/hotel/models/hotel_reservation_line.py
index bc87355af..c5120ff65 100644
--- a/hotel/models/hotel_reservation_line.py
+++ b/hotel/models/hotel_reservation_line.py
@@ -17,6 +17,8 @@ class HotelReservationLine(models.Model):
discount = fields.Float(
string='Discount (%)',
digits=dp.get_precision('Discount'), default=0.0)
+ invoiced = fields.Boolean('Invoiced')
+
@api.constrains('date')
def constrains_duplicated_date(self):
diff --git a/hotel/models/inherited_account_invoice.py b/hotel/models/inherited_account_invoice.py
index be8626210..e42f483f3 100644
--- a/hotel/models/inherited_account_invoice.py
+++ b/hotel/models/inherited_account_invoice.py
@@ -45,16 +45,17 @@ class AccountInvoice(models.Model):
@api.multi
def _compute_dif_customer_payment(self):
for inv in self:
- sales = inv.mapped('invoice_line_ids.sale_line_ids.order_id')
- folios = self.env['hotel.folio'].search([('order_id.id','in',sales.ids)])
- if folios:
- inv.from_folio = True
- inv.folio_ids = [(6, 0, folios.ids)]
- payments_obj = self.env['account.payment']
- payments = payments_obj.search([('folio_id','in',folios.ids)])
- for pay in payments:
- if pay.partner_id != inv.partner_id:
- inv.dif_customer_payment = True
+ return False
+ #~ sales = inv.mapped('invoice_line_ids.sale_line_ids.order_id')
+ #~ folios = self.env['hotel.folio'].search([('order_id.id','in',sales.ids)])
+ #~ if folios:
+ #~ inv.from_folio = True
+ #~ inv.folio_ids = [(6, 0, folios.ids)]
+ #~ payments_obj = self.env['account.payment']
+ #~ payments = payments_obj.search([('folio_id','in',folios.ids)])
+ #~ for pay in payments:
+ #~ if pay.partner_id != inv.partner_id:
+ #~ inv.dif_customer_payment = True
@api.multi
def action_invoice_open(self):
diff --git a/hotel/models/inherited_account_invoice_line.py b/hotel/models/inherited_account_invoice_line.py
new file mode 100644
index 000000000..cc3ca1328
--- /dev/null
+++ b/hotel/models/inherited_account_invoice_line.py
@@ -0,0 +1,13 @@
+# Copyright 2017 Alexandre Díaz
+# Copyright 2017 Dario Lodeiros
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
+from odoo import api, fields, models, _
+
+class AccountInvoiceLine(models.Model):
+ _inherit = 'account.invoice.line'
+
+ reservation_ids = fields.Many2many(
+ 'hotel.reservation',
+ 'reservation_line_invoice_rel',
+ 'invoice_line_id', 'reservation_id',
+ string='Reservations', readonly=True, copy=False)
diff --git a/hotel/views/hotel_folio_views.xml b/hotel/views/hotel_folio_views.xml
index 71d5cdc71..51a6df265 100644
--- a/hotel/views/hotel_folio_views.xml
+++ b/hotel/views/hotel_folio_views.xml
@@ -20,9 +20,9 @@
attrs="{'invisible': [('has_cancelled_reservations_to_send', '=', False)]}" class="oe_highlight"/> -->
-
+ attrs="{'invisible': [('state', '!=', 'confirm')]}"/>
+
+
diff --git a/hotel/wizard/folio_make_invoice_advance.py b/hotel/wizard/folio_make_invoice_advance.py
index 2797cf308..3159191e5 100644
--- a/hotel/wizard/folio_make_invoice_advance.py
+++ b/hotel/wizard/folio_make_invoice_advance.py
@@ -16,14 +16,7 @@ class FolioAdvancePaymentInv(models.TransientModel):
@api.model
def _get_advance_payment_method(self):
- if self._count() == 1:
- sale_obj = self.env['sale.order']
- folio_obj = self.env['hotel.folio']
- order = sale_obj.browse(folio_obj.mapped('order_id.id'))
- if all([line.product_id.invoice_policy == 'order' for line in order.order_line]) \
- or order.invoice_count:
- return 'all'
- return 'delivered'
+ return 'all'
@api.model
def _default_product_id(self):
@@ -40,15 +33,22 @@ class FolioAdvancePaymentInv(models.TransientModel):
return self._default_product_id().taxes_id
advance_payment_method = fields.Selection([
- ('delivered', 'Invoiceable lines'),
('all', 'Invoiceable lines (deduct down payments)'),
('percentage', 'Down payment (percentage)'),
('fixed', 'Down payment (fixed amount)')
], string='What do you want to invoice?', default=_get_advance_payment_method,
required=True)
+ count = fields.Integer(default=_count, string='# of Orders')
+ folio_ids = fields.Many2many("hotel.folio", string="Folios",
+ help="Folios grouped")
+ group_folios = fields.Boolean('Group Folios')
+ line_ids = fields.One2many('line.advance.inv',
+ 'advance_inv_id',
+ string="Invoice Lines")
+ view_detail = fields.Boolean('View Detail')
+ #Advance Payment
product_id = fields.Many2one('product.product', string='Down Payment Product',
domain=[('type', '=', 'service')], default=_default_product_id)
- count = fields.Integer(default=_count, string='# of Orders')
amount = fields.Float('Down Payment Amount',
digits=dp.get_precision('Account'),
help="The amount to be invoiced in advance, taxes excluded.")
@@ -139,12 +139,11 @@ class FolioAdvancePaymentInv(models.TransientModel):
@api.multi
def create_invoices(self):
folios = self.env['hotel.folio'].browse(self._context.get('active_ids', []))
- sale_orders = self.env['sale.order'].browse(folios.mapped('order_id.id'))
if self.advance_payment_method == 'delivered':
- sale_orders.action_invoice_create()
+ folios.action_invoice_create()
elif self.advance_payment_method == 'all':
- sale_orders.action_invoice_create(final=True)
+ folios.action_invoice_create()
else:
# Create deposit product if necessary
if not self.product_id:
@@ -196,3 +195,68 @@ class FolioAdvancePaymentInv(models.TransientModel):
'property_account_income_id': self.deposit_account_id.id,
'taxes_id': [(6, 0, self.deposit_taxes_id.ids)],
}
+
+ @api.onchange('view_detail')
+ def prepare_reservation_invoice_lines(self):
+ vals = []
+ folios = self.env['hotel.folio'].browse(self._context.get('active_ids', []))
+ for folio in folios:
+ folio_name = folio.name
+ for reservation in folio.room_lines:
+ reservation_name = reservation.name
+ unit_price = False
+ discount = False
+ qty = 0
+ for day in reservation.reservation_line_ids.sorted('date'):
+ if day.price == unit_price and day.discount == discount:
+ date_to = day.date
+ qty += 1
+ else:
+ if unit_price:
+ vals.append((0, False, {
+ 'date_from': date_from,
+ 'date_to': date_to,
+ 'room_type_id': reservation.room_type_id,
+ 'product_id': self.env['product.product'].browse(
+ reservation.room_type_id.product_id.id
+ ),
+ 'qty': qty,
+ 'discount': discount,
+ 'unit_price': unit_price
+ }))
+ qty = 1
+ unit_price = day.price
+ date_from = day.date
+ date_to = day.date
+ vals.append((0, False, {
+ 'date_from': date_from,
+ 'date_to': date_to,
+ 'room_type_id': reservation.room_type_id,
+ 'product_id': self.env['product.product'].browse(
+ reservation.room_type_id.product_id.id
+ ),
+ 'qty': qty,
+ 'discount': discount,
+ 'unit_price': unit_price
+ }))
+ self.line_ids = vals
+
+class LineAdvancePaymentInv(models.TransientModel):
+ _name = "line.advance.inv"
+ _description = "Lines Advance Invoice"
+
+ date_from = fields.Date('From')
+ date_to = fields.Date('To')
+ room_type_id = fields.Many2one('hotel.room.type')
+ product_id = fields.Many2one('product.product', string='Down Payment Product',
+ domain=[('type', '=', 'service')])
+ qty = fields.Integer('Quantity')
+ unit_price = fields.Float('Price')
+ advance_inv_id = fields.Many2one('folio.advance.payment.inv')
+ discount = fields.Float(
+ string='Discount (%)',
+ digits=dp.get_precision('Discount'), default=0.0)
+ to_invoice = fields.Boolean('To Invoice')
+
+
+
diff --git a/hotel/wizard/folio_make_invoice_advance_views.xml b/hotel/wizard/folio_make_invoice_advance_views.xml
index 110dfbde3..2e25aa5f4 100644
--- a/hotel/wizard/folio_make_invoice_advance_views.xml
+++ b/hotel/wizard/folio_make_invoice_advance_views.xml
@@ -28,8 +28,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+