Module: Modules::Reservations::RewardPoints

Overview

typed: ignore

Instance Method Summary collapse

Methods included from CorporateUsers::RewardPointsExt

#calc_points_for_corporate_reservation

Instance Method Details

#calc_dynamic_points(reservation_id, for_serializer = false) ⇒ Integer, Float

Note:

Business Logic - Currency Points Conversion:

  • **SGD & MYR**: 1 point = 1 cent (1:1 ratio) Example: $10.50 SGD = 1050 cents → 1050 points (floor) → user earns 1050 points

  • *THB*: 1 point = 100 baht (1:100 ratio) Example: ฿1050 THB → 10.5 points (floor) → user earns 10 points

Note:

Why SGD and MYR are treated identically: Both currencies use the same points-to-currency ratio to maintain consistent reward value across Southeast Asian markets. This simplifies the loyalty program and provides fair earning rates regardless of country.

Note:

Configuration: If different conversion rates are needed per currency in the future, consider extracting this logic to a configurable Country model attribute (e.g., `points_conversion_ratio`) instead of hardcoding currency checks.

Calculates reward points for a reservation based on total price and currency.

Parameters:

  • reservation_id (Integer)

    The ID of the reservation

  • for_serializer (Boolean) (defaults to: false)

    Whether this is being called from a serializer

Returns:

  • (Integer, Float)

    The calculated reward points (Integer for base calculation, Float if corporate or loyalty level multiplier is applied by calculate_max_points)



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'app/my_lib/modules/reservations/reward_points.rb', line 28

def calc_dynamic_points(reservation_id, for_serializer = false)
  reservation = Reservation.find_by(id: reservation_id)
  return 0 if reservation.nil?

  # User won't get points if the reservation is created from website
  return 0 if reservation.created_from_website?

  is_eligible = if reservation.pay_now?
                  !reservation.eligible_to_get_instant_reward?
                else
                  !reservation.eligible_to_get_reward?
                end

  invalid_reservation = if for_serializer
                          if reservation.cancelled?
                            true
                          else
                            reservation.reward&.redeemed && reservation.reward&.description == 'Cancel redemption request'
                          end
                        else
                          is_eligible
                        end

  return 0 if reservation.package.blank? || invalid_reservation

  price_currency = reservation.package['price_currency']
  points = calc_points(reservation)
  points = case price_currency
           when Country::SINGAPORE_CURRENCY_CODE, Country::MALAYSIA_CURRENCY_CODE
             points.floor
           else
             (points / 100.0).floor
           end

  calculate_max_points(points, reservation)
end