| @@ -1,6 +1,6 @@ | |||||
| import { APICommonResponse, ApiId, HttpMethod, request } from ".."; | import { APICommonResponse, ApiId, HttpMethod, request } from ".."; | ||||
| import { ReceiptIssuingOrder } from "../receipt-issuing-order"; | |||||
| import { getUrl } from "../url"; | import { getUrl } from "../url"; | ||||
| import { AppReceiptIssuingOrder } from "./receipt-issuing-order"; | |||||
| export type CheckTokenRequest = { | export type CheckTokenRequest = { | ||||
| access_token: string; | access_token: string; | ||||
| @@ -8,7 +8,7 @@ export type CheckTokenRequest = { | |||||
| export type CheckTokenResponse = { | export type CheckTokenResponse = { | ||||
| data: { | data: { | ||||
| receipt_issuing_order: ReceiptIssuingOrder; | |||||
| receipt_issuing_order: AppReceiptIssuingOrder; | |||||
| }; | }; | ||||
| } & APICommonResponse; | } & APICommonResponse; | ||||
| export const checkToken = async (data: CheckTokenRequest) => { | export const checkToken = async (data: CheckTokenRequest) => { | ||||
| @@ -1,7 +1,25 @@ | |||||
| import { APICommonResponse, ApiId, HttpMethod, makeParam, request } from ".."; | |||||
| import { ReceiptIssuingOrder } from "../receipt-issuing-order"; | |||||
| import { ApiId, HttpMethod, makeParam, request } from ".."; | |||||
| import { getUrl } from "../url"; | import { getUrl } from "../url"; | ||||
| export type AppReceiptIssuingOrder = { | |||||
| id: string; | |||||
| access_token_expires_at: string; | |||||
| receipt_use_date?: string; | |||||
| receipt_shop_name?: string; | |||||
| receipt_issuer?: string; | |||||
| receipt_purpose?: string; | |||||
| receipt_name?: string; | |||||
| receipt_amount?: string; | |||||
| confirmed: boolean; | |||||
| status_order_mail_datetime?: string; | |||||
| status_mail_post_date?: string; | |||||
| updated_at: string; | |||||
| }; | |||||
| // 領収証確定 | // 領収証確定 | ||||
| export type ConfirmRequest = { | export type ConfirmRequest = { | ||||
| id: string; | id: string; | ||||
| @@ -5,6 +5,7 @@ import { | |||||
| makeFormData, | makeFormData, | ||||
| request, | request, | ||||
| } from "api"; | } from "api"; | ||||
| import { ReceiptIssuingOrder } from "api/receipt-issuing-order"; | |||||
| import { getUrl } from "api/url"; | import { getUrl } from "api/url"; | ||||
| export type HTCustomer = { | export type HTCustomer = { | ||||
| @@ -50,19 +51,16 @@ export const createReceiptIssuingOrder = async ( | |||||
| return res; | return res; | ||||
| }; | }; | ||||
| export type ReceiptIssuingOrder = { | |||||
| id: string; | |||||
| order_datetime: string; | |||||
| export type ReceiptIssuingOrderHTCustom = { | |||||
| customer_code: string; | customer_code: string; | ||||
| parking_management_code: string; | parking_management_code: string; | ||||
| customer_name: string; | customer_name: string; | ||||
| parking_name: string; | parking_name: string; | ||||
| status_name: string; | |||||
| handler_id: string; | |||||
| handler_name: string; | |||||
| }; | |||||
| adjust_seq_no?: number; | |||||
| } & ReceiptIssuingOrder; | |||||
| export type ReceiptIssuingOrdersRequest = { | export type ReceiptIssuingOrdersRequest = { | ||||
| id?: string; | |||||
| customer_code?: string; | customer_code?: string; | ||||
| customer_name?: string; | customer_name?: string; | ||||
| parking_management_code?: string; | parking_management_code?: string; | ||||
| @@ -71,7 +69,7 @@ export type ReceiptIssuingOrdersRequest = { | |||||
| export type ReceiptIssuingOrdersResponse = { | export type ReceiptIssuingOrdersResponse = { | ||||
| data: { | data: { | ||||
| records: ReceiptIssuingOrder[]; | |||||
| records: ReceiptIssuingOrderHTCustom[]; | |||||
| }; | }; | ||||
| } & APICommonResponse; | } & APICommonResponse; | ||||
| @@ -24,6 +24,8 @@ export const ApiId = { | |||||
| RECEIPT_ISSUING_ORDERS: id++, | RECEIPT_ISSUING_ORDERS: id++, | ||||
| RECEIPT_ISSUING_ORDER: id++, | RECEIPT_ISSUING_ORDER: id++, | ||||
| RECEIPT_ISSUING_ORDER_CREATE: id++, | RECEIPT_ISSUING_ORDER_CREATE: id++, | ||||
| RECEIPT_ISSUING_ORDER_MAIL_POST_COMPLETE: id++, | |||||
| DOWNLOAD_RECEIPT_LETTER: id++, | |||||
| // FOR CUSTOM | // FOR CUSTOM | ||||
| HT_CUSTOM_CUSTOMERS: id++, | HT_CUSTOM_CUSTOMERS: id++, | ||||
| @@ -3,19 +3,42 @@ import { getUrl } from "./url"; | |||||
| export type ReceiptIssuingOrder = { | export type ReceiptIssuingOrder = { | ||||
| id: string; | id: string; | ||||
| order_datetime: string; | |||||
| status_name: string; | |||||
| handler_id: string; | |||||
| handler_name: string; | |||||
| summary_key1?: string; | |||||
| summary_key2?: string; | |||||
| status_done: boolean; | |||||
| contract_id: string; | |||||
| access_token_expires_at: string; | |||||
| status_sms_send_datetime?: string; | |||||
| status_first_access_datetime?: string; | |||||
| status_receipt_confirm_datetime?: string; | |||||
| status_order_mail_datetime?: string; | |||||
| status_mail_download_datetime?: string; | |||||
| status_mail_post_date?: string; | |||||
| status_receipt_download_datetime?: string; | |||||
| status_receipt_email_send_order_datetime?: string; | |||||
| status_receipt_email_send_datetime?: string; | |||||
| sms_phone_number?: string; | |||||
| sms_send_success?: boolean; | |||||
| receipt_no?: string; | |||||
| receipt_use_date?: string; | receipt_use_date?: string; | ||||
| receipt_shop_name?: string; | receipt_shop_name?: string; | ||||
| receipt_issuer?: string; | receipt_issuer?: string; | ||||
| receipt_purpose?: string; | receipt_purpose?: string; | ||||
| receipt_name?: string; | receipt_name?: string; | ||||
| receipt_amount?: string; | |||||
| confirmed: boolean; | |||||
| status_order_mail_datetime?: string; | |||||
| status_mail_post_date?: string; | |||||
| receipt_invoice_no?: string; | |||||
| receipt_amount?: number; | |||||
| email?: string; | |||||
| mail_pref_code?: string; | |||||
| mail_zip_code?: string; | |||||
| mail_address1?: string; | |||||
| mail_address2?: string; | |||||
| mail_address3?: string; | |||||
| mail_name?: string; | |||||
| memo?: string; | |||||
| updated_at: string; | updated_at: string; | ||||
| }; | }; | ||||
| @@ -41,3 +64,19 @@ export const getReceiptIssuingOrders = async ( | |||||
| }); | }); | ||||
| return res; | return res; | ||||
| }; | }; | ||||
| // 郵送投函完了登録 ----------------------- | |||||
| export type MailPostCompleteRequest = { | |||||
| id: string; | |||||
| status_mail_post_date: Date | null; | |||||
| timestamp: string; | |||||
| }; | |||||
| export const completeMailPost = async (data: MailPostCompleteRequest) => { | |||||
| const res = await request({ | |||||
| url: getUrl(ApiId.RECEIPT_ISSUING_ORDER_MAIL_POST_COMPLETE), | |||||
| method: HttpMethod.POST, | |||||
| data: makeParam(data), | |||||
| }); | |||||
| return res; | |||||
| }; | |||||
| @@ -12,6 +12,9 @@ const urls = { | |||||
| [A.RECEIPT_ISSUING_ORDER_CONFIRM]: "receipt-issuing-order/confirm", | [A.RECEIPT_ISSUING_ORDER_CONFIRM]: "receipt-issuing-order/confirm", | ||||
| [A.DOWNLOAD_RECEIPT]: "receipt/download", | [A.DOWNLOAD_RECEIPT]: "receipt/download", | ||||
| [A.RECEIPT_ISSUING_ORDER_MAIL_ORDER]: "receipt-issuing-order/mail-order", | [A.RECEIPT_ISSUING_ORDER_MAIL_ORDER]: "receipt-issuing-order/mail-order", | ||||
| [A.RECEIPT_ISSUING_ORDER_MAIL_POST_COMPLETE]: | |||||
| "receipt-issuing-order/mail-complete", | |||||
| [A.DOWNLOAD_RECEIPT_LETTER]: "receipt-letter/download", | |||||
| [A.RECEIPT_ISSUING_ORDERS]: "receipt-issuing-orders", | [A.RECEIPT_ISSUING_ORDERS]: "receipt-issuing-orders", | ||||
| @@ -28,6 +31,7 @@ const urls = { | |||||
| const prefixs = { | const prefixs = { | ||||
| [A.CSRF_TOKEN]: "", | [A.CSRF_TOKEN]: "", | ||||
| [A.DOWNLOAD_RECEIPT]: "", | [A.DOWNLOAD_RECEIPT]: "", | ||||
| [A.DOWNLOAD_RECEIPT_LETTER]: "", | |||||
| }; | }; | ||||
| const DEFAULT_API_URL_PREFIX = "api"; | const DEFAULT_API_URL_PREFIX = "api"; | ||||
| @@ -1 +0,0 @@ | |||||
| export { default as TableHeadCustom } from "./TableHeadCustom"; | |||||
| @@ -0,0 +1,61 @@ | |||||
| import { | |||||
| Button, | |||||
| Stack, | |||||
| SxProps, | |||||
| Table, | |||||
| TableBody, | |||||
| TableCell, | |||||
| TableRow, | |||||
| Typography, | |||||
| useTheme, | |||||
| } from "@mui/material"; | |||||
| import TextFieldEx from "components/form/TextFieldEx"; | |||||
| import { ReactNode, useEffect, useMemo } from "react"; | |||||
| export { default as TableHeadCustom } from "./TableHeadCustom"; | |||||
| type SimpleDataListProps = { | |||||
| data: { | |||||
| title: string; | |||||
| value?: string; | |||||
| end?: ReactNode; | |||||
| }[]; | |||||
| tableSx?: SxProps; | |||||
| }; | |||||
| export const SimpleDataList = ({ data, tableSx }: SimpleDataListProps) => { | |||||
| const { typography } = useTheme(); | |||||
| const fontSize = useMemo(() => { | |||||
| return typography.body2.fontSize; | |||||
| }, [typography]); | |||||
| return ( | |||||
| <Table sx={tableSx}> | |||||
| <TableBody> | |||||
| {data.map(({ title, value, end }, index) => { | |||||
| return ( | |||||
| <TableRow key={index}> | |||||
| <TableCell | |||||
| sx={{ borderRight: "1px solid rgba(224, 224, 224, 1)" }} | |||||
| > | |||||
| <Typography variant="body2">{title}</Typography> | |||||
| </TableCell> | |||||
| <TableCell> | |||||
| <Stack direction="row" spacing={1}> | |||||
| <TextFieldEx | |||||
| value={value ?? ""} | |||||
| readOnly | |||||
| multiline | |||||
| fullWidth | |||||
| inputProps={{ style: { fontSize } }} | |||||
| /> | |||||
| {end} | |||||
| </Stack> | |||||
| </TableCell> | |||||
| </TableRow> | |||||
| ); | |||||
| })} | |||||
| </TableBody> | |||||
| </Table> | |||||
| ); | |||||
| }; | |||||
| @@ -1,9 +1,6 @@ | |||||
| import { HasChildren } from "@types"; | import { HasChildren } from "@types"; | ||||
| import { checkToken } from "api/app"; | import { checkToken } from "api/app"; | ||||
| import { | |||||
| ReceiptIssuingOrder, | |||||
| getReceiptIssuingOrders, | |||||
| } from "api/receipt-issuing-order"; | |||||
| import { AppReceiptIssuingOrder } from "api/app/receipt-issuing-order"; | |||||
| import { PageID } from "codes/page"; | import { PageID } from "codes/page"; | ||||
| import useAPICall from "hooks/useAPICall"; | import useAPICall from "hooks/useAPICall"; | ||||
| import useNavigateCustom from "hooks/useNavigateCustom"; | import useNavigateCustom from "hooks/useNavigateCustom"; | ||||
| @@ -14,7 +11,7 @@ import { getPath } from "routes/path"; | |||||
| type App = { | type App = { | ||||
| token: string; | token: string; | ||||
| tokenResult: "cheking" | "ok" | "ng"; | tokenResult: "cheking" | "ok" | "ng"; | ||||
| receiptIssuingOrder: ReceiptIssuingOrder | null; | |||||
| receiptIssuingOrder: AppReceiptIssuingOrder | null; | |||||
| setToken: (token: string) => void; | setToken: (token: string) => void; | ||||
| fetch: VoidFunction; | fetch: VoidFunction; | ||||
| navigateToHome: VoidFunction; | navigateToHome: VoidFunction; | ||||
| @@ -38,7 +35,7 @@ export function AppContextProvider({ children }: Props) { | |||||
| const [token, _setToken] = useState(""); | const [token, _setToken] = useState(""); | ||||
| const [receiptIssuingOrder, setReceiptIssuingOrder] = | const [receiptIssuingOrder, setReceiptIssuingOrder] = | ||||
| useState<ReceiptIssuingOrder | null>(null); | |||||
| useState<AppReceiptIssuingOrder | null>(null); | |||||
| const [tokenResult, setTokenResult] = useState<"cheking" | "ok" | "ng">( | const [tokenResult, setTokenResult] = useState<"cheking" | "ok" | "ng">( | ||||
| "cheking" | "cheking" | ||||
| @@ -0,0 +1,271 @@ | |||||
| import { | |||||
| Box, | |||||
| Button, | |||||
| Divider, | |||||
| Grid, | |||||
| Paper, | |||||
| Stack, | |||||
| Typography, | |||||
| } from "@mui/material"; | |||||
| import { | |||||
| ReceiptIssuingOrderHTCustom, | |||||
| getReceiptIssuingOrders, | |||||
| } from "api/custom/hello-techno/receipt-issuing-order"; | |||||
| import { PageID } from "codes/page"; | |||||
| import { getPrefName } from "codes/prefcode"; | |||||
| import { SimpleDataList } from "components/table"; | |||||
| import useAPICall from "hooks/useAPICall"; | |||||
| import useBackDrop from "hooks/useBackDrop"; | |||||
| import useDashboard from "hooks/useDashBoard"; | |||||
| import useNavigateCustom from "hooks/useNavigateCustom"; | |||||
| import useSnackbarCustom from "hooks/useSnackbarCustom"; | |||||
| import { isNumber } from "lodash"; | |||||
| import { useEffect, useMemo, useState } from "react"; | |||||
| import { useParams } from "react-router-dom"; | |||||
| import { sprintf } from "sprintf-js"; | |||||
| import { formatDateStr, formatDateTimeStr } from "utils/datetime"; | |||||
| import useMailPostCompleteDialog from "./hooks/useMailPostCompleteDialog"; | |||||
| import { getFullUrl } from "api/url"; | |||||
| import { ApiId } from "api"; | |||||
| export default function ReceiptIssuingOrderDetail() { | |||||
| const { setHeaderTitle, setTabs } = useDashboard( | |||||
| PageID.DASHBOARD_RECEIPT_ISSUING_ORDER_DETAIL | |||||
| ); | |||||
| const { navigate } = useNavigateCustom(); | |||||
| const { error } = useSnackbarCustom(); | |||||
| const { id: receiptIssuingOrderId } = useParams(); | |||||
| const { setShowBackDrop } = useBackDrop(); | |||||
| const [order, setOrder] = useState<ReceiptIssuingOrderHTCustom | null>(null); | |||||
| const postCompleteDialog = useMailPostCompleteDialog(order, () => { | |||||
| fetch(); | |||||
| }); | |||||
| const { callAPI, sending } = useAPICall({ | |||||
| apiMethod: getReceiptIssuingOrders, | |||||
| onSuccess: (res) => { | |||||
| const target = res.data.records[0]; | |||||
| if (target) { | |||||
| setOrder(target); | |||||
| } | |||||
| }, | |||||
| onFailed: () => { | |||||
| error("情報取得失敗"); | |||||
| navigate(-1); | |||||
| }, | |||||
| }); | |||||
| const fetch = () => { | |||||
| if (receiptIssuingOrderId) { | |||||
| callAPI({ | |||||
| id: receiptIssuingOrderId, | |||||
| }); | |||||
| } | |||||
| }; | |||||
| const hasMailOrder = useMemo(() => { | |||||
| return !!order?.status_order_mail_datetime; | |||||
| }, [order]); | |||||
| const orderInfo = useMemo(() => { | |||||
| if (!order) return []; | |||||
| return [ | |||||
| { title: "ステータス", value: order.status_name }, | |||||
| { | |||||
| title: "担当者", | |||||
| value: order.handler_name, | |||||
| end: <Button sx={{ minWidth: 80 }}>担当変更</Button>, | |||||
| }, | |||||
| { title: "SMS送信先", value: order.sms_phone_number }, | |||||
| { title: "依頼日", value: formatDateStr(order.order_datetime) }, | |||||
| { title: "運営会社", value: order.customer_name }, | |||||
| { title: "駐車場", value: order.parking_name }, | |||||
| { title: "利用日", value: formatDateStr(order.receipt_use_date) }, | |||||
| { | |||||
| title: "精算連番", | |||||
| value: isNumber(order.adjust_seq_no) | |||||
| ? sprintf("%06d", order.adjust_seq_no) | |||||
| : "-", | |||||
| }, | |||||
| { | |||||
| title: "金額", | |||||
| value: isNumber(order.receipt_amount) | |||||
| ? order.receipt_amount.toLocaleString() + "円" | |||||
| : "-", | |||||
| }, | |||||
| { title: "備考", value: order.memo }, | |||||
| ]; | |||||
| }, [order]); | |||||
| const mailStatus1 = useMemo(() => { | |||||
| if (!order) return []; | |||||
| return [{ title: "郵送依頼", value: hasMailOrder ? "あり" : "なし" }]; | |||||
| }, [order]); | |||||
| const mailStatus2 = useMemo(() => { | |||||
| if (!order || !hasMailOrder) return []; | |||||
| return [ | |||||
| { title: "郵便番号", value: "〒" + order.mail_zip_code }, | |||||
| { title: "都道府県", value: getPrefName(order.mail_pref_code ?? "") }, | |||||
| { title: "市区町村", value: order.mail_address1 }, | |||||
| { title: "番地等", value: order.mail_address2 }, | |||||
| { title: "建物名/部屋番号等", value: order.mail_address3 }, | |||||
| { title: "宛名", value: order.mail_name }, | |||||
| ]; | |||||
| }, [order]); | |||||
| const receiptInfo = useMemo(() => { | |||||
| if (!order) return []; | |||||
| return [ | |||||
| { title: "領収証番号", value: order.receipt_no }, | |||||
| { | |||||
| title: "宛名", | |||||
| value: order.receipt_name, | |||||
| }, | |||||
| ]; | |||||
| }, [order]); | |||||
| const actionDatetimes = useMemo(() => { | |||||
| if (!order) return []; | |||||
| return [ | |||||
| { | |||||
| title: "SMS送信", | |||||
| value: formatDateTimeStr(order.status_sms_send_datetime), | |||||
| }, | |||||
| { | |||||
| title: "初回アクセス", | |||||
| value: formatDateTimeStr(order.status_first_access_datetime), | |||||
| }, | |||||
| { | |||||
| title: "領収証確定", | |||||
| value: formatDateTimeStr(order.status_receipt_confirm_datetime), | |||||
| }, | |||||
| { | |||||
| title: "郵送依頼", | |||||
| value: formatDateTimeStr(order.status_order_mail_datetime), | |||||
| }, | |||||
| { title: "郵送投函", value: formatDateStr(order.status_mail_post_date) }, | |||||
| { | |||||
| title: "領収証ダウンロード", | |||||
| value: formatDateTimeStr(order.status_receipt_download_datetime), | |||||
| }, | |||||
| { | |||||
| title: "メール配信依頼", | |||||
| value: formatDateTimeStr( | |||||
| order.status_receipt_email_send_order_datetime | |||||
| ), | |||||
| }, | |||||
| { | |||||
| title: "メール配信完了", | |||||
| value: formatDateTimeStr(order.status_receipt_email_send_datetime), | |||||
| }, | |||||
| ]; | |||||
| }, [order]); | |||||
| const downloadUrl = useMemo(() => { | |||||
| return getFullUrl(ApiId.DOWNLOAD_RECEIPT_LETTER) + "?id=" + order?.id; | |||||
| }, [order]); | |||||
| useEffect(() => { | |||||
| setHeaderTitle("領収証発行依頼"); | |||||
| setTabs(null); | |||||
| fetch(); | |||||
| }, []); | |||||
| useEffect(() => { | |||||
| setShowBackDrop(sending); | |||||
| }, [sending]); | |||||
| return ( | |||||
| <Box> | |||||
| <Grid container spacing={2}> | |||||
| <Grid item xs={12}> | |||||
| <Stack direction="row" spacing={2}> | |||||
| <Button onClick={() => navigate(-1)}>戻る</Button> | |||||
| </Stack> | |||||
| </Grid> | |||||
| <Grid item xs={4}> | |||||
| <Paper elevation={0} sx={{ border: "1px solid" }}> | |||||
| <Stack spacing={2}> | |||||
| <Typography | |||||
| variant="h6" | |||||
| fontWeight="bold" | |||||
| sx={{ my: 2, textAlign: "center" }} | |||||
| > | |||||
| 依頼内容 | |||||
| </Typography> | |||||
| <SimpleDataList data={orderInfo} /> | |||||
| <Divider sx={{ my: 2 }} /> | |||||
| <Typography | |||||
| variant="subtitle1" | |||||
| sx={{ my: 2, textAlign: "center" }} | |||||
| > | |||||
| 領収証情報 | |||||
| </Typography> | |||||
| <SimpleDataList data={receiptInfo} /> | |||||
| </Stack> | |||||
| </Paper> | |||||
| </Grid> | |||||
| <Grid item xs={4}> | |||||
| <Paper elevation={0} sx={{ pb: 2, border: "1px solid" }}> | |||||
| <Stack spacing={2}> | |||||
| <Typography | |||||
| variant="h6" | |||||
| fontWeight="bold" | |||||
| sx={{ my: 2, textAlign: "center" }} | |||||
| > | |||||
| 郵送管理 | |||||
| </Typography> | |||||
| <SimpleDataList data={mailStatus1} /> | |||||
| {hasMailOrder && ( | |||||
| <> | |||||
| <Divider sx={{ my: 2 }} /> | |||||
| <Typography | |||||
| variant="subtitle1" | |||||
| sx={{ my: 2, textAlign: "center" }} | |||||
| > | |||||
| 郵送先 | |||||
| </Typography> | |||||
| <SimpleDataList data={mailStatus2} /> | |||||
| <Divider /> | |||||
| <Stack direction="row" spacing={2} sx={{ px: 2 }}> | |||||
| <Button variant="contained" href={downloadUrl}> | |||||
| 印字 | |||||
| </Button> | |||||
| <Button | |||||
| variant="contained" | |||||
| onClick={postCompleteDialog.open} | |||||
| > | |||||
| 投函完了 | |||||
| </Button> | |||||
| </Stack> | |||||
| {postCompleteDialog.element} | |||||
| </> | |||||
| )} | |||||
| </Stack> | |||||
| </Paper> | |||||
| </Grid> | |||||
| <Grid item xs={4}> | |||||
| <Paper elevation={0} sx={{ border: "1px solid" }}> | |||||
| <Stack spacing={2}> | |||||
| <Typography | |||||
| variant="h6" | |||||
| fontWeight="bold" | |||||
| sx={{ my: 2, textAlign: "center" }} | |||||
| > | |||||
| 各種アクション日時 | |||||
| </Typography> | |||||
| <SimpleDataList data={actionDatetimes} /> | |||||
| </Stack> | |||||
| </Paper> | |||||
| </Grid> | |||||
| </Grid> | |||||
| </Box> | |||||
| ); | |||||
| } | |||||
| @@ -0,0 +1,118 @@ | |||||
| import { yupResolver } from "@hookform/resolvers/yup"; | |||||
| import { | |||||
| Button, | |||||
| Dialog, | |||||
| DialogActions, | |||||
| DialogContent, | |||||
| DialogTitle, | |||||
| } from "@mui/material"; | |||||
| import { | |||||
| ReceiptIssuingOrder, | |||||
| completeMailPost, | |||||
| } from "api/receipt-issuing-order"; | |||||
| import { FormProvider } from "components/hook-form"; | |||||
| import RHFDatePicker from "components/hook-form/RHFDatePicker"; | |||||
| import useAPICall from "hooks/useAPICall"; | |||||
| import useBackDrop from "hooks/useBackDrop"; | |||||
| import useSnackbarCustom from "hooks/useSnackbarCustom"; | |||||
| import { useEffect, useState } from "react"; | |||||
| import { useForm } from "react-hook-form"; | |||||
| import { now } from "utils/datetime"; | |||||
| import * as Yup from "yup"; | |||||
| type FormProps = { | |||||
| date: Date | null; | |||||
| }; | |||||
| export default function useMailPostCompleteDialog( | |||||
| order: ReceiptIssuingOrder | null, | |||||
| onComplete?: VoidFunction | |||||
| ) { | |||||
| const [show, setShow] = useState(false); | |||||
| const { setShowBackDrop } = useBackDrop(); | |||||
| const { success, error } = useSnackbarCustom(); | |||||
| const form = useForm<FormProps>({ | |||||
| defaultValues: { | |||||
| date: now(), | |||||
| }, | |||||
| resolver: yupResolver( | |||||
| Yup.object().shape({ | |||||
| date: Yup.date() | |||||
| .required("必須項目です") | |||||
| .typeError("正しく入力してください"), | |||||
| }) | |||||
| ), | |||||
| }); | |||||
| const { callAPI, sending } = useAPICall({ | |||||
| apiMethod: completeMailPost, | |||||
| onSuccess: () => { | |||||
| success("登録しました"); | |||||
| setShow(false); | |||||
| if (onComplete) { | |||||
| onComplete(); | |||||
| } | |||||
| }, | |||||
| onFailed: () => { | |||||
| error("失敗しました"); | |||||
| }, | |||||
| }); | |||||
| const open = () => { | |||||
| setShow(true); | |||||
| }; | |||||
| const close = () => { | |||||
| setShow(false); | |||||
| }; | |||||
| const handleSubmit = (data: FormProps) => { | |||||
| if (!order) return; | |||||
| callAPI({ | |||||
| id: order.id, | |||||
| status_mail_post_date: data.date, | |||||
| timestamp: order.updated_at, | |||||
| }); | |||||
| }; | |||||
| const element = ( | |||||
| <Dialog open={show} onClose={close}> | |||||
| <DialogTitle>投稿完了登録</DialogTitle> | |||||
| <FormProvider methods={form} onSubmit={form.handleSubmit(handleSubmit)}> | |||||
| <DialogContent> | |||||
| <RHFDatePicker name="date" label="投函完了日" /> | |||||
| </DialogContent> | |||||
| <DialogActions> | |||||
| <Button onClick={close}>CANCEL</Button> | |||||
| <Button type="submit">OK</Button> | |||||
| </DialogActions> | |||||
| </FormProvider> | |||||
| </Dialog> | |||||
| ); | |||||
| useEffect(() => { | |||||
| setShowBackDrop(sending); | |||||
| }, [sending]); | |||||
| useEffect(() => { | |||||
| console.log(now()); | |||||
| // console.log(formatDateStr(now())); | |||||
| // form.setValue('date', formatDateStr(now()) | |||||
| }, []); | |||||
| return { | |||||
| // param | |||||
| show, | |||||
| // Element | |||||
| element, | |||||
| // function | |||||
| open, | |||||
| close, | |||||
| setShow, | |||||
| }; | |||||
| } | |||||
| @@ -10,7 +10,7 @@ import { | |||||
| } from "@mui/material"; | } from "@mui/material"; | ||||
| import { Dictionary } from "@types"; | import { Dictionary } from "@types"; | ||||
| import { | import { | ||||
| ReceiptIssuingOrder, | |||||
| ReceiptIssuingOrderHTCustom, | |||||
| getReceiptIssuingOrders, | getReceiptIssuingOrders, | ||||
| } from "api/custom/hello-techno/receipt-issuing-order"; | } from "api/custom/hello-techno/receipt-issuing-order"; | ||||
| import { PageID, TabID } from "codes/page"; | import { PageID, TabID } from "codes/page"; | ||||
| @@ -20,10 +20,12 @@ import { SearchConditionContextProvider } from "contexts/SearchConditionContext" | |||||
| import useAPICall from "hooks/useAPICall"; | import useAPICall from "hooks/useAPICall"; | ||||
| import useBackDrop from "hooks/useBackDrop"; | import useBackDrop from "hooks/useBackDrop"; | ||||
| import useDashboard from "hooks/useDashBoard"; | import useDashboard from "hooks/useDashBoard"; | ||||
| 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 { useEffect } from "react"; | import { useEffect } from "react"; | ||||
| import { useForm } from "react-hook-form"; | import { useForm } from "react-hook-form"; | ||||
| import { getPath } from "routes/path"; | |||||
| export default function ReceiptIssuingOrderList() { | export default function ReceiptIssuingOrderList() { | ||||
| const { setHeaderTitle, setTabs } = useDashboard( | const { setHeaderTitle, setTabs } = useDashboard( | ||||
| @@ -44,7 +46,7 @@ export default function ReceiptIssuingOrderList() { | |||||
| } | } | ||||
| function Page() { | function Page() { | ||||
| const table = useTable<ReceiptIssuingOrder>(); | |||||
| const table = useTable<ReceiptIssuingOrderHTCustom>(); | |||||
| return ( | return ( | ||||
| <Box> | <Box> | ||||
| @@ -59,7 +61,7 @@ type FormProps = { | |||||
| parking_name: string; | parking_name: string; | ||||
| }; | }; | ||||
| type CommonProps = { | type CommonProps = { | ||||
| table: UseTableReturn<ReceiptIssuingOrder>; | |||||
| table: UseTableReturn<ReceiptIssuingOrderHTCustom>; | |||||
| }; | }; | ||||
| function SearchBox({ table }: CommonProps) { | function SearchBox({ table }: CommonProps) { | ||||
| const { | const { | ||||
| @@ -226,11 +228,23 @@ function TableBox({ table }: CommonProps) { | |||||
| } | } | ||||
| type RowProps = { | type RowProps = { | ||||
| data: ReceiptIssuingOrder; | |||||
| data: ReceiptIssuingOrderHTCustom; | |||||
| }; | }; | ||||
| function Row({ data }: RowProps) { | function Row({ data }: RowProps) { | ||||
| const { navigateWhenChanged } = useNavigateCustom(); | |||||
| const handleClick = () => { | |||||
| navigateWhenChanged( | |||||
| getPath(PageID.DASHBOARD_RECEIPT_ISSUING_ORDER_DETAIL, { | |||||
| query: { | |||||
| id: data.id, | |||||
| }, | |||||
| }) | |||||
| ); | |||||
| }; | |||||
| return ( | return ( | ||||
| <TableRow hover sx={{ cursor: "pointer" }}> | |||||
| <TableRow hover sx={{ cursor: "pointer" }} onClick={handleClick}> | |||||
| <TableCell>{data.order_datetime}</TableCell> | <TableCell>{data.order_datetime}</TableCell> | ||||
| <TableCell>{data.customer_name}</TableCell> | <TableCell>{data.customer_name}</TableCell> | ||||
| <TableCell>{data.parking_name}</TableCell> | <TableCell>{data.parking_name}</TableCell> | ||||
| @@ -78,6 +78,11 @@ const DashboardRoutes = (): RouteObject => { | |||||
| element: <ReceiptIssuingOrderList />, | element: <ReceiptIssuingOrderList />, | ||||
| target: UserRole.NORMAL_ADMIN, | target: UserRole.NORMAL_ADMIN, | ||||
| }, | }, | ||||
| { | |||||
| pageId: PageID.DASHBOARD_RECEIPT_ISSUING_ORDER_DETAIL, | |||||
| element: <ReceiptIssuingOrderDetail />, | |||||
| target: UserRole.NORMAL_ADMIN, | |||||
| }, | |||||
| ]; | ]; | ||||
| const children: RouteObject[] = useMemo(() => { | const children: RouteObject[] = useMemo(() => { | ||||
| @@ -138,6 +143,9 @@ const ReceiptIssuingOrderCreate = Loadable( | |||||
| const ReceiptIssuingOrderList = Loadable( | const ReceiptIssuingOrderList = Loadable( | ||||
| lazy(() => import("pages/dashboard/receipt-issuing-order/list")) | lazy(() => import("pages/dashboard/receipt-issuing-order/list")) | ||||
| ); | ); | ||||
| const ReceiptIssuingOrderDetail = Loadable( | |||||
| lazy(() => import("pages/dashboard/receipt-issuing-order/detail")) | |||||
| ); | |||||
| // その他 --------------------------------- | // その他 --------------------------------- | ||||
| const Page403 = Loadable(lazy(() => import("pages/common/Page403"))); | const Page403 = Loadable(lazy(() => import("pages/common/Page403"))); | ||||
| @@ -54,7 +54,7 @@ const PATHS = { | |||||
| [makePathKey(PageID.DASHBOARD_RECEIPT_ISSUING_ORDER_LIST)]: | [makePathKey(PageID.DASHBOARD_RECEIPT_ISSUING_ORDER_LIST)]: | ||||
| "/dashboard/receipt-issusing-order/list/:page", | "/dashboard/receipt-issusing-order/list/:page", | ||||
| [makePathKey(PageID.DASHBOARD_RECEIPT_ISSUING_ORDER_DETAIL)]: | [makePathKey(PageID.DASHBOARD_RECEIPT_ISSUING_ORDER_DETAIL)]: | ||||
| "/dashboard/receipt-issusing-order/detail", | |||||
| "/dashboard/receipt-issusing-order/detail/:id", | |||||
| // その他 | // その他 | ||||
| [makePathKey(PageID.PAGE_403)]: "403", | [makePathKey(PageID.PAGE_403)]: "403", | ||||