Skip to content

Commit

Permalink
fix: [ANDROAPP-6644] Display correct style for scheduled overdue even…
Browse files Browse the repository at this point in the history
…ts (#3896)

* fix: [ANDROAPP-6644] check if scheduled event is overdue and test implementation

* fix: [ANDROAPP-6644] manage icon for scheduled events correctly

* fix: [ANDROAPP-6644] invoke onDateValue changed after sdk update request, set overdue correctly from repository

* fix: [ANDROAPP-6644] resolve code smells

* fix: [ANDROAPP-6644] correct test
  • Loading branch information
xavimolloy authored Nov 27, 2024
1 parent 0be47dd commit 732b459
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import org.dhis2.commons.bindings.enrollment
import org.dhis2.commons.bindings.fromCache
import org.dhis2.commons.bindings.tei
import org.dhis2.commons.date.DateLabelProvider
import org.dhis2.commons.date.DateUtils
import org.dhis2.commons.date.toOverdueOrScheduledUiText
import org.dhis2.commons.resources.MetadataIconProvider
import org.dhis2.commons.resources.ResourceManager
Expand Down Expand Up @@ -41,6 +42,7 @@ class EventInfoProvider(
private val dateLabelProvider: DateLabelProvider,
private val metadataIconProvider: MetadataIconProvider,
private val profilePictureProvider: ProfilePictureProvider,
private val dateUtils: DateUtils,
) {
private val cachedPrograms = mutableMapOf<String, Program>()
private val cachedDisplayOrgUnit = mutableMapOf<String, Boolean>()
Expand Down Expand Up @@ -276,18 +278,19 @@ class EventInfoProvider(

EventStatus.SCHEDULE -> {
val text = dueDate.toOverdueOrScheduledUiText(resourceManager)

val color = if (dateUtils.isEventDueDateOverdue(dueDate)) AdditionalInfoItemColor.ERROR.color else AdditionalInfoItemColor.SUCCESS.color
val iconVector = if (dateUtils.isEventDueDateOverdue(dueDate)) Icons.Outlined.EventBusy else Icons.Outlined.Event
AdditionalInfoItem(
icon = {
Icon(
imageVector = Icons.Outlined.Event,
imageVector = iconVector,
contentDescription = text,
tint = AdditionalInfoItemColor.SUCCESS.color,
tint = color,
)
},
value = text,
isConstantItem = true,
color = AdditionalInfoItemColor.SUCCESS.color,
color = color,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,14 @@ class ProgramEventDetailModule(
resourceManager: ResourceManager,
metadataIconProvider: MetadataIconProvider,
profilePictureProvider: ProfilePictureProvider,
dateUtils: DateUtils,
) = EventInfoProvider(
d2,
resourceManager,
DateLabelProvider(context, resourceManager),
metadataIconProvider,
profilePictureProvider,
dateUtils,
)

@Provides
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ SearchRepositoryKt searchRepositoryKt(
DispatcherProvider dispatcherProvider,
FieldViewModelFactory fieldViewModelFactory,
MetadataIconProvider metadataIconProvider,
ColorUtils colorUtils
ColorUtils colorUtils,
DateUtils dateUtils
) {
ResourceManager resourceManager = new ResourceManager(moduleContext, colorUtils);
DateLabelProvider dateLabelProvider = new DateLabelProvider(moduleContext, new ResourceManager(moduleContext, colorUtils));
Expand All @@ -201,7 +202,8 @@ SearchRepositoryKt searchRepositoryKt(
resourceManager,
dateLabelProvider,
metadataIconProvider,
profilePictureProvider
profilePictureProvider,
dateUtils
)
);
}
Expand Down Expand Up @@ -323,6 +325,13 @@ SearchTeiViewModelFactory providesViewModelFactory(
);
}

@Provides
@PerActivity
DateUtils provideDateUtils(
) {
return DateUtils.getInstance();
}

@Provides
@PerActivity
ProgramConfigurationRepository provideProgramConfigurationRepository(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import org.dhis2.commons.data.ProgramConfigurationRepository;
import org.dhis2.commons.date.DateLabelProvider;
import org.dhis2.commons.date.DateUtils;
import org.dhis2.commons.di.dagger.PerActivity;
import org.dhis2.commons.di.dagger.PerFragment;
import org.dhis2.commons.resources.MetadataIconProvider;
import org.dhis2.commons.resources.ResourceManager;
Expand Down Expand Up @@ -96,7 +98,8 @@ RelationshipMapsRepository providesRepository(
D2 d2,
ResourceManager resourceManager,
MetadataIconProvider metadataIconProvider,
DateLabelProvider dateLabelProvider
DateLabelProvider dateLabelProvider,
DateUtils dateUtils
) {
RelationshipConfiguration config;
if (teiUid != null) {
Expand All @@ -119,7 +122,8 @@ RelationshipMapsRepository providesRepository(
resourceManager,
dateLabelProvider,
metadataIconProvider,
profilePictureProvider
profilePictureProvider,
dateUtils
)
);
}
Expand Down Expand Up @@ -155,6 +159,13 @@ RelationshipsViewModel provideRelationshipsViewModel(
);
}

@Provides
@PerFragment
DateUtils provideDateUtils(
) {
return DateUtils.getInstance();
}

@Provides
@PerFragment
GetRelationshipsByType provideGetRelationshipsByType(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class TEIDataModule(
d2: D2,
periodUtils: DhisPeriodUtils,
metadataIconProvider: MetadataIconProvider,
dateUtils: DateUtils,
): TeiDataRepository {
return TeiDataRepositoryImpl(
d2,
Expand All @@ -100,6 +101,7 @@ class TEIDataModule(
enrollmentUid,
periodUtils,
metadataIconProvider,
dateUtils,
)
}

Expand Down Expand Up @@ -165,8 +167,9 @@ class TEIDataModule(
@PerFragment
fun providesTEIEventCardMapper(
resourceManager: ResourceManager,
dateUtils: DateUtils,
): TEIEventCardMapper {
return TEIEventCardMapper(resourceManager)
return TEIEventCardMapper(resourceManager, dateUtils)
}

@Provides
Expand All @@ -191,5 +194,5 @@ class TEIDataModule(
fun provideD2ErrorUtils() = D2ErrorUtils(view.context, NetworkUtils(view.context))

@Provides
fun provideDateUtils() = DateUtils.getInstance()
fun provideDateUtils(): DateUtils = DateUtils.getInstance()
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class TeiDataRepositoryImpl(
private val enrollmentUid: String?,
private val periodUtils: DhisPeriodUtils,
private val metadataIconProvider: MetadataIconProvider,
private val dateUtils: DateUtils,
) : TeiDataRepository {

override fun getTEIEnrollmentEvents(
Expand Down Expand Up @@ -379,7 +380,7 @@ class TeiDataRepositoryImpl(
private fun checkEventStatus(events: List<Event>): List<Event> {
return events.mapNotNull { event ->
if (event.status() == EventStatus.SCHEDULE &&
event.dueDate()?.before(DateUtils.getInstance().today) == true
dateUtils.isEventDueDateOverdue(event.dueDate())
) {
d2.eventModule().events().uid(event.uid()).setStatus(EventStatus.OVERDUE)
d2.eventModule().events().uid(event.uid()).blockingGet()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import org.dhis2.R
import org.dhis2.commons.data.EventViewModel
import org.dhis2.commons.date.DateUtils
import org.dhis2.commons.date.toOverdueOrScheduledUiText
import org.dhis2.commons.resources.ResourceManager
import org.dhis2.commons.ui.model.ListCardUiModel
Expand All @@ -34,6 +35,7 @@ import java.util.Date

class TEIEventCardMapper(
val resourceManager: ResourceManager,
val dateUtils: DateUtils,
) {

fun map(
Expand Down Expand Up @@ -193,18 +195,19 @@ class TEIEventCardMapper(

EventStatus.SCHEDULE -> {
val text = dueDate.toOverdueOrScheduledUiText(resourceManager)

val color = if (dateUtils.isEventDueDateOverdue(dueDate)) AdditionalInfoItemColor.ERROR.color else AdditionalInfoItemColor.SUCCESS.color
val icon = if (dateUtils.isEventDueDateOverdue(dueDate)) Icons.Outlined.EventBusy else Icons.Outlined.Event
AdditionalInfoItem(
icon = {
Icon(
imageVector = Icons.Outlined.Event,
imageVector = icon,
contentDescription = text,
tint = AdditionalInfoItemColor.SUCCESS.color,
tint = color,
)
},
value = text,
isConstantItem = true,
color = AdditionalInfoItemColor.SUCCESS.color,
color = color,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,9 @@ class SchedulingViewModel(
d2.eventModule().events().uid(eventUid).run {
setDueDate(dueDate.currentDate)
setStatus(EventStatus.SCHEDULE)
onDueDateUpdated?.invoke()
}
}

onDueDateUpdated?.invoke()
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.dhis2.commons.date;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import java.util.Calendar;
import java.util.Date;

public class DateUtilsTest {


@Test
public void returnsEventOverDueDateCorrectly() {

Calendar calendar = Calendar.getInstance();
//should return false for current date
calendar.setTime(new Date());
assertFalse(DateUtils.getInstance().isEventDueDateOverdue(calendar.getTime()));
//false for future date
calendar.add(Calendar.DAY_OF_MONTH, 10);
assertFalse(DateUtils.getInstance().isEventDueDateOverdue(calendar.getTime()));
//true for past dates
calendar.add(Calendar.DAY_OF_MONTH, -30);
assertTrue(DateUtils.getInstance().isEventDueDateOverdue(calendar.getTime()));

}
}
13 changes: 13 additions & 0 deletions commons/src/main/java/org/dhis2/commons/date/DateUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,19 @@ public Boolean isEventExpired(@Nullable Date currentDate, Date completedDay, int
completedDay.getTime() + TimeUnit.DAYS.toMillis(compExpDays) < date.getTime();
}

/**
* Check if an event due date is overdue
*
* @param dueDate the date the event is due
* @return true or false
*/
public Boolean isEventDueDateOverdue(Date dueDate) {
Date currentDate = getStartOfDay(new Date());
if(dueDate.equals(currentDate)) return false;
return dueDate.before(currentDate);
}


/**
* @param currentDate Date from which calculation will be carried out. Default value is today.
* @param expiryDays Number of extra days to add events on previous period
Expand Down

0 comments on commit 732b459

Please sign in to comment.