diff --git a/src/apps/入金予定結果/index.tsx b/src/apps/入金予定結果/index.tsx index dbc9805..7dcf371 100644 --- a/src/apps/入金予定結果/index.tsx +++ b/src/apps/入金予定結果/index.tsx @@ -21,7 +21,7 @@ import { 定期申込予約フィールド名 } from "@/types/定期申込予約 import { 車室情報管理フィールド名 } from "@/types/車室情報管理"; import { 顧客マスタフィールド名 } from "@/types/顧客マスタ"; import { KintoneRestAPIClient } from "@kintone/rest-api-client"; -import { addDays, format, setHours } from "date-fns"; +import { addDays, addMonths, format, setHours, setMonth } from "date-fns"; import Swal from "sweetalert2"; const client = new KintoneRestAPIClient(); @@ -179,16 +179,24 @@ const setData = (event: any, targets: 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.請求対象分_月]: record.target_month.value, + [F.請求対象分_月]: String(請求対象分月.getMonth() + 1), [F.請求対象分_金額]: 申込.定期駐車料金.value, - [F.日割り分_金額]: String(日割り金額), - [F.日割り分_月]: 日割り月, + [F.日割り分_金額]: 日割り金額 === 0 ? "" : String(日割り金額), + [F.日割り分_月]: + 日割り金額 === 0 ? "" : String(日割り対象月.getMonth() + 1), }), }); await bulkRequest.save(); @@ -204,6 +212,10 @@ const setData = (event: any, targets: string[]) => { 入金予定結果フィールド名.支払予定金額, 入金予定結果フィールド名.支払種別, 入金予定結果フィールド名.支払方法, + 入金予定結果フィールド名.支払対象_利用_年, + 入金予定結果フィールド名.支払対象_利用_月, + 入金予定結果フィールド名.支払対象_利用_月間数, + 入金予定結果フィールド名.支払予定日, ]); 残金設定(record); diff --git a/src/apps/定期申込予約/index.tsx b/src/apps/定期申込予約/index.tsx index c05a41a..2342c74 100644 --- a/src/apps/定期申込予約/index.tsx +++ b/src/apps/定期申込予約/index.tsx @@ -9,10 +9,67 @@ import { WarningDialog, } from "@/middleware/swal"; import { getCreateUrl, getDetailUrl } from "@/rest-api/url"; -import { 入金予定結果フィールド名 } from "@/types/入金予定結果"; +import { + 入金予定結果フィールド名, + 支払方法Dropdown, + 支払種別Dropdown, +} from "@/types/入金予定結果"; import { 定期申込予約, 状態Dropdown } 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); +}; setup(() => { kintone.events.on( @@ -51,22 +108,10 @@ setup(() => { const 契約 = entry.作成後契約取得(); if (!契約) throw new Error(); - const param = new URLSearchParams({ - [入金予定結果フィールド名.車室情報管理レコード番号]: - 契約.$id.value, - [入金予定結果フィールド名.初回振り込み関連申込レコード番号]: - record.$id.value, - }); + // 入金予定アプリ画面オープン { - // 入金予定アプリ画面オープン - const url = getCreateUrl(AppID.入金予定結果, param); - console.log(url, param); - window.open(url, "_blank"); - } - { - // 車室情報管理アプリ画面オープン - const url = getDetailUrl(AppID.車室情報管理, 契約.$id.value); - window.open(url, "_blank"); + const 申込 = await get定期申込予約(record.$id.value); + await 初回入金予定作成画面オープン(申込); } setEvent(new 契約情報更新イベント().getEvent(契約)); @@ -84,15 +129,7 @@ setup(() => { setHeaderButton( "初回入金予定作成", apptemplate(async () => { - // 車室情報管理アプリ画面オープン - const param = new URLSearchParams({ - [入金予定結果フィールド名.車室情報管理レコード番号]: - record.自動承認契約情報.value, - [入金予定結果フィールド名.初回振り込み関連申込レコード番号]: - record.$id.value, - }); - const url = getCreateUrl(AppID.入金予定結果, param); - window.open(url, "_blank"); + 初回入金予定作成画面オープン(record); }) ); } diff --git a/src/logic/定期駐車場料金計算.ts b/src/logic/定期駐車場料金計算.ts new file mode 100644 index 0000000..42a2d06 --- /dev/null +++ b/src/logic/定期駐車場料金計算.ts @@ -0,0 +1,87 @@ +import { 定期駐車場プランマスタ } from "@/types/定期駐車場プランマスタ"; +import { + addMonths, + differenceInDays, + endOfMonth, + getDaysInMonth, + getMonth, + getYear, +} from "date-fns"; + +export default class 定期駐車場料金計算 { + private プラン: 定期駐車場プランマスタ; + + 当月分_月: number | null = null; + 当月分_金額: number | null = null; + 前月分_月: number | null = null; + 前月分_金額: number | null = null; + + constructor(プラン: 定期駐車場プランマスタ) { + this.プラン = プラン; + } + + 期間の計算(開始日: Date, 終了日: Date): number { + console.log("期間の計算", 開始日, 終了日); + + let 計算結果 = 0; + let loopContinue = true; + let loopCount = 0; + + let 処理中開始日 = 開始日; + + while (loopContinue) { + let 処理中終了日 = endOfMonth(処理中開始日); + if (終了日 < 処理中終了日) { + 処理中終了日 = 終了日; + loopContinue = false; + } + const 金額 = this.月の計算(処理中開始日, 処理中終了日); + 計算結果 += 金額; + + this.前月分_月 = this.当月分_月; + this.前月分_金額 = this.当月分_金額; + this.当月分_月 = 処理中開始日.getMonth() + 1; + this.当月分_金額 = 金額; + + 処理中開始日 = addMonths(処理中開始日, 1); + 処理中開始日.setDate(1); + + if (終了日 < 処理中開始日) { + loopContinue = false; + } + + loopCount++; + if (12 < loopCount) { + throw new Error("期間の計算は1年未満まで可能"); + } + } + return 計算結果; + } + + 月の計算(開始日: Date, 終了日: Date | null = null): number { + if (終了日 === null) { + 終了日 = endOfMonth(開始日); + } + console.log("月の計算", 開始日, 終了日); + if ( + getYear(開始日) !== getYear(終了日) || + getMonth(開始日) !== getMonth(終了日) + ) { + throw new Error("開始日終了日エラー 銅年月を指定すること"); + } + const 月の日数 = getDaysInMonth(開始日); + const 利用日数 = differenceInDays(終了日, 開始日) + 1; + if (利用日数 < 0) { + throw new Error("利用日日数エラー"); + } + + const 契約金額 = Number(this.プラン.契約金額.value); + if (月の日数 === 利用日数) { + console.log({ 契約金額, 月の日数, 利用日数 }); + return 契約金額; + } + const 計算結果 = Math.floor((契約金額 / 月の日数) * 利用日数); + console.log({ 計算結果, 月の日数, 利用日数 }); + return 計算結果; + } +}