Kaynağa Gözat

全体整備

develop
sosuke.iwabuchi 2 yıl önce
ebeveyn
işleme
78939be4d4
10 değiştirilmiş dosya ile 339 ekleme ve 130 silme
  1. +23
    -17
      src/apps/入金予定結果/index.tsx
  2. +83
    -41
      src/apps/定期予約選考/index.ts
  3. +8
    -9
      src/apps/定期申込予約/index.tsx
  4. +25
    -23
      src/apps/定期駐車場マスタ/index.tsx
  5. +91
    -0
      src/apps/車室情報2/index.ts
  6. +57
    -32
      src/common/header-button.ts
  7. +26
    -0
      src/common/kintone-event.ts
  8. +11
    -0
      src/rest-api/query.ts
  9. +13
    -6
      src/types/定期予約選考.ts
  10. +2
    -2
      src/types/定期申込予約.ts

+ 23
- 17
src/apps/入金予定結果/index.tsx Dosyayı Görüntüle

@@ -1,6 +1,6 @@
import { eventHnalder } from "@/common/app-template";
import { AppID } from "@/common/appids";
import { setHeaderButton } from "@/common/header-button";
import { initMenuBox, setHeaderButton } from "@/common/header-button";
import { KintoneEvent, 値設定 } from "@/common/kintone-event";
import { makeRecordData } from "@/common/rest-api-client";
import { Message } from "@/exception";
@@ -86,16 +86,19 @@ const setData = (event: any, targets: string[]) => {
(() => {
console.info("script build at " + process.env.BUILD_TIME);

kintone.events.on("app.record.detail.show", (event) => {
const currentRecord = event.record as 入金予定結果;

// 各種ボタンの設置
if (currentRecord[入金予定結果フィールド名.残金].value !== "0") {
if (currentRecord.parking_name.value.startsWith("TP")) {
setHeaderButton("テスト充当", getCallbackFillAmount(currentRecord));
kintone.events.on(
[KintoneEvent.詳細.レコード詳細画面を表示した後],
eventHnalder(async (event) => {
const currentRecord = event.record as 入金予定結果;
await initMenuBox();
// 各種ボタンの設置
if (currentRecord[入金予定結果フィールド名.残金].value !== "0") {
if (currentRecord.parking_name.value.startsWith("TP")) {
setHeaderButton("テスト充当", getCallbackFillAmount(currentRecord));
}
}
}
});
})
);

const 初回請求金額確定チェック = (record: 入金予定結果) => {
if (!record.first_payment_entry_record_no.value) {
@@ -150,13 +153,16 @@ const setData = (event: any, targets: string[]) => {
await bulkRequest.save();
};

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

kintone.events.on(
KintoneEvent.追加.保存するとき,


+ 83
- 41
src/apps/定期予約選考/index.ts Dosyayı Görüntüle

@@ -1,14 +1,19 @@
import { AppID } from "@/common/appids";
import { setHeaderButton } from "@/common/header-button";
import { initMenuBox, setHeaderButton } from "@/common/header-button";
import { makeRecordData } from "@/common/rest-api-client";
import { fillCandidates, noticeToCandidates } from "@/mypage/定期予約選考";
import {
定期予約選考,
定期予約選考フィールド名,
対象車室一覧行データ,
選考ステータスDropdown,
} from "@/types/定期予約選考";
import { 定期申込予約フィールド名, 状態Dropdown } from "@/types/定期申込予約";
import { KintoneRestAPIClient } from "@kintone/rest-api-client";
import { setup } from "..";
import { KintoneEvent, サブテーブル設定, 値設定 } from "@/common/kintone-event";
import { eventHnalder } from "@/common/app-template";
import { forEach } from "lodash";

// 検索用文字列をセットする
const setSearchCondition = (currentRecord: 定期予約選考) => {
@@ -109,43 +114,80 @@ const getCallBackHandleFinish = (currentRecord: 定期予約選考) => {
};
};

(() => {
console.info("script build at " + process.env.BUILD_TIME);

const events = ["app.record.create.show", "app.record.edit.show"];
kintone.events.on(events, (event) => {
const record = event.record as 定期予約選考;
});

kintone.events.on("app.record.detail.show", (event) => {
const currentRecord: 定期予約選考 = event.record;

// 各種ボタンの設置
if (currentRecord.選考ステータス.value === 選考ステータスDropdown.起票) {
setHeaderButton(
"候補者設定",
getCallBackHandleFillcandidates(currentRecord)
);
}
if (
currentRecord.選考ステータス.value === 選考ステータスDropdown.通知者選択中
) {
setHeaderButton(
"通知メール送信",
getCallBackHandleNoticeTocandidates(currentRecord)
);
}
if (
currentRecord.選考ステータス.value === 選考ステータスDropdown.候補者仮決定
) {
setHeaderButton("当選者確定", getCallBackHandleFinish(currentRecord));
}
});

kintone.events.on("app.record.edit.submit", (event) => {
const currentRecord: 定期予約選考 = event.record;
setSearchCondition(currentRecord);

return event;
});
})();
setup(() => {
kintone.events.on(
[KintoneEvent.追加.レコード追加画面を表示した後],
eventHnalder(async (event) => {
const param = new URLSearchParams(location.search.replace("?", ""));
if (param.has(定期予約選考フィールド名.対象車室一覧_車室レコード番号)) {
const rows = (
param.get(定期予約選考フィールド名.対象車室一覧_車室レコード番号) ??
""
)
.split(",")
.map((val) => {
return {
対象車室一覧_車室レコード番号: {
value: val,
// type: "NUMBER",
lookup: true,
},
};
});

サブテーブル設定(event, 定期予約選考フィールド名.対象車室一覧, rows);
console.log(rows, event);
}
if (param.has(定期予約選考フィールド名.駐車場名)) {
値設定(
event,
定期予約選考フィールド名.駐車場名,
param.get(定期予約選考フィールド名.駐車場名) ?? "",
true
);
}
return event;
})
);

kintone.events.on(
[KintoneEvent.詳細.レコード詳細画面を表示した後],
eventHnalder(async (event) => {
const currentRecord: 定期予約選考 = event.record;

await initMenuBox();
// 各種ボタンの設置
if (currentRecord.選考ステータス.value === 選考ステータスDropdown.起票) {
setHeaderButton(
"候補者設定",
getCallBackHandleFillcandidates(currentRecord)
);
}
if (
currentRecord.選考ステータス.value ===
選考ステータスDropdown.通知者選択中
) {
setHeaderButton(
"通知メール送信",
getCallBackHandleNoticeTocandidates(currentRecord)
);
}
if (
currentRecord.選考ステータス.value ===
選考ステータスDropdown.候補者仮決定
) {
setHeaderButton("当選者確定", getCallBackHandleFinish(currentRecord));
}
})
);

kintone.events.on(
[KintoneEvent.編集.保存するとき],
eventHnalder(async (event) => {
const currentRecord: 定期予約選考 = event.record;
setSearchCondition(currentRecord);

return event;
})
);
});

+ 8
- 9
src/apps/定期申込予約/index.tsx Dosyayı Görüntüle

@@ -1,8 +1,9 @@
import { apptemplate, eventHnalder } from "@/common/app-template";
import { AppID } from "@/common/appids";
import { setHeaderButton } from "@/common/header-button";
import { CancelError, Message } from "@/exception";
import { initMenuBox, setHeaderButton } from "@/common/header-button";
import { KintoneEvent } from "@/common/kintone-event";
import { 契約情報更新イベント } from "@/event/契約情報更新";
import {
ErrorDialog,
ShowConfirmDialog,
SuccessDialog,
WarningDialog,
@@ -10,18 +11,16 @@ import {
import { getCreateUrl, getDetailUrl } from "@/rest-api/url";
import { 入金予定結果フィールド名 } from "@/types/入金予定結果";
import { 定期申込予約 } from "@/types/定期申込予約";
import { 申込 } from "./自動承認";
import { apptemplate } from "@/common/app-template";
import { setup } from "..";
import { KintoneEvent } from "@/common/kintone-event";
import { 契約情報更新イベント } from "@/event/契約情報更新";
import { 申込 } from "./自動承認";

setup(() => {
kintone.events.on(
[KintoneEvent.詳細.レコード詳細画面を表示した後],
(event) => {
eventHnalder(async (event) => {
const record: 定期申込予約 = event.record;

await initMenuBox();
if (!record.auto_confirm_status.value) {
setHeaderButton(
"自動承認",
@@ -69,6 +68,6 @@ setup(() => {
})
);
}
}
})
);
});

+ 25
- 23
src/apps/定期駐車場マスタ/index.tsx Dosyayı Görüntüle

@@ -1,33 +1,35 @@
import { apptemplate } from "@/common/app-template";
import { setHeaderButton } from "@/common/header-button";
import { apptemplate, eventHnalder } from "@/common/app-template";
import { initMenuBox, setHeaderButton } from "@/common/header-button";
import { KintoneEvent } from "@/common/kintone-event";
import { 契約状況同期 } from "@/logic/契約状況同期";
import { ShowConfirmDialog, SuccessDialog } from "@/middleware/swal";
import bulkRequest from "@/rest-api/bulk";
import { 定期駐車場マスタ } from "@/types/定期駐車場マスタ";
import { setup } from "..";

(() => {
console.info("script build at " + process.env.BUILD_TIME);
setup(() => {
kintone.events.on(
KintoneEvent.詳細.レコード詳細画面を表示した後,
eventHnalder(async (event) => {
const record: 定期駐車場マスタ = event.record;
await initMenuBox();
setHeaderButton(
"契約状況同期",
apptemplate(async () => {
const confirm = await ShowConfirmDialog({
text: "契約状況を同期しますか",
});
if (!confirm.isConfirmed) return;

kintone.events.on(KintoneEvent.詳細.レコード詳細画面を表示した後, (event) => {
const record: 定期駐車場マスタ = event.record;
await 契約状況同期(record.駐車場名.value);

setHeaderButton(
"契約状況同期",
apptemplate(async () => {
const confirm = await ShowConfirmDialog({
text: "契約状況を同期しますか",
});
if (!confirm.isConfirmed) return;
await bulkRequest.save();

await 契約状況同期(record.駐車場名.value);
await SuccessDialog.fire();

await bulkRequest.save();

await SuccessDialog.fire();

location.reload();
})
);
});
})();
location.reload();
})
);
})
);
});

+ 91
- 0
src/apps/車室情報2/index.ts Dosyayı Görüntüle

@@ -0,0 +1,91 @@
import { apptemplate, eventHnalder } from "@/common/app-template";
import { initMenuBox, setHeaderButton } from "@/common/header-button";
import { KintoneEvent } from "@/common/kintone-event";
import {
ShowConfirmDialog,
SuccessDialog,
WarningDialog,
} from "@/middleware/swal";
import { saveReceipt } from "@/mypage/領収証発行";
import { 領収証 } from "@/types/領収証";
import { setup } from "..";
import { 車室情報2, 車室情報2フィールド名 } from "@/types/車室情報2";
import { 契約状況同期 } from "@/logic/契約状況同期";
import bulkRequest from "@/rest-api/bulk";
import { KintoneRestAPIClient } from "@kintone/rest-api-client";
import { AppID } from "@/common/appids";
import { QueryBuilder } from "@/rest-api/query";
import { 定期申込予約フィールド名, 状態Dropdown } from "@/types/定期申込予約";
import { getCreateUrl } from "@/rest-api/url";
import { 定期予約選考フィールド名 } from "@/types/定期予約選考";

const client = new KintoneRestAPIClient();

setup(() => {
const 申込確認 = async (record: 車室情報2) => {
const query = new QueryBuilder();
query
.whereIn(定期申込予約フィールド名.状態, [
状態Dropdown.予約,
状態Dropdown.空き待ち,
])
.where(定期申込予約フィールド名.駐車場名, record.定期駐車場.value);
const { records } = await client.record.getRecords({
app: AppID.定期申込予約,
query: query.build(),
});
return records.length !== 0;
};

kintone.events.on(
[KintoneEvent.詳細.レコード詳細画面を表示した後],
eventHnalder(async (event) => {
const record = event.record as 車室情報2;

await initMenuBox();
// 契約状況同期
setHeaderButton(
"契約状況同期",
apptemplate(async ({ needReloadAtEnd }) => {
const confirm = await ShowConfirmDialog({
text: "契約状況を同期しますか",
});
if (!confirm.isConfirmed) return;
await 契約状況同期(
record.定期駐車場.value,
Number(record.車室番号.value)
);
await bulkRequest.save();
await SuccessDialog.fire();
needReloadAtEnd(true);
})
);

// 選考開始
setHeaderButton(
"空き募集",
apptemplate(async () => {
// 候補者がいるか確認
const 申込有無 = await 申込確認(record);
if (!申込有無) {
await WarningDialog.fire({
title: "申込者がいないため募集できません",
});
return;
}

const url = getCreateUrl(
AppID.定期予約選考,
new URLSearchParams({
[定期予約選考フィールド名.対象車室一覧_車室レコード番号]:
record.$id.value,
[定期予約選考フィールド名.駐車場名]: record.定期駐車場.value,
})
);

window.open(url, "_blank");
})
);
})
);
});

+ 57
- 32
src/common/header-button.ts Dosyayı Görüntüle

@@ -1,39 +1,64 @@
export const setHeaderButton = (title: string, onClick: VoidFunction) => {
const interval = setInterval(() => {
const wrapper = document.getElementsByClassName(
"gaia-app-statusbar-actionmenu-wrapper"
)[0];

if (wrapper) {
// メニューが存在しなければ作成する
let menu = wrapper.querySelector(".gaia-app-statusbar-actionmenu");
if (!menu) {
menu = document.createElement("div");
menu.classList.add(".gaia-app-statusbar-actionmenu");
wrapper.appendChild(menu);
}
const getWrapper = () => {
const element = document.querySelector<HTMLDivElement>(
".gaia-app-statusbar-actionmenu-wrapper"
);

return element;
};

const getMenu = () => {
const wrapper = getWrapper();
if (wrapper === null) return null;

// ステータスバーの表示が無効になっていれば解除する
const statusbar = document.querySelector<HTMLDivElement>(
".gaia-app-statusbar"
);
if (statusbar) {
statusbar.style.display = "unset";
const menu = wrapper.querySelector<HTMLDivElement>(
".gaia-app-statusbar-actionmenu"
);
return menu;
};
export const initMenuBox = () => {
return new Promise<void>((resolve) => {
const interval = setInterval(() => {
const wrapper = getWrapper();

if (wrapper) {
// メニューが存在しなければ作成する
let menu = getMenu();
if (!menu) {
menu = document.createElement("div");
menu.classList.add("gaia-app-statusbar-actionmenu");
wrapper.appendChild(menu);
}

// ステータスバーの表示が無効になっていれば解除する
const statusbar = document.querySelector<HTMLDivElement>(
".gaia-app-statusbar"
);
if (statusbar) {
statusbar.style.display = "unset";
}

clearInterval(interval);
resolve();
}
}, 50);
});
};

const button = document.createElement("span");
button.classList.add("gaia-app-statusbar-action");
const label = document.createElement("span");
label.setAttribute("title", title);
label.innerText = title;
label.classList.add("gaia-app-statusbar-action-label");
export const setHeaderButton = (title: string, onClick: VoidFunction) => {
console.log("setHeaderButton", title);
const menu = getMenu();
if (!menu) return;

button.onclick = onClick;
const button = document.createElement("span");
button.classList.add("gaia-app-statusbar-action");
const label = document.createElement("span");
label.setAttribute("title", title);
label.innerText = title;
label.classList.add("gaia-app-statusbar-action-label");

button.appendChild(label);
menu.appendChild(button);
button.onclick = onClick;

clearInterval(interval);
}
}, 50);
button.appendChild(label);
menu.appendChild(button);
console.log("setHeaderButton", title, "complete");
};

+ 26
- 0
src/common/kintone-event.ts Dosyayı Görüntüle

@@ -37,3 +37,29 @@ export const 値設定 = (
event.record[target].lookup = true;
}
};

type サブテーブル設定Props = {
[target: string]: {
value: any;
lookup?: boolean;
};
};
export const サブテーブル設定 = (
event: any,
target: string,
rows: サブテーブル設定Props[]
) => {
const template: any = event.record[target].value[0].value;
const val = rows.map((row) => {
const v: any = {};
Object.keys(row).forEach((ele) => {
console.log("add", ele, row[ele], template[ele]);
v[ele] = {
...template[ele],
...row[ele],
};
});
return { value: v };
});
event.record[target].value = val;
};

+ 11
- 0
src/rest-api/query.ts Dosyayı Görüntüle

@@ -21,6 +21,17 @@ export class QueryBuilder {
return this;
}

whereIn(カラム: string, 条件: string[]) {
const condition = 条件
.map((val) => {
return sprintf('"%s"', val);
})
.join(",");

this.whereConditions.push(sprintf("%s in (%s)", カラム, condition));
return this;
}

orderBy(カラム: string, 並び: ORDER = "asc") {
this.order.push({
カラム,


+ 13
- 6
src/types/定期予約選考.ts Dosyayı Görüntüle

@@ -3,9 +3,13 @@ import { AppRecord } from ".";

const F = {
選考ステータス: "選考ステータス",
駐車場名: "駐車場名",
検索用_申込一覧_レコード番号: "検索用_申込一覧_レコード番号",
検索用_契約希望者_レコード番号: "検索用_契約希望者_レコード番号",
検索用_選考結果_レコード番号: "検索用_選考結果_レコード番号",

対象車室一覧: "対象車室一覧",
対象車室一覧_車室レコード番号: "対象車室一覧_車室レコード番号",
} as const;

export const 選考ステータスDropdown = {
@@ -20,6 +24,13 @@ export type 選考ステータスDropdown =
(typeof 選考ステータスDropdown)[keyof typeof 選考ステータスDropdown];

export const 定期予約選考フィールド名 = F;

export type 対象車室一覧行データ = {
対象車室一覧_車室タイプ?: KintoneRecordField.SingleLineText;
対象車室一覧_車室番号?: KintoneRecordField.SingleLineText;
[F.対象車室一覧_車室レコード番号]: KintoneRecordField.Number;
};

export type 定期予約選考 = AppRecord & {
利用開始日: KintoneRecordField.Date;
[F.検索用_契約希望者_レコード番号]: KintoneRecordField.SingleLineText;
@@ -27,7 +38,7 @@ export type 定期予約選考 = AppRecord & {
[F.選考ステータス]: KintoneRecordField.Dropdown;
選考締切日: KintoneRecordField.Date;
[F.検索用_申込一覧_レコード番号]: KintoneRecordField.SingleLineText;
駐車場名: KintoneRecordField.SingleLineText;
[F.駐車場名]: KintoneRecordField.SingleLineText;
[F.検索用_選考結果_レコード番号]: KintoneRecordField.SingleLineText;
申込者一覧: KintoneRecordField.Subtable<{
申込者一覧_申込レコード番号: KintoneRecordField.Number;
@@ -41,11 +52,7 @@ export type 定期予約選考 = AppRecord & {
申込者一覧_状態: KintoneRecordField.SingleLineText;
申込者一覧_通知対象: KintoneRecordField.CheckBox;
}>;
対象車室一覧: KintoneRecordField.Subtable<{
対象車室一覧_車室タイプ: KintoneRecordField.SingleLineText;
対象車室一覧_車室番号: KintoneRecordField.SingleLineText;
対象車室一覧_車室レコード番号: KintoneRecordField.Number;
}>;
[F.対象車室一覧]: KintoneRecordField.Subtable<対象車室一覧行データ>;
選考結果一覧: KintoneRecordField.Subtable<{
選考結果一覧_氏名: KintoneRecordField.SingleLineText;
選考結果一覧_申込レコード番号: KintoneRecordField.Number;


+ 2
- 2
src/types/定期申込予約.ts Dosyayı Görüntüle

@@ -5,7 +5,7 @@ const F = {
状態: "status",
自動承認ステータス: "auto_confirm_status",
利用開始希望日: "利用開始希望日",
駐車場名: "駐車場",
定期駐車料金: "定期駐車料金",
振込期日: "振込期日",
日割り分_月: "日割り分_月",
@@ -62,7 +62,7 @@ export type 定期申込予約 = AppRecord & {
メモ: KintoneRecordField.MultiLineText;
車室番号: KintoneRecordField.SingleLineText;
ParkingNavi駐車場: KintoneRecordField.SingleLineText;
駐車場: KintoneRecordField.SingleLineText;
[F.駐車場名]: KintoneRecordField.SingleLineText;
[F.振込期日]: KintoneRecordField.Date;
日割り分_金額: KintoneRecordField.Number;
自動承認メモ: KintoneRecordField.MultiLineText;


Yükleniyor…
İptal
Kaydet