Browse Source

初回入金対応

develop
sosuke.iwabuchi 2 years ago
parent
commit
733c9a9eb8
10 changed files with 282 additions and 55 deletions
  1. +92
    -17
      src/apps/入金予定結果/index.tsx
  2. +23
    -24
      src/apps/定期申込予約/index.tsx
  3. +17
    -9
      src/apps/定期申込予約/自動承認.ts
  4. +45
    -0
      src/common/app-template.ts
  5. +1
    -0
      src/common/appids.ts
  6. +39
    -0
      src/common/kintone-event.ts
  7. +1
    -0
      src/rest-api/bulk.ts
  8. +16
    -0
      src/rest-api/定期申込予約.ts
  9. +35
    -0
      src/rest-api/定期駐車場プランマスタ.ts
  10. +13
    -5
      src/types/定期申込予約.ts

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

@@ -1,9 +1,15 @@
import { eventHnalder } from "@/common/app-template";
import { AppID } from "@/common/appids";
import { 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 { 入金予定結果, 入金予定結果フィールド名 } from "@/types/入金予定結果";
import { 定期申込予約フィールド名 } from "@/types/定期申込予約";
import { KintoneRestAPIClient } from "@kintone/rest-api-client";
import { format } from "date-fns";
import Swal from "sweetalert2";
@@ -74,8 +80,7 @@ const setData = (event: any, targets: string[]) => {
targets.forEach((target) => {
const value = param.get(target);
if (value === null) return;
event.record[target].value = value;
event.record[target].lookup = true;
値設定(event, target, value, true);
});
};
(() => {
@@ -92,7 +97,61 @@ const setData = (event: any, targets: string[]) => {
}
});

kintone.events.on("app.record.create.show", (event) => {
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 申込 = await get定期申込予約(
record.first_payment_entry_record_no.value
);

// 申込の初回振り込み情報を入力する
const F = 定期申込予約フィールド名;
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 request = new BulkRequest();
request.update({
app: AppID.定期申込予約,
id: record.first_payment_entry_record_no.value,
record: makeRecordData({
[F.振込期日]: 支払予定日,
[F.初回振り込み合計額]: 支払予定金額,
[F.請求対象分_月]: record.target_month.value,
[F.請求対象分_金額]: 申込.定期駐車料金.value,
[F.日割り分_金額]: String(日割り金額),
[F.日割り分_月]: 日割り月,
}),
});
await request.save();
};

kintone.events.on(KintoneEvent.追加.レコード追加画面を表示した後, (event) => {
setData(event, [
入金予定結果フィールド名.車室契約情報レコード番号,
入金予定結果フィールド名.初回振り込み関連申込レコード番号,
@@ -100,18 +159,34 @@ const setData = (event: any, targets: string[]) => {
return event;
});

kintone.events.on("app.record.create.submit.success", (event) => {
const record = event.record as 入金予定結果;
// 初回請求確定時にはメールを送信する
if (
record[入金予定結果フィールド名.初回振り込み関連申込レコード番号].value
) {
sendEmail(EmailID.申込受付, {
season_ticket_contract_entry_record_no: Number(
record[入金予定結果フィールド名.初回振り込み関連申込レコード番号]
.value
),
});
}
});
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) => {
const record = event.record as 入金予定結果;
// 初回請求確定時にはメールを送信する
if (
record[入金予定結果フィールド名.初回振り込み関連申込レコード番号].value
) {
// メール送信
sendEmail(EmailID.申込受付, {
season_ticket_contract_entry_record_no: Number(
record[入金予定結果フィールド名.初回振り込み関連申込レコード番号]
.value
),
});
}
})
);
})();

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

@@ -7,10 +7,11 @@ import {
SuccessDialog,
WarningDialog,
} from "@/middleware/swal";
import { getCreateUrl } from "@/rest-api/url";
import { getCreateUrl, getDetailUrl } from "@/rest-api/url";
import { 入金予定結果フィールド名 } from "@/types/入金予定結果";
import { 定期申込予約 } from "@/types/定期申込予約";
import { 申込 } from "./自動承認";
import { apptemplate } from "@/common/app-template";

