import { IAction, IActionResult, IActionNode, IActionProperty, IContext, IField, } from "../types/ActionTypes"; import { actionAddins } from "."; import type { Record} from "@kintone/rest-api-client/lib/src/client/types"; import { KintoneRestAPIClient} from "@kintone/rest-api-client"; import "./auto-lookup.scss"; import "bootstrap/js/dist/modal"; // import "bootstrap/js/dist/spinner"; import {Modal} from "bootstrap" import $ from "jquery"; interface Props { displayName: string; lookupField: LookupField; condition: Condition; } interface Condition { queryString: string; index: number; type: string; children: Child[]; parent: null; logicalOperator: string; } interface Child { index: number; type: string; parent: string; object: any; operator: string; value: string; } interface LookupField { app: App; fields: Field[]; } interface Field { name: string; type: string; code: string; label: string; noLabel: boolean; required: boolean; lookup: Lookup; } interface Lookup { relatedApp: RelatedApp; relatedKeyField: string; fieldMappings: FieldMapping[]; lookupPickerFields: any[]; filterCond: string; sort: string; } interface FieldMapping { field: string; relatedField: string; } interface RelatedApp { app: string; code: string; } interface App { id: string; name: string; description: string; createdate: string; } export class AutoLookUpAction implements IAction { name: string; actionProps: IActionProperty[]; props: Props; constructor() { this.name = "ルックアップ更新"; this.actionProps = []; this.props = {} as Props; this.register(); } /*** * アクセスのメインの処理関数 */ async process( prop: IActionNode, event: any, context: IContext ): Promise { this.actionProps = prop.actionProps; this.props = { ...prop.ActionValue, condition: JSON.parse((prop.ActionValue as any).condition), } as Props; // console.log(context); let result = { canNext: true, result: "", } as IActionResult; try { const lookUpFields = this.props.lookupField.fields.filter( (f) => f.lookup && f.lookup.relatedApp.app === String(kintone.app.getId()) ); if (!lookUpFields || lookUpFields.length===0) { throw new Error( `ルックアップの設定は不正です。${this.props.lookupField.fields[0].label} ` ); } const lookUpField = this.props.lookupField.fields[0]; const key = event.record[lookUpField.lookup.relatedKeyField].value; const targetRecords = await this.getUpdateRecords(lookUpField, key); //更新対象がない時にスキップ if(targetRecords.length===0){ return result; } const updateRecords = this.convertForLookup(targetRecords,lookUpField,key); console.log("updateRecords", updateRecords); this.showSpinnerModel(this.props.lookupField.app); await this.updateLookupTarget(updateRecords); this.showResult(this.props.lookupField.app,updateRecords.length); } catch (error) { console.error("ルックアップ更新中例外が発生しました。", error); if(error instanceof Error){ event.error = error.message; }else{ event.error = "ルックアップ更新中例外が発生しました。"; } result.canNext = false; } console.log("autoLookupProps", this.props); return result; } /** * REST API用クエリ作成 * TODO:共通関数として作成 * @param lookUpField * @param key * @returns */ makeQuery=(lookUpField:Field,key:any)=>{ if(typeof key==='number'){ return `${lookUpField.code} = ${key}` } if(typeof key==='string'){ return `${lookUpField.code} = "${key}"` } } /** * 更新対象のレコードを取得する */ getUpdateRecords = async (lookUpField:Field,key:any):Promise< Record[]>=>{ const client=new KintoneRestAPIClient(); const resp = await client.record.getAllRecords({ app:this.props.lookupField.app.id, fields:["$id"], condition:this.makeQuery(lookUpField,key) }); return resp; } /** * ルックアップ更新用レコードに変換する * @param targetRecords 更新対象レコード * @param lookUpField ルックアップフィールド * @param key ルックアップフィールドの値 * @returns */ convertForLookup = (targetRecords:Record[],lookUpField:Field,key:any):Array=>{ return targetRecords.map((r) => ({ id: Number(r["$id"].value), record: { [lookUpField.code]: { value: key } }, })); } /** * ルックアップ先を更新する * @param updateRecords */ updateLookupTarget = async (updateRecords:Array)=>{ if (updateRecords && updateRecords.length > 0) { const client=new KintoneRestAPIClient(); client.record.updateAllRecords({ app:this.props.lookupField.app.id, records:updateRecords }); // await kintone.api(kintone.api.url("/k/v1/records.json", true), "PUT", { // app: this.props.lookupField.app.id, // records: updateRecords // }); } } /** * 更新中のダイアログ表示 * @param app */ showSpinnerModel = (app:App) => { let dialog = $("#alcLookupModal"); if(dialog.length===0){ const modalHTML = ` `; dialog = $(modalHTML).appendTo("body"); dialog.get()[0].addEventListener('hidden.bs.modal',(ev)=>{ Modal.getOrCreateInstance(dialog.get()[0]).dispose(); $("#alcLookupModal").remove(); }); }else{ const dialogBody=$("#alcLookupModal .modal-body"); const htmlrow=`
${app.name}
`; dialogBody.append(htmlrow); } Modal.getOrCreateInstance(dialog.get()[0]).show(); } /** * 更新結果を表示する * @param app  更新先アプリ情報 * @param count 更新件数 */ showResult=(app:App,count:number)=>{ const dialogBody=$(`#alcLookupModal .modal-body #app${app.id}`); const html=`
${app.name}
更新件数:${count}件
`; dialogBody.html(html); } register(): void { actionAddins[this.name] = this; } } new AutoLookUpAction();