DIY Set Package
Description / Background
Our current party packs come with fixed menu items and set quantities. While convenient, this setup doesn’t work for every group—especially those with different tastes or dietary needs. Customers often want more flexibility when choosing food for their group.
To solve this, we’re launching the DIY Set Package. This feature lets customers build their own party pack by choosing how many dishes they want from each category, without having to pick specific items right away. There are two options: one with a minimum spend and one without, so customers can choose what works best for their budget.
The DIY Set Package makes group bookings easier, more flexible, and better suited to a wider range of customer needs.
Objectives
- User can select the how many dishes on each menu group (main dish. appetizer, drink, etc)
- User can select only 1 type of the menu group as long as the price is over the minimum spend
- user can modify booking max 2 hours, after the booking (need confirm to owner)
- User can user other promo code (like voucher, point etc)
- User can get spending discount tier when the total spend per person reach X baht
- User can find the spending tier on the checkout page
- User can book DIY Set package as Group Booking
- User can book DIY Set Package with Add-On

- User can book DIY Set Package as Big Group Order
- Big Group Order only available for Pay at Restaurant
- No kids price for DIY Set Package
- Restaurant can have minimum spend requirement per person
- Restaurant can set the minimum people
- The button checkout will not clickable when the minimum spend is not reach
- The price based on menu group, it only have 1 price per group, but it can have the highest price and selling price (the selling price is the price that user pay, the highest price is for the dash
300display on user side) - The DIY set package can be mix and match with the other DIY package
- Its not available for vendor
- It available for all payment type
- The discount tier is on package level
- The discount tier can be per booking and can be per person
- The inventory logic is same as party pack
- Admin can export the DIY set package
- Add DIY set package into all report that we have on the system
- Admin can set the Add-On into DIY Set Package
Scope
package, booking flow, admin dashboard
Phase 1:
- Package card
- store page
- booking flow
- database schema design
- API
- DIY calculator
- Admin dashboard
- Export on admin dashboard and partner portal (after 1 week after released)
Out of scope
- Dynamic pricing
- 3rd party
- Kid price
How to set DIY Package
Sequence Diagram / Flow
ERD

