# 23th August Report ## Progress Time: **09:00** Event: Entering the lab --- ### Fixing data fetch filter for Future Mission Time: **10:00** - Problem found that if `RepairCallTime` attribute has different month then it will discarded. - There is wrong on back end code where it check the `DateOfMonth` (e.g. 1, 17, 31) of **missionTime** must above than **currentTime**, this logic error occured when it has Date above the currentTime but with DateOfMonth below than currentTime. - Example of this error: ``` currentTime: "2019-08-23 00:00:00" missionTime: "2019-09-02 00:00:00" currentTime : { "Year": 2019, "Month": 08, "DateOfMonth": 23 } missionTime : { "Year": 2019, "Month": 09, "DateOfMonth": 02 } ``` - The `currentTime` has greater Year and Month than `missionTime`. - The `currentTime` has lower DateOfMonth than `missionTime`. - Based on the logic the mission should be discarded because even though it has greater Year and Month but it has lower DateOfMonth - New update in **dispenser-api.service.ts**: ```typescript= async getAssignmentNext (employee_id: string, nowTime: string) { // get data from RepairCondition let data = await this.getRepairmanMissions(employee_id); let returnArray = []; // for every data will be filtered to get what have been done for (let i = 0 ; i < data.length ; i++) { let missionTime = UnitConverter.convertApiTimeToJson(data[i]['RepairCallTime']); let currentTime = UnitConverter.convertApiTimeToJson(nowTime); // check if it has greater year if (missionTime['Year'] > currentTime['Year']) { returnArray.push(data[i]); // check if it has greater month } else if (missionTime['Year'] === currentTime['Year']) { if (missionTime['Month'] > currentTime['Month']) { returnArray.push(data[i]); // check if it has greater date } else if (missionTime['Year'] === currentTime['Year']) { if (missionTime['Month'] === currentTime['Month']) { if (missionTime['DateOfMonth'] > currentTime['DateOfMonth']) { returnArray.push(data[i]); } } } } } return returnArray; } ``` - It has three conditions when the time to put the data into array: - Check if year is greater. - Check if year is same and month is greater. - Check if year and month is same with date is greater. - - The result is as expected, now from the same example we can see the mission with `missionTime` has greater Month but lower DateOfMonth. --- ### First time preference Time: **15:00** - Like in User/Student App, there is an error when the first time access using non-desktop device or through smartphone the preference KEY cannot be checked if not being created first. - If check through preference where is not being created first, e.g.: `"my_key": "my_value"` then it will return nothing, or simply it will return null or undefined. - To handle this, user Preference Manager service function, `setData()`, to set the KEY and empty string value. - With this, the `getData()` function from Preference Manager service can return empty string value instead null or undefined so. - Because the first time page to opened is Login page, in **login.page.ts**: ```typescript= async checkPrefFirstTime () { // in here check the first time when app opened let a = await this.pref.getData(StaticVariables.KEY__CHECK_PREF_CREATED); // if identified that user first time use if (a === null || a === undefined) { // create some key first using empty data await this.pref.setData(StaticVariables.KEY__CHECK_PREF_CREATED, true); await this.pref.setData(StaticVariables.KEY__LOGIN_EMPLOYEE_EMAIL, ""); await this.pref.setData(StaticVariables.KEY__LOGIN_EMPLOYEE_ID, ""); await this.pref.setData(StaticVariables.KEY__EMPLOYEE_NAME, ""); await this.pref.setData(StaticVariables.KEY__DEVICE_ID, ""); await this.pref.setData(StaticVariables.KEY__DEVICE_TYPE, ""); await this.pref.setData(StaticVariables.KEY__DEVICE_BUILDING_LOC, ""); await this.pref.setData(StaticVariables.KEY__DEVICE_PLACEMENT_LOC, ""); await this.pref.setData(StaticVariables.KEY__PROBLEM_DESCRIPTION, ""); await this.pref.setData(StaticVariables.KEY__MISSION_NUMBER, ""); await this.pref.setData(StaticVariables.KEY__MISSION_DONE_UNDONE__BOOLEAN, ""); } } ``` - Call the function above in `ngOnInit()`. - In **static-variables.class.ts** we have: ```typescript= export class StaticVariables { public static KEY__LOGIN_EMPLOYEE_EMAIL = "login_employee_email"; public static KEY__LOGIN_EMPLOYEE_ID = "login_employee_id"; public static KEY__EMPLOYEE_NAME = "employee_name"; public static KEY__DEVICE_ID = "device_id"; public static KEY__DEVICE_TYPE = "device_type"; public static KEY__DEVICE_BUILDING_LOC = "device_building_location"; public static KEY__DEVICE_PLACEMENT_LOC = "device_placement_location"; public static KEY__PROBLEM_DESCRIPTION = "problem_description"; public static KEY__MISSION_NUMBER = "mission_number"; public static KEY__MISSION_DONE_UNDONE__BOOLEAN = "mission_done_undone_boolean"; public static KEY__CHECK_PREF_CREATED = "check_pref_created"; public static MISSION_UPDATE = false; } ``` --- ### Detail modal page for future mission Time: **16:00** - The purpose is to help the repairman know the details of mission before it become today mission and appeared in Today Mission list. - The function has added one parameter to check if the detail modal page is opened from Future Mission part or not. - In **home.page.ts**: ```typescript= async openDetail(mission: any, isDoneMission: boolean, disabledButton: boolean) { // set some details to preference for complete/incomplete the mission await this.setDetailReportToPref(mission); // create object property for Modal page let buildNewMission = { 'Disabled': disabledButton, 'Data': mission, 'DoneMission': isDoneMission }; // create the modal page const modal = await this.modalController.create({ component: DetailPage, componentProps: buildNewMission, cssClass: 'my-custom-modal-css' }); await modal.present(); await modal.onDidDismiss().then(async () => { if (StaticVariables.MISSION_UPDATE === true) { await this.updateMissionData(); StaticVariables.MISSION_UPDATE = false; } }); } ``` - The `disabledButton` parameter is to pass boolean value (true/false) - If it from Future Mission then the ARRIVED button is displayed but cannot be clicked. - In **home.page.html** we call the function and pass the proper parameter: ```htmlmixed= <!-- FUTURE SLIDE --> <ion-slide> <ion-content> <ng-container *ngIf="loadReady && futureMissionList !== null"> <ion-list class="ion-list--no-background" *ngFor="let missionDay of futureMissionList"> <ion-item class="ion-item--no-background" lines="none"> <ion-label> <h2 class="subtitle">{{missionDay.DayString.toUpperCase()}}</h2> <span class="subtitle--date">{{missionDay.DateString.toUpperCase()}}</span> </ion-label> </ion-item> <ion-card class="card-future" *ngFor="let missionItem of missionDay.Data" (click)="openDetail(missionItem, false, true)"> <ion-item lines="none"> <ion-label class="card--title"> <span>{{missionItem.ClientName}}</span> </ion-label> <ion-label class="card--title-time"> <span>{{missionItem.MissionTimeOnlyHour}}</span> </ion-label> </ion-item> <ion-item lines="none"> <ion-label class="card--address"> <span>{{missionItem.ClientAddress}}</span> </ion-label> </ion-item> </ion-card> </ion-list> </ng-container> <div class="no-data" *ngIf="!loadReady"> <b>Please wait ...</b> </div> <div class="no-data" *ngIf="loadReady && futureMissionList === null"> <b>No mission has been assigned.</b> </div> <br> </ion-content> </ion-slide> </ion-slides> ``` - In **line 14** we call `openDetail()` function and pass `missionItem, false, true`. - Above means that we pass **true** for `disabledButton` parameter, see again on **html.page.ts** function explanation. - In **detail.page.ts** get the parameter from Home page: ```typescript= export class DetailPage implements OnInit { data: any; doneMission: boolean; disabledButton: boolean; constructor( public navParams: NavParams, private navCtrl: NavController ) { this.data = navParams.get('Data'); this.doneMission = navParams.get('DoneMission'); this.disabledButton = navParams.get('Disabled'); } } ``` - Passed parameters are stored through constructor means everytime the page is loaded/called then new data will be stored. - We store the value of `disabledButton` to field variable on detail page. - In **detail.page.html** we put the result on ARRIVED button as attribute. ```htmlmixed= <ion-footer *ngIf="!doneMission"> <section class="full-width"> <ion-button disabled="{{disabledButton}}" expand="full" *ngIf="!arrived" (click)="setArrival()">Arrived</ion-button> <ion-grid *ngIf="arrived"> <ion-row> <ion-col size="6"> <div> <ion-button expand="full" (click)="wantToClearMission(false)">Cannot complete<br>by now</ion-button> </div> </ion-col> <ion-col size="6"> <div> <ion-button expand="full" (click)="wantToClearMission(true)">Complete repair</ion-button> </div> </ion-col> </ion-row> </ion-grid> </section> </ion-footer> ``` - The `<ion-button>` has attribute to enable/disable the button function, see in **line 4**. - Using the `disabledButton` value which already true/false we can through pass the value. - The result is: - When it from Future Mission it will pass **true** value to `disabledButton`. - The other will pass **false** value to `disabledButton`. --- ## Conclusion - Fixing the filtering data for Future Mission so it can fetch all missions with greater Year, greater Year and Month, and last greater Year, Month, and Date. - Import the First Time Preference from User/Student App to Repairman App so when this app was opened from smartphone and create empty string with KEY in Preference Manager using service. - Creating preference value and KEY at first time is to handle problem when get data which hasn't be set the KEY from preference will return nothing. - Display the Detail modal page when click item in Future mission so the repairman can check earlier what the details of the mission he got. --- Time: **19:00** Event: Leaving the lab ###### tags: `on-intern`