Skip to content

Commit

Permalink
fix: minor
Browse files Browse the repository at this point in the history
  • Loading branch information
suyashpatil78 committed Mar 4, 2024
1 parent 36e194c commit b13046c
Show file tree
Hide file tree
Showing 6 changed files with 259 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/app/core/models/platform/v1/expense.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { ReportState } from '../platform-report.model';
import { Account } from './account.model';
import { CustomFields } from '../custom-fields.model';
import { CustomInput } from '../../custom-input.model';
import { CommuteDetails } from './commute-details.model';

export interface Expense {
// `activity_details` is not added on purpose
Expand Down Expand Up @@ -109,6 +110,9 @@ export interface Expense {
verifier_comments: string[];
report_last_paid_at: Date;
report_last_approved_at: Date;
commute_deduction?: 'ONE_WAY' | 'ROUND_TRIP' | 'NO_DEDUCTION';
commute_details?: CommuteDetails;
commute_details_id?: number;
}

export interface Employee {
Expand Down
56 changes: 56 additions & 0 deletions src/app/fyle/add-edit-mileage/add-edit-mileage.page.html
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,62 @@
</ng-container>
</ng-container>

<ng-container *ngIf="showCommuteDeductionField && commuteDeductionOptions">
<div
class="add-edit-mileage--internal-block"
[ngClass]="{'add-edit-mileage--internal-block__invalid': fg.controls.commuteDeduction.touched && !fg.controls.commuteDeduction.valid}"
>
<app-fy-select
[enableSearch]="false"
[label]="'Commute Deduction'"
[mandatory]="true"
[nullOption]="false"
[options]="commuteDeductionOptions"
[selectModalHeader]="'Commute Deduction'"
formControlName="commuteDeduction"
[selectionElement]="commuteDeduction"
[touchedInParent]="fg.controls.commuteDeduction.touched"
[validInParent]="fg.controls.commuteDeduction.valid"
>
</app-fy-select>
<ng-template
#commuteDeduction
let-label="label"
let-value="value"
let-distance="distance"
let-selected="selected"
>
<div>
<div class="add-edit-mileage--commute-deduction">{{label}}</div>
<div *ngIf="distance > 0" class="add-edit-mileage--payment-mode-section">
{{distance.toFixed(2) + ' ' + distanceUnit}}
</div>
<div *ngIf="distance === 0" class="add-edit-mileage--payment-mode-section">
{{distance + ' ' + distanceUnit}}
</div>
<div
*ngIf="distance === null"
class="add-edit-mileage--add-location"
(click)="openCommuteDetailsModal()"
>
<ion-icon
class="add-edit-mileage--add-location--icon"
src="../../../assets/svg/plus-square.svg"
></ion-icon>
Add Location
</div>
</div>
<mat-icon *ngIf="selected" class="add-edit-mileage--check"> check </mat-icon>
</ng-template>
</div>
<div
*ngIf="fg.controls.commuteDeduction.touched && !fg.controls.commuteDeduction.valid"
class="add-edit-mileage--error"
>
Select Commute Deduction.
</div>
</ng-container>

<ng-container *ngIf="mileageRatesOptions$|async as mileageRatesOptions">
<div
*ngIf="mileageRatesOptions.length > 1"
Expand Down
14 changes: 14 additions & 0 deletions src/app/fyle/add-edit-mileage/add-edit-mileage.page.scss
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,20 @@
margin-top: 4px;
}

&--add-location {
display: flex;
align-items: center;
margin-top: 6px;
gap: 6px;
font-weight: 500;

&--icon {
width: 14px;
height: 14px;
color: $brand-primary;
}
}

&--check {
color: $brand-primary;
font-size: 20px;
Expand Down
168 changes: 167 additions & 1 deletion src/app/fyle/add-edit-mileage/add-edit-mileage.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ import { ToastMessageComponent } from 'src/app/shared/components/toast-message/t
import { TrackingService } from '../../core/services/tracking.service';
import { PlatformHandlerService } from 'src/app/core/services/platform-handler.service';
import { MileageRatesOptions } from 'src/app/core/models/mileage-rates-options.data';
import { CommuteDetails } from 'src/app/core/models/platform/v1/commute-details.model';
import { ExpensesService } from 'src/app/core/services/platform/v1/spender/expenses.service';
import { EmployeesService } from 'src/app/core/services/platform/v1/spender/employees.service';
import { FySelectCommuteDetailsComponent } from 'src/app/shared/components/fy-select-commute-details/fy-select-commute-details.component';
import { OverlayResponse } from 'src/app/core/models/overlay-response.modal';

type FormValue = {
route: {
Expand All @@ -125,6 +130,7 @@ type FormValue = {
purpose: string;
project_dependent_fields: TxnCustomProperties[];
cost_center_dependent_fields: TxnCustomProperties[];
commuteDeduction: { label: string; value: string; distance: number };
};

@Component({
Expand Down Expand Up @@ -281,6 +287,20 @@ export class AddEditMileagePage implements OnInit {

selectedCostCenter$: BehaviorSubject<CostCenter>;

showCommuteDeductionField = false;

commuteDetails: CommuteDetails;

distanceUnit: string;

commuteDeductionOptions: { label: string; value: string; distance: number }[];

initialDistance: number;

previousCommuteDeductionType: string;

previousRouteValue: { roundTrip: boolean; mileageLocations: Location[]; distance: number };

private _isExpandedView = false;

constructor(
Expand Down Expand Up @@ -320,7 +340,9 @@ export class AddEditMileagePage implements OnInit {
private categoriesService: CategoriesService,
private orgSettingsService: OrgSettingsService,
private platformHandlerService: PlatformHandlerService,
private storageService: StorageService
private storageService: StorageService,
private expenseService: ExpensesService,
private employeesService: EmployeesService
) {}

get showSaveAndNext(): boolean {
Expand Down Expand Up @@ -1274,6 +1296,47 @@ export class AddEditMileagePage implements OnInit {
);
}

updateDistance(commuteDeductionType: string): void {
console.log('invoked');
const distance = this.getFormValues().route?.distance;
if (distance > 0 && commuteDeductionType) {
const selectedCommuteDeduction = this.commuteDeductionOptions.find(
(option) => option.value === commuteDeductionType
);

if (this.previousCommuteDeductionType) {
// If there is a previous commute deduction type, add previosly deducted distance to the distance
const commuteDeduction = this.commuteDeductionOptions.find(
(option) => option.value === this.previousCommuteDeductionType
);
this.initialDistance = distance + commuteDeduction.distance;
} else {
// User choosing the commute deduction type for the first time
this.initialDistance = distance;
}

const commuteDeductedDistance = this.initialDistance - selectedCommuteDeduction.distance;
console.log(commuteDeductedDistance);
if (commuteDeductedDistance < 0) {
this.previousCommuteDeductionType = null;
this.fg.controls.route.patchValue({ distance: 0 }, { emitEvent: false });
} else {
this.previousCommuteDeductionType = commuteDeductionType;
this.fg.controls.route.patchValue({ distance: 1 }, { emitEvent: false });
console.log(this.fg.value);
console.log(commuteDeductedDistance);
}
}
}

getCommuteDeductionOptions(distance: number): { label: string; value: string; distance: number }[] {
return [
{ label: 'One Way Distance', value: 'ONE_WAY', distance: distance || null },
{ label: 'Round Trip Distance', value: 'ROUND_TRIP', distance: distance ? distance * 2 : null },
{ label: 'No Deduction', value: 'NO_DEDUCTION', distance: 0 },
];
}

ionViewWillEnter(): void {
this.initClassObservables();

Expand All @@ -1285,6 +1348,7 @@ export class AddEditMileagePage implements OnInit {
this.expenseStartTime = new Date().getTime();
this.fg = this.fb.group({
mileage_rate_name: [],
commuteDeduction: [],
dateOfSpend: [, this.customDateValidator],
route: [],
paymentMode: [, Validators.required],
Expand Down Expand Up @@ -1506,6 +1570,7 @@ export class AddEditMileagePage implements OnInit {
recentValue: this.recentlyUsedValues$,
recentProjects: this.recentlyUsedProjects$,
recentCostCenters: this.recentlyUsedCostCenters$,
eou: from(this.authService.getEou()),
})
),
take(1),
Expand All @@ -1527,6 +1592,7 @@ export class AddEditMileagePage implements OnInit {
recentValue,
recentProjects,
recentCostCenters,
eou,
}) => {
if (project) {
this.selectedProject$.next(project);
Expand Down Expand Up @@ -1560,6 +1626,76 @@ export class AddEditMileagePage implements OnInit {
}
});

this.showCommuteDeductionField =
orgSettings.mileage?.allowed &&
orgSettings.mileage.enabled &&
orgSettings.commute_deduction_settings?.allowed &&
orgSettings.commute_deduction_settings.enabled;
console.log('isCommuteenabled', this.showCommuteDeductionField);

if (this.showCommuteDeductionField) {
this.distanceUnit = orgSettings.mileage?.unit === 'MILES' ? 'Miles' : 'km';
this.fg.controls.commuteDeduction.valueChanges.subscribe((commuteDeductionType: string) => {
console.log(commuteDeductionType);
this.updateDistance(commuteDeductionType);
});

this.fg.controls.route.valueChanges.subscribe(
(route: { roundTrip: boolean; mileageLocations: Location[]; distance: number }) => {
if (
this.previousRouteValue &&
route &&
(this.previousRouteValue.roundTrip !== route.roundTrip ||
this.previousRouteValue.distance !== route.distance)
) {
console.log('route invoke hua');
this.updateDistance(this.getFormValues().commuteDeduction?.value);
this.previousRouteValue = route;
}
}
);

if (etxn?.tx?.id) {
/**
* If we are editing an expense, then
* 1. Fetch the expense details
* 2. Take the commute details from the expense, if present.
* 3. Setup the commute deduction field options.
* 4. Select the commute deduction field value, if present.
*/
this.expenseService.getExpenseById(etxn.tx.id).subscribe((expense) => {
this.commuteDetails = expense.commute_details || null;
this.distanceUnit = this.commuteDetails?.distance_unit || this.distanceUnit;
this.distanceUnit = this.distanceUnit === 'MILES' ? 'Miles' : 'km';
this.commuteDeductionOptions = this.getCommuteDeductionOptions(this.commuteDetails?.distance);
if (expense.commute_deduction) {
this.fg.patchValue(
{
commuteDeduction: expense.commute_deduction,
},
{ emitEvent: false }
);
}
});
} else {
/**
* If we are creating a new expense, then
* 1. Fetch the commute details from the platform api.
* 2. Setup the commute deduction field options.
*/
this.employeesService
.getCommuteDetails(eou)
.pipe(map((response) => response?.data?.[0] || null))
.subscribe((commuteDetailsResponse) => {
this.commuteDetails = commuteDetailsResponse?.commute_details || null;
this.distanceUnit = this.commuteDetails?.distance_unit || this.distanceUnit;
this.distanceUnit = this.distanceUnit === 'MILES' ? 'Miles' : 'km';
this.commuteDeductionOptions = this.getCommuteDeductionOptions(this.commuteDetails?.distance);
console.log(this.commuteDeductionOptions);
});
}
}

// Check if auto-fills is enabled
const isAutofillsEnabled =
orgSettings.org_expense_form_autofills &&
Expand Down Expand Up @@ -2701,4 +2837,34 @@ export class AddEditMileagePage implements OnInit {
this.onPageExit$.next(null);
this.onPageExit$.complete();
}

async openCommuteDetailsModal(): Promise<Subscription> {
const commuteDetailsModal = await this.modalController.create({
component: FySelectCommuteDetailsComponent,
componentProps: {
existingCommuteDetails: this.commuteDetails,
},
mode: 'ios',
});

await commuteDetailsModal.present();

const { data } = (await commuteDetailsModal.onWillDismiss()) as OverlayResponse<{ action: string }>;

// If the user edited or saved the commute details, refresh the page and show the toast message
if (data.action === 'save') {
return from(this.authService.getEou())
.pipe(
concatMap((eou) =>
this.employeesService.getCommuteDetails(eou).pipe(map((response) => response?.data?.[0] || null))
)
)
.subscribe((commuteDetailsResponse) => {
this.commuteDetails = commuteDetailsResponse?.commute_details || null;
this.distanceUnit = this.commuteDetails?.distance_unit || this.distanceUnit;
this.distanceUnit = this.distanceUnit === 'MILES' ? 'Miles' : 'km';
this.commuteDeductionOptions = this.getCommuteDeductionOptions(this.commuteDetails?.distance);
});
}
}
}
10 changes: 9 additions & 1 deletion src/app/shared/components/fy-select/fy-select.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,15 @@ export class FySelectComponent implements ControlValueAccessor {
}

async openModal() {
const cssClass = this.label === 'Payment Mode' ? 'payment-mode-modal' : 'fy-modal';
let cssClass: string;

if (this.label === 'Payment Mode') {
cssClass = 'payment-mode-modal';
} else if (this.label === 'Commute Deduction') {
cssClass = 'add-location-modal';
} else {
cssClass = 'fy-modal';
}

const selectionModal = await this.modalController.create({
component: FySelectModalComponent,
Expand Down
9 changes: 9 additions & 0 deletions src/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,15 @@ ion-modal.payment-mode-modal {
}
}

ion-modal.add-location-modal {
&::part(content) {
border-radius: 16px 16px 0 0 !important;
position: absolute;
max-height: 40%;
bottom: 0;
}
}

.mat-chip.mat-standard-chip {
background-color: $pure-white;
border: 1px solid $grey-lighter;
Expand Down

0 comments on commit b13046c

Please sign in to comment.