Backend Implementation
- Introduces a new package type called "DIY" to the system.
- Adds English, Thai, and Chinese descriptions for the package.
- Sets color code and type code for the new package.
- This migration helps the system recognize and display the "DIY" package type.
- New Model: Added a new
DIYpackage type, including custom pricing logic and database migrations to support it. - Pricing Enhancements: DIY packages include new pricing menus, spending tiers, per-item support, and minimum spending requirements.
- Discounts: The system now calculates tiered discounts based on spending, and integrates these into the pricing flow.
- Validation: Controllers and models validate DIY-specific configs (min spend, tiers, menus).
- Database: Multiple migrations add support for DIY package types, pricing tiers, menus, and group sections.
- Business Logic:
charge_calculator.rb: Handles DIY group sections, tiered discounts, new validations.selected_packages_builder.rb: Returns spending tier, applies discounts, supports grouping.price_finder.rb: Calculates DIY price from selected items and group sections.dynamic_pricings_for_package.rb,dynamic_pricings_for_pricing.rb: Support for per-item pricing and DIY validations.diy.rb: New model for DIY package with single-pricing enforcement.update.rb/modify_booking_for_user.rb: Detects DIY changes and validates on duplication.
- Expose DIY Data: Serializers (e.g.,
restaurant_package_serializer.rb) now expose DIY attributes, menus, tiers for API v5. - Admin Mailer Improvements: Staff and owner mailers (
staff_mailer.rb,owner_mailer.rb) are refactored to use locals-based rendering. - Admin UI: Admin helpers and controller logic expanded to support DIY package management and validation.
- Admin New Routes: Routing updated for DIY resources.
- The array
package_typeis used to filter restaurant packages. Previously, it allowed only three types: Ayce, PartyPack, and Xperience. The update adds a fourth type: Diy ('HhPackage::Package::Diy'). - Any restaurant package with the type
Diywill now be included in API responses or internal logic that relies on this method. - Restaurants that offer a "Diy" (Do It Yourself) package can now have these packages processed and returned via the API for partners.
- The update refactors the logic for the
min_spendingattribute in theRestaurantPackageSerializer. It replaces early returns with clear conditional blocks, making the code easier to follow and ensuring all cases are handled explicitly. The actual output for clients remains consistent, but the codebase is now more robust and maintainable.
[
github.com
https://github.com/hungryhub-team/hh-server/pull/6979
](https://github.com/hungryhub-team/hh-server/pull/6979)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/7134/files
](https://github.com/hungryhub-team/hh-server/pull/7134/files)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/7152/files
](https://github.com/hungryhub-team/hh-server/pull/7152/files)
[
github.com
https://github.com/hungryhub-team/hh-server/pull/7178/files
](https://github.com/hungryhub-team/hh-server/pull/7178/files)
Hybrid Implementation
- Introduces a new feature for handling "DIY packages" in the system.
- Includes
diytype in helpers and constants for consistent reference throughout the code. - Updates relevant helpers and constants files to support DIY package identification and handling.
- Implements API and service logic to fetch DIY packages:
- API: Adds
getRestaurantDIYPackagesendpoint. - Service: Adds
getDIYPackagesservice for business logic. - Store: Updates or adds
restaurantDIYPackagesstore to manage DIY package state.
- API: Adds
- Integrates new UI components for DIY packages:
- DIYSection Component: Renders the DIY package section on relevant pages.
- DIYPackageCard Component: Displays individual DIY package details.
- Updates main restaurant page components to include and render the new DIY section.
- Data flows from fetching via API, through service and store, to rendering in the UI.
- The updates required changes across backend (API/service/store) and frontend (components/pages).
- Constants and helpers were updated to support the new "diy" type.
- State management was extended to include DIY packages.
- UI components were added for DIY package display and interaction.
- Implements API and service logic to fetch DIY packages:
- API: Adds
getRestaurantDIYPackagesendpoint. - Service: Adds
getDIYPackagesservice for business logic. - Store: Updates or adds
restaurantDIYPackagesstore to manage DIY package state.
- API: Adds
- Integrates new UI components for DIY packages:
- DIYSection Component: Renders the DIY package section on relevant pages.
- DIYPackageCard Component: Displays individual DIY package details.
- Updates main restaurant page components to include and render the new DIY section.
- Data flows from fetching via API, through service and store, to rendering in the UI.
[
github.com
https://github.com/hungryhub-team/hh-pegasus/pull/1934/files
](https://github.com/hungryhub-team/hh-pegasus/pull/1934/files)
Partner Portal Implementation
- Added
DIY(Do-It-Yourself) package type across booking, billing, and package features. - All relevant components, filters, pages, and state stores now support
DIYpackage type. - Displays DIY package sections and quantities in the booking table.
- Enhanced booking/payment details modal component, supports new package logic.
- Added new option for
"diy"package type to filters. - Ensured short type logic and translations support DIY.
- Updated filter arrays and logic to include DIY.
- "DIY Set" or similar translation added everywhere.
- Added support for DIY package display and color/visuals (
BillingPage.vue,BillingPage.scss,ListPackageType.vue). - Store now tracks and handles DIY packages.
- Logic updated to process selected packages, promos, add-ons, and vouchers for DIY type.
- Displays DIY package details if present.
- Uses new modal and menu components for DIY details.
- Icon logic now includes "icon-yellow" for DIY.
- Added DIY package filter and title support.
- Project version updated to 1.38.0.
- Dependencies updated (e.g.,
axios,nanoid,start-server-and-test, etc.). -
- A new helper function called
getPricehas been added. This function determines how the price should be displayed based on the package type and other attributes.
- A new helper function called
- If the package is not a DIY package (
packageTypeShortnot "diy"), it returns the regularnetPrice. - If the package is a DIY package:
- If there is a spending tier discount (
hasSpendingTierDiscountis true), it returns a string showing the minimum spend required, formatted asMin. Spend {minSpending.format}(or "-" if the format isn't available). - If there is no spending tier discount, it returns
"No Min. Spend".
- If there is a spending tier discount (
- If there is a spending tier discount, the price displays as "Min. Spend {amount}".
- If there is no discount, the price displays as "No Min. Spend".
- Fixes issues with how kids' pricing add-ons are displayed in booking summaries.
- Corrects the summary calculations and display for prepaid DIY package bookings.
- Ensures that "Party Pack" options are now correctly shown in booking summaries.
- Addresses problems with how DIY package pricing is handled and displayed, including fixes for package type recognition and summary calculations.
- Introduces a new booking form feature for DIY packages, allowing users to customize their package selection and view the corresponding price summary dynamically.
[
github.com
https://github.com/hungryhub-team/book-bite/pull/938/files
](https://github.com/hungryhub-team/book-bite/pull/938/files)
[
github.com
https://github.com/hungryhub-team/book-bite/pull/939/files
](https://github.com/hungryhub-team/book-bite/pull/939/files)
[
github.com
https://github.com/hungryhub-team/book-bite/pull/949/files
](https://github.com/hungryhub-team/book-bite/pull/949/files)
PRD & Task
PRD: Private (https://app.clickup.com/9003122396/docs/8ca1fpw-7922/8ca1fpw-52796) Private (https://app.clickup.com/t/86czp511g)
Design
[
www.figma.com
https://www.figma.com/design/OgKr4mU73xB8ZBOFv3vNy2/DIY-Set?node-id=56-13394&t=l3OFyJGFaVAtqho1-1
](https://www.figma.com/design/OgKr4mU73xB8ZBOFv3vNy2/DIY-Set?node-id=56-13394&t=l3OFyJGFaVAtqho1-1)
API Blueprint
| Method | Path | URL | Description | Payload |
|---|---|---|---|---|
New Query
DB Schema / Database Migration
- Creates a new table
hh_package_package_diyswith fields for reservation duration, menu links, commission, pricing, and other package-specific configs. - Adds new columns to the
hh_package_pricingstable to support minimum spending features and spending tier discounts.- Columns include
require_min_spending,min_spending_type,min_spending_cents,min_spending_currency,has_spending_tier_discount,spending_tier_unit,spending_tier_discount_type.
- Columns include
- Adds a new table
hh_package_pricing_spending_tiersfor tiered pricing on packages. Fields include package reference, name, price, currency, and discount value. - Adds a table
hh_package_pricing_menusto manage menu-related pricing within packages. Fields for package references, section details, price points, and currency. - Adds a table
reservation_group_sectionsfor grouping reservations with menu/pricing sections. - Adds a new JSON column
selected_packages_datatopartners_reservation_summaries. Allows storing structured data about selected packages for partner reservation summaries. -
Improvement:
| Feature Name | Date | What Changed | Description |
|---|---|---|---|