[WIP] Calcule Price based in vals and onchange refactoring

This commit is contained in:
Dario Lodeiros
2018-08-30 15:38:32 +02:00
parent 0bbd3b6c92
commit fef843a57e
2 changed files with 62 additions and 76 deletions

View File

@@ -257,9 +257,9 @@ class HotelReservation(models.Model):
# digits=dp.get_precision('Product Unit of Measure')) # digits=dp.get_precision('Product Unit of Measure'))
# qty_delivered = fields.Float(string='Delivered', copy=False, digits=dp.get_precision('Product Unit of Measure'), default=0.0) # 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) # qty_delivered_updateable = fields.Boolean(compute='_compute_qty_delivered_updateable', string='Can Edit Delivered', readonly=True, default=True)
price_subtotal = fields.Monetary(string='Subtotal', readonly=True, store=True) price_subtotal = fields.Monetary(string='Subtotal', readonly=True, store=True, compute='_compute_amount_reservation')
price_total = fields.Monetary(string='Total', readonly=True, store=True) price_total = fields.Monetary(string='Total', readonly=True, store=True, compute='_compute_amount_reservation')
price_tax = fields.Float(string='Taxes', readonly=True, store=True) price_tax = fields.Float(string='Taxes', readonly=True, store=True, compute='_compute_amount_reservation')
currency_id = fields.Many2one(related='folio_id.currency_id', store=True, string='Currency', readonly=True) currency_id = fields.Many2one(related='folio_id.currency_id', store=True, string='Currency', readonly=True)
# FIXME discount per night # FIXME discount per night
discount = fields.Float(string='Discount (%)', digits=dp.get_precision('Discount'), default=0.0) discount = fields.Float(string='Discount (%)', digits=dp.get_precision('Discount'), default=0.0)
@@ -287,7 +287,7 @@ class HotelReservation(models.Model):
#~ 'reserve_color_text': colors[1], #~ 'reserve_color_text': colors[1],
}) })
if self.compute_price_out_vals(vals): if self.compute_price_out_vals(vals):
vals.update(self.env['hotel.reservation'].compute_amount_reservation(vals)) vals.update(self.env['hotel.reservation'].prepare_reservation_lines(vals))
record = super(HotelReservation, self).create(vals) record = super(HotelReservation, self).create(vals)
#~ if (record.state == 'draft' and record.folio_id.state == 'sale') or \ #~ if (record.state == 'draft' and record.folio_id.state == 'sale') or \
#~ record.preconfirm: #~ record.preconfirm:
@@ -296,17 +296,21 @@ class HotelReservation(models.Model):
@api.multi @api.multi
def write(self, vals): def write(self, vals):
#~ if self.notify_update(vals): if self.notify_update(vals):
#~ vals.update({ vals.update({
#~ 'last_updated_res': date_utils.now(hours=True).strftime(DEFAULT_SERVER_DATETIME_FORMAT) 'last_updated_res': date_utils.now(hours=True).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
#~ }) })
#~ for record in self: for record in self:
#~ if record.compute_price_out_vals(vals): if record.compute_price_out_vals(vals):
#~ record.update(self.compute_amount_reservation(vals)) days_diff = (fields.Date.from_string(record.checkout) - fields.Date.from_string(record.checkin)).days
#~ if ('checkin' in vals and record.checkin != vals['checkin']) or \ record.update(record.prepare_reservation_lines(
#~ ('checkout' in vals and record.checkout != vals['checkout']) or \ record.checkin,
#~ ('state' in vals and record.state != vals['state']) : days_diff,
#~ vals.update({'to_send': True}) vals = vals))
if ('checkin' in vals and record.checkin != vals['checkin']) or \
('checkout' in vals and record.checkout != vals['checkout']) or \
('state' in vals and record.state != vals['state']) :
vals.update({'to_send': True})
res = super(HotelReservation, self).write(vals) res = super(HotelReservation, self).write(vals)
return res return res
@@ -314,11 +318,11 @@ class HotelReservation(models.Model):
def _prepare_add_missing_fields(self, values): def _prepare_add_missing_fields(self, values):
""" Deduce missing required fields from the onchange """ """ Deduce missing required fields from the onchange """
res = {} res = {}
onchange_fields = ['room_type_id', 'pricelist_id', onchange_fields = ['room_id', 'pricelist_id',
'reservation_type', 'currency_id'] 'reservation_type', 'currency_id']
if values.get('partner_id') and values.get('room_type_id') and any(f not in values for f in onchange_fields): if values.get('partner_id') and values.get('room_type_id') and any(f not in values for f in onchange_fields):
line = self.new(values) line = self.new(values)
line.room_type_id_change() line.onchange_room_id()
for field in onchange_fields: for field in onchange_fields:
if field not in values: if field not in values:
res[field] = line._fields[field].convert_to_write(line[field], line) res[field] = line._fields[field].convert_to_write(line[field], line)
@@ -391,12 +395,16 @@ class HotelReservation(models.Model):
""" """
@api.onchange('adults', 'room_id') @api.onchange('adults', 'room_id')
def onchange_check_capacity(self): def onchange_room_id(self):
if self.room_id: if self.room_id:
if self.room_id.capacity < self.adults: if self.room_id.capacity < self.adults:
self.adults = self.room_id.capacity self.adults = self.room_id.capacity
raise UserError( raise UserError(
_('%s people do not fit in this room! ;)') % (persons)) _('%s people do not fit in this room! ;)') % (persons))
if self.adults == 0:
self.adults = self.room_id.capacity
if not self.room_type_id:
self.room_type_id = self.room_id.room_type_id
@api.onchange('partner_id') @api.onchange('partner_id')
def onchange_partner_id(self): def onchange_partner_id(self):
@@ -410,21 +418,30 @@ class HotelReservation(models.Model):
# When we need to overwrite the prices even if they were already established # When we need to overwrite the prices even if they were already established
@api.onchange('room_type_id', 'pricelist_id', 'reservation_type') @api.onchange('room_type_id', 'pricelist_id', 'reservation_type')
def onchange_overwrite_price_by_day(self): def onchange_overwrite_price_by_day(self):
self.update(self.compute_amount_reservation(update_old_prices=True)) if self.room_type_id and self.checkin and self.checkout:
days_diff = (fields.Date.from_string(self.checkout) - fields.Date.from_string(self.checkin)).days
self.update(self.prepare_reservation_lines(
self.checkin,
days_diff,
update_old_prices = True))
# When we need to update prices respecting those that were already established # When we need to update prices respecting those that were already established
@api.onchange('checkin', 'checkout') @api.onchange('checkin', 'checkout')
def onchange_check_dates(self): def onchange_dates(self):
if not self.checkin: if not self.checkin:
self.checkin = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT) self.checkin = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
if not self.checkout: if not self.checkout:
self.checkout = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT) self.checkout = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
checkin_dt = fields.Date.from_string(self.checkin) checkin_dt = fields.Date.from_string(self.checkin)
checkout_dt = fields.Date.from_string(self.checkout) checkout_dt = fields.Date.from_string(self.checkout)
if checkin_dt >= checkout_dt: if checkin_dt >= checkout_dt:
self.checkout = (fields.Date.from_string(self.checkin) + timedelta(days=1)).strftime(DEFAULT_SERVER_DATE_FORMAT) self.checkout = (fields.Date.from_string(self.checkin) + timedelta(days=1)).strftime(DEFAULT_SERVER_DATE_FORMAT)
self.update(self.compute_amount_reservation(update_old_prices=True)) if self.room_type_id:
days_diff = (fields.Date.from_string(self.checkout) - fields.Date.from_string(self.checkin)).days
self.update(self.prepare_reservation_lines(
self.checkin,
days_diff,
update_old_prices = False))
@@ -664,57 +681,41 @@ class HotelReservation(models.Model):
""" """
if not vals: if not vals:
vals = {} vals = {}
if ('price_total' not in vals and \ if ('reservation_line_ids' not in vals and \
('checkout' in vals or 'checkin' in vals or \ ('checkout' in vals or 'checkin' in vals or \
'room_type_id' in vals or 'pricelist_id' in vals)): 'room_type_id' in vals or 'pricelist_id' in vals)):
return True return True
return False return False
@api.multi @api.depends('reservation_line_ids', 'reservation_line_ids.discount', 'tax_id')
def compute_amount_reservation(self, vals=False, update_old_prices=False): def _compute_amount_reservation(self):
""" """
Compute the amounts of the reservation. Compute the amounts of the reservation.
if vals: Then it is a new record and We must use pass in vals
if not vals: Then we calc the price based in self data
""" """
if not vals: for line in self:
vals = {} amount_room = 0
checkin = vals.get('checkin') or self.checkin for day in line.reservation_line_ids:
checkout = vals.get('checkout') or self.checkout amount_room += day.price
reservation_type = vals.get('reservation_type') or self.reservation_type if amount_room > 0:
room_type = self.env['hotel.room.type'].browse(vals.get('room_type_id') or self.room_type_id.id) product = line.room_type_id.product_id
discount = vals.get('discount') or self.discount price = amount_room * (1 - (line.discount or 0.0) / 100.0)
tax = self.env['account.tax'].browse(vals.get('tax_id') or self.tax_id.id) taxes = line.tax_id.compute_all(price, line.currency_id, 1, product=product)
currency = self.env['res.currency'].browse(vals.get('currency_id') or self.currency_id.id) line.update({
'price_tax': sum(t.get('amount', 0.0) for t in taxes.get('taxes', [])),
days_diff = (fields.Date.from_string(checkout) - fields.Date.from_string(checkin)).days 'price_total': taxes['total_included'],
rlines = self.prepare_reservation_lines( 'price_subtotal': taxes['total_excluded'],
checkin, })
days_diff,
vals = vals,
update_old_prices = update_old_prices)
if reservation_type in ['staff', 'out']:
amount_room = 0.0
else:
amount_room = rlines['total_price']
product = room_type.product_id
price = amount_room * (1 - (discount or 0.0) / 100.0)
taxes = tax.compute_all(price, currency, 1, product=product)
return({
'reservation_line_ids': rlines['commands'],
'price_tax': sum(t.get('amount', 0.0) for t in taxes.get('taxes', [])),
'price_total': taxes['total_included'],
'price_subtotal': taxes['total_excluded'],
})
@api.multi @api.multi
def prepare_reservation_lines(self, dfrom, days, vals=False, def prepare_reservation_lines(self, dfrom, days, vals=False,
update_old_prices=False): update_old_prices=False):
total_price = 0.0 total_price = 0.0
cmds = [] cmds = []
#~ pricelist_id = self.env['ir.default'].sudo().get( if not vals:
#~ 'res.config.settings', 'parity_pricelist_id') vals = {}
pricelist_id = vals.get('pricelist_id') or self.pricelist_id.id pricelist_id = self.env['ir.default'].sudo().get(
'res.config.settings', 'parity_pricelist_id')
#~ pricelist_id = vals.get('pricelist_id') or self.pricelist_id.id
product = self.env['hotel.room.type'].browse(vals.get('room_type_id') or self.room_type_id.id).product_id product = self.env['hotel.room.type'].browse(vals.get('room_type_id') or self.room_type_id.id).product_id
old_lines_days = self.mapped('reservation_line_ids.date') old_lines_days = self.mapped('reservation_line_ids.date')
partner = self.env['res.partner'].browse(vals.get('partner_id') or self.partner_id.id) partner = self.env['res.partner'].browse(vals.get('partner_id') or self.partner_id.id)
@@ -742,14 +743,9 @@ class HotelReservation(models.Model):
})) }))
else: else:
line_price = old_line.price line_price = old_line.price
cmds.append((4, old_line.id))
total_price += line_price total_price += line_price
#unlink old lines deleted return {'price_total': total_price, 'reservation_line_ids': cmds}
dto = (fields.Date.from_string(dfrom) + timedelta(days=days)).strftime(DEFAULT_SERVER_DATE_FORMAT)
old_deleted_days = self.reservation_line_ids.filtered(
lambda d: d.date < dfrom
or d.date >= dto)
old_deleted_days.unlink()
return {'total_price': total_price, 'commands': cmds}
@api.multi @api.multi
def action_pay_folio(self): def action_pay_folio(self):

View File

@@ -34,13 +34,3 @@ class HotelReservationLine(models.Model):
discount = fields.Float( discount = fields.Float(
string='Discount (%)', string='Discount (%)',
digits=dp.get_precision('Discount'), default=0.0) digits=dp.get_precision('Discount'), default=0.0)
@api.model
def create(self, vals):
record = super(HotelReservation, self).create(vals)
return record
@api.multi
def write(self, vals):
res = super(HotelReservation, self).write(vals)
return res