OCL Expressions

Produktlinien: Expert
Module: Leistung & CRM
Erstellt: 28.11.2011, Änderung: 11.07.2017
Formatierung angepasst
Mehr ansehen

OCL Expressions für alle Einträge

  • Aktuell angemeldeter Benutzer: Timsession.allInstances->first.login Gibt den aktuell eingeloggten Projektbearbeiter zurück.
  • Zugriff auf eindeutige Objekt-ID: boldid Der Operator boldid liefert die eindeutige Id-Nummer des Objekts. Diese Nummer wird bei neu erzeugten Objekten fortlaufend vergeben und kann daher auch für Sortierungen nach Erzeugungsreihenfolge nützlich sein.bo
  • Erzeuger eines Eintrags: creator.
  • Modifizierer eines Eintrags: modifier.
  • Erzeugungsdatum eines Eintrags: creationDateTime.
  • Änderungdatum: modifiedDateTime.

OCL Expressions für Adresseinträge

  • Alle Adressen: adresseintrag.
  • Alle Personen: person.
  • Alle Firmen: firma.
  • Alle Kontakte: kontakt.
  • Alle Paare: paar.
  • Alle einfachen Adressen: einfacheAdresse.
  • Kunden (Adresseinträge, die eines oder mehrere Projekte haben): adresseintrag->select(projekte->size>0)
  • Adresseinträge, die im Feld "Stellung" den Eintrag CEO haben: adresseintrag->select(stellung.asstring='CEO')
  • Adresseinträge, die keinen Eintrag im Feld "Stellung" haben: adresseintrag->select(stellung.asstring='')
  • Adresseinträge, die einen Eintrag im Feld "Stellung" haben: adresseintrag->select(stellung.asstring<>'')
  • Adresseinträge, die im Feld "Kanton/State" den Eintrag ZH haben: adresseintrag->select(standardkanton='ZH')
  • Personen, die keine Kontaktverknüpfung zu einer Firma haben: person->select(kontakte->size=0)
  • Adresseinträge, die im Namen "wald" enthalten oder deren Namen mit "Treu" beginnt: adresseintrag->select(name.sqlLike('%wald%') or name.sqlLike('Treu%'))

    Die Variante sqlLikeCaseInsensitive macht denselben Vergleich, achtet aber nicht auf Gross/Kleinschreibung; "and", "or" und "not" sind erlaubt (Klammersetzung beachten, immer kleinschreiben).

  • Vornamen von Personen: In Listen können verschiedene Adressarten gleichzeitig angezeigt werden (Personen, Firmen, Kontakte, Paare). Will man in einer solchen Liste den Vornamen der Person anzeigen, muss man eine Fallunterscheidung machen:
    if self.oclistypeof(Person) then self.oclastype(Person).vorname else if self.oclistypeof(Kontakt) then 
    if self.oclastype(Kontakt).person->notempty then self.oclastype(Kontakt).person.vorname 
    else self.oclastype(Kontakt).vorname endif else '' endif endif
  • Namen von Personen:In der Liste können verschiedene Adressarten gleichzeitig angezeigt werden (Personen, Firmen, Kontakte). Will man in einer solchen Liste den Namen der Person anzeigen, muss man eine Fallunterscheidung machen:
    if self.oclistypeof(Person) then self.oclastype(Person).name else if self.oclistypeof(Kontakt) then 
    if self.oclastype(Kontakt).person->notempty then self.oclastype(Kontakt).person.name 
    else self.oclastype(Kontakt).name endif else '' endif endif
  • Namen aller Adresseinträge (Firmen, Kontakte, Personen, Paare):
    if self.oclistypeof(Paar) then if self.oclastype(Paar).personA->notempty and self.oclastype(Paar).personB->notempty then if self.oclastype(Paar).personA.name.asstring = self.oclastype(Paar).personB.name.asstring then self.oclastype(Paar).personA.name else self.oclastype(Paar).personA.name + ' & ' + self.oclastype(Paar).personB.name endif else if self.oclastype(Paar).personA->notempty then if self.oclastype(Paar).personA.name.asstring = self.oclastype(Paar).nameb.asstring then self.oclastype(Paar).personA.name else self.oclastype(Paar).personA.name + ' & ' + self.oclastype(Paar).nameb endif else if self.oclastype(Paar).personB->notempty then if self.oclastype(Paar).namea.asstring = self.oclastype(Paar).personB.name.asstring then self.oclastype(Paar).namea else self.oclastype(Paar).namea + ' & ' + self.oclastype(Paar).personB.name endif else if self.oclastype(Paar).namea.asstring = self.oclastype(Paar).nameb.asstring then self.oclastype(Paar).namea else self.oclastype(Paar).namea + ' & ' + self.oclastype(Paar).nameb endif endif endif endif else if self.oclistypeof(Kontakt) then if self.oclastype(Kontakt).person->notempty then self.oclastype(Kontakt).person.name else self.oclastype(Kontakt).name endif else name endif endif
  • Vornamen von Paaren: Es werden beide Vornamen angezeigt, getrennt durch '&':
    if self.oclastype(Paar).personA->notempty and self.oclastype(Paar).personB->notempty then self.oclastype(Paar).personA.vorname + ' & ' + self.oclastype(Paar).personB.vorname else if self.oclastype(Paar).personA->notempty then self.oclastype(Paar).personA.vorname + ' & ' + self.oclastype(Paar).vornameb else if self.oclastype(Paar).personB->notempty then self.oclastype(Paar).vornameA + ' & ' + self.oclastype(Paar).personB.vorname else self.oclastype(Paar).vornameA + ' & ' + self.oclastype(Paar).vornameb endif endif endif
  • Nachnamen von Paaren: Es werden beide Namen angezeigt, getrennt durch '&':
  • if self.oclastype(Paar).personA->notempty and self.oclastype(Paar).personB->notempty then self.oclastype(Paar).personA.name + ' & ' + self.oclastype(Paar).personB.name else if self.oclastype(Paar).personA->notempty then self.oclastype(Paar).personA.name + ' & ' + self.oclastype(Paar).nameb else if self.oclastype(Paar).personB->notempty then self.oclastype(Paar).nameA + ' & ' + self.oclastype(Paar).personB.name else self.oclastype(Paar).nameA + ' & ' + self.oclastype(Paar).nameb endif endif endif
  • Geburtstage von (aktiven) Personen in den nächsten 30 Tagen:
    person->select(aktiv)->select(geburtsdatum.asstring<>'')->select(((date<=encodedate(date.year,geburtsdatum.month,geburtsdatum.day))
    and(date>=encodedate(date.year,geburtsdatum.month,geburtsdatum.day).incday(-30)))or((date<=encodedate(date.year+1,geburtsdatum.month,geburtsdatum.day))
    and (date>=encodedate(date.year+1, geburtsdatum.month,geburtsdatum.day).incday(-30))))
  • Geschlecht der Person: Die Expression funktioniert auf beliebigen Adresslisten und gibt im Falle einer Firma oder eines Paars einen Leerstring zurück.
    if ocliskindof(Kontakt) then self->oclastype(Kontakt)->asset->collect(x| if x.person->size>0 then
    if x.person.ismale then 'Male' else 'Female' endif else if x.ismale then 'Male' else 'Female' endif  endif)->first
    else if ocliskindof(Person) then if oclastype(Person).ismale then 'Male' else 'Female' endif else '' endif endif

