import { actionAddins } from "."; import { IAction, IActionResult, IActionNode, IActionProperty, IField ,IContext, IVarName} from "../types/ActionTypes"; /** * アクションの属性定義 */ interface IDateTimeCalcProps{ verNameGet:string; calcOption:string; verName:IVarName; year:string; month:string; date:string; hour:string; minute:string; second:string; } /** * */ export class DateTimeCalcAction implements IAction{ name: string; actionProps: IActionProperty[]; props:IDateTimeCalcProps; constructor(){ this.name="日時を加算/減算する";// DBに登録したアクション名 this.actionProps=[]; //プロパティ属性の初期化 this.props={ verNameGet:'', calcOption:'', verName:{name:''}, year:"0", month:"0", date:"0", hour:"0", minute:"0", second:"0" } //アクションを登録する this.register(); } /** * 基準日となる変数の値が、日付・日時の形式であるか、判断する * @param {string} dateValue * @returns {boolean} */ isDateValue(dateValue :string){ let date; //正規表現チェック let singleDigitMonth = dateValue.match(/(\d{4})-(\d{1})-(\d{1})$/);//4桁の数字-1桁の数字-2桁の数字 let twoDigitMonth = dateValue.match(/(\d{4})-(\d{2})-(\d{2})$/);//4桁の数字-2桁の数字-2桁の数字 let singleDigitDate = dateValue.match(/(\d{4})-(\d{2})-(\d{1})$/);//4桁の数字-2桁の数字-1桁の数字 let twoDigitDate = dateValue.match(/(\d{4})-(\d{1})-(\d{2})$/);//4桁の数字-1桁の数字-2桁の数字 let dateTimeMilliSecond = dateValue.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}).(\d{2,3})Z$/);//時刻入りのUTCの日付形式(ミリ秒) let dateTime = dateValue.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z$/);//時刻入りのUTCの日付形式 //date型に変換 date = new Date(dateValue); //date型変換できたか確認 if(date !== undefined && !isNaN(date.getDate())){ //正規表現チェック確認 if(twoDigitMonth === null && singleDigitMonth === null && singleDigitDate === null && twoDigitDate === null && dateTime === null && dateTimeMilliSecond === null){ throw new Error("計算の基準日となる値が、適切な日付・日時の形式ではありません。「日時を加算/減算する」コンポーネントの処理を中断しました。"); } } return true; } /** * 値を数値に変換する * @param {any} context * @param {string} calcValue,calcOption * @returns {number} */ valueToNumber(context :any,calcValue :string,calcOption :string): number{ const getContextVarByPath = (obj: any, path: string) => { return path.split(".").reduce((o, k) => (o || {})[k], obj); }; //計算値が変数の場合は、変数の値を取得 if(calcOption === "変数" && isNaN(Number(calcValue))){ calcValue = getContextVarByPath (context.variables,calcValue); } //数値型に変換 let number = Number(calcValue); //有限数かどうか判定 if(!isFinite(number)){ throw new Error("計算値が、数値ではありません。「日時を加算/減算する」コンポーネントの処理を中断しました。"); } return number; } /** * 日付・日時を加算・減算する * @param {any} dateValue * @param {number} year month day hour minute second * @returns {string} */ calcDate(dateValue:any,year:number,month:number,date:number,hour:number,minute:number,second:number):string{ let calcResult; //フィールドの値(文字列)をdate型に変換する dateValue = new Date(dateValue); // 年を計算 dateValue.setFullYear(dateValue.getFullYear()+year); //月を計算 dateValue.setMonth(dateValue.getMonth()+month); //日を計算 dateValue.setDate(dateValue.getDate()+date); //時間を計算 dateValue.setHours(dateValue.getHours()+hour); //分を計算 dateValue.setMinutes(dateValue.getMinutes()+minute); //秒を計算 dateValue.setSeconds(dateValue.getSeconds()+second); //UTC形式に変換 calcResult = dateValue.toISOString(); return calcResult; } /** * アクションの実行を呼び出す * @param actionNode * @param event * @returns */ async process(actionNode:IActionNode,event:any,context:IContext):Promise { let result={ canNext:true, result:false }; try{ //属性設定を取得する this.actionProps = actionNode.actionProps; this.props = actionNode.ActionValue as IDateTimeCalcProps; const getContextVarByPath = (obj: any, path: string) => { return path.split(".").reduce((o, k) => (o || {})[k], obj); }; //基準日となる変数の値取得 const dateValue = getContextVarByPath (context.variables,this.props.verNameGet); //基準日となる変数の値が空の場合、処理を終了する if(!dateValue){ throw new Error("基準値となる変数の値が空、または存在しません。「日時を加算/減算する」コンポーネントの処理を中断しました。"); } let checkDateValue; //基準値となる変数の値、日時、日付形式か確認する checkDateValue = this.isDateValue(dateValue); if(checkDateValue){ //計算値の入力方法を取得する let calcOptions = this.props.calcOption; //計算値を数値型に変換する let year = this.valueToNumber(context,this.props.year,calcOptions); let month = this.valueToNumber(context,this.props.month,calcOptions); let date = this.valueToNumber(context,this.props.date,calcOptions); let hour = this.valueToNumber(context,this.props.hour,calcOptions); let minute = this.valueToNumber(context,this.props.minute,calcOptions); let second = this.valueToNumber(context,this.props.second,calcOptions); //計算結果の日付を格納する変数 let calculatedDate; //日付を加算、減算する calculatedDate = this.calcDate(dateValue,year,month,date,hour,minute,second); //計算結果を変数に代入する context.variables[this.props.verName.name] = calculatedDate; } result= { canNext:true, result:true } return result; }catch(error){ context.errors.handleError(error,actionNode); result.canNext=false; return result; } } register(): void { actionAddins[this.name]=this; } } new DateTimeCalcAction();