Monopoly app bouwen in Salesforce – deel 7: Assets kopen van de bank

In de vorige delen van deze serie hebben we een flow gebouwd om met de dobbelstenen te gooien en de speler te verplaatsen. Ook hebben we flows gebouwd om de eerste regel van een Position uit te laten voeren.

Er zijn ook vakjes die geen Rules aan zich gekoppeld hebben, maar wel een Asset (straat) die je daar kunt kopen. Tenminste, als die niet al door een andere speler gekocht is.

Ook dit proces gaan we weer in een eigen screenflow bouwen die we vervolgens in de SCR – Roll and Move flow zullen invoegen.

Wat moet er gebeuren?

  1. Controleren of de Asset nog in eigendom van de bank is
  2. Als dat zo is, de speler een scherm tonen dat de Asset te koop is en – als de speler genoeg geld bezit – de optie geven om deze te kopen
  3. Als de speler daarvoor kiest de transactie uitvoeren:
    1. Cash Balance van de speler verminderen met het aankoopbedrag
    2. Eigendom van de Asset veranderen van de bank naar de Player

De input variabele

Wat we nodig hebben voor deze flow is de Player record en de Position record. Omdat de Position via een lookup relatie een parent record is van de Player, hebben we met alleen de Player record als inputvariabele alles bij de hand dat we nodig hebben.

Ik houd niet zo van complexe namen voor variabelen met afkortingen en aan arbitraire ‘var’ erin. Wel markeer ik graag welke variabelen voor input of output geselecteerd zijn. Ik gebruik camel case. Daarbij rijg je verschillende woorden aaneen zonder spaties or underscores, maar maak je het iets leesbaarder door vanaf het tweede woord elk nieuw woord met een hoofdletter te beginnen. Bij meervoud gebruik ik gewoon de meervoudsvorm die het woord normaal heeft. Bijvoorbeeld inputWorkOrderLineItems. Lang verhaal om uit te leggen waarom onze input variabele inputPlayer heet.

Nu we de input variabele gemaakt hebben, kunnen we de flow opslaan en een naam geven. Regelmatig tussentijds opslaan tijdens het bouwen wordt dan gemakkelijker.

Wie is de eigenaar van de Asset

We beginnen de flow met een Decision element.

  • Label: Is the Asset owned by the bank?
  • API name: Is_the_Asset_owned_by_the_bank
  • Outcome label: Y
  • Outcome API name: Is_the_Asset_owned_by_the_bank_Y
  • Criteria: inputPlayer.Position__r.Asset__r.Owned_by_Player__r.Name
  • Operator: equals
  • Value: Bank
  • Default outcome label: N

Dat negatieve pad is waar we in het volgende deel het betalen van huur onder gaan plaatsen.

Wat laten we de speler zien

Als bepaald is dat de bank deze Asset te koop heeft, is het natuurlijk ook nog de vraag of de speler wel genoeg geld heeft om deze te kopen. Daar zouden we weer een Decision element voor kunnen gebruiken, maar we kunnen ook verschillende Display text componenten tonen afhankelijk van bepaalde condities.

Heeft de speler genoeg geld, dan laten we zien dat de speler de Asset kan kopen. Zo niet, dan laten we zien dat de Asset weliswaar te koop is en de speler geen huur hoeft te betalen, maar bieden we de optie om te kopen niet aan.

Om de voorwaardelijke zichtbaarheid van deze beide screen components te kunnen instellen hebben we een formule nodig die een boolean (true of false) output heeft. De formule isPlayerCashBalanceSufficient is:

inputPlayer.Position__r.Asset__r.Purchase_Price__c < inputPlayer.Cash_Balance__c

Is de waarde van die formule true, dan is alleen het eerste Display text element zichtbaar. Bij false juist alleen het element dat zegt dat de speler de Asset niet kan kopen.

Aan het icoon dat een oog lijkt voor te stellen, kun je zien dat er voorwaardelijke zichtbaarheid geconfigureerd is op een Screen component. In de screenshot hierboven zie je dat de toggle om de Asset te kunnen kopen alleen getoond wordt als de speler daarvoor genoeg geld heeft.

Action button

Sinds 2024 biedt Flow builder ook Actions aan die je binnen een Screen element van een screenflow kunt aanroepen. Dit is dus anders dan een Apex Action of subflow die je tussen twee schermen als element invoegt.

Ik wil dat hier ook doen omdat het mooier staat dan de toggle. Daarvoor maken we eerst een heel eenvoudige Autolaunched Flow.

Net als bij de screenflow, waar we zo bij terug komen, hebben we alleen de inputPlayer variabele nodig. Voor deze subflow vink ik ook Available for Output aan op die variabale. Dan kan ik na het kopen de nieuwe Cash Balance van de Player gemakkelijk op het scherm laten zien.

Het eerste element in deze flow is het updaten van de waarde van Owned_by_Player__c op de Asset.

Natuurlijk moeten we dan ook het aankoopbedrag van de Cash Balance van de Player af halen. Hierbij gebruik ik niet meteen een Update Records element, maar eerst een Assignment element, omdat ik hiermee de nieuwe waarde gemakkelijker kan toewijzen. In de bovenstaande screenshot zie je dat we dan alleen een veldwaarden kunnen toewijzen zonder keuze voor de operator. Dan zouden we dus speciaal voor het berekenen van de nieuwe Cash Balance een formule moeten schrijven. Dat is niet nodig, want in het Assignment element kun je simpelweg de subtract operator gebruiken.

Het Update Records element is vervolgens ook vrij eenvoudig

Klaar. Deze slaan we op als ALF – Buy Asset from Bank. Vergeet hem niet te activeren.

Terug naar onze SCR – Buy Asset or Pay Rent flow. Deze slaan we even op en dan F5’en we het scherm. Anders weet deze flow nog niet van het bestaan van de Autolaunched flow die we net gemaakt hebben.

Open het Screen element en sleep de Action Button component op het scherm.

Bij Action kun je de Apex Action of actieve subflow zoeken op naam en selecteren. Voor de flow zelf moeten we natuurlijk de input variabele nog opgeven en hier moet je ook weer een API naam aan hangen.

Vervolgens bepalen we de voorwaardelijke zichtbaarheid van de knop. Hij mag alleen zichtbaar zijn wanneer de Player voldoende geld heeft (net zoals bij de toggle die we straks weer gaan weghalen) EN de Asset moet niet al in bezit van de Player zijn. Zou je dat niet doen, dan zou de speler door per abuis meer dan één keer op de knop te klikken dubbel kunnen betalen.

Om de speler te laten zien dat de koop geslaagd is, voegen we ook nog een Display text toe die juist verschijnt wanneer de button verdwijnt.

Hier neem ik je echt real time mee in het bouwen en zie je hoe je met voortschrijdend inzicht te maken krijgt. Ik bedenk nu namelijk dat ik als speler ook voor ik kies om wel of niet te kopen wel precies wil zien hoeveel geld ik heb. Misschien is het immers niet zo handig als ik na de aankoop nog maar een heel klein bedrag over heb.

Dus voegen we nog een Display Text toe, die zichtbaar is vóór de aankoop. Ook bedenk ik dat het handiger is qua conditionele zichtbaarheid om een vóór de aankoop sectie te maken en een ná de aankoop sectie.

De zichtbaarheid is nu als volgt bepaald:

  • Wanneer de Asset nog niet in bezit is van de speler is de bovenste Sectie zichtbaar
  • Daarbinnen is de inleiding met wat de Asset kost en hoeveel geld de Player heeft altijd zichtbaar
  • De Buy this Asset button binnen deze Sectie is alleen beschikbaar als de Player voldoende geld heeft
  • Heeft de speler niet voldoende geld, dan is de Display text “You do not have enough cash (…)” juist zichtbaar
  • Wanneer de Asset in bezit is gekomen van de speler is de bovenste Sectie niet meer zichtbaar en wordt de onderste juist zichtbaar.

Ik heb dit nog niet getest, maar twijfel of de conditionele zichtbaarheid op basis van de Asset eigenaar zal werken. Allereerst moet ik sowieso output variabelen van de Screen Action gebruiken. Ik heb de zichtbaarheid van de “te koop” sectie nu als volgt ingesteld:

{!buyAssetSubflow.Results.Flow__InterviewGuid} Is Null True

Zolang de Action Button niet aangelikt is, heeft er geen flow interview plaatsgevonden en heeft dat dus ook geen Id.

Voor de “Verkocht” sectie, verwacht ik dat deze conditie geschikt is:

{!buyAssetSubflow.IsSuccess} Equals True

Tijd voor de test

We slaan de flow op en bereiden onze testdata voor.

In de eerste test, staat de Player op een straat die in bezit van de bank is en heeft de Player genoeg geld. Helaas kunt je op dit moment nog geen Flow Tests maken voor Screen Flows zoals je dat voor Record Triggered Flows doet, dus ik moet daadwerkelijk eerst even de Player manipuleren. Ook moet ik zorgen dat de Asset in bezit van de bank is. Dat hebben we bij de import niet gedaan.

Het scherm dat we te zien krijgen is precies goed

Als ik op de Buy this Asset knop klik, gebeurt het volgende.

Fout: de Steenstraat kost € 10.000, dus de Cash Balance had nu € 140.000 moeten worden.

Nu even op de records checken wat er wel gebeurd is. Het eigenaarschap van de Asset is correct overgedragen en in werkelijkheid is de Cash Balance van de Player wel degelijk bijgewerkt naar € 140.000.

Dat betekent dat ik gewoon de verkeerde waarde gebruik in mijn Display text element. Dit passen we als volgt aan. Voor de nieuwe Cash Balance gebruiken we nu ook de output van de Screen Action in plaats van de Cash Balance uit de inputPlayer variabele.

Om dezelfde test nogmaals uit te voeren, moeten we eerst zorgen dat de Bank weer de eigenaar van de Asset wordt. Na het opslaan van de wijziging in de flow debuggen we opnieuw.

Verder testen we de volgende scenario’s:

  • De speler bezit deze Asset al: De speler bereikt dit scherm dan helemaal nooit
  • De Asset is te koop, maar de speler heeft niet genoeg geld
Resultaat van de test waarbij Test Player 1 al de eigenaar is.
Resultaat van de test waarbij Test Player 1 niet voldoende geld heeft.

Laatste toevoeging

In de volgende aflevering, zorgen we dat de actieve Player huur kan betalen aan de eigenaar van de Asset wanneer dit niet de bank is. Maar laten we hiervoor nog één toevoeging aan deze flow maken. Wanneer onze actieve speler de Asset zelf bezit, hoeft die natuurlijk geen huur te betalen.

Dus we passen eerst het Decision element aan het begin van onze flow aan.

Daar hangen we een simpel scherm onder.

Volgende keer

Over twee weken voegen we het betalen van huur aan een andere speler toe aan deze flow.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *