@@ -15,6 +15,8 @@ import com.woocommerce.android.ui.bookings.compose.BookingSummaryModel
1515import com.woocommerce.android.ui.bookings.details.CancelStatus
1616import com.woocommerce.android.ui.bookings.list.BookingListItem
1717import com.woocommerce.android.util.CurrencyFormatter
18+ import com.woocommerce.android.util.normalizeDuration
19+ import com.woocommerce.android.util.toHumanReadableFormat
1820import com.woocommerce.android.viewmodel.ResourceProvider
1921import kotlinx.coroutines.Dispatchers
2022import kotlinx.coroutines.withContext
@@ -65,8 +67,8 @@ class BookingMapper @Inject constructor(
6567 cancelStatus : CancelStatus ,
6668 ): BookingAppointmentDetailsModel {
6769 val duration = Duration .between(start, end)
68- .normalizeBookingDuration ()
69- .toHumanReadableFormat()
70+ .normalizeDuration ()
71+ .toHumanReadableFormat(resourceProvider )
7072 return BookingAppointmentDetailsModel (
7173 date = detailsDateFormatter.format(start),
7274 time = " ${timeRangeFormatter.format(start)} - ${timeRangeFormatter.format(end)} " ,
@@ -135,77 +137,6 @@ class BookingMapper @Inject constructor(
135137 )
136138 }
137139
138- /* *
139- * Normalize booking duration by adjusting for precision issues.
140- *
141- * This function handles cases where a booking duration is very close to
142- * common time boundaries (days/hours) but falls short due to precision issues.
143- * It rounds up durations that are within one minute of these boundaries.
144- */
145- private fun Duration.normalizeBookingDuration (): Duration {
146- val dayInSeconds = Duration .ofDays(1 ).seconds
147- val hourInSeconds = Duration .ofHours(1 ).seconds
148- val minuteInSeconds = Duration .ofMinutes(1 ).seconds
149-
150- var durationInSeconds = this .seconds
151- val boundaries = listOf (dayInSeconds, hourInSeconds)
152- for (boundary in boundaries) {
153- val remainder = durationInSeconds % boundary
154- val difference = if (remainder == 0L ) 0L else boundary - remainder
155- if (difference > 0 && difference <= minuteInSeconds) {
156- durationInSeconds + = difference
157- }
158- }
159- return Duration .ofSeconds(durationInSeconds)
160- }
161-
162- @Suppress(" LongMethod" )
163- private fun Duration.toHumanReadableFormat (): String {
164- if (this < Duration .ofMinutes(1 )) {
165- return resourceProvider.getQuantityString(
166- quantity = seconds.toInt(),
167- default = R .string.booking_duration_seconds,
168- one = R .string.booking_duration_second
169- )
170- }
171-
172- val days = toDays()
173- val hours = minusDays(days).toHours()
174- val minutes = minusDays(days).minusHours(hours).toMinutes()
175-
176- return buildString {
177- if (days > 0 ) {
178- append(
179- resourceProvider.getQuantityString(
180- quantity = days.toInt(),
181- default = R .string.booking_duration_days,
182- one = R .string.booking_duration_day
183- )
184- )
185- }
186- if (hours > 0 ) {
187- append(" " )
188- append(
189- resourceProvider.getQuantityString(
190- quantity = hours.toInt(),
191- default = R .string.booking_duration_hours,
192- one = R .string.booking_duration_hour
193- )
194- )
195- }
196- if (minutes > 0 ) {
197- append(" " )
198- append(
199- resourceProvider.getQuantityString(
200- quantity = minutes.toInt(),
201- default = R .string.booking_duration_minutes,
202- one = R .string.booking_duration_minute
203- )
204- )
205- }
206- }.trim()
207- }
208-
209140 private suspend fun BookingCustomerInfo.address (): Address ? {
210141 val countryCode = billingCountry ? : return null
211142 val (country, state) = withContext(Dispatchers .IO ) {
0 commit comments