Del via


Kapittel 7: Legge til funksjonalitet i appen

Kiana og Maria gleder seg til å vise lagerstyringsappen til Caleb, feltreparatøren. Caleb liker den, men foreslår å legge til litt ekstra funksjonalitet i brukergrensesnittet for å gjøre den enklere å bruke. Caleb ønsker spesifikt å kunne gjøre følgende:

  • Legg til et bilde av arbeidet som er gjort på en koker- eller klimaanleggenhet, og legge det til i avtaledetaljene på skjermbildet Rediger avtale. Dette bildet kan være nyttig som dokumentarisk bevis på utførte reparasjoner. På skjermbildet Rediger avtale kan brukeren legge til et bilde for avtalen, men bildet lagres ikke, siden denne funksjonen ikke er fullt ut implementert ennå. Årsaken til denne utelatelsen er at Kiana og Preeti må finne ut hva som er det beste stedet å lagre bildedata. Caleb ønsker å legge til denne funksjonaliteten så snart som mulig.

  • Vis en fullstendig avtalelogg for en kunde for å spore reparasjoner som ble forespurt, og overvåke eventuelle pågående problemer som kan kreve at reparatørene blir oppringt flere ganger.

  • Bestill deler fra skjermbildet Deledetaljer.

I tillegg viser bilde-kontrollen på Deledetaljer-skjermen bildene som er lagret på en spesfikk URL-adresse. URL-adressene i dataene er ganske enkelt plassholdere for øyeblikket. På samme måten som for bildene på avtaleskjermen må Kiana og Preeti finne ut hva som er det beste stedet å lagre bilder, slik at de er tilgjengelige for appen.

Legge til et bilde i en avtale

Bilder må lagres et sted som er tilgjengelig for appen. Av ytelses- og sikkerhetshensyn ønsker ikke Preeti at bilder skal lagres i OneDrive eller i Azure SQL Database. I stedet bestemmer de seg for å bruke Azure Blob Storage. Blob Storage er optimalisert for oppbevaring av store binærobjekter og er kraftig med innebygd sikkerhet. Power Apps har en tilkobling som gir tilgang til Blob Storage. Maria forslår å legge til et nytt skjermbilde for å ta bilder, noe som forbedrer brukeropplevelsen for Caleb.

Mer informasjon: Azure Blob Storage

Preeti oppretter Blob Storage-kontoen fra Azure-portalen ved å følge disse trinnene:

  1. I Azure-portalen, på Hjem-siden velger du + Opprett en ressurs. I boksen Søk på Marketplace skriver du inn Lagringskonto og velger deretter Enter.

    Azure Marketplace-søk.

  2. Lagringskonto-siden velger du Opprett.

  3. På siden Opprett lagringskonto angir du følgende detaljer og velger deretter Gå gjennom + opprett:

    • Abonnement: Velg abonnementet ditt
    • Ressursgruppe: webapi_rg
    • Navn på lagringskonto: Angi et globalt unikt navn, og noter deg navnet for senere bruk.
    • Sted: Velg ditt nærmeste sted
    • Ytelse: Standard
    • Kontotype: BlobStorage
    • Replikering: RA-GRS

    Opprett Azure Storage-kontoen.

  4. På valideringssiden velger du Opprett og venter mens lagringskontoen klargjøres.

  5. Gå til siden for den nye lagringskontoen.

  6. Oversikt-siden velger du Beholdere.

    Oversikt-siden for lagringskontoen.

  7. Beholdere-siden velger du + Beholder. Opprett en ny beholder med navnet bilder, og velg deretter Opprett. Endre Offentlig tilgangsnivå til Blob.

    Opprett Bilder-beholderen.

  8. Tilbake på Oversikt-siden for lagringskontoen velger du Tilgangsnøkler under innstillingene. På Tilgangsnøkler-siden velger du Vis nøkler. Noter deg verdien av nøkkelen for key1.

    Tilgangsnøkler for lagringskonto.

Preeti gir lagringskontonavnet og -nøkkelen til Kiana, som bruker denne informasjonen til å opprette en egendefinert kobling for appen ved å følge denne fremgangsmåten:

  1. Logg på Power Apps.

  2. Utvid Data og velg Tilkoblinger i venstre rute. De eksisterende tilkoblingene som brukes av appen, skal vises. Velg + Ny kobling.

    Tilkoblingsside i Power Apps.

  3. På siden Ny tilkobling ruller du ned og velger Tilkoblinger, Azure Blob Storage og deretter Opprett.

    Velg Azure Blob Storage-koblingen.

  4. I dialogboksen Azure Blob Storage angir du navnet på lagringskontoen og tilgangsnøkkelen som Preeti har oppgitt, og deretter velger du Opprett.

    Angi lagringslegitimasjon.

  5. Vent mens den nye tilkoblingen opprettes. Den skal vises i listen over tilkoblinger.

Maria kan bruke denne tilkoblingen til Blob Storage i appen for å lagre og hente fotografiske bilder. Marias første oppgave er å legge til tilkoblingen i appen ved å følge disse trinnene:

  1. Åpne VanArsdelApp-appen for redigering i Power Apps Studio.

  2. I Data-ruten velger du Legg til data. Søk etter Azure Blob Storage-koblingen, og velg deretter koblingen.

    Søk etter Blob Storage-koblingen.

  3. I dialogboksen Azure Blob Storage velger du Azure Blob Storage-koblingen for å legge den til i appen.

    Legg til en Blob Storage-tilkobling.