OCL Expressions für Bearbeiter

  • Alle Bearbeiter: projektbearbeiter
  • Alle aktiven Bearbeiter: projektbearbeiter->select(aktiv)
  • Angemeldeter (aktuell eingeloggter) Bearbeiter: Timsession.allInstances->first.login

Bearbeiter, die:

  • Projektleiter eines oder mehrerer Projekte sind: projektbearbeiter->select(eigprojekte->size>0)
  • der Bearbeiterstufe "Secretary" zugeordnet sind: projektbearbeiter->select(stufe.asstring='Secretary')
  • keinen Eintrag im Feld "Kürzel" haben: projektbearbeiter->select(kuerzel.asstring='')
  • einen Eintrag im Feld "Kürzel" haben: projektbearbeiter->select(kuerzel.asstring<>'')
  • Alle Leistungen eines Bearbeiters während eines Jahres:
    projektbearbeiter-->groupleistungenb('01.01.2011', '31.12.2011','')
    ->collect(minutenintoffen + minutenintverrechnet)->sum
  • Anteil der verrechenbaren Leistungen eines Bearbeiters während eines Jahres:
    self->groupleistungenB('1.1.2011', '31.12.2011', '')
    ->collect(s | (s.minutenextOffen-s.minutenextOffenUnprod+s.minutenextVerrechnet-s.minutenextVerrechnetUnprod)
    / (s.minutenIntVerrechnet+s.minutenIntOffen) *100)->sum

