Dela via


Kapitel 7: Lägga till funktioner i appen

Kiana och Maria är glada att kunna visa lagerhanteringsappen för fältteknikern Caleb. Caleb gillar den, men föreslår att de lägger till några extra funktioner för användargränssnittet för att göra den enklare att använda. Caleb vill kunna:

  • Lägg till ett fotografi av arbetet som har utförts på en enhet för luftkonditioneringsaggregat och lägg till det i informationen om avtalade tider på skärmen Redigera avtalad tid. Bilden kan visa sig vara användbar som ett dokument för reparation som utförs. På skärmen Redigera avtalad tid kan användaren för tillfället lägga till en bild i den avtalade tiden, men bilden sparas inte eftersom den här funktionen inte har implementerats helt ännu. Orsaken till problemet är att Kiana och Preeti måste avgöra var bilddata ska lagras på bästa sätt. Caleb vill att den här funktionen ska läggas till så fort som möjligt.

  • Visa en fullständig historik över avtalade tider för en kund om du vill spåra reparationer som har begärts och övervaka pågående problem som kan kräva att tekniker upprepade gånger kallas ut.

  • Beställa delar från skärmen delinformation.

Dessutom visas bilder som lagras på en angiven URL i Bild-kontrollen på skärmen delinformation. URL:erna i dessa data är för närvarande endast platshållare. Precis som för skärmarna för den avtalade tiden måste Kiana och Preeti avgöra var de kan lagra bilder så att de är tillgängliga för appen.

Lägga till fotografi för en avtalad tid

Fotografier måste lagras någonstans tillgängliga för appen. Av prestanda- och säkerhetsskäl vill Preeti inte spara fotografier filer i OneDrive eller i Azure SQL Database. Istället väljer de att använda Azure Blob Storage. Blob Storage är optimerat för att lagra stora binärobjekt och är robust med inbyggd säkerhet. Power Apps har en anslutning som ger åtkomst till Blob Storage. Maria föreslår att du lägger till en ny skärmbild som förbättrar användarupplevelsen för Caleb.

Mer information: Azure Blob Storage

Preeti skapar Blob Storage-konto från Azure-portalen genom att följa stegen nedan:

  1. I Azure-portalen, på sidan Start, välj + Skapa en resurs. I rutan Sök på Marketplace anger du Lagerkonto och väljer sedan Retur.

    Azure Marketplace-sökning.

  2. Välj Skapa på sidan Lagringskonto.

  3. På sidan Skapa lagringskonto ange följande information och välj sedan Granska + skapa:

    • Prenumeration: Välj din prenumeration
    • Resursgrupp: webapi_rg
    • Lagringskontonamn: Ange ett globalt unikt namn och notera det för senare
    • Plats: Välj närmaste plats
    • Prestanda: Standard
    • Kontosort: BlobStorage
    • Replikering: RA-GRS

    Skapa Azure Storage-kontot.

  4. På valideringssidan, välj Skapa och vänta tills lagringskontot har etablerats.

  5. Gå till sidan för det nya lagringskontot.

  6. På sidan Översikt, välj Behållare.

    Översiktssida för lagringskonto.

  7. På sidan Behållare, välj + Behållare. Skapa en ny behållare med namnet bilder och välj sedan Skapa. Ändra offentlig åtkomstnivå till Blob.

    Skapa behållaren Foton.

  8. Tillbaka på sidan Översikt för lagringskontot väljer du Åtkomstnycklar under inställningar. På sidan Åtkomstnycklar väljer du Visa nycklar. Notera värdet för nyckeln för key1.

    Lagringskontoåtkomstnycklar.

Preeti ger lagringskontonamnet och nyckeln till Kiana, som använder denna information för att skapa en anpassad kontakt för appen genom att följa dessa steg:

  1. Logga in på Power Apps.

  2. I den vänstra navigeringrutan expanderar du Data och väljer Anpassningar. De befintliga anslutningarna som appen använder bör finnas med i listan. Välj + Ny anslutning.

    Sidan Power Apps anslutningar.

  3. På sidan Ny anslutning, bläddra ned, välj Anslutningar, välj Azure Blob Storage och välj sedan Skapa.

    Välj Azure Blob Storage-anslutning.

  4. I dialogrutan Azure Blob Storage ange namnet på lagringskontot och den åtkomstnyckel som Preeti gav och välj Skapa.

    Ange lagringsinformation.

  5. Vänta medan den nya anslutningen skapas. Den ska visas i listan med anslutningar.

Maria kan använda den här anslutningen till Blob Storage i appen för att spara och hämta bilder. Marias första uppgift är att lägga till anslutningen till programmet genom att följa stegen nedan:

  1. Öppna appen VanArsdelApp för redigering i Power Apps Studio.

  2. I panelen Data, välj Lägg till data, sök efter anslutningsappen Azure Blob Storage och välj sedan anslutningsappen.

    Sök efter Blob Storage-anslutningen.

  3. I dialogrutan Azure Blob Storage, välj anslutningsprogrammet Azure Blob Storage för att lägga till den i appen.

    Lägg till en Blob Storage-anslutning.