Marias neste oppgave er å legge til en skjerm som gjør det mulig for en reparatør eller tekniker å lagre et bilde. Maria bestemmer seg for å legge til en ny skjerm med en Bilde-kontroll. Når appen kjøres på en mobilenhet, kan denne kontrollen integreres med et kamera slik at teknikeren kan ta et bilde. På andre enheter ber denne kontrollen brukeren om å laste opp en bildefil i stedet. Maria legger til en kobling til denne nye skjermen fra EditAppointment-skjermen ved å følge denne fremgangsmåten:

  1. Sett inn-menyen velger du Ny skjerm, og deretter velger du Kan rulles-malen.

    Ny skjerm fra Kan rulles-malen.

  2. I trevisningsruten velger du den nye skjermen og endrer navnet på den til TakePhoto.

  3. Endre Text-egenskapen for LblAppNameX-kontrollen på denne skjermen til Ta et bilde.

  4. Slett CanvasX-kontrollen fra skjermen.

  5. Sett inn-menyen, fra rullegardinlisten Medier, velger du Legg til bilde for å opprette en ny bildekontroll.

    Legg til en bildekontroll.

    Obs!

    Picture-kontrollen er faktisk en sammensatt egendefinert komponent som gjør det mulig for brukeren å legge til et bilde på skjermen og vise resultatene.

  6. Endre størrelsen på og flytte bilde-kontrollen for å okkupere brødteksten på skjermen.

  7. I trevisningsruten velger du IconBackarrowX-kontrollen på AppointmentDetails-skjermen og velger deretter Kopier.

    Kopier Pil tilbake-kontrollen.

  8. I trevisningsruten høyreklikker du på TakePhoto-skjermen og velger deretter Lim inn. IconBackArrowX-kontrollen legges til på skjermen.

    Lim inn Pil tilbake-kontrollen i TakePhoto-skjermbildet.

  9. Flytt IconBackArrowX-kontrollen øverst til venstre på overskriftslinjen.

  10. I trevisningsruten velger du IconBackArrowX-kontrollen på TakePhoto-skjermen. I den høyre ruten, på Avansert-fanen, endrer du OnSelect-handlingsegenskapen til Navigate(EditAppointment, ScreenTransition.None).

  11. Legg til en ny Lagre-ikonkontroll øverst til høyre på overskriftslinjen. Angi egenskapen Visible for denne kontrollen til If(IsBlank(AddMediaButton1.Media), false, true).

    Denne innstillingen gjør Lagre-ikonet usynlig hvis brukeren ikke har valgt et bilde.

    Legg til Lagre-ikonkontroll.

  12. Endre formelen i OnSelect-handlingsegenskapen for Lagre-ikonkontrollen til følgende.

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

    Erstatt <storage account name> med navnet på Azure Storage-kontoen som Preeti opprettet.

    Denne koden laster opp bildet til bilder-beholderen i Blob Storage. Hvert bilde får et unikt filnavn. Patch-funksjonen oppdaterer imageUrl-egenskapen i avtaleoppføringen med URL-adressen til bildet i Blob Storage.

  13. I trevisningsruten utvider du AddMediaWithImageX-kontrollen. Endre Image-egenskapen for UploadedImageX-kontrollen, og sett den til AppointmentImage.

    AppointmentImage er en variabel som fylles med et bilde som enten lastes opp av brukeren, eller som et resultat av et bilde. Du initialiserer denne variabelen senere i skjermbildet EditAppointment.

  14. I trevisningsruten velger du AddMediaButtonX-kontrollen. Angi UseMobileCamera-egenskapen i denne kontrollen til true. Angi OnChange-handlingsegenskapen i kontrollen til følgende.

    Set(AppointmentImage, AddMediaButton1.Media)
    

    Denne formelen endrer AppointmentImage-variabelen slik at den refererer til det nye bildet. UploadedImageX-kontrollen viser dette bildet.

  15. I trevisningsruten velger du EditAppointment-skjermen.

  16. Utvid EditFormX-kontrollen. Under Bilde_DataCardX-kontrollen fjerner du AddPictureX-kontrollen.

    Fjern AddPicture-kontrollen.

  17. Velg ImageX-kontrollen. Endre følgende egenskaper:

    • Image: Parent.Default
    • X: 30
    • Y: DataCardKeyX.Y + DataCardKeyX.Height + 150 (der DataCardKeyX er datakortet som inneholder ImageX-kontrollen)
    • Bredde: Parent.Width - 60
    • Høyde: 400

    Obs!

    Bildekontrollen ruller ned under bunnen av skjermen, men et rullefelt legges til automatisk for at bildet skal kunne vises.

  18. Legg til et Kamera-ikon på datakortet og plasser det mellom Image-etiketten og ImageX-kontrollen. Endre navnet på kontrollen til CameraIcon.

    Obs!

    Kontroller at du velger kameraikonkontrollen, ikke kameramediekontrollen.

    Legg til kameraikon.

  19. Angi OnSelect-handlingsegenskapen i CameraIcon-kontrollen til følgende.

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

    Når brukerne velger dette ikonet, går de til TakePhoto-skjermbildet, der de kan ta et bilde eller laste opp et bilde. Det første bildet som vises, er standard eksempelbilde.