OCL Expressions für Projekte /​ Phasen

  • Alle Projekte: projekt oder Projekt.allInstances (Gross-/Kleinschreibung beachten)
  • Alle Projektphasen: projektphase oder Projektphase.allInstances (Gross-/Kleinschreibung beachten)

Alle Projekte, die

  • keine Projektphasen haben: projekt->select(phasen->size=0)
  • mindestens eine Projektphase haben: projekt->select(phasen->size>0)
  • einem produktiven Projekttypen zugeordnet sind: projekt->select(typ.produktiv)
  • in französischer Sprache geführt werden: projekt->select(sprache.asstring='FR')
  • aktiv sind: projekt->select(aktiv)
  • inaktiv sind: projekt->select(not aktiv)
  • Projekte mit doppelten Codes auflisten: projekt->select(code->asset->collect(x|Projekt.allinstances->select(code=x)->size)->sum>1) Als Ergebnis werden alle Projekte aufgelistet, deren Code doppelt vorkommt.

Alle Projektphasen, die

  • Pauschalphasen sind: projektphase->select(pauschal)
  • nicht verrechenbar sind: projektphase->select(not verrechenbar)
  • Die Oberphase einer Projektphase: parentphase
  • Die erste Ebene der Subphasen einer Projektphase: subphasen
  • Alle Oberphasen einer Projektphase: parentlist Reihenfolge ist zuerst oberste Parentphase, zuletzt die unmittelbare Parentphase. Mit parentlist->first kann also auf die oberste Ebene im Baum zugegriffen werden.
  • Alle Subphasen einer Projektphase: sublist Durchläuft den ganzen Baum der Subphasen und beinhaltet auch die Subphasen der Subphasen.

Status der Projektphasen

  • Datum offeriert: offertDatum
  • Datum erteilt: erteiltDatum
  • Datum abgeschlossen: abschlussDatum
  • Datum abgelehnt: abgelehntDatum

Den einzelnen Status kann man über eine Nummer abfragen (bsp. phasen->select(status=1)). Die Nummern der einzelnen Status lautet wie folgt:

0: Im Angebot

1: Erteilt

2: Abgeschlossen

3: Abgelehnt

Budgetwerte auf Projekten

Leistungen

  • Aufwand geplant: planMinutenInt
  • Aufwand effektiv: sumMinutenInt
  • Honorar geplant: planWertExt
  • Honorar effektiv: sumWertExt
  • Honorar intern geplant: planWertInt
  • Honorar intern effektiv: sumLeistungWertInt
  • Kosten geplant: planKostenLeistung
  • Kosten effektiv: sumLeistungWertKosten

Spesen

  • Betrag geplant: planSpesenWert
  • Betrag effektiv: sumSpesenWert
  • Kosten geplant: planKostenSpesen
  • Kosten effektiv: sumKostenSpesen

