[FIX] pms_api_rest, connector_pms_wubook: bill board service via pricelist, not raw amount#79
Open
DarioLodeiros wants to merge 1 commit into
Open
Conversation
…elist, not raw amount When an external channel posts a reservation with a package price (room + board) plus a boardServiceId, the room price was computed by subtracting `pms.board.service.room.type.line.amount * (adults|children)` from the package. But the auto-computed `pms.service.line` actually bills the board service through the pricelist + fiscal-position tax path, so the two diverge whenever the line amount does not match the pricelist-derived price (different pricelist override, intracommunity fiscal position mapping a price-include tax to a non-include one, etc). Result: the reservation line ends up under-priced by the gap, leaving the folio total below what the channel sent. Centralize the per-day billed price computation in a new helper `pms.board.service.room.type._get_billed_day_price`, mirroring `pms.service.line._get_price_unit_line`, and call it from the three buggy callsites (POST /folios, the update flow, and the wubook connector mapper).
Diff CoverageDiff: origin/16.0...HEAD, staged and unstaged changes
Summary
connector_pms_wubook/models/pms_reservation_line/mapper_import.pyLines 54-62 54 if record["board"] and record["board_included"]:
55 board_service_room = get_board_service_room_type(
56 self, room_type, record["board"], pricelist_id
57 )
! 58 board_day_price = board_service_room._get_billed_day_price(
59 pricelist=self.env["product.pricelist"].browse(pricelist_id),
60 consumption_date=record["day"],
61 pms_property_id=self.backend_record.pms_property_id.id,
62 adults=record["occupancy"],Lines 66-72 66 if agency
67 else False,
68 company=self.backend_record.pms_property_id.company_id,
69 )
! 70 price -= board_day_price
71 return {"price": price}pms_api_rest/models/pms_board_service_room_type.pyLines 34-42 34 ):
35 if bsl.adults and adults:
36 qty = adults
37 elif bsl.children and children:
! 38 qty = children
39 else:
40 continue
41 raw_price = pricelist._get_product_price(
42 product=bsl.product_id.with_context(pms_api_rest/services/pms_folio_service.pyLines 982-990 982 # package (room + board). Compute the board portion
983 # per date with the same pricing logic the auto-
984 # computed pms.service.line will use, so we can
985 # subtract it cleanly and leave the room price.
! 986 board_day_prices = {}
987 if external_app and vals.get("board_service_room_id"):
988 board = (
989 self.env["pms.board.service.room.type"]
990 .sudo()Lines 990-999 990 .sudo()
991 .browse(vals["board_service_room_id"])
992 )
993 pms_api_check_access(user=self.env.user, records=board)
! 994 for rline in reservation.reservationLines:
! 995 board_day_prices[rline.date] = board._get_billed_day_price(
996 pricelist=folio.pricelist_id,
997 consumption_date=rline.date,
998 pms_property_id=folio.pms_property_id.id,
999 adults=reservation.adults,Lines 2567-2575 2567 new_res or proposed_reservation.state in ["draft", "confirm"]
2568 ):
2569 # The service price is included in day price
2570 # when it is a board service (external api)
! 2571 board_day_prices = {}
2572 if external_app:
2573 # if proposed reservation and not board_service_room_id in vals,
2574 # get board_day_price from the already-billed board services
2575 # of the proposed reservation (same value for every day).Lines 2573-2581 2573 # if proposed reservation and not board_service_room_id in vals,
2574 # get board_day_price from the already-billed board services
2575 # of the proposed reservation (same value for every day).
2576 if proposed_reservation and not vals.get("board_service_room_id"):
! 2577 avg = sum(
2578 proposed_reservation.service_ids.filtered(
2579 lambda s: s.is_board_service
2580 ).mapped("price_total")
2581 ) / (Lines 2584-2593 2584 - proposed_reservation.checkin
2585 ).days
2586 or 1
2587 )
! 2588 for rline in info_reservation.reservationLines:
! 2589 board_day_prices[rline.date] = avg
2590 else:
2591 board = (
2592 self.env["pms.board.service.room.type"]
2593 .sudo()Lines 2600-2608 2600 )
2601 )
2602 )
2603 pms_api_check_access(user=self.env.user, records=board)
! 2604 pricelist = (
2605 self.env["product.pricelist"]
2606 .sudo()
2607 .browse(info_reservation.pricelistId)
2608 if info_reservation.pricelistIdLines 2607-2616 2607 .browse(info_reservation.pricelistId)
2608 if info_reservation.pricelistId
2609 else folio.pricelist_id
2610 )
! 2611 for rline in info_reservation.reservationLines:
! 2612 board_day_prices[rline.date] = board._get_billed_day_price(
2613 pricelist=pricelist,
2614 consumption_date=rline.date,
2615 pms_property_id=folio.pms_property_id.id,
2616 adults=info_reservation.adults,Lines 2652-2663 2652 board_day_prices=None,
2653 proposed_reservation=False,
2654 commission_percent_to_deduct=0,
2655 ):
! 2656 board_day_prices = board_day_prices or {}
2657 cmds = []
2658 for line in reservation.reservationLines:
! 2659 board_day_price = board_day_prices.get(line.date, 0)
2660 if proposed_reservation:
2661 # Not is necesay check new dates, becouse a if the dates change,
2662 # the reservation is new
2663 proposed_line = proposed_reservation.reservation_line_ids.filtered( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When an external channel (OTA via
/foliosPOST, Wubook connector) sends a reservation with a package price (room + board) plus aboardServiceId, the room price is computed by subtracting the per-adult/children board service amount from the package. The previous code subtractedpms.board.service.room.type.line.amount × (adults|children)directly, but the auto-computedpms.service.linebills the board service through the pricelist + fiscal-position tax path. When these two computations disagree (different pricelist override, intracommunity fiscal position mapping a price-include tax to a non-include one, etc), the reservation line ends up under-priced by the gap and the folio total falls below what the channel actually sent.The fix routes the API-side computation through the same pricing path the service line will use, so the split is always consistent.
Changes
pms.board.service.room.type._get_billed_day_price(...)inpms_api_rest/models/pms_board_service_room_type.py. Mirrorspms.service.line._get_price_unit_line: pricelist_get_product_pricewithboard_service_line_id+consumption_datecontext, then_fix_tax_included_price_companyagainst the fiscal-position-mapped taxes.pms_api_rest/services/pms_folio_service.py: replaces the three buggy callsites that subtracted the raw amount (POST/folios, the update-reservations flow, andwrapper_reservation_lines). The per-day amount is now computed via the helper and threaded as a dict by date.connector_pms_wubook/models/pms_reservation_line/mapper_import.py: same swap for the Wubook import mapper.Test plan
docker-compose run --rm odoo odoo --test-tags /pms_api_rest -d devel --no-http -u pms_api_rest— 13 tests, 0 failuresamount_total = 59.9 €for the original failing payload, matching what the OTA sent.