Module: Api::Vendor::V1::Klook::Concerns::SerializerUtils
- Extended by:
- ActiveSupport::Concern
- Includes:
- Concerns::ReservationUtils
- Included in:
- AvailabilitySerializer, BookingSerializer, ProductSerializer, VendorsService::Klook::AvailabilityService
- Defined in:
- app/serializers/api/vendor/v1/klook/concerns/serializer_utils.rb
Overview
typed: ignore frozen_string_literal: true
Instance Attribute Summary collapse
-
#currency_code ⇒ Object
readonly
Returns the value of attribute currency_code.
Instance Method Summary collapse
- #generate_time_slots(restaurant_package, day_name = nil) ⇒ Object
-
#get_restaurant_package_open_close_times(restaurant_package, day_name = nil) ⇒ Array<String, String>
Returns opening and closing times for a restaurant package for a given day.
- #serialize_option(restaurant_package) ⇒ Object
- #serialize_pricings(restaurant_package, unit) ⇒ Object
- #serialize_product(restaurant) ⇒ Object
- #serialize_total_pricings(restaurant:, restaurant_package:, reservation: nil, units: nil) ⇒ Object
- #serialize_units(restaurant_package) ⇒ Object
Instance Attribute Details
#currency_code ⇒ Object (readonly)
Returns the value of attribute currency_code.
9 10 11 |
# File 'app/serializers/api/vendor/v1/klook/concerns/serializer_utils.rb', line 9 def currency_code @currency_code end |
Instance Method Details
#generate_time_slots(restaurant_package, day_name = nil) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'app/serializers/api/vendor/v1/klook/concerns/serializer_utils.rb', line 91 def generate_time_slots(restaurant_package, day_name = nil) default_periods = Reservation::PERIODS_WITHOUT_00_AM if day_name.present? open_time, close_time = get_restaurant_package_open_close_times(restaurant_package, day_name) else open_time, close_time = get_restaurant_package_open_close_times(restaurant_package) end interval = restaurant_package.restaurant.start_time_interval.to_s[/\d+/].to_i return default_periods if open_time.blank? || close_time.blank? || interval <= 0 begin start = Time.zone.parse(open_time) finish = Time.zone.parse(close_time) rescue ArgumentError, TypeError return default_periods end return default_periods if start.nil? || finish.nil? slots = [] current = start while current <= finish slots << current.strftime('%H:%M') current += interval * 60 end slots.any? ? slots : default_periods end |
#get_restaurant_package_open_close_times(restaurant_package, day_name = nil) ⇒ Array<String, String>
Returns opening and closing times for a restaurant package for a given day.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'app/serializers/api/vendor/v1/klook/concerns/serializer_utils.rb', line 73 def get_restaurant_package_open_close_times(restaurant_package, day_name = nil) # opening_hours is an array of hashes: [{:day_name=>"Monday", :schedule=>{"open"=>"11:00", "close"=>"22:00"}}, ...] opening_hours = RestPackageCpt::Cells::OpeningHours.new.search_availability_of_next_days(restaurant_package) return [] if opening_hours.blank? if day_name.present? day_schedule_hash = opening_hours.detect { |h| h[:day_name] == day_name } day_schedule = day_schedule_hash&.dig(:schedule) return [nil, nil] if day_schedule.nil? || %w[closed nil].include?(day_schedule['open']) || %w[closed nil].include?(day_schedule['close']) return [day_schedule['open'], day_schedule['close']] end opens = opening_hours.map { |h| h[:schedule]['open'] }.reject { |t| t.nil? || t == 'closed' } closes = opening_hours.map { |h| h[:schedule]['close'] }.reject { |t| t.nil? || t == 'closed' } [opens.min, closes.max] end |
#serialize_option(restaurant_package) ⇒ Object
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 64 65 |
# File 'app/serializers/api/vendor/v1/klook/concerns/serializer_utils.rb', line 34 def serialize_option(restaurant_package) # skip postpaid packages since Klook reservations will be 100% prepaid. return nil unless restaurant_package.package.require_cc || restaurant_package.package.pay_now @currency_code = get_restaurant_currency(restaurant_package.restaurant) is_per_pack = restaurant_package&.package&.dynamic_price_pricing_model&.to_sym == :per_pack per_pack_qty = is_per_pack ? restaurant_package&.package&.dynamic_pricings&.first&.per_pack.to_i : 1 min_seat = restaurant_package.package.decide_min_seat.to_i min_units = [min_seat / per_pack_qty, 1].max # null = unlimited max_seat = restaurant_package.package.decide_max_seat.to_i max_seat = nil if max_seat == HhPackage::UNLIMITED max_units = max_seat.nil? ? nil : max_seat / per_pack_qty { id: restaurant_package.id.to_s, default: restaurant_package.rank_in_restaurant_scope == 0, internalName: restaurant_package.name, reference: restaurant_package.slug, availabilityLocalStartTimes: generate_time_slots(restaurant_package), cancellationCutoff: nil, cancellationCutoffAmount: nil, cancellationCutoffUnit: nil, requiredContactFields: ['firstName', 'lastName', 'emailAddress'], restrictions: { # The minimum number of tickets that can be purchased in a single booking (in terms of pax / packs) minUnits: min_units, # The maximum number of tickets that can be purchased in a single booking (in terms of pax / packs) maxUnits: max_units, }, units: serialize_units(restaurant_package), } end |
#serialize_pricings(restaurant_package, unit) ⇒ Object
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'app/serializers/api/vendor/v1/klook/concerns/serializer_utils.rb', line 178 def serialize_pricings(restaurant_package, unit) dynamic_pricings = restaurant_package.package.dynamic_pricings dynamic_pricing_flipper = DynamicPricingsFlipper.new(restaurant_package.restaurant.time_zone) # for Klook, it doesn't support dynamic pricing yet, so we hardcode the support_dynamic_pricing_feature to false pricing = dynamic_pricing_flipper.filter_by_package(dynamic_pricings, restaurant_package.package, false).last raise NotImplementedError, 'Failed to find pricing for option' if pricing.blank? @currency_code = pricing.price_currency price_cents = unit == 'child' && pricing.kids_price_cents.to_i.positive? ? pricing.kids_price_cents.to_i : pricing.price_cents.to_i original_price_cents = restaurant_package.package&.fetch_package_attr&.original_price_cents original_price = original_price_cents.present? && original_price_cents.to_i.positive? ? original_price_cents : price_cents percentage = get_vendor_commission_excluded_price_percentage(restaurant_package) vendor_price_cents = (price_cents.to_d * percentage.to_d).ceil.to_i [{ unitId: unit, original: original_price, retail: price_cents, net: vendor_price_cents, currency: currency_code, currencyPrecision: 2, includedTaxes: [], }.compact] end |
#serialize_product(restaurant) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'app/serializers/api/vendor/v1/klook/concerns/serializer_utils.rb', line 11 def serialize_product(restaurant) @currency_code = get_restaurant_currency(restaurant) { id: restaurant.id.to_s, internalName: restaurant.name_en, reference: restaurant.slug, locale: MyLocaleManager.new.culture_names[MyLocaleManager::EN], timeZone: restaurant.time_zone, allowFreesale: false, instantConfirmation: true, instantDelivery: true, availabilityRequired: true, availabilityType: 'START_TIME', deliveryFormats: ['QRCODE'], deliveryMethods: ['VOUCHER'], redemptionMethod: 'DIGITAL', options: restaurant.restaurant_packages.valid_to_have_agendas_and_not_preview.order_for_restaurant.map { |rp| serialize_option(rp) }.compact, defaultCurrency: currency_code, availableCurrencies: [currency_code], pricingPer: 'UNIT', } end |
#serialize_total_pricings(restaurant:, restaurant_package:, reservation: nil, units: nil) ⇒ Object
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'app/serializers/api/vendor/v1/klook/concerns/serializer_utils.rb', line 205 def serialize_total_pricings(restaurant:, restaurant_package:, reservation: nil, units: nil) # no need to return total_pricing if availability api is called without unit items return nil if reservation.nil? && units.nil? adult, kids, package_qty = calculate_adult_kids_pkg_qty(restaurant_package, reservation, units) calculator = HhPackage::ReservationPackages::ChargeCalculator.new calculator.use_dynamic_pricing = false package_bought = [ rest_pack: restaurant_package, package: restaurant_package.package, restaurant_package_id: restaurant_package.id, restaurant: restaurant, quantity: package_qty, ] total_price_cents = calculator.calculate(package_bought, adult, kids, 0.0, restaurant, nil)[:total_price_cents].to_i # Calculates the original price in cents for the given restaurant package and units. # - If the package uses 'pack' units and has an original price, multiply by package quantity. # - If the package has an original price and uses 'adult'/'child' units, multiply by total pax. # - Otherwise, fallback to total calculated price. # # @return [Integer] The original price in cents. original_price = restaurant_package.package&.fetch_package_attr&.original_price_cents original_price_cents = if original_price.present? && original_price.to_i.positive? if units&.any? { |item| item[:id] == 'pack' } original_price * package_qty else original_price * (adult + kids) end else total_price_cents end percentage = get_vendor_commission_excluded_price_percentage(restaurant_package) vendor_price_cents = (total_price_cents.to_d * percentage.to_d).ceil.to_i { original: original_price_cents, retail: total_price_cents, net: vendor_price_cents, currency: currency_code, currencyPrecision: 2, includedTaxes: [], } end |
#serialize_units(restaurant_package) ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'app/serializers/api/vendor/v1/klook/concerns/serializer_utils.rb', line 121 def serialize_units(restaurant_package) @currency_code = get_restaurant_currency(restaurant_package.restaurant) if restaurant_package&.package&.dynamic_price_pricing_model&.to_sym == :per_pack [{ id: 'pack', internalName: 'pack', type: 'OTHER', requiredContactFields: ['firstName', 'lastName', 'emailAddress'], restrictions: { min_age: nil, max_age: nil, id_required: true, min_quantity: nil, max_quantity: nil, pax_count: 1, accompanied_by: [], }, pricingFrom: serialize_pricings(restaurant_package, 'pack'), }] else [ { id: 'adult', internalName: 'adult', type: 'ADULT', requiredContactFields: ['firstName', 'lastName', 'emailAddress'], restrictions: { min_age: nil, max_age: nil, id_required: true, min_quantity: nil, max_quantity: nil, pax_count: 1, accompanied_by: [], }, pricingFrom: serialize_pricings(restaurant_package, 'adult'), }, { id: 'child', internalName: 'child', type: 'CHILD', requiredContactFields: ['firstName'], restrictions: { min_age: nil, max_age: nil, id_required: true, min_quantity: nil, max_quantity: nil, pax_count: 1, accompanied_by: ['adult'], }, pricingFrom: serialize_pricings(restaurant_package, 'child'), }, ] end end |