Gjør følgende for å teste appen:

  1. I trevisningsruten velger du Hjem-skjermen.

  2. Velg F5 for å forhåndsvise appen.

  3. Hjem-skjermen velger du Avtaler.

  4. Velg en avtale i bla gjennom-skjermbildet.

  5. Velg redigeringsikonet i skjermhodet i detaljskjermbildet for avtalen.

  6. Velg Kamera-ikonet for bildet i redigeringsskjermbildet.

  7. Kontroller at skjermbildet Ta et bilde vises.

  8. Velg Endre bilde, og last opp et bilde du velger (eller ta et bilde hvis du kjører appen på en mobilenhet).

  9. Velg Lagre. Kontroller at bildet vises på detaljsiden, og velg deretter hakeikonet for å lagre endringene tilbake i databasen.

  10. Lukk forhåndsvisningsvinduet, og gå tilbake til Power Apps Studio.

Vise bilder av deler

Etter at Preeti og Kiana har fastslått at Blob Storage er et ideelt sted for lagring av bilder tilknyttet avtaler, bestemmer de seg for at de bør bruke samme metode for å lagre bilder av deler. En viktig fordel med denne metoden er at den ikke krever endringer i appen. Appen bruker samme lagringskonto og samme tilkobling på nytt. Som en egen overføringsøvelse kan de gjøre følgende:

  1. Opprett en ny Blob Storage-beholder.

  2. Last opp delebildene til denne beholderen.

  3. Endre ImageUrl-referansene i Deler-tabellen i InventoryDB-databasen til URL-adressen for hvert bilde.

Appen henter automatisk den nye URL-adressen for hvert delebilde, og Bilde-kontrollen på PartDetails-skjermen viser bildet.

Spore avtaleloggen for en kunde

Maria tror at det å kunne raskt vise hele loggen fra en kundes tidligere besøk av en reparatør, kan legges til i appen ved å opprette en egendefinert komponent. Maria samarbeider med Caleb om hvilken informasjon hun vil se, og utformer en enkel utforming som består av notatene og datoen for hvert besøk.

Data for avtaleloggen for en kunde.

Når hun ser på dataene, mener Maria at en gallerikontroll er den beste måten å vise tabelldataene på på en skjerm.

På denne måten oppretter Maria den egendefinerte komponenten:

  1. Bruk Power Apps Studio, gå til trevisningsruten, velg Komponenter, og velg deretter + Ny komponent.

    Opprett en ny komponent.

    Det opprettes en ny tom komponent kalt Component1. Endre navnet på komponenten til DateHistoryComponent.

    Endre navn på komponenten.

  2. Sett inn-menyen velger du Galleri og velger deretter gallerimalen Tom fleksibel høyde.

    Legg til en gallerikontroll.

  3. Flytt gallerikontrollen, og endre størrelsen på den for å fylle den egendefinerte komponenten.

  4. Velg Legg til et element fra Sett inn-ruten, og velg deretter Tekstetikett.

    Legg til en tekstetikett for komponenten.

  5. I trevisningsruten endrer du navnet på etikettkontrollen til NotesLabel. Sett Overflow-egenskapen til Overflow.Scroll. Med denne innstillingen kan kontrollen vise flere tekstlinjer og la brukeren bla gjennom den. Angi følgende egenskaper slik at du kan plassere og endre størrelse på kontrollen:

    • LineHeight: 2
    • X: 28
    • Y: 18
    • Bredde: 574
    • Høyde: 140
  6. Legg til en ekstra tekstetikett for kontrollen. Endre navnet på kontrollen til DateLabel, og angi følgende egenskaper:

    • LineHeight: 2
    • X: 28
    • Y: 174
    • Bredde: 574
    • Høyde: 70
  7. Hvis du vil se hvordan kontrollen vil se ut når den settes inn i appen og vises med temaet, går du til trevisningsruten og velger DateHistoryComponent. På Avansert-fanen i den høyre ruten velger du Fyll-feltet og endrer fargen til RGBA(0, 0, 0, 1).

    Vis komponenten.

  8. I Sett inn-ruten utvider du Figurer og legger til en Rektangel-kontroll for den egendefinerte komponenten. Angi følgende egenskaper for denne kontrollen:

    • X: 0
    • Y: 273
    • Bredde: Parent.Width
    • Høyde: 2

    Denne kontrollen fungerer som et skilletegn mellom oppføringene som vises i galleriet.

    Legg til en rektangelkontroll.

