From 49b0ab0e1f7d96e58ffe474c32bba60e16f19201 Mon Sep 17 00:00:00 2001 From: Pranav Date: Thu, 2 Jul 2026 01:03:22 -0700 Subject: [PATCH] fix: Consider business hours when computing SLA breaches (#13392) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fixes SLA breach computation to respect the "Only during business hours" setting - Backend now pre-computes SLA deadlines, simplifying frontend logic ## How it works Before: SLA deadlines were calculated using wall-clock time, ignoring business hours. After: When an SLA policy has "Only during business hours" enabled and the inbox has working hours configured, the deadline is calculated by adding threshold time only during business hours. **How you check if a conversation has a SLA hit or miss?** Screenshot 2026-01-28 at 7 06 53 PM **Example:** - Conversation created: Friday 4:30 PM - FRT threshold: 1 hour - Business hours: Mon-Fri 9 AM - 5 PM | | Breach time | |--|--| | Before | Friday 5:30 PM | | After | Monday 9:30 AM | ## Test plan - [x] Create an SLA policy with "Only during business hours" enabled - [x] Configure inbox with business hours (e.g., Mon-Fri 9-5) - [x] Conversation created during business hours - Create a conversation on Wednesday 10:00 AM UTC - Expected: FRT deadline shows Wednesday 12:00 PM UTC (2 business hours later) - [x] Conversation created before business hours - Create a conversation on Wednesday 7:00 AM UTC - Expected: FRT deadline shows Wednesday 11:00 AM UTC (counting starts at 9 AM) - [x] Conversation created after business hours - Create a conversation on Wednesday 6:00 PM UTC - Expected: FRT deadline shows Thursday 11:00 AM UTC (counting starts next day 9 AM) - [x] Conversation created on weekend - Create a conversation on Saturday 10:00 AM UTC - Expected: FRT deadline shows Monday 11:00 AM UTC (skips weekend) - [x] Threshold spans weekend - Create a conversation on Friday 4:00 PM UTC with 2-hour FRT - Expected: FRT deadline shows Monday 10:00 AM UTC (1h Friday + 1h Monday) - [x] SLA without business hours - Create an SLA policy with only_during_business_hours: false - Create a conversation on Friday 4:00 PM UTC with 2-hour FRT - Expected: FRT deadline shows Friday 6:00 PM UTC (wall-clock time) - [x] All Day marked as closed_all_day - Create a conversation on Tuesday 4:00 PM UTC with 2-hour FRT - Expected: FRT deadline shows Thursday 10:00 AM UTC - [x] All Day marked as open_all_day - Create a conversation on Saturday 10:00 AM UTC with 2-hour FRT - Expected: FRT deadline shows Saturday 12:00 PM UTC - [x] UI displays correct countdown - Verify conversation card shows correct SLA timer - Verify timer shows flame icon when breached - Verify timer shows alarm icon when within threshold - Time updates automatically when time passes - [x] Verify the breach with a different timezone than your local timezone --------- Co-authored-by: Muhsin Keloth Co-authored-by: Sojan Jose Co-authored-by: Sony Mathew Co-authored-by: Sony Mathew <2040199+sony-mathew@users.noreply.github.com> --- .../ConversationCard/SLACardLabel.vue | 15 +- .../Conversation/Sla/SLACardLabel.vue | 4 +- .../conversation/components/SLACardLabel.vue | 3 +- app/javascript/dashboard/helper/slaHelper.js | 150 ++++++ .../dashboard/helper/specs/slaHelper.spec.js | 450 ++++++++++++++++++ .../finders/enterprise/conversation_finder.rb | 4 +- enterprise/app/models/applied_sla.rb | 59 ++- .../services/sla/business_hours_service.rb | 108 +++++ .../sla/evaluate_applied_sla_service.rb | 155 +++--- .../api/v1/models/_applied_sla.json.jbuilder | 4 + spec/enterprise/models/applied_sla_spec.rb | 119 ++++- .../sla/business_hours_service_spec.rb | 184 +++++++ .../sla/evaluate_applied_sla_service_spec.rb | 73 ++- 13 files changed, 1228 insertions(+), 100 deletions(-) create mode 100644 app/javascript/dashboard/helper/slaHelper.js create mode 100644 app/javascript/dashboard/helper/specs/slaHelper.spec.js create mode 100644 enterprise/app/services/sla/business_hours_service.rb create mode 100644 spec/enterprise/services/sla/business_hours_service_spec.rb diff --git a/app/javascript/dashboard/components-next/Conversation/ConversationCard/SLACardLabel.vue b/app/javascript/dashboard/components-next/Conversation/ConversationCard/SLACardLabel.vue index ff57d6c93..608bd84bd 100644 --- a/app/javascript/dashboard/components-next/Conversation/ConversationCard/SLACardLabel.vue +++ b/app/javascript/dashboard/components-next/Conversation/ConversationCard/SLACardLabel.vue @@ -1,6 +1,6 @@