Marias nästa uppgift är att lägga till en skärm som gör att en tekniker eller ingenjör kan spara tid och arbete. Maria bestämmer sig för att lägga till en ny skärm med en Picture-kontroll. När appen körs på en mobil enhet kan den här kontrollen integreras med kamera så att teknikern kan ta för sig. På andra enheter uppmanas användaren att i stället överföra en bildfil. Maria lägger till en länk på den nya skärmen från skärmen EditAppointment genom att utföra följande steg:

  1. På menyn Infoga, välj Ny skärm och välj sedan den Rullningsbar mall.

    Ny skärm från den rullbara mallen.

  2. I fönstret Trädvy, och byt namn på den till TakePhoto.

  3. Ändra egenskapen Text för kontrollen LblAppNameX på den här skärmen så att den blir Ta en bild.

  4. Ta bort kontrollen CanvasX från skärmen.

  5. I menyn Infoga från listrutan Media, välj Lägg till bild för att skapa en ny bildkontroll.

    Lägg till en Picture-kontroll.

    Anteckning

    Picture-kontrollen är egentligen en sammansatt anpassad komponent som gör att användaren kan lägga till en bild på skärmen och visa resultaten.

  6. Ändra storlek på och flytta picture-kontrollen så att den upptar skärmens brödtext.

  7. I fönstret Trädvy, välj kontrollen IconBackarrowX på skärm AppointmentDetails och välj Kopiera.

    Kopiera Back Arrow-kontrollen.

  8. I menyn Trädvy högerklicka på skärmen TakePhoto och välj Klistra in. Kontrollen IconBackArrowX läggs till på skärmen.

    Klistra in Back Arrow-kontrollen på TakePhoto-skärmen.

  9. Flytta kontrollen IconBackArrowX längst upp till vänster i rubrikfältet.

  10. I fönstret Trädvy, välj kontrollen IconBackArrowX på skärmen TakePhoto. I det högra fönstret, på fliken Avancerat, ändra åtgärdsegenskapen OnSelect till Navigate(EditAppointment, ScreenTransition.None).

  11. Lägg till en ny ikonkontroll för Save längst upp till höger i rubrikfältet. Ange egenskapen Visible för den här kontrollen till If(IsBlank(AddMediaButton1.Media), false, true).

    Med den här inställningen blir ikonen Spara osynlig om användaren inte har valt en bild.

    Lägg till Save-ikonkontroll.

  12. Ändra formeln i åtgärdsegenskapen OnSelect för ikonkontrollen Spara till följande.

    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);
    

    Ersätt <storage account name> med namnet på det Azure-lagringskonto som Preeti skapade.

    Den här koden överför bilden till behållaren bilder i Blob Storage. Varje bild får ett unikt filnamn. Funktionen Korrigering uppdateras egenskapen imageUrl i posten avtalade tider med URL-adressen för bilden i Blob Storage.

  13. I fönstret Trädvy visar du kontrollen AddMediaWithImageX. Ändra egenskapen Bild för kontrollen UploadedImageX och ställ in den som AppointmentImage.

    AppointmentImage är en variabel som kommer att fyllas i med en bild som antingen överförs av användaren eller som ett resultat av att användaren har förts över till en annan bild. Du initierar variabeln i skärmen EditAppointment senare.

  14. I fönstret Trädvy väljer du kontrollen AddMediaButtonX. Ställ in egenskapen UseMobileCamera för den här kontrollen till true. Ange egenskapen OnChange för kontrollen till följande.

    Set(AppointmentImage, AddMediaButton1.Media)
    

    Med den här formeln ändras variabeln AppointmentIage så att den refererar till den nya bilden. Den här bilden visas med kontrollen UploadedImageX.

  15. I fönstret Trädvy väljer du skärmen EditAppointment.

  16. Expandera kontrollen EditFormX. Under kontrollen Bild_DataCardX, ta bort kontrollen AddPictureX.

    Ta bort AddPicture-kontrollen.

  17. Välj kontrollen BildX. Ändra följande egenskaper:

    • Bild: Parent.Default
    • X: 30
    • Y: DataCardKeyX.Y + DataCardKeyX.Height + 150 (där DataCardKeyX är datakort som innehåller kontrollen BildX)
    • Bredd: Parent.Width - 60
    • Höjd: 400

    Anteckning

    Bild-kontrollen visas nedanför skärmens nederkant, men en rullningslist läggs till automatiskt så att bilden kan visas.

  18. Lägg till ikonen Kamera på datakorten och placera den sedan mellan etiketten Bild och kontrollen ImageX. Ändra namnet på kontrollen till CameraIcon.

    Anteckning

    Kontrollera att du väljer kontrollen Kameraikon och inte kontrollen Kameramedia.

    Lägg till kameraikon.

  19. Ange åtgärdsegenskapen OnSelect för kontrollen CameraIcon till följande.

    Set(AppointmentImage, SampleImage);
    
    Navigate(TakePhoto, ScreenTransition.None);
    

    När användaren väljer den här ikonen kommer han eller hon att gå till skärmen TakePhoto där de kan ta en bild eller ladda upp en bild. Den ursprungliga bild som visas är standardexempelbild.