Auslagen

  • Betrag geplant: planAuslagenWert
  • Betrag effektiv: sumAuslagenWert
  • Kosten geplant: planKostenAuslagen
  • Kosten effektiv: sumKostenAuslagen

Budgetwerte auf Projektphasen

Leistungen

  • Aufwand geplant: planMinutenInt
  • Aufwand effektiv: sumMinutenInt
  • Honorar geplant: planWertExt
  • Honorar effektiv: sumWertExt
  • Honorar intern geplant: planWertInt
  • Honorar intern effektiv: sumWertInt
  • Kosten geplant: planKostenLeistung
  • Kosten effektivsumKostenLeistung

Spesen

  • Betrag geplant: planSpesenWert
  • Betrag effektiv: sumSpesenWert
  • Kosten geplant: planKostenSpesen
  • Kosten effektiv: sumKostenSpesen

Auslagen

  • Betrag geplant: planAuslagenWert
  • Betrag effektiv: sumAuslagenWert
  • Kosten geplant: planKostenAuslagen
  • Kosten effektiv: sumKostenAuslagen

Zusätzliche Felder (auf der Oberfläche nicht sichtbar):

  • Erwartetes Mindestbudget Leistungen: minPlanWertLeist
  • Erwartetes Maximalbudget Leistungen: maxPlanWertLeist
  • Erwartetes Mindestbudget Spesen: minPlanWertSpesen
  • Erwartetes Maximalbudget Spesen: maxPlanWertSpesen

Werte auf Phasenzu­ordnungen

Auf Phasenzuordnungen sind ausser der oben gelisteten Budgetwerte zusätzlich folgende Werte verfügbar:

Bearbeiter-Zuordnung

  • aktiv
  • ansatzBearbeiter
  • ansatzExt
  • ansatzKosten
  • tagespauschaleExt
Tätigkeitszuordnung
  • aktiv
  • bearbeiter
  • startDatum
  • endDatum
  • ansatzExt
  • ansatzKosten
  • ansatzBearbeiter
  • tagespauschaleExt
  • stueckwert
  • name (nur über OCL)
  • offertText
  • bezeichnung
Spesentyp-Zuordnung
  • bearbeiter
  • wertProEinheitInt
  • wertProEinheitExt
  • wertProEinheitKosten
  • name (nur über OCL)
  • offertText
  • bezeichnung
Auslagentyp-Zuordnung
  • bearbeiter
  • wertProEinheitInt
  • wertProEinheitExt
  • wertProEinheitKosten
  • name (nur über OCL)
  • offertText
  • bezeichnung

OCL Expressions für Rechnungen

Zugriff auf Buchungszeile der Rechnung und Buchungen auswerten

  • Buchungszeile aufrufen: buchungsbeleg->oclAsType(Beleg).buchungen

Von hier aus kann mann nun auf die verschiedenen Werte zugreifen wie z.B.die

  • Nettobeträge der Haben Buchungen einer Rechnung: buchungsbeleg->oclastype(Beleg).buchungen->select(isthaben).betrag->sum

Vorschüsse auf Rechnungen

  • Welche Vorschüsse werden mit welchen Beträgen auf der Rechnung in Abzug gebracht:
    rechnungvorschusslink->select(betragnetto<>0)->collect
    (vorschuesse.bezeichnung + ': ' + betragnetto.asstring)->listtostring(' / ')

    Zeigt die Bezeichnung der Vorschüsse und den jeweiligen Betrag an, z.B. in einer Listenspalte.

  • Vorschüsse, die auf der Rechnung verrechnet werden: vorschuesseAufRechnung
  • Vorschüsse, die auf der Rechnung in Abzug gebracht werden: vorschuesse

OCL Expressions für Rechnungsberichte