Maria er kjent med å legge til kontroller i skjermer og bygge apper med Power Apps. Komponenter som kan brukes om igjen, fungerer imidlertid ikke på helt samme måte. Kiana beskrev for Maria at for å kunne bruke data i en egendefinert komponent, må noen ekstra egendefinerte inndataegenskaper legges til. Kiana forklarte også at Maria må oppgi eksempeldata for disse egenskapene for å referere til datafeltene i kontrollene i komponenten på denne måten:

  1. I trevisningsruten velger du DateHistoryComponent. På Egenskaper-fanen i den høyre ruten velger du Ny egendefinert egenskap.

    Ny egendefinert egenskap.

  2. I dialogboksen Ny egendefinert egenskap angir du følgende verdier og velger deretter Opprett:

    • Visningsnavn: Data
    • Navn: Data
    • Beskrivelse: Tabellen over avtaler for en kunde som viser notater og datoer
    • Egenskapstype: Inndata
    • Datatype: Tabell
    • Øk OnReset når verdien endres: La feltet være tomt

    Nye egendefinerte egenskaper.

  3. Hvis du vil endre eksempeldataene som vises av kontrollen, velger du den nye egendefinerte Data-egenskapen. I formelfeltet skriver du inn Table({Notes: "Example notes field text.", 'Appointment Date': Text(Today())}).

    Endre eksempeldataene.

  4. I trevisningsruten velger du GalleryX-kontrollen i DateHistoryComponent og endrer navnet til AppointmentHistory.

  5. Avansert-fanen i den høyre rute setter du Items-egenskapen for AppointmentHistory-gallerikontrollen til Parents.Data.

    Oppdater Items-egenskapen for galleri-kontrollen.

  6. Velg NotesLabel-kontrollen. På Avansert-fanen i den høyre ruten endrer du Text-egenskapen til ThisItem.Notes og endrer Size-egenskapen til 20.

    Obs!

    Egenskapen Size angir skriftstørrelsen for teksten som vises av kontrollen.

  7. Velg DateLabel-kontrollen for å endre Text-egenskapen til ThisItem.'Appointment Date' og endre Size-egenskapen til 20. Feltene i den egendefinerte komponenten skal vise eksempeldataene.

    Egendefinert komponent med eksempeldata.

Den egendefinerte komponenten er fullført. Maria oppretter en ny skjerm for å vise avtalehistorikken for en kunde ved å bruke denne komponenten, som følger:

  1. I trevisningsruten velger du Skjermer-fanen.

  2. Utvid BrowseAppointments-skjermen, utvid BrowseAppointmentsGallery-kontrollen, og velg Body1_1-kontrollen. Velg IkonerSett inn-menyen, og deretter velger du Detaljliste-ikonet.

    Legg til Detaljliste-ikonet.

  3. Endre navnet på ikonkontrollen til ViewAppointments.

  4. trevisningsmenyen velger du BrowseAppointmentsGallery-kontrollen. På Avansert-fanen i den høyre ruten endrer du TemplateSize-egenskapen til 220. Hvis du øker denne egenskapen, utvides plassen som er tilgjengelig i galleriet.

  5. Flytt ViewAppointments-ikonet til det tomme området under kundenavnet.

    Endret avtalegalleri.

  6. Velg ViewAppointments-ikonkontrollen. Angi OnSelect-handlingsegenskapen til følgende formel.

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

    Denne formelen fyller ut en samling kalt customerAppointmentsCollection med avtalene for den valgte kunden og flytter deretter til AppointmentHistoryScreen for å vise dem. Du skal opprette denne skjermen i fremgangsmåten nedenfor.

  7. Sett inn-menyen velger du Ny skjerm, og deretter velger du Kan rulles-malen.

    Ny skjerm basert på Kan rulles-malen.

  8. Endre navnet på det nye skjermbildet til AppointmentHistoryScreen.

  9. Slett CanvasX-kontrollen som ble lagt til i denne skjermen.

    Slett Lerret-kontrollen.

  10. Velg LblAppNameX-kontrollen på denne skjermen. På Avansert-fanen i den høyre ruten endrer du Text-egenskapen til følgende.

    "Appointments History for " &  BrowseAppointmentsGallery.Selected.customer.name
    
  11. Angi følgende egenskaper for LblAppNameX-kontrollen for å justere posisjon og størrelse:

    • X: 90
    • Y: 0
    • Bredde: 550
    • Høyde: 140
  12. Velg RectQuickActionBarX-kontrollen, og sett Height-egenskapen til 140.

  13. Legg til en Venstre ikon-kontroll i skjermhodet til venstre for tittelen. Angi OnSelect-handlingsegenskapen for denne kontrollen til Navigate(BrowseAppointments, Transition.None).

    Tom AppointmentsHistory-skjerm.

  14. Velg EgendefinertSett inn-menyen, og deretter velger du DateHistoryComponent.

    Legg til DateHistory-komponent.

  15. Flytt og endre størrelsen på komponenten slik at den opptar brødteksten på skjermen under overskriften.

    Komponent med endret størrelse.

  16. Angi følgende egenskaper for denne komponenten:

    • Data: customerAppointmentsCollection
    • Avtaledato: startDateTime
    • Merknader: notes
  17. Lagre appen.

Gjør følgende for å teste appen:

  1. I trevisningsruten velger du Hjem-skjermen.

  2. Velg F5 for å forhåndsvise appen.

  3. Hjem-skjermen velger du Avtaler.

  4. I bla gjennom-skjermbildet velger du Detaljliste-ikonet for en avtale.

  5. Kontroller at skjermbildet Avtalelogg for den valgte kunden vises.

  6. Lukk forhåndsvisningsvinduet, og gå tilbake til Power Apps Studio.

Bestille deler

Et viktig krav i systemet er å gjøre det mulig for en reparatør å bestille delene som kreves når de besøker en kunde. Hvis delene er på lager, skal det være mulig å planlegge et nytt besøk for å fullføre reparasjonen på neste praktiske dato for kunden. Hvis delene er på lager og må bestilles, kan reparatøren fortelle kunden. Malik kan deretter avtale med kunden når Maria får melding om at delene er kommet til lageret.