För att testa appen gör du följande:

  1. I fönstret Trädvy väljer du skärmen Start.

  2. Välj F5 om du vill förhandsgranska appen.

  3. På skärmen Start, välj Avtalad tid.

  4. Välj en avtalad tid i bläddringsskärmen.

  5. I detaljskärmen för den avtalade tiden markerar du redigeringsikonen i skärmhuvudet.

  6. På skärmen redigera, välj ikonen Kamera för bilden.

  7. Kontrollera att skärmen Ta en kontroll visas.

  8. Välj Ändra bild och överför en valfri bild (eller vidta åtgärder om du kör appen på en mobil enhet).

  9. Välj Spara. Kontrollera att bilden visas på informationssidan och markera sedan börsikonen för att spara ändringarna tillbaka till databasen.

  10. Stäng förhandsgranskningsfönstret och återgå till Power Apps Studio.

Visa bilder på delar

Efter att ha bestämt att Blob Storage är en idealisk plats för att spara bilder i samband med möten, bestämmer Preeti och Kiana att de ska använda samma tillvägagångssätt för att lagra bilder på delar. En viktig fördel med den här metoden är att den inte kräver några ändringar av appen. Appen återanvänder samma lagringskonto och samma anslutning. Som en separat migrering kan de göra följande:

  1. Skapa en ny Blob Storage behållare.

  2. Överför delbilderna till den här behållare.

  3. Ändra ImageUrl i tabellen Delar i databasen InventoryDB till URL för varje bild.

Appen hämtar automatiskt den nya URL-adressen för varje bild för varje del och kontrollen Bild på skärmen PartDetails visar bilden.

Historik för spåra avtalad tid för en kund

Maria berättar att man snabbt kan se hela historiken från en kunds tidigare teknikers besök genom att skapa en anpassad komponent. När Maria arbetar med Caleb och tar fram den information de vill ha, skapar Maria en enkel design med anteckningarna och datum för varje besök.

Data för kundernas möteshistorik.

När Maria tittar på dessa data tror hon att en Galleri-kontroll är det bästa sättet att visa tabelldata på en skärm.

Maria skapar den anpassade komponenten enligt följande:

  1. Med Power Apps Studio, i fönstret Trädvyn, välj Komponenter och välj + Ny komponent.

    Skapa en ny komponent.

    En ny tom komponent med namnet Component1 skapas. Byt namn på komponenten som DateHistoryComponent.

    Byt namn på komponenten.

  2. I menyn Infoga, välj Galleri och välj sedan gallerimallen Tom flexibel höjd.

    Lägg till en Galleri-kontroll.

  3. Flytta Galleri-kontrollen och ändra storlek på den så att den fyller den anpassade komponenten.

  4. Markera Lägg till ett objekt från infogningsrutan och välj sedan Textetikett.

    Lägg till en textetikett till komponenten.

  5. I rutan Trädvy byter du namn på Etikett-kontrollen till NotesLabel. Ange egenskapen Spill till Overflow.Scroll. Den här inställningen gör att kontrollen kan visa flera textrader och låta användaren bläddra igenom den. Ange följande egenskaper så att du kan placera och ändra storlek på kontrollen:

    • LineHeight: 2
    • X: 28
    • Y: 18
    • Bredd: 574
    • Höjd: 140
  6. Lägg till en andra textetikett i kontrollen. Byt namn på den här kontrollen som DateLabel och ange följande egenskaper:

    • LineHeight: 2
    • X: 28
    • Y: 174
    • Bredd: 574
    • Höjd: 70
  7. För att se hur kontrollen kommer att se ut när den sätts in i appen och visas med dess tema, på Trädvy, välj DateHistoryComponent. I det högra fönstret, på fliken Avancerat, välj fältet Fyll och ändra färgen till RGBA(0, 0, 0, 1).

    Visa komponenten.

  8. I fönstret Infoga, visa Former och lägg till kontrollen Rectangle till den anpassade komponenten. Ange följande egenskaper för den här kontrollen:

    • X: 0
    • Y: 273
    • Bredd: Parent.Width
    • Höjd: 2

    Den här kontrollen fungerar som en avgränsare mellan posterna som visas i galleriet.

    Lägg till en Rectangle-kontroll.

Maria är bekant med att lägga till kontroller i skärmar och att skapa appar med Power Apps. Återanvändbara komponenter fungerar emellertid inte på samma sätt. Kiana har beskrivit för Maria att för att kunna använda data i en anpassad komponent måste några ytterligare anpassade indataegenskaper läggas till. Kiana har också förklarat att Maria måste tillhandahålla exempeldata för dessa egenskaper så att hon kan referera till datafälten i kontrollerna i komponenten enligt följande:

  1. I fönstret Trädvy väljer du skärmen DateHistoryComponent. På den högra rutan, på fliken Egenskaper, välj Ny anpassad egenskap.

    Ny anpassad egendom.

  2. I dialogrutan Ny anpassad egenskap anger du följande värden och välj Skapa:

    • Visningsnamn: Data
    • Namn: Data
    • Beskrivning: Tabellen med avtalade tider för en kund med anteckningar och datum
    • Egenskapstyp: Indata
    • Datatyp: Tabell
    • Höj OnReset när värdet ändras: Lämna tom

    Nya egendomsegenskaper.

  3. Om du vill ändra vilka exempeldata som visas för kontrollen väljer du den nya anpassade egenskapen Data. I formelfältet, ange Table({Notes: "Example notes field text.", 'Appointment Date': Text(Today())}).

    Ändra provdata.

  4. I Trädvy markerar du kontrollen GalleriX i DateHistoryComponent och byter namn på den till AppointmentHistory.

  5. I den högra rutan på fliken Avancerat anger du kontrollen Items för gallerikontrollen AppointmentHistory till Parents.Data.

    Uppdatera Items-egenskapen för Galleri-kontrollen.

  6. Välj kontrollen NotesLabel. I den högra rutan på fliken Avancerat, ändra egenskapen Text till ThisItem.Notes, och ändra egenskapen Storlek till 20.

    Anteckning

    Egenskapen Storlek anger teckenstorleken för den text som visas av kontrollen.

  7. Markera kontrollen DateLabel om du vill ändra egenskapen Text till ThisItem.'Appointment Date' och ändra egenskapen Storlek till 20. Fälten i den anpassade komponenten ska visa exempeldata.

    Anpassad komponent med exempeldata.