Wie Sie Word-Berichte aufbauen, finden Sie im Artikel Word-Berichte. Was die einzelnen Felder auf der Rechnung bedeuten, finden Sie im Artikel Die Rechnung in OCL.

  • Rechnungsadresse: rechnungsadresstext
  • Rechnungsdatum: datum
  • Rechnungsnummer: nummer
  • Rechnungsperiode von: von.asstring
  • Rechnungsperiode bis: bis.asstring
  • Briefanrede: rechnungsbriefanrede
  • Grussformel: rechnungsgrussformel
  • Projekt: projekt
  • Projektbetreff: projekt.betreffend
  • Ist Pauschalrechnung: pauschal
  • Pauschalbetrag: pauschalbetrag
  • Total Leistungen: leistwertext
  • RabattBetrag: rabattBetrag
  • RabattProzent: rabattProzent
  • Totalrabatt (egal, ob in % oder fix): totalRabattBetrag
  • MWSTProzent Leistungen: leistmwstsatz
  • MWST Leistungen: leistmwst
  • Total Leistungen inkl. MWST: leistwertextmitmwst
  • Total Spesenpauschale: pauschalspesenbetrageff
  • Spesenpauschale Betrag: pauschalspesenbetrag
  • Spesenpauschale Prozent: pauschalspesenprozent
  • Total Spesen (pauschal + Einträge): spesenext
  • Total Spesen (ohne pauschale): spesenext - pauschalspesenbetrageff
  • MWST Spesen: spesenmwst
  • MWSTProzent Spesen: spesenmwstsatz
  • Total Spesen inkl. MWST: spesenextmitmwst
  • Auslagen: auslagenext
  • MWST Auslagen: auslagenmwst
  • MWSTProzent Auslagen: spesenmwstsatz
  • Total Auslagen inkl MWST: auslagenextmitmwst
  • Vorschüsse, die verrechnet werden: vorschussbetrag
  • MWST Vorschüsse: vorschussmwst
  • Vorschüsse mit MWST: vorschussbetrag + vorschussmwst
  • MWST Prozent auf Vorschüssen: leistmwstsatz
  • Total Leistungen, Spesen, Auslagen und Vorschüsse, inkl. MWST: leistspesenextmitmwst + vorschussbetrag + vorschussmwst
  • Rechnungstotal: total
  • Währung der Rechnung: waehrung
  • Projektleiter: projekt.projektleiter
  • Totalbetrag ohne Rappen: total.floor.asstring
  • Sortierung nach PLZ eines Rechnungsreports, der auf einer Liste von Rechnungen ausgeführt wird (Expression des Masterbands):
    if oclisKindOf(Container) then oclAsType(Container).eintraege
    ->list->oclAsType(Rechnung)->ordermulti('if xRechnungsadresse
    ->isEmpty then projekt.kunde.oclastype(Adresseintrag) else 
    xRechnungsadresse.oclastype(Adresseintrag) endif.standardplz') 
    else self->asset endif

Conditional Expressions

Expressions, die eine Bedingung abfragen, also JA oder NEIN zurückgeben. Normalerweise Band Expressions für 'Cond'-Bands (siehe Artikel Word-Berichte).

  • Hat Rechnungsperiode: von.asstring <> '' or bis.asstring <> ''
  • Hat Leistungen (und ist keine Pauschalrechnung): (not pauschal) and (leistwertext <> 0)
  • Hat Rabatt: rabatt
  • Rabatt ist als Betrag: rabattBetrag > 0
  • Rabatt ist in Prozent: rabattProzent > 0
  • Hat MWST auf Leistungen: leistmwst > 0
  • Hat Spesenpauschale: pauschalspesen
  • Spesenpauschale als Betrag: pauschalspesenbetrag > 0
  • Spesenpauschale in Prozent: pauschalspesenprozent > 0
  • Speseneinträge?: usespesen
  • Hat Spesen: spesenext > 0
  • Es hat Spesen und sie sollen verwendet werden: (spesenext > 0) and usespesen
  • Hat MWST auf Spesen: spesenmwst > 0
  • Hat Auslagen: auslagenext > 0
  • Hat MWST auf Auslagen: auslagenmwst > 0
  • Hat Spesen oder Auslagen: ((spesenext > 0) and usespesen) or (auslagenext > 0)
  • Hat zu verrechnende Vorschüsse: vorschussbetrag > 0
  • Hat geleistete Vorschüsse: vorschusseffektiv > 0
  • Geleistete Vorschüsse ist inkl. MWST: vorschusseffektivmwst > 0
  • MWSTBetrag geleistete Vorschüsse: vorschusseffektivmwst

Gruppierungen

  • Leistungen nach Ansatz:
    leistungen->orderby(boldid)->select(x|x.boldid=self.leistungen
    ->orderby(boldid)->select(ansatzext=x.ansatzext)->first.boldid)

    Technisch gesehen macht die Expression eine Liste von Leistungen, bei der jede einzelne einen anderen Ansatz hat.

    Innerhalb eines solchen Bands kann man die Leistungen dann filtern, z.B. mit:

    leistungen->select(bndAnsatz.ansatz=ansatz).wertext->sum
  • Leistungen nach Taetigkeit UND Ansatz:
    leistungen->orderby(boldid)->select(x|x.boldid=self.leistungen
    ->orderby(boldid)->select((ansatzext=x.ansatzext) and (typ=x.typ))
    ->first.boldid)

    Filtern mit:

    leistungen->select(bndTaetigkeit.typ=typ)
    ->select(bndTaetigkeit.ansatz=ansatz).wertext->sum

OCL Expressions für Vorschüsse

  • Auf welchen Rechnungen wird wieviel des Vorschusses abgezogen:
    rechnungvorschusslink->select(betragnetto<>0)->collect
    (rechnungen.nummer.asstring + ': ' + betrag.asstring)->listtostring(' / ')

    Zeigt die Rechnungsnummern und den jeweiligen Betrag, zum Beispiel in einer Listenspalte.

OCL Expressions mit Datumsoperatoren

Informationen zu den OCL Datumsoperatoren finden Sie hier.

  • Heutiges Datum (inkl. Zeit): now
  • Heutiges Datum (ohne Zeitteil): date

Formatierungen von Datums– und Zeitwerten

formatdatetime: Zur Formatierung von Datums- und Zeitwerten kann der Operator formatdatetime verwendet werden. Diese Abfrage z.B. stellt die aktuelle Zeit dar, im Format Stunden.Minuten: now.formatdatetime('hh.mm'). Alle Informationen zu formatdatetime finden Sie im Artikel OCL.

encodedate: Für Datumsabfragen wird der Operator encodeDate verwendet. Beispiel: Ordner mit allen Rechnungen, die im Jahr 2011 erstellt wurden: rechnung->select(datum >= encodeDate(2011,01,01)). Alle Informationen zu encodeDate finden Sie im Artikel OCL.

  • Nicht bezahlte Rechnungen, die älter sind als dreissig Tage:
    rechnung->select(not bezahlt)->select(datumselect(not bezahlt)->select(faelligdatum<=date)
  • Wer (Personenadressen) hat in den nächsten dreissig Tagen Geburtstag:
    person->select(aktiv)->select(geburtsdatum.asstring<>'')->select( ((date<=encodedate(date.year,geburtsdatum.month,geburtsdatum.day)) 
    and(date>=encodedate(date.year,geburtsdatum.month,geburtsdatum.day) .incday(-30)))or((date<=encodedate(date.year+1,geburtsdatum.month, geburtsdatum.day))
    and (date>=encodedate(date.year+1, geburtsdatum.month,geburtsdatum.day).incday(-30))))
  • In den letzten 360 Tagen erfasste Adressen (z.B. für Weihnachtskartencheck):
    adresseintrag->select((creationDateTime >= date.incday(-360)) and (creationDateTime <= date))