Decimal Price
Description / Background
Decimal price for Singapore expansion
Glossary
Private (https://app.clickup.com/9003122396/docs/8ca1fpw-35796/8ca1fpw-41516)
Objectives
- User can see the price until the cents number
- User can pay the prepaid booking with decimal number
- System will not display for
.00 - This feature have flipper to enable or disable the feature

Backend Implementation
app/controllers/api/v5/pages_controller.rb: Added a new feature toggle for enabling decimal prices.- Adjusted the calculation for total amount and due amount to handle decimal values more accurately.
- Added new attributes to handle prices in both integer and decimal formats.
- Changed amount calculation to use floating-point numbers instead of integers.
- Updated price formatting to conditionally remove cents if the price is a whole number.
- Updated to handle and display prices accurately, including conditional formatting for whole numbers and decimals.
- Added validation and monetization for amount in cents.
- Added methods to handle price in both cents and decimal formats.
app/models/hh_package/pricing.rb: Changed price handling from integer to floating-point.app/my_lib/hh_money.rb: Added methods to handle prices with and without cents.app/my_lib/hh_package/reservation_packages/charge_calculator.rb: Updated calculations to handle decimal values accurately.app/my_lib/hh_package/reservation_packages/voucher_calculator.rb: Adjusted voucher calculations to handle cents.app/my_lib/my_active_merchants/gb_primepay_gateway.rb: Changed amount handling to use floating-point numbers.app/my_lib/receptionist/credit_card_checker.rb: Changed charge amount handling to use floating-point numbers.- Changed charge amount handling to use floating-point numbers.
- Added logic to handle prices in cents and decimals based on feature toggles.
- Updated payment summary to handle decimal values and added a private method to format values to decimals.
- A new currency/money field named
amount_v2is added to several models and calculations to handle monetary values with higher precision (to_d) while maintaining backward compatibility with the existingamountfield (which usesto_i). - A new migration file (
20250415062310_add_amount_v2_cents_to_reservation_vouchers.rb) adds a fieldamount_v2_centsto thereservation_voucherstable. - The
ReservationVouchermodel now includes theamount_v2field usingmonetize. Methods dealing withamountare updated to useamount_v2where necessary. - Example updates include:
- Using
amount.to_dfor precise calculations. - Updating
assign_amount_voucherto store both the integer (to_i) and decimal (to_d) representations.
- Using
- Controllers like
api/v5/vouchers_controller.rbanddashboard/v2/reservations_controller.rbare modified to includeamount_v2in their logic and response payloads. - Example: The
serialized_vouchermethod now includesvouchers_amount_v2in the metadata. - Services such as
partner_service/bills/calculate_service.rbnow useamount_v2_centsfor summing voucher values instead ofamount_cents. VoucherForm::Applyintroduces a new methodvouchers_amount_v2to calculate the total amount using theamount_v2field.- The
Api::V5::ReservationSerializernow includesamount_v2in its serialized output for vouchers. - Updates in views like
admin/vouchers/show.html.slimto displayamount_v2instead ofamount. - The
voucher_calculatorclass is updated with logic for handlingamount_v2in various calculations (e.g.,get_voucher_amount_v2,assign_used_vouchers). - Both
amountandamount_v2exist in parallel, ensuring backward compatibility while transitioning to the new field. - Handles backfill for the
amount_v2field on charges. - Changes include:
- Skipping charges where
amountisnilor zero. - If
amountisnil, it sets it to0and updates the database without validations. - Updates the
amount_v2_centsandamount_v2_currencyfields directly in the database usingupdate_column.
- Skipping charges where
- Handles backfill for the
total_price_v2_centsandcharge_price_v2_centsfields on reservations. - Changes include:
- If no reservations are found to process, it raises an
ActiveRecord::Rollbackinstead of just returning. - Updates
total_price_v2_centsandcharge_price_v2_centsdirectly in the database usingupdate_column.
- If no reservations are found to process, it raises an
- A placeholder worker for backfilling decimals. No diff was generated, so the exact implementation isn't shown.
- The workers now prefer
update_columnfor direct database updates instead ofsave!to skip validations and improve performance. - Added a new entry in
sidekiq_scheduler.yml:backfill_decimals_price_and_charge:- Scheduled to run daily at midnight (UTC+7 timezone).
- Executes the
ScheduleWorkers::Decimals::BackfillDecimalsworker.
[
github.com
https://github.com/hungryhub-team/hh-server/pull/6395/files
](https://github.com/hungryhub-team/hh-server/pull/6395/files)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/6369
](https://github.com/hungryhub-team/hh-server/pull/6369)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/6395/commits/ca894a1821be89c87893023a1f6a143864a9c80f
](https://github.com/hungryhub-team/hh-server/pull/6395/commits/ca894a1821be89c87893023a1f6a143864a9c80f)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/6542
](https://github.com/hungryhub-team/hh-server/pull/6542)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/6511
](https://github.com/hungryhub-team/hh-server/pull/6511)
Hybrid Implementation
getBookingDetail.ts:- Added new fields
chargePriceDecimalandtotalPriceDecimal, which store price values as strings.
- Added new fields
searchRestaurantGraphql.ts:- Added
amountCentsto thepriceAndPricingTypeobject, which stores the price in cents.
- Added
BookingSummary.vue:- Updated the display of the total price to use a new
isInCentsparameter for formatting money.
- Updated the display of the total price to use a new
RestaurantCardRoot.vue:- Added
isInCentsparameter to theformatMoneyfunction call.
- Added
string.ts:- Modified the
formatMoneyfunction to handle theisInCentsparameter. IfisInCentsis true, it converts cents to the main currency unit before formatting.
- Modified the
onHoldPrice.ts:- Changed the
pricePerPersonandpricefields to usechargePriceCents. - Added the
isInCentsparameter when formatting money.
- Changed the
restaurant.ts:- Added
amountCentsto thepriceV2object.
- Added
BookingConfirmationDesktop.vueandBookingConfirmationMobile.vue:- Added the
isInCentsparameter when formatting money.
- Added the
PaymentSuccessPage.vue:- Added the
isInCentsparameter when formatting money. - Modified the calculation of
amountandchargePriceto use cents values.
- Added the
QrPackagePage.vueandQrPackagePageDesktop.vue:- Added the
isInCentsparameter when formatting money.
- Added the
SearchRestaurantCard.vue:- Added
currencyto the price display. - Imported
convertToNumberand used it to format the lowest price.
- Added
SelectDateTime.vue:- Simplified icon class names.
PopUpTotalPrice.vue:- Changed the
totalPricefield tototalPackagePriceCentsand added theisInCentsparameter when formatting money.
- Changed the
BookingEditChargeSummary.vue:- Added new fields
chargePriceCents,totalPriceCents, andtotalPackagePriceCentsto thechargeObject.
- Added new fields
BookingSummary.vue:- Changed the
totalPricefield tototalPriceCents.
- Changed the
BreadCrumbs.vue:- Simplified class names.
bookingCharge.ts:- Added
chargePriceCentsandtotalPriceCentsfields to theChargeObjecttype. - Modified functions to use these new fields and convert cents to the main currency unit.
- Added
chargeSummary.ts:- Added the
chargePriceCentsandtotalPriceCentsfields to theChargeObjecttype. - Modified functions to use these new fields and convert cents to the main currency unit.
- Added the
Booking.ts:- Added
chargePriceCents,totalPriceCents, andtotalPackagePriceCentsto thebookingChargeSchema.
- Added
Restaurant.ts:- Added
amountCentsto thepricePerPersonandpriceAndPricingTypeobjects.
- Added
[
github.com
https://github.com/hungryhub-team/hh-pegasus/pull/1678
](https://github.com/hungryhub-team/hh-pegasus/pull/1678)
Partner Portal Implementation
- The original implementation used
accounting.formatMoneyto format the price with no decimal places (precision set to0). - Sets the precision to 2 decimal places (for more accurate monetary representation).
- Checks if the resulting
formattedPriceends with.00.- If true, it removes the trailing
.00for cleaner formatting. - Otherwise, it returns the formatted price as-is.
- If true, it removes the trailing
- The code now checks if there is a preformatted price (
item.price_format). If it exists, it usesitem.price_format; otherwise, it falls back to formatting the price withformatMoney. - This ensures that any preformatted price provided is prioritized over dynamically formatting it.
- The total package price is now calculated from
response.data?.total_package_price_centsby dividing it by 100 (to convert from cents to the base currency). The result is then stored inthis.totalPackagePrice. - This change standardizes the handling of monetary values to use cents, which is a common practice to avoid floating-point errors in calculations.
- The function now uses
accounting.formatMoneyto format the price but replaces trailing.00,.X0, or.0Xwith a more compact representation (e.g., removes unnecessary zeros). The new regex ensures that only significant decimal places are retained. - This change improves the formatting of prices, making them cleaner and easier to read.
[
github.com
https://github.com/hungryhub-team/book-bite/pull/656
](https://github.com/hungryhub-team/book-bite/pull/656)
[
github.com
https://github.com/hungryhub-team/book-bite/pull/792
](https://github.com/hungryhub-team/book-bite/pull/792)
PRD & Task
Private (https://app.clickup.com/t/86cy3bqmr)
Design
no design