拡張機能によってモデル要素をカスタマイズする
このチュートリアルでは、フリート管理拡張モデルを詳しく見ていきます。 このモデルには、フリート管理アプリケーションの機能を拡張する要素が含まれています。 拡張機能 を作成することにより、モデル要素をカスタマイズすることができます。 Microsoft Dynamics AX 2012 の オーバーレイ機能とは異なり、拡張機能はベースライン モデル要素をオーバーレイしません。 代わりに、拡張機能はモデルと関連付けられているビジネス ロジックに追加またはカスタマイズする別のアセンブリとしてコンパイルされます。 テーブルにフィールドを追加、またはフォームにコントロールを追加することなどによりメタデータを拡張、およびイベント ハンドラおよびプラグイン クラスを定義することによりビジネス ロジックを拡張またはカスタマイズすることができます。 テーブル、フォーム、フォーム データ ソース、フォーム コントロール、およびその他を使用して、様々な定義済みイベントでイベント ハンドラーを作成することができるようになりました。 プラグインは、アプリケーションのビジネス ロジックを交換または拡張するできるようにする新しい機能拡張の概念でもあります。
前提条件
このチュートリアルでは、リモート デスクトップを使用して環境にアクセスし、インスタンスの管理者としてプロビジョニングする必要があります。
フリート管理モデルを理解する
フリート管理アプリケーションは、車両、顧客、および車両予約を管理するためのシステムをレンタカー会社に提供します。 アプリケーションは、フリート係とフリート マネージャの役割で使用されるよう設計されています。
フリート係
担当者は、顧客との対面または電話でのやり取りを処理する受付従業員です。 担当者は主に、アプリケーションに顧客情報を入力する、顧客の車両予約を作成する、車両アクセサリをオファーすることで予約をアップセルする、車両レンタルの終了時に車両の返却を処理することに関心を持っています。 担当者は、各自のニーズを予測し、楽しくて印象的なエクスペリエンスを提供しながら、顧客とやり取りすることにより、フリート管理ワークスペースを使用して顧客とのやり取りを準備することに大部分の時間を費やします。
フリート マネージャー
マネージャーは、業務要件とプロセスの設定を処理するバック オフィス従業員です。 マネージャーは、車両の情報を入力する、使用可能な車両アクセサを定義する、車両メンテナンス、価格を決定する、および収益、アップセルの成功などのビジネス パフォーマンス測定を分析することに主に関心を持っています。 アプリケーションのビジネス ロジックは、次の 3 つの主なエンティティとそれらの間の関係を中心に展開されます。
顧客
顧客は、車両の予約を行い、車両のアクセサリを選択し、車両をチェックアウトおよび返却をし、車両のレンタル料を支払うためにフリート係に連絡します。 顧客関連の情報は、FMCustomer というテーブルに保管されています。
車両及び運搬具
車両は主として価格が異なり、車両のクラスに比例します。 車両に関する情報を格納するテーブルの名前は、 FMVehicleで始まります。
引当とレンタル
引当は、顧客および車両間の関係を処理します。 引当情報には、引当日、顧客情報、車両の選択と価格、およびアクセサリや手数料などの追加の雑費が含まれます。 引当やレンタル情報は、FMRental および FMRentalCharge テーブルに格納されます。 計算エンジンは、車両予約の価格決定に関連するトランザクションの情報を処理します。 このデータ モデルを使用すると、フリート管理アプリケーションは基本的な自動車レンタル経験を提供します。
フリート管理モデルを拡張
基本的なフリート管理アプリケーションは、追加機能でカスタマイズされています。これらの機能によりレンタカー会社は、割引を使用して顧客に価格インセンティブを提供することができます。 これらの割引機能を使用可能にする追加のビジネス ロジックおよびデータは、フリート管理拡張モデルに格納されます。 割引機能は、3 つの主要なカスタマイズを介してフリート管理アプリケーションに価値を追加します。
フリート管理拡張モデル
割引に関連する情報を格納する 2 つの新しいテーブルが追加されました。 FEDiscounts には、すべての割引とその料金のリストが保存されています。 FERentalDiscountRelationTable は割引が適用される引当を追跡します。 既存のテーブルは、価格設定スキームへの割引口座に拡張されました。 FMRental という特定の予約の車両料金を追跡するテーブルは、車両料金の割引に対応するように拡張されました。 FMRentalCharge という予約のアクセサリーを追跡しているテーブルは、アクセサリーに適用される割引に対応するために拡張されました。
フリート管理拡張計算エンジン
基本的な計算エンジンには、カスタマイズにより、新しい割引によって定義されたさまざまな価格決定スキーマが追加されています。 プラグイン クラスによって、基本計算エンジンの機能が置き換えられました。 車両の予約が 7 日間を超えるときは、車両フリート管理モデルが、車両の 1 日当たりの料金とより低い 1 週間あたりの料金との差に基づいて、節約を計算します。 プラグインは、同じ動作を割引を使用して実現できるため、1 週間あたりの料金の計算を削除します。
フリート管理ユーザー インターフェイス拡張
FMRental という名前のフォームに組み込まれている Rental は、担当者が予約に割引を適用できるように拡張されています。 画面上の価格の概要は、予約に関連する車両およびアクセサリに適用可能な割引に関する貯蓄情報によってリアルタイムで更新されます。 次の手順では、フリート管理拡張モデルでのカスタマイズを調べて、自分でカスタマイズの一部を再実装します。
段取り
前のチュートリアルでフリート管理ソリューションを開いていない場合は、以下の手順を実行します。 フリート管理ソリューション ファイルは、Dynamics AX のダウンロード可能な VM で利用できます。
- デスクトップで、Visual Studio ショートカットをダブルクリックして、開発環境を開きます。
- FleetManagement ソリューションを開きます。 ファイル メニューで、開くをポイントし、プロジェクト/ソリューションを選択します。
- デスクトップを参照し、FleetManagement フォルダーを開きます。 ソリューション ファイルが自分のコンピューターにない場合、作成手順は フリート管理サンプル アプリケーションのエンド アンド エンドのシナリオ に記載されています。
- FleetManagement という名前のソリューション ファイルを選択します。 表示されるファイル タイプは Microsoft Visual Studio Solution です。
- 開く を選択します。 ソリューションを開くには時間がかかる場合があります。
デモ データのインストール
デモ データを既にインストールしている場合、次のセクションに進めます。
VM で、Microsoft Edge を開き、アプリケーションのベース URL に移動します。
サインインします。
ダッシュ ボードで、ナビゲーション ウィンドウを開き、フリート管理 > 設定 > フリート設定に移動します。
デモ データの設定をクリックします。
デモ データの再読み込みを促すメッセージが表示されたら、はいを選択します。
データの読み込みが完了したら、 閉じる を選択します。
ダッシュ ボードで、ナビゲーション バーを開き、システム管理 > 共通 > 集計の測定を維持に移動します。 (手順 7 ~ 9 は、新しいリリースでは適用できません。)
FMAggregateMeasurements を選択し、アクション ペインで今すぐ更新を選択します。
処理が完了するまで待機します。 進行中の処理は、一連の移動するドットによってページの上部に示されます。 インジケータが消えて、前回処理時刻 フィールドが更新されると、処理が完了します。
1 ボックス環境で FMRental フォームを開く
VM で、Microsoft Edge を開き、Dynamics AX アプリケーションのベース URL に移動します。 詳細については、トピック 開発環境の配置とアクセス を参照してください。
求められた場合にログインします。
予約管理 タイルをクリックして予約管理ワークスペースを開きます。
予約管理ワークスペースが開いたら、現在のレンタルを選択します。
グリッド ビューでレンタル フォームが開きます。
レンタル フォームを読み込んだら、オプション > ビューの変更 > ヘッダーを選択して、ヘッダーの表示を開きます。
ヘッダーの表示フォームを読み込んだら、下までスクロールし、割引 タブを展開します。このタブはフリート管理モデルに含まれていません。 これは、FMRental フォームに対する拡張機能としてフリート管理拡張モデルでモデリングされています。
割引を追加するために追加を選択します。
得意先割引を選択し、OK を選択します。 選択した割引が 割引 グリッドに追加されます。
FactBox を開くには、ショートカット キー Alt+F2 を使用します。
右側のレンタル合計情報ボックスを展開し、適用されるディスカウントの割引を表示します。
フリート管理割引の拡張プロジェクトの概要
このチュートリアルでは、FleetManagementDiscounts プロジェクトにフリート管理拡張という名前のモデルに属しているモデルの要素が含まれます。 ここで、プロジェクト要素について調べ、学びます。
ツリー デザイナーで FMRental.Extension に移動します。
Visual Studio のソリューション エクスプローラーの FleetManagement 割引プロジェクトで、ユーザー インターフェイス > フォーム機能拡張と展開します。
FMRental.Extension 要素は、2 つの新しいデータ ソースと新しいタブ コントロールを追加することによって FMRental フォームの機能を拡張する拡張要素です。
ソリューション エクスプローラーで、FMRental.Extension をダブルクリックしてデザイナーを開きます。 次のイメージに示します。
- 斜体のテキストで示されているデータ ソースはベースライン フォームで定義されているデータ ソースです。
- 太字で示されているデータ ソースは現在の拡張子で定義されています。
デザイナーは、その拡張機能を含めて、モデル要素の統合ビューを表示します。 読み取り専用ノードは斜体で表示さえrますが、現在の拡張機能に属するノードはカスタマイズの種類を示す他の視覚的な記号と共に太字で表示されます。
デザイナーの検索ボックスに、次の図に示すように「e:」と入力します。 現在のデザイナーがフィルター処理され、現在の拡張に属するノードのみが表示されます。
また、'e:LineViewDiscounts' と入力してデザイナーをフィルター処理し、LineViewDiscounts という名前と一致し現在の拡張子に属するノードを表示することができます。
内容を確認するには、LineViewDiscounts ノードを展開します。
FMRental.Extension XML ファイルを開いてメタデータを表示
ソリューション エクスプローラーで、FMRental.Extension フォーム拡張子をクリックしてからプログラムから開くをクリックします。
プログラムから開くダイアログ ボックスで、XML (テキスト) エディターを選択してから OK をクリックします。
デザイナーを閉じるように求めるメッセージが表示されたら、はい をクリックします。
対応するマイナス記号をクリックすると、制御およびデータ ソース ノードの子ノードが折りたたまれます。 正しい結果については次の図を参照してください。
XML ファイルには、FMRental.Extension 要素に関連付けられているメタデータが含まれます。 このファイルに、拡張機能の一部である 1 つのみのタブ ページ コントロールおよび 2 つのデータ ソースを説明するメタデータが含まれることがわかります。 基本フォームからのメタデータが含まれていないことを確認することもできます。
フリート管理割引の拡張プロジェクトのその他の要素の表示
FleetManagement Discounts プロジェクトには 2 つの新しいテーブル FEDiscount および FERentalDiscountRelationTable と、既存のフリート管理テーブル FMRental および FMRentalCharge への 2 つの拡張が含まれています。
ソリューション エクスプローラーの FleetManagement 割引でデータ モデル > テーブル拡張機能 > FMRental.Extension をダブルクリックしてデザイナーを開きます。
フィールドノードを展開し、拡張子に追加されたフィールド FEVehicleRateDiscount がベース FMRental テーブルに含まれていることを確認します。
同様に、デザイナーで FMRentalChange.Extension 要素を開いて、その内容を調べます。
データ イベント ハンドラーの検査
ソリューション エクスプローラーの FleetManagement 割引プロジェクトで、コード > クラス > FMRentalCharge_Extension をダブルクリックしてコード エディターを開きます。
このクラスには、FMRentalCharge テーブルの更新および挿入イベントに登録するイベント ハンドラーの実装が含まれています。 Microsoft Dynamics AX では、テーブルおよび他の種類で発生する可能性のあるデータ イベントが導入されます。 基本 X++ コードをオーバーレイせずにビジネス ロジックを拡張するアプリケーションを有効にする、テーブルのデータ イベントを申し込むことができます。 このチュートリアルの後半で、簡単にテーブル イベントをサブスクライブする方法について説明します。
メモ
このクラスが拡張クラス (_Extension の接尾語によって示される) であることを確認します。 任意のクラスでイベント ハンドラーを作成することができます。このクラスは拡張クラスである必要はありません。 拡張子クラスは、拡張メソッドを作成するために必要です。 拡張メソッドの詳細については、拡張メソッド 記事の「拡張メソッド」セクションを参照してください。
プラグイン クラスの表示
前のセクションに示された FMRentalCharge_Extension クラスのイベント ハンドラー コードでは、両方のイベント ハンドラーが FMTotalsEngineBase::GetInstance を呼び出してフリート管理計算エンジンの現在のインスタンスを取得することを確認してください。 計算エンジンは、プラグイン クラスを使用して実装されます。 クラス ファクトリは、コンフィギュレーションまたはビジネス データに基づくプラグイン クラスの適切なインスタンスを作成します。
FMRentalCharge_Extension.xpp を表示するコード エディター ウィンドウで、GetInstance を右クリックしてから定義に移動を選択します。 抽象クラス FMTotalsEngineBase が表示したコード エディターが開きます。 この抽象クラスはプラグインポイントと呼ばれ、次の属性に関連付けられています: [Microsoft.Dynamics.AX.Platform.Extensibility.ExportInterfaceAttribute()]
プラグイン クラスは、抽象クラスやインターフェイスの拡張機能または実装を表します。 プラグイン クラスは、そのメタデータとプラグイン ポイントを定義する属性に関連付けられます。 この例では、FMTotalsEngineBase プラグイン ポイントに関連付けられている 2 つのプラグイン クラスがあります。 基本計算エンジンは、プラグイン クラス FMTotalsEngine によって定義されます。 プロジェクト 移行されたフリート管理 > コード > クラス で見つけることができます。
割引計算エンジンは、プラグイン クラス FEDiscountEngine によって定義されます。 プロジェクト フリート管理割引 > コード > クラス で見つけることができます。
GetInstance メソッドを確認します。 このメソッドは、プラグイン ファクトリ SysPluginFactory::Instance を使用して、現在のプラグイン メタデータに基づいて現在の計算エンジンのインスタンスを作成します。 プラグイン メタデータは、グローバル構成テーブルの FMParameters で指定されます。
財務と運用アプリは、構成可能なプラグイン クラスもサポートしており、クラスに関連付けられているプラグイン メタデータは開発時には未知で、管理者がランタイム時に構成可能です。 このチュートリアルでは、その機能についてカバーしていません。
追加のフリート管理拡張子を作成する
このセクションでは、Visual Studio ツールを使用して拡張機能を作成して操作する方法を示します。
FMVehicle テーブルを拡張
ソリューション エクスプローラーで、FleetManagement 割引プロジェクトを選択します。
Visual studio のアプリケーション エクスプローラーで、表示 > アプリケーション エクスプローラーを選択して、FMVehicle という名前のテーブルを検索します。 フィルター バーに
FMVehicle type:Table
と入力し、Enter を押します。FMVehicle を右クリックしてから、拡張機能の作成を選択します。
FMVehicle.Extension という名前の FleetManagement Discounts プロジェクトで FMVehicle テーブルの拡張機能が作成されます。
ソリューション エクスプローラーで、FMVehicle.Extension を右クリックしてからプログラムから開くを選択します。 ダイアログ ボックスで XML (テキスト) エディターを選択してから OK を選択します。 注記: この拡張子ファイルは、データベースの FMVehicle テーブルのメタデータを含まない簡単なテンプレートです。 拡張ファイルには拡張を定義するメタデータのみが常に含まれ、基本モデル要素からは何もありません。
XML エディターを閉じます。
ソリューション エクスプローラーで、FMVehicle.Extension をダブルクリックしてデザイナーを開きます。
フィールド を右クリックし、新しい整数型フィールドを追加します。 フィールドの名前を NumberOfCylinders に変更します。
プロパティ ウィンドウで、新しいフィールドのラベル プロパティを NumberofCylinders に設定します。
NumberOfCylinders フィールドを AutoReport フィールド グループにドラッグ アンド ドロップし、ベース テーブルのフィールド グループに展開します。
FMVehicle.Extension を保存します。
イベントノードを展開します。 イベント ノードには、テーブルが公開するすべてのイベントが一覧表示されます。 このリストには、フレームワークによって定義されたイベントと、アプリケーション開発者によって定義されたデリゲート メソッドが含まれています。
メモ
テーブルのイベント、フォームイベント、フォーム データ ソース イベント、フォーム コントロール イベントなど、異なるフレームワーク イベントが、さまざまなタイプの要素とサブ要素のデザイナーに公開されています。
onValidatedWrite を右クリックし、イベント ハンドラー メソッドをコピー を選択します。
このステップは、イベント ハンドラー メソッドのシグネチャをクリップボードにコピーします。
FMVehicleEventHandlers という名前の新しいクラスを FleetManagement Discounts プロジェクトに追加します。
ソリューション エクスプローラーで、FEVehicleEventHandlers をダブルクリックしてコード エディターを開きます。
右クリックし、手順 12 にコピーしたイベント ハンドラー メソッドを貼り付けます。
Class FMVehicleEventHandlers { /// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> [DataEventHandler(tableStr(FMVehicle), DataEventType::ValidatedWrite)] public static void FMVehicle_onValidatedWrite(Common sender, DataEventArgs e) { } }
次のコードを FMVehicleonValidatedWrite イベント ハンドラーに挿入します。 このコードは、シリンダの数が 8 を超えることができないことを検証します。
[DataEventHandler(tableStr(FMVehicle), DataEventType::ValidatedWrite)] public static void FMVehicle_onValidatedWrite(Common sender, DataEventArgs e) { ValidateEventArgs validateArgs = e as ValidateEventArgs; FMVehicle vehicle = sender as FMVehicle; boolean result = validateArgs.parmValidateResult(); if (vehicle.NumberOfCylinders > 8) { result = checkFailed("Invalid number of cylinders."); validateArgs.parmValidateResult(result); } }
FMVehicleEventHandlers クラス を保存する
ヒント
モデルの任意の クラス にイベント ハンドラー を貼り付けて定義することができます。 クラス FMVehicleEventHandlers は、例としてのみ使用されます。
FMVehicle フォームを拡張
次に、FleetManagement 割引プロジェクトの FMVehicle フォーム拡張機能を追加します。 最初に、ソリューション エクスプローラーでこのプロジェクトを選択することを確認します。
アプリケーション エクスプローラーを使用して FMVehicle という名前のフォームを検索し、アプリケーション エクスプローラーのフィルター バーに
FMVehicle type:form
を入力します。フォームを右クリックし、拡張子の作成 をクリックします。
下に示すように、NumberOfCylinders という名前の新しい整数コントロールを Attributes2 グループ コントロールに追加します。 このコントロールは、デザイン> タブ > TabPageDetails > TabHeader > DetailsDetails > Attributes2 を展開すると見つけることができます。
次のように新しいコントロールをプロパティ ウィンドウの NumberOfCylinders データ フィールドにバインドします。
FMVehicle.Extension を保存し、プロジェクトを作成します。
拡張機能をテスト
ソリューション エクスプローラーで、FleetManagement 割引を右クリックしてから、スタートアップ プロジェクトとして設定をクリックします。
同様に、FleetManagement 割引で、スタートアップ オブジェクトとして FMVehicle.Extension フォームを設定します。
Ctrl+F5 キーを押してデバッグなしで開始するか、デバッグ メニューを使用します。
車両フォームが開いた後、車両を選択して詳細を表示します。
詳細タブを展開し、新しいシリンダ番号フィールドを通知します。
アクション ウィンドウで、編集をクリックしてシリンダの数フィールドの値を 12 に変更します。
アクション ウィンドウで、保存をクリックします。
検証エラーを確認します。
有効なシリンダ数を 9 より小さく入力し、次に新しい値を保存します。
フォーム コントロールでのイベント ハンドラーを試す
既存のコントロールにイベント ハンドラー メソッドを追加できます。
FMRental フォーム デザイナーで AddLine コマンド ボタン コントロールを検索し、OnClicked イベントを右クリックし、次に選択イベント ハンドラーのメソッドをコピーを選択します。
フリート管理拡張モデルのクラスでイベント ハンドラー メソッドを貼り付け、X++ コードを追加して実装します。
/// <summary> /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> [FormControlEventHandler(formControlStr(FMRental, AddLine), FormControlEventType::Clicked)] public static void AddLine_OnClicked(FormControl sender, FormControlEventArgs e) { }
AddLine_OnClicked イベント ハンドラーを実装すると、sender パラメーターを使用して、ボタン コントロール インスタンスにアクセスできます。
FormButtonControl button = sender as FormButtonControl;
親フォームや、変数のいずれかにアクセスする場合は、この例では、FormRun インスタンスとデータ ソースのいずれかにアクセスする方法が示されています。
FormRun fr;
fr = sender.formRun();
var frDs = fr.dataSource("FMRental");
フォーム データ ソースでのイベント ハンドラーを試す
テーブル、フォーム コントロールおよびその他の要素タイプと同じように、フォーム データ ソースとフォーム データ ソース フィールドはフレームワーク レベルのイベントを提供します。 次の例は、フォーム データ ソースの ValidatingWrite イベントまたはフォーム データ ソースの検証イベントを使用して FMRental フォームのユーザー入力を検証する方法を示しています。 この機能は、Platform Update 7 以降で利用できます。
/// <summary>
/// When saving a new rental, prevent setting the start mileage on the FMRental form to a value that is equal to 1
/// </summary>
[FormDataSourceEventHandler(formDataSourceStr(FMRental, FMRental), FormDataSourceEventType::ValidatingWrite)]
public static void FMRental_OnValidatingWrite(FormDataSource sender, FormDataSourceEventArgs e)
{
var datasource = sender as FormDataSource;
var args = e as FormDataSourceCancelEventArgs;
if (args != null && datasource != null)
{
FMRental record = datasource.cursor() as FMRental;
if (record.recId == 0)
{
if(record.startmileage == 1)
{
boolean doCancel = !checkFailed("Start Mileage = 1 is not allowed");
args.cancel(doCancel);
}
}
}
}
/// <summary>
/// Prevent changing the start mileage field on the FMRental form to a value that is equal to 1
/// </summary>
[FormDataFieldEventHandler(formDataFieldStr(FMRental, FMRental, StartMileage), FormDataFieldEventType::Validating)]
public static void StartMileage_OnValidating(FormDataObject sender, FormDataFieldEventArgs e)
{
var dataObject = sender as FormDataObject;
var args = e as FormDataFieldCancelEventArgs;
if (args != null && dataObject != null)
{
var datasource = dataObject.datasource() as FormDataSource;
if (datasource != null)
{
FMRental record = datasource.cursor() as FMRental;
if (record.RecId > 0)
{
if (record.StartMileage == 1 )
{
boolean doCancel = !checkFailed("Start Mileage = 1 is not allowed");
args.cancel(doCancel);
}
}
}
}
}
テーブル 拡張子ディスプレイを試し、メソッドを編集
拡張メソッドを使用すると、新しい表示を作成してテーブルを拡張し、オーバーレイ X++ コード無しでテーブルのメソッドを編集します (拡張メソッドは、名前に _Extension という接尾語のあるクラスに属している必要があります)。 たとえば、このクラスは、CupHoldersDisplay と呼ばれる拡張表示メソッドを使用して、FMVehicle テーブルを拡張する方法を表示します。
public static class FMVehicle_Extension
{
public static display int CupHoldersDisplay(FMVehicle vehicle)
{
return 7;
}
}
フォームまたはフォームの拡張機能では、以下の画像に示すように、「Data Source = FMVehicle」および「Data method ="FMVehicle_Extension::CupHoldersDisplay」を設定することによってこの表示メソッドにコントロールをバインドできます。
展開のためのフリート拡張パッケージを作成する
拡張機能をテスト環境、運用前環境、運用環境などの別の環境に展開するには、展開パッケージを作成する必要があります。
Visual Studio の Dynamics AX メニューで、配置をポイントしてから、配置パッケージの作成を選択します。
フリート管理拡張 チェック ボックスをオンにします。
パッケージ ファイルの場所テキスト ボックスに、「c:\FMLab」と入力します。
作成を選択します。 フリート管理拡張パッケージを含む配置パッケージが作成されます。