Class: VendorsService::GenerateMemoService
- Inherits:
-
BaseOperationService
- Object
- BaseOperationService
- VendorsService::GenerateMemoService
- Includes:
- DefaultErrorContainer, ElasticAPM::SpanHelpers, MoneyRails::ActionViewExtension
- Defined in:
- app/services/vendors_service/generate_memo_service.rb
Overview
Service for generating standardized supplier notes/memos for reservations Outputs a formatted text memo with package, payment, and reservation details
Output format (4 sections, nil values auto-filtered):
SECTION 1: Package Information (Plan, Price, Qty, Total)
SECTION 2: Payment Information (Payment Status, PrePaid, Due, Discount, Payment Method)
SECTION 3: Additional Information (Customer Request, Occasion, Big Group Booking)
SECTION 4: Reservation Details (Reservation ID, Vendor, Reference ID, Reseller Reference ID, Reservation Link)
Constant Summary collapse
- PAYMENT_STATUS_FULLY_PAID =
Payment status constants
'100% Fully Paid'- PAYMENT_STATUS_PENDING =
'Payment is Pending'- PAYMENT_STATUS_FAILED =
'CANCEL BECAUSE OF PAYMENT FAILED'- PAYMENT_STATUS_PAY_AT_RESTAURANT =
'Pay at the restaurant'- PAYMENT_STATUS_UNKNOWN =
'Unknown Status, pls. verify via Reservation Link'- PAYMENT_METHOD_PROMO_CODE =
Payment method constants
'Promo Code'- CANCEL_REASON_PAYMENT =
Cancel reason keyword
'Payment canceled'
Instance Attribute Summary collapse
-
#reservation ⇒ Object
readonly
Returns the value of attribute reservation.
Attributes inherited from BaseOperationService
Instance Method Summary collapse
-
#build_standardized_memo ⇒ String
Builds standardized memo with all possible fields organized in 4 sections Each section is a hash where nil values are automatically filtered out using compact.
-
#calculate_payment_status_percentage ⇒ String?
Calculates payment percentage for partially paid reservations.
-
#calculate_reservation_amounts(reservation) ⇒ Hash?
Calculates reservation amounts using ChargeCalculator for vendor prepaid reservations.
-
#calculate_total_amount ⇒ Money
Calculates total amount excluding delivery fee.
-
#discount_value ⇒ String?
Returns formatted discount amount from vouchers if applicable.
-
#due_value ⇒ String?
Returns formatted due amount if applicable (not shown if 0).
-
#execute ⇒ String
Generates and returns the supplier memo text.
-
#format_memo_sections(sections) ⇒ String
Formats sections into final memo output Each section is separated by a blank line, empty sections are filtered out.
-
#format_money(amount_or_money) ⇒ String
Formats money value with currency symbol.
-
#fully_paid? ⇒ Boolean
Determines if reservation is fully paid (100%).
-
#get_active_reservation_vouchers ⇒ Array
Returns active reservation vouchers.
-
#get_formatted_packages ⇒ Array<Hash>
Returns formatted packages array.
-
#get_restaurant_package(formatted_package) ⇒ HhPackage::RestaurantPackage?
Gets restaurant package for a formatted package with caching.
-
#initialize(reservation = nil, is_vendor_prepaid_reservation = false, reference_id = nil, reseller_reference_id = nil) ⇒ GenerateMemoService
constructor
Initialize the memo service.
-
#owner_confirmation_url ⇒ String
Returns owner confirmation URL for the reservation.
-
#package_plan_line ⇒ String?
Returns package plan name with type prefix.
-
#package_price_line ⇒ String?
Returns package unit prices based on pricing model.
-
#package_qty_line ⇒ String?
Returns package quantity based on pricing model.
-
#parsed_vendor_name(reservation) ⇒ String
Extracts vendor name from booking channel name (removes “HH x ” prefix).
-
#payment_method_value ⇒ String?
Returns payment method name if applicable.
-
#payment_status_text ⇒ String
Returns payment status text based on reservation state.
-
#prepaid_value ⇒ String?
Returns formatted prepaid amount if applicable.
-
#reference_id_value ⇒ String?
Returns vendor reference ID if available.
-
#reseller_reference_id_value ⇒ String?
Returns reseller reference ID if available.
-
#reservation_id_text ⇒ String
Returns reservation ID text (handles old/new ID pairs for migrated reservations).
-
#restaurant_packages_map(formatted) ⇒ Hash<Integer, HhPackage::RestaurantPackage>
Preloads all restaurant packages referenced by formatted packages to avoid N+1 queries.
-
#update_vendor_reservation_status(reservation, vendor_reservation_memo_payment_status) ⇒ void
Updates vendor reservation supplier_memo_payment_status.
-
#vendor_name_text ⇒ String
Returns vendor name from booking channel or default.
Methods included from DefaultErrorContainer
#error, #error_message_simple, #merge_errors
Methods inherited from BaseOperationService
Constructor Details
#initialize(reservation = nil, is_vendor_prepaid_reservation = false, reference_id = nil, reseller_reference_id = nil) ⇒ GenerateMemoService
Initialize the memo service
46 47 48 49 50 51 52 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 46 def initialize(reservation = nil, is_vendor_prepaid_reservation = false, reference_id = nil, reseller_reference_id = nil) super() @reservation = reservation&.decorate @is_vendor_prepaid_reservation = is_vendor_prepaid_reservation @reference_id = reference_id @reseller_reference_id = reseller_reference_id end |
Instance Attribute Details
#reservation ⇒ Object (readonly)
Returns the value of attribute reservation.
38 39 40 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 38 def reservation @reservation end |
Instance Method Details
#build_standardized_memo ⇒ String
Builds standardized memo with all possible fields organized in 4 sections Each section is a hash where nil values are automatically filtered out using compact
86 87 88 89 90 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 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 86 def build_standardized_memo section_package = { 'Plan' => package_plan_line, 'Price' => package_price_line, 'Qty' => package_qty_line, 'Total' => format_money(calculate_total_amount), }.compact section_payment = { 'Payment Status' => payment_status_text, 'PrePaid' => prepaid_value, 'Due' => due_value, 'Discount' => discount_value, 'Payment Method' => payment_method_value, }.compact section_additional = { 'Customer Request' => reservation., 'Occasion' => reservation.dining_occasion&.name_en, 'Big Group Booking' => (reservation.group_booking? ? 'Yes' : nil), }.compact section_reservation = { 'Reservation ID' => reservation_id_text, 'Vendor' => vendor_name_text, 'Reference ID' => reference_id_value, 'Reseller Reference ID' => reseller_reference_id_value, 'Reservation Link' => owner_confirmation_url, }.compact format_memo_sections([section_package, section_payment, section_additional, section_reservation]) end |
#calculate_payment_status_percentage ⇒ String?
Calculates payment percentage for partially paid reservations
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 349 def calculate_payment_status_percentage paid_amount = reservation.paid_amount.to_d total_amount_value = reservation.total_amount.to_d due_amount_value = reservation.due_amount.amount.to_d charge_percent = reservation.charge_percent active_vouchers = get_active_reservation_vouchers discount = active_vouchers.map(&:amount).sum.amount if active_vouchers.present? discount = discount.to_d total_paid = paid_amount + discount paid_percentage = total_amount_value.positive? ? ((total_paid / total_amount_value) * 100).to_i : 0 having_due = paid_amount.positive? && due_amount_value.positive? && due_amount_value < total_amount_value if having_due || (charge_percent.positive? && charge_percent < 100) "#{paid_percentage}% Paid" elsif reservation.prepaid_full? PAYMENT_STATUS_FULLY_PAID end end |
#calculate_reservation_amounts(reservation) ⇒ Hash?
Calculates reservation amounts using ChargeCalculator for vendor prepaid reservations
578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 578 def calculate_reservation_amounts(reservation) adult = reservation.adult kids = reservation.kids reservation_date = reservation.date vendor_channel = reservation.booking_channel restaurant = reservation.restaurant calculator = HhPackage::ReservationPackages::ChargeCalculator.new formatted_packages = get_formatted_packages rest_packs_map = restaurant_packages_map(formatted_packages) package_bought = formatted_packages.map do |pack_bought| rest_pack_id = pack_bought['restaurant_package_id'] || pack_bought[:restaurant_package_id] rest_pack = rest_packs_map[rest_pack_id] if rest_pack.nil? BUSINESS_LOGGER.error('Restaurant package not found', package_id: rest_pack_id) APMErrorHandler.report('Missing restaurant package in vendor payment calculation', package_id: rest_pack_id) next end pack_bought['package'] = rest_pack.package pack_bought end.compact calculator.use_dynamic_pricing = vendor_channel&.support_dynamic_pricing || false begin data = calculator.calculate(package_bought, adult, kids, 0.0, restaurant, reservation_date) data.presence rescue StandardError => e BUSINESS_LOGGER.error('Error calculating reservation amount', error: e., reservation_id: reservation.id) APMErrorHandler.report('Calculator error in vendor payment calculation', error: e.) {} end end |
#calculate_total_amount ⇒ Money
Calculates total amount excluding delivery fee
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 230 def calculate_total_amount return @calculate_total_amount if defined?(@calculate_total_amount) formatted_packages = get_formatted_packages return @calculate_total_amount = Money.new(0, reservation.package_price_currency) if formatted_packages.blank? reservation_total = reservation.total_amount.to_f # If total_amount is zero/nil, calculate from packages (values are in cents) if reservation_total.zero? package_total_cents = formatted_packages.sum do |pkg| # Check if this is per_pack pricing restaurant_package = get_restaurant_package(pkg) is_per_pack = restaurant_package&.package&.dynamic_price_pricing_model&.to_sym == :per_pack if is_per_pack # For per_pack: only use total_adult_price (total_kids_price is the same value, not additive) pkg[:total_adult_price] || 0 else # For per_person: sum adult and kids prices (pkg[:total_adult_price] || 0) + (pkg[:total_kids_price] || 0) end end reservation_total = package_total_cents / 100.0 end delivery_fee = reservation.original_delivery_fee.to_d @calculate_total_amount = Money.from_amount(reservation_total - delivery_fee, reservation.package_price_currency) end |
#discount_value ⇒ String?
Returns formatted discount amount from vouchers if applicable
438 439 440 441 442 443 444 445 446 447 448 449 450 451 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 438 def discount_value active_vouchers = get_active_reservation_vouchers return nil if active_vouchers.blank? discount = active_vouchers.map(&:amount).sum.amount return nil if discount <= 0 # Don't show discount for pay at restaurant unless user created if payment_status_text == PAYMENT_STATUS_PAY_AT_RESTAURANT && !(reservation.created_by.to_sym == :user) return nil end HhMoney.from_amount(discount, reservation.package_price_currency).default_format end |
#due_value ⇒ String?
Returns formatted due amount if applicable (not shown if 0)
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 415 def due_value # Don't show due for certain statuses return nil if reservation.status_as_symbol == :cancelled && (reservation&.cancel_reason&.include?(CANCEL_REASON_PAYMENT) || reservation&.payment_expired?) return nil if !reservation.payment_is_confirmed? return nil if reservation.paid_by_voucher_full? return nil if payment_status_text == PAYMENT_STATUS_FULLY_PAID due_amount_value = reservation.due_amount.amount.to_d # For "Pay at the restaurant" with no calculated due_amount, use the total as due if due_amount_value <= 0 && payment_status_text == PAYMENT_STATUS_PAY_AT_RESTAURANT total = calculate_total_amount return format_money(total) if total.positive? end return nil if due_amount_value <= 0 format_money(reservation.due_amount) end |
#execute ⇒ String
Generates and returns the supplier memo text
62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 62 def execute BUSINESS_LOGGER.set_business_context(reservation_id: reservation&.id) raise ArgumentError, 'Reservation is nil' if reservation.nil? memo_text = build_standardized_memo BUSINESS_LOGGER.info('Generated Supplier Notes/Memo', memo: memo_text) memo_text rescue StandardError => e clean_backtrace = Rails.backtrace_cleaner.clean(e.backtrace) BUSINESS_LOGGER.error('Error in GenerateMemoService', error: e., backtrace: clean_backtrace.first(5)) APMErrorHandler.report(e, reservation_id: reservation&.id, backtrace: clean_backtrace) '' end |
#format_memo_sections(sections) ⇒ String
Formats sections into final memo output Each section is separated by a blank line, empty sections are filtered out
551 552 553 554 555 556 557 558 559 560 561 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 551 def format_memo_sections(sections) formatted_sections = sections.map do |section| next if section.empty? section.map do |key, value| key == 'Reservation ID' ? value : "#{key}: #{value}" end.join("\n") end.compact formatted_sections.join("\n\n") end |
#format_money(amount_or_money) ⇒ String
Formats money value with currency symbol
542 543 544 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 542 def format_money(amount_or_money) HhMoney.new(amount_or_money, reservation.package_price_currency).default_format end |
#fully_paid? ⇒ Boolean
Determines if reservation is fully paid (100%)
317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 317 def fully_paid? # Vendor prepaid reservations are always fully paid return true if @is_vendor_prepaid_reservation payment_type_provider = reservation.payment_type_provider # Channel payments for user-created reservations if payment_type_provider.present? && payment_type_provider == reservation.channel_uri_name && reservation.created_by.to_sym == :user return true end # For admin/owner created reservations with channel payment, check if prepaid_full if payment_type_provider.present? && payment_type_provider == reservation.channel_uri_name && [:admin, :owner].include?(reservation.created_by.to_sym) return reservation.prepaid_full? end # Fully paid by voucher/promo code return true if reservation.paid_by_voucher_full? # Check if prepaid_full for other cases return true if reservation.prepaid_full? false end |
#get_active_reservation_vouchers ⇒ Array
Returns active reservation vouchers
628 629 630 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 628 def get_active_reservation_vouchers @active_reservation_vouchers ||= reservation.active_reservation_vouchers || [] end |
#get_formatted_packages ⇒ Array<Hash>
Returns formatted packages array
621 622 623 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 621 def get_formatted_packages @formatted_packages ||= reservation.package_obj&.formatted_packages || [] end |
#get_restaurant_package(formatted_package) ⇒ HhPackage::RestaurantPackage?
Gets restaurant package for a formatted package with caching
636 637 638 639 640 641 642 643 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 636 def get_restaurant_package(formatted_package) package_with_indifferent_access = formatted_package.with_indifferent_access restaurant_package_id = package_with_indifferent_access[:restaurant_package_id] return nil if restaurant_package_id.blank? @restaurant_packages_cache ||= {} @restaurant_packages_cache[restaurant_package_id] ||= HhPackage::RestaurantPackage.includes(:package).find_by(id: restaurant_package_id) end |
#owner_confirmation_url ⇒ String
Returns owner confirmation URL for the reservation
524 525 526 527 528 529 530 531 532 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 524 def owner_confirmation_url @owner_confirmation_url ||= begin owner = reservation.restaurant.owner Rails.application.routes.url_helpers.owner_confirmation_reservation_url( owner_hash: owner.to_url_hash, reservation_hash: reservation.to_url_hash, ) end end |
#package_plan_line ⇒ String?
Returns package plan name with type prefix
130 131 132 133 134 135 136 137 138 139 140 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 130 def package_plan_line formatted_packages = get_formatted_packages return nil if formatted_packages.blank? package_obj = reservation.package_obj&.type_short package_name = I18n.with_locale(:en) do I18n.t("views.booking.package_data_name.#{package_obj}", name: formatted_packages.first[:name]) end "(#{package_obj&.upcase}) #{package_name}" end |
#package_price_line ⇒ String?
Returns package unit prices based on pricing model
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 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 150 def package_price_line formatted_packages = get_formatted_packages return nil if formatted_packages.blank? package = formatted_packages.first package_obj = reservation.package_obj # Determine if this is per_pack pricing using dynamic_price_pricing_model restaurant_package = get_restaurant_package(package) is_per_pack = restaurant_package&.package&.dynamic_price_pricing_model&.to_sym == :per_pack if is_per_pack # For per_pack: show price per pack pack_price = HhMoney.new(package[:price_cents], package['price_currency']).default_format "#{pack_price}/Pack" else # For per_person: show adult and optionally kid prices adult_price = HhMoney.new(package[:price_cents], package['price_currency']).default_format # Show kid price if there are kids AND either kids_amount > 0 OR total_kids_price exists has_kid_price = reservation.kids.positive? && (package['kids_amount'].to_d.positive? || package[:total_kids_price].to_i.positive?) if has_kid_price kids_price = if package[:use_kids_price] == true HhMoney.new(package[:kids_price_v2], package['price_currency']).default_format elsif package[:total_kids_price].to_i.positive? && reservation.kids.positive? # Calculate kid price from total_kids_price kid_price_cents = (package[:total_kids_price].to_d / reservation.kids).to_i HhMoney.new(kid_price_cents, package['price_currency']).default_format else adult_price end "#{adult_price}/Adult, #{kids_price}/Kid" else "#{adult_price}/Adult" end end end |
#package_qty_line ⇒ String?
Returns package quantity based on pricing model
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 199 def package_qty_line formatted_packages = get_formatted_packages return nil if formatted_packages.blank? package = formatted_packages.first package_obj = reservation.package_obj # Determine if this is per_pack pricing using dynamic_price_pricing_model restaurant_package = get_restaurant_package(package) is_per_pack = restaurant_package&.package&.dynamic_price_pricing_model&.to_sym == :per_pack if is_per_pack # For per_pack: show "X Pack (Y Adult, Z Kid)" or "X Pack (Y Adult)" pack_quantity = package[:quantity] || 1 if reservation.kids.positive? "#{pack_quantity} Pack (#{reservation.adult} Adult, #{reservation.kids} Kid)" else "#{pack_quantity} Pack (#{reservation.adult} Adult)" end elsif reservation.kids.positive? # For per_person: show "X Adult, Y Kid" or "X Adult" "#{reservation.adult} Adult, #{reservation.kids} Kid" else "#{reservation.adult} Adult" end end |
#parsed_vendor_name(reservation) ⇒ String
Extracts vendor name from booking channel name (removes “HH x ” prefix)
567 568 569 570 571 572 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 567 def parsed_vendor_name(reservation) vendor_name = reservation&.booking_channel&.name return '' if vendor_name.blank? vendor_name.to_s.split('HH x ').last end |
#payment_method_value ⇒ String?
Returns payment method name if applicable
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 456 def payment_method_value # Show "Promo Code" for voucher payments return PAYMENT_METHOD_PROMO_CODE if reservation.paid_by_voucher_full? || reservation.paid_by_voucher_partially? payment_type_provider = reservation&.payment_type_provider return nil if payment_type_provider.blank? return nil unless reservation.created_by.to_sym == :user # Only show if payment_type_provider is NOT the same as channel_uri_name return nil if payment_type_provider == reservation.channel_uri_name # Don't show for these statuses return nil if reservation.status_as_symbol == :cancelled && (reservation&.cancel_reason&.include?(CANCEL_REASON_PAYMENT) || reservation&.payment_expired?) return nil if !reservation.payment_is_confirmed? return nil if payment_status_text == PAYMENT_STATUS_PAY_AT_RESTAURANT payment_type_provider.to_s.split('_').join(' ').titleize end |
#payment_status_text ⇒ String
Returns payment status text based on reservation state
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 273 def payment_status_text return @payment_status_text if defined?(@payment_status_text) payment_type_provider = reservation&.payment_type_provider vendor_status = nil status_text = if reservation.status_as_symbol == :cancelled && (reservation&.cancel_reason&.include?(CANCEL_REASON_PAYMENT) || reservation&.payment_expired?) # Cancelled due to payment failure - highest priority check vendor_status = :failed PAYMENT_STATUS_FAILED elsif fully_paid? # Check for 100% fully paid scenarios (includes vendor prepaid override) # This must come before payment_is_confirmed check to handle vendor prepaid reservations vendor_status = :paid PAYMENT_STATUS_FULLY_PAID elsif !reservation.payment_is_confirmed? || (reservation.paid_by_voucher_partially? && reservation.paid_amount.zero?) # Payment not confirmed yet OR partial voucher without actual money payment vendor_status = :pending PAYMENT_STATUS_PENDING elsif payment_type_provider.present? || (reservation.model.payment_status == 'prepaid' && reservation.due_amount.amount > 0) # Calculate percentage for partial payments vendor_status = :paid calculate_payment_status_percentage elsif reservation.model.payment_status == 'no_deposit' || (reservation.paid_amount.zero? && reservation.due_amount.amount > 0) # Pay at restaurant - no prepayment required vendor_status = :postpaid PAYMENT_STATUS_PAY_AT_RESTAURANT else # Unknown/unhandled payment status vendor_status = :pending PAYMENT_STATUS_UNKNOWN end # Update vendor reservation status update_vendor_reservation_status(reservation, vendor_status) if vendor_status.present? @payment_status_text = status_text end |
#prepaid_value ⇒ String?
Returns formatted prepaid amount if applicable
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 373 def prepaid_value # Don't show prepaid for these statuses return nil if reservation.status_as_symbol == :cancelled && (reservation&.cancel_reason&.include?(CANCEL_REASON_PAYMENT) || reservation&.payment_expired?) return nil if !reservation.payment_is_confirmed? return nil if reservation.paid_by_voucher_full? # Check if there's actually an amount paid before hiding PrePaid # Don't show prepaid if payment_status is "Pay at the restaurant" AND no amount has been paid yet if payment_status_text == PAYMENT_STATUS_PAY_AT_RESTAURANT && reservation.paid_amount.is_a?(Money) && reservation.paid_amount.zero? return nil end # For vendor prepaid reservations, calculate from packages if @is_vendor_prepaid_reservation calc_amounts = calculate_reservation_amounts(reservation) return format_money(calc_amounts[:total_price_cents]) if calc_amounts.present? end # Calculate prepaid amount from reservation paid = reservation.paid_amount if paid.is_a?(Money) && paid.zero? && (reservation.payment_type_provider.present? || @is_vendor_prepaid_reservation) formatted_packages = get_formatted_packages paid_cents = formatted_packages.sum { |pkg| (pkg[:total_adult_price] || 0) + (pkg[:total_kids_price] || 0) } paid = Money.new(paid_cents, reservation.package_price_currency) end # Format Money object properly prepaid_amt = if paid.is_a?(Money) HhMoney.from_amount(paid.amount, paid.currency).default_format else format_money(paid) end return nil if paid.is_a?(Money) && paid.zero? return nil if !paid.is_a?(Money) && prepaid_amt == format_money(0) prepaid_amt end |
#reference_id_value ⇒ String?
Returns vendor reference ID if available
510 511 512 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 510 def reference_id_value reservation.vendor_reservation&.reference_id || @reference_id end |
#reseller_reference_id_value ⇒ String?
Returns reseller reference ID if available
517 518 519 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 517 def reseller_reference_id_value reservation.vendor_reservation&.reseller_reference_id || @reseller_reference_id end |
#reservation_id_text ⇒ String
Returns reservation ID text (handles old/new ID pairs for migrated reservations)
485 486 487 488 489 490 491 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 485 def reservation_id_text if reservation.old_reservation_id.present? "Reservation Old ID: #{reservation.old_reservation_id}\nReservation New ID: #{reservation.id}" else "Reservation ID: #{reservation.id}" end end |
#restaurant_packages_map(formatted) ⇒ Hash<Integer, HhPackage::RestaurantPackage>
Preloads all restaurant packages referenced by formatted packages to avoid N+1 queries
649 650 651 652 653 654 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 649 def restaurant_packages_map(formatted) ids = formatted.map { |p| p['restaurant_package_id'] || p[:restaurant_package_id] }.compact return {} if ids.empty? HhPackage::RestaurantPackage.includes(:package, :restaurant).where(id: ids).index_by(&:id) end |
#update_vendor_reservation_status(reservation, vendor_reservation_memo_payment_status) ⇒ void
This method returns an undefined value.
Updates vendor reservation supplier_memo_payment_status
661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 661 def update_vendor_reservation_status(reservation, vendor_reservation_memo_payment_status) vr = reservation.vendor_reservation return if vr.blank? vr.update!(supplier_memo_payment_status: vendor_reservation_memo_payment_status) BUSINESS_LOGGER.info( 'Updated supplier_memo_payment_status', vendor_reservation_id: vr.id, status: vendor_reservation_memo_payment_status, reservation_id: reservation.id, ) rescue StandardError => e BUSINESS_LOGGER.error( 'Failed to update supplier_memo_payment_status', error: e., reservation_id: reservation&.id, vendor_reservation_id: vr&.id, ) APMErrorHandler.report(e, reservation_id: reservation&.id) end |
#vendor_name_text ⇒ String
Returns vendor name from booking channel or default
496 497 498 499 500 501 502 503 504 505 |
# File 'app/services/vendors_service/generate_memo_service.rb', line 496 def vendor_name_text is_show_in_owner_dashboard = reservation&.booking_channel&.show_in_owner_dashboard? if is_show_in_owner_dashboard vendor_name = parsed_vendor_name(reservation) vendor_name.presence || 'Hungry Hub' else 'Hungry Hub' end end |