Den anpassade komponenten är slutförd. Maria skapar en ny skärm där historiken för avtalade tider för en kund visas med hjälp av den här komponenten enligt följande:

  1. I fönstret Trädvy väljer du fliken Skärm.

  2. Expandera skärmen BrowseAppointments, expandera kontrollen BrowseAppointmentsGallery och välj kontrollen Body1_1. På menyn Infoga välj Ikoner och välj sedan ikonen Detaljlista.

    Lägg till detaljerad ikon.

  3. Ändra namnet på Ikon-kontrollen till ViewAppointments.

  4. I menyn Trädvy väljer du kontrollen BrowseAppointmentsGallery. I högra rutan, välj fliken Avancerat, ändra egenskapen TemplateSize till 220. Om du ökar egenskapen expanderas det tillgängliga utrymmet i galleriet.

  5. Flytta ikonen ViewAppointments till det tomma utrymmet under kundnamnet.

    Ändrat mötesgalleri.

  6. Välj ikonkontrollen ViewAppointments. Ange åtgärdsegenskapen OnSelect till följande formel.

    ClearCollect(customerAppointmentsCollection, FieldEngineerAPI.getapicustomeridappointments(ThisItem.customerId));
    
    Navigate(AppointmentsHistoryScreen, ScreenTransition.Fade)
    

    Den här formeln fyller i en samling med namnet customerAppointmentsCollection med avtalade tider för den valda kunden och flyttar sedan till AppointmentHistoryScreen för att visa dem. Du skapar den här skärmen i följande steg.

  7. På menyn Infoga, välj Ny skärm och välj sedan den Rullningsbar mall.

    Ny skärm baserad på den rullbara mallen.

  8. Ändra namnet på den nya skärmen till AppointmentHistoryScreen.

  9. Ta bort kontrollen CanvasX som lades till på skärmen.

    Ta bort Canvas-kontrollen.

  10. Välj kontrollen LblAppNameX på den här skärmen. I högra rutan, välj fliken Avancerat ändra egenskapen Text till följande.

    "Appointments History for " &  BrowseAppointmentsGallery.Selected.customer.name
    
  11. Ange följande egenskaper för kontrollen LblAppNameX för att justera position och storlek:

    • X: 90
    • Y: 0
    • Bredd: 550
    • Höjd: 140
  12. Välj kontrollen RectQuickActionBarX och ställ in egenskapen Height till 140.

  13. Lägg till en kontroll för vänster ikon i skärmrubriken, till vänster om rubriken. Ange åtgärdsegenskapen OnSelect för den här kontrollen till Navigate(BrowseAppointments, Transition.None).

    Tomma möten Historikskärm.

  14. På menyn Infoga välj Anpassa och välj sedan ikonen DateHistoryComponent.

    Lägg till DateHistory-komponent.

  15. Flytta och ändra storlek på komponenten så att den täcker skärmens brödtext, under rubriken.

    Storleksändrad komponent.

  16. Ange följande egenskaper för den här komponenten:

    • Data: customerAppointmentsCollection
    • Datum för avtalad tid: startDateTime
    • Anteckningar: anteckningar
  17. Spara appen.

För att testa appen gör du följande:

  1. I fönstret Trädvy väljer du skärmen Start.

  2. Välj F5 om du vill förhandsgranska appen.

  3. På skärmen Start, välj Avtalad tid.

  4. I bläddringsskärmen, välj ikonen Detaljlista för en avtalad tid.

  5. Kontrollera att skärmen Historiken för avtalade tider för den valda kunden visas.

  6. Stäng förhandsgranskningsfönstret och återgå till Power Apps Studio.

Beställa delar

Ett viktigt krav i systemet är att en tekniker kan beställa alla delar som krävs när han eller hon besöker en kund. Om reservdelarna är i lager bör det vara möjligt att schemalägga ett annat besök för att slutföra reparationen vid nästa lämpliga datum för kunden. Om reservdelarna för närvarande är slut på lagret och måste beställas kan teknikern meddela kunden. Malik kan då ordna en avtalad tid med kunden när Maria får meddelande om att delarna har kommit till lagret.

Reservationsdelen av appen använder tabellerna i databasen InventoryDB som visas i följande bild. Tabellen Order innehåller information om ordrar som har placerats för reservdelar. Tabellen Reservationer anger de bokningsförfrågningar som tekniker och ingenjörer har gjort för delar. I tabellen Tekniker finns namn och kontaktnummer för teknikern som gjorde bokningsbeställningen, vilket gör det enkelt för lageransvarig Maria att fråga vid behov.

