Browse Source

初回請求分対応

develop
sosuke.iwabuchi 1 year ago
parent
commit
8705a2ffb3
13 changed files with 567 additions and 238 deletions
  1. +56
    -111
      src/apps/入金予定結果/index.tsx
  2. +90
    -0
      src/apps/定期申込予約/buttons/保証金入金予定作成ボタン.ts
  3. +71
    -0
      src/apps/定期申込予約/buttons/初月分入金予定作成ボタン.ts
  4. +84
    -0
      src/apps/定期申込予約/buttons/受付メール送信ボタン.ts
  5. +67
    -0
      src/apps/定期申込予約/buttons/日割り入金予定作成ボタン.ts
  6. +59
    -0
      src/apps/定期申込予約/buttons/自動承認ボタン.ts
  7. +13
    -124
      src/apps/定期申込予約/index.tsx
  8. +16
    -0
      src/apps/定期申込予約/自動承認.ts
  9. +3
    -3
      src/common/datetime.ts
  10. +26
    -0
      src/common/rest-api-client.ts
  11. +22
    -0
      src/rest-api/url.ts
  12. +39
    -0
      src/types/入金予定結果.ts
  13. +21
    -0
      src/types/定期申込予約.ts

+ 56
- 111
src/apps/入金予定結果/index.tsx View File

@@ -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();
}
})
);


+ 90
- 0
src/apps/定期申込予約/buttons/保証金入金予定作成ボタン.ts View File

@@ -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");
})
);
}
}

+ 71
- 0
src/apps/定期申込予約/buttons/初月分入金予定作成ボタン.ts View File

@@ -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");
})
);
}
}

+ 84
- 0
src/apps/定期申込予約/buttons/受付メール送信ボタン.ts View File

@@ -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);
})
);
}
}

+ 67
- 0
src/apps/定期申込予約/buttons/日割り入金予定作成ボタン.ts View File

@@ -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");
})
);
}
}

+ 59
- 0
src/apps/定期申込予約/buttons/自動承認ボタン.ts View File

@@ -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);
})
);
}
}

+ 13
- 124
src/apps/定期申込予約/index.tsx View File

@@ -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);
})
);
});

+ 16
- 0
src/apps/定期申込予約/自動承認.ts View File

@@ -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 () => {


+ 3
- 3
src/common/datetime.ts View File

@@ -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);


+ 26
- 0
src/common/rest-api-client.ts View File

@@ -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);
};

+ 22
- 0
src/rest-api/url.ts View File

@@ -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;
};

+ 39
- 0
src/types/入金予定結果.ts View File

@@ -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: 保証金明細行データ;
}[];
};
};

+ 21
- 0
src/types/定期申込予約.ts View File

@@ -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;
};

Loading…
Cancel
Save