[ADD] WorkFlow Product per_day, Service Lines creation and modifications

This commit is contained in:
Dario Lodeiros
2018-11-20 13:11:03 +01:00
parent 7ac201873c
commit d57906deb6
6 changed files with 205 additions and 150 deletions

View File

@@ -103,7 +103,7 @@ class HotelReservation(models.Model):
if record.folio_id:
record.shared_folio = len(record.folio_id.room_lines) > 1 or \
any(record.folio_id.service_line_ids.filtered(
lambda x: x.ser_room_line != record.id))
lambda x: x.ser_room_line.id != record.id))
@api.depends('checkin', 'checkout')
def _computed_nights(self):
@@ -310,25 +310,52 @@ class HotelReservation(models.Model):
'last_updated_res': fields.Datetime.now()
})
for record in self:
checkin = vals['checkin'] if 'checkin' in vals else record.checkin
checkout = vals['checkout'] if 'checkout' in vals else record.checkout
days_diff = (
fields.Date.from_string(checkout) - \
fields.Date.from_string(checkin)
).days
if record.compute_price_out_vals(vals):
checkin = vals['checkin'] if 'checkin' in vals else record.checkin
checkout = vals['checkout'] if 'checkout' in vals else record.checkout
days_diff = (
fields.Date.from_string(checkout) - \
fields.Date.from_string(checkin)
).days
record.update(record.prepare_reservation_lines(
vals['checkin'] if 'checkin' in vals else record.checkin,
checkin,
days_diff,
vals=vals)) #REVISAR el unlink
if record.compute_qty_service_day(vals):
for service in record.service_line_ids:
if service.product_id.per_day:
params = {
'per_person': service.product_id.per_person,
'persons': vals['adults'] if 'adults' in vals else record.adults
}
service.update(service.prepare_service_lines(
checkin,
days_diff,
params
))
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})
('checkout' in vals and record.checkout != vals['checkout']) or \
('state' in vals and record.state != vals['state']):
record.update({'to_send': True})
res = super(HotelReservation, self).write(vals)
return res
@api.multi
def compute_qty_service_day(self, vals):
"""
Compute if It is necesary calc price in write/create
"""
self.ensure_one()
if not vals:
vals = {}
if 'service_line_ids' in vals:
return False
if ('checkin' in vals and self.checkin != vals['checkin']) or \
('checkout' in vals and self.checkout != vals['checkout']) or \
('adults' in vals and self.checkout != vals['adults']):
return True
return False
@api.model
def _prepare_add_missing_fields(self, values):
""" Deduce missing required fields from the onchange """
@@ -507,6 +534,12 @@ class HotelReservation(models.Model):
self.name = self.room_type_id.name + ': ' + checkin_str + ' - '\
+ checkout_str
@api.onchange('checkin', 'checkout')
def onchange_update_service_per_day(self):
services = self.service_line_ids.filtered(lambda r: r.per_day == True)
for service in services:
service.onchange_product_calc_qty()
@api.multi
@api.onchange('checkin', 'checkout', 'room_id')
def onchange_room_availabiltiy_domain(self):
@@ -748,7 +781,8 @@ class HotelReservation(models.Model):
#~ pricelist_id = vals.get('pricelist_id') or self.pricelist_id.id
room_type_id = vals.get('room_type_id') or self.room_type_id.id
product = self.env['hotel.room.type'].browse(room_type_id).product_id
old_lines_days = self.mapped('reservation_line_ids.date')
old_lines_days = self.mapped('reservation_line_ids.date') #TODO: This is a
# PROBLEM when self is multirecord and the records has different old lines
partner = self.env['res.partner'].browse(vals.get('partner_id') or self.partner_id.id)
for i in range(0, days):
idate = (fields.Date.from_string(dfrom) + timedelta(days=i)).strftime(

View File

@@ -4,6 +4,7 @@
from odoo import models, fields, api
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT
from datetime import timedelta
from odoo.exceptions import ValidationError
class HotelService(models.Model):
_name = 'hotel.service'
@@ -22,9 +23,10 @@ class HotelService(models.Model):
folio_id = fields.Many2one('hotel.folio', 'Folio', ondelete='cascade')
ser_room_line = fields.Many2one('hotel.reservation', 'Room',
default=_default_ser_room_line)
per_day = fields.Boolean(related='product_id.per_day', 'Unit increment per day')
per_day = fields.Boolean(related='product_id.per_day')
service_line_ids = fields.One2many('hotel.service.line', 'service_id')
product_qty = fields.Integer('Quantity')
days_qty = fields.Integer(compute="_compute_days_qty", store=True)
pricelist_id = fields.Many2one(related='folio_id.pricelist_id')
channel_type = fields.Selection([
('door', 'Door'),
@@ -48,53 +50,95 @@ class HotelService(models.Model):
store=True,
compute='_compute_amount_reservation')
@api.model
def create(self, vals):
if self.compute_lines_out_vals(vals):
reservation = self.env['hotel.reservation'].browse(vals['reservation_id'])
product = self.env['product.product'].browse(vals['product_id'])
params = {
'per_person': product.per_person,
'persons': reservation.adults
}
vals.update(self.prepare_service_lines(
reservation.checkin,
reservation.days,
params
))
record = super(HotelService, self).create(vals)
return record
@api.multi
def write(self, vals):
#If you write product, We must check if its necesary create or delete
#service lines
if vals.get('product_id'):
product = self.env['product.product'].browse(vals.get('product_id'))
if not product.per_day:
vals.update({
'service_line_ids' : [(5, 0, 0)]
})
else:
for record in self:
reservations = self.env['hotel.reservation']
reservation = reservations.browse(vals['reservation_id']) \
if 'reservation_id' in vals else record.reservation_id
params = {
'per_person': product.per_person,
'persons': reservation.adults
}
record.update(record.prepare_service_lines(
reservation.checkin,
reservation.days,
params
))
res = super(HotelService, self).write(vals)
return res
@api.multi
def compute_lines_out_vals(self, vals):
"""
Compute if It is necesary service days in write/create
"""
if not vals:
vals = {}
if 'product_id' in vals:
product = self.env['product.product'].browse(vals['product_id']) \
if 'product_id' in vals else self.product_id
if (product.per_day and 'service_line_ids' not in vals):
return True
return False
@api.onchange('product_id')
def onchange_product_calc_qty(self):
"""
Compute the default quantity according to the
configuration of the selected product
configuration of the selected product, in per_day product configuration,
the qty is autocalculated and readonly based on service_lines qty
"""
for record in self:
product = record.product_id
reservation = record.ser_room_line
if product and reservation:
qty = 1
if product.per_day:
qty = qty * reservation.nights
if product.per_person:
qty = qty * (reservation.adults + reservation.children)
record.product_qty = qty
@api.onchange('product_qty')
def onchange_product_qty_days_selection(self):
"""
Try to calculate the days on which the product
should be served as long as the product is per day
"""
for record in self:
reservation = record.ser_room_line
if record.product_id.per_day:
days_diff = (
fields.Date.from_string(reservation.checkout) - fields.Date.from_string(reservation.checkin)
).days
record.update(record.prepare_service_lines(
reservation.checkin,
days_diff))
else:
record.update(record.prepare_service_lines(
reservation.checkin, 1))
##WIP##
if record.per_day and record.ser_room_line:
product = record.product_id
reservation = record.ser_room_line
params = {
'per_person': product.per_person,
'persons': reservation.adults
}
record.update(self.prepare_service_lines(
reservation.checkin,
reservation.nights,
params))
@api.multi
def prepare_service_lines(self, dfrom, days, vals=False):
def prepare_service_lines(self, dfrom, days, params=False):
"""
Respect the old manual changes on lines
"""
self.ensure_one()
old_qty = 0
cmds = [(5, 0, 0)]
old_lines_days = self.mapped('service_line_ids.date')
for day in self.service_line_ids:
old_qty = old_qty + day.day_qty
qty_day = (self.product_qty - old_qty) // (days - len(old_line_days))
rest_day = (self.product_qty - old_qty) % (days - len(old_line_days))
total_qty = 0
day_qty = 1
if params.get('per_person'): #WARNING: Change adults in reservation NOT update qty service!!
day_qty = params.get('persons')
for i in range(0, days):
idate = (fields.Date.from_string(dfrom) + timedelta(days=i)).strftime(
DEFAULT_SERVER_DATE_FORMAT)
@@ -102,11 +146,13 @@ class HotelService(models.Model):
if idate not in old_lines_days:
cmds.append((0, False, {
'date': idate,
'day_qty': qty_day
'day_qty': day_qty
}))
total_qty = total_qty + day_qty
else:
cmds.append((4, old_line.id))
return {'service_line_ids': cmds}
total_qty = total_qty + old_line.day_qty
return {'service_line_ids': cmds, 'product_qty': total_qty}
@api.depends('qty_product', 'tax_id')
def _compute_amount_service(self):
@@ -122,3 +168,25 @@ class HotelService(models.Model):
'price_total': taxes['total_included'],
'price_subtotal': taxes['total_excluded'],
})
@api.depends('service_line_ids.day_qty')
def _compute_days_qty(self):
for record in self:
if record.per_day:
qty = sum(record.service_line_ids.mapped('day_qty'))
vals = {
'days_qty': qty,
'product_qty': qty
}
else:
vals = {'days_qty': 0}
record.update(vals)
@api.constrains('qty_product')
def constrains_qty_per_day(self):
for record in self:
if record.per_day:
service_lines = self.env['hotel.service_line']
total_day_qty = sum(service_lines.with_context({'service_id': record.id}).mapped('day_qty'))
if record.qty_product != total_day_qty:
raise ValidationError (_('The quantity per line and per day does not correspond'))

View File

@@ -26,7 +26,6 @@ class HotelServiceLine(models.Model):
if limit < out_qty + record.day_qty:
raise ValidationError(
_("Limit exceeded for %s")% record.date)