mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[ADD] Add report folio
This commit is contained in:
@@ -856,3 +856,32 @@ class HotelFolio(models.Model):
|
||||
info_grouped.append(vals)
|
||||
return sorted(sorted(info_grouped,key=lambda k: k['num'], reverse=True),
|
||||
key=lambda k: k['room_type']['id'])
|
||||
|
||||
@api.multi
|
||||
def _get_tax_amount_by_group(self):
|
||||
self.ensure_one()
|
||||
res = {}
|
||||
for line in self.room_lines:
|
||||
price_reduce = line.price_total
|
||||
product = line.room_type_id.product_id
|
||||
taxes = line.tax_ids.compute_all(price_reduce, quantity=1, product=product)['taxes']
|
||||
for tax in line.tax_ids:
|
||||
group = tax.tax_group_id
|
||||
res.setdefault(group, {'amount': 0.0, 'base': 0.0})
|
||||
for t in taxes:
|
||||
if t['id'] == tax.id or t['id'] in tax.children_tax_ids.ids:
|
||||
res[group]['amount'] += t['amount']
|
||||
res[group]['base'] += t['base']
|
||||
for line in self.service_ids:
|
||||
price_reduce = line.price_unit * (1.0 - line.discount / 100.0)
|
||||
taxes = line.tax_ids.compute_all(price_reduce, quantity=line.product_qty, product=line.product_id)['taxes']
|
||||
for tax in line.tax_ids:
|
||||
group = tax.tax_group_id
|
||||
res.setdefault(group, {'amount': 0.0, 'base': 0.0})
|
||||
for t in taxes:
|
||||
if t['id'] == tax.id or t['id'] in tax.children_tax_ids.ids:
|
||||
res[group]['amount'] += t['amount']
|
||||
res[group]['base'] += t['base']
|
||||
res = sorted(res.items(), key=lambda l: l[0].sequence)
|
||||
res = [(l[0].name, l[1]['amount'], l[1]['base'], len(res)) for l in res]
|
||||
return res
|
||||
|
||||
@@ -295,6 +295,7 @@ class HotelReservation(models.Model):
|
||||
has_checkout_to_send = fields.Boolean(
|
||||
related='folio_id.has_checkout_to_send',
|
||||
readonly=True)
|
||||
to_print = fields.Boolean('Print', help='Print in Folio Report', default=True)
|
||||
# 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)
|
||||
@@ -302,10 +303,11 @@ class HotelReservation(models.Model):
|
||||
related='pricelist_id.currency_id',
|
||||
string='Currency', readonly=True, required=True)
|
||||
invoice_status = fields.Selection([
|
||||
('invoiced', 'Fully Invoiced'),
|
||||
('to invoice', 'To Invoice'),
|
||||
('no', 'Nothing to Invoice')
|
||||
], string='Invoice Status', compute='_compute_invoice_status', store=True, readonly=True, default='no')
|
||||
('invoiced', 'Fully Invoiced'),
|
||||
('to invoice', 'To Invoice'),
|
||||
('no', 'Nothing to Invoice')
|
||||
], string='Invoice Status', compute='_compute_invoice_status',
|
||||
store=True, readonly=True, default='no')
|
||||
tax_ids = fields.Many2many('account.tax',
|
||||
string='Taxes',
|
||||
domain=['|', ('active', '=', False), ('active', '=', True)])
|
||||
@@ -741,7 +743,7 @@ class HotelReservation(models.Model):
|
||||
def onchange_room_availabiltiy_domain(self):
|
||||
self.ensure_one()
|
||||
if self.checkin and self.checkout:
|
||||
if self.overbooking or self.reselling or self.state in ('cancelled'):
|
||||
if self.overbooking or self.reselling:
|
||||
return
|
||||
occupied = self.env['hotel.reservation'].get_reservations(
|
||||
self.checkin,
|
||||
@@ -1094,7 +1096,7 @@ class HotelReservation(models.Model):
|
||||
@api.model
|
||||
def _get_domain_reservations_occupation(self, dfrom, dto):
|
||||
#WARNING If add or remove domain items, update _hcalendar_get_count_reservations_json_data
|
||||
# in calendar module hotel_calendar_management.py
|
||||
# in calendar module hotel_calendar
|
||||
domain = [('reservation_line_ids.date', '>=', dfrom),
|
||||
('reservation_line_ids.date', '<=', dto),
|
||||
('state', '!=', 'cancelled'),
|
||||
@@ -1141,9 +1143,7 @@ class HotelReservation(models.Model):
|
||||
if fields.Date.from_string(self.checkin) >= fields.Date.from_string(self.checkout):
|
||||
raise ValidationError(_('Room line Check In Date Should be \
|
||||
less than the Check Out Date!'))
|
||||
if not self.overbooking \
|
||||
and self.state not in ('cancelled') \
|
||||
and not self._context.get("ignore_avail_restrictions", False):
|
||||
if not self.overbooking and not self._context.get("ignore_avail_restrictions", False):
|
||||
occupied = self.env['hotel.reservation'].get_reservations(
|
||||
self.checkin,
|
||||
(fields.Date.from_string(self.checkout) - timedelta(days=1)).
|
||||
|
||||
@@ -127,6 +127,7 @@ class HotelService(models.Model):
|
||||
product_qty = fields.Integer('Quantity', default=1)
|
||||
days_qty = fields.Integer(compute="_compute_days_qty", store=True)
|
||||
is_board_service = fields.Boolean()
|
||||
to_print = fields.Boolean('Print', help='Print in Folio Report')
|
||||
# Non-stored related field to allow portal user to see the image of the product he has ordered
|
||||
product_image = fields.Binary('Product Image', related="product_id.image", store=False, related_sudo=True)
|
||||
company_id = fields.Many2one(related='folio_id.company_id', string='Company', store=True, readonly=True)
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
<tr>
|
||||
<th>Description</th>
|
||||
<th class="text-right">Quantity</th>
|
||||
<th class="text-right">Unit Price</th>
|
||||
<th t-if="display_discount" class="text-right" groups="sale.group_discount_per_so_line">Disc.(%)</th>
|
||||
<th class="text-right">Taxes</th>
|
||||
<th class="text-right" groups="sale.group_show_price_subtotal">Amount</th>
|
||||
@@ -66,29 +65,52 @@
|
||||
<tbody class="sale_tbody">
|
||||
<!-- Lines associated -->
|
||||
<t t-foreach="doc.room_lines" t-as="l">
|
||||
<tr>
|
||||
<td><span t-field="l.name"/></td>
|
||||
<td class="text-right">
|
||||
<span t-field="l.nights"/>
|
||||
</td>
|
||||
<!--<td class="text-right">
|
||||
<span t-field="l.price_unit"/>
|
||||
</td>-->
|
||||
<td t-if="display_discount" class="text-right" groups="sale.group_discount_per_so_line">
|
||||
<span t-field="l.discount"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-esc="', '.join(map(lambda x: (x.description or x.name), l.tax_ids))"/>
|
||||
</td>
|
||||
<td class="text-right" groups="sale.group_show_price_subtotal">
|
||||
<span t-field="l.price_subtotal"
|
||||
t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/>
|
||||
</td>
|
||||
<td class="text-right" groups="sale.group_show_price_total">
|
||||
<span t-field="l.price_total"
|
||||
t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
<t t-if="l.to_print == True and l.price_total > 0">
|
||||
<tr>
|
||||
<td><span t-field="l.name"/></td>
|
||||
<td class="text-right">
|
||||
<span t-field="l.nights"/>
|
||||
</td>
|
||||
<td t-if="display_discount" class="text-right" groups="sale.group_discount_per_so_line">
|
||||
<span t-field="l.discount"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-esc="', '.join(map(lambda x: (x.description or x.name), l.tax_ids))"/>
|
||||
</td>
|
||||
<td class="text-right" groups="sale.group_show_price_subtotal">
|
||||
<span t-field="l.price_subtotal"
|
||||
t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/>
|
||||
</td>
|
||||
<td class="text-right" groups="sale.group_show_price_total">
|
||||
<span t-field="l.price_total"
|
||||
t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</t>
|
||||
<t t-foreach="doc.service_ids" t-as="l">
|
||||
<t t-if="l.to_print == True and l.price_total > 0">
|
||||
<tr>
|
||||
<td><span t-field="l.name"/></td>
|
||||
<td class="text-right">
|
||||
<span t-field="l.product_qty"/>
|
||||
</td>
|
||||
<td t-if="display_discount" class="text-right" groups="sale.group_discount_per_so_line">
|
||||
<span t-field="l.discount"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-esc="', '.join(map(lambda x: (x.description or x.name), l.tax_ids))"/>
|
||||
</td>
|
||||
<td class="text-right" groups="sale.group_show_price_subtotal">
|
||||
<span t-field="l.price_subtotal"
|
||||
t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/>
|
||||
</td>
|
||||
<td class="text-right" groups="sale.group_show_price_total">
|
||||
<span t-field="l.price_total"
|
||||
t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -104,7 +126,7 @@
|
||||
t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
<!--<t t-foreach="doc._get_tax_amount_by_group()" t-as="amount_by_group">
|
||||
-<t t-foreach="doc._get_tax_amount_by_group()" t-as="amount_by_group">
|
||||
<tr style="border-bottom:1px solid #dddddd;">
|
||||
<t t-if="amount_by_group[3] == 1 and doc.amount_untaxed == amount_by_group[2]">
|
||||
<td>
|
||||
@@ -126,7 +148,7 @@
|
||||
</td>
|
||||
</t>
|
||||
</tr>
|
||||
</t>-->
|
||||
</t>
|
||||
<tr class="border-black">
|
||||
<td><strong>Total</strong></td>
|
||||
<td class="text-right">
|
||||
@@ -134,10 +156,60 @@
|
||||
t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-black">
|
||||
<td><strong>Pending Payment</strong></td>
|
||||
<td class="text-right">
|
||||
<span t-field="doc.pending_amount"
|
||||
t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span t-if="doc.payment_ids">
|
||||
<table style="width:80%;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Payment Ref.</th>
|
||||
<th>Payment Date</th>
|
||||
<th>Payment Method</th>
|
||||
<th>Paid Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="doc.payment_ids" t-as="l">
|
||||
<td t-esc="l.name" />
|
||||
<td t-esc="l.payment_date" />
|
||||
<td t-esc="l.journal_id.name" />
|
||||
<td t-esc="l.amount" />
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</span>
|
||||
<span t-if="doc.return_ids">
|
||||
<table style="width:80%;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Return Ref.</th>
|
||||
<th>Return Date</th>
|
||||
<th>Return Method</th>
|
||||
<th>Return Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="doc.return_ids" t-as="r">
|
||||
<td t-esc="r.name" />
|
||||
<td t-esc="r.date" />
|
||||
<td t-esc="r.journal_id.name" />
|
||||
<t t-set="total_amount" t-value="sum(l.amount for l in r.line_ids)"/>
|
||||
<td t-esc="total_amount" />
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p t-field="doc.note" />
|
||||
<p t-if="doc.payment_term_id.note">
|
||||
|
||||
@@ -437,6 +437,7 @@
|
||||
decoration-warning="overbooking">
|
||||
<field name="splitted" invisible="1" />
|
||||
<field name="pricelist_id" invisible="1" />
|
||||
<field name="to_print" invisible="1"/>
|
||||
<button icon="fa fa-1x fa-chain-broken"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
@@ -505,6 +506,9 @@
|
||||
<attribute name="delete">false</attribute>
|
||||
<attribute name="string">Rooms</attribute>
|
||||
</tree>
|
||||
<xpath expr="//field[@name='to_print']" position="attributes">
|
||||
<attribute name="invisible">0</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='state']" position="before">
|
||||
<button type="object" class="oe_stat_button"
|
||||
icon="fa fa-2x fa-suitcase"
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
<tree string="Services" editable="bottom"
|
||||
decoration-success="is_board_service == True">
|
||||
<field name="is_board_service" invisible="1" />
|
||||
<field name="to_print" />
|
||||
<button type="object" class="oe_stat_button"
|
||||
icon="fa fa-1x fa-bed"
|
||||
name="open_service_lines"
|
||||
|
||||
Reference in New Issue
Block a user