[WIP] Invoice WorkFlow

This commit is contained in:
Dario Lodeiros
2019-01-18 17:37:43 +01:00
parent c5d3f7facc
commit 9e1bf442b3
6 changed files with 72 additions and 56 deletions

View File

@@ -228,7 +228,6 @@ class HotelFolio(models.Model):
'Prepaid Warning Days',
help='Margin in days to create a notice if a payment \
advance has not been recorded')
rooms_char = fields.Char('Rooms', compute='_computed_rooms_char')
segmentation_ids = fields.Many2many('res.partner.category',
string='Segmentation')
client_order_ref = fields.Char(string='Customer Reference', copy=False)
@@ -253,10 +252,6 @@ class HotelFolio(models.Model):
'amount_total': amount_untaxed + amount_tax,
})
def _computed_rooms_char(self):
for record in self:
record.rooms_char = ', '.join(record.mapped('room_lines.room_id.name'))
@api.depends('amount_total', 'payment_ids', 'return_ids')
@api.multi
def compute_amount(self):

View File

@@ -4,11 +4,21 @@
from odoo import models, fields, api, _
from odoo.addons import decimal_precision as dp
from odoo.exceptions import ValidationError
from datetime import date
class HotelReservationLine(models.Model):
_name = "hotel.reservation.line"
_order = "date"
@api.multi
def name_get(self):
result = []
for res in self:
date = fields.Date.from_string(res.date)
name = u'%s/%s' % (date.day, date.month)
result.append((res.id, name))
return result
reservation_id = fields.Many2one('hotel.reservation', string='Reservation',
ondelete='cascade', required=True,
copy=False)

View File

@@ -201,6 +201,7 @@
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="activity_ids" widget="mail_activity"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
@@ -219,7 +220,7 @@
<field name="name"/>
<field name="partner_id" select="1"/>
<field name="date_order" select="1"/>
<field name="rooms_char" string="Rooms"/>
<field name="room_lines" widget="many2many_tags" />
<field name="amount_total" sum="Total amount"/>
</tree>
</field>

View File

@@ -195,10 +195,13 @@
<!-- TODO: How to filter to avoid show False (generic) pricelist board when exist a specific pricelist board¿? -->
<field name="board_service_room_id" domain="[
('hotel_room_type_id', '=', room_type_id),
('pricelist_id', 'in', [pricelist_id, False])]" />
('pricelist_id', 'in', [pricelist_id, False])]"
options="{'no_create': True,'no_open': True}" />
<field name="name"/>
<field name="adults"/>
<field name="children"/>
<field name="qty_invoiced" />
<field name="qty_to_invoice" />
<field name="room_type_id" on_change="1" options="{'no_create': True,'no_open': True}"
attrs="{'readonly':[('state','not in',('draft'))]}"/>
<field name="channel_type" attrs="{'required':[('reservation_type','not in',('staff','out'))]}"/>
@@ -259,7 +262,7 @@
attrs = "{'required': [('per_day','=',True)]}" />
<field name="product_id"
domain="[('sale_ok', '=', True)]"
options="{'create': False, 'create_edit': False}" />
options="{'no_create': True,'no_open': True}" />
<field name="name"/>
<field name="product_qty" attrs="{'readonly': [('per_day','=',True)]}" force_save="1"/>
<button type="object" class="oe_stat_button"
@@ -308,6 +311,7 @@
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers"/>
<field name="activity_ids" widget="mail_activity"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>

View File

