Date Time Conditions
Complete guide to date/time-based pricing conditions.
Overview
Date time conditions define when a pricing rule applies. Each condition specifies a date_type that determines which fields are required and how the condition evaluates.
Location: app/models/date_time_condition.rb
Date Types
Defined in: DATE_TYPES constant
| date_type | Description | Required Fields | Uses condition_items |
|---|---|---|---|
everyday | Applies every day within rule period | action_type, value_type, value | ❌ No |
specific_date | Applies on specific dates | condition_items with date fields | ✅ Yes |
specific_time | Applies at specific times daily | condition_items with time fields | ✅ Yes |
specific_date_time | Applies on specific dates AND times | condition_items with date & time | ✅ Yes |
day_of_week | Applies on specific weekdays | days_of_week array | ❌ No |
day_time_of_week | Applies on specific weekdays AND times | days_of_week + condition_items with time | ✅ Yes |
Model Attributes
| Field | Type | Description | Required |
|---|---|---|---|
pricing_rule_id | Integer | Parent rule (FK) | ✅ Yes |
date_type | String | Type of condition (see Date Types) | ✅ Yes |
action_type | String | increase or decrease | Conditional |
value_type | String | percentage or fixed | Conditional |
value | Integer | Amount in basis points or cents | Conditional |
period_mode | String | single or range | ❌ No |
days_of_week | Integer[] | Day numbers (0=Sun, 6=Sat) | For day types |
Value Storage Format
IMPORTANT: Values are stored as integers:
- Percentage: Basis points (1% = 100 basis points)
- Fixed Amount: Cents (IDR)
Examples:
- 10% =
1000basis points - 25% =
2500basis points - IDR 5,000 =
500000cents - IDR 10,000 =
1000000cents
Action Types
Defined in: ACTION_TYPES constant
| Value | Description |
|---|---|
increase | Increase price by value |
decrease | Decrease price by value |
Value Types
Defined in: VALUE_TYPES constant
| Value | Description | Storage Unit |
|---|---|---|
percentage | Percentage adjustment | Basis points (1% = 100) |
fixed | Fixed amount adjustment | Cents |
Days of Week
Defined in: VALID_DAYS constant
Storage Format: Integer array (0-6)
| Integer | Day |
|---|---|
| 0 | Sunday |
| 1 | Monday |
| 2 | Tuesday |
| 3 | Wednesday |
| 4 | Thursday |
| 5 | Friday |
| 6 | Saturday |
String constants (validation only):
["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
API Usage: Send as integer array
{
"days_of_week": [0, 6] // Sunday and Saturday
}
Condition Items
Some date_types require condition_items (time slots):
Required for:
specific_datespecific_timespecific_date_timeday_time_of_week
Not required for:
everydayday_of_week
See: app/models/condition_item.rb
Condition Item Fields
| Field | Type | Used by |
|---|---|---|
start_date | Date | specific_date, specific_date_time |
end_date | Date | specific_date, specific_date_time |
start_time | Time | specific_time, specific_date_time, day_time_of_week |
end_time | Time | specific_time, specific_date_time, day_time_of_week |
Validations
Required Validations
date_type: Must be one of DATE_TYPESaction_type: Must beincreaseordecrease(if present)value_type: Must bepercentageorfixed(if present)value: Must be integer >= 0 (if present)
Custom Validations
- days_of_week_valid: If present, must be valid day numbers (0-6)
- days_of_week_required_for_day_types: Required for
day_of_weekandday_time_of_week - condition_items_required_for_slot_types: Required for types with slots
- action_configuration_complete: action_type, value_type, and value must all be present together
Scopes
By Date Type
DateTimeCondition.by_date_type('everyday')
DateTimeCondition.everyday
DateTimeCondition.specific_date
DateTimeCondition.specific_time
DateTimeCondition.specific_date_time
DateTimeCondition.day_of_week
DateTimeCondition.day_time_of_week
By Day
DateTimeCondition.for_day(0) # Sunday
DateTimeCondition.for_day(Date.today) # Today's weekday
Active
DateTimeCondition.active # Conditions from active rules
Helper Methods
condition.everyday? # Is everyday type?
condition.specific_date? # Is specific_date type?
condition.specific_time? # Is specific_time type?
condition.specific_date_time? # Is specific_date_time type?
condition.day_of_week? # Is day_of_week type?
condition.day_time_of_week? # Is day_time_of_week type?
condition.requires_slots? # Needs condition_items?
condition.uses_days_of_week? # Uses days_of_week field?
Example Payloads
1. Everyday (All Day, Every Day)
{
"date_type": "everyday",
"action_type": "increase",
"value_type": "percentage",
"value": 1000
}
2. Specific Date (Certain Dates Only)
{
"date_type": "specific_date",
"action_type": "increase",
"value_type": "percentage",
"value": 1500,
"condition_items_attributes": [
{
"start_date": "2025-01-15",
"end_date": "2025-01-15"
},
{
"start_date": "2025-02-14",
"end_date": "2025-02-14"
}
]
}
3. Specific Time (Daily Time Slots)
{
"date_type": "specific_time",
"action_type": "increase",
"value_type": "percentage",
"value": 2000,
"condition_items_attributes": [
{
"start_time": "11:00",
"end_time": "14:00"
},
{
"start_time": "18:00",
"end_time": "21:00"
}
]
}
4. Specific Date Time (Exact Date + Time)
{
"date_type": "specific_date_time",
"action_type": "decrease",
"value_type": "fixed",
"value": 500000,
"condition_items_attributes": [
{
"start_date": "2025-01-01",
"end_date": "2025-01-01",
"start_time": "10:00",
"end_time": "12:00"
}
]
}
5. Day of Week (Specific Weekdays, All Day)
{
"date_type": "day_of_week",
"days_of_week": [0, 6],
"action_type": "increase",
"value_type": "percentage",
"value": 1000
}
6. Day Time of Week (Specific Weekdays + Times)
{
"date_type": "day_time_of_week",
"days_of_week": [5, 6],
"action_type": "increase",
"value_type": "percentage",
"value": 1500,
"condition_items_attributes": [
{
"start_time": "18:00",
"end_time": "23:00"
}
]
}
Nested Attributes
Conditions accept nested attributes for condition_items:
accepts_nested_attributes_for :condition_items,
allow_destroy: true,
reject_if: :all_blank
Cache Invalidation
Callback: after_commit :invalidate_pricing_rule_cache
Automatically invalidates parent rule’s cache after:
- Create
- Update
- Destroy
Global Pricing Limits
All conditions are validated against restaurant’s global pricing limits:
Enforced at: PricingRule model level
Validation: validate_global_pricing_limits
Limits check:
- Increase/decrease values don’t exceed global limits
- Value type matches global limit type
See: 007-GLOBAL-PRICING-SETTINGS.md
Related Documentation
- 005-PRICING-RULES.md - Parent rule model
- 008-ENUM-REFERENCE.md - All enum values
- 004-API-ENDPOINTS.md - API endpoints