(() => {
console.info("script build at " + process.env.BUILD_TIME);
@@ -19,13 +20,14 @@ import { 申込 } from "./自動承認";
const record: 定期申込予約 = event.record;

if (!record.auto_confirm_status.value) {
setHeaderButton("自動承認", async () => {
const confirm = await ShowConfirmDialog({
text: "承認しますか",
});
if (!confirm.isConfirmed) return;
setHeaderButton(
"自動承認",
apptemplate(async () => {
const confirm = await ShowConfirmDialog({
text: "承認しますか",
});
if (!confirm.isConfirmed) return;

try {
const entry = new 申込(record);
await entry.初期化();
await entry.選定();
@@ -45,25 +47,22 @@ import { 申込 } from "./自動承認";
[入金予定結果フィールド名.初回振り込み関連申込レコード番号]:
record.$id.value,
});
const url = getCreateUrl(AppID.入金予定結果, param);
console.log(url, param);
window.open(url, "_blank");
{
// 入金予定アプリ画面オープン
const url = getCreateUrl(AppID.入金予定結果, param);
console.log(url, param);
window.open(url, "_blank");
}
{
// 車室契約情報アプリ画面オープン
const url = getDetailUrl(AppID.車室契約情報, 契約.$id.value);
console.log(url, param);
window.open(url, "_blank");
}

location.reload();
} catch (e) {
if (e instanceof CancelError) {
console.log("canceled");
return;
} else if (e instanceof Message) {
ErrorDialog.fire({
text: e.message,
});
return;
}
ErrorDialog.fire();
throw e;
}
});
})
);
}
});
})();

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

@@ -1,14 +1,10 @@
import { AppID } from "@/common/appids";
import { makeRecordData } from "@/common/rest-api-client";
import { 契約状況同期 } from "@/logic/契約状況同期";
import {
ConfirmDialog,
ShowConfirmDialog,
showLoadingDialog,
} from "@/middleware/swal";
import { EmailID, sendEmail } from "@/mypage/メール";
import { ShowConfirmDialog } from "@/middleware/swal";
import { BulkRequest } from "@/rest-api/bulk";
import { getDetailUrl } from "@/rest-api/url";
import { get定期駐車場プランマスタ } from "@/rest-api/定期駐車場プランマスタ";
import { get自動承認グループ } from "@/rest-api/自動承認グループ";
import { get車室契約情報, get車室契約情報一覧 } from "@/rest-api/車室契約情報";
import { get車室情報一覧 } from "@/rest-api/車室情報2";
@@ -23,14 +19,13 @@ import {
状態Dropdown,
自動承認ステータスDropdown,
} from "@/types/定期申込予約";
import { 定期駐車場プランマスタ } from "@/types/定期駐車場プランマスタ";
import { 自動承認グループ } from "@/types/自動承認グループ";
import { 車室契約情報, 車室契約情報フィールド名 } from "@/types/車室契約情報";
import { 車室情報2 } from "@/types/車室情報2";
import { 顧客マスタフィールド名 } from "@/types/顧客マスタ";
import { sprintf } from "sprintf";
import { CancelError, Message } from "../../exception";
import { 入金予定結果フィールド名 } from "@/types/入金予定結果";
import { dateParse, now } from "@/common/datetime";
import { CancelError, Message } from "@/exception";

