Skip to content

Commit

Permalink
Merge branch 'develop' into fix#6621
Browse files Browse the repository at this point in the history
  • Loading branch information
konavivekramakrishna authored Jan 10, 2024
2 parents 6ed07ce + 197cb39 commit a5f0ad9
Show file tree
Hide file tree
Showing 32 changed files with 346 additions and 402 deletions.
56 changes: 52 additions & 4 deletions cypress/e2e/facility_spec/inventory.cy.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { cy, describe, before, beforeEach, it, afterEach } from "local-cypress";
import FacilityPage from "../../pageobject/Facility/FacilityCreation";
import LoginPage from "../../pageobject/Login/LoginPage";
import FacilityHome from "../../pageobject/Facility/FacilityHome";

describe("Inventory Management Section", () => {
const facilityPage = new FacilityPage();
const loginPage = new LoginPage();
const facilityHome = new FacilityHome();

before(() => {
loginPage.loginAsDisctrictAdmin();
Expand All @@ -16,18 +18,64 @@ describe("Inventory Management Section", () => {
cy.clearLocalStorage(/filters--.+/);
cy.awaitUrl("/");
cy.viewport(1280, 720);
});

it("Adds Inventory", () => {
facilityPage.visitAlreadyCreatedFacility();
facilityPage.clickManageFacilityDropdown();
facilityPage.clickInventoryManagementOption();
});

it("Add New Inventory | Modify data and delete last entry ", () => {
// add a new item
facilityPage.clickManageInventory();
facilityPage.fillInventoryDetails("Liquid Oxygen", "Add Stock", "120");
facilityPage.fillInventoryDetails("PPE", "Add Stock", "10");
facilityPage.clickAddInventory();
facilityPage.verifySuccessNotification("Inventory created successfully");
facilityPage.clickManageInventory();
// modify the new item
facilityPage.fillInventoryDetails("PPE", "Use Stock", "5");
facilityPage.clickAddInventory();
facilityPage.verifySuccessNotification("Inventory created successfully");
// verify the new modification
facilityPage.verifyPpeQuantity("PPE");
facilityPage.verifyPpeQuantity("5");
// delete the last Entry
facilityPage.clickPpeQuantity();
facilityPage.clickLastEntry();
// verify the last entry deletion
facilityPage.verifyStockInRow("#row-0", "Added Stock");
facilityPage.verifyStockInRow("#row-1", "Used Stock");
cy.wait(3000);
facilityHome.navigateBack();
facilityPage.verifyPpeQuantity("PPE");
});

it("Add New Inventory | Verify Backend and manual Minimum", () => {
// Add Inventory
facilityPage.clickManageInventory();
facilityPage.fillInventoryDetails("PPE", "Add Stock", "5");
facilityPage.clickAddInventory();
facilityPage.verifySuccessNotification("Inventory created successfully");
// Verify Backend minimum badge
facilityPage.verifyBadgeWithText(".badge-danger", "Low Stock");
// modify with manual minimum badge
facilityPage.clickAddMinimumQuanitity();
cy.wait(3000);
cy.get("body").then(($body) => {
if ($body.find("#update-minimum-quantity").is(":visible")) {
// If the 'update-minimum-quantity' element is visible, click it
facilityPage.clickUpdateMinimumQuantity();
facilityPage.setQuantity("5");
facilityPage.clickSaveUpdateMinimumQuantity();
} else {
// Otherwise, click the 'set-minimum-quantity' element
facilityPage.clickSetMinimumQuantity();
facilityPage.fillInventoryMinimumDetails("PPE", "1");
facilityPage.clickSetButton();
facilityPage.verifySuccessNotification(
"Minimum quantiy updated successfully"
);
}
});
});
afterEach(() => {
cy.saveLocalStorage();
});
Expand Down
50 changes: 50 additions & 0 deletions cypress/pageobject/Facility/FacilityCreation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,12 @@ class FacilityPage {
cy.get("[name='quantity']").type(quantity);
}

fillInventoryMinimumDetails(name: string, quantity: string) {
cy.get("div#id").click();
cy.get("div#id ul li").contains(name).click();
cy.get("[name='quantity']").type(quantity);
}

clickAddInventory() {
cy.intercept("POST", "**/api/v1/facility/*/inventory/").as(
"createInventory"
Expand All @@ -380,6 +386,10 @@ class FacilityPage {
cy.wait("@createInventory").its("response.statusCode").should("eq", 201);
}

clickSetButton() {
cy.get("#submit").contains("Set").click();
}

fillResourceRequestDetails(
name: string,
phone_number: string,
Expand Down Expand Up @@ -443,6 +453,46 @@ class FacilityPage {
}
});
}

verifyPpeQuantity(text: string) {
cy.get("#PPE").contains(text).should("be.visible");
}

clickPpeQuantity() {
cy.get("#PPE").click();
}

clickLastEntry() {
cy.get("#delete-last-entry").click();
}

verifyStockInRow(rowId: string, stockText: string) {
cy.get(rowId).contains(stockText).should("be.visible");
}

verifyBadgeWithText(badgeClass: string, text: string) {
cy.get(badgeClass).contains(text).should("exist");
}

clickAddMinimumQuanitity() {
cy.get("#add-minimum-quantity").click();
}

clickUpdateMinimumQuantity() {
cy.get("#update-minimum-quantity").first().click();
}

setQuantity(quantity: string) {
cy.get("#quantity").click().clear().click().type(quantity);
}

clickSaveUpdateMinimumQuantity() {
cy.get("#save-update-minimumquanitity").click();
}

clickSetMinimumQuantity() {
cy.get("#set-minimum-quantity").click();
}
}

export default FacilityPage;
28 changes: 7 additions & 21 deletions src/Components/Common/AssetSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useCallback } from "react";
import { useDispatch } from "react-redux";
import { listAssets } from "../../Redux/actions";
import AutoCompleteAsync from "../Form/AutoCompleteAsync";
import routes from "../../Redux/api";
import request from "../../Utils/request/request";

interface AssetSelectProps {
name: string;
Expand All @@ -16,7 +16,6 @@ interface AssetSelectProps {
asset_class?: string;
showAll?: boolean;
showNOptions?: number;
freeText?: boolean;
selected: any;
setSelected: (selected: any) => void;
}
Expand All @@ -33,21 +32,13 @@ export const AssetSelect = (props: AssetSelectProps) => {
is_permanent = null,
showNOptions = 10,
className = "",
freeText = false,
errors = "",
asset_class = "",
} = props;

const dispatchAction: any = useDispatch();

const AssetSearch = useCallback(
async (text: string) => {
const params: Partial<AssetSelectProps> & {
limit: number;
offset: number;
search_text: string;
asset_class: string;
} = {
const query = {
limit: 50,
offset: 0,
search_text: text,
Expand All @@ -56,17 +47,12 @@ export const AssetSelect = (props: AssetSelectProps) => {
in_use_by_consultation,
is_permanent,
asset_class,
};
} as const;

const res = await dispatchAction(listAssets(params));
if (freeText)
res?.data?.results?.push({
id: -1,
name: text,
});
return res?.data?.results;
const { data } = await request(routes.listAssets, { query });
return data?.results;
},
[dispatchAction]
[asset_class, facility, in_use_by_consultation, is_permanent, is_working]
);

return (
Expand Down
24 changes: 11 additions & 13 deletions src/Components/Common/BedSelect.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useCallback } from "react";
import { useDispatch } from "react-redux";
import { listFacilityBeds } from "../../Redux/actions";
import { BedModel } from "../Facility/models";
import AutoCompleteAsync from "../Form/AutoCompleteAsync";
import { useTranslation } from "react-i18next";
import request from "../../Utils/request/request";
import routes from "../../Redux/api";

interface BedSelectProps {
name: string;
Expand Down Expand Up @@ -34,13 +34,11 @@ export const BedSelect = (props: BedSelectProps) => {
location,
showNOptions = 20,
} = props;

const dispatchAction: any = useDispatch();
const { t } = useTranslation();

const onBedSearch = useCallback(
async (text: string) => {
const params = {
const query = {
limit: 50,
offset: 0,
search_text: text,
Expand All @@ -49,17 +47,17 @@ export const BedSelect = (props: BedSelectProps) => {
location,
};

const res = await dispatchAction(listFacilityBeds(params));
if (res && res.data) {
let beds = res.data.results;
if (unoccupiedOnly) {
beds = beds.filter((bed: BedModel) => bed?.is_occupied === false);
}
const { data } = await request(routes.listFacilityBeds, { query });

return beds;
if (unoccupiedOnly) {
return data?.results?.filter(
(bed: BedModel) => bed?.is_occupied === false
);
}

return data?.results;
},
[dispatchAction, facility, location, searchAll, unoccupiedOnly]
[facility, location, searchAll, unoccupiedOnly]
);

return (
Expand Down
47 changes: 29 additions & 18 deletions src/Components/Common/BloodPressureFormField.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,41 @@
import { FieldValidator } from "../Form/FieldValidators";
import FormField from "../Form/FormFields/FormField";
import RangeAutocompleteFormField from "../Form/FormFields/RangeAutocompleteFormField";
import {
FieldChangeEvent,
FormFieldBaseProps,
useFormFieldPropsResolver,
} from "../Form/FormFields/Utils";
import { DailyRoundsModel } from "../Patient/models";

export interface BloodPressure {
systolic: number;
diastolic: number;
}
type BloodPressure = NonNullable<DailyRoundsModel["bp"]>;

type Props = FormFieldBaseProps<Partial<BloodPressure>>;
type Props = FormFieldBaseProps<BloodPressure>;

export default function BloodPressureFormField(props: Props) {
const field = useFormFieldPropsResolver(props as any);

const handleChange = (event: FieldChangeEvent<number>) => {
field.onChange({
name: field.name,
value: {
...field.value,
[event.name]: event.value ?? -1,
},
});
const value: BloodPressure = {
...field.value,
[event.name]: event.value,
};
value.mean = meanArterialPressure(value);
field.onChange({ name: field.name, value });
};

const map =
!!props.value?.diastolic &&
!!props.value.systolic &&
meanArterialPressure(props.value as BloodPressure);
meanArterialPressure(props.value);

return (
<FormField
field={{
...field,
labelSuffix:
map && map !== -1 ? (
<span className="font-medium">MAP: {map.toFixed(1)}</span>
) : undefined,
labelSuffix: map ? (
<span className="font-medium">MAP: {map.toFixed(1)}</span>
) : undefined,
}}
>
<div className="flex flex-row items-center">
Expand Down Expand Up @@ -108,5 +105,19 @@ export const meanArterialPressure = ({
diastolic,
systolic,
}: BloodPressure) => {
return (2 * diastolic + systolic) / 3;
if (diastolic != null && systolic != null) {
return (2 * diastolic + systolic) / 3;
}
};

export const BloodPressureValidator: FieldValidator<BloodPressure> = (bp) => {
if (Object.values(bp).every((v) => v == null)) {
return;
}
if (bp.diastolic == null) {
return "Diastolic is missing. Either specify both or clear both.";
}
if (bp.systolic == null) {
return "Systolic is missing. Either specify both or clear both.";
}
};
Loading

0 comments on commit a5f0ad9

Please sign in to comment.