From ef1c4a02913a2054611eb2f670a4b0114ffa4876 Mon Sep 17 00:00:00 2001 From: oscar alvarez Date: Sun, 20 Mar 2022 08:46:25 -0500 Subject: [PATCH] Fix --- booking.py | 52 ++++++++++++-------- channel.py | 10 ++-- constants.py | 1 - folio.py | 97 +++++++++++++++++++------------------ invoice.py | 4 +- view/booking_folio_form.xml | 4 +- view/booking_form.xml | 10 ++-- view/channel_form.xml | 2 +- 8 files changed, 95 insertions(+), 85 deletions(-) diff --git a/booking.py b/booking.py index b7fabe5..67eb053 100644 --- a/booking.py +++ b/booking.py @@ -127,7 +127,7 @@ class Booking(Workflow, ModelSQL, ModelView): ], depends=['party']) vip = fields.Boolean('V.I.P. Customer', states=STATES) ota_booking_code = fields.Char('OTA Code', select=True, - states={'invisible': ~Eval('media') == 'ota'} + states={'invisible': Eval('media') != 'ota'} ) vehicles_num = fields.Integer('Vehicles Number', states=STATES, help="Number of vehicles that bring with guests.") @@ -141,10 +141,14 @@ class Booking(Workflow, ModelSQL, ModelView): breakfast_included = fields.Boolean('Breakfast Included') channel_commission = fields.Function(fields.Numeric('Channel Commission', digits=(16, 2), depends=['lines']), 'get_channel_commission') - channel_invoice = fields.Many2One('account.invoice', 'Invoice', - states={'invisible': ~Eval('channel')}) + channel_invoice = fields.Many2One('account.invoice', 'Channel Invoice', + states={ + 'invisible': ~Eval('channel'), + 'readonly': True + }) channel_paymode = fields.Selection(PAYMENT_METHOD_CHANNEL, 'Channel Paymode', states={'invisible': ~Eval('channel')}, + depends=['channel'] ) @classmethod @@ -249,20 +253,19 @@ class Booking(Workflow, ModelSQL, ModelView): @fields.depends('party', 'price_list', 'lines') def on_change_party(self): if self.party: - print(' aqui ...') if self.party.sale_price_list: self.price_list = self.party.sale_price_list.id self.price_list.rec_name = self.party.sale_price_list.rec_name for folio in self.lines: - print(' aqui ...2') - if not folio.main_guest and self.party.type_document != '31': - print(' aqui ...3') + if self.party.type_document != '31': folio.main_guest = self.party.id @fields.depends('channel') def on_change_channel(self): - if self.channel and self.channel.price_list: - self.price_list = self.channel.price_list + if self.channel: + self.channel_paymode = self.channel.payment_method + if self.channel.price_list: + self.price_list = self.channel.price_list @classmethod @ModelView.button_action('hotel.wizard_select_rooms') @@ -418,8 +421,9 @@ class Booking(Workflow, ModelSQL, ModelView): if not party: raise UserError(gettext('hotel.msg_customer_is_required')) + bk = fo.booking - # FIXME: Add agent + print(' fo.booking ....', fo.booking) agent_id = bk.channel.agent.id if bk.channel else None if party.id not in res.keys(): # Add room product to sale @@ -466,16 +470,21 @@ class Booking(Workflow, ModelSQL, ModelView): }) for charge in charges: + bk = charge.folio.booking invoice_party_id = charge.invoice_to.id unit_price = bk.currency.round(charge.unit_price) - if invoice_party_id != party.id: - if invoice_party_id not in res.keys(): - res[invoice_party_id] = { - 'party': charge.invoice_to, - 'currency': bk.currency.id, - 'payment_term': None, - 'lines': [], - } + if invoice_party_id not in res.keys(): + res[invoice_party_id] = { + 'party': charge.invoice_to, + 'currency': bk.currency.id, + 'payment_term': None, + 'number': bk.number, + 'reference': charge.folio.registration_card, + 'lines': [], + } + # if invoice_party_id != bk.party.id: + # else: + res[invoice_party_id]['lines'].append({ 'description': ' | '.join([ str(charge.date_service), @@ -528,6 +537,7 @@ class Booking(Workflow, ModelSQL, ModelView): for charge in folio.charges: if not charge.invoice_line and charge.to_invoice: _charges.append(charge) + print('_charges.... ', _charges) return _folios, _charges @classmethod @@ -577,6 +587,7 @@ class Booking(Workflow, ModelSQL, ModelView): pool = Pool() Invoice = pool.get('account.invoice') InvoiceLine = pool.get('account.invoice.line') + Foilo = pool.get('hotel.folio') if not bk.channel: return data = { @@ -584,6 +595,7 @@ class Booking(Workflow, ModelSQL, ModelView): 'reference': bk.number, 'description': f"{bk.ota_booking_code} | {bk.party.name}", 'payment_term': bk.payment_term, + 'number': bk.number, } invoice = cls._get_new_invoice(data) invoice.on_change_invoice_type() @@ -690,9 +702,7 @@ class Booking(Workflow, ModelSQL, ModelView): if data.get('agent'): agent = Agent(data['agent']) - journal, = Journal.search([ - ('type', '=', 'revenue'), - ], limit=1) + journal, = Journal.search([('type', '=', 'revenue')], limit=1) address = party.address_get(type='invoice') payment_term = data.get('payment_term', None) diff --git a/channel.py b/channel.py index 14b3433..ce9a96b 100644 --- a/channel.py +++ b/channel.py @@ -47,8 +47,8 @@ class SaleChannel(ModelSQL, ModelView): currency = fields.Many2One('currency.currency', 'Currency', required=True) price_list = fields.Many2One('product.price_list', 'Price List') - payment_method = fields.Selection(PAYMENT_METHOD_CHANNEL, 'Payment Method', - required=True) + payment_method = fields.Selection(PAYMENT_METHOD_CHANNEL, + 'Payment Method') collection_mode = fields.Selection([ ('', ''), ('anticipated', 'Anticipated'), @@ -57,16 +57,14 @@ class SaleChannel(ModelSQL, ModelView): @classmethod def __setup__(cls): + # alter table hotel_channel drop column commission; + # alter table hotel_channel drop column payment_method; super(SaleChannel, cls).__setup__() @staticmethod def default_company(): return Transaction().context.get('company') - @staticmethod - def default_payment_method(): - return 'ota_collect' - @staticmethod def default_currency(): Company = Pool().get('company.company') diff --git a/constants.py b/constants.py index 21a0cb0..1ebb058 100644 --- a/constants.py +++ b/constants.py @@ -93,7 +93,6 @@ INVOICE_STATES = [ ] PAYMENT_METHOD_CHANNEL = [ - ('', ''), ('at_destination', 'At Destination'), ('ota_collect', 'OTA Collect'), ] diff --git a/folio.py b/folio.py index 2801c95..7912776 100644 --- a/folio.py +++ b/folio.py @@ -91,18 +91,18 @@ class Folio(ModelSQL, ModelView): contact = fields.Char('Contact', states=STATES_CHECKIN) num_children = fields.Function(fields.Integer('No. Children'), 'get_num_children') - nights_quantity = fields.Function(fields.Integer('Nights'), - 'on_change_with_nights_quantity') + nights_quantity = fields.Integer('Nights', states={'readonly': True}, + depends=['arrival_date', 'departure_date']) host_quantity = fields.Integer('Host', states=STATES_CHECKIN) unit_digits = fields.Function(fields.Integer('Unit Digits'), 'get_unit_digits') notes = fields.Text('Notes') total_amount = fields.Function(fields.Numeric('Total Amount', digits=(16, 2)), 'get_totals') total_balance = fields.Function(fields.Numeric('Total Balance', - digits=(16, 2), depends=['paid_by_channel']), 'get_totals') + digits=(16, 2)), 'get_totals') commission_amount = fields.Numeric('Commission Amount', digits=(16, 2), - depends=['product', 'departure_date', 'arrival_date'] - ) + depends=['nights_quantity', 'unit_price'], states={'readonly': True} + ) guests = fields.One2Many('hotel.folio.guest', 'folio', 'Guests', states={'readonly': Eval('registration_state').in_(['check_out'])}) nationality = fields.Many2One('party.nationality', 'Nationality', @@ -137,16 +137,16 @@ class Folio(ModelSQL, ModelView): breakfast_included = fields.Boolean('Breakfast Included', states={ 'readonly': Eval('registration_state') != 'check_in', }) - paid_by_channel = fields.Boolean('Paid By Channel') + # paid_by_channel = fields.Boolean('Paid By Channel') room_amount = fields.Function(fields.Numeric('Room Amount', - digits=(16, 2)), 'get_change_with_room_amount') + digits=(16, 2), depends=['nights_quantity', 'unit_price'] + ), 'on_change_with_room_amount') stock_moves = fields.Many2Many('hotel.folio-stock.move', 'folio', 'move', 'Stock Moves', states={'readonly': True}) - # channel_invoice = fields.Function(fields.Many2One('account.invoice', - # 'Invoice', depends=['booking']), 'get_channel_invoice') @classmethod def __setup__(cls): + # UPDATE hotel_folio SET nights_quantity=(departure_date-arrival_date) super(Folio, cls).__setup__() cls._check_modify_exclude = [ 'nationality', 'origin_country', 'target_country', @@ -193,6 +193,14 @@ class Folio(ModelSQL, ModelView): ] return domain + @classmethod + def create(cls, values): + folios = super(Folio, cls).create(values) + for folio in folios: + folio.update_nights(folio.arrival_date, folio.departure_date) + folio.update_commission() + folio.save() + @classmethod @ModelView.button def check_in(cls, records): @@ -282,16 +290,11 @@ class Folio(ModelSQL, ModelView): res = value['base'] + value['amount'] return res - @fields.depends('unit_price_w_tax', 'nights_quantity') - def get_change_with_room_amount(self, name=None): + @fields.depends('unit_price', 'nights_quantity', 'arrival_date', 'departure_date') + def on_change_with_room_amount(self, name=None): res = 0 - Date = Pool().get('ir.date') - if self.unit_price_w_tax and self.nights_quantity: - if name == 'room_amount': - res = self.unit_price_w_tax * self.nights_quantity - else: - delta = (Date.today() - self.start_date).days - res = self.unit_price_w_tax * delta + if self.unit_price and self.nights_quantity: + res = self.unit_price * self.nights_quantity return round(res, Folio.total_amount.digits[1]) @staticmethod @@ -325,11 +328,6 @@ class Folio(ModelSQL, ModelView): if self.invoice_line and self.invoice_line.invoice: return self.invoice_line.invoice.id - # @fields.depends('accommodation', 'product') - # def on_change_accommodation(self): - # if not self.accommodation: - # self.product = None - def get_room_info(self): description = ' \n'.join([ self.product.rec_name, @@ -340,7 +338,8 @@ class Folio(ModelSQL, ModelView): ]) return description - @fields.depends('product', 'unit_price', 'uom', 'booking', 'nights_quantity') + @fields.depends('product', 'unit_price', 'uom', 'booking', + 'nights_quantity', 'commission_amount') def on_change_product(self): Product = Pool().get('product.product') if self.product and self.booking: @@ -353,13 +352,26 @@ class Folio(ModelSQL, ModelView): self.unit_price = self.booking.currency.round(self.unit_price) else: self.unit_price = self.product.list_price + self.update_commission() - @fields.depends('arrival_date', 'departure_date') + def update_commission(self): + if self.nights_quantity and self.unit_price and self.booking: + if not self.booking.channel: + return + amount = self.on_change_with_room_amount() + self.commission_amount = self.booking.channel.compute(amount) + + @fields.depends('arrival_date', 'departure_date', 'unit_price', 'booking') def on_change_arrival_date(self): - if not self.arrival_date or ( - self.departure_date and self.departure_date > self.arrival_date): - return - self.departure_date = self.arrival_date + timedelta(days=1) + if self.arrival_date and self.departure_date: + self.update_nights(self.arrival_date, self.departure_date) + self.update_commission() + + @fields.depends('arrival_date', 'departure_date', 'unit_price', 'booking') + def on_change_departure_date(self): + if self.arrival_date and self.departure_date: + self.update_nights(self.arrival_date, self.departure_date) + self.update_commission() def check_method(self): """ @@ -433,17 +445,8 @@ class Folio(ModelSQL, ModelView): rooms_available_ids = set(rooms_ids) - set(rooms_not_available_ids) return list(rooms_available_ids) - @fields.depends('arrival_date', 'departure_date') - def on_change_with_nights_quantity(self, name=None): - """ - Compute nights between start and end - return a integer the mean days of occupancy. - """ - nights = 0 - if not self.arrival_date or not self.departure_date: - return nights - nights = (self.departure_date - self.arrival_date).days - return nights + def update_nights(self, arrival_date, departure_date): + self.nights_quantity = (departure_date - arrival_date).days def get_totals(self, name): """ @@ -452,7 +455,7 @@ class Folio(ModelSQL, ModelView): instead of flat price. Fee is linked to channel management. """ res = [] - if name == 'total_amount' or not self.paid_by_channel: + if name == 'total_amount' or not self.invoice_line: if self.nights_quantity and self.unit_price_w_tax: res = [self.nights_quantity * self.unit_price_w_tax] for charge in self.charges: @@ -460,18 +463,16 @@ class Folio(ModelSQL, ModelView): res = round(sum(res), Folio.total_amount.digits[1]) return res - @fields.depends('arrival_date', 'departure_date', 'product') + @fields.depends('nights_quantity', 'unit_price', 'booking') def on_change_with_commission_amount(self): """ Calculation of commission amount for channel based on booking """ - print(' - - - - >', self.arrival_date, self.product, self.departure_date) res = Decimal(0) - if all([self.arrival_date, self.product, self.departure_date]): - if self.booking.channel: - print(self.room_amount) - res = self.booking.channel.compute(self.room_amount) - return res + if self.nights_quantity and self.unit_price and self.booking.channel: + amount = self.on_change_with_room_amount() + res = self.booking.channel.compute(amount) + return res class FolioGuest(ModelSQL, ModelView): diff --git a/invoice.py b/invoice.py index 6bb906b..eb932b1 100644 --- a/invoice.py +++ b/invoice.py @@ -30,7 +30,9 @@ class Invoice(metaclass=PoolMeta): booking = line.origin if not booking.vouchers: continue - vouchers.extend(booking.vouchers) + for voucher in booking.vouchers: + if invoice.party.id == voucher.party.id: + vouchers.append(voucher) if vouchers: invoice.create_move_advance(set(vouchers)) diff --git a/view/booking_folio_form.xml b/view/booking_folio_form.xml index c6bce76..2f92469 100644 --- a/view/booking_folio_form.xml +++ b/view/booking_folio_form.xml @@ -26,8 +26,8 @@ this repository contains the full copyright notices and license terms. -->