Skip to content

Commit

Permalink
feat: fees list details
Browse files Browse the repository at this point in the history
* chore: client gen

* feat: fees list

* style: sonar

* refactor: request changes
  • Loading branch information
NyAndoMayah authored Nov 19, 2024
1 parent 1923fb7 commit deafe34
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 76 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"test:merge:reports": "srm ./dist/test-reports.xml \"./dist/**/!(*test-reports).xml\""
},
"dependencies": {
"@haapi/typescript-client": "^1.75.0",
"@haapi/typescript-client": "^1.77.1",
"@mui/x-date-pickers": "^7.21.0",
"@react-admin/ra-calendar": "^4.0.1",
"@react-admin/ra-enterprise": "^7.0.0",
Expand Down
10 changes: 6 additions & 4 deletions src/operations/fees/TransactionFeeList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import {
Cancel,
Pending,
Check,
Download,
} from "@mui/icons-material";
import {Chip} from "@mui/material";
import {FeeStatusEnum} from "@haapi/typescript-client";
import {Chip, Typography} from "@mui/material";
import {HaList} from "@/ui/haList/HaList";
import {EMPTY_TEXT} from "@/ui/constants";
import {FeesFilters} from "./components/FeesFilter";
Expand Down Expand Up @@ -57,7 +55,11 @@ const TransactionFeeList = () => {
<>
<ListHeader
cardContents={headerCardContent}
title="Liste des frais (en retard par défaut)"
title={
<Typography variant="h6" fontWeight="bold">
Statistiques des frais de ce mois-ci
</Typography>
}
/>
<HaList
icon={<Money />}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {useMemo} from "react";
import {FC, useMemo} from "react";
import {
Course,
FeeStatusEnum,
FeeTypeEnum,
LetterStatus,
Expand All @@ -13,29 +14,24 @@ import {
SelectArrayInput,
SelectInput,
SimpleForm,
TextField,
TextInput,
useGetList,
useRecordContext,
useRefresh,
useListContext,
regex,
minLength,
} from "react-admin";
import {EditableDatagrid} from "@react-admin/ra-editable-datagrid";
import {AxiosError} from "axios";
import {
AddCard as AddMbpsIcon,
Visibility as ShowIcon,
WarningOutlined,
FilePresent as SlipIcon,
Repartition,
Paid,
} from "@mui/icons-material";
import {Box, Chip, TextField as MuiTextInput, Typography} from "@mui/material";
import {RowForm, useRowContext} from "@react-admin/ra-editable-datagrid";
import {Box, TextField as MuiTextInput, Typography} from "@mui/material";
import {useNotify, useToggle} from "@/hooks";
import {useStudentRef} from "@/hooks/useStudentRef";
import {EMPTY_TEXT} from "@/ui/constants";
import {HaList} from "@/ui/haList/HaList";
import {ButtonBase, HaActionWrapper} from "@/ui/haToolbar";
import {Create} from "@/operations/common/components";
Expand All @@ -48,9 +44,6 @@ import {
IconButtonWithTooltip,
} from "@/operations/utils";
import {
rowStyle,
PSP_COLORS,
PSP_VALUES,
MpbsStatusIcon,
DEFAULT_REMEDIAL_COSTS_AMOUNT,
DEFAULT_REMEDIAL_COSTS_DUE_DATETIME,
Expand All @@ -61,13 +54,30 @@ import {FeesDialog} from "./FeesDialog";
import {LetterStatusIcon} from "./letterIcon";
import authProvider from "@/providers/authProvider";

interface CreateProps {
onSuccess: () => void;
}

interface TransformData {
psp_id?: string;
psp_type?: MobileMoneyType;
}

const TRANSACTION_PATTERN =
/^MP[a-zA-Z0-9]{6}\.[a-zA-Z0-9]{4}\.[a-zA-Z0-9]{6}$/;

const pspIdValidationContraints = [
minLength(20, "La référence doit contenir exactement 20 caractères"),
regex(
TRANSACTION_PATTERN,
"La référence n'est pas saisie correctement (ex : MP123456.1234.B12345)"
),
];

const DefaultInfos = () => {
return (
<FormDataConsumer>
{({formData, ...rest}) => {
{({formData}) => {
const {course_list = []} = formData;

return (
Expand Down Expand Up @@ -95,9 +105,11 @@ const DefaultInfos = () => {
);
};

const CatchupFeesCreate = ({toggle}) => {
const CatchupFeesCreate: FC<CreateProps> = ({onSuccess}) => {
const notify = useNotify();
const {data: courses} = useGetList("course", {pagination: {perPage: 50}});
const {data: courses = []} = useGetList("course", {
pagination: {perPage: 50, page: 1},
});
const {id: student_id} = authProvider.getCachedWhoami();

return (
Expand All @@ -108,11 +120,15 @@ const CatchupFeesCreate = ({toggle}) => {
mutationOptions={{
onSuccess: () => {
notify("Frais créés avec succès", {type: "success"});
toggle();
onSuccess();
},
}}
transform={(data) => {
return data?.course_list.map((course) => ({
transform={(
data: {
course_list: Course[];
} = {course_list: []}
) => {
return data.course_list.map((course: Course) => ({
type: FeeTypeEnum.REMEDIAL_COSTS,
comment: `Rattrapage ${course}`,
total_amount: DEFAULT_REMEDIAL_COSTS_AMOUNT,
Expand Down Expand Up @@ -141,11 +157,24 @@ const CatchupFeesCreate = ({toggle}) => {
);
};

const MpbsCreate = ({toggle}) => {
const MpbsCreate: FC<CreateProps> = ({onSuccess}) => {
const notify = useNotify();
const {id} = useRecordContext();
const {id: fee_id, mpbs} = useRecordContext();
const {id: student_id} = authProvider.getCachedWhoami();

const handleError = (error: AxiosError) => {
if (!error.response) return;

const messages: Record<number, string> = {
500: "Cette référence de transaction existe déjà",
404: "Transaction non trouvée chez Orange",
};

const message =
messages[error.response.status] || "Une erreur inattendue s'est produite";
notify(message, {type: "error"});
};

return (
<Create
resource="fees"
Expand All @@ -154,40 +183,22 @@ const MpbsCreate = ({toggle}) => {
mutationOptions={{
onSuccess: () => {
notify("Frais créés avec succès", {type: "success"});
toggle();
},
onError: (error) => {
if (error.response?.status === 500) {
notify("Cette référence de transaction existe déjà", {
type: "error",
});
} else if (error.response?.status === 404) {
notify("Transaction non trouvée chez Orange", {
type: "error",
});
} else {
notify("Une erreur inattendue s'est produite", {
type: "error",
});
}
onSuccess();
},
onError: (error: AxiosError) => handleError(error),
}}
transform={(data) => ({...data, student_id, id})}
transform={(data: TransformData = {}) => ({
...data,
student_id,
fee_id,
mpbs_id: mpbs?.id,
})}
>
<SimpleForm>
<TextInput
source="psp_id"
label="Référence de la transaction"
validate={[
minLength(
20,
"La référence doit contenir exactement 20 caractères"
),
regex(
TRANSACTION_PATTERN,
"La référence n'est pas saisie correctement (ex : MP123456.1234.B12345)"
),
]}
validate={pspIdValidationContraints}
fullWidth
/>
<SelectInput
Expand All @@ -202,7 +213,7 @@ const MpbsCreate = ({toggle}) => {
);
};

const ListActionButtons = ({studentId}) => {
const ListActionButtons: FC<{studentId: string}> = ({studentId}) => {
const {id, total_amount, mpbs, letter, status, due_datetime, student_id} =
useRecordContext();
const {data: fees = []} = useGetList("fees", {
Expand Down Expand Up @@ -266,7 +277,7 @@ const ListActionButtons = ({studentId}) => {
show={show3}
toggle={toggle3}
>
<MpbsCreate toggle={toggle3} />
<MpbsCreate onSuccess={toggle3} />
</FeesDialog>
<CreateLettersDialog
isOpen={show4}
Expand Down Expand Up @@ -312,9 +323,10 @@ export const StudentFeeList = () => {
}}
/>
}
label="Frais rattrapage"
onClick={toggle}
/>
>
Frais de rattrapage
</ButtonBase>
</HaActionWrapper>
</Box>
}
Expand All @@ -326,7 +338,9 @@ export const StudentFeeList = () => {
/>
<FunctionField
label="Reste à payer"
render={(record) => renderMoney(record.remaining_amount)}
render={(record: {remaining_amount: number}) =>
renderMoney(record.remaining_amount)
}
/>
<FunctionField
source="comment"
Expand All @@ -352,7 +366,7 @@ export const StudentFeeList = () => {
</HaList>
<FeesDialog
title="Créer mon/mes frais de rattrapage"
children={<CatchupFeesCreate toggle={toggle} />}
children={<CatchupFeesCreate onSuccess={toggle} />}
show={show}
toggle={toggle}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/operations/utils/IconButtonWithTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {IconButton, Tooltip} from "@mui/material";
export const IconButtonWithTooltip: FC<{
title: string;
children: ReactNode;
disabled: boolean;
disabled?: boolean;
}> = ({title, children, disabled = false}) => {
return (
<Tooltip title={title}>
Expand Down
27 changes: 13 additions & 14 deletions src/providers/feeProvider.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {v4 as uuid} from "uuid";
import {WhoamiRoleEnum} from "@haapi/typescript-client";
import {payingApi} from "./api";
import {HaDataProviderType} from "./HaDataProviderType";
Expand Down Expand Up @@ -53,34 +54,32 @@ const feeProvider: HaDataProviderType = {
},

async saveOrUpdate(resources: Array<any>) {
const fees = resources[0];
const payload = resources[0];
const role = authProvider.getCachedRole();

if (fees?.psp_id) {
const fee = fees;
if (payload?.psp_id) {
const feeId = toApiIds(payload?.fee_id).feeId;

const feeId = toApiIds(fee?.id).feeId;

const createMpbs = {
student_id: fee?.student_id,
const mpbs = {
id: payload.mpbs_id ?? uuid(),
student_id: payload?.student_id,
fee_id: feeId,
psp_id: fee?.psp_id,
psp_type: fee?.psp_type,
psp_id: payload?.psp_id,
psp_type: payload?.psp_type,
};

return await payingApi()
.createMpbs(createMpbs?.student_id, createMpbs?.fee_id, createMpbs)
.then((result) => [{...result.data, ...fee}]);
.crupdateMpbs(mpbs?.student_id, mpbs?.fee_id, mpbs)
.then((result) => [{...result.data, ...payload}]);
}
console.log("role jhejhejheh", role);
if (role === WhoamiRoleEnum.STUDENT) {
return await payingApi()
.createStudentFees(fees[0].student_id, fees)
.createStudentFees(payload[0].student_id, payload)
.then((result) => result.data);
}
if (role === WhoamiRoleEnum.MANAGER) {
return await payingApi()
.crupdateStudentFees(fees)
.crupdateStudentFees(payload)
.then((result) => result.data);
}
},
Expand Down

0 comments on commit deafe34

Please sign in to comment.