export class 申込 {
private 定期申込予約: 定期申込予約;
@@ -43,6 +38,7 @@ export class 申込 {
private 車室一覧: 車室情報2[] = [];
private 契約一覧: 車室契約情報[] = [];
private 自動承認グループ: 自動承認グループ | null = null;
private プラン: 定期駐車場プランマスタ | null = null;

private 作成後契約: 車室契約情報 | null = null;

@@ -59,6 +55,8 @@ export class 申込 {
await this.契約情報取得();
// 自動承認データの取得
await this.自動承認グループ取得();
// 定期駐車場プランマスタデータの取得
await this.プラン取得();

this.初期化済み = true;
return this;
@@ -117,6 +115,14 @@ export class 申込 {
this.定期申込予約.定期駐車場プラン.value
);
}
private async プラン取得() {
if (!this.定期申込予約.定期駐車場プラン.value) {
throw new Message("プラン名の設定をしてください");
}
this.プラン = await get定期駐車場プランマスタ(
this.定期申込予約.定期駐車場プラン.value
);
}

private 対象車室取得() {
if (!this.初期化済み) {
@@ -227,6 +233,7 @@ export class 申込 {
}

private async 申込情報完了() {
if (this.プラン === null) throw new Error();
const F = 定期申込予約フィールド名;
this.requests.update({
app: AppID.定期申込予約,
@@ -234,6 +241,7 @@ export class 申込 {
record: makeRecordData({
[F.状態]: 状態Dropdown.承認_自動承認,
[F.自動承認ステータス]: 自動承認ステータスDropdown.承認済,
[F.定期駐車料金]: this.プラン.契約金額.value,
}),
});
}


+ 45
- 0
src/common/app-template.ts View File

@@ -0,0 +1,45 @@
import { CancelError, Message } from "@/exception";
import { ErrorDialog } from "@/middleware/swal";

export const apptemplate = (callback: () => Promise<void>) => {
return async () => {
try {
const ret = await callback();
} catch (e) {
if (e instanceof CancelError) {
console.log("canceled");
return;
} else if (e instanceof Message) {
ErrorDialog.fire({
text: e.message,
});
return;
}
ErrorDialog.fire();
throw e;
}
};
};

export const eventHnalder = (callback: (event: any) => Promise<any>) => {
return async (event: any) => {
try {
const ret = await callback(event);
return ret;
} catch (e) {
if (e instanceof CancelError) {
console.log("canceled");
return false;
} else if (e instanceof Message) {
console.error("message", e.message);
ErrorDialog.fire({
text: e.message,
});
return false;
}
ErrorDialog.fire();
console.error(e);
return false;
}
};
};

+ 1
- 0
src/common/appids.ts View File

@@ -12,5 +12,6 @@ export const AppID = {
車室契約情報: APP_ID.車室契約情報,
車室情報2: APP_ID.車室情報2,
自動承認グループ: APP_ID.自動承認グループ,
定期駐車場プランマスタ: APP_ID.定期駐車場プランマスタ,
} as const;
export type AppID = (typeof AppID)[keyof typeof AppID];

+ 39
- 0
src/common/kintone-event.ts View File

@@ -0,0 +1,39 @@
export const KintoneEvent = {
一覧: {
一覧画面を表示した後: "app.record.index.show",
},

詳細: {
レコード詳細画面を表示した後: "app.record.detail.show",
レコードを削除する前: "app.record.detail.delete.submit",
プロセス管理のアクションを実行したとき: "app.record.detail.process.proceed",
},
// レコード追加画面
追加: {
レコード追加画面を表示した後: "app.record.create.show",
保存するとき: "app.record.create.submit",
保存に成功した後: "app.record.create.submit.success",
},

// レコード編集画面
編集: {
レコード編集画面を表示した後: "app.record.edit.show",
保存するとき: "app.record.edit.show",
保存に成功した後: "app.record.edit.success",
},
} as const;

export const 画面遷移 = (event: any, url: string) => {
event.url = url;
};
export const 値設定 = (
event: any,
target: string,
value: any,
lookup: boolean = false
) => {
event.record[target].value = value;
if (lookup) {
event.record[target].lookup = true;
}
};

+ 1
- 0
src/rest-api/bulk.ts View File

@@ -74,6 +74,7 @@ export class BulkRequest {
}

async save() {
this.debug();
let results: BulkRequestResponse[] = [];
for (const requests of chunk(this.requests, 20)) {
const res = await this.client.bulkRequest({ requests });


+ 16
- 0
src/rest-api/定期申込予約.ts View File

@@ -0,0 +1,16 @@
import { AppID } from "@/common/appids";
import { 定期申込予約 } from "@/types/定期申込予約";
import { KintoneRestAPIClient } from "@kintone/rest-api-client";

const client = new KintoneRestAPIClient();

export const get定期申込予約 = async (
レコード番号: string | number
): Promise<定期申込予約> => {
const { record } = await client.record.getRecord<定期申込予約>({
app: AppID.定期申込予約,
id: レコード番号,
});

return record;
};

+ 35
- 0
src/rest-api/定期駐車場プランマスタ.ts View File

@@ -0,0 +1,35 @@
import { AppID } from "@/common/appids";
import {
定期駐車場プランマスタ,
定期駐車場プランマスタフィールド名,
} from "@/types/定期駐車場プランマスタ";
import { KintoneRestAPIClient } from "@kintone/rest-api-client";
import { sprintf } from "sprintf";

const client = new KintoneRestAPIClient();

export const get定期駐車場プランマスタ = async (
プラン名: string
): Promise<定期駐車場プランマスタ> => {
const query = sprintf(
sprintf('%s = "%s"', 定期駐車場プランマスタフィールド名.プラン名, プラン名)
);

const { records } = await client.record.getRecords<定期駐車場プランマスタ>({
app: AppID.定期駐車場プランマスタ,
query,
});

if (records.length !== 1) {
throw new Error(
sprintf(
"定期駐車場プランマスタ取得数数エラー expect %d, actual %d query:%s",
1,
records.length,
query
)
);
}

return records[0];
};

+ 13
- 5
src/types/定期申込予約.ts View File

@@ -5,6 +5,14 @@ const F = {
状態: "status",
自動承認ステータス: "auto_confirm_status",
利用開始希望日: "利用開始希望日",

定期駐車料金: "定期駐車料金",
振込期日: "振込期日",
日割り分_月: "日割り分_月",
日割り分_金額: "日割り分_金額",
請求対象分_月: "請求対象分_月",
請求対象分_金額: "請求対象分_金額",
初回振り込み合計額: "初回振り込み合計額",
} as const;

export const 状態Dropdown = {
@@ -38,12 +46,12 @@ export type 定期申込予約 = AppRecord & {
台数: KintoneRecordField.SingleLineText;
防犯登録番号: KintoneRecordField.SingleLineText;
請求対象分_月: KintoneRecordField.Number;
初回振り込み合計額: KintoneRecordField.Number;
[F.初回振り込み合計額]: KintoneRecordField.Number;
メールアドレス: KintoneRecordField.SingleLineText;
受付日時: KintoneRecordField.DateTime;
学生手帳: KintoneRecordField.SingleLineText;
氏名: KintoneRecordField.SingleLineText;
定期駐車料金: KintoneRecordField.Number;
[F.定期駐車料金]: KintoneRecordField.Number;
学校名: KintoneRecordField.SingleLineText;
住所: KintoneRecordField.SingleLineText;
電話番号: KintoneRecordField.SingleLineText;
@@ -55,13 +63,13 @@ export type 定期申込予約 = AppRecord & {
車室番号: KintoneRecordField.SingleLineText;
ParkingNavi駐車場: KintoneRecordField.SingleLineText;
駐車場: KintoneRecordField.SingleLineText;
振込期日: KintoneRecordField.Date;
[F.振込期日]: KintoneRecordField.Date;
日割り分_金額: KintoneRecordField.Number;
自動承認メモ: KintoneRecordField.MultiLineText;
車両番号: KintoneRecordField.SingleLineText;
請求対象分_金額: KintoneRecordField.Number;
[F.請求対象分_金額]: KintoneRecordField.Number;
ParkingNaviプラン: KintoneRecordField.SingleLineText;
日割り分_月: KintoneRecordField.Number;
[F.日割り分_月]: KintoneRecordField.Number;
支払方法: KintoneRecordField.Dropdown;
[F.自動承認ステータス]: KintoneRecordField.SingleLineText;
[F.状態]: KintoneRecordField.Dropdown;


Loading…
Cancel
Save