Datamodellen Reservationer.

För att stödja den här funktionen måste Kiana uppdatera webb-API:et med en metod som hämtar antalet reserverade objekt för en viss del, enligt följande:

  1. Öppna FieldEngineerApi Webb-API projektet i Visual Studio Code.

  2. Lägg till en fil med namnet Order.cs till mappen Modeller. Lägg till följande kod i filen. Klassen Order spårar information om beställningar som gjorts för reservdelar.

    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; }
        }
    }
    
  3. Lägg till ytterligare en ny fil med namnet Reservation.cs till mappen Modeller och lägg till följande kod i filen. Klassen Reservation innehåller information om antalet objekt för en viss del som för närvarande är reserverade för andra kunder.

    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; }
        }
    }
    
  4. Lägg till ytterligare en fil med InventoryEngineer.cs till mappen Modeller med följande kod. Klassposter InventoryEngineer som tekniker har gjort som innehåller reservationer.

    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; }
        }
    }
    
  5. Öppna filen InventoryContext.cs i mappen Modeller och lägg till följande uttryck i klassen 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; }
    }
    
  6. I fönstret Terminal i Visual Studio Code, kör följande kommandon för att bygga styrenheter för hantering av beställningar och bokningar.

    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
    
  7. Öppna filen BoilerPartController.cs i mappen Kontrollanter och lägg till följande metod GetTotalReservations till klassen 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}; 
        }
        ...
    }
    
  8. Redigera filen OrdersController.cs och ändra metoden PostOrder i klassen OrdersController enligt följande.

    [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);
    }
    
  9. Redigera filen ReservationsController.cs. Ändra metoden PostReservation i klassen ReservationsController enligt följande.

    [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);
    }
    
  10. I terminalfönstret kör du följande kommandon för att bygga och publicera webb-API:et som är redo för distribution.

    dotnet build
    dotnet publish -c Release -o ./publish
    
  11. I Visual Studio Code, högerklicka på mappen publicera och välj Distribuera till webbappen.

Preeti kan nu uppdatera API Management-tjänsten som används av VanArsdel-appen så att den återspeglar det uppdaterade webb-API:et. Det här är en icke-ny ändring, befintlig verksamhet kommer att fortsätta att fungera, skillnaden är att de nya kontrollanterna och åtgärderna för att göra ändringar och lägga order. Preeti utför följande åtgärder:

Anteckning

Preeti kunde ha valt att ta bort det befintliga API:et för fälttekniker och ersätta det med en ny version, men den metoden förutsätter att befintliga program som för närvarande använder API bryts. Det är bättre att lämna det befintliga API:et på plats och lägga till ändringarna som en revidering.

  1. Gå till API Management-tjänsten på Azure-portalen.

  2. På sidan API Management-tjänsten i den vänstra rutan under API:er, välj API:er.

  3. Välj Fälttekniker API, välj ellips-menyn och välj sedan Lägg till revision.

    Lägg till en revision i Field Engineer API.

  4. I dialogrutan Skapa en ny revision av fälttekniker API ange beskrivningen Lade till GET-åtgärd och POST-åtgärder för reservationer och beställningar av del och välj Skapa.

    Skapa revisionen.

  5. På sidan REVISION 2, välj Design.

    Utforma revisionen.

  6. På sidan Design väljer du Lägg till åtgärd. I fönstret FrontEnd ange följande egenskaper och välj sedan Spara. Den här åtgärden används för att hämta antalet objekt som är reserverade för en viss värmardel:

    • Visningsnamn: api/BoilerParts/{id}/Reserved
    • Namn: api-boilerparts-id-reserved
    • URL: GET api/BoilerParts/{id}/Reserved

    Lägg till Reserverad API-åtgärd.

  7. På fliken Test för den nya åtgärden anger du id parameter till ett giltigt delnummer (i exemplet på bilden används del 1) och väljer sedan Skicka.

    Testa webb-API: et.

  8. Kontrollera att testet har lyckats. Åtgärden ska slutföras med ett HTTP 200-svar och en brödtext med information om hur många fel produkten har.

    Testsvaret.

  9. På sidan Design väljer du Lägg till åtgärd. I fönstret FrontEnd ange följande egenskaper (den här åtgärden definierar POST-begäran för att skapa nya order):

    • Visningsnamn: api/Orders - POST
    • Namn: api-orders-post
    • URL: POST api/Orders
  10. På fliken Fråga, välj + Lägg till parameter, lägg till följande parametrar och välj Spara:

    • Namn: boilerPartId, Beskrivning: värmardel-ID, Typ: lång
    • Namn: kvantitet, Beskrivning : Kvantitet, Typ: heltal

    Lägg till parametrar i API-hanteringsfrågan.

  11. Välj Lägg till åtgärd igen i fönstret FrontEnd och ange följande egenskaper (den här åtgärden definierar POST-begäran för att skapa nya reservationer):

    • Visningsnamn: api/Reservations - POST
    • Namn: api-reservations-post
    • URL: POST api/Reservations
  12. På fliken Fråga, lägg till följande parametrar och välj Spara:

    • Namn: boilerPartId, Beskrivning: värmardel-ID, Typ: lång
    • Namn: engineerId, Beskrivning: Tekniker-ID, Typ: sträng
    • Namn: quantityToReserve, Beskrivning: Kvantitet som ska reserveras, Typ: heltal
  13. På fliken Revisioner, välj den nya versionen. På ellips-menyn för denna version, välj Gör aktuell.

    Ställ in den aktuella versionen för revisionen.

  14. I dialogrutan Gör revision aktuell, välj Spara.

  15. Öppna en annan sida i din webbläsare och gå till URL https://<APIM name>.azure-api.net/api/boilerparts/1/reserved där <APIM name> är namnet på din API-tjänst. Kontrollera att du får ett liknande svar som följande.

    {"id":1,"totalReservations":5}
    

