diff --git a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json
index 27172cdba..538d6d5f0 100644
--- a/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json
+++ b/app/javascript/dashboard/i18n/locale/en/inboxMgmt.json
@@ -463,7 +463,8 @@
"HOURS": "hours",
"VALIDATION_ERROR": "Starting time should be before closing time.",
"CHOOSE": "Choose"
- }
+ },
+ "ALL_DAY":"All-Day"
},
"IMAP": {
"TITLE": "IMAP",
diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/components/BusinessDay.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/components/BusinessDay.vue
index a0701e2cb..119dd149a 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/inbox/components/BusinessDay.vue
+++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/components/BusinessDay.vue
@@ -4,7 +4,7 @@
@@ -14,26 +14,38 @@
+
+
+ {{ $t('INBOX_MGMT.BUSINESS_HOURS.ALL_DAY') }}
+
@@ -79,9 +91,14 @@ export default {
},
},
computed: {
- timeSlots() {
+ fromTimeSlots() {
return timeSlots;
},
+ toTimeSlots() {
+ return timeSlots.filter(slot => {
+ return slot !== '12:00 AM';
+ });
+ },
isDayEnabled: {
get() {
return this.timeSlot.from && this.timeSlot.to;
@@ -93,12 +110,14 @@ export default {
from: timeSlots[0],
to: timeSlots[16],
valid: true,
+ openAllDay: false,
}
: {
...this.timeSlot,
from: '',
to: '',
valid: false,
+ openAllDay: false,
};
this.$emit('update', newSlot);
},
@@ -146,15 +165,39 @@ export default {
return parse(this.toTime, 'hh:mm a', new Date());
},
totalHours() {
- const totalHours = differenceInMinutes(this.toDate, this.fromDate) / 60;
- if (this.toTime === '12:00 AM') {
- return 24 + totalHours;
+ if (this.timeSlot.openAllDay) {
+ return 24;
}
+ const totalHours = differenceInMinutes(this.toDate, this.fromDate) / 60;
return totalHours;
},
hasError() {
return !this.timeSlot.valid;
},
+ isOpenAllDay: {
+ get() {
+ return this.timeSlot.openAllDay;
+ },
+ set(value) {
+ if (value) {
+ this.$emit('update', {
+ ...this.timeSlot,
+ from: '12:00 AM',
+ to: '11:59 PM',
+ valid: true,
+ openAllDay: value,
+ });
+ } else {
+ this.$emit('update', {
+ ...this.timeSlot,
+ from: '09:00 AM',
+ to: '05:00 PM',
+ valid: true,
+ openAllDay: value,
+ });
+ }
+ },
+ },
},
};
@@ -182,7 +225,7 @@ export default {
box-sizing: content-box;
border-bottom: 1px solid var(--color-border-light);
}
-.enable-day {
+.enable-checkbox {
margin: 0;
}
@@ -240,4 +283,17 @@ export default {
font-size: var(--font-size-mini);
color: var(--r-300);
}
+
+.open-all-day {
+ margin-right: var(--space-medium);
+ span {
+ font-size: var(--font-size-small);
+ font-weight: var(--font-weight-medium);
+ margin-left: var(--space-smaller);
+ }
+ input {
+ font-size: var(--font-size-small);
+ font-weight: var(--font-weight-medium);
+ }
+}
diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/helpers/businessHour.js b/app/javascript/dashboard/routes/dashboard/settings/inbox/helpers/businessHour.js
index 2bd9a281a..69089bf3c 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/inbox/helpers/businessHour.js
+++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/helpers/businessHour.js
@@ -86,6 +86,7 @@ export const timeSlotParse = timeSlots => {
close_hour: closeHour,
close_minutes: closeMinutes,
closed_all_day: closedAllDay,
+ open_all_day: openAllDay,
} = slot;
const from = closedAllDay ? '' : getTime(openHour, openMinutes);
const to = closedAllDay ? '' : getTime(closeHour, closeMinutes);
@@ -95,13 +96,15 @@ export const timeSlotParse = timeSlots => {
to,
from,
valid: !closedAllDay,
+ openAllDay,
};
});
};
export const timeSlotTransform = timeSlots => {
return timeSlots.map(slot => {
- const closed = !(slot.to && slot.from);
+ const closed = slot.openAllDay ? false : !(slot.to && slot.from);
+ const openAllDay = slot.openAllDay;
let fromDate = '';
let toDate = '';
let openHour = '';
@@ -125,6 +128,7 @@ export const timeSlotTransform = timeSlots => {
open_minutes: openMinutes,
close_hour: closeHour,
close_minutes: closeMinutes,
+ open_all_day: openAllDay,
};
});
};
diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/helpers/specs/businessHour.spec.js b/app/javascript/dashboard/routes/dashboard/settings/inbox/helpers/specs/businessHour.spec.js
index d6534cb5e..077337ae6 100644
--- a/app/javascript/dashboard/routes/dashboard/settings/inbox/helpers/specs/businessHour.spec.js
+++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/helpers/specs/businessHour.spec.js
@@ -40,6 +40,7 @@ describe('#timeSlotParse', () => {
close_hour: 4,
close_minutes: 30,
closed_all_day: false,
+ open_all_day: false,
};
expect(timeSlotParse([slot])).toStrictEqual([
@@ -48,6 +49,7 @@ describe('#timeSlotParse', () => {
from: '01:30 AM',
to: '04:30 AM',
valid: true,
+ openAllDay: false,
},
]);
});
@@ -60,6 +62,7 @@ describe('#timeSlotTransform', () => {
from: '01:30 AM',
to: '04:30 AM',
valid: true,
+ openAllDay: false,
};
expect(timeSlotTransform([slot])).toStrictEqual([
@@ -70,6 +73,7 @@ describe('#timeSlotTransform', () => {
close_hour: 4,
close_minutes: 30,
closed_all_day: false,
+ open_all_day: false,
},
]);
});
diff --git a/app/javascript/widget/mixins/availability.js b/app/javascript/widget/mixins/availability.js
index 730c09c95..c797f79e4 100644
--- a/app/javascript/widget/mixins/availability.js
+++ b/app/javascript/widget/mixins/availability.js
@@ -31,9 +31,12 @@ export default {
closeHour,
closeMinute,
closedAllDay,
+ openAllDay,
} = this.currentDayAvailability;
const { utcOffset } = this.channelConfig;
+ if (openAllDay) return true;
+
if (closedAllDay) return false;
const startTime = buildDateFromTime(openHour, openMinute, utcOffset);
@@ -56,6 +59,7 @@ export default {
openMinute: workingHourConfig.open_minutes,
closeHour: workingHourConfig.close_hour,
closeMinute: workingHourConfig.close_minutes,
+ openAllDay: workingHourConfig.open_all_day,
};
},
isInBusinessHours() {
diff --git a/app/models/concerns/out_of_offisable.rb b/app/models/concerns/out_of_offisable.rb
index e22dd668c..f1753a5f8 100644
--- a/app/models/concerns/out_of_offisable.rb
+++ b/app/models/concerns/out_of_offisable.rb
@@ -3,7 +3,7 @@
module OutOfOffisable
extend ActiveSupport::Concern
- OFFISABLE_ATTRS = %w[day_of_week closed_all_day open_hour open_minutes close_hour close_minutes].freeze
+ OFFISABLE_ATTRS = %w[day_of_week closed_all_day open_hour open_minutes close_hour close_minutes open_all_day].freeze
included do
has_many :working_hours, dependent: :destroy_async
@@ -29,7 +29,8 @@ module OutOfOffisable
# "open_hour"=>9,
# "open_minutes"=>0,
# "close_hour"=>17,
- # "close_minutes"=>0},...]
+ # "close_minutes"=>0,
+ # "open_all_day=>false" },...]
def update_working_hours(params)
ActiveRecord::Base.transaction do
params.each do |working_hour|
@@ -41,12 +42,12 @@ module OutOfOffisable
private
def create_default_working_hours
- working_hours.create!(day_of_week: 0, closed_all_day: true)
- working_hours.create!(day_of_week: 1, open_hour: 9, open_minutes: 0, close_hour: 17, close_minutes: 0)
- working_hours.create!(day_of_week: 2, open_hour: 9, open_minutes: 0, close_hour: 17, close_minutes: 0)
- working_hours.create!(day_of_week: 3, open_hour: 9, open_minutes: 0, close_hour: 17, close_minutes: 0)
- working_hours.create!(day_of_week: 4, open_hour: 9, open_minutes: 0, close_hour: 17, close_minutes: 0)
- working_hours.create!(day_of_week: 5, open_hour: 9, open_minutes: 0, close_hour: 17, close_minutes: 0)
- working_hours.create!(day_of_week: 6, closed_all_day: true)
+ working_hours.create!(day_of_week: 0, closed_all_day: true, open_all_day: false)
+ working_hours.create!(day_of_week: 1, open_hour: 9, open_minutes: 0, close_hour: 17, close_minutes: 0, open_all_day: false)
+ working_hours.create!(day_of_week: 2, open_hour: 9, open_minutes: 0, close_hour: 17, close_minutes: 0, open_all_day: false)
+ working_hours.create!(day_of_week: 3, open_hour: 9, open_minutes: 0, close_hour: 17, close_minutes: 0, open_all_day: false)
+ working_hours.create!(day_of_week: 4, open_hour: 9, open_minutes: 0, close_hour: 17, close_minutes: 0, open_all_day: false)
+ working_hours.create!(day_of_week: 5, open_hour: 9, open_minutes: 0, close_hour: 17, close_minutes: 0, open_all_day: false)
+ working_hours.create!(day_of_week: 6, closed_all_day: true, open_all_day: false)
end
end
diff --git a/app/models/working_hour.rb b/app/models/working_hour.rb
index 890a452ba..885165da2 100644
--- a/app/models/working_hour.rb
+++ b/app/models/working_hour.rb
@@ -7,6 +7,7 @@
# close_minutes :integer
# closed_all_day :boolean default(FALSE)
# day_of_week :integer not null
+# open_all_day :boolean default(FALSE)
# open_hour :integer
# open_minutes :integer
# created_at :datetime not null
@@ -22,6 +23,7 @@
class WorkingHour < ApplicationRecord
belongs_to :inbox
+ before_validation :ensure_open_all_day_hours
before_save :assign_account
validates :open_hour, presence: true, unless: :closed_all_day?
@@ -35,6 +37,7 @@ class WorkingHour < ApplicationRecord
validates :close_minutes, inclusion: 0..59, unless: :closed_all_day?
validate :close_after_open, unless: :closed_all_day?
+ validate :open_all_day_and_closed_all_day
def self.today
find_by(day_of_week: Date.current.wday)
@@ -69,4 +72,19 @@ class WorkingHour < ApplicationRecord
errors.add(:close_hour, 'Closing time cannot be before opening time')
end
+
+ def ensure_open_all_day_hours
+ return unless open_all_day?
+
+ self.open_hour = 0
+ self.open_minutes = 0
+ self.close_hour = 23
+ self.close_minutes = 59
+ end
+
+ def open_all_day_and_closed_all_day
+ return unless open_all_day? && closed_all_day?
+
+ errors.add(:base, 'open_all_day and closed_all_day cannot be true at the same time')
+ end
end
diff --git a/db/migrate/20220216151613_add_open_all_day_to_working_hour.rb b/db/migrate/20220216151613_add_open_all_day_to_working_hour.rb
new file mode 100644
index 000000000..138f6edb6
--- /dev/null
+++ b/db/migrate/20220216151613_add_open_all_day_to_working_hour.rb
@@ -0,0 +1,5 @@
+class AddOpenAllDayToWorkingHour < ActiveRecord::Migration[6.1]
+ def change
+ add_column :working_hours, :open_all_day, :boolean, default: false
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index c1cd951ab..8c37b7897 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -773,6 +773,7 @@ ActiveRecord::Schema.define(version: 2022_02_18_120357) do
t.integer "close_minutes"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
+ t.boolean "open_all_day", default: false
t.index ["account_id"], name: "index_working_hours_on_account_id"
t.index ["inbox_id"], name: "index_working_hours_on_inbox_id"
end
diff --git a/spec/models/working_hour_spec.rb b/spec/models/working_hour_spec.rb
index 73cb4efdf..c126f6f87 100644
--- a/spec/models/working_hour_spec.rb
+++ b/spec/models/working_hour_spec.rb
@@ -50,4 +50,42 @@ RSpec.describe WorkingHour do
expect(described_class.today.closed_now?).to be true
end
end
+
+ context 'when open_all_day is true' do
+ let(:inbox) { create(:inbox) }
+
+ before do
+ Time.zone = 'UTC'
+ inbox.working_hours.find_by(day_of_week: 5).update(open_all_day: true)
+ travel_to '18.02.2022 11:00'.to_datetime
+ end
+
+ it 'updates open hour and close hour' do
+ expect(described_class.today.open_all_day?).to be true
+ expect(described_class.today.open_hour).to be 0
+ expect(described_class.today.open_minutes).to be 0
+ expect(described_class.today.close_hour).to be 23
+ expect(described_class.today.close_minutes).to be 59
+ end
+ end
+
+ context 'when open_all_day and closed_all_day true at the same time' do
+ let(:inbox) { create(:inbox) }
+
+ before do
+ Time.zone = 'UTC'
+ inbox.working_hours.find_by(day_of_week: 5).update(open_all_day: true)
+ travel_to '18.02.2022 11:00'.to_datetime
+ end
+
+ it 'throws validation error' do
+ working_hour = inbox.working_hours.find_by(day_of_week: 5)
+ working_hour.closed_all_day = true
+ expect(working_hour.invalid?).to be true
+ expect do
+ working_hour.save!
+ end.to raise_error(ActiveRecord::RecordInvalid,
+ 'Validation failed: open_all_day and closed_all_day cannot be true at the same time')
+ end
+ end
end