この記事では、Microsoft Dynamics 365 Commerce の [顧客の追加/編集] 画面など、既存の POS ビューを拡張する方法について説明します。
トランザクション画面とようこそ画面を拡張するには、画面レイアウト デザイナーを使用します。 顧客の追加/編集画面など、他のすべての POS ビューを拡張するには、リテール ソフトウェア開発キット (SDK) を使用します。 この記事では、Retail SDK による既存の POS ビューの拡張について説明します。
POS ビューでは、次の拡張ポイントとパターンがサポートされます。
- カスタム アプリケーション バーのボタン - 選択したページのアプリケーション バーにカスタム ボタンを追加します。
- カスタム列セット - 選択したページのグリッド列をカスタム列に置き換えます。
- カスタム コントロール - 選択したページに、新しいコントロールを追加します。
- カスタム フィルター – 選択したページにカスタム フィルターを追加します。
拡張機能をサポートする POS ビュー
次の表に、拡張機能をサポートする POS ビューを示します。 また、各 POS ビューがサポートする拡張ポイントのタイプも示します。
メモ
今後のリリースと修正プログラムでは、他のビューでより多くの拡張ポイントのサポートが追加されます。
| POS ビュー (リリース) | サポートされているカスタム コントロール | サポートされているカスタム列 | サポートされているカスタム アプリ バー ボタン |
|---|---|---|---|
| カート ビュー (画面レイアウトに基づく) | 有 | 有 | いいえ |
| カスタマー追加編集ビュー | 有 | いいえ | 有 |
| 顧客詳細ビュー | 有 | いいえ | 有 |
| SearchView | いいえ | 有 | 有 |
| 在庫検索ビュー | いいえ | 有 | 有 |
| ショージャーナルビュー | いいえ | 有 | 有 |
| シンプル製品詳細ビュー | 有 | いいえ | 有 |
| 住所追加編集ビュー | 有 | いいえ | 有 |
| PaymentView | いいえ | いいえ | 有 |
| PriceCheckView | 有 | いいえ | 有 |
| PriceCheckViewPhone | いいえ | いいえ | 有 |
| SearchOrdersView | いいえ | 有 | 有 |
| SearchPickingAndReceivingView | いいえ | 有 | 有 |
| 顧客注文履歴ビュー | いいえ | 有 | いいえ |
| SearchStockCountView | いいえ | 有 | いいえ |
| StockCountDetailsView | いいえ | 有 | 有 |
| ResumeCartView | いいえ | 有 | 有 |
| InventoryLookupMatrixView | いいえ | いいえ | 有 |
| SuspendTransactionView | いいえ | 有 | いいえ |
| ManageShiftView | いいえ | いいえ | 有 |
| レポート詳細ビュー | いいえ | いいえ | 有 |
| 転送注文詳細ビュー | いいえ | いいえ | 有 |
| FulfillmentLineView | いいえ | 有 | 有 |
| ReturnTransactionView | いいえ | 有 | 有 |
| PickingAndReceivingDetailsView | いいえ | 有 | 有 |
| PickingAndReceivingDetailsView (高度な倉庫) | いいえ | 有 | 有 |
| SalesInvoiceDetailsView (10.0.11) | いいえ | いいえ | 有 |
| SalesInvoicesView (10.0.11) | いいえ | 有 | いいえ |
| InventoryDocumentShippingAndReceivingView (10.0.13) | いいえ | はい (10.0.23) | 有 |
| 在庫文書一覧ビュー | いいえ | はい (10.0.15) | はい (10.0.13) |
| ManageShiftsView | いいえ | はい (10.0.21) | いいえ |
メモ
テーブルは、最新のリリースバージョンと修正プログラムに基づいて更新されます。 以前のバージョンでは、これらの拡張ポイントの一部は使用できません。
[履歴の表示 (行グリッド)] および [トランザクションの戻り値] ビューでは、行サブフィールドを使用してカスタム列がサポートされます。 これらのサブフィールドは、情報コード メッセージ、シリアル番号、割引値など、列ではなく行として表示されます。
カスタム フィルターの拡張機能
次の表の POS ビューは、カスタム フィルター拡張機能をサポートしています。 検索順序ビュー では、拡張機能を使用して、ユーザー インターフェイス (UI) での検索の既定のパラメーターを設定することもできます。 たとえば、店舗検索において既定のパラメーターを追加する場合は、拡張機能を使用して UI にそのパラメーターを表示することができます。
| POS ビュー | カスタム フィルターはサポートされていますか? | 既定のフィルター パラメーター? | リリース |
|---|---|---|---|
| ショージャーナルビュー | 有 | いいえ | |
| SearchOrdersView | 有 | 有 | |
| FulfillmentLineView | 有 | いいえ | |
| 在庫文書一覧ビュー | 有 | いいえ | 10.0.23 |
| InventoryDocumentShippingAndReceivingView | 有 | いいえ | 10.0.25 |
| 在庫調整ドキュメント一覧ビュー | 有 | いいえ | 10.0.25 |
| 在庫調整書類作業表示 | 有 | いいえ | 10.0.25 |
| InventoryDocumentStockCountingListView | 有 | いいえ | 10.0.25 |
| 在庫ドキュメント在庫計数作業ビュー | 有 | いいえ | 10.0.25 |
カスタム フィルター拡張機能のサンプル コードは、 ...\RetailSDK\Code\POS\Extensions\SampleExtensions\ViewExtensions\SearchOrders\SampleOrderSearchTextFilter.tsの Retail SDK で入手できます。
カスタム列とアプリ バー ボタンの追加
Microsoft Visual Studio 2015 を管理者として起動します。
ModernPOS ソリューションを …\RetailSDK\POS から開きます。
POS.Extensions プロジェクトで SearchExtension という名前のフォルダーを作成します。
SearchExtension フォルダーで、ViewExtensions という名前のフォルダーを作成します。
ViewExtensions フォルダーで、Search という名前のフォルダーを作成します。
検索フォルダーに、CustomCustomerSearchColumns.tsという名前の TypeScript ファイルを作成します。
CustomCustomerSearchColumns.ts ファイルで、次の import ステートメントを追加して関連するエンティティおよびコンテキストをインポートします。
import { ICustomerSearchColumn } from "PosApi/Extend/Views/SearchView"; import { ICustomColumnsContext } from "PosApi/Extend/Views/CustomListColumns"; import { ProxyEntities } from "PosApi/Entities";ファイルに既存の列とカスタム列を追加します。
export default (context: ICustomColumnsContext): ICustomerSearchColumn[] => { return [ { title: context.resources.getString("string_2"), computeValue: (row: ProxyEntities.GlobalCustomer): string => { return row.AccountNumber; }, ratio: 15, collapseOrder: 5, minWidth: 120 }, { title: context.resources.getString("string_3"), computeValue: (row: ProxyEntities.GlobalCustomer): string => { return row.FullName; }, ratio: 20, collapseOrder: 4, minWidth: 200 }, { title: context.resources.getString("string_4"), computeValue: (row: ProxyEntities.GlobalCustomer): string => { return row.FullAddress; }, ratio: 25, collapseOrder: 1, minWidth: 200 }, { title: context.resources.getString("string_5"), computeValue: (row: ProxyEntities.GlobalCustomer): string => { return row.Email; }, ratio: 20, collapseOrder: 2, minWidth: 200 }, { title: context.resources.getString("string_7"), computeValue: (row: ProxyEntities.GlobalCustomer): string => { return row.Phone; }, ratio: 20, collapseOrder: 3, minWidth: 120 } ]; };列名のローカライズ用のリソース ファイルを追加します。 SearchExtension フォルダーに、Resources という名前のフォルダーを作成します。
Resources フォルダーに、Strings という名前のフォルダーを作成します。
Strings フォルダーに、en-USという名前のフォルダーを作成します。
en-US フォルダーに resources.resjson という名前のファイルを作成します。
resources.resjson ファイルに次のコードを追加します。
{ //======================== Sample View extensions strings. ======================== "string_0" : "Quick compare products", "_string_0.comment" : "Product search page app bar command label.", "string_1" : "View customer summary", "_string_1.comment" : "Customer search page app bar command label.", //======================== Column names. ======================== "string_2" : "ACCOUNT NUMBER_CUSTOMIZED", "_string_2.comment" : "Customer search column name.", "string_3" : "NAME", "_string_3.comment" : "Customer search column name.", "string_4" : "ADDRESS", "_string_4.comment" : "Customer search column name.", "string_5" : "CONTACT EMAIL", "_string_5.comment" : "Customer search column name.", "string_7" : "PHONE NUMBER", "_string_7.comment" : "Customer search column name." }SearchExtension フォルダーにDialogSample という名前のフォルダーを作成します。
DialogSample フォルダーに、MessageDialog.tsという名前の TypeScript ファイルを作成します。
MessageDialog.ts ファイルで、次の import ステートメントを追加して関連するエンティティおよびコンテキストをインポートします。
import { ShowMessageDialogClientRequest, ShowMessageDialogClientResponse, IMessageDialogOptions } from "PosApi/Consume/Dialogs"; import { IExtensionContext } from "PosApi/Framework/ExtensionContext"; import { ClientEntities } from "PosApi/Entities";MessageDialog という名前のクラスを作成します。
export default class MessageDialog {}MessageDialog クラスで、次の show メソッドを追加します。
public static show(context: IExtensionContext, message: string): Promise<void> { let promise: Promise<void> = new Promise<void>((resolve: () => void, reject: (reason?: any) => void) => { let messageDialogOptions: IMessageDialogOptions = { title: "Extension Message Dialog", message: message, showCloseX: true, // this property will return "Close" as result when "X" is clicked to close dialog. button1: { id: "Button1Close", label: "OK", result: "OKResult" }, button2: { id: "Button2Cancel", label: "Cancel", result: "CancelResult" } }; let dialogRequest: ShowMessageDialogClientRequest<ShowMessageDialogClientResponse> = new ShowMessageDialogClientRequest<ShowMessageDialogClientResponse>(messageDialogOptions); context.runtime.executeAsync(dialogRequest).then(( result: ClientEntities.ICancelableDataResult<ShowMessageDialogClientResponse>) => { if (!result.canceled) { context.logger.logInformational("MessageDialog result: " + result.data.result.dialogResult); resolve(); } }).catch((reason: any) => { context.logger.logError(JSON.stringify(reason)); reject(reason); }); }); return promise; }検索ビューにカスタム アプリ バー ボタンを追加して、選択した顧客に関する詳細を含むダイアログ ボックスを開きます。 ViewExtensions フォルダーに、ViewCustomerSummaryCommand.tsという名前の TypeScript ファイルを作成します。
ViewCustomerSummaryCommand.ts ファイルで、次の import ステートメントを追加して関連するエンティティおよびコンテキストをインポートします。
import { ProxyEntities } from "PosApi/Entities"; import { ArrayExtensions, ObjectExtensions } from "PosApi/TypeExtensions"; import { IExtensionCommandContext } from "PosApi/Extend/Views/AppBarCommands"; import * as SearchView from "PosApi/Extend/Views/SearchView"; import MessageDialog from "../../Controls/DialogSample/MessageDialog";ViewCustomerSummaryCommand という名前のクラスを作成し、CustomerSearchExtensionCommandBase から拡張します。
export default class ViewCustomerSummaryCommand extends SearchView.CustomerSearchExtensionCommandBase {}ViewCustomerSummaryCommand クラスで、選択した顧客を検索するときに、結果をキャプチャするプライベート変数を宣言します。
private _customerSearchResults: ProxyEntities.GlobalCustomer[];クラス コンストラクター メソッドを追加して、検索ハンドラーを初期化してクリアします。
constructor(context: IExtensionCommandContext<SearchView.ICustomerSearchToExtensionCommandMessageTypeMap>) { super(context); this.id = "viewCustomerSummaryCommand"; this.label = context.resources.getString("string_1"); this.extraClass = "iconLightningBolt"; this._customerSearchResults = []; this.searchResultsSelectedHandler = (data: SearchView.CustomerSearchSearchResultSelectedData): void => { this._customerSearchResults = data.customers; this.canExecute = true; }; this.searchResultSelectionClearedHandler = (): void => { this._customerSearchResults = []; this.canExecute = false; }; }init メソッドを追加して、表示プロパティを初期化します。
protected init(state: SearchView.ICustomerSearchExtensionCommandState): void { this.isVisible = true; }アプリ ボタン クリック ハンドラーを処理する実行メソッドを追加します。 execute メソッドは、ハンドラーから選択した顧客のデータを読み取り、単純なダイアログ ボックスに表示します。
protected execute(): void { let customer: ProxyEntities.GlobalCustomer = ArrayExtensions.firstOrUndefined(this._customerSearchResults); if (!ObjectExtensions.isNullOrUndefined(customer)) { let message: string = "Customer Account: " + (customer.AccountNumber || "") + " | "; message += "Name: " + customer.FullName + " | "; message += "Phone Number: " + customer.Phone + " | "; message += "Email Address: " + customer.Email; MessageDialog.show(this.context, message); } }コード サンプルの全体は次のようになります。
import { ProxyEntities } from "PosApi/Entities"; import { ArrayExtensions, ObjectExtensions } from "PosApi/TypeExtensions"; import { IExtensionCommandContext } from "PosApi/Extend/Views/AppBarCommands"; import * as SearchView from "PosApi/Extend/Views/SearchView"; import MessageDialog from "../../DialogSample/MessageDialog"; export default class ViewCustomerSummaryCommand extends SearchView.CustomerSearchExtensionCommandBase { private _customerSearchResults: ProxyEntities.GlobalCustomer[]; /** * Creates a new instance of the ViewCustomerSummaryCommand class. * @param {IExtensionCommandContext<CustomerDetailsView.ICustomerSearchToExtensionCommandMessageTypeMap>} context The command context. * @remarks The command context contains APIs through which a command can communicate with POS. */ constructor(context: IExtensionCommandContext<SearchView.ICustomerSearchToExtensionCommandMessageTypeMap>) { super(context); this.id = "viewCustomerSummaryCommand"; this.label = context.resources.getString("string_1"); this.extraClass = "iconLightningBolt"; this._customerSearchResults = []; this.searchResultsSelectedHandler = (data: SearchView.CustomerSearchSearchResultSelectedData): void => { this._customerSearchResults = data.customers; this.canExecute = true; }; this.searchResultSelectionClearedHandler = (): void => { this._customerSearchResults = []; this.canExecute = false; }; } /** * Initializes the command. * @param {CustomerDetailsView.ICustomerDetailsExtensionCommandState} state The state used to initialize the command. */ protected init(state: SearchView.ICustomerSearchExtensionCommandState): void { this.isVisible = true; } /** * Executes the command. */ protected execute(): void { let customer: ProxyEntities.GlobalCustomer = ArrayExtensions.firstOrUndefined(this._customerSearchResults); if (!ObjectExtensions.isNullOrUndefined(customer)) { let message: string = "Customer Account: " + (customer.AccountNumber || "") + " | "; message += "Name: " + customer.FullName + " | "; message += "Phone Number: " + customer.Phone + " | "; message += "Email Address: " + customer.Email; MessageDialog.show(this.context, message); } } }SearchExtension フォルダーに、manifest.jsonという名前の JSON ファイルを作成します。
manifest.json ファイルに次のコードを追加します。
{ "$schema": "../manifestSchema.json", "name": "Pos_Extensibility_Samples", "publisher": "Microsoft", "version": "7.2.0", "minimumPosVersion": "7.2.0.0", "components": { "resources": { "supportedUICultures": [ "en-US" ], "fallbackUICulture": "en-US", "culturesDirectoryPath": "Resources/Strings ", "stringResourcesFileName": "resources.resjson", "cultureInfoOverridesFilePath": "Resources/cultureInfoOverrides.json" }, "extend": { "views": { "SearchView": { "customerAppBarCommands": [ { "modulePath": "ViewExtensions/Search/ViewCustomerSummaryCommand" } ], "customerListConfiguration": { "modulePath": "ViewExtensions/Search/CustomCustomerSearchColumns" } } } } } }POS.Extensions プロジェクトで extensions.json ファイルを開き、SearchExtension サンプルで更新して、POS が実行時にこの拡張機能に含まれるようにします。
{ "extensionPackages": [ { "baseUrl": "SampleExtensions2" }, { "baseUrl": "SearchExtension" } ] }tsconfig.json ファイルで、除外リストに拡張パッケージ フォルダーをコメントアウトします。 POS は、このファイルを使用して、拡張機能を追加または除外します。 既定では、リストに除外された拡張リスト全体が含まれています。 POS の一部として拡張機能を含めるには、拡張機能フォルダーの名前を追加し、次の例に示すように、除外リストで拡張機能をコメント アウトします。
"exclude": [ "SampleExtensions" //"SampleExtensions2", //"SearchExtension" ],プロジェクトをコンパイル、およびリビルドします。
カスタマイズの検証
カスタマイズを検証するには、次の手順に従います。
- オペレーター ID として 000160、パスワードとして 123 を使用し、Store Commerce アプリにサインインします。
- 上部の検索バーを使って顧客 2001 を検索します。 追加したカスタム列が表示されました。
- 顧客を選択し、新しいアプリケーション バーのボタンを選択します。 選択した顧客に関する詳細を含むダイアログ ボックスが表示されます。