Skip to content

Commit

Permalink
Merge pull request #45 from akvo/feature/44-handle-onfinish-save-case…
Browse files Browse the repository at this point in the history
…-profile

Feature/44 handle onfinish save case profile
  • Loading branch information
dedenbangkit authored Oct 23, 2023
2 parents 11fdd8b + b3dba5a commit 1f1a1b7
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 18 deletions.
25 changes: 21 additions & 4 deletions backend/db/crud_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import Optional, List
from typing_extensions import TypedDict
from fastapi import HTTPException, status
from datetime import datetime

from models.user import User
from models.case import Case, CaseBase, CaseDict, CaseListDict
Expand All @@ -16,11 +17,12 @@ class PaginatedCaseData(TypedDict):


def add_case(session: Session, payload: CaseBase, user: User) -> CaseDict:
current_datetime = datetime.now()
case = Case(
name=payload.name,
description=payload.description,
date=payload.date,
year=payload.year,
date=payload.date if payload.date else current_datetime.date(),
year=payload.year if payload.year else current_datetime.year,
country=payload.country,
focus_commodity=payload.focus_commodity,
currency=payload.currency,
Expand Down Expand Up @@ -62,6 +64,11 @@ def add_case(session: Session, payload: CaseBase, user: User) -> CaseDict:
area_size_unit=payload.area_size_unit,
volume_measurement_unit=payload.volume_measurement_unit,
)
# store tags
if payload.tags:
for tag_id in payload.tags:
tag = CaseTag(tag=tag_id)
case.case_tags.append(tag)
case.case_commodities.append(def_diversified_commodity)
session.add(case)
session.commit()
Expand Down Expand Up @@ -109,8 +116,8 @@ def update_case(session: Session, id: int, payload: CaseBase) -> CaseDict:
case.name = payload.name
if payload.description is not None:
case.description = payload.description
case.date = payload.date
case.year = payload.year
case.date = payload.date if payload.date else case.date
case.year = payload.year if payload.year else case.year
case.country = payload.country
case.focus_commodity = payload.focus_commodity
case.currency = payload.currency
Expand All @@ -123,6 +130,16 @@ def update_case(session: Session, id: int, payload: CaseBase) -> CaseDict:
case.multiple_commodities = 1 if payload.multiple_commodities else 0
case.logo = payload.logo
case.private = 1 if payload.private else 0
# handle tag
if payload.tags:
prev_tags = session.query(CaseTag).filter(CaseTag.case == case.id).all()
for ct in prev_tags:
session.delete(ct)
session.commit()
# store new tags
for tag_id in payload.tags:
tag = CaseTag(tag=tag_id, case=case.id)
case.case_tags.append(tag)
# store other commodities
# TODO ::
"""
Expand Down
12 changes: 10 additions & 2 deletions backend/models/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
CaseCommodityType,
)
from models.segment import Segment, SimplifiedSegmentDict
from models.case_tag import CaseTag


class LivingIncomeStudyEnum(enum.Enum):
Expand Down Expand Up @@ -125,6 +126,12 @@ class Case(Base):
passive_deletes=True,
back_populates="case_detail",
)
case_tags = relationship(
CaseTag,
cascade="all, delete",
passive_deletes=True,
back_populates="case_detail",
)
# country_detail = relationship(
# 'Country',
# cascade="all, delete",
Expand Down Expand Up @@ -265,8 +272,8 @@ class OtherCommoditysBase(BaseModel):
class CaseBase(BaseModel):
name: str
description: Optional[str] = None
date: date_format
year: int
date: Optional[date_format] = None
year: Optional[int] = None
country: int
focus_commodity: int
currency: str
Expand All @@ -280,6 +287,7 @@ class CaseBase(BaseModel):
logo: Optional[str] = None
private: Optional[bool] = False
other_commodities: Optional[List[OtherCommoditysBase]] = None
tags: Optional[List[int]] = None


class PaginatedCaseResponse(BaseModel):
Expand Down
14 changes: 7 additions & 7 deletions backend/models/case_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ class CaseTag(Base):
case = Column(Integer, ForeignKey('case.id'), nullable=False)
tag = Column(Integer, ForeignKey('tag.id'), nullable=False)

# case_detail = relationship(
# 'Case',
# cascade="all, delete",
# passive_deletes=True,
# backref='case_tag'
# )
case_detail = relationship(
'Case',
cascade="all, delete",
passive_deletes=True,
back_populates='case_tags'
)
case_tag_detail = relationship(
'Tag',
cascade="all, delete",
Expand All @@ -27,7 +27,7 @@ class CaseTag(Base):

def __init__(
self,
case: int,
case: Optional[int] = None,
tag: Optional[int] = None,
id: Optional[int] = None,
):
Expand Down
2 changes: 2 additions & 0 deletions backend/tests/test_020_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ async def test_create_not_private_case(
"area_size_unit": "hectare",
}
],
"tags": [1],
}
# without cred
res = await client.post(
Expand Down Expand Up @@ -267,6 +268,7 @@ async def test_update_case(
"volume_measurement_unit": "liters",
}
],
"tags": [1],
}
# without cred
res = await client.put(
Expand Down
9 changes: 8 additions & 1 deletion frontend/src/pages/cases/Case.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const Case = () => {
const [formData, setFormData] = useState({});
const [finished, setFinished] = useState([]);
const [commodityList, setCommodityList] = useState([]);
const [currentCaseId, setCurrentCaseId] = useState(null);

const setActive = (selected) => {
if (finished.includes(selected)) {
Expand Down Expand Up @@ -51,10 +52,16 @@ const Case = () => {
setFinished={setFinished}
setPage={setPage}
setCommodityList={setCommodityList}
currentCaseId={currentCaseId}
setCurrentCaseId={setCurrentCaseId}
/>
)}
{page === "Income Driver Data Entry" && (
<IncomeDriverDataEntry commodityList={commodityList} />
<IncomeDriverDataEntry
commodityList={commodityList}
currentCaseId={currentCaseId}
setCurrentCaseId={setCurrentCaseId}
/>
)}
</Col>
</Row>
Expand Down
81 changes: 77 additions & 4 deletions frontend/src/pages/cases/components/CaseProfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
Switch,
Button,
Space,
message,
} from "antd";
import { StepForwardOutlined } from "@ant-design/icons";
import {
Expand All @@ -19,11 +20,14 @@ import {
currencyOptions,
reportingPeriod,
selectProps,
tagOptions,
yesNoOptions,
} from "./";
import { api } from "../../../lib";
import { UIState } from "../../../store";

const CaseForm = ({ setCaseTitle }) => {
const tagOptions = UIState.useState((s) => s.tagOptions);

return (
<>
<h3>General Information</h3>
Expand Down Expand Up @@ -63,7 +67,7 @@ const CaseForm = ({ setCaseTitle }) => {
]}
>
<Select
mode="tags"
mode="multiple"
placeholder="Add Tags"
options={tagOptions}
{...selectProps}
Expand Down Expand Up @@ -192,16 +196,21 @@ const CaseProfile = ({
finished,
setFinished,
setCommodityList,
currentCaseId,
setCurrentCaseId,
}) => {
const [form] = Form.useForm();
const [secondary, setSecondary] = useState(false);
const [tertiary, setTertiary] = useState(false);
const [isSaving, setIsSaving] = useState(false);
const [messageApi, contextHolder] = message.useMessage();

const onFinish = (values) => {
setIsSaving(true);
setFormData(values);
setPage("Income Driver Data Entry");
const completed = finished.filter((item) => item !== "Case Profile");
setFinished([...completed, "Case Profile"]);

let other_commodities = [];
let commodities = [
{
commodity: values.focus_commodity,
Expand All @@ -222,6 +231,16 @@ const CaseProfile = ({
volume_measurement_unit: values["1-volume_measurement_unit"],
},
];
other_commodities = [
...other_commodities,
{
commodity: values["1-commodity"],
breakdown: values["1-breakdown"] ? true : false,
commodity_type: "secondary",
area_size_unit: values["1-area_size_unit"],
volume_measurement_unit: values["1-volume_measurement_unit"],
},
];
}
if (tertiary) {
commodities = [
Expand All @@ -234,8 +253,59 @@ const CaseProfile = ({
volume_measurement_unit: values["2-volume_measurement_unit"],
},
];
other_commodities = [
...other_commodities,
{
commodity: values["2-commodity"],
breakdown: values["2-breakdown"] ? true : false,
commodity_type: "tertiary",
area_size_unit: values["2-area_size_unit"],
volume_measurement_unit: values["2-volume_measurement_unit"],
},
];
}

const payload = {
name: values.name,
description: values.description,
country: values.country,
focus_commodity: values.focus_commodity,
currency: values.currency,
area_size_unit: values.area_size_unit,
volume_measurement_unit: values.volume_measurement_unit,
reporting_period: values.reporting_period,
multiple_commodities: secondary || tertiary,
// need to handle below value correctly
cost_of_production_unit: "cost_of_production_unit",
segmentation: true,
living_income_study: null,
logo: null,
private: false,
other_commodities: other_commodities,
tags: values.tags || null,
};

setCommodityList(commodities);

const apiCall = currentCaseId
? api.put(`case/${currentCaseId}`, payload)
: api.post("case", payload);
apiCall
.then((res) => {
setCurrentCaseId(res?.data?.id);
setFinished([...completed, "Case Profile"]);
setPage("Income Driver Data Entry");
})
.catch((e) => {
console.error(e);
messageApi.open({
type: "error",
content: "Failed to save case profile.",
});
})
.finally(() => {
setIsSaving(false);
});
};

const onFinishFailed = () => {
Expand All @@ -252,6 +322,7 @@ const CaseProfile = ({
onFinishFailed={onFinishFailed}
autoComplete="off"
>
{contextHolder}
<Row gutter={[16, 16]}>
<Col span={12}>
<Card title="Case Details">
Expand Down Expand Up @@ -303,12 +374,14 @@ const CaseProfile = ({
<Button
htmlType="submit"
className="button button-submit button-secondary"
loading={isSaving}
>
Save
</Button>
<Button
htmlType="submit"
className="button button-submit button-secondary"
loading={isSaving}
>
Next
<StepForwardOutlined />
Expand Down

0 comments on commit 1f1a1b7

Please # to comment.