Kiana と Maria は、フィールド技術者である Caleb に在庫管理アプリを紹介します。 Caleb はそのアプリを気に入っていますが、より使いやすくするために、別のユーザー インターフェイス機能をいくつか追加することを提案します。 具体的に、Caleb は次のことができるようにしたいと考えます:
ボイラーまたは空調ユニットで行われた作業の写真を追加し、それを予定の編集画面で詳細予定に追加します。 この画像は、実行された修理の証拠書類として役立つ可能性があります。 予定の編集画面では現在、ユーザーが予定に画像を追加できますが、この機能がまだ完全に実装されていないため、画像は保存されません。 Kiana と Preeti が画像データを保存するのに最適な場所を決定する必要があるためです。 Caleb は、この機能をできるだけ早く追加したいと考えています。
顧客の完全な予約履歴を表示して、要求された修理を追跡し、技術者を繰り返し呼び出しかねない進行中の問題を監視します。
部品詳細画面から部品を注文します。
さらに、部品詳細画面の画像コントロールには、指定した URL に保存されている画像が表示されます。 現在、データの URL は単なるプレースホルダーです。 予約画面の写真と同様に、Kiana と Preeti は、アプリで利用できるよう画像を保存するのに最適な場所を決定する必要があります。
予定に写真を追加する
写真は、アプリによってアクセスできる場所に保存する必要があります。 パフォーマンスとセキュリティ上の理由から、Preeti は写真を OneDrive または Azure SQL Database 内に保存することを望みません。 代わりに、Azure Blob Storage を使用することにします。 Blob Storage は、大規模なバイナリ オブジェクトを保持するために最適化されており、組み込まれたセキュリティにより堅牢です。 Power Apps には Blob Storage へのアクセスを許可するコネクタがあります。 Maria は、新しい写真撮影画面を追加して、Caleb のユーザー エクスペリエンスを向上させることを提案します。
詳細情報: Azure Blob Storage
Preeti は、次の手順に従って、Azure portal から Blob Storage アカウントを作成します:
Azure ポータルの、ホーム ページで、+ リソースの作成を選択します。 MarketPlace を検索ボックスにストレージ アカウントと入力し、Enter キーを選択します。
ストレージ アカウント ページで、作成を選択します。
ストレージ アカウントの作成ページで、次の詳細を入力してから、レビューと作成を選択します。
- サブスクリプション: ご使用のサブスクリプションを選択してください
- リソース グループ: webapi_rg
- ストレージ アカウント名: グローバルに一意の名前を指定し、後で使用できるようにメモします
- 場所: 最も近い場所を選択してください
- パフォーマンス: 標準
- アカウントの種類: BlobStorage
- レプリケーション: RA-GRS
検証ページで作成を選択し、ストレージ アカウントがプロビジョニングされるまで待ちます。
新しいストレージ アカウントのページに移動します。
概要ページで、コンテナーを選択します。
コンテナー ページで、+ コンテナーを選択します。 写真という名前の付いた新しいコンテナーを作成してから、作成を選択します。 パブリック アクセス レベルを BLOB に変更します。
ストレージ アカウントの概要ページに戻り、設定の下で、アクセス キーを選択します。 アクセス キー ページで、キーの表示 を選択します。key1 のキーの値をメモします。
Preeti は、ストレージ アカウント名とキーを Kiana に提供します。Kiana はこの情報を使用し、次の手順に従ってアプリのカスタム コネクタを作成します:
Power Apps にサインインします。
左ウィンドウで、データを展開し、接続を選択します。 アプリで使用されている既存の接続を一覧表示する必要があります。 + 新しい接続を選択します。
新しい接続ページで、下にスクロールして、接続を選択し、Azure Blob Storage を選択してから、作成を選択します。
Azure Blob Storage ダイアログで、Preeti が提供したストレージ アカウント名とアクセス キーを入力してから、作成を選択します。
新しい接続が作成されるまで待機します。 接続の一覧に表示されます。
Maria は、アプリの Blob Storage へのこの接続を使用して、写真画像を保存および取得できます。 Maria が最初に実行するタスクは、次の手順に従ってアプリに接続を追加することです。
編集する VanArsdelApp アプリを Power Apps Studio で開きます。
データ ウィンドウで、データの追加を選択し、Azure Blob Storage コネクタを検索してから、コネクタを選択します。
Azure Blob Storage ダイアログで、アプリに追加する Azure Blob Storage コネクタを選択します。
Maria が実行する次のタスクは、技術者またはエンジニアが写真を保存できるよう画面を追加することです。 Maria は、画像コントロールを備えた新しい画面を追加することにしました。 アプリをモバイル デバイスで実行すると、このコントロールをカメラと統合して、技術者が写真を撮ることができます。 他のデバイスでは、このコントロールはユーザーに代わりに画像ファイルをアップロードするように促します。 Maria は次の手順に従って、EditAppointment 画面からこの新しい画面へのリンクを追加します。
挿入メニューで、新規画面を選択してから、スクロール可能なテンプレートを選択します。
ツリー ビュー ウィンドウで、新しい画面を選択し、名前を TakePhoto に変更します。
この画面の LblAppNameX コントロールの テキスト プロパティを 写真を撮る に変更します。
画面からの CanvasX コントロールを削除します。
挿入メニューの、メディア ドロップダウン一覧から、画像の追加を選択して新しい画像コントロールを作成します。
注意
画像コントロールは、実際にはユーザーが画面に画像を追加して結果を表示できるようにする複合カスタムコンポーネントです。
画面の本体を占めるように、画像コントロールのサイズと位置を変更します。
ツリー ビュー ウィンドウで、AppointmentDetails 画面の IconBackarrowX コントロールを選択してから、コピー を選択します。
ツリー ビュー メニューで TakePhoto 画面を右クリックしてから、貼り付けを選択します。 IconBackArrowX コントロールが画面に追加されます。
IconBackArrowX コントロールをヘッダーバーの左上に移動します。
ツリー ビュー ウィンドウで、TakePhoto 画面のIconBackArrowX コントロールを選択します。 右側ウィンドウの詳細タブで、OnSelect アクション プロパティを Navigate(EditAppointment, ScreenTransition.None) に変更します。
新しい保存アイコン コントロールをヘッダー バーの右上に追加します。 15.このコントロールの Visible プロパティを f(IsBlank(AddMediaButton1.Media), false, true) に設定します。
この設定により、ユーザーが画像を選択していない場合、保存アイコンは非表示になります。
保存アイコン コントロールの OnSelect アクション プロパティで式を次のように変更します。
Set(ImageID, GUID() & ".jpg"); AzureBlobStorage.CreateFile("photos", ImageID, AddMediaButton1.Media); Patch(appointmentsCollection, LookUp(appointmentsCollection,id=BrowseAppointmentsGallery.Selected.id), {imageUrl:"https://myappphotos.blob.core.windows.net/photos/" & ImageID}); Navigate(EditAppointment,ScreenTransition.Cover);
Preeti が作成した Azure Storage アカウントの名前と <storage account name> を置き換えます。
このコードは画像を Blob Storage の写真コンテナーにアップロードします。 各画像には一意のファイル名が付けられます。 Patch 関数は、Blob Storage 内の画像の URL を使用して、予定レコードの imageUrl プロパティを更新します。
ツリー ビュー ウィンドウで、AddMediaWithImageX コントロールを展開します。 UploadedImageX コントロールの 画像 プロパティを変更し、AppointmentImage に設定します。
AppointmentImage は、ユーザーがアップロードした画像、または写真を撮った結果として画像が入力される変数です。 この変数は、後で EditAppointment 画面で初期化されます。
ツリー ビュー ウィンドウで、AddMediaButtonX コントロールを選択します。 このコントロールの UseMobileCamera プロパティを true に設定します。 コントロールの OnChange アクション プロパティを次に設定します。
Set(AppointmentImage, AddMediaButton1.Media)
この式は AppointmentImage 変数を変更して新しい画像を参照します。 UploadedImageX コントロールはこの画像を表示します。
ツリー ビュー ウィンドウで、EditAppointment 画面を選択します。
EditFormX コントロールを展開します。 Image_DataCardX コントロールで、AddPictureX コントロールを削除します。
ImageX コントロールを選択します。 次のようにプロパティを変更します:
- 画像: Parent.Default
- X: 30
- Y: DataCardKeyX.Y + DataCardKeyX.Height + 150 (DataCardKeyX は ImageX コントロールを含むデータ カードです)
- 幅: Parent.Width - 60
- Height: 400
注意
画像コントロールは画面の下部にドロップダウンしますが、画像を表示できるようにスクロール バーが自動的に追加されます。
カメラ アイコンをデータ カードに追加し、画像ラベルと ImageX コントロールの間に配置します。 コントロールの名前を CameraIcon に変更します。
注意
カメラ メディア コントロールではなく、カメラ アイコン コントロールを選択していることを確認してください。
CameraIcon コントロールの OnSelect アクション プロパティを次に設定します。
Set(AppointmentImage, SampleImage); Navigate(TakePhoto, ScreenTransition.None);
ユーザーがこのアイコンを選択すると、写真を撮ったり画像をアップロードしたりできる TakePhoto 画面に移動します。 表示される最初の画像は、既定のサンプル画像になります。
アプリをテストするには、次の手順を実行します:
ツリー ビュー ウィンドウで、ホーム画面を選択します。
F5 を選択してアプリをプレビューします。
ホーム画面で、予定を選択します。
参照画面で、任意の予定を選択します。
予定の詳細画面で、画面ヘッダーの編集アイコンを選択します。
編集画面で、画像のカメラ アイコンを選択します。
写真を撮る画面が表示されることを確認してください。
画像の変更および選択した画像のアップロード (または、モバイル デバイスでアプリを実行している場合は、写真を撮る) を選択します。
保存を選択します。 詳細ページに画像が表示されていることを確認し、チェック アイコンを選択して変更をデータベースに保存します。
プレビュー ウィンドウを閉じて、Power Apps Studio に戻ります。
部品の画像を表示する
Preeti と Kiana は、Blob Storage が予定に関連する写真を保存するのに理想的な場所であると判断し、部品の画像を保存するために同じアプローチを使用する必要があると判断します。 このアプローチの主な利点は、アプリに変更を加える必要がないことです。 アプリは同じストレージ アカウントおよび同じ接続を再利用します。 個別の移行演習として、次の手順を実行できます:
新しい Blob Storage コンテナーを作成します。
部品画像をこのコンテナーにアップロードします。
InventoryDB データベースの部品テーブルの ImageUrl 参照を、各画像の URL に変更します。
アプリは各部品画像の新しい URL を自動的に取得し、PartDetails 画面の画像コントロールに画像が表示されます。
顧客の予約履歴を追跡する
Maria は、カスタム コンポーネントを作成することで、顧客の以前の技術者の訪問からのすべての履歴をすばやく表示できるようアプリに追加できると考えます。 Maria は、Caleb と協力し、表示する情報について、メモと各訪問の日付で構成されるシンプルなデザイン構想を練ります。
データを見ると、Maria は、ギャラリー コントロールがテーブル データを画面に表示するための最良の方法であると考えます。
Maria は次の手順でカスタム コンポーネントを作成します:
Power Apps Studio を使用して、ツリー ビュー ウィンドウで、コンポーネントを選択してから、+ 新しいコンポーネントを選択します。
Component1 という名前の付いた新しい空白のコンポーネントが作成されます。 コンポーネントの名前を DateHistoryComponent と変更します。
挿入メニューで、ギャラリーを選択してから、高さ (伸縮可能、空) ギャラリー テンプレートを選択します。
ギャラリー コントロールを移動し、カスタム コンポーネントを埋めるようにサイズを変更します。
挿入ウィンドウで項目を追加するを選択してから、テキスト ラベルを選択します。
ツリー ビュー ウィンドウで、ラベル コントロールの名前を NotesLabel に変更します。 オーバーフロー プロパティを Overflow.Scroll に設定します。 この設定により、コントロールはテキストの複数行を表示し、ユーザーがそれをスクロールできるようになります。 コントロールの位置とサイズを設定できるように、次のプロパティを設定します:
- LineHeight: 2
- X: 28
- Y: 18
- Width: 574
- Height: 140
2 番目のテキスト ラベルをコントロールに追加します。 このコントロールの名前を DateLabel に変更し、次のプロパティを設定します:
- LineHeight: 2
- X: 28
- Y: 174
- Width: 574
- Height: 70
コントロールがアプリに挿入され、テーマとともに表示されたときの外観を確認するには、ツリー ビュー ウィンドウで、DateHistoryComponent を選択します。 右側ウィンドウの、詳細タブで、塗りつぶしフィールドを選択して、色を RGBA(0, 0, 0, 1) に変更します。
挿入ウィンドウで、形を展開し、四角形コントロールをカスタム コンポーネントにを追加します。 このコントロールに、次のプロパティを設定します:
- X: 0
- Y: 273
- 幅: Parent.Width
- Height: 2
このコントロールは、ギャラリーに表示されるレコード間の区切り文字として機能します。
Maria は、画面にコントロールを追加し、Power Apps を使用してアプリを構築することに精通しています。 ただし、再利用可能なコンポーネントはまったく同じようには機能しません。 Kiana は、カスタム コンポーネントでデータを使用できるようにするには、いくつかのカスタム入力プロパティを追加する必要があることを Maria に説明しました。 Kiana はまた、コンポーネント内のコントロールのデータ フィールドを参照できるように、Maria がこれらのプロパティのサンプル データを次のように提供する必要があることを説明しました。
ツリー ビュー ウィンドウで、DateHistoryComponent を選択します。 右側のウィンドウのプロパティ タブで、新しいカスタム プロパティを選択します。
新しいカスタム プロパティ ダイアログで、次の値を指定してから、作成を選択します:
- 表示名: データ
- 名前: データ
- 説明: メモと日付を表示する、顧客の予定の表
- プロパティの種類: 入力
- データの種類: 表
- 値が変更されたときに OnReset を上げる: 空白のまま
コントロールによって表示されるサンプル データを変更するには、新しいデータ カスタム プロパティを選択します。 数式フィールドに、Table({Notes: "Example notes field text.", 'Appointment Date': Text(Today())}) と入力します。
ツリー ビュー ウィンドウで、DateHistoryComponent の GalleryX コントロールを選択し、名前を AppointmentHistory に変更します。
右側のウィンドウの、詳細タブで、AppointmentHistory ギャラリー コントロールの項目プロパティを Parents.Data に設定します。
NotesLabel コントロールを選択します。 右側ウィンドウの詳細タブで、テキスト プロパティを ThisItem.Notes, に変更し、サイズ プロパティを 20 に変更します。
注意
サイズ プロパティは、コントロールによって表示されるテキストのフォント サイズを指定します。
DateLabel コントロールを選択して、Text プロパティを ThisItem.'Appointment Date' に変更し、Size プロパティを 20 に変更します。 カスタム コンポーネントのフィールドには、サンプル データが表示されます。
カスタム コンポーネントが完了しました。 Maria は、次のように、このコンポーネントを使用して顧客の予定履歴を表示する新しい画面を作成します。
ツリー ビュー ウィンドウで、画面タブを選択します。
BrowseAppointments 画面を展開し、BrowseAppointmentsGallery コントロールを展開してから、Body1_1 コントロールを選択します。 挿入メニューで、アイコンを選択してから、詳細一覧アイコンを選択します。
アイコン コントロールの名前を ViewAppointments に変更します。
ツリー ビュー メニューで、BrowseAppointmentsGallery コントロールを選択します。 右側のウィンドウの、詳細タブで、TemplateSize プロパティを 220 に変更します。 このプロパティを増やすと、ギャラリーで使用可能なスペースが拡張されます。
ViewAppointments アイコンを顧客名の下の空白スペースに移動します。
ViewAppointments アイコン コントロールを選択します。 OnSelect アクション プロパティを次の式に設定します。
ClearCollect(customerAppointmentsCollection, FieldEngineerAPI.getapicustomeridappointments(ThisItem.customerId)); Navigate(AppointmentsHistoryScreen, ScreenTransition.Fade)
この式は、選択した顧客の予定を含む customerAppointmentsCollection という名前のコレクションにデータを入力してから、AppointmentHistoryScreen に移動してそれらを表示します。 次の手順でこの画面を作成します。
挿入メニューで、新規画面を選択してから、スクロール可能なテンプレートを選択します。
AppointmentHistoryScreen への新しい画面の名前を変更します。
この画面に追加された CanvasX コントロールを削除します。
この画面の LblAppNameX コントロールを選択します。 右側のウィンドウの、詳細タブで、テキスト プロパティを次のように変更します。
"Appointments History for " & BrowseAppointmentsGallery.Selected.customer.name
LblAppNameX コントロールの次のプロパティを設定して、位置とサイズを調整します:
- X: 90
- Y: 0
- Width: 550
- Height: 140
RectQuickActionBarX コントロールを選択し、Height プロパティを 140 に設定します。
左アイコン コントロールを、タイトルの左側にある画面ヘッダーに追加します。 このコントロールの OnSelect アクション プロパティを Navigate(BrowseAppointments, Transition.None) に設定します。
挿入メニューで、カスタムを選択してから、DateHistoryComponent を選択します。
コンポーネントを移動してサイズを変更し、画面の本体、見出しの下を占めるようにします。
このコンポーネントに、次のプロパティを設定します:
- データ: customerAppointmentsCollection
- 予約日: startDateTime
- メモ: メモ
アプリを保存します。
アプリをテストするには、次の手順を実行します:
ツリー ビュー ウィンドウで、ホーム画面を選択します。
F5 を選択してアプリをプレビューします。
ホーム画面で、予定を選択します。
参照画面で、任意の予定の詳細一覧アイコンを選択します。
選択した顧客の予定履歴画面が表示されるのを確認します。
プレビュー ウィンドウを閉じて、Power Apps Studio に戻ります。
部品を注文する
システムの主な要件は、技術者が顧客を訪問している間に必要な部品を注文できるようにすることです。 部品の在庫がある場合は、お客様にとって次の都合の良い日に修理を完了するために、別の訪問をスケジュールすることが可能になります。 現在部品が在庫切れで注文する必要がある場合、技術者は顧客にその点を伝えることができます。 Malik は、部品が倉庫に到着したという通知を Maria が受け取ったら、顧客との予定を手配できます。
アプリの予約部分は、次の図に示すように、InventoryDB データベースのテーブルを使用します。 注文テーブルには、部品の注文に関する情報が含まれています。 予約テーブルでは、技術者およびエンジニアが部品に対して行った予約要求を一覧表示します。 エンジニア テーブルには、予約を取ったエンジニアの名前と連絡先番号が記載されています。これにより、在庫管理者の Maria が必要に応じて容易に問い合わせができます。
この機能をサポートするには、Kiana は次のように、指定された部品の予約済み品目の数をフェッチするメソッドで Web API を更新する必要があります。
Visual Studio Code の FieldEngineerApi Web API プロジェクトを開きます。
Order.cs という名前の付いたファイルをモデル フォルダーに追加します。 次のコードをこのファイルに追加します。 注文クラスは、部品の注文の詳細を追跡します。
using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace FieldEngineerApi.Models { public class Order { [Key] public long Id { get; set; } public long BoilerPartId { get; set; } public BoilerPart BoilerPart { get; set; } public long Quantity { get; set; } [Column(TypeName = "money")] public decimal TotalPrice { get; set; } [Display(Name = "OrderedDate")] [DataType(DataType.DateTime)] [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] public DateTime OrderedDateTime { get; set; } public bool Delivered { get; set; } [Display(Name = "DeliveredDate")] [DataType(DataType.DateTime)] [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] public DateTime? DeliveredDateTime { get; set; } } }
Reservation.cs という名前の付いた別の新しいファイルをモデル フォルダーに追加し、このファイルに次のコードを追加します。 予約クラスには、現在他の顧客のために予約されている特定の部品の品目数に関する情報が含まれます。
using System; using System.ComponentModel.DataAnnotations; namespace FieldEngineerApi.Models { public class Reservation { [Key] public long Id { get; set; } public long BoilerPartId { get; set; } public BoilerPart BoilerPart { get; set; } public int NumberToReserve { get; set; } public string EngineerId { get; set; } public InventoryEngineer Engineer { get; set; } } }
次のコードを使用して、InventoryEngineer.cs, という名前のファイルをモデル フォルダーにもう 1 つ追加します。 InventoryEngineer クラスでは、どのエンジニアがどの予約を行ったかを記録します。
using System.ComponentModel.DataAnnotations; using System.Collections.Generic; namespace FieldEngineerApi.Models { public class InventoryEngineer { [Key] public string Id { get; set; } [Required] public string Name { get; set; } public string ContactNumber { get; set; } public List<Reservation> Reservations { get; set; } } }
モデル フォルダーの InventoryContext.cs ファイルを開き、次のステートメントを InventoryContext クラスに追加します。
public class InventoryContext : DbContext { public InventoryContext(DbContextOptions\<InventoryContext\> options) : base(options) { } public DbSet<BoilerPart> BoilerParts { get; set; } public DbSet<InventoryEngineer> Engineers { get; set; } public DbSet<Order> Orders { get; set; } public DbSet<Reservation> Reservations { get; set; } }
Visual Studio Code のターミナル ウィンドウで、次のコマンドを実行して、注文と予約を処理するためのコントローラーを構築します。
dotnet aspnet-codegenerator controller ^ -name OrdersController -async -api ^ -m Order ^ -dc InventoryContext -outDir Controllers dotnet aspnet-codegenerator controller ^ -name ReservationsController -async -api ^ -m Reservation ^ -dc InventoryContext -outDir Controllers
コントローラー フォルダーの BoilerPartController.cs ファイルを開き、次の GetTotalReservations メソッドを BoilerPartsController クラスに追加します。
public class BoilerPartsController : ControllerBase { private readonly InventoryContext _context; public BoilerPartsController(InventoryContext context) { _context = context; } ... // GET: api/BoilerParts/5/Reserved [HttpGet("{id}/Reserved")] public async Task<ActionResult<object>> GetTotalReservations(long id) { var reservations = await _context .Reservations .Where(r => r.BoilerPartId == id) .ToListAsync(); int totalReservations = 0; foreach(Reservation reservation in reservations) { totalReservations += reservation.NumberToReserve; } return new {id, totalReservations}; } ... }
OrdersController.cs ファイルを編集し、次に示すように、OrdersController クラスの PostOrder メソッドを変更します。
[HttpPost] public async Task<ActionResult<Order>> PostOrder(long boilerPartId, int quantity) { var part = await _context.BoilerParts.FindAsync(boilerPartId); Order order = new Order { BoilerPartId = boilerPartId, Quantity = quantity, OrderedDateTime = DateTime.Now, TotalPrice = quantity * part.Price }; _context.Orders.Add(order); await _context.SaveChangesAsync(); return CreatedAtAction("GetOrder", new { id = order.Id }, order); }
ReservationsController.cs ファイルを編集します。 次のように、ReservationsController クラスの PostReservation メソッドを変更します。
[HttpPost] public async Task<ActionResult<Reservation>> PostReservation(long boilerPartId, string engineerId, int quantityToReserve) { Reservation reservation = new Reservation { BoilerPartId = boilerPartId, EngineerId = engineerId, NumberToReserve = quantityToReserve }; _context.Reservations.Add(reservation); await _context.SaveChangesAsync(); return CreatedAtAction("GetReservation", new { id = reservation.Id }, reservation); }
ターミナル ウィンドウで、次のコマンドを実行して、展開するための Web API を構築および公開します。
dotnet build dotnet publish -c Release -o ./publish
Visual Studio Code で公開フォルダーを右クリックし、Web アプリに展開を選択します。
Preeti は、VanArsdel アプリで使用される API 管理サービスを更新して、更新された Web API を反映できるようになりました。 これは互換性のない変更です。既存の操作は引き続き機能しますが、予約と注文を行うための新しいコントローラーと操作の違いがあります。 Preeti は次のタスクを実行します:
注意
Preeti は、既存のフィールド エンジニア API を削除して新しいバージョンに置き換えることを選択できましたが、そのアプローチでは、現在 API を使用している可能性のある既存のアプリケーションが破損するリスクがあります。 既存の API をそのまま残し、変更をリビジョンとして追加することをお勧めします。
Azure ポータルで、API 管理サービスに移動します。
API 管理サービス ページの、API 下の左側ウィンドウで、API を選択します。
フィールド エンジニア API を選択し、省略記号メニューを選択してから、リビジョンを追加を選択します。
フィールド エンジニア API の新しいリビジョンを作成するダイアログで、部品の予約と注文に対する GET 操作と POST 操作を追加済という説明を入力してから、作成を選択します。
REVISION 2 ページで、デザインを選択します。
デザイン ページで、操作の追加を選択します。 FrontEnd ページで、次のプロパティを設定してから、保存を選択します。 この操作は、特定のボイラー部品用に予約された品目の数を取得するために使用されます:
- 表示名: api/BoilerParts/{id}/Reserved
- 名前: api-boilerparts-id-reserved
- URL: GETapi/BoilerParts/{id}/Reserved
新しい操作のテスト タブで、id パラメーターを有効な部品番号 (画像の例では部品 1 を使用) に設定してから、送信を選択します。
テストが成功したことを確認します。 操作は、HTTP 200 応答と、製品の予約数を示す本文で完了する必要があります。
デザイン ページで、操作の追加を選択します。 FrontEnd ウィンドウで、次のプロパティを設定します (この操作は新しい注文を作成するための POST 要求を定義します):
- 表示名: api/Orders - POST
- 表示名: api-orders-post
- URL: POSTapi/Orders
クエリ タブで、+ パラメーターを追加を選択し、次のパラメーターを追加してから、保存を選択します:
- 名前: boilerPartId、説明**: ボイラー部品 ID**、種類: 長い
- 名前: 数量、説明**: 数量**、種類: 整数
FrontEnd ウィンドウの操作の追加を再度選択し、次のプロパティを設定します (この操作は新しい予約を作成するための POST 要求を定義します):
- 表示名: api/Reservations - POST
- 表示名: api-reservations-post
- URL: POSTapi/Reservations
クエリ タブで、次のパラメーターを追加してから、保存を選択します:
- 名前: boilerPartId、説明: ボイラー部品 ID、種類: 長い
- 名前: engineerId、説明: エンジニア ID、種類: 文字列
- 名前: quantityToReserve、説明: 予約する数量、種類: 文字列
リビジョン タブで、新しいバージョンを選択します。 このバージョンの省略記号メニューで、最新にするを選択します。
リビジョンを最新にするダイアログで、保存を選択します。
Web ブラウザーで別のページを開き、URL https://<APIM name>.azure-api.net/api/boilerparts/1/reserved に移動します。<APIM name> は API サービスの名前です。 次のような応答が返されることを確認します。
{"id":1,"totalReservations":5}
更新された Web API が利用可能になりました。 理論的には、Kiana は更新された Web API 用の新しいカスタム コネクタを作成し、それをアプリに追加できます。 次にアプリは独自のロジックを実装して、指定した製品の現在在庫数、品目の予約数、必要な品目数との結果の比較、必要に応じた追加在庫の注文、または既存の在庫からの品目の予約を決定します。 ただし、この種類のロジックは、Azure ロジック アプリでより適切に実装されます。 Power Apps は、技術者が部品の予約または注文を希望する場合、カスタム コネクタを介してロジック アプリを呼び出すことができます。
ロジック アプリを作成するため、Kiana は次の手順を使用します:
注意
簡単にするために、この例で作成されたロジック アプリは非トランザクションです。 部品の在庫状況を確認してから予約するまでの間に、同時実行ユーザーが競合する予約を行う可能性があります。 このロジック アプリのロジックの一部を InventoryDB データベースのストアド プロシージャに置き換えることで、トランザクション セマンティクスを実装できます。
Azure ポータルの、ホーム ページで、+ リソースの作成を選択します。
Marketplace を検索ボックスに、ロジック アプリと入力してから、Enter キーを選択します。
ロジック アプリ ページで、作成を選択します。
ロジック アプリの作成ページで、次の値を入力してから、レビューと作成を選択します。
- サブスクリプション: ご使用の Azure サブスクリプションを選択してください
- リソース グループ: webapi_rg
- ロジック アプリ名: FieldEngineerPartsOrdering
- 地域: Web API に使用したのと同じ場所を選択します
- 統合サービス環境の関連付け: 空白のまま
- ログ分析の有効化: 空白のまま
検証ページで、作成を選択し、ロジック アプリが展開されるまで待ちます。
展開が完了したら、リソースに移動を選択します。
Logic Apps デザイナー ページで、テンプレート セクションまで下にスクロールしてから、空のロジック アプリを選択します。
すべてタブの、コネクタとトリガーを検索するテキスト ボックスで、要求を選択します。
トリガー タブで、HTTP 要求の受信時 を選択します。
要求本文の JSON スキーマ ボックスに、次のスキーマを入力してから、+ 新しいステップを選択します。
{ "type": "object", "properties": { "boilerPartId": { "type": "integer" }, "numberToReserve": { "type": "integer" }, "engineerId": { "type": "string" } } }
このスキーマは、ロジック アプリが想定している HTTP 要求のコンテンツを定義します。 要求本文は、ボイラー部品の ID、予約する品目の数、および要求を行うエンジニアの ID で構成されます。 エンジニアが部品を予約する時に、アプリはこの要求を送信します。
操作の選択ボックスで、すべてを選択してから、HTTP を選択します。
ロジック アプリは Web API の BoilerParts{id} 操作を呼び出して、アプリからの要求によって提供されたボイラー部品に関する情報を取得します。
アクション ウィンドウで、HTTP アクションを選択します。
HTTP アクション ボックスの、省略記号メニューで、名前の変更を選択し、アクションの名前を CheckBoilerPart に変更します。
HTTP アクションのプロパティを次のように設定してから、+ 新しいステップを選択します:
- メソッド: GET
- URI: https://<APIM name>.azure-api.net/api/boilerparts/。ここで <APIM name> は API Management サービスの名前です。 この URI の 動的コンテンツ ボックスの、動的コンテンツ タブで、boilerPartId を選択します
操作の選択ボックスの、コネクタとアクションを検索するボックスで、JSON の解析を入力してから、JSON の解析アクションを選択します。
JSON の解析アクションの省略記号メニューを使用して、アクションの名前を ParseBoilerPart に変更します。
ParseBoilerPart アクションのコンテンツ ボックスの、動的コンテンツ ボックスで、本文を選択します。 スキーマ ボックスに、次の JSON スキーマを入力してから、+ 新しいステップを選択します。
{ "type": "object", "properties": { "id": { "type": "integer" }, "name": { "type": "string" }, "categoryId": { "type": "string" }, "price": { "type": "number" }, "overview": { "type": "string" }, "numberInStock": { "type": "integer" }, "imageUrl": { "type": "string" }, } }
このアクションは、getBoilerParts/{id} 要求によって返された応答メッセージを解析します。 応答には、現在の在庫数など、ボイラー部品の詳細が含まれます。
新しいステップの操作の選択ボックスで、HTTP コネクタを選択します。
アクション タブで、HTTP アクションを選択します。
操作の省略記号メニューを使用して、操作の名前を CheckReservations に変更します。
この操作のプロパティを次のように設定してから、+ 新しいステップを選択します:
- メソッド: GET
- URI: https://<APIM name>.azure-api.net/api/boilerparts/. 前と同じように、この URI の動的コンテンツ ボックスの、動的コンテンツ タブで、boilerPartId を選択します。 URI フィールドで、boilerPartId プレースホルダーの後にテキスト /reserved を追加する
新しいアクションの操作の選択ボックスの、コネクタとアクションを検索するボックスで、JSON の解析を入力してから、JSON の解析アクションを選択します。
操作の名前を ParseReservations に変更します。
コンテンツ プロパティを本文に設定します。
次のスキーマを入力してから、+ 新しいステップを選択します。
{ "type": "object", "properties": { "id": { "type": "integer" }, "totalReservations": { "type": "integer" } } }
新しいアクションの操作の選択ボックスの、コネクタとアクションを検索するボックスで、条件を入力してから、条件コントロール アクションを選択します。
操作の名前を CompareStock に変更します。
値の選択ボックスを選択します。 動的コンテンツの追加ボックスの、式タブで、次の式を入力してから、OK を選択します。
add(body('ParseReservations')?['totalReservations'], triggerBody()?['numberToReserve'])
この式は、現在予約されている指定したボイラー部品の品目の数と、エンジニアにより要求された数の合計を計算します。
条件ドロップダウン リスト ボックスで、次の値より大きいを選択します。
残りの値の選択ボックス、動的コンテンツ ボックス、動的コンテンツ タブの、ParseBoilerPart の下で numberInStock を選択します。
必要な品目の数と予約数の合計が在庫数よりも多い場合、アプリは在庫を補充するために注文する必要があります。 CompareStock アクションの True の分岐で、アクションの追加を選択します。
新しい操作のすべてタブで、HTTP を選択してから、HTTP アクションを選択します。
操作の名前を PostOrder に変更します。
PostOrder 操作に、次のプロパティを設定します:
- メソッド: POST
- URI: https://<APIM name>.azure-api.net/api/orders
- クエリ テーブルの、最初の行に、キー boilerPartId を入力します。 動的コンテンツの追加ボックスの値に関しては、動的コンテンツ タブで、**boilerPartId** を選択します
- クエリ テーブルの、2 番目の行に、キー数量を入力します。 値フィールドに、50 と入力します。
ロジック アプリは、在庫が少なくなると、指定された部品の 50 品目を自動的に注文します。
注意
ロジック アプリでは、エンジニアが 1 回の要求で指定された部品の 50 を超える品目を実際に予約しないことを想定しています。
CompareStock アクションの False の分岐を空のままにします。
CompareStock アクションの下で、+ 新しいステップを選択します。
新しい操作のすべてタブで、HTTP を選択してから、HTTP アクションを選択します。
操作の名前を PostReservation に変更します。
PostReservation 操作に、次のプロパティを設定します:
- メソッド: POST
- URI: https://<APIM name>.azure-api.net/api/reservations
- クエリ テーブルの、最初の行に、キー boilerPartId を入力します。 動的コンテンツの追加ボックスの値に関しては、動的コンテンツ タブで、boilerPartId を選択します。
- 2 行目に、キー engineerId を入力します。 動的コンテンツの追加ボックスの値に関しては、動的コンテンツ タブで、engineerId を選択します
- 3 行目に、キー quantityToReserve を入力します。 動的コンテンツの追加ボックスの値に関しては、動的コンテンツ タブで、numberToReserve を選択します
+ 新規ステップを選択します。 操作の選択ボックスで、応答アクションを検索して選択します。
応答アクションに、次のプロパティを設定します:
- 状態コード: 200
- ヘッダー: キー - content-type、値 - application/json
- 本文: 動的コンテンツ ボックスで、 PostReservation 要求からの本文要素を選択します。 これは予約時に返される本文です。
Logic Apps デザイナー ページの左上で、保存を選択します。 ロジック アプリがエラーなしで保存できることを確認します。
Power Apps がロジック アプリをトリガーするために使用できるカスタム コネクタを作成するには、Kiana は Azure ポータル内で次の手順を実行します:
ロジック アプリの概要ページで、エクスポートを選択します。
Power Apps へのエクスポート ウィンドウで、コネクタに PartsOrderingConnector という名前を付け、Power Apps 環境を選択してから、OK を選択します。
Power Apps にサインインします。
ご使用の環境の、データの下で、カスタム コネクタを選択し、PartsOrderingConnector が表示されていることを確認します。
Maria は、VanArsdel アプリを変更して、技術者が顧客サイトにアクセスしながら部品を注文できるようになりました。 Maria は次のように、注文ボタンを PartDetails 画面に追加します。
Power Apps にサインインします (まだサインインしていない場合)。
アプリの下で、VanArsdelApp アプリを選択します。 アプリの省略記号メニューで、編集を選択します。
データ ウィンドウで、データの追加を選択し、PartsOrderingConnector コネクタを検索し、そのコネクタを使用して新しい接続を追加します。
ツリー ビュー ウィンドウで、PartDetails 画面を展開してから、DetailForm1 フォームを展開します。
右側のプロパティ ウィンドウで、フィールドの編集を選択します。 フィールド ウィンドウの、省略記号メニューで、カスタム カードの追加を選択します。
ツリー ビュー ウィンドウで、新しいカードの名前を DataCard1 から ReserveCard に変更します。 デザイン ビュー ウィンドウで、カードのサイズを変更して、画面の下部、Image_DataCard1 コントロールの下を占めるようにします。
挿入メニューで、入力サブ メニューから、テキスト入力コントロール、ボタン コントロール、およびラベル コントロールを ReserveCard コントロールに追加します。
コントロールのサイズを変更して、ボタン コントロールをテキスト入力コントロールの右側に、ラベルをボタン コントロールの下に隣接するように配置します。
テキスト入力コントロールのプロパティ ウィンドウで、既定プロパティを解除します。
ボタン コントロールのプロパティ ウィンドウで、テキスト プロパティを予約に設定します。
テキスト入力コントロールの名前を NumberToReserve に変更し、ボタン コントロールの名前を予約に変更し、ラベル コントロールの名前をメッセージに変更します。
メッセージ コントロールのプロパティ ウィンドウで、テキスト プロパティを予約済部品に設定し、表示プロパティを MessageIsVisible に設定します。
注意
MessageIsVisible は画面が表示された場合に false に初期化する変数ですが、ユーザーが予約ボタン選択すると true に変更されます。
予約ボタン コントロールの OnSelect プロパティを次の式に設定します。
FieldEngineerPartsOrdering.manualinvoke({boilerPartId:ThisItem.id, engineerId:"ab9f4790-05f2-4cc3-9f01-8dfa7d848179", numberToReserve:NumberToReserve.Text}); Set(MessageIsVisible, true);
注意
この式は、ハードコーディングされたエンジニア ID を使用して、現在アプリを実行している技術者を表します。 第 8 章では、サインオンしたユーザーの ID を取得する方法について説明します。
さらに、アプリはエラー チェックを実行しません。部品を予約する要求は常に成功することを想定しています。 エラー処理の詳細については、Power Apps の機能のエラーを参照してください。
PartDetails 画面の OnVisible プロパティを Set(MessageIsVisible, false) に設定します。
アプリをテストするには、次の手順を実行します:
ツリー ビュー ウィンドウで、ホーム画面を選択します。
F5 を選択してアプリをプレビューします。
ホーム画面で、部品を選択します。
参照画面で、任意の部品を選択します。
部品詳細画面で、予約セクションまで下にスクロールし、正の整数値を入力してから、予約を選択します。 予約済部品メッセージが表示されることを確認します。
プレビュー ウィンドウを閉じて、Power Apps Studio に戻ります。
Azure ポータルで、InventoryDB SQL データベースのページに移動します。
クエリ エディターを選択し、パスワードを使用して sqladmin としてサインインします。
クエリ 1 ウィンドウで、次のクエリを入力してから、実行を選択します。 VanArsdel アプリで行った予約が表示されることを確認します。
SELECT * FROM [dbo].[Reservations]