Skip to content

Commit 71e95f7

Browse files
committed
ensure that whether weekdays collide is only checked for opening hours that are otherwise supported (fixes #6715)
1 parent 64a28dd commit 71e95f7

File tree

4 files changed

+49
-22
lines changed

4 files changed

+49
-22
lines changed

app/src/androidMain/kotlin/de/westnordost/streetcomplete/quests/opening_hours/AddOpeningHours.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import de.westnordost.streetcomplete.data.quest.AndroidQuest
1313
import de.westnordost.streetcomplete.data.user.achievements.EditTypeAchievement.CITIZEN
1414
import de.westnordost.streetcomplete.osm.Tags
1515
import de.westnordost.streetcomplete.osm.isPlaceOrDisusedPlace
16-
import de.westnordost.streetcomplete.osm.opening_hours.isLikelyIncorrect
1716
import de.westnordost.streetcomplete.osm.opening_hours.isSupported
1817
import de.westnordost.streetcomplete.osm.opening_hours.toOpeningHours
1918
import de.westnordost.streetcomplete.osm.updateCheckDateForKey
@@ -184,8 +183,7 @@ mapOf(
184183
// invalid opening_hours rules -> applicable because we want to ask for opening hours again
185184
// be strict
186185
val oh = ohStr.toOpeningHoursOrNull(lenient = false) ?: return true
187-
// only display supported rules, or ambiguous rules that should be corrected
188-
return oh.isSupported(allowTimePoints = false) || oh.isLikelyIncorrect()
186+
return oh.isSupported(allowTimePoints = false, allowAmbiguity = true)
189187
}
190188

191189
override fun getHighlightedElements(element: Element, getMapData: () -> MapDataWithGeometry) =

app/src/androidMain/kotlin/de/westnordost/streetcomplete/quests/postbox_collection_times/AddPostboxCollectionTimes.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import de.westnordost.streetcomplete.data.quest.AndroidQuest
1212
import de.westnordost.streetcomplete.data.quest.NoCountriesExcept
1313
import de.westnordost.streetcomplete.data.user.achievements.EditTypeAchievement.POSTMAN
1414
import de.westnordost.streetcomplete.osm.Tags
15-
import de.westnordost.streetcomplete.osm.opening_hours.isLikelyIncorrect
1615
import de.westnordost.streetcomplete.osm.opening_hours.isSupported
1716
import de.westnordost.streetcomplete.osm.opening_hours.toOpeningHours
1817
import de.westnordost.streetcomplete.osm.updateWithCheckDate
@@ -81,7 +80,7 @@ class AddPostboxCollectionTimes : OsmElementQuestType<CollectionTimesAnswer>, An
8180
// be strict
8281
val oh = ct.toOpeningHoursOrNull(lenient = false) ?: return true
8382
// only display supported rules, or ambiguous rules that should be corrected
84-
return oh.isSupported(allowTimePoints = true) || oh.isLikelyIncorrect()
83+
return oh.isSupported(allowTimePoints = true, allowAmbiguity = true)
8584
}
8685

8786
override fun getHighlightedElements(element: Element, getMapData: () -> MapDataWithGeometry) =

app/src/androidUnitTest/kotlin/de/westnordost/streetcomplete/quests/opening_hours/AddOpeningHoursTest.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,4 +350,16 @@ class AddOpeningHoursTest {
350350
timestamp = "2000-11-11".toCheckDate()?.toEpochMilli()
351351
)))
352352
}
353+
354+
@Test fun `isApplicableTo returns false for valid but not supported opening hours with ranges that are also colliding`() {
355+
val millisecondsFor400Days: Long = 1000L * 60 * 60 * 24 * 400
356+
assertFalse(questType.isApplicableTo(node(
357+
tags = mapOf(
358+
"shop" to "sports",
359+
"name" to "Atze's Angelladen",
360+
"opening_hours" to "\"by appointment, see timetable\"; PH \"by appointment\""
361+
),
362+
timestamp = nowAsEpochMilliseconds() - millisecondsFor400Days
363+
)))
364+
}
353365
}

