diff --git a/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts b/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts index e2516cd58..5d0e45571 100644 --- a/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts +++ b/src/app/modules/shared/components/details-fields/details-fields.component.spec.ts @@ -213,6 +213,7 @@ describe('DetailsFieldsComponent', () => { it('should emit saveEntry event', () => { spyOn(component.saveEntry, 'emit'); + component.entryToEdit = { ...entryToEdit }; component.entryForm.setValue({ project_id: 'p1', project_name: 'p-name', @@ -294,6 +295,7 @@ describe('DetailsFieldsComponent', () => { component.goingToWorkOnThis = true; spyOn(component.saveEntry, 'emit'); + component.entryToEdit = { ...entryToEdit }; component.entryForm.setValue({ ...formValues, start_date: '2020-06-11', end_date: '2020-06-11' }); component.onSubmit(); @@ -310,13 +312,71 @@ describe('DetailsFieldsComponent', () => { }, shouldRestartEntry: false }; - expect(component.saveEntry.emit).toHaveBeenCalledWith(data); }); + it('should not modify the start_date when start_hour has not been modified', () => { + const dateTest = moment().format('YYYY-MM-DD'); + const startHourTest = moment().subtract(3, 'hours').format('HH:mm:ss'); + const expectedStartDate = new Date(`${dateTest}T${startHourTest.trim()}`); + + component.entryToEdit = {...entryToEdit, start_date: expectedStartDate }; + fixture.componentInstance.ngOnChanges(); + + component.entryForm.patchValue({ description: 'test' }); + + expect(component.startDateToSubmit()).toEqual(expectedStartDate); + }); + + it('should modify the start_date when start_hour has been modified', () => { + const dateTest = moment().format('YYYY-MM-DD'); + const startHourTest = moment().format('HH:mm:ss'); + const startDate = new Date(`${dateTest}T${startHourTest.trim()}`); + + component.entryToEdit = {...entryToEdit, start_date: startDate }; + fixture.componentInstance.ngOnChanges(); + + const updatedStartDate = moment().subtract(1, 'hours'); + const updatedStartHour = updatedStartDate.format('HH:mm'); + component.entryForm.patchValue({start_hour: updatedStartHour}); + + const expectedStartDate = moment(updatedStartDate).seconds(0).millisecond(0).toISOString(); + expect(component.startDateToSubmit()).toEqual(expectedStartDate); + }); + + it('should not modify the end_date when end_hour has not been modified', () => { + const dateTest = moment().format('YYYY-MM-DD'); + const endtHourTest = moment().subtract(3, 'hours').format('HH:mm:ss'); + const expectedEndDate = new Date(`${dateTest}T${endtHourTest.trim()}`); + + component.entryToEdit = {...entryToEdit, end_date: expectedEndDate }; + fixture.componentInstance.ngOnChanges(); + + component.entryForm.patchValue({ description: 'test' }); + + expect(component.endDateToSubmit()).toEqual(expectedEndDate); + }); + + it('should modify the end_date when end_hour has been modified', () => { + const dateTest = moment().format('YYYY-MM-DD'); + const endHourTest = moment().format('HH:mm:ss'); + const endDate = new Date(`${dateTest}T${endHourTest.trim()}`); + + component.entryToEdit = {...entryToEdit, end_date: endDate }; + fixture.componentInstance.ngOnChanges(); + + const updatedEndDate = moment().subtract(1, 'hours'); + const updatedEndHour = updatedEndDate.format('HH:mm'); + component.entryForm.patchValue({end_hour: updatedEndHour}); + + const expectedEndDate = moment(updatedEndDate).seconds(0).millisecond(0).toISOString(); + expect(component.endDateToSubmit()).toEqual(expectedEndDate); + }); + it('displays error message when the date selected is in the future', () => { spyOn(toastrServiceStub, 'error'); + component.entryToEdit = { ...entryToEdit }; const futureDate = moment().add(1, 'days').format(DATE_FORMAT_YEAR); component.entryForm.setValue({ ...formValues, start_date: futureDate, end_date: futureDate }); component.onSubmit(); @@ -327,6 +387,7 @@ describe('DetailsFieldsComponent', () => { it('when start_date is in the future and end_date is OK then throws an error', () => { spyOn(toastrServiceStub, 'error'); + component.entryToEdit = { ...entryToEdit }; const futureDate = moment().add(1, 'days').format(DATE_FORMAT_YEAR); const currentDate = moment().format(DATE_FORMAT_YEAR); component.entryForm.setValue({ ...formValues, start_date: futureDate, end_date: currentDate }); @@ -338,6 +399,7 @@ describe('DetailsFieldsComponent', () => { it('when start_date is OK and end_date is in the future then throws an error future', () => { spyOn(toastrServiceStub, 'error'); + component.entryToEdit = { ...entryToEdit }; const futureDate = moment().add(1, 'days').format(DATE_FORMAT_YEAR); const currentDate = moment().format(DATE_FORMAT_YEAR); component.entryForm.setValue({ ...formValues, start_date: currentDate, end_date: futureDate }); diff --git a/src/app/modules/shared/components/details-fields/details-fields.component.ts b/src/app/modules/shared/components/details-fields/details-fields.component.ts index 8f90c97aa..516395b74 100644 --- a/src/app/modules/shared/components/details-fields/details-fields.component.ts +++ b/src/app/modules/shared/components/details-fields/details-fields.component.ts @@ -197,29 +197,56 @@ export class DetailsFieldsComponent implements OnChanges, OnInit { this.closeModal?.nativeElement?.click(); } + startDateToSubmit(){ + const startDate = this.entryForm.value.start_date; + const initialStartDate = this.entryToEdit.start_date; + const updatedStartDate = new Date(`${startDate}T${this.entryForm.value.start_hour.trim()}`).toISOString(); + const initialStartHour = formatDate(get(this.entryToEdit, 'start_date', '00:00'), 'HH:mm', 'en'); + const updatedStartHour = this.entryForm.value.start_hour; + const startHourHasNotChanged = updatedStartHour === initialStartHour; + const result = startHourHasNotChanged ? initialStartDate : updatedStartDate; + return result; + } + + endDateToSubmit(){ + const endDate = this.entryForm.value.end_date; + const initialEndDate = this.entryToEdit.end_date; + const updatedEndDate = new Date(`${endDate}T${this.entryForm.value.end_hour.trim()}`).toISOString(); + const initialEndHour = formatDate(get(this.entryToEdit, 'end_date', '00:00'), 'HH:mm', 'en'); + const updatedEndHour = this.entryForm.value.end_hour; + const endDateHasNotChanged = updatedEndHour === initialEndHour; + const result = endDateHasNotChanged ? initialEndDate : updatedEndDate; + return result; + } + onSubmit() { if (this.entryForm.invalid) { this.toastrService.warning('Make sure to select a project and activity'); return; } - const startDate = this.entryForm.value.start_date; - const endDate = this.entryForm.value.end_date; + + const startDateToSubmit = this.startDateToSubmit(); + const endDateToSubmit = this.endDateToSubmit(); + const entry = { project_id: this.entryForm.value.project_id, activity_id: this.entryForm.value.activity_id, technologies: get(this, 'selectedTechnologies', []), description: this.entryForm.value.description, - start_date: new Date(`${startDate}T${this.entryForm.value.start_hour.trim()}`).toISOString(), - end_date: new Date(`${endDate}T${this.entryForm.value.end_hour.trim()}`).toISOString(), + start_date: startDateToSubmit, + end_date: endDateToSubmit, uri: this.entryForm.value.uri, timezone_offset: new Date().getTimezoneOffset(), }; if (this.goingToWorkOnThis) { delete entry.end_date; } - const isStartDateInTheFuture = moment(startDate).isAfter(moment()); - const isEndDateInTheFuture = moment(endDate).isAfter(moment()); - if (isStartDateInTheFuture || isEndDateInTheFuture) { + + const isStartDateInTheFuture = moment(startDateToSubmit).isAfter(moment()); + const isEndDateInTheFuture = moment(endDateToSubmit).isAfter(moment()); + const timeEntryIsInTheFuture = isStartDateInTheFuture || isEndDateInTheFuture; + + if (timeEntryIsInTheFuture) { this.toastrService.error('You cannot start a time-entry in the future'); return; } diff --git a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts index bd3ef5c49..6213e3ca7 100644 --- a/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts +++ b/src/app/modules/time-clock/components/project-list-hover/project-list-hover.component.ts @@ -88,6 +88,7 @@ export class ProjectListHoverComponent implements OnInit, OnDestroy { project_id: selectedProject, start_date: new Date().toISOString(), timezone_offset: new Date().getTimezoneOffset(), + technologies: [] }; this.store.dispatch(new entryActions.ClockIn(entry)); this.projectsForm.setValue( { project_id: `${customerName} - ${name}`, } ); diff --git a/src/app/modules/time-clock/store/entry.effects.ts b/src/app/modules/time-clock/store/entry.effects.ts index 6add71c00..806ec9a19 100644 --- a/src/app/modules/time-clock/store/entry.effects.ts +++ b/src/app/modules/time-clock/store/entry.effects.ts @@ -26,6 +26,7 @@ export class EntryEffects { project_id: action.idProjectSwitching, start_date: stopDateForEntry.toISOString(), timezone_offset: new Date().getTimezoneOffset(), + technologies: [] }; return new actions.ClockIn(entry); }),