Det uppdaterade webb-API:t är nu tillgängligt. I teorin kan Kiana skapa en ny anpassad kontakt för det uppdaterade webb-API:et och lägga till det i appen. Appen kan sedan implementera sin egen logik för att avgöra hur många artiklar av den angivna produkten som för närvarande finns i lager, hur många som är reserverade, jämföra resultaten med antalet artiklar som krävs, göra en beställning för mer lager om det behövs eller reservera artiklar från befintligt lager. Den här typen av logik implementeras dock bättre i en Azure-logikapp. Power Apps kan anropa logikappen via en anpassad kontakt om en tekniker förfrågas om att boka eller beställa en del.

För att skapa logikappen, Kiana gör du så här:

Anteckning

Logikappen som skapas i det här exemplet är icke-transaktionell för att det ska vara enkelt. Det är möjligt att en samtidig användare kan göra en motstridig reservation mellan att kontrollera tillgängligheten för en del och göra en reservation. Du kan implementera transaktioner genom att ersätta en del av logiken i logikappen med en lagrad procedur i InventoryDB-databasen.

  1. I Azure-portalen, på sidan Start, välj + Skapa en resurs.

  2. I rutan Sök på Marketplace anger du Logikapp och väljer sedan Retur.

  3. På sidan Logikapp, välj Skapa.

    Skapa logikappen.

  4. På sidan Skapa en logikapp ange följande värden och välj sedan Granska + skapa:

    • Prenumeration: Välj din Azure-prenumeration
    • Resursgrupp: webapi_rg
    • Namn på logikappen: FieldEngineerPartsOrdering
    • Region: Välj samma plats som du använde för webb-API:et
    • Associera med integrationstjänstmiljö: Lämna tomt
    • Aktivera logganalys: Lämna tomt
  5. På verifieringssidan, välj Skapa och vänta medan logikprogrammet har distribuerats.

  6. När distributionen är slutförd, välj Gå till resurs.

  7. På sidan Logic Apps Designer, bläddra ned till avsnittet Mallar och välj Tom logikapp.

    Välj Tom Logic App-mall.

  8. På fliken Alla  i textrutan Sök kopplingar och utlösare , välj Begär.

    Välj utlösningsbegäran. 

  9. På fliken Utlösare, välj När en HTTP-förfrågan tas emot.

    Utlös när en HTTP-begäran tas emot.

  10. I rutan Begärandetext JSON-schema, ange följande schema och välj sedan + Nytt steg.

    {
        "type": "object",
        "properties": {
            "boilerPartId": {
                "type": "integer"
            },
            "numberToReserve": {
                "type": "integer"
            },
            "engineerId": {
                "type": "string"
            }
        }
    }
    

    Schema för logikappbegäran.

    Det här schemat definierar innehållet i den HTTP-begäran som logikappen förväntar sig. Begärandetexten innehåller ID för en värmardel, antalet objekt som ska reserveras samt ID:t för den tekniker som har begärt den. Appen skickar förfrågan när en tekniker vill reservera en del.

  11. I rutan Välj en åtgärd väljer du Alla och sedan HTTP.

    VäljH tHTTP-åtgärdsalternativet.

    Logikappen anropar åtgärden BoilerParts{id} för webb-API för att hämta information om den värmardel som tillhandahålls av begäran från appen.

  12. I fönstret Åtgärder, välj åtgärden HTTP.

    Välj alternativet HTTP-åtgärd.

  13. I åtgärdsrutan HTTP på ellips-menyn, välj Ändra namn och ändra namnet på åtgärden till CheckBoilerPart.

    Byt namn på HTTP-åtgärden.

  14. Ange egenskaperna för HTTP-åtgärden enligt följande och välj sedan + Nytt steg:

    • Metod: GET
    • URI: https://<APIM name>.azure-api.net/api/boilerparts/, där <APIM name> är namnet på din API Management-tjänst. I rutan Dynamiskt innehåll för denna URI, på fliken Dynamiskt innehåll, välj boilerPartId

    Ange dynamiskt innehåll för HTTP-åtgärd.

  15. I rutan Välj en åtgärd, i rutan Sök efter anslutningar och åtgärder, ange Parsa JSON och välj sedan åtgärden Parsa JSON.

    Välj åtgärd för att analysera JSON.

  16. Använd ellips-menyn för åtgärden Parsa JSON, byt namn på åtgärden till ParseBoilerPart.

  17. I rutan Innehåll för åtgärden ParseBoilerPart i rutan Dynamiskt innehåll, välj Brödtext. I rutan Schema, ange följande JSON-schema och välj sedan + Nytt steg.

    {
        "type": "object",
        "properties": {
            "id": {
                "type": "integer"
            },
            "name": {
                "type": "string"
            },
            "categoryId": {
                "type": "string"
            },
            "price": {
                "type": "number"
            },
            "overview": {
                "type": "string"
            },
            "numberInStock": {
                "type": "integer"
            },
            "imageUrl": {
                "type": "string"
            },
        }
    }
    

    Analysera BoilerPart-objektet.

    Den här åtgärden parsar svarsmeddelandet som returneras av förfrågan getBoilerParts/{id}. Svaret innehåller information om värmardelen, inklusive det antal som för närvarande finns på lager.

  18. I rutan Välj en åtgärd för nästa steg, välj HTTP-koppling.

  19. På fliken Åtgärder, välj åtgärden HTTP.

  20. Använd ellips-menyn för åtgärden, byt namn på åtgärden till CheckReservations.

  21. Ställ in följande egenskaper för den här åtgärden och välj sedan + Nytt steg:

    • Metod: GET
    • URI: https://<APIM name>.azure-api.net/api/boilerparts/. Precis som tidigare i rutan Dynamiskt innehåll för denna URI, på fliken Dynamiskt innehåll, välj boilerPartId. I fältet URI, lägg till texten /reserved efter platshållaren boilerPartId

    Steget CheckReservations.

  22. I rutan Välj en åtgärd, i rutan för den nya åtgärden Sök efter anslutningar och åtgärder, ange Parsa JSON och välj sedan åtgärden Parsa JSON.

  23. Byt namn på åtgärden till ParseReservations.

  24. Ange egenskapen Innehåll till Brödtext.

  25. Ange följande schema ock klicka sedan på + Nytt steg.

    {
        "type": "object",
        "properties": {
            "id": {
                    "type": "integer"
            },
            "totalReservations": {
                    "type": "integer"
            }
        }
    }
    

    Analysera bokningsdata.

  26. I rutan Välj en åtgärd, i rutan för den nya åtgärden Sök efter anslutningar och åtgärder, ange Villkor och välj sedan åtgärden Villkorskontroll.

    Välj Condition-kontroll.

  27. Byt namn på åtgärden till CompareStock.

  28. Välj rutan Välj ett värde. I rutan Lägg till dynamiskt innehåll, på fliken Uttryck anger du följande uttryck och väljer OK.

    add(body('ParseReservations')?['totalReservations'], triggerBody()?['numberToReserve'])
    

    I det här uttrycket beräknas summan av antalet objekt i den angivna värmardelen som för närvarande är reserverade och det antal som teknikern begär.

    Villkoret CompareStock.

  29. I listrutan för villkor är alternativet större än.

  30. I återstående rutan Välj ett värde i rutan Dynamiskt innehåll på fliken Dynamiskt innehåll under ParseBoilerPart, välj numberInStock.

    Jämför totala reservationer med antal artiklar i lager.

  31. Om antalet objekt som krävs plus det reserverade antalet är större än antalet i lagret måste appen göra en order för att undvika att lagret fylls i. I grenen True för åtgärden CompareStock, välj Lägg till en åtgärd.

  32. På fliken Alla för den nya åtgärden, välj HTTP och välj sedan åtgärden HTTP.

  33. Byt namn på åtgärden till PostOrder.

  34. Ange följande egenskaper för åtgärden PostOrder:

    • Metod: POST
    • URI: https://<APIM name>.azure-api.net/api/orders
    • I tabellen Frågor på första raden anger du nyckeln boilerPartId. För värdet i rutan Lägg till dynamiskt innehåll på fliken Dynamiskt innehåll, välj boilerPartId
    • I den andra raden av tabellen Frågor anger du nyckeln kvantitet. I värdefältet, ange 50.

    Skicka en begäran om att beställa fler delar.

    Logikappen beställer automatiskt 50 objekt för den angivna delen när lagret börjar ta slut.

    Anteckning

    Logikappen förutsätter att teknikern inte försöker reservera mer än 50 objekt av en angiven del i en enda förfrågan!

  35. Lämna grenen Falsk för åtgärden CompareStock tom.

  36. Under åtgärden CompareStock, välj + Nytt steg.

  37. På fliken Alla för den nya åtgärden, välj HTTP och välj sedan åtgärden HTTP.

  38. Byt namn på åtgärden till PostReservation.

  39. Ange följande egenskaper för åtgärden PostReservation:

    • Metod: POST
    • URI: https://<APIM name>.azure-api.net/api/reservations
    • I tabellen Frågor på första raden anger du nyckeln boilerPartId. För värdet i rutan Lägg till dynamiskt innehåll på fliken Dynamiskt innehåll, välj boilerPartId.
    • På den andra raden anger du nyckeln engineerId. För värdet i rutan Lägg till dynamiskt innehåll på fliken Dynamiskt innehåll, välj engineerId.
    • På den tredje raden anger du nyckeln quantityToReserve. För värdet i rutan Lägg till dynamiskt innehåll på fliken Dynamiskt innehåll, välj numberToReserve.
  40. Välj + Nytt steg. I rutan Markera en åtgärd söker du efter och markerar åtgärden Svar.

  41. Ange följande egenskaper för åtgärden Svar:

    • Statuskod: 200
    • Rubriker: Nyckel - content-type, Värde - application/json
    • Brödtext: I rutan Dynamiskt innehåll markerar du elementet Brödtext i begäran PostReservation. Detta är det brödtext som returneras när bokning görs.

    Svarsmeddelande skickat av logikappen.

  42. Längst upp till höger på sidan Logic Apps Designer väljer du Spara. Kontrollera att logikappen kan sparas utan fel.

För att skapa den anpassade kopplingen som Power Apps kan använda för att utlösa logikappen utför följande steg medan du är kvar på Azure-portalen:

  1. På sidan Översikt för logikappen, välj Exportera.

    Exportera logikappen.

  2. I fönster Exportera till Power Apps namnge anslutningsprogram PartsOrderingConnector, välj miljön Power Apps och välj OK.

    Exportera logikappen till Power Apps.

  3. Logga in på Power Apps.

  4. I din miljö, under Data, välj Anpassade anslutningar och verifiera PartsOrderingConnector finns med i listan.

    Anpassade anslutningsprogram för Power Apps.

Nu kan Maria ändra appen VanArsdel så att en tekniker kan beställa delar vid en kundplats. Maria lägger till knappen Order på skärmen PartDetails enligt följande:

  1. Logga in på Power Apps (om det inte redan är inloggad).

  2. Under Appar, välj appen VanArsdelApp. På ellips-menyn, välj Redigera.

  3. I fönstret Data, välj Lägg till data, sök efter PartsOrderingConnector anslutningen och lägg till en ny anslutning med den kopplingen.

    Lägg till PartsOrdering-kontakten i appen.

  4. I fönstret Trädvy visa skärmen PartDetails och visa sedan formuläret DetailForm1.

  5. I rutan till Egenskaper till höger, välj Redigera fält. I rutan Fält på ellips-menyn, välj Lägg till ett anpassat kort.

    Lägg till en anpassad Datakort-kontroll i appen.

  6. I rutan Trädvy, byt namn på det nya kortet från DataCard1 till ReserveCard. I fönstret Designvy, ändra storlek på kortet så att det tar upp den nedre delen av skärmen under kontrollen Bild_DataCard1.

    Byt namn på och ändra storlek på Datakort-kontrollen.

  7. På menyn Infoga från undermenyn Indata lägger du till kontrollen Textinmatning, kontrollen Knapp och kontrollen Etikett till kontrollen ReserveCard.

  8. Ändra storlek på och placera kontrollerna så att de är angränsande, med kontrollen Knapp till höger om kontrollen Textinmatning och Etikett under kontrollen Knapp.

  9. I rutan Egenskaper för kontrollen Textinmatning avmarkerar du egenskapen Standard.

  10. I rutan Egenskaper för kontrollen Knapp anger du egenskapen Text till Reservera.

    Layouten på skärmen ParttDetails.

  11. Byt namn kontrollen Textinmatning till NumberToReserve, byt namn på kontrollen Knapp till Reservera och byt namn på kontrollen Etikett som Meddelande.

  12. I rutan Egenskaper för kontrollen Message ange egenskapen Text till Reserverade delar och ange egenskapen Synlig till MessageIsVisible.

    Anteckning

    MessageIsVisible är en variabel som du initierar till falsk när skärmen visas, men den ändras till sant om användaren väljer knappen Reservera.

  13. Ange egenskapen OnSelect för knappen Reservera för att kontrollera följande formel.

    FieldEngineerPartsOrdering.manualinvoke({boilerPartId:ThisItem.id, engineerId:"ab9f4790-05f2-4cc3-9f01-8dfa7d848179", numberToReserve:NumberToReserve.Text});
    
    Set(MessageIsVisible, true);
    

    Anteckning

    Den här formeln använder ett hårdkodat tekniker-ID för att representera teknikern som kör appen. I kapitel 8 beskrivs hur du hämtar ID:t för den inloggade användaren.

    Dessutom utförs ingen felkontroll i appen. förutsätter att förfrågan om reservdelar alltid lyckas. Mer information om felhantering finns i Felfunktion i Power Apps.

  14. Ange egenskapen OnVisible för skärmen PartDetails till Set(MessageIsVisible, false).

För att testa appen gör du följande:

  1. I fönstret Trädvy väljer du skärmen Start.

  2. Välj F5 om du vill förhandsgranska appen.

  3. På skärmen Start, välj Delar.

  4. Välj en del i bläddringsskärmen.

  5. Rulla nedåt till avsnittet för delinformation, ange ett positivt heltalsvärde och välj Reservera. Kontrollera att meddelandet reserverade delar visas.

    PartDetails-skärmen med reservfunktionen aktiverad.

  6. Stäng förhandsgranskningsfönstret och återgå till Power Apps Studio.

  7. I Azure-portal, gå till sidan InventoryDB SQL Database.

  8. Välj Frågeredigeraren och logga in som sqladmin med ditt lösenord.

  9. I fönstret Fråga 1 anger du följande fråga. Välj sedan Kör. Kontrollera att bokningsbeställningen som du gjorde i appen VanArsdel visas.

    SELECT * FROM [dbo].[Reservations]
    

    Frågan resulterar i SQL Database.