| @@ -4,28 +4,67 @@ import { formatDateStr, today } from "@/common/datetime"; | |||
| import { initMenuBox, setHeaderButton } from "@/common/header-button"; | |||
| import { KintoneEvent, 値設定 } from "@/common/kintone-event"; | |||
| import { makeRecordData } from "@/common/rest-api-client"; | |||
| import { Message } from "@/exception"; | |||
| import { EmailID, sendEmail } from "@/mypage/メール"; | |||
| import { makeReceipt } from "@/mypage/領収証発行"; | |||
| import bulkRequest from "@/rest-api/bulk"; | |||
| import { get定期申込予約 } from "@/rest-api/定期申込予約"; | |||
| import { get定期駐車場プランマスタ } from "@/rest-api/定期駐車場プランマスタ"; | |||
| import { get車室情報管理 } from "@/rest-api/車室情報管理"; | |||
| import { parseFromUrlSearchQuery } from "@/rest-api/url"; | |||
| import { get顧客マスタ } from "@/rest-api/顧客マスタ"; | |||
| import { | |||
| 入金予定結果, | |||
| 入金予定結果フィールド名, | |||
| 定期料金日割り分Checkbox, | |||
| 支払種別Dropdown, | |||
| } from "@/types/入金予定結果"; | |||
| import { 定期申込予約フィールド名 } from "@/types/定期申込予約"; | |||
| import { 車室情報管理フィールド名 } from "@/types/車室情報管理"; | |||
| import { 顧客マスタフィールド名 } from "@/types/顧客マスタ"; | |||
| import { KintoneRestAPIClient } from "@kintone/rest-api-client"; | |||
| import { addDays, addMonths, format, setHours, setMonth } from "date-fns"; | |||
| import { addDays, format, setHours } from "date-fns"; | |||
| import { get, set } from "lodash"; | |||
| import Swal from "sweetalert2"; | |||
| const client = new KintoneRestAPIClient(); | |||
| const 初回入金予定作成完了 = (入金予定: 入金予定結果) => { | |||
| const F = 入金予定結果フィールド名; | |||
| if (!入金予定[F.初回振り込み関連申込レコード番号].value) { | |||
| throw new Error("初回入金予定でない"); | |||
| } | |||
| const param = {}; | |||
| if (入金予定[F.支払種別].value === 支払種別Dropdown.定期料金) { | |||
| if ( | |||
| 入金予定[F.定期料金日割り分].value.find( | |||
| (val) => val === 定期料金日割り分Checkbox.該当 | |||
| ) | |||
| ) { | |||
| set( | |||
| param, | |||
| 定期申込予約フィールド名.初回入金予定_日割り分入金予定, | |||
| 入金予定.$id.value | |||
| ); | |||
| } else { | |||
| set( | |||
| param, | |||
| 定期申込予約フィールド名.初回入金予定_初月分入金予定, | |||
| 入金予定.$id.value | |||
| ); | |||
| } | |||
| } else if (入金予定[F.支払種別].value === 支払種別Dropdown.保証金) { | |||
| set( | |||
| param, | |||
| 定期申込予約フィールド名.初回入金予定_保証金入金予定, | |||
| 入金予定.$id.value | |||
| ); | |||
| } else { | |||
| throw new Error("想定外の初回入金種別"); | |||
| } | |||
| bulkRequest.update({ | |||
| app: AppID.定期申込予約, | |||
| id: 入金予定.first_payment_entry_record_no.value, | |||
| record: makeRecordData(param), | |||
| }); | |||
| }; | |||
| const 残金設定 = (record: 入金予定結果) => { | |||
| record[入金予定結果フィールド名.残金].value = (() => { | |||
| const amount = | |||
| @@ -95,10 +134,11 @@ const getCallbackFillAmount = (record: 入金予定結果) => { | |||
| // クエリパラメータよりフィールドに値をセットする | |||
| const setData = (event: any, targets: string[]) => { | |||
| const param = new URLSearchParams(location.search.replace("?", "")); | |||
| const param = parseFromUrlSearchQuery(); | |||
| targets.forEach((target) => { | |||
| const value = param.get(target); | |||
| if (value === null) return; | |||
| const value = get(param, target); | |||
| console.log(target, value); | |||
| if (value === undefined) return; | |||
| 値設定(event, target, value, true); | |||
| }); | |||
| }; | |||
| @@ -119,89 +159,6 @@ const setData = (event: any, targets: string[]) => { | |||
| }) | |||
| ); | |||
| const 初回請求金額確定チェック = (record: 入金予定結果) => { | |||
| if (!record.first_payment_entry_record_no.value) { | |||
| throw new Message("初回振り込み関連申込レコード番号が入力されていません"); | |||
| } | |||
| // 申込の初回振り込み情報を入力する | |||
| const F = 定期申込予約フィールド名; | |||
| const 支払予定日 = record.payment_plan_date.value; | |||
| if (!支払予定日) { | |||
| throw new Message("支払予定日が入力されていません"); | |||
| } | |||
| const 支払予定金額 = record.payment_plan_amount.value; | |||
| if (!支払予定金額) { | |||
| throw new Message("支払予定金額が入力されていません"); | |||
| } | |||
| }; | |||
| const 初回請求金額確定 = async (record: 入金予定結果) => { | |||
| 初回請求金額確定チェック(record); | |||
| const F = 定期申込予約フィールド名; | |||
| const P = 入金予定結果フィールド名; | |||
| const 申込 = await get定期申込予約( | |||
| record.first_payment_entry_record_no.value | |||
| ); | |||
| const 契約 = await get車室情報管理(record.contract_record_number.value); | |||
| const プラン = await get定期駐車場プランマスタ( | |||
| 契約[車室情報管理フィールド名.プラン名].value | |||
| ); | |||
| // 申込の初回振り込み情報を入力する | |||
| const 支払予定日 = record.payment_plan_date.value ?? ""; | |||
| const 支払予定金額 = record.payment_plan_amount.value ?? ""; | |||
| const 日割り金額 = Number(支払予定金額) - Number(プラン.契約金額.value); | |||
| const 日割り月 = (() => { | |||
| if (日割り金額 === 0) return ""; | |||
| let month = Number(record.target_month.value) - 1; | |||
| if (month === 0) { | |||
| month = 12; | |||
| } | |||
| return String(month); | |||
| })(); | |||
| // 保証金計算 | |||
| const 保証金 = Number(プラン.保証金合計額.value ?? 0); | |||
| if (0 < 保証金) { | |||
| bulkRequest.create({ | |||
| app: AppID.入金予定結果, | |||
| record: makeRecordData({ | |||
| [P.車室情報管理レコード番号]: record.contract_record_number.value, | |||
| [P.支払種別]: 支払種別Dropdown.保証金, | |||
| [P.支払方法]: record.payment_method.value ?? "", | |||
| [P.支払予定日]: record.payment_plan_date.value ?? "", | |||
| [P.支払予定金額]: プラン.保証金合計額.value, | |||
| [P.入金額]: "0", | |||
| [P.残金]: String(保証金), | |||
| }), | |||
| }); | |||
| } | |||
| const 請求対象分月 = addMonths( | |||
| setMonth(new Date(), Number(record.target_month.value) - 1), | |||
| Number(record.target_term_month.value) - 1 | |||
| ); | |||
| const 日割り対象月 = addMonths(請求対象分月, -1); | |||
| bulkRequest.update({ | |||
| app: AppID.定期申込予約, | |||
| id: record.first_payment_entry_record_no.value, | |||
| record: makeRecordData({ | |||
| [F.振込期日]: 支払予定日, | |||
| [F.初回振り込み合計額]: 支払予定金額, | |||
| [F.請求対象分_月]: String(請求対象分月.getMonth() + 1), | |||
| [F.請求対象分_金額]: 申込.定期駐車料金.value, | |||
| [F.日割り分_金額]: 日割り金額 === 0 ? "" : String(日割り金額), | |||
| [F.日割り分_月]: | |||
| 日割り金額 === 0 ? "" : String(日割り対象月.getMonth() + 1), | |||
| }), | |||
| }); | |||
| await bulkRequest.save(); | |||
| }; | |||
| kintone.events.on( | |||
| KintoneEvent.追加.レコード追加画面を表示した後, | |||
| eventHnalder(async (event) => { | |||
| @@ -216,6 +173,8 @@ const setData = (event: any, targets: string[]) => { | |||
| 入金予定結果フィールド名.支払対象_利用_月, | |||
| 入金予定結果フィールド名.支払対象_利用_月間数, | |||
| 入金予定結果フィールド名.支払予定日, | |||
| 入金予定結果フィールド名.定期料金日割り分, | |||
| 入金予定結果フィールド名.保証金明細, | |||
| ]); | |||
| 残金設定(record); | |||
| @@ -223,18 +182,6 @@ const setData = (event: any, targets: string[]) => { | |||
| }) | |||
| ); | |||
| kintone.events.on( | |||
| KintoneEvent.追加.保存するとき, | |||
| eventHnalder(async (event: any) => { | |||
| const record = event.record as 入金予定結果; | |||
| // 初回請求確定時にはメールを送信する | |||
| if ( | |||
| record[入金予定結果フィールド名.初回振り込み関連申込レコード番号].value | |||
| ) { | |||
| await 初回請求金額確定(record); | |||
| } | |||
| }) | |||
| ); | |||
| kintone.events.on( | |||
| KintoneEvent.追加.保存に成功した後, | |||
| eventHnalder(async (event: any) => { | |||
| @@ -243,13 +190,7 @@ const setData = (event: any, targets: string[]) => { | |||
| if ( | |||
| record[入金予定結果フィールド名.初回振り込み関連申込レコード番号].value | |||
| ) { | |||
| // メール送信 | |||
| sendEmail(EmailID.申込受付, { | |||
| season_ticket_contract_entry_record_no: Number( | |||
| record[入金予定結果フィールド名.初回振り込み関連申込レコード番号] | |||
| .value | |||
| ), | |||
| }); | |||
| 初回入金予定作成完了(record); | |||
| // 口座振替登録催促日時を設定する | |||
| const 口座登録催促日時 = (() => { | |||
| @@ -265,6 +206,10 @@ const setData = (event: any, targets: string[]) => { | |||
| [顧客マスタフィールド名.口座登録催促予定日時]: 口座登録催促日時, | |||
| }), | |||
| }); | |||
| await bulkRequest.save(); | |||
| if (window.opener) window.opener.location.reload(); | |||
| } | |||
| }) | |||
| ); | |||
| @@ -0,0 +1,90 @@ | |||
| import { apptemplate } from "@/common/app-template"; | |||
| import { AppID } from "@/common/appids"; | |||
| import { dateParse, formatDateStr } from "@/common/datetime"; | |||
| import { setHeaderButton } from "@/common/header-button"; | |||
| import { makeSubTableRecordData } from "@/common/rest-api-client"; | |||
| import { getCreateUrl, makeUrlSearchParams } from "@/rest-api/url"; | |||
| import { get定期駐車場プランマスタ } from "@/rest-api/定期駐車場プランマスタ"; | |||
| import { get車室情報管理 } from "@/rest-api/車室情報管理"; | |||
| import { | |||
| 保証金明細行データ, | |||
| 保証金明細行データ作成, | |||
| 入金予定結果フィールド名, | |||
| 支払方法Dropdown, | |||
| 支払種別Dropdown, | |||
| } from "@/types/入金予定結果"; | |||
| import { 初回入金予定Checkbox, 定期申込予約 } from "@/types/定期申込予約"; | |||
| import { 車室情報管理フィールド名 } from "@/types/車室情報管理"; | |||
| import { addDays } from "date-fns"; | |||
| export default function 保証金入金予定作成ボタン(record: 定期申込予約) { | |||
| if ( | |||
| !!record.自動承認契約情報.value && | |||
| record.初回入金予定_必要分.value.includes(初回入金予定Checkbox.保証金) && | |||
| !record.初回入金予定_保証金入金予定.value | |||
| ) { | |||
| setHeaderButton( | |||
| "保証金入金予定作成", | |||
| apptemplate(async () => { | |||
| // 計算 | |||
| const 契約 = await get車室情報管理(record.自動承認契約情報.value); | |||
| const 契約日 = dateParse(契約.契約日.value); | |||
| if (契約日 === null) return; | |||
| const プラン = await get定期駐車場プランマスタ( | |||
| 契約[車室情報管理フィールド名.プラン名].value | |||
| ); | |||
| const 請求金額 = Number(プラン.保証金合計額.value); | |||
| const 明細 = (() => { | |||
| const ret: 保証金明細行データ[] = []; | |||
| if (0 < Number(プラン.保証金.value)) { | |||
| ret.push( | |||
| 保証金明細行データ作成({ | |||
| [入金予定結果フィールド名.保証金明細_名称]: "保証金", | |||
| [入金予定結果フィールド名.保証金明細_金額]: プラン.保証金.value, | |||
| }) | |||
| ); | |||
| } | |||
| if (0 < Number(プラン.チェーンゲート保証金.value)) { | |||
| ret.push( | |||
| 保証金明細行データ作成({ | |||
| [入金予定結果フィールド名.保証金明細_名称]: | |||
| "チェーンゲート保証金", | |||
| [入金予定結果フィールド名.保証金明細_金額]: | |||
| プラン.チェーンゲート保証金.value, | |||
| }) | |||
| ); | |||
| } | |||
| if (0 < Number(プラン.パスカード保証金.value)) { | |||
| ret.push( | |||
| 保証金明細行データ作成({ | |||
| [入金予定結果フィールド名.保証金明細_名称]: "保証金", | |||
| [入金予定結果フィールド名.保証金明細_金額]: | |||
| プラン.パスカード保証金.value, | |||
| }) | |||
| ); | |||
| } | |||
| return ret; | |||
| })(); | |||
| const 保証金明細 = makeSubTableRecordData(明細); | |||
| const param = makeUrlSearchParams({ | |||
| [入金予定結果フィールド名.車室情報管理レコード番号]: | |||
| record.自動承認契約情報.value, | |||
| [入金予定結果フィールド名.初回振り込み関連申込レコード番号]: | |||
| record.$id.value, | |||
| [入金予定結果フィールド名.支払予定金額]: String(請求金額), | |||
| [入金予定結果フィールド名.支払方法]: 支払方法Dropdown.振込, | |||
| [入金予定結果フィールド名.支払種別]: 支払種別Dropdown.保証金, | |||
| [入金予定結果フィールド名.支払予定日]: formatDateStr( | |||
| addDays(契約日, -1) | |||
| ), | |||
| [入金予定結果フィールド名.保証金明細]: 保証金明細, | |||
| }); | |||
| const url = getCreateUrl(AppID.入金予定結果, param); | |||
| window.open(url, "_blank", "popup"); | |||
| }) | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,71 @@ | |||
| import { apptemplate } from "@/common/app-template"; | |||
| import { AppID } from "@/common/appids"; | |||
| import { dateParse, formatDateStr } from "@/common/datetime"; | |||
| import { setHeaderButton } from "@/common/header-button"; | |||
| import 定期駐車場料金計算 from "@/logic/定期駐車場料金計算"; | |||
| import { getCreateUrl, makeUrlSearchParams } from "@/rest-api/url"; | |||
| import { get定期駐車場プランマスタ } from "@/rest-api/定期駐車場プランマスタ"; | |||
| import { get車室情報管理 } from "@/rest-api/車室情報管理"; | |||
| import { | |||
| 入金予定結果フィールド名, | |||
| 支払方法Dropdown, | |||
| 支払種別Dropdown, | |||
| } from "@/types/入金予定結果"; | |||
| import { 初回入金予定Checkbox, 定期申込予約 } from "@/types/定期申込予約"; | |||
| import { 車室情報管理フィールド名 } from "@/types/車室情報管理"; | |||
| import { addDays, addMonths, endOfMonth, setDate } from "date-fns"; | |||
| export default function 初月分入金予定作成ボタン(record: 定期申込予約) { | |||
| if ( | |||
| !!record.自動承認契約情報.value && | |||
| record.初回入金予定_必要分.value.includes(初回入金予定Checkbox.初月分) && | |||
| !record.初回入金予定_初月分入金予定.value | |||
| ) { | |||
| setHeaderButton( | |||
| "初月分入金予定作成", | |||
| apptemplate(async () => { | |||
| // 計算 | |||
| const 契約 = await get車室情報管理(record.自動承認契約情報.value); | |||
| const 契約日 = dateParse(契約.契約日.value); | |||
| if (契約日 === null) return; | |||
| const プラン = await get定期駐車場プランマスタ( | |||
| 契約[車室情報管理フィールド名.プラン名].value | |||
| ); | |||
| const 開始日 = (() => { | |||
| if (契約日.getDate() === 1) { | |||
| return 契約日; | |||
| } | |||
| return setDate(addMonths(契約日, 1), 1); | |||
| })(); | |||
| const 終了日 = endOfMonth(開始日); | |||
| const 計算 = new 定期駐車場料金計算(プラン); | |||
| const 請求金額 = 計算.期間の計算(開始日, 終了日); | |||
| const param = makeUrlSearchParams({ | |||
| [入金予定結果フィールド名.車室情報管理レコード番号]: | |||
| record.自動承認契約情報.value, | |||
| [入金予定結果フィールド名.初回振り込み関連申込レコード番号]: | |||
| record.$id.value, | |||
| [入金予定結果フィールド名.支払予定金額]: String(請求金額), | |||
| [入金予定結果フィールド名.支払方法]: 支払方法Dropdown.振込, | |||
| [入金予定結果フィールド名.支払種別]: 支払種別Dropdown.定期料金, | |||
| [入金予定結果フィールド名.支払対象_利用_年]: String( | |||
| 開始日.getFullYear() | |||
| ), | |||
| [入金予定結果フィールド名.支払対象_利用_月]: String( | |||
| 開始日.getMonth() + 1 | |||
| ), | |||
| [入金予定結果フィールド名.支払対象_利用_月間数]: "1", | |||
| [入金予定結果フィールド名.支払予定日]: formatDateStr( | |||
| addDays(契約日, -1) | |||
| ), | |||
| }); | |||
| const url = getCreateUrl(AppID.入金予定結果, param); | |||
| window.open(url, "_blank", "popup"); | |||
| }) | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,84 @@ | |||
| import { apptemplate } from "@/common/app-template"; | |||
| import { AppID } from "@/common/appids"; | |||
| import { now } from "@/common/datetime"; | |||
| import { setHeaderButton } from "@/common/header-button"; | |||
| import { makeDatetimeStr, makeRecordData } from "@/common/rest-api-client"; | |||
| import { Message } from "@/exception"; | |||
| import { ShowConfirmDialog, SuccessDialog } from "@/middleware/swal"; | |||
| import { EmailID, sendEmail } from "@/mypage/メール"; | |||
| import bulkRequest from "@/rest-api/bulk"; | |||
| import { | |||
| 初回入金予定Checkbox, | |||
| 定期申込予約, | |||
| 定期申込予約フィールド名, | |||
| } from "@/types/定期申込予約"; | |||
| const 表示判定 = (record: 定期申込予約): boolean => { | |||
| if (!record.自動承認契約情報.value) { | |||
| return false; | |||
| } | |||
| if ( | |||
| record.初回入金予定_必要分.value.includes(初回入金予定Checkbox.初月分) && | |||
| !record.初回入金予定_初月分入金予定.value | |||
| ) { | |||
| return false; | |||
| } | |||
| if ( | |||
| record.初回入金予定_必要分.value.includes(初回入金予定Checkbox.日割り分) && | |||
| !record.初回入金予定_日割り分入金予定.value | |||
| ) { | |||
| return false; | |||
| } | |||
| if ( | |||
| record.初回入金予定_必要分.value.includes(初回入金予定Checkbox.保証金) && | |||
| !record.初回入金予定_保証金入金予定.value | |||
| ) { | |||
| return false; | |||
| } | |||
| return true; | |||
| }; | |||
| export default function 受付メール送信ボタン(record: 定期申込予約) { | |||
| if (表示判定(record)) { | |||
| setHeaderButton( | |||
| "受付メール送信", | |||
| apptemplate(async ({ needReloadAtEnd }) => { | |||
| const confirmMessage = (() => { | |||
| if (!!record.受付メール送信日時.value) { | |||
| return "送信しますか?(再送信)"; | |||
| } | |||
| return "送信しますか?"; | |||
| })(); | |||
| const confirm = await ShowConfirmDialog({ | |||
| text: confirmMessage, | |||
| }); | |||
| if (!confirm.isConfirmed) return; | |||
| // メール送信 | |||
| const emailSuccess = await sendEmail(EmailID.申込受付, { | |||
| season_ticket_contract_entry_record_no: Number(record.$id.value), | |||
| }); | |||
| if (!emailSuccess) { | |||
| throw new Message("メール送信に失敗しました"); | |||
| } | |||
| bulkRequest.update({ | |||
| app: AppID.定期申込予約, | |||
| id: record.$id.value, | |||
| record: makeRecordData({ | |||
| [定期申込予約フィールド名.受付メール送信日時]: makeDatetimeStr( | |||
| now() | |||
| ), | |||
| }), | |||
| }); | |||
| await bulkRequest.save(); | |||
| await SuccessDialog.fire(); | |||
| needReloadAtEnd(true); | |||
| }) | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,67 @@ | |||
| import { apptemplate } from "@/common/app-template"; | |||
| import { AppID } from "@/common/appids"; | |||
| import { dateParse, formatDateStr } from "@/common/datetime"; | |||
| import { setHeaderButton } from "@/common/header-button"; | |||
| import 定期駐車場料金計算 from "@/logic/定期駐車場料金計算"; | |||
| import { getCreateUrl, makeUrlSearchParams } from "@/rest-api/url"; | |||
| import { get定期駐車場プランマスタ } from "@/rest-api/定期駐車場プランマスタ"; | |||
| import { get車室情報管理 } from "@/rest-api/車室情報管理"; | |||
| import { | |||
| 入金予定結果フィールド名, | |||
| 定期料金日割り分Checkbox, | |||
| 支払方法Dropdown, | |||
| 支払種別Dropdown, | |||
| } from "@/types/入金予定結果"; | |||
| import { 初回入金予定Checkbox, 定期申込予約 } from "@/types/定期申込予約"; | |||
| import { 車室情報管理フィールド名 } from "@/types/車室情報管理"; | |||
| import { addDays, endOfMonth } from "date-fns"; | |||
| export default function 日割り入金予定作成ボタン(record: 定期申込予約) { | |||
| if ( | |||
| !!record.自動承認契約情報.value && | |||
| record.初回入金予定_必要分.value.includes(初回入金予定Checkbox.日割り分) && | |||
| !record.初回入金予定_日割り分入金予定.value | |||
| ) { | |||
| setHeaderButton( | |||
| "日割り分入金予定作成", | |||
| apptemplate(async () => { | |||
| // 計算 | |||
| const 契約 = await get車室情報管理(record.自動承認契約情報.value); | |||
| const 契約日 = dateParse(契約.契約日.value); | |||
| if (契約日 === null) return; | |||
| const プラン = await get定期駐車場プランマスタ( | |||
| 契約[車室情報管理フィールド名.プラン名].value | |||
| ); | |||
| const 月末 = endOfMonth(契約日); | |||
| const 計算 = new 定期駐車場料金計算(プラン); | |||
| const 請求金額 = 計算.期間の計算(契約日, 月末); | |||
| const param = makeUrlSearchParams({ | |||
| [入金予定結果フィールド名.車室情報管理レコード番号]: | |||
| record.自動承認契約情報.value, | |||
| [入金予定結果フィールド名.初回振り込み関連申込レコード番号]: | |||
| record.$id.value, | |||
| [入金予定結果フィールド名.支払予定金額]: String(請求金額), | |||
| [入金予定結果フィールド名.支払方法]: 支払方法Dropdown.振込, | |||
| [入金予定結果フィールド名.支払種別]: 支払種別Dropdown.定期料金, | |||
| [入金予定結果フィールド名.支払対象_利用_年]: String( | |||
| 契約日.getFullYear() | |||
| ), | |||
| [入金予定結果フィールド名.支払対象_利用_月]: String( | |||
| 契約日.getMonth() + 1 | |||
| ), | |||
| [入金予定結果フィールド名.支払対象_利用_月間数]: "1", | |||
| [入金予定結果フィールド名.支払予定日]: formatDateStr( | |||
| addDays(契約日, -1) | |||
| ), | |||
| [入金予定結果フィールド名.定期料金日割り分]: [ | |||
| 定期料金日割り分Checkbox.該当, | |||
| ], | |||
| }); | |||
| const url = getCreateUrl(AppID.入金予定結果, param); | |||
| window.open(url, "_blank", "popup"); | |||
| }) | |||
| ); | |||
| } | |||
| } | |||
| @@ -0,0 +1,59 @@ | |||
| import { apptemplate } from "@/common/app-template"; | |||
| import { setHeaderButton } from "@/common/header-button"; | |||
| import { 契約情報更新イベント } from "@/event/契約情報更新"; | |||
| import { Message } from "@/exception"; | |||
| import { | |||
| ShowConfirmDialog, | |||
| SuccessDialog, | |||
| WarningDialog, | |||
| } from "@/middleware/swal"; | |||
| import { 定期申込予約, 状態Dropdown } from "@/types/定期申込予約"; | |||
| import { 申込 } from "../自動承認"; | |||
| const 表示判定 = (record: 定期申込予約): boolean => { | |||
| const S = 状態Dropdown; | |||
| if ( | |||
| ![S.新規, S.選考当選, S.予約, S.空き待ち].find((status) => { | |||
| return status === record.status.value; | |||
| }) | |||
| ) { | |||
| return false; | |||
| } | |||
| return true; | |||
| }; | |||
| export default function 自動承認ボタン(record: 定期申込予約) { | |||
| if (表示判定(record)) { | |||
| setHeaderButton( | |||
| "受付", | |||
| apptemplate(async ({ setEvent, needReloadAtEnd }) => { | |||
| if (record.台数.value !== "1") { | |||
| throw new Message("台数を1にしてください"); | |||
| } | |||
| const confirm = await ShowConfirmDialog({ | |||
| text: "承認しますか", | |||
| }); | |||
| if (!confirm.isConfirmed) return; | |||
| const entry = new 申込(record); | |||
| await entry.初期化(); | |||
| await entry.選定(); | |||
| await SuccessDialog.fire(); | |||
| await WarningDialog.fire({ | |||
| timer: 2000, | |||
| timerProgressBar: true, | |||
| text: "各初回請求データを作成してください", | |||
| }); | |||
| const 契約 = entry.作成後契約取得(); | |||
| if (!契約) throw new Error(); | |||
| setEvent(new 契約情報更新イベント().getEvent(契約)); | |||
| needReloadAtEnd(true); | |||
| }) | |||
| ); | |||
| } | |||
| } | |||
| @@ -1,75 +1,13 @@ | |||
| import { apptemplate, eventHnalder } from "@/common/app-template"; | |||
| import { AppID } from "@/common/appids"; | |||
| import { initMenuBox, setHeaderButton } from "@/common/header-button"; | |||
| import { eventHnalder } from "@/common/app-template"; | |||
| import { initMenuBox } from "@/common/header-button"; | |||
| import { KintoneEvent } from "@/common/kintone-event"; | |||
| import { 契約情報更新イベント } from "@/event/契約情報更新"; | |||
| import { | |||
| ShowConfirmDialog, | |||
| SuccessDialog, | |||
| WarningDialog, | |||
| } from "@/middleware/swal"; | |||
| import { getCreateUrl, getDetailUrl } from "@/rest-api/url"; | |||
| import { | |||
| 入金予定結果フィールド名, | |||
| 支払方法Dropdown, | |||
| 支払種別Dropdown, | |||
| } from "@/types/入金予定結果"; | |||
| import { 定期申込予約, 状態Dropdown } from "@/types/定期申込予約"; | |||
| import { 定期申込予約 } from "@/types/定期申込予約"; | |||
| import { setup } from ".."; | |||
| import { 申込 } from "./自動承認"; | |||
| import { get車室情報管理 } from "@/rest-api/車室情報管理"; | |||
| import { dateParse, formatDateStr, now } from "@/common/datetime"; | |||
| import { | |||
| addDays, | |||
| addMonths, | |||
| differenceInMonths, | |||
| endOfMonth, | |||
| getDaysInMonth, | |||
| } from "date-fns"; | |||
| import 定期駐車場料金計算 from "@/logic/定期駐車場料金計算"; | |||
| import { get定期駐車場プランマスタ } from "@/rest-api/定期駐車場プランマスタ"; | |||
| import { 車室情報2フィールド名 } from "@/types/車室情報2"; | |||
| import { 車室情報管理フィールド名 } from "@/types/車室情報管理"; | |||
| import { get定期申込予約 } from "@/rest-api/定期申込予約"; | |||
| const 初回入金予定作成画面オープン = async (record: 定期申込予約) => { | |||
| // 計算 | |||
| const 契約 = await get車室情報管理(record.自動承認契約情報.value); | |||
| const 契約日 = dateParse(契約.契約日.value); | |||
| if (契約日 === null) return; | |||
| const プラン = await get定期駐車場プランマスタ( | |||
| 契約[車室情報管理フィールド名.プラン名].value | |||
| ); | |||
| const 請求終了日: Date = (() => { | |||
| // 実行日基準に翌月の末日 | |||
| const 基準日1 = endOfMonth(addMonths(now(), 1)); | |||
| // 開始月の月末 | |||
| const 基準日2 = endOfMonth(契約日); | |||
| return 基準日1 < 基準日2 ? 基準日2 : 基準日1; | |||
| })(); | |||
| const 計算 = new 定期駐車場料金計算(プラン); | |||
| const 請求金額 = 計算.期間の計算(契約日, 請求終了日); | |||
| const param = new URLSearchParams({ | |||
| [入金予定結果フィールド名.車室情報管理レコード番号]: | |||
| record.自動承認契約情報.value, | |||
| [入金予定結果フィールド名.初回振り込み関連申込レコード番号]: | |||
| record.$id.value, | |||
| [入金予定結果フィールド名.支払予定金額]: String(請求金額), | |||
| [入金予定結果フィールド名.支払方法]: 支払方法Dropdown.振込, | |||
| [入金予定結果フィールド名.支払種別]: 支払種別Dropdown.定期料金, | |||
| [入金予定結果フィールド名.支払対象_利用_年]: String(契約日.getFullYear()), | |||
| [入金予定結果フィールド名.支払対象_利用_月]: String(契約日.getMonth() + 1), | |||
| [入金予定結果フィールド名.支払対象_利用_月間数]: String( | |||
| differenceInMonths(請求終了日, 契約日) + 1 | |||
| ), | |||
| [入金予定結果フィールド名.支払予定日]: formatDateStr(addDays(契約日, -1)), | |||
| }); | |||
| const url = getCreateUrl(AppID.入金予定結果, param); | |||
| window.open(url); | |||
| }; | |||
| import 保証金入金予定作成ボタン from "./buttons/保証金入金予定作成ボタン"; | |||
| import 初月分入金予定作成ボタン from "./buttons/初月分入金予定作成ボタン"; | |||
| import 受付メール送信ボタン from "./buttons/受付メール送信ボタン"; | |||
| import 日割り入金予定作成ボタン from "./buttons/日割り入金予定作成ボタン"; | |||
| import 自動承認ボタン from "./buttons/自動承認ボタン"; | |||
| setup(() => { | |||
| kintone.events.on( | |||
| @@ -79,60 +17,11 @@ setup(() => { | |||
| await initMenuBox(); | |||
| const S = 状態Dropdown; | |||
| if ( | |||
| [S.新規, S.選考当選, S.予約, S.空き待ち].find((status) => { | |||
| return status === record.status.value; | |||
| }) && | |||
| record.台数.value === "1" | |||
| ) { | |||
| setHeaderButton( | |||
| "自動承認", | |||
| apptemplate(async ({ setEvent, needReloadAtEnd }) => { | |||
| const confirm = await ShowConfirmDialog({ | |||
| text: "承認しますか", | |||
| }); | |||
| if (!confirm.isConfirmed) return; | |||
| const entry = new 申込(record); | |||
| await entry.初期化(); | |||
| await entry.選定(); | |||
| await SuccessDialog.fire(); | |||
| await WarningDialog.fire({ | |||
| timer: 2000, | |||
| timerProgressBar: true, | |||
| text: "初回請求データを作成してください", | |||
| }); | |||
| const 契約 = entry.作成後契約取得(); | |||
| if (!契約) throw new Error(); | |||
| // 入金予定アプリ画面オープン | |||
| { | |||
| const 申込 = await get定期申込予約(record.$id.value); | |||
| await 初回入金予定作成画面オープン(申込); | |||
| } | |||
| setEvent(new 契約情報更新イベント().getEvent(契約)); | |||
| needReloadAtEnd(true); | |||
| }) | |||
| ); | |||
| } | |||
| if ( | |||
| !!record.自動承認契約情報.value && | |||
| [S.承認_手動, S.承認_自動承認].find((status) => { | |||
| return status === record.status.value; | |||
| }) | |||
| ) { | |||
| setHeaderButton( | |||
| "初回入金予定作成", | |||
| apptemplate(async () => { | |||
| 初回入金予定作成画面オープン(record); | |||
| }) | |||
| ); | |||
| } | |||
| 自動承認ボタン(record); | |||
| 初月分入金予定作成ボタン(record); | |||
| 日割り入金予定作成ボタン(record); | |||
| 保証金入金予定作成ボタン(record); | |||
| 受付メール送信ボタン(record); | |||
| }) | |||
| ); | |||
| }); | |||
| @@ -12,6 +12,7 @@ import { | |||
| get顧客マスタ, | |||
| } from "@/rest-api/顧客マスタ"; | |||
| import { | |||
| 初回入金予定Checkbox, | |||
| 定期申込予約, | |||
| 定期申込予約フィールド名, | |||
| 状態Dropdown, | |||
| @@ -253,6 +254,21 @@ export class 申込 { | |||
| [F.状態]: 状態Dropdown.承認_自動承認, | |||
| [F.自動承認ステータス]: 自動承認ステータスDropdown.承認済, | |||
| [F.定期駐車料金]: this.プラン.契約金額.value, | |||
| [F.初回入金予定_必要分]: (() => { | |||
| const ret: string[] = []; | |||
| ret.push(初回入金予定Checkbox.初月分); | |||
| const 契約日 = dateParse(this.定期申込予約.利用開始希望日.value); | |||
| if (!契約日) throw new Error("契約日不正"); | |||
| if (契約日.getDate() !== 1) { | |||
| ret.push(初回入金予定Checkbox.日割り分); | |||
| } | |||
| if (0 < Number(this.プラン.保証金合計額.value)) { | |||
| ret.push(初回入金予定Checkbox.保証金); | |||
| } | |||
| return ret; | |||
| })(), | |||
| }), | |||
| }, | |||
| async () => { | |||
| @@ -9,8 +9,8 @@ import { | |||
| } from "date-fns"; | |||
| export const DEFAULT_DATE_FORMAT = "yyyy-MM-dd"; | |||
| export const DEFAULT_DATE_TIME_FORMAT = "yyyy/MM/dd HH:mm:ss"; | |||
| export const DEFAULT_DATE_TIME_FORMAT_ANOTHER1 = "yyyy-MM-dd HH:mm:ss"; | |||
| export const DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; | |||
| export const DEFAULT_DATE_TIME_FORMAT_ANOTHER1 = "yyyy/MM/dd HH:mm:ss"; | |||
| export const DEFAULT_YYYYMM_FORMAT = "yyyyMM"; | |||
| type Input = Date | string | null | undefined; | |||
| @@ -26,7 +26,7 @@ export const formatYYYYMMStr = (source: Date | string | null | undefined) => { | |||
| return formatToStr(source, DEFAULT_YYYYMM_FORMAT); | |||
| }; | |||
| const formatToStr = (source: Input, formatStr: string) => { | |||
| export const formatToStr = (source: Input, formatStr: string) => { | |||
| if (source === null || source === undefined) return ""; | |||
| if (source instanceof Date) return format(source, formatStr); | |||
| return format(parseISO(source), formatStr); | |||
| @@ -1,3 +1,6 @@ | |||
| import { get } from "lodash"; | |||
| import { formatDateStr } from "./datetime"; | |||
| export type Field = { | |||
| [fieldCode: string]: { | |||
| value: unknown; | |||
| @@ -27,3 +30,26 @@ export const makeRecordData = (data: { | |||
| }); | |||
| return ret; | |||
| }; | |||
| export const makeSubTableRecordData = (data: { [key: string]: any }[]) => { | |||
| const ret = data.map((row) => { | |||
| const obj: { | |||
| value: { | |||
| [key: string]: object; | |||
| }; | |||
| } = { value: {} }; | |||
| Object.keys(row).forEach((key) => { | |||
| const val = get(row, key); | |||
| obj.value[key] = val; | |||
| }); | |||
| return obj; | |||
| }); | |||
| return ret; | |||
| }; | |||
| export const makeDatetimeStr = (data: Date): string => { | |||
| return data.toISOString(); | |||
| }; | |||
| export const makeDateDatetime = (data: Date): string => { | |||
| return formatDateStr(data); | |||
| }; | |||
| @@ -1,4 +1,5 @@ | |||
| import { AppID } from "@/common/appids"; | |||
| import { get } from "lodash"; | |||
| import { sprintf } from "sprintf"; | |||
| export const getDetailUrl = (app: AppID, レコード番号: string | number) => { | |||
| @@ -15,3 +16,24 @@ export const getCreateUrl = (app: AppID, param?: URLSearchParams) => { | |||
| !!param ? param.toString() : "" | |||
| ); | |||
| }; | |||
| export const makeUrlSearchParams = (data: object) => { | |||
| const param = new URLSearchParams(); | |||
| Object.keys(data).forEach((key) => { | |||
| const val = get(data, key); | |||
| param.append(key, JSON.stringify(val)); | |||
| console.log("append", key, val, JSON.stringify(val), data); | |||
| }); | |||
| return param; | |||
| }; | |||
| export const parseFromUrlSearchQuery = () => { | |||
| const param = new URLSearchParams(location.search.replace("?", "")); | |||
| const obj: { [key: string]: string } = {}; | |||
| for (const [key, value] of param.entries()) { | |||
| obj[key] = JSON.parse(value); | |||
| } | |||
| return obj; | |||
| }; | |||
| @@ -1,5 +1,6 @@ | |||
| import { KintoneRecordField } from "@kintone/rest-api-client"; | |||
| import { AppRecord } from "."; | |||
| import { get, has, set } from "lodash"; | |||
| const F = { | |||
| 車室情報管理レコード番号: "contract_record_number", | |||
| @@ -15,6 +16,11 @@ const F = { | |||
| 初回振り込み関連申込レコード番号: "first_payment_entry_record_no", | |||
| 支払方法: "payment_method", | |||
| 支払種別: "payment_type", | |||
| 定期料金日割り分: "定期料金日割り分", | |||
| 保証金明細: "保証金明細", | |||
| 保証金明細_名称: "保証金明細_名称", | |||
| 保証金明細_金額: "保証金明細_金額", | |||
| } as const; | |||
| export const 支払種別Dropdown = { | |||
| @@ -38,6 +44,31 @@ export const 支払方法Dropdown = { | |||
| export type 支払方法Dropdown = | |||
| (typeof 支払方法Dropdown)[keyof typeof 支払方法Dropdown]; | |||
| export const 定期料金日割り分Checkbox = { | |||
| 該当: "該当", | |||
| } as const; | |||
| export type 定期料金日割り分Checkbox = | |||
| (typeof 定期料金日割り分Checkbox)[keyof typeof 定期料金日割り分Checkbox]; | |||
| export type 保証金明細行データ = { | |||
| 保証金明細_名称: KintoneRecordField.SingleLineText; | |||
| 保証金明細_金額: KintoneRecordField.Number; | |||
| }; | |||
| export const 保証金明細行データ作成 = (data: object): 保証金明細行データ => { | |||
| const row: 保証金明細行データ = { | |||
| 保証金明細_名称: { value: "", type: "SINGLE_LINE_TEXT" }, | |||
| 保証金明細_金額: { value: "", type: "NUMBER" }, | |||
| }; | |||
| Object.keys(row).forEach((target) => { | |||
| if (has(data, target)) { | |||
| set(row, target + ".value", get(data, target)); | |||
| } | |||
| }); | |||
| return row; | |||
| }; | |||
| export const 入金予定結果フィールド名 = F; | |||
| export type 入金予定結果 = AppRecord & { | |||
| @@ -58,4 +89,12 @@ export type 入金予定結果 = AppRecord & { | |||
| customer_code: KintoneRecordField.Number; | |||
| [F.支払方法]: KintoneRecordField.Dropdown; | |||
| [F.初回振り込み関連申込レコード番号]: KintoneRecordField.Number; | |||
| 定期料金日割り分: KintoneRecordField.CheckBox; | |||
| 保証金明細: { | |||
| type: "SUBTABLE"; | |||
| value: { | |||
| id: string; | |||
| value: 保証金明細行データ; | |||
| }[]; | |||
| }; | |||
| }; | |||
| @@ -14,6 +14,12 @@ const F = { | |||
| 請求対象分_金額: "請求対象分_金額", | |||
| 初回振り込み合計額: "初回振り込み合計額", | |||
| 自動承認契約情報: "自動承認契約情報", | |||
| 受付メール送信日時: "受付メール送信日時", | |||
| 承認メール送信日時: "承認メール送信日時", | |||
| 初回入金予定_必要分: "初回入金予定_必要分", | |||
| 初回入金予定_初月分入金予定: "初回入金予定_初月分入金予定", | |||
| 初回入金予定_日割り分入金予定: "初回入金予定_日割り分入金予定", | |||
| 初回入金予定_保証金入金予定: "初回入金予定_保証金入金予定", | |||
| } as const; | |||
| export const 状態Dropdown = { | |||
| @@ -36,6 +42,14 @@ export const 自動承認ステータスDropdown = { | |||
| export type 自動承認ステータスDropdown = | |||
| (typeof 自動承認ステータスDropdown)[keyof typeof 自動承認ステータスDropdown]; | |||
| export const 初回入金予定Checkbox = { | |||
| 初月分: "初月分", | |||
| 日割り分: "日割り分", | |||
| 保証金: "保証金", | |||
| } as const; | |||
| export type 初回入金予定Checkbox = | |||
| (typeof 初回入金予定Checkbox)[keyof typeof 初回入金予定Checkbox]; | |||
| export const 定期申込予約フィールド名 = F; | |||
| export type 定期申込予約 = AppRecord & { | |||
| @@ -75,4 +89,11 @@ export type 定期申込予約 = AppRecord & { | |||
| [F.自動承認ステータス]: KintoneRecordField.SingleLineText; | |||
| [F.状態]: KintoneRecordField.Dropdown; | |||
| [F.自動承認契約情報]: KintoneRecordField.Number; | |||
| [F.自動承認契約情報]: KintoneRecordField.Number; | |||
| [F.受付メール送信日時]: KintoneRecordField.DateTime; | |||
| [F.承認メール送信日時]: KintoneRecordField.DateTime; | |||
| [F.初回入金予定_必要分]: KintoneRecordField.CheckBox; | |||
| [F.初回入金予定_初月分入金予定]: KintoneRecordField.SingleLineText; | |||
| [F.初回入金予定_日割り分入金予定]: KintoneRecordField.SingleLineText; | |||
| [F.初回入金予定_保証金入金予定]: KintoneRecordField.SingleLineText; | |||
| }; | |||