app/src/commonMain/kotlin/de/westnordost/streetcomplete/osm/opening_hours/OpeningHoursValidator.kt

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -36,28 +36,43 @@ import kotlin.jvm.JvmName
3636
* - "off" rules with exclusively weekdays, weekday ranges, PH
3737
* - clock time spans with optional open end, or clock time points
3838
*
39-
* Weekdays that collide (Mo-Fr 8:30-12:30; We 14:00-18:00) are not supported - they are likely
40-
* tagging mistakes (Maybe user meant to use "," instead of ";"?).
39+
* Weekdays that collide (Mo-Fr 8:30-12:30; We 14:00-18:00) are considered ambiguous - they are
40+
* likely tagging mistakes (Maybe user meant to use "," instead of ";"?).
4141
*
42-
* Also, when any rule has months defined, all rules must have months defined, for clarity.
42+
* Also, when any rule has months defined, all rules must have months defined, for clarity,
43+
* otherwise they are not supported at all (not even considered ambiguous, see code comment below)
4344
*/
44-
fun OpeningHours.isSupported(allowTimePoints: Boolean = false): Boolean =
45+
fun OpeningHours.isSupported(
46+
allowTimePoints: Boolean = false,
47+
allowAmbiguity: Boolean = false,
48+
): Boolean =
4549
rules.all { rule -> rule.isSupported() } &&
4650
(allowTimePoints || !containsTimePoints()) &&
47-
!rules.hasCollidingWeekdays() &&
51+
(allowAmbiguity || !rules.hasCollidingWeekdays()) &&
52+
/*
53+
in #6175 we decided to not classify opening hours that have incomplete months as
54+
ambiguous (=> ask user to clarify) and instead just don't support them at all. Reason:
55+
56+
Ambiguous opening hours are treated the same as invalid opening hours: they are not shown
57+
to the user in the widget, as if they haven't been defined at all yet. Apart from
58+
implementation effort, the reason for not displaying those at all is that the widget
59+
doesn't show the difference between ";" (overwriting) and "," (additive) rules which are
60+
usually the cause for the ambiguity. So, users would be unable to detect that something is
61+
wrong with the currently mapped opening hours if they were displayed.
62+
63+
E.g.
64+
`Mo-We 10:00-12:00; Tu 14:00-18:00` would be displayed the same as
65+
`Mo-We 10:00-12:00, Tu 14:00-18:00` while the first is likely a mistake (and if it is not,
66+
writing `Mo,We 10:00-12:00; Tu 14:00-18:00` would be not ambiguous)
67+
68+
For ambiguous opening hours with incomplete months like
69+
`10:00-12:00; Apr-Sep 14:00-18:00` in particular, the concern has been that the user might
70+
input only the hours for summer or only for winter in case the opening hours plates are
71+
just swapped twice a year by the shop since he is unable to see in the app what was
72+
already mapped.
73+
*/
4874
!rules.hasIncompleteMonths()
4975

50-
/** Return whether the given valid opening hours are however ambiguous and thus should be corrected.
51-
* */
52-
fun OpeningHours.isLikelyIncorrect(): Boolean =
53-
// in #6175 we decided to not classify opening hours that have incomplete months as ambiguous
54-
// (but just don't support them at all), mainly due to fears that if the previous opening hours
55-
// like e.g. "12:00-18:00; Nov-Feb 12:00-14:00" are not shown in the opening hours widget, the
56-
// user might input only the hours for summer or only for winter in case the opening hours
57-
// plates are just swapped twice a year by the shop. (Showing those to the user would somewhat
58-
// keep the user from overwriting, but they can't be shown because they are unsupported)
59-
rules.hasCollidingWeekdays()
60-
6176
fun Rule.isSupported(): Boolean =
6277
// comments not supported
6378
comment == null &&
@@ -145,7 +160,10 @@ private fun Range.hasMonths(): Boolean =
145160

146161
/** For example, "Mo-Fr 10:00-12:00; We 14:00-16:00" self-collides: Wednesday is overwritten
147162
* to only be open 14:00 to 16:00. A rule collides with another whenever the days overlap. When
148-
* non-additive rules and additive rules mix, it becomes a bit difficult to find it out */
163+
* non-additive rules and additive rules mix, it becomes a bit difficult to find it out
164+
*
165+
* @throws IllegalArgumentException if any of the rules is not supported
166+
* */
149167
fun List<Rule>.hasCollidingWeekdays(): Boolean {
150168
for (i in indices) {
151169
val rule1 = get(i)

0 commit comments

Comments
 (0)