@@ -61,6 +61,7 @@ class FolioAdvancePaymentInv(models.TransientModel):
advance_payment_method = fields.Selection([
('all', 'Invoiceable lines (deduct down payments)'),
('one', 'One line (Bill all in one line)'),
('percentage', 'Down payment (percentage)'),
('fixed', 'Down payment (fixed amount)')
], string='What do you want to invoice?', default=_get_advance_payment_method,
@@ -80,7 +81,6 @@ class FolioAdvancePaymentInv(models.TransientModel):
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="Product",
domain=[('type', '=', 'service')], default=_default_product_id)
@@ -185,6 +185,9 @@ class FolioAdvancePaymentInv(models.TransientModel):
invoice = inv_obj.create(inv_data)
for line in self.line_ids:
line.invoice_line_create(invoice.id, line.qty)
elif self.advance_payment_method == 'all':
pass
#Group lines by tax_ids
else:
# Create deposit product if necessary
if not self.product_id:
@@ -281,51 +284,30 @@ class FolioAdvancePaymentInv(models.TransientModel):
for service in services:
extra_price += service.price_unit * \
service.service_line_ids.filtered(
lambda x: x.date == day.date).day_qty
lambda x: x.date == day.date).day_qty
#group_key: if group by reservation, We no need group by room_type
group_key = (reservation.id, reservation.room_type_id.id, day.price + extra_price, day.discount)
date = fields.Date.from_string(day.date)
if group_key in invoice_lines:
invoice_lines[group_key][('qty')] += 1
if date == fields.Date.from_string(
invoice_lines[group_key][('date_to')]) + timedelta(days=1):
desc = invoice_lines[group_key][('description')]
invoice_lines[group_key][('description')] = \
desc.replace(desc[desc.rfind(" - "):], ' - ' + \
(date + timedelta(days=1)).strftime(DEFAULT_SERVER_DATE_FORMAT) + ')')
else:
invoice_lines[group_key][('description')] += \
' (' + date.strftime(DEFAULT_SERVER_DATE_FORMAT) + \
' - ' + (date + timedelta(days=1)).strftime(
DEFAULT_SERVER_DATE_FORMAT) + \
')'
invoice_lines[group_key][('date_to')] = day.date
else:
room_type_description = folio.name + ' ' + reservation.room_type_id.name + ' (' + \
reservation.board_service_room_id.hotel_board_service_id.name + ')' \
if board_service else folio.name + ' ' + reservation.room_type_id.name
description = room_type_description + \
': (' + date.strftime(DEFAULT_SERVER_DATE_FORMAT) + \
' - ' + (date + timedelta(days=1)).strftime(DEFAULT_SERVER_DATE_FORMAT) + \
')'
invoice_lines[group_key] = {
'description' : description,
'reservation_id': reservation.id,
'room_type_id': reservation.room_type_id,
'product_id': self.env['product.product'].browse(
reservation.room_type_id.product_id.id
),
'qty': 1,
'discount': day.discount,
'price_unit': day.price + extra_price,
'date_to': day.date,
'reservation_line_ids': []
description = folio.name + ' ' + reservation.room_type_id.name + ' (' + \
reservation.board_service_room_id.hotel_board_service_id.name + ')' \
if board_service else folio.name + ' ' + reservation.room_type_id.name
invoice_lines[group_key] = {
'description' : description,
'reservation_id': reservation.id,
'room_type_id': reservation.room_type_id,
'product_id': self.env['product.product'].browse(
reservation.room_type_id.product_id.id),
'discount': day.discount,
'price_unit': day.price + extra_price,
'reservation_line_ids': []
}
invoice_lines[group_key][('reservation_line_ids')].append((4,day.id))
for group_key in invoice_lines:
vals.append((0, False, invoice_lines[group_key]))
self.line_ids = vals
self.line_ids.onchange_reservation_line_ids()
@api.onchange('view_detail', 'folio_ids')
@api.onchange('folio_ids')
def onchange_folio_ids(self):
vals = []
folios = self.folio_ids
@@ -388,11 +370,13 @@ class LineAdvancePaymentInv(models.TransientModel):
qty = fields.Integer('Quantity')
price_unit = fields.Float('Price')
advance_inv_id = fields.Many2one('folio.advance.payment.inv')
price_room = fields.Float(compute='_compute_price_room')
discount = fields.Float(
string='Discount (%)',
digits=dp.get_precision('Discount'), default=0.0)
to_invoice = fields.Boolean('To Invoice')
description = fields.Text('Description')
description_dates = fields.Text('Range')
reservation_id = fields.Many2one('hotel.reservation')
service_id = fields.Many2one('hotel.service')
folio_id = fields.Many2one('hotel.folio', compute='_compute_folio_id')
@@ -400,10 +384,25 @@ class LineAdvancePaymentInv(models.TransientModel):
'hotel.reservation.line',
string='Reservation Lines')
def _compute_price_room(self):
for record in self:
record.price_room = self.reservation_line_ids[0].price
def _compute_folio_id(self):
for record in self:
origin = record.reservation_id if record.reservation_id.id else record.service_id
record.folio_id = origin.folio_id
@api.onchange('reservation_line_ids')
def onchange_reservation_line_ids(self):
for record in self:
if record.reservation_id:
if not record.reservation_line_ids:
raise UserError(_('If you want drop the line, use the trash icon'))
record.qty = len(record.reservation_line_ids)
record.description_dates = record.reservation_line_ids[0].date + ' - ' + \
((fields.Date.from_string(record.reservation_line_ids[-1].date)) + \
timedelta(days=1)).strftime(DEFAULT_SERVER_DATE_FORMAT)
@api.multi
def invoice_line_create(self, invoice_id, qty):
@@ -446,6 +445,7 @@ class LineAdvancePaymentInv(models.TransientModel):
'reservation_ids': [(6, 0, [origin.id])],
'reservation_line_ids': [(6, 0, line.reservation_line_ids.ids)]
})
import wdb; wdb.set_trace()
elif line.service_id:
vals.update({
'invoice_id': invoice_id,

View File

@@ -27,6 +27,9 @@
domain="[('type_tax_use','=','sale')]"
attrs="{'invisible': ['|', ('advance_payment_method', 'not in', ('fixed', 'percentage')), ('product_id', '!=', False)]}"/>
</group>
<group>
<field name="group_folios" string="Add Folios"/>
</group>
<field name="folio_ids" attrs="{'invisible': [('group_folios', '=', False)]}">
<tree string="Folios" editable="bottom"
decoration-danger="partner_invoice_id != parent.partner_invoice_id">
@@ -41,18 +44,21 @@
domain="[('folio_id', 'in', folio_ids)]"/>
</group>
<group>
<field name="group_folios" />
<field name="view_detail" />
</group>
<group>
<field name="line_ids" attrs="{'invisible': [('view_detail', '=', False)]}"
nolabel="1">
<field name="line_ids">
<tree string="Lines" editable="bottom">
<field name="product_id" invisible="1"/>
<field name="reservation_line_ids" />
<field name="reservation_id" />
<field name="service_id" />
<field name="product_id" invisible="1" />
<field name="price_room" invisible="1" />
<field name="reservation_id"
options="{'no_create': True,'no_open': True}"/>
<field name="service_id"
options="{'no_create': True,'no_open': True}"/>
<field name="description" />
<field name="description_dates" readonly="1" />
<field name="reservation_line_ids"
widget="many2many_tags" string="Nights"
domain="[('reservation_id','=',reservation_id),
('price','=', price_room)]"
options="{'no_create': True,'no_open': True}"/>
<field name="qty" />
<field name="discount" />
<field name="price_unit" />