Reservasjonsdelen av appen bruker tabellene i InventoryDB-databasen som vises på følgende bilde. Ordrer-tabellen inneholder informasjon om ordrer som er lagt inn for deler. Tabellen Reservasjoner viser reservasjonsforespørsler som reparatører og teknikere har utført for deler. Tabellen Ingeniører inneholder navnet og kontaktnummeret til ingeniøren som utførte bestillingen, noe som gjør det enkelt for Maria, lagersjefen, å spørre om nødvendig.

Reservasjoner-datamodellen.

For å støtte denne funksjonen må Kiana oppdatere nett-API-en med en metode som henter antall reserverte elementer for en bestemt del på denne måten:

  1. Åpne FieldEngineerApi-prosjektet for nett-API-en i Visual Studio Code.

  2. Legg til en fil med navnet Order.cs i Modeller-mappen. Legg til følgende kode i denne filen. Ordrer-klassen sporer detaljene for ordrer som er lagt inn for deler.

    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. Legg til en ny fil med navnet Reservation.cs i Modeller-mappen, og legg til følgende kode i denne filen. Reservasjon-klassen inneholder informasjon om antall elementer for en gitt del som for øyeblikket er reservert for andre 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. Legg til én fil til med navnet InventoryEngineer.cs i Modeller-mappen med følgende kode: InventoryEngineer-klassen registrerer hvilke ingeniører som har foretatt hvilke reservasjoner.

    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. Åpne InventoryContext.cs-filen i Modeller-mappen, og legg til følgende setninger for InventoryContext-klassen.

    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 Terminal-vinduet i Visual Studio Code kjører du følgende kommander for å bygge kontrollere for å håndtere ordrer og reservasjoner.

    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. Åpne BoilerPartController.cs-filen i Kontrollere-mappen, og legg til følgende GetTotalReservations-metode i BoilerPartsController-klassen.

    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. Rediger OrdersController.cs-filen, og endre PostOrder-metoden i OrdersController-klassen som vist nedenfor.

    [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. Rediger ReservationsController.cs-filen. Endre PostReservation-metoden i ReservationsController-klassen på denne måten.

    [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 Terminal-vinduet kjører du følgende kommandoer for å bygge og publisere web-API-en som er klar for distribusjon.

    dotnet build
    dotnet publish -c Release -o ./publish
    
  11. I Visual Studio Code høyreklikker du på Publiser-mappen og velger deretter Distribuer til webprogram.

Preeti kan nå oppdatere API Management-tjenesten som brukes av VanArsdel-appen, slik at den gjenspeiler den oppdaterte web-API-en. Dette er en ikke-ny endring. Eksisterende operasjoner vil fortsette å fungere, og forskjellen er de nye kontrollerne og operasjonene som gjør bestillinger og legger inn ordrer. Preeti utfører følgende oppgaver:

Obs!

Preeti kunne ha valgt å slette den eksisterende Field Engineer API og erstatte den med en ny versjon, men den metoden risikerer å bryte eksisterende programmer som for øyeblikket bruker API-en. Det er bedre å la den eksisterende API-en være på plass og legge til endringene som en revisjon.

  1. Gå til API Management-tjenesten i Azure-portalen.

  2. På siden API Management-tjeneste, i den venstre ruten under API-er, velger du API-er.

  3. Velg Field Engineer API, velg ellipsemenyen, og velg deretter Legg til revisjon.

    Legg til en revisjon i Field Engineer API.

  4. I dialogboksen Opprett en ny revisjon av Field Engineer API angir du beskrivelsen Lagt til GET-operasjon og POST-operasjoner for delereservasjoner og ordrer, og deretter velger du Opprett.

    Opprett revisjonen.

  5. REVISJON 2-siden velger du Utforming.

    Utform revisjonen.

  6. Utforming-siden velger du Legg til operasjon. På FrontEnd-siden angir du følgende egenskaper og velger deretter Lagre. Denne operasjonen brukes til å hente antallet elementer reservert for en gitt standarddel:

    • Visningsnavn: api/BoilerParts/{id}/Reserved
    • Navn: api-boilerparts-id-reserved
    • URL-adresse: GET api/BoilerParts/{id}/Reserved

    Legg til den reserverte API-operasjonen.

  7. Test-fanen for den nye operasjonen angir du id-parameteren til et gyldig delenummer (eksemplet på bilde bruker del 1) og velger deretter Send.

    Test nett-API-en.

  8. Kontroller at testen er vellykket. Operasjonen skal fullføres med et HTTP 200-svar, og en brødtekst som viser antall bestillinger for produktet.

    Testsvaret.

  9. Utforming-siden velger du Legg til operasjon. På FrontEnd-ruten angir du følgende egenskaper (denne operasjonen definerer POST-forespørsler for oppretting av nye ordrer):

    • Visningsnavn: api/Orders - POST
    • Navn: api-orders-post
    • URL-adresse: POST api/Orders
  10. Spørring-fanen velger du + Legg til parameter. Legg til følgende parametere, og velg deretter Lagre:

    • Navn: boilerPartId, Beskrivelse : Boiler Part ID, Type: long
    • Navn: quantity, Beskrivelse : Quantity, Type: integer

    Legg til parametere i API Management-spørringsoperasjonen.

  11. Velg Legg til operasjon igjen i FrontEnd-ruten, og angi følgende egenskaper (denne operasjonen definerer POST-forespørsler for oppretting av nye reservasjoner):

    • Visningsnavn: api/Reservations - POST
    • Navn: api-reservations-post
    • URL-adresse: POST api/Reservations
  12. Spørring-fanen legger du til følgende parametere og velger deretter Lagre:

    • Navn: boilerPartId, Beskrivelse: Boiler Part ID, Type: long
    • Navn: engineerId, Beskrivelse: Ingeniør-ID, Type: string
    • Navn: quantityToReserve, Beskrivelse: Angall som skal reserveres, Type: integer
  13. Velg den nye versjonen på Revissjoner-fanen. Velg Gjør gjeldende på ellipsemenyen for denne versjonen.

    Angi gjeldende versjon for revisjonen.

  14. I dialogboksen Gjør revisjon gjeldende velger du Lagre.

  15. Åpne en annen side i nettleseren, og gå til URL-adressen https://<APIM name>.azure-api.net/api/boilerparts/1/reserved, der <APIM name> er navnet på API-tjenesten. Kontroller at du får et svar som ligner på følgende:

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

Den oppdaterte nett-API-en er nå tilgjengelig. I teorien kunne Kiana opprettet en ny tilpasset kontakt for den oppdaterte nett-API-en og legge den til i appen. Appen kunne deretter implementert sin egen logikk for å avgjøre hvor mange elementer av det angitte produktet som finnes på lager, hvor mange som er reservert, sammenligne resultatene med antall elementer som kreves, plassere en ordre for flere lager om nødvendig, eller reservere elementer fra den eksisterende aksjen. Denne typen logikk er imidlertid bedre implementert i en logisk Azure-app. Power Apps kan kalle den logiske appen via en tilpasset tilkobling når en tekniker ønsker å reservere eller bestille en del.

For å opprette den logiske appen bruker Kiana følgende trinn:

Obs!

For å gjøre ting enkelt er den logiske appen som opprettes i dette eksemplet, ikke-transaksjonsbasert. Det kan hende at en samtidig bruker kan foreta en motstridende bestilling mellom å kontrollere om en del er tilgjengelig og reservere den. Du kan implementere transaksjonssemantikk ved å erstatte noe av logikken i denne logiske appen med en lagret prosedyre i InventoryDB-databasen.

  1. I Azure-portalen, på Hjem-siden velger du + Opprett en ressurs.

  2. I boksen Søk på Marketplace skriver du inn Logisk app og velger deretter Enter.

  3. Logisk app-siden velger du Opprett.

    Opprett den logiske appen.

  4. På siden Opprett en logisk app velger du følgende verdier og velger deretter Gå gjennom + opprett:

    • Abonnement: Velg Azure-abonnementet ditt
    • Ressursgruppe: webapi_rg
    • Navn på logisk app: FieldEngineerPartsOrdering
    • Område: Velg samme plassering som du brukte for web-API-en
    • Knytt til integreringsmiljø: La være tomt
    • Aktiver logganalyse: La være tomt
  5. På verifiseringssiden velger du Opprett og venter mens den logiske appen distribueres.

  6. Når distribusjonen er fullført, velger du Gå til ressurs.

  7. På siden Logic Apps Designer ruller du ned til Maler-delen og velger deretter Tom logisk app.

    Velg malen Tom logisk app.

  8. På Alle-fanen i tekstenboksen Søk etter koblinger og utløsere velger du Forespørsel.

    Velg Forespørsel-utløseren. 

  9. Utløsere-fanen velger du Når en HTTP-forespørsel mottas.

    Utløser når en HTTP-forespørsel mottas.

  10. I boksen Be om JSON-skjematekst angir du følgende skjema og velger deretter + Nytt trinn.

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

    Skjema for å be om logisk app.

    Dette skjemaet definerer innholdet i HTTP-forespørselen som den logiske appen forventer. Forespørselsteksten består av ID-en til en kokerdel, antall elementer som skal reserveres, og ID-en til ingeniøren som sendte forespørselen. Appen sender denne forespørselen når en tekniker ønsker å reservere en del.

  11. I boksen Velg en operasjon velger du Alle og velger deretter HTTP.

    Velg HTTP-operasjonsalternativet.

    Den logiske appen kaller BoilerParts{id}-operasjonen i nett-API-en for å hente informasjon om kokerdelen som ble oppgitt av forespørselen fra appen.

  12. I Handlinger-ruten velger du HTTP-handlingen.

    Velg HTTP-handlingsalternativet.

  13. I HTTP-handlingsboksen, på ellipsemenyen, velger du Gi nytt nav og endrer navnet på handlingen til CheckBoilerPart.

    Endre navnet på HTTP-handlingen.

  14. Angi egenskapene for HTTP-handlingen på følgende måte, og velg deretter + Nytt trinn:

    • Metode: GET
    • URI: https://<APIM name>.azure-api.net/api/boilerparts/, der <APIM name> er navnet på API Management-tjenesten. I boksen Dynamisk innhold for denne URI-en, på fanen Dynamisk innhold, velger du boilerPartId

    Angi dynamisk innhold for HTTP-handling.

  15. I boksen Velg en operasjon, i boksen Søk etter koblinger og handlinger, skriver du inn Analyser JSON, og deretter velger du handlingen Analyser JSON.

    Velg handlingen Analyser JSON.

  16. Bruk ellipsemenyen for handlingen Analyser JSON til å endre navnet på handlingen til ParseBoilerPart.

  17. I Innhold-boksen for ParseBoilerPart-handlingen, i boksen Dynamisk innhold, velger du Brødtekst. I boksen Skjema angir du følgende JSON-skjema og velger deretter + Nytt trinn.

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

    Analyser BoilerPart-objektet.

    Denne handlingen analyserer svarmeldingen som returneres av forespørselen getBoilerParts/{id}. Svaret inneholder informasjon om kokerdelen, inkludert antallet som finnes på lager.

  18. I boksen Velg en operasjon for det nye trinnet velger du HTTP-koblingen.

  19. Handlinger-fanen velger du HTTP-handlingen.

  20. Bruk ellipsemenyen for operasjonen til å endre navnet på operasjonen til CheckReservations.

  21. Angi følgende egenskaper for denne operasjonen, og velg deretter + Nytt trinn:

    • Metode: GET
    • URI: https://<APIM name>.azure-api.net/api/boilerparts/. Som tidligere, i boksen Dynamisk innhold for denne URI-en, på fanen Dynamisk innhold, velger du boilerPartId. I URI-feltet legger du til teksten /reserved etter boilerPartId-plassholderen.

    CheckReservations-trinnet.

  22. I boksen Velg en operasjon for den nye handlingen, i boksen Søk etter koblinger og handlinger, skriver du inn Analyser JSON, og deretter velger du handlingen Analyser JSON.

  23. Endre navnet på operasjonen til ParseReservations.

  24. Angi Content-egenskapen til Brødtekst.

  25. Angi følgende skjema, og velg deretter + Nytt trinn.

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

    Analyser reservasjonsdataene.

  26. I boksen Velg en operasjon for den nye handlingen, i boksen Søk etter koblinger og handlinger, skriver du inn Tilstand, og deretter velger du handlingen Tilstandskontroll.

    Velg tilstandskontrollen.

  27. Endre navnet på operasjonen til CompareStock.

  28. Velg boksen Velg en verdi. I boksen Legg til dynamisk innhold, på Uttrykk-fanen, skriver du inn følgende uttrykk og velger deretter OK.

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

    Dette uttrykket beregner summen av antall elementer for den angitte kokerdelen som er reservert, og antallet teknikeren ber om.

    CompareStock-betingelsen.

  29. I rullegardiinlisteboksen Betingelse velger du er større enn.

  30. I boksen Velg en verdi, i boksen Dynamisk innhold, på fanen Dynamisk innhold, under ParseBoilerPart, velger du numberInStock.

    Sammenligne totalt antall bestillinger med antall elementer på lager.

  31. Hvis antall elementer som er nødvendig pluss antallet som er reservert, er større enn antallet på lager, må appen legge inn en ordre for å fylle på lageret. I True-grenen for CompareStock-handlingen velger du Legg til en handling.

  32. Alle-fanen for den nye operasjonen velger du HTTP og velger deretter HTTP-handlingen.

  33. Endre navnet på operasjonen til PostOrder.

  34. Angi følgende egenskaper for PostOrder-operasjonen:

    • Metode: POST
    • URI: https://<APIM name>.azure-api.net/api/orders
    • I Spørringer-tabellen, i den første raden, angir du nøkkelen boilerPartId. For verdien i boksen Legg til dynamisk innhold, på fanen Dynamisk innhold, velger du boilerPartId
    • I den andre raden i Spørringer-tabellen angir du nøkkelen quantity. Angi 50 i verdifeltet.

    Legg inn en forespørsel om å bestille flere deler.

    Den logiske appen bestiller automatisk 50 elementer av den angitte delen når det begynner å bli lite på lager.

    Obs!

    Den logiske appen forutsetter at ingeniøren faktisk ikke vil prøve å reservere mer enn 50 elementer av en bestemt del i én enkelt forespørsel!

  35. La False-grenen i CompareStock-handlingen være tom.

  36. Under CompareStock-handlingen velger du + Nytt trinn.

  37. Alle-fanen for den nye operasjonen velger du HTTP og velger deretter HTTP-handlingen.

  38. Endre navnet på operasjonen til PostReservation.

  39. Angi følgende egenskaper for PostReservation-operasjonen:

    • Metode: POST
    • URI: https://<APIM name>.azure-api.net/api/reservations
    • I Spørringer-tabellen, i den første raden, angir du nøkkelen boilerPartId. For verdien i boksen Legg til dynamisk innhold, på fanen Dynamisk innhold, velger du boilerPartId.
    • Angi nøkkelen engineerId i den andre raden. For verdien i boksen Legg til dynamisk innhold, på fanen Dynamisk innhold, velger du engineerId.
    • I den tredje raden angir du nøkkelen quantityToReserve. For verdien i boksen Legg til dynamisk innhold, på fanen Dynamisk innhold, velger du numberToReserve.
  40. Velg + Nytt trinn. I boksen Velg en operasjon søker du etter og velger Svar-handlingen.

  41. Angi følgende egenskaper for Svar-handlingen:

    • Statuskode: 200
    • Overskrifter: Nøkkel - content-type, Verdi - application/json
    • Brødtekst: I boksen Dynamisk innhold velger du Brødtekst-elementet fra PostReservation-forespørselen. Dette er brødteksten som returneres når reservasjonen foretas.

    Svarmelding sendt av den logiske appen.

  42. Øverst til venstre på Logic Apps Designer-siden velger du Lagre. Kontroller at den logiske appen kan lagres uten feil.

For å opprette den egendefinerte koblingen som Power Apps kan bruke til å utløse den logiske appen, utfører Kiana følgende trinn mens hun fremdeles er i Azure-portalen:

  1. Oversikt-siden for den logiske appen velger du Eksporter.

    Eksporter den logiske appen.

  2. I ruten Eksporter til Power Apps gir du koblingen navnet PartsOrderingConnector, velger Power Apps-miljøet og velger deretter OK.

    Eksporter den logiske appen til Power Apps.

  3. Logg på Power Apps.

  4. Under Data i miljøet velger du Egendefinerte koblinger og bekrefter at PartsOrderingConnector er oppført.

    Egendefinerte Power Apps-koblinger.

Maria kan nå endre VanArsdel-appen slik at en reparatør kan bestille deler mens han/hun er på et kundested. Maria legger til en Ordre-knapp i skjermbildet PartDetails på denne måten:

  1. Logg på Power Apps (hvis du ikke allerede er logget på).

  2. Under Apper velger du VanArsdelApp-appen. Velg Rediger på ellipsemenyen for appen.

  3. I Data-ruten velger du Legg til dd data, søker etter PartsOrderingConnector-koblingen og legger til en ny tilkobling ved hjelp av denne koblingen.

    Legg til PartsOrdering-koblingen i appen.

  4. I trevisningsruten utvider du PartDetails-skjermen og utvider deretter DetailForm1-skjemaet.

  5. I Egenskaper-ruten til høyre velger du Rediger felter. I Felter-ruten, på ellipsemenyen, velger du Legg til et egendefinert kort.

    Legg til en egendefinert datakortkontroll i appen.

  6. I trevisningsruten endrer du navnet på det nye kortet fra DataCard1 til ReserveCard. I vinduet Utformingsvisning endrer du størrelsen på kortet slik at det dekker den nedre delen av skjermen, under Bilde_DataCard1-kontrollen.

    Gi nytt navn til og endre størrelsen på datakortkontrollen.

  7. Sett inn-menyen, fra Inndata-undermenyen, legger du til en Tekstinndata-kontroll, en Knapp-kontroll og en Etikett-kontroll for ReserveCard-kontrollen.

  8. Endre størrelsen på og plasser kontrollene slik at de ligger ved siden av hverandre, med Knapp-kontrollen til høyre for Tekstinndata-kontrollen og Etikett under Knapp-kontrollen.

  9. I Egenskaper-ruten for Tekstinndata-kontrollen fjerner du Default-egenskapen.

  10. I Egenskaper-ruten for Knapp-kontrollen setter du Text-egenskaper til Reserver.

    Oppsettet på skjermbildet PartDetails.

  11. Endre navnet på Tekstinndata-kontrollen til NumberToReserve, endre navnet på Knapp-kontrollen til Reserver, og endre navnet på Etikett-kontrolle til Melding.

  12. I Egenskaper-ruten for Melding-kontrollen setter du Text-egenskapen til Reserverte deler og setter Visible-egenskapen til MessageIsVisible.

    Obs!

    MessageIsVisible er en variabel som du må initialisere til false når skjermen vises, men den endres til true hvis brukeren velger Reserver-knappen.

  13. Sett OnSelect-egenskapen for Reserver-knappekontrollen til følgende formel.

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

    Obs!

    Denne formelen bruker en hardkodet ingeniør-ID til å representere teknikeren som kjører appen. Kapittel 8 beskriver hvordan du henter ID-en for den påloggede brukeren.

    Appen utfører heller ingen feilkontroll. Den forutsetter at forespørselen om å reservere deler alltid lykkes. Hvis du vil ha mer informasjon om feilhåndtering, kan du gå til Feil-funksjonen i Power Apps.

  14. Sett OnVisible-egenskapen for PartDetails-skjermen til Set(MessageIsVisible, false).

Gjør følgende for å teste appen:

  1. I trevisningsruten velger du Hjem-skjermen.

  2. Velg F5 for å forhåndsvise appen.

  3. Hjem-skjermen velger du Deler.

  4. Velg en del i bla gjennom-skjermbildet.

  5. I skjermbildet Deledetaljer blar du ned til reservasjonsdelen, angir en positiv heltallsverdi og velger deretter Reserver. Kontroller at meldingen Reserverte deler vises.

    PartDetails-skjermbildet med Reserver-funksjonen aktivert.

  6. Lukk forhåndsvisningsvinduet, og gå tilbake til Power Apps Studio.

  7. I Azure-portalen går du til siden for InventoryDB SQL Database.

  8. Velg Power Query-redigering, og logg på som sqladmin med passordet ditt.

  9. Angi følgende spørring i Spørring 1-ruten, og velg deretter Kjør. Kontroller at bestillingen du har gjort i VanArsdel-appen, vises.

    SELECT * FROM [dbo].[Reservations]
    

    Spørringsresultatene i SQL Database.