Tiedostojen dynaaminen luominen Flow:n avulla on todella hyödyllinen ja tehokas ominaisuus. Mutta niin kovin vähän käytetty.

Mikä olisikaan parempi syy tutustua siihen hieman tarkemmin?

Office ja PDF -tiedostoja voi luoda Flow:ssa usealla eri tavalla. Esimerkiksi

Pidän kovasti Word-yhdistimestä. Se on monipuolinen, mutta kuitenkin yksinkertainen käyttää. Tällä kertaa tehdäänkin esimerkkitoteutus sitä hyödyntäen.

Esimerkki – Laskuliitteiden luominen

Laskuliite on klassiinen esimerkki tarpeesta luoda siistin näköinen liitetiedosto tietojoukon pohjalta. Asiantuntijatyössä asiakasta laskutetaan tehdyistä tunneista, jolloin laskun yhteydessä asiakkaalle olisi suotavaa lähettää tuntierittely tehdystä työstä.

Tämä on tilanne myös meillä. Miten olemme asian ratkaisseet?

Ensinnäkin tuntikirjauksemme on rakennettu Power Platformin päälle. Tuntierittelyt saa ladattua Common Data Servicestä vakio-ominaisuuksia hyödyntäen, mutta

  • lopputulos näyttää aika karulta (Excel)
  • erittelyjen lataaminen on manuaalista työtä, joka olisi järkevää automatisoida.

Siis tuumasta toimeen.

Tietomalli

Ohessa yksinkertaistettu kuva laskutukseen liittyvistä entiteeteistä.

  • Asiakkaisiin (Account) liittyy n kpl
  • Työtilauksia (WorkOrder), joihin liittyy n kpl
  • Tuntikirjauksia (HourEntry).
  • Jokaisella tuntikirjauksella on tekijä (User)

 

tuntikirjaus_model

Haluamme luoda jokaiselle asiakkaalle kuukausittain liitetiedoston, joka sisältää työtilauksiin liitttyvät tunnit selitteineen.

Word-template

Aloitetaan tekemällä laskuliitteen mallipohja (template). Se sisältää

  • Yrityksen logon ja asiakkaan nimen (ylätunniste)
  • Tuntien kokonaismäärän
  • Taulukon tehdyistä tunneista (työkohde, päivä, tuntimäärä, kuvaus ja tekijä)

word template 1

Seuraavaksi valmistellaan pohja Flow:ta varten. Aktivoidaan Developer-välilehdeltä suunnittelutila (Design mode).

word template 2

Näin pääsemme lisäämään dokumenttiin paikkamerkkejä (placeholder), joihin Flow:sta käsin voi syöttää sisältöä.

Työkalurivin Plain text -ikonia klikkaamalla dokumenttiin ilmestyy paikkamerkki. Lisätään paikka tuntien kokonaismäärälle (total hours).

word template 3

Jokaiselle paikkamerkille tulee lisätä otsikko (Title) ja leima (Tag).  Tämä tehdään paikkamerkin ominaisuuksista (Properties).

word template 4

Dynaamisen taulukon tekeminen on pykälän monimutkaisempaa. Aloitetaan luomalla taulukon ensimmäiselle riville toistuva kontrolli (Repeating Section Content Control).

Näin Flow:ssa voidaan välittää Word-dokumentille 0-n kappaletta rivejä, joilla taulukko täytetään.

word template 5

Kontrollin sisään luodaan kuhunkin sarakkeeseen tavallinen paikkamerkki sarakkeen arvoa varten (päivä, tuntimäärä, tekijä jne).

Lopputulos näyttää tältä.

word template 6

Tallennetaan vaivalla tehty mallipohja SharePoint-dokumenttikirjastoon ja siirytään hauskaan osuuteen, eli Flow:hun.

Laskuliitteet muodostava Flow

Yksinkertaistetaan esimerkkiä hieman. Toteutetaan Flow, joka muodostaa liitetiedoston jokaisesta asiakkaan työtilauksesta. Sitä on helppoa jatkojalostaa siten, että asiakkaan kaikki työtilaukset yhteen liitteeseen niputetaan.

Laskuliitteiden muodostus käynnistyy manuaalisesti (Manually trigger a flow -käynnistin). Flow voisi luontevasti käynnistyä myös kuun viimeisenä päivänä ajastetusti.

Muodostetaan hakemistopolku (path), johon liitetiedostot tallennetaan. Se on muotoa vuosi/kuukausi.

formatDateTime(utcNow(),'yyyy')

/

formatDateTime(utcNow(),'MM')

Tämän jälkeen haetaan kaikki asiakkaat (List Accounts) Common Data Service:stä.

invoice flow 1

Kunkin asiakkaan kohdalla haetaan siihen liitetyt työnumerot (WorkOrders).

invoice flow 2

Ennen varsinaista dokumentin muodostusta, meidän tulee noutaa kaikki dokumentilla esitettävä tieto.

Laskutettavien tuntien kokonaissumma

Dokumentilla näytetään laskutettavien tuntien kokonaisumma. Voisimme käydä työnumeron kaikki tuntikirjaukset (HourEntries) läpi (Apply to each -toiminnolla) ja laskea itse tunnit yhteen.

Mutta sen voi tehdä helpomminkin.

Haetaan kaikki työnumeroon liittyvät tuntikirjaukset (List records -toiminto) ja Aggregation transformation -parametrin avulla:

  • Ryhmitellään tunnit sen mukaan onko ne laskutettu vai ei: groupby((ff_invoiced),
  • lasketaan ryhmän sisällä yhteen tuntimäärät: aggregate(ff_hours with sum as ffhours)

Rajaamme kyselyssä tulosjoukon kattamaan vain laskuttamattomat tunnit. Näin kysely palauttaa ainoastaan yhden ryhmän (Uninvoiced) ja sen kokonaistuntimäärän (ff_hours).

[
  {
    "@odata.id": "https://ff.crm4.dynamics.com/api/data/v9.0/ff_hourentries(00000000-0000-0000-0000-000000000000)",
    "@odata.etag": "",
    "ItemInternalId": "00000000-0000-0000-0000-000000000000",
    "ff_invoiced": 1,
    "_ff_invoiced_label": "Uninvoiced",
    "ff_hours": 150
  }
]

Poimitaan kokonaistuntimäärä talteen Compose-toiminnolla ja seuraava kaavalla.

first(outputs('List_sum_of_hours')?['body/value'])['ff_hours']

invoice flow 3

Tuntikirjaajan nimen selvittäminen

Seuraavaksi haetaan työnumeroon liittyvät (laskuttamattomat) tuntikirjaukset.

Laskuliitteen rivillä on myös työn tehneen henkilön nimi. Harmiksemme tuntikirjaus-tietue sisältää ainoastaan kirjaajan tunnisteen (guid).

Voi ei, pitääkö jokaisen kirjausrivin kohdalla hakea User-entiteetistä käyttäjän nimi?

Ei.

Expand query -ominaisuuden avulla voimme laajentaa tulosjoukon kattamaan relaation takaa löytyviä kenttiä.

Haetaan sen avulla tulosjoukkoon kirjaajan nimi (fullname).

Expand Query: ff_WorkDoneByUser($select=fullname)

Voilà!

invoice flow 4

Kirjausrivien muotoilu Word-templatea varten

Aluksi tekemämme Word-template odottaa saavansa tuntikirjaukset seuraavassa muodossa.

[
  {
    "Hours": "1",
    "Description": "Documentation",
    "Day": "1.1.2020",
    "Work order": "Work order 1",
    "User": "Timo Pertilä"
  },
  {
    "Hours": "3",
    "Description": "Implementation work",
    "Day": "1.1.2020",
    "Work order": "Work order 1",
    "User": "Timo Pertilä"
  }
]

List hour entries -toiminnon tulosjoukon (value) voi helposti muotoilla kyseiseen muotoon Select-toimintoa käyttäen.

invoice flow select

Yksittäisen tuntikirjauksen description-kentän arvo voi olla tyhjä. Tällöin Word-dokumentin muodostus menee virheeseen. Korvataan coalesce-komennolla tyhjät arvot viivalla.

coalesce(item()?['ff_description'], '-')

Muotoillaan samalla päivämäärä-kentän arvo suomalaiseen makuun sopivammaksi.

formatDateTime(item()?['ff_workday'], 'dd.MM.yyyy')

Liitetiedoston luominen

Valmistelut olivat hieman työläitä, mutta niiden jälkeen itse Word-dokumentin luonti on helppoa.

Suoritetaan Populate a Microsoft Word Template -toiminto, joka saa parametreinaan

  • laskun rivit (InvoiceLine)
  • tuntien kokonaismäärän (Total Hours)
  • asiakkaan nimen (Customer)

invoice flow 6

Tallennetaan laskuliite SharePointiin (Create file).

invoice flow 8

Lopuksi Word-dokumentista muodostetaan asiakkaalle lähetettävä PDF-tiedosto (Convert Word Document to PDF), joka tallennetaan samaan paikkaan Word-dokumentin kanssa.

invoice flow 10

Lopputulos

Flow:n suorituksen jälkeen kuukauden laskuliitteet löytyvät omasta hakemistostaan.

invoices in folder

Valmiit laskuliitteet näyttävät tältä.

invoice attachment

Ja Flow kokonaisuudessaan tältä.

invoice flow full

Mikä parasta, voit muodostaa juuri sen näköiset ja sisältöiset liitteet kuin haluat.