| @@ -8,28 +8,21 @@ import { | |||||
| import { getUrl } from "../../url"; | import { getUrl } from "../../url"; | ||||
| export type UseSummary = { | export type UseSummary = { | ||||
| id: string; | |||||
| summary_yyyymm: string; | |||||
| summary_key1: string; | |||||
| summary_key2?: string; | |||||
| date_from: string; | |||||
| date_to: string; | |||||
| customer_code: string; | |||||
| customer_name: string; | customer_name: string; | ||||
| parking_name?: string; | |||||
| receipt_order_count: string; | receipt_order_count: string; | ||||
| mail_order_count: string; | mail_order_count: string; | ||||
| sms_send_count: string; | sms_send_count: string; | ||||
| sms_send_cost: string; | |||||
| is_fixed: boolean; | |||||
| updated_at: string; | |||||
| }; | }; | ||||
| // 利用実績一覧取得 ----------------------- | // 利用実績一覧取得 ----------------------- | ||||
| export type UseSummariesRequest = { | export type UseSummariesRequest = { | ||||
| summary_yyyymm: string; | |||||
| date_from: string; | |||||
| date_to: string; | |||||
| } & ListRequest; | } & ListRequest; | ||||
| export type UseSummariesResponse = { | export type UseSummariesResponse = { | ||||
| @@ -47,6 +47,7 @@ export const ApiId = { | |||||
| HT_CUSTOM_RECEIPT_ISSUING_ORDERS: id++, | HT_CUSTOM_RECEIPT_ISSUING_ORDERS: id++, | ||||
| HT_CUSTOM_RECEIPT_ISSUING_ORDER_CREATE: id++, | HT_CUSTOM_RECEIPT_ISSUING_ORDER_CREATE: id++, | ||||
| HT_CUSTOM_USE_SUMMARIES: id++, | HT_CUSTOM_USE_SUMMARIES: id++, | ||||
| HT_CUSTOM_USE_SUMMARY_DOWNLOAD_CSV: id++, | |||||
| } as const; | } as const; | ||||
| export type ApiId = (typeof ApiId)[keyof typeof ApiId]; | export type ApiId = (typeof ApiId)[keyof typeof ApiId]; | ||||
| @@ -40,12 +40,14 @@ const urls = { | |||||
| [A.HT_CUSTOM_RECEIPT_ISSUING_ORDER_CREATE]: | [A.HT_CUSTOM_RECEIPT_ISSUING_ORDER_CREATE]: | ||||
| "custom/hello-techno/receipt-issuing-order/create", | "custom/hello-techno/receipt-issuing-order/create", | ||||
| [A.HT_CUSTOM_USE_SUMMARIES]: "custom/hello-techno/use-summaries", | [A.HT_CUSTOM_USE_SUMMARIES]: "custom/hello-techno/use-summaries", | ||||
| [A.HT_CUSTOM_USE_SUMMARY_DOWNLOAD_CSV]: "custom/hello-techno/use-summary/csv", | |||||
| }; | }; | ||||
| const prefixs = { | const prefixs = { | ||||
| [A.CSRF_TOKEN]: "", | [A.CSRF_TOKEN]: "", | ||||
| [A.DOWNLOAD_RECEIPT]: "", | [A.DOWNLOAD_RECEIPT]: "", | ||||
| [A.DOWNLOAD_RECEIPT_LETTER]: "", | [A.DOWNLOAD_RECEIPT_LETTER]: "", | ||||
| [A.HT_CUSTOM_USE_SUMMARY_DOWNLOAD_CSV]: "", | |||||
| }; | }; | ||||
| const DEFAULT_API_URL_PREFIX = "api"; | const DEFAULT_API_URL_PREFIX = "api"; | ||||
| @@ -1,5 +1,5 @@ | |||||
| // @mui | // @mui | ||||
| import { Theme } from '@mui/material/styles'; | |||||
| import { Theme } from "@mui/material/styles"; | |||||
| import { | import { | ||||
| Box, | Box, | ||||
| SxProps, | SxProps, | ||||
| @@ -8,7 +8,7 @@ import { | |||||
| TableCell, | TableCell, | ||||
| TableHead, | TableHead, | ||||
| TableSortLabel, | TableSortLabel, | ||||
| } from '@mui/material'; | |||||
| } from "@mui/material"; | |||||
| // ---------------------------------------------------------------------- | // ---------------------------------------------------------------------- | ||||
| @@ -16,20 +16,29 @@ const visuallyHidden = { | |||||
| border: 0, | border: 0, | ||||
| margin: -1, | margin: -1, | ||||
| padding: 0, | padding: 0, | ||||
| width: '1px', | |||||
| height: '1px', | |||||
| overflow: 'hidden', | |||||
| position: 'absolute', | |||||
| whiteSpace: 'nowrap', | |||||
| clip: 'rect(0 0 0 0)', | |||||
| width: "1px", | |||||
| height: "1px", | |||||
| overflow: "hidden", | |||||
| position: "absolute", | |||||
| whiteSpace: "nowrap", | |||||
| clip: "rect(0 0 0 0)", | |||||
| } as const; | } as const; | ||||
| // ---------------------------------------------------------------------- | // ---------------------------------------------------------------------- | ||||
| export type HeadLabelProps = { | |||||
| id: string; | |||||
| label?: string; | |||||
| align?: "inherit" | "left" | "center" | "right" | "justify"; | |||||
| width?: number | string; | |||||
| minWidth?: number | string; | |||||
| needSort?: boolean; | |||||
| // { id: "customer_name", label: "運営会社名", align: "left" }, | |||||
| }; | |||||
| type Props = { | type Props = { | ||||
| order?: 'asc' | 'desc'; | |||||
| order?: "asc" | "desc"; | |||||
| orderBy?: string; | orderBy?: string; | ||||
| headLabel: any[]; | |||||
| headLabel: HeadLabelProps[]; | |||||
| rowCount?: number; | rowCount?: number; | ||||
| numSelected?: number; | numSelected?: number; | ||||
| onSort?: (id: string) => void; | onSort?: (id: string) => void; | ||||
| @@ -65,7 +74,7 @@ export default function TableHeadCustom({ | |||||
| {headLabel.map((headCell) => ( | {headLabel.map((headCell) => ( | ||||
| <TableCell | <TableCell | ||||
| key={headCell.id} | key={headCell.id} | ||||
| align={headCell.align || 'left'} | |||||
| align={headCell.align || "left"} | |||||
| sortDirection={orderBy === headCell.id ? order : false} | sortDirection={orderBy === headCell.id ? order : false} | ||||
| sx={{ width: headCell.width, minWidth: headCell.minWidth }} | sx={{ width: headCell.width, minWidth: headCell.minWidth }} | ||||
| > | > | ||||
| @@ -73,15 +82,17 @@ export default function TableHeadCustom({ | |||||
| <TableSortLabel | <TableSortLabel | ||||
| hideSortIcon | hideSortIcon | ||||
| active={orderBy === headCell.id} | active={orderBy === headCell.id} | ||||
| direction={orderBy === headCell.id ? order : 'asc'} | |||||
| direction={orderBy === headCell.id ? order : "asc"} | |||||
| onClick={() => onSort(headCell.id)} | onClick={() => onSort(headCell.id)} | ||||
| sx={{ textTransform: 'capitalize' }} | |||||
| sx={{ textTransform: "capitalize" }} | |||||
| > | > | ||||
| {headCell.label} | {headCell.label} | ||||
| {orderBy === headCell.id ? ( | {orderBy === headCell.id ? ( | ||||
| <Box sx={{ ...visuallyHidden }}> | <Box sx={{ ...visuallyHidden }}> | ||||
| {order === 'desc' ? 'sorted descending' : 'sorted ascending'} | |||||
| {order === "desc" | |||||
| ? "sorted descending" | |||||
| : "sorted ascending"} | |||||
| </Box> | </Box> | ||||
| ) : null} | ) : null} | ||||
| </TableSortLabel> | </TableSortLabel> | ||||
| @@ -30,7 +30,7 @@ export type UseTableReturn<T extends object> = { | |||||
| }; | }; | ||||
| export default function useTable<T extends object>(): UseTableReturn<T> { | export default function useTable<T extends object>(): UseTableReturn<T> { | ||||
| const ROWS_PER_PAGES = [20, 50, 100]; | |||||
| const ROWS_PER_PAGES = [50, 100, 500]; | |||||
| const ORDER = "order"; | const ORDER = "order"; | ||||
| const SORT = "sort"; | const SORT = "sort"; | ||||
| @@ -16,6 +16,7 @@ import { Contract, getContracts } from "api/contract"; | |||||
| import { PageID, TabID } from "codes/page"; | import { PageID, TabID } from "codes/page"; | ||||
| import { FormProvider, RHFTextField } from "components/hook-form"; | import { FormProvider, RHFTextField } from "components/hook-form"; | ||||
| import { TableHeadCustom } from "components/table"; | import { TableHeadCustom } from "components/table"; | ||||
| import { HeadLabelProps } from "components/table/TableHeadCustom"; | |||||
| import { SearchConditionContextProvider } from "contexts/SearchConditionContext"; | import { SearchConditionContextProvider } from "contexts/SearchConditionContext"; | ||||
| import useAPICall from "hooks/useAPICall"; | import useAPICall from "hooks/useAPICall"; | ||||
| import useAuth from "hooks/useAuth"; | import useAuth from "hooks/useAuth"; | ||||
| @@ -155,7 +156,7 @@ function SearchBox({ table }: CommonProps) { | |||||
| } | } | ||||
| function TableBox({ table }: CommonProps) { | function TableBox({ table }: CommonProps) { | ||||
| const TABLE_HEAD = [ | |||||
| const TABLE_HEAD: HeadLabelProps[] = [ | |||||
| { id: "id", label: "ID", align: "left" }, | { id: "id", label: "ID", align: "left" }, | ||||
| { id: "name", label: "名前", align: "left" }, | { id: "name", label: "名前", align: "left" }, | ||||
| ]; | ]; | ||||
| @@ -50,6 +50,7 @@ import RHFDatePicker from "components/hook-form/RHFDatePicker"; | |||||
| import { dateParse, formatDateStr } from "utils/datetime"; | import { dateParse, formatDateStr } from "utils/datetime"; | ||||
| import { Clear } from "@mui/icons-material"; | import { Clear } from "@mui/icons-material"; | ||||
| import { LoginUser, getLoginUsers } from "api/login-user"; | import { LoginUser, getLoginUsers } from "api/login-user"; | ||||
| import { HeadLabelProps } from "components/table/TableHeadCustom"; | |||||
| export default function LoginUserList() { | export default function LoginUserList() { | ||||
| const { setHeaderTitle, setTabs } = useDashboard( | const { setHeaderTitle, setTabs } = useDashboard( | ||||
| @@ -217,7 +218,7 @@ function SearchBox({ table }: CommonProps) { | |||||
| } | } | ||||
| function TableBox({ table }: CommonProps) { | function TableBox({ table }: CommonProps) { | ||||
| const TABLE_HEAD = [ | |||||
| const TABLE_HEAD: HeadLabelProps[] = [ | |||||
| { id: "name", label: "名前", align: "left" }, | { id: "name", label: "名前", align: "left" }, | ||||
| { id: "email", label: "Email", align: "left" }, | { id: "email", label: "Email", align: "left" }, | ||||
| ]; | ]; | ||||
| @@ -30,6 +30,7 @@ import { PageID, TabID } from "codes/page"; | |||||
| import { FormProvider, RHFCheckbox, RHFTextField } from "components/hook-form"; | import { FormProvider, RHFCheckbox, RHFTextField } from "components/hook-form"; | ||||
| import RHFDatePicker from "components/hook-form/RHFDatePicker"; | import RHFDatePicker from "components/hook-form/RHFDatePicker"; | ||||
| import { TableHeadCustom } from "components/table"; | import { TableHeadCustom } from "components/table"; | ||||
| import { HeadLabelProps } from "components/table/TableHeadCustom"; | |||||
| import { SearchConditionContextProvider } from "contexts/SearchConditionContext"; | import { SearchConditionContextProvider } from "contexts/SearchConditionContext"; | ||||
| import useAPICall from "hooks/useAPICall"; | import useAPICall from "hooks/useAPICall"; | ||||
| import useAuth from "hooks/useAuth"; | import useAuth from "hooks/useAuth"; | ||||
| @@ -43,6 +44,19 @@ import { useForm } from "react-hook-form"; | |||||
| import { getPath } from "routes/path"; | import { getPath } from "routes/path"; | ||||
| import { dateParse, formatDateStr } from "utils/datetime"; | import { dateParse, formatDateStr } from "utils/datetime"; | ||||
| export const SearchParam = { | |||||
| CUSTOMER_NAME: "customer_name", | |||||
| PARKING_NAME: "parking_name", | |||||
| INCLUDE_DONE: "include_done", | |||||
| STATUS: "status", | |||||
| SMS_PHONE_NUMBER: "sms_phone_number", | |||||
| HANDLER_NAME: "handler_name", | |||||
| ORDER_DATE_FROM: "order_date_from", | |||||
| ORDER_DATE_TO: "order_date_to", | |||||
| RECEIPT_NO: "receipt_no", | |||||
| } as const; | |||||
| export type SearchParam = (typeof SearchParam)[keyof typeof SearchParam]; | |||||
| export default function ReceiptIssuingOrderList() { | export default function ReceiptIssuingOrderList() { | ||||
| const { setHeaderTitle, setTabs } = useDashboard( | const { setHeaderTitle, setTabs } = useDashboard( | ||||
| PageID.DASHBOARD_RECEIPT_ISSUING_ORDER_LIST_CUSTOM_HELLO_TECHNO, | PageID.DASHBOARD_RECEIPT_ISSUING_ORDER_LIST_CUSTOM_HELLO_TECHNO, | ||||
| @@ -73,15 +87,15 @@ function Page() { | |||||
| } | } | ||||
| type FormProps = { | type FormProps = { | ||||
| customer_name: string; | |||||
| parking_name: string; | |||||
| include_done: boolean; | |||||
| status: string; | |||||
| sms_phone_number: string; | |||||
| handler_name: string; | |||||
| order_date_from: Date | null; | |||||
| order_date_to: Date | null; | |||||
| receipt_no: string; | |||||
| [SearchParam.CUSTOMER_NAME]: string; | |||||
| [SearchParam.PARKING_NAME]: string; | |||||
| [SearchParam.INCLUDE_DONE]: boolean; | |||||
| [SearchParam.STATUS]: string; | |||||
| [SearchParam.SMS_PHONE_NUMBER]: string; | |||||
| [SearchParam.HANDLER_NAME]: string; | |||||
| [SearchParam.ORDER_DATE_FROM]: Date | null; | |||||
| [SearchParam.ORDER_DATE_TO]: Date | null; | |||||
| [SearchParam.RECEIPT_NO]: string; | |||||
| }; | }; | ||||
| type CommonProps = { | type CommonProps = { | ||||
| table: UseTableReturn<ReceiptIssuingOrderHTCustom>; | table: UseTableReturn<ReceiptIssuingOrderHTCustom>; | ||||
| @@ -215,7 +229,7 @@ function SearchBox({ table }: CommonProps) { | |||||
| <Typography>担当者</Typography> | <Typography>担当者</Typography> | ||||
| <Stack direction="row"> | <Stack direction="row"> | ||||
| <RHFTextField | <RHFTextField | ||||
| name="handler_name" | |||||
| name={SearchParam.HANDLER_NAME} | |||||
| fullWidth={false} | fullWidth={false} | ||||
| onBlur={handleBlur} | onBlur={handleBlur} | ||||
| /> | /> | ||||
| @@ -232,13 +246,17 @@ function SearchBox({ table }: CommonProps) { | |||||
| <Grid item xs={3} lg={2}> | <Grid item xs={3} lg={2}> | ||||
| <Stack> | <Stack> | ||||
| <Typography>ステータス</Typography> | <Typography>ステータス</Typography> | ||||
| <RHFTextField name="status" onBlur={handleBlur} /> | |||||
| <RHFTextField name={SearchParam.STATUS} onBlur={handleBlur} /> | |||||
| </Stack> | </Stack> | ||||
| </Grid> | </Grid> | ||||
| <Grid item> | <Grid item> | ||||
| <Stack> | <Stack> | ||||
| <Typography>完了を含む</Typography> | <Typography>完了を含む</Typography> | ||||
| <RHFCheckbox name="include_done" label="" sx={{ mx: "auto" }} /> | |||||
| <RHFCheckbox | |||||
| name={SearchParam.INCLUDE_DONE} | |||||
| label="" | |||||
| sx={{ mx: "auto" }} | |||||
| /> | |||||
| </Stack> | </Stack> | ||||
| </Grid> | </Grid> | ||||
| </Grid> | </Grid> | ||||
| @@ -246,22 +264,31 @@ function SearchBox({ table }: CommonProps) { | |||||
| <Grid item xs={3} lg={2}> | <Grid item xs={3} lg={2}> | ||||
| <Stack> | <Stack> | ||||
| <Typography>運営会社</Typography> | <Typography>運営会社</Typography> | ||||
| <RHFTextField name="customer_name" onBlur={handleBlur} /> | |||||
| <RHFTextField | |||||
| name={SearchParam.CUSTOMER_NAME} | |||||
| onBlur={handleBlur} | |||||
| /> | |||||
| </Stack> | </Stack> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={3} lg={2}> | <Grid item xs={3} lg={2}> | ||||
| <Stack> | <Stack> | ||||
| <Typography>駐車場名</Typography> | <Typography>駐車場名</Typography> | ||||
| <RHFTextField name="parking_name" onBlur={handleBlur} /> | |||||
| <RHFTextField | |||||
| name={SearchParam.PARKING_NAME} | |||||
| onBlur={handleBlur} | |||||
| /> | |||||
| </Stack> | </Stack> | ||||
| </Grid> | </Grid> | ||||
| <Grid item xs={3} lg={2}> | <Grid item xs={3} lg={2}> | ||||
| <Typography>電話番号</Typography> | <Typography>電話番号</Typography> | ||||
| <RHFTextField name="sms_phone_number" onBlur={handleBlur} /> | |||||
| <RHFTextField | |||||
| name={SearchParam.SMS_PHONE_NUMBER} | |||||
| onBlur={handleBlur} | |||||
| /> | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={3} lg={2}> | <Grid item xs={3} lg={2}> | ||||
| <Typography>領収証番号</Typography> | <Typography>領収証番号</Typography> | ||||
| <RHFTextField name="receipt_no" onBlur={handleBlur} /> | |||||
| <RHFTextField name={SearchParam.RECEIPT_NO} onBlur={handleBlur} /> | |||||
| </Grid> | </Grid> | ||||
| <Grid item xs={3} lg={2}> | <Grid item xs={3} lg={2}> | ||||
| <Typography>受付時刻</Typography> | <Typography>受付時刻</Typography> | ||||
| @@ -309,7 +336,7 @@ function SearchBox({ table }: CommonProps) { | |||||
| <Stack direction="row" spacing={2}> | <Stack direction="row" spacing={2}> | ||||
| <Box> | <Box> | ||||
| <Typography>From</Typography> | <Typography>From</Typography> | ||||
| <RHFDatePicker name="order_date_from" /> | |||||
| <RHFDatePicker name={SearchParam.ORDER_DATE_FROM} /> | |||||
| </Box> | </Box> | ||||
| <Box> | <Box> | ||||
| <Typography> </Typography> | <Typography> </Typography> | ||||
| @@ -317,7 +344,7 @@ function SearchBox({ table }: CommonProps) { | |||||
| </Box> | </Box> | ||||
| <Box> | <Box> | ||||
| <Typography>To</Typography> | <Typography>To</Typography> | ||||
| <RHFDatePicker name="order_date_to" /> | |||||
| <RHFDatePicker name={SearchParam.ORDER_DATE_TO} /> | |||||
| </Box> | </Box> | ||||
| </Stack> | </Stack> | ||||
| </DialogContent> | </DialogContent> | ||||
| @@ -336,7 +363,7 @@ function SearchBox({ table }: CommonProps) { | |||||
| } | } | ||||
| function TableBox({ table }: CommonProps) { | function TableBox({ table }: CommonProps) { | ||||
| const TABLE_HEAD = [ | |||||
| const TABLE_HEAD: HeadLabelProps[] = [ | |||||
| { id: "order_datetime", label: "受付時刻", align: "left" }, | { id: "order_datetime", label: "受付時刻", align: "left" }, | ||||
| { id: "customer_name", label: "運営会社名", align: "left" }, | { id: "customer_name", label: "運営会社名", align: "left" }, | ||||
| { id: "parking_name", label: "駐車場名", align: "left" }, | { id: "parking_name", label: "駐車場名", align: "left" }, | ||||
| @@ -2,6 +2,7 @@ import { | |||||
| Box, | Box, | ||||
| Button, | Button, | ||||
| Grid, | Grid, | ||||
| Stack, | |||||
| Table, | Table, | ||||
| TableBody, | TableBody, | ||||
| TableCell, | TableCell, | ||||
| @@ -10,24 +11,31 @@ import { | |||||
| TableRow, | TableRow, | ||||
| Typography, | Typography, | ||||
| } from "@mui/material"; | } from "@mui/material"; | ||||
| import { ApiId } from "api"; | |||||
| import { | import { | ||||
| UseSummary, | UseSummary, | ||||
| getUseSummaries, | getUseSummaries, | ||||
| getUseSummaryYYYYMMs, | getUseSummaryYYYYMMs, | ||||
| } from "api/custom/hello-techno/use-summary"; | } from "api/custom/hello-techno/use-summary"; | ||||
| import { getFullUrl } from "api/url"; | |||||
| import { PageID, TabID } from "codes/page"; | import { PageID, TabID } from "codes/page"; | ||||
| import { FormProvider } from "components/hook-form"; | import { FormProvider } from "components/hook-form"; | ||||
| import RHFDatePicker from "components/hook-form/RHFDatePicker"; | |||||
| import RHFSelect, { SelectOptionProps } from "components/hook-form/RHFSelect"; | import RHFSelect, { SelectOptionProps } from "components/hook-form/RHFSelect"; | ||||
| import { TableHeadCustom } from "components/table"; | import { TableHeadCustom } from "components/table"; | ||||
| import { HeadLabelProps } from "components/table/TableHeadCustom"; | |||||
| import { SearchConditionContextProvider } from "contexts/SearchConditionContext"; | import { SearchConditionContextProvider } from "contexts/SearchConditionContext"; | ||||
| import useAPICall from "hooks/useAPICall"; | import useAPICall from "hooks/useAPICall"; | ||||
| import useDashboard from "hooks/useDashBoard"; | import useDashboard from "hooks/useDashBoard"; | ||||
| import useNavigateCustom from "hooks/useNavigateCustom"; | import useNavigateCustom from "hooks/useNavigateCustom"; | ||||
| import useSearchConditionContext from "hooks/useSearchConditionContext"; | import useSearchConditionContext from "hooks/useSearchConditionContext"; | ||||
| import useTable, { UseTableReturn } from "hooks/useTable"; | import useTable, { UseTableReturn } from "hooks/useTable"; | ||||
| import { SearchParam } from "pages/dashboard/receipt-issuing-order/custom/hello-techno/list"; | |||||
| import { useEffect, useMemo, useState } from "react"; | import { useEffect, useMemo, useState } from "react"; | ||||
| import { useForm } from "react-hook-form"; | import { useForm } from "react-hook-form"; | ||||
| import { getPath } from "routes/path"; | |||||
| import { sprintf } from "sprintf-js"; | import { sprintf } from "sprintf-js"; | ||||
| import { dateParse, formatDateStr } from "utils/datetime"; | |||||
| export default function UseSummaryList() { | export default function UseSummaryList() { | ||||
| const { setHeaderTitle, setTabs } = useDashboard( | const { setHeaderTitle, setTabs } = useDashboard( | ||||
| @@ -60,7 +68,8 @@ function Page() { | |||||
| } | } | ||||
| type FormProps = { | type FormProps = { | ||||
| summary_yyyymm: string; | |||||
| date_from: Date | null; | |||||
| date_to: Date | null; | |||||
| }; | }; | ||||
| type CommonProps = { | type CommonProps = { | ||||
| @@ -76,50 +85,15 @@ function SearchBox({ table }: CommonProps) { | |||||
| const form = useForm<FormProps>({ | const form = useForm<FormProps>({ | ||||
| defaultValues: { | defaultValues: { | ||||
| summary_yyyymm: "", | |||||
| date_from: null, | |||||
| date_to: null, | |||||
| }, | }, | ||||
| }); | }); | ||||
| const selectedYYYYMM = form.watch("summary_yyyymm"); | |||||
| const dateFrom = form.watch("date_from"); | |||||
| const dateTo = form.watch("date_to"); | |||||
| const [yyyymm, setYYYYMM] = useState<string[] | null>(null); | |||||
| const yyyymmOptions: SelectOptionProps[] = useMemo(() => { | |||||
| if (yyyymm === null) return []; | |||||
| return yyyymm.map((ele) => { | |||||
| return { | |||||
| value: ele, | |||||
| label: sprintf("%s/%s", ele.substring(0, 4), ele.substring(4, 6)), | |||||
| }; | |||||
| }); | |||||
| }, [yyyymm]); | |||||
| const downloadCsvUrl = useMemo(() => { | |||||
| if (!selectedYYYYMM) return ""; | |||||
| const param = new URLSearchParams({ | |||||
| summary_yyyymm: selectedYYYYMM, | |||||
| }); | |||||
| return ( | |||||
| process.env.REACT_APP_HOST_API_KEY + | |||||
| "/custom/hello-techno/use-summary/csv?" + | |||||
| param.toString() | |||||
| ); | |||||
| }, [selectedYYYYMM]); | |||||
| const { callAPI: callGetUseSummaryYYYYMMs } = useAPICall({ | |||||
| apiMethod: getUseSummaryYYYYMMs, | |||||
| backDrop: true, | |||||
| onSuccess: ({ data: { records } }) => { | |||||
| setYYYYMM(records); | |||||
| }, | |||||
| }); | |||||
| const { | |||||
| callAPI: callGetContracts, | |||||
| makeSendData, | |||||
| sending, | |||||
| } = useAPICall({ | |||||
| const { callAPI: callGetContracts } = useAPICall({ | |||||
| apiMethod: getUseSummaries, | apiMethod: getUseSummaries, | ||||
| backDrop: true, | backDrop: true, | ||||
| onSuccess: ({ data }) => { | onSuccess: ({ data }) => { | ||||
| @@ -134,61 +108,59 @@ function SearchBox({ table }: CommonProps) { | |||||
| const addCondition = (data: FormProps) => { | const addCondition = (data: FormProps) => { | ||||
| add({ | add({ | ||||
| ...data, | ...data, | ||||
| date_from: formatDateStr(data.date_from), | |||||
| date_to: formatDateStr(data.date_to), | |||||
| }); | }); | ||||
| }; | }; | ||||
| const fetch = async () => { | const fetch = async () => { | ||||
| const dateFrom = form.getValues("date_from"); | |||||
| const dateTo = form.getValues("date_to"); | |||||
| if (!dateFrom || !dateTo) return; | |||||
| const sendData = { | const sendData = { | ||||
| ...condition, | |||||
| ...form.getValues(), | |||||
| date_from: formatDateStr(dateFrom), | |||||
| date_to: formatDateStr(dateTo), | |||||
| }; | }; | ||||
| if (sendData.summary_yyyymm) { | |||||
| callGetContracts(sendData); | |||||
| } | |||||
| callGetContracts(sendData); | |||||
| }; | }; | ||||
| // 初期値設定 | // 初期値設定 | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (initialized && yyyymm !== null) { | |||||
| form.setValue( | |||||
| "summary_yyyymm", | |||||
| get("summary_yyyymm", yyyymm.find(() => true) ?? "") | |||||
| ); | |||||
| addCondition(form.getValues()); | |||||
| if (initialized) { | |||||
| form.setValue("date_from", dateParse(get("date_from"))); | |||||
| form.setValue("date_to", dateParse(get("date_to"))); | |||||
| } | } | ||||
| }, [initialized, condition, yyyymm]); | |||||
| }, [initialized]); | |||||
| // Fetchアクション | // Fetchアクション | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (initialized) { | if (initialized) { | ||||
| fetch(); | fetch(); | ||||
| } | } | ||||
| }, [condition, initialized, selectedYYYYMM]); | |||||
| }, [condition, initialized]); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| callGetUseSummaryYYYYMMs({}); | |||||
| }, []); | |||||
| addCondition(form.getValues()); | |||||
| }, [dateFrom, dateTo]); | |||||
| return ( | return ( | ||||
| <FormProvider methods={form} onSubmit={form.handleSubmit(handleSubmit)}> | <FormProvider methods={form} onSubmit={form.handleSubmit(handleSubmit)}> | ||||
| <Box sx={{ p: 1, m: 1 }}> | <Box sx={{ p: 1, m: 1 }}> | ||||
| <Grid container spacing={2}> | <Grid container spacing={2}> | ||||
| <Grid item xs={3} lg={2}> | <Grid item xs={3} lg={2}> | ||||
| <Typography>年月</Typography> | |||||
| <RHFSelect | |||||
| options={yyyymmOptions} | |||||
| name="summary_yyyymm" | |||||
| <Typography>開始年月日</Typography> | |||||
| <RHFDatePicker | |||||
| name="date_from" | |||||
| size="small" | size="small" | ||||
| onChange={() => { | |||||
| console.log("ge"); | |||||
| }} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| {!!selectedYYYYMM && ( | |||||
| <Grid item xs={3} lg={2}> | |||||
| <Typography>CSV</Typography> | |||||
| <Button variant="contained" color="info" href={downloadCsvUrl}> | |||||
| ダウンロード | |||||
| </Button> | |||||
| </Grid> | |||||
| )} | |||||
| <Grid item xs={3} lg={2}> | |||||
| <Typography>終了年月日</Typography> | |||||
| <RHFDatePicker name="date_to" size="small" /> | |||||
| </Grid> | |||||
| </Grid> | </Grid> | ||||
| </Box> | </Box> | ||||
| </FormProvider> | </FormProvider> | ||||
| @@ -196,12 +168,12 @@ function SearchBox({ table }: CommonProps) { | |||||
| } | } | ||||
| function TableBox({ table }: CommonProps) { | function TableBox({ table }: CommonProps) { | ||||
| const TABLE_HEAD = [ | |||||
| const TABLE_HEAD: HeadLabelProps[] = [ | |||||
| { id: "customer_name", label: "運営会社名", align: "left" }, | { id: "customer_name", label: "運営会社名", align: "left" }, | ||||
| { id: "parking_name", label: "駐車場名", align: "left" }, | |||||
| { id: "receipt_order_count", label: "領収証発行件数", align: "left" }, | { id: "receipt_order_count", label: "領収証発行件数", align: "left" }, | ||||
| { id: "mail_order_count", label: "郵送依頼件数", align: "left" }, | { id: "mail_order_count", label: "郵送依頼件数", align: "left" }, | ||||
| { id: "sms_send_count", label: "SMS送信件数", align: "left" }, | { id: "sms_send_count", label: "SMS送信件数", align: "left" }, | ||||
| { id: "actions", label: "アクション", align: "left", needSort: false }, | |||||
| ]; | ]; | ||||
| const { | const { | ||||
| order, | order, | ||||
| @@ -267,13 +239,51 @@ type RowProps = { | |||||
| data: UseSummary; | data: UseSummary; | ||||
| }; | }; | ||||
| function Row({ data }: RowProps) { | function Row({ data }: RowProps) { | ||||
| const { navigateWhenChanged } = useNavigateCustom(); | |||||
| const handleClickDetail = () => { | |||||
| const param = new URLSearchParams({ | |||||
| [SearchParam.CUSTOMER_NAME]: data.customer_name, | |||||
| [SearchParam.ORDER_DATE_FROM]: data.date_from, | |||||
| [SearchParam.ORDER_DATE_TO]: data.date_to, | |||||
| [SearchParam.INCLUDE_DONE]: "1", | |||||
| }); | |||||
| navigateWhenChanged( | |||||
| getPath(PageID.DASHBOARD_RECEIPT_ISSUING_ORDER_LIST_CUSTOM_HELLO_TECHNO), | |||||
| param | |||||
| ); | |||||
| }; | |||||
| const downloadCsvUrl = useMemo(() => { | |||||
| const param = new URLSearchParams({ | |||||
| date_from: data.date_from, | |||||
| date_to: data.date_to, | |||||
| customer_code: data.customer_code, | |||||
| }); | |||||
| return ( | |||||
| getFullUrl(ApiId.HT_CUSTOM_USE_SUMMARY_DOWNLOAD_CSV) + | |||||
| "?" + | |||||
| param.toString() | |||||
| ); | |||||
| }, [data]); | |||||
| return ( | return ( | ||||
| <TableRow> | <TableRow> | ||||
| <TableCell>{data.customer_name}</TableCell> | <TableCell>{data.customer_name}</TableCell> | ||||
| <TableCell>{data.parking_name}</TableCell> | |||||
| <TableCell>{data.receipt_order_count}件</TableCell> | <TableCell>{data.receipt_order_count}件</TableCell> | ||||
| <TableCell>{data.mail_order_count}件</TableCell> | <TableCell>{data.mail_order_count}件</TableCell> | ||||
| <TableCell>{data.sms_send_count}件</TableCell> | <TableCell>{data.sms_send_count}件</TableCell> | ||||
| <TableCell> | |||||
| <Stack direction="row" spacing={2}> | |||||
| <Button variant="contained" onClick={handleClickDetail}> | |||||
| 詳細 | |||||
| </Button> | |||||
| <Button variant="contained" href={downloadCsvUrl}> | |||||
| CSV | |||||
| </Button> | |||||
| </Stack> | |||||
| </TableCell> | |||||
| </TableRow> | </TableRow> | ||||
| ); | ); | ||||
| } | } | ||||