Description of Vertec Python functions
Operating mode
Cloud Suite
|ON-PREMISES
Modules
Services & CRM
Budget & Phases
Purchases
Resource Planning
Business Intelligence
The Vertec installation includes a Vertec Python library (module), which is automatically available in the Python scripts after installation and is called vtcapp.
The module has the following methods/features:
Method / feature | description | Sample code | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
__doc__ |
Documentation of a feature. | >>> print vtcapp.__doc__ Interface module to host application. |
||||||||||||||||||||||||||
argobject |
Current Vertec object. This variable is always available, so the call can be made without |
projekt = argobject |
||||||||||||||||||||||||||
checkcreate(class:string): int |
Checks whether there are user rights to create objects of the specified class. Returns 0 or 1 (False, True) |
>>> print vtcapp.checkcreate('Projekt') 1 |
||||||||||||||||||||||||||
checkfeature(featurecode: string): boolean |
Checks whether a particular feature is licensed. The feature codes are according to Vertec feature matrix (e.g. Returns False or True |
>>> vtcapp.checkfeature('fcPhasen') True |
||||||||||||||||||||||||||
convertwordtopdf(wordDoc: string): string |
Converts a Word document of type |
The corresponding Word document must be created and read: in_file = open("C:\<yourPath>\BeispielWordFürEmail.docx", "rb") wordDoc = in_file.read() Conversion: pdfDoc = vtcapp.convertwordtopdf(wordDoc) |
||||||||||||||||||||||||||
createoutlookmail(to, subject, body=”“, cc=”“, bcc=”“, attachments=[], show=True, onBehalfOf=”“)Python method from version 6.4.0.4, which creates to create an email message on the client via Outlook. Works with the Desktop App and the Cloud App. If you are working with the Web App, the sendmail() method can be used.
Optional:
*Keyword means that you can specify the optional values with the parameter as a keyword, e.g. Examples:
Note: Use tables in your Word documents and avoid tab stops, as they cannot be processed in the email.
|
||||||||||||||||||||||||||||
createlist(classname, [list]): list |
As of version 6.1.0.14. With this, a Vertec list can be created, on which OCL can be evaluated.
Starting with version 6.2.0.7 the python methods evalocl(), getwithsql() and getmemberwithsql() automatically return Vertec lists, see Vertec lists. |
mylist = vtcapp.createlist('Projekt') mylist.append(argobject) or liste = vtcapp.createlist("Projekt", vtcapp.evalocl("projekt->select(code.sqllike('A%'))")) liste2 = liste.evalocl("self->select(aktiv)") |
||||||||||||||||||||||||||
createobject(class: string) |
Creates new object of the specified class. | leistung = vtcapp.createobject("OffeneLeistung") |
||||||||||||||||||||||||||
currentlogin(): User |
Current logged in user | >>> bearbeiter = vtcapp.currentlogin() >>> bearbeiter.name Christoph Keller |
||||||||||||||||||||||||||
currentobject |
See the description in the article Python Scripts. | projekt = currentobject |
||||||||||||||||||||||||||
disableevents() |
As of Vertec 6.7.0.7 always use Disabledevents() instead. With |
# Ganzes Script try: vtcapp.disableevents() main() finally: vtcapp.enableevents() # Teil eines Scripts vtcapp.disableevents() rechnung.datum = vtcapp.currentdate() vtcapp.enableevents() |
||||||||||||||||||||||||||
DisabledEvents() |
As of version 6.7.0.7. Must include Within this method, event scripting is turned off, affecting the entire Vertec session (other Vertec sessions or Desktop App are not affected). Used, for example, to modify a certain attribute that would otherwise execute an event. |
with vtcapp.DisabledEvents(): rechnung.datum = vtcapp.currentdate() |
||||||||||||||||||||||||||
evalocl(expression: string): expressiontype |
Evaluate global OCL expression. | projektListe = vtcapp.evalocl("Projekt.allinstances->orderby(code)") |
||||||||||||||||||||||||||
evaloclstring(obj: object, expStr: string): string |
Evaluate OCL expression within a string. Return Value: Fully evaluated string. | >>> vtcapp.evaloclstring(argobject,"Bearbeiter: %name% ist %stufe.asstring%") Bearbeiter: Christoph Keller ist Senior Consultant |
||||||||||||||||||||||||||
evaltovariable(obj: object, ocl: string, varname: string) |
Evaluates an OCL and saves the value in an OCL variable. The variable can then be queried globally with evalocl() .Starting with version 6.1.0.14 you can no longer use “self” as the variable name, because this is a keyword. An error message appears. |
>>> projekt = vtcapp.evalocl("projekt->select(code='TRASTA')->first") >>> vtcapp.evaltovariable(projekt, "rechnungen->first", "varRechnung") >>> vtcapp.evalocl("varRechnung") 15070005, TRASTA >>> projekt.evalocl("varRechnung") 15070005, TRASTA |
||||||||||||||||||||||||||
executefile(command: string, [argumentString: string])Before 6.4.0.10: executefile(path: string) Opens a file on the client (without Web App). The file path must be accessible from the client. Starting with version 6.4.0.10 Command Line Parameters are also supported. You can optionally pass arguments for this. The previous simple case still works. Parameter parsing is as follows:
As of Vertec 6.5.0.11 only files of the type
Examples: pfad = r'S:\Dokumente\Kontakte\Bistro Cooper\Brief.docx' vtcapp.executefile(pfad) The r in front of the path causes control characters to be ignored. Since the backslash is a control character in some combinations for Python, otherwise the path may be misinterpreted or fragmented, resulting in an error. vtcapp.executefile("calc.exe") opens the Windows computer. From 6.4.0.10 also: vtcapp.executefile('notepad++.exe', r'-lpython "C:\Dokumente\Mein Script.py"') |
||||||||||||||||||||||||||||
executefolder(path: string) |
Opens the specified folder on the client (without Web App), e.g. in Windows Explorer. The path must be accessible from the client. If the folder does not exist yet, a message appears whether it should be created: ![]() In a script this has to be queried and the folder has to be created in the code if no message should appear on the interface. This can be done e.g. via the Python module os (does not work with Restricted Scripting). |
import os pfad = r'S:\Dokumente\Kontakte\Bistro Cooper' if os.path.isdir(pfad): vtcapp.executefolder(pfad) The r in front of the path causes control characters to be ignored. Since the backslash is a control character in some combinations for Python, otherwise the path may be misinterpreted or fragmented, resulting in an error. |
||||||||||||||||||||||||||
executereport(rootObj, optarg, reportObj, [saveAs, showDialog, doPrint, showApp]): reportAllows you to call and run Reports based on a report object. For
Examples: Show a Word report for invoice without dialog and without saving a filesave vtcapp.executereport(rech, None, rechTempl, "", showDialog=False) The rechTempl variable must contain the object report for an invoice, the rech variable must contain the invoice object. Starting with version 6.4.0.8 the method returns the report output as a byte string (only if berichObj is a Vertec report definition, not if a path is specified). This can be further processed and, for example, attached as an attachment to an email via rechTempl = vtcapp.evalocl("bericht->select(eintragid='BerichtScriptInvoiceWithList')->first") pdf = vtcapp.executereport(argobject, None, rechTempl, "", showDialog=False) vtcapp.createoutlookmail("mail@adresse.com", "Betreffend", "Inhalt", attachments=[('rechnung.pdf', pdf)]) |
||||||||||||||||||||||||||||
executereport2(rootObj, optarg, reportObj, [saveAs, showDialog, doPrint, showApp]): (report, activity) |
Starting with version 6.4.0.22. Allow calling and executing Reports based on a report object. The method returns a tuple consisting of the report output as a byte string and the corresponding activity. For the description of the parameters see executereport() above. Only a Vertec report definition (class report) can be passed as reportObj, no file paths. For a table of availability with the different systems, see the section further down. |
rechTempl = vtcapp.evalocl("bericht->select(eintragid='BerichtScriptInvoiceWithList')->first") reportdoc, activity = vtcapp.executereport2(argobject, None, rechTempl) The method returns a tuple:
An activity is only created when a report is saved. |
||||||||||||||||||||||||||
execututeurl(url) |
Opens the specified URL on the client (all full-featured apps). The URL must be accessible from the client. The Web App must be a publicly accessible path, access to the local client is not possible. |
For example, to open a website in the browser: vtcapp.executeurl("https://www.vertec.com") Or a Vertec Breadcrumb URL: vtcapp.executeurl("vertec://CK-676/eigene+Projekte-49/COMINSTALL-2880/") the same also works as a short version, in which only the IDs are specified: vtcapp.executeurl("vertec://676/49/2880/") |
||||||||||||||||||||||||||
extractplaintext(file): string |
Used to extract plain text from files. The method checks whether the passed file (bytearray) is one of the following files:
If so, it extracts the text from these files and returns it as plaintext (string). If the byte array does not represent any of the specified file types, or if reading the content fails, for example because the file is invalid or it is a password-protected PDF, a blank string is output. |
Document Storage Internal:
file = argobject.content
text = vtcapp.extractplaintext(file) Document Storage File system/DMS: filename, file = vtcapp.requestfilefromclient("File auswählen", r"C:\Dokumente", "PDF|*.pdf|DOCX|*.docx|EML|*.eml|MIME|*.msg") text = vtcapp.extractplaintext(file) |
||||||||||||||||||||||||||
fetchlinkmembers(objectlist, membername): objectlist |
As of version 6.4. Load the sublist (membername) for a list of objects (objectlist) into memory, and at the same time makes the multilink current, which means that when the link is accessed, the list is not reloaded. Therefore, the call should fetchlinkmembers() immediately prior to the re-use of the list. |
# Loop durch die Phasen von Projekten, welche mindestens eine Phase "erteilt" haben projekte = vtcapp.getwithsql("Projekt", "bold_id IN (SELECT projekt FROM projektphase WHERE status=1)", "") vtcapp.fetchlinkmembers(projekte, "phasen") for projekt in projekte: x = projekt.evalocl("phasen->select(status=1)") |
||||||||||||||||||||||||||
generateinvoicenumber() |
Generates the next Vertec invoice number according to system settings invoice / invoice. |
rech = argobject rech.nummer = vtcapp.generateinvoicenumber() |
||||||||||||||||||||||||||
getcurrentobject() |
Returns the selected object in the tree and can be called from Ocl call operators using OCL call operators. |
|||||||||||||||||||||||||||
getmailattachment(content, idx): bytestring |
From version 6.5. Allow you to download an email attachment of an activity. Returns the contents of the attachment as a byte string. Since the names of the attachments are not necessarily unique, it must be identified by Idx. |
filecontent = vtcapp.getmailattachment(activity.content, 0) outfile.write(filecontent) outfile.close() |
||||||||||||||||||||||||||
getmailattachments(content): list(string) |
As of version 6.5. Return a list of attachment names of an activity. |
filename = vtcapp.getmailattachments(activity.content)[0] outfile = open('C:/data/' + filename, 'wb') |
||||||||||||||||||||||||||
getmemberwithsql(obj: object, membername: string, where: string, order: string): list of objects |
Allows querying members of an object via SQL. |
projekt = argobject li=vtcapp.getmemberwithsql(projekt, "offeneleistungen", "xwertext>200", "") print len(li) >>> 3 |
||||||||||||||||||||||||||
getobjectbyentryid(classname: string, entryid: string): object |
As of version 6.6.0.2. Get the object with the specified class and Entry Id Both parameters must always be specified. If the class If no or more objects are found, an error is thrown. Note: The objects are loaded internally via SQL. Thus, only objects already stored in the database are found. For newly created objects, a |
obj = vtcapp.getobjectbyentryid("Ordner", "FolderPublicProjectBySectors") |
||||||||||||||||||||||||||
getobjectbyid(id: int, string or long*): object |
Gets the object with the specified Internal Id. If the id does not exist, an error is thrown. Note: The objects are loaded internally via SQL. Thus, only objects already stored in the database are found. For newly created objects, a * As of Vertec 6.7.0.4. |
obj = vtcapp.getobjectbyid(62162) or obj = vtcapp.getobjectbyid("62162") |
||||||||||||||||||||||||||
getpropertyvalue(propname: string): value |
Returns the value of the system setting (property) with the specified name. The return value depends on the type of property. |
>>> print vtcapp.getpropertyvalue("firma") LKT Engineering GmbH, Hamburg |
||||||||||||||||||||||||||
getvertecserveraddress(): string |
Returns the address where the Vertec Cloud Server is available from the Internet. |
vtcapp.executeurl(vtcapp.getvertecserveraddress()) |
||||||||||||||||||||||||||
getwithsql(class: string, where: string, order: string, [idfilterfeld: string, objectlist: list]): list of objectsBefore version 6.3.0.8:
|
This global SQL statement is used to filter lists to be filtered directly on the database in a performance-optimized manner (see the article Performance-optimized access to vertec objects). A call via The executing user must have administrator rights or the SQL Query right. For granting temporary administrator rights, the variant of extended user rights is available.
In Vertec versions before 6.7.0.9 (before Firebird 5) lists (not the result list, but the filter criteria list, in the example on the right the |
Without optional filter criteria: projektlist = vtcapp.getwithsql("Projekt", "bold_id IN (SELECT projekt FROM projektphase WHERE status=1)", "code") With optional filter criteria: projekte = argobject.evalocl("eigProjekte") leistungen = vtcapp.getwithsql("OffeneLeistung","", "datum", "projekt", projekte)
|
||||||||||||||||||||||||||
getwithsqlbymember(class: string, member: string, expression: string, order [optional]: string): list of objects |
Allows searching of objects of a class based on a single member comparison for users without SQL privilege (the generic SQL search methods getwithsql and getmemberwithsql are subject to SQL privilege restrictions because they can be called with any SQL WHERE clause.
When the feature is called, the user rights of the current user are checked on the member used for the selection. The user must have class-wide read permission on the member for the search to work. Otherwise, an error occurs. |
projektlist = vtcapp.getwithsqlbymember("Projekt", "Code", "COM%") |
||||||||||||||||||||||||||
importconfigset(xmltext: string/file)As of Vertec 6.7.0.7: importconfigset(xmltext: string/file): string |
Import a config set into Vertec and apply it. Valid XML text is passed as a string or file as a config set. Note the encoding: Until 6.3.0.12 the passed XML text must be in ANSI format, from 6.3.0.13 it must be in UTF-8. As of Vertec 6.7.0.7 the feature returns a string containing possible errors during the import. |
vtcapp.importconfigset("""<?xml version="1.0" encoding="utf-8"?> <configset name="test" author="test"> <requirements /> <references/> <objects/> <settings> <system-setting name="GlobalDokPfad">C:\Dokumente</system-setting> </settings></configset>""") From 6.3.0.13: xml="""<?xml version="1.0" encoding="utf-8"?> <configset name="test" author="test"> <requirements /> <references/> <objects/> <settings> <system-setting name="GlobalDokPfad">C:\Dokumente</system-setting> </settings></configset>""".encode('utf-8') vtcapp.importconfigset(xml) Or as a file: f = open(r"C:\Projekte\Vertec\ConfigSet\ConfigSet.xml") vtcapp.importconfigset(f.read()) |
||||||||||||||||||||||||||
indexall([clean:boolean]) |
As of Vertec 6.8. Re-indexes all objects for Full Text Search. If clean is specified, the existing index is discarded and created. |
vtcapp.indexall() keeps the current index and supplements it with the changed objects. vtcapp.indexall(True) discards the existing index and creates it from scratch. |
||||||||||||||||||||||||||
indexclass(classname: string) |
As of Vertec 6.8. Re-indexes objects of the specified class for Full Text Search. If index configurations have been defined for the class passed with classname or if the System Settings for indexing documents or emails have been set for the class activity, all objects of this class are re-indexed with this feature. If these conditions are not met, then nothing is done. |
vtcapp.indexclass("Project") |
||||||||||||||||||||||||||
indexlist(objectlist) |
As of Vertec 6.8. The method takes a list of objects and re-indexes them for the Full Text Search. Objects for which no index should be written are automatically sorted out. It is also possible to pass a single object as a list. |
Indexing a single object:
vtcapp.indexlist([argobject]) Index list:
liste = argobject.eintraege
vtcapp.indexlist(liste) |
||||||||||||||||||||||||||
As of Vertec 6.8. This method can be used to re-index activities of a specific type for Full Text Search. One of the following values is passed as type:
|
vtcapp.indexactivities(1) re-indexes all documents (Word and PDF). |
|||||||||||||||||||||||||||
indexstatus(): dict |
As of Vertec 6.8. Outputs indexing status information for Full Text Search-text search as a dictionary with the following information:
This information is also output to the System Info in the new Indexing area. Complex operations are |
print vtcapp.indexstatus() {u'OperationRunning': False, u'IsAvailable': True, u'StatusMessage': u'idle'} |
||||||||||||||||||||||||||
indexabort() |
As of Vertec 6.8. Abort a current running indexing for Full Text Search. The queuing of the objects is canceled, already queued objects are indexed. |
vtcapp.indexabort() |
||||||||||||||||||||||||||
inputbox(caption: string, prompt: string[, default: string]): string |
Show simple input field.
The structure of the buttons and the return values works according to article msgbox/inputbox: description of the parameters. |
print vtcapp.inputbox("Titel", "Geben Sie einen Text ein:") >>> test |
||||||||||||||||||||||||||
log(category: string, level: int, msg: string) |
Log Message in Vertec Logging System. Levels available:
|
projekt = argobject leistung = projekt.evalocl("offeneleistungen->first") if leistung: try: leistung.xwertext = 0 except: vtcapp.log("Leistungen anpassen", 30, "Keine Berechtigung") |
||||||||||||||||||||||||||
msgbox(msg: string) |
Show Message Box (versions before 6.0) | Information is used as the title and always Info is used as the dialog type (button / symbol combination). vtcapp.msgbox("Das ist ein Test") |
||||||||||||||||||||||||||
msgbox(text: string [, buttons: int, title: string]): int |
Show Message Box (versions 6.0 and above) The feature supports (optional) arguments for buttons and titles. The structure of the buttons and the return values works according to article msgbox/inputbox: description of the parameters. |
vtcapp.msgbox("Dies ist mein Text", 1, "Vertec") |
||||||||||||||||||||||||||
msgtomime(msgcontent): mimecontent |
From version 6.5.0.11 up to and including version 6.6. Convert
Existing emails as |
import os for act in argobject.eintraege: if act.effpfad and os.path.exists(act.effpfad): try: f = open(act.effpfad, 'rb') act.content = vtcapp.msgtomime(f.read()) except Exception as e: print('error on activity %s: %s' % (act, e)) else: print('path is empty or doesn\'t exist on activity %s' % act) |
||||||||||||||||||||||||||
pdfcombine(doc1:string, doc2:string): string |
As of version 6.5.0.7. This method merges 2 PDF documents. The PDF documents are passed as a byte string. |
newpdf = vtcapp.pdfcombine(pdf1, pdf2) |
||||||||||||||||||||||||||
pdfextract(doc:string, pagefrom:int, pagetill:int): string |
As of version 6.5.0.7. This method extracts one or more pages. The pagefrom and pagetill parameters correspond to the first and last page, respectively, and must be specified. | newpdf = vtcapp.pdfextract(pdf1, pagefrom, pagetill) |
||||||||||||||||||||||||||
pdfpagecount(doc:string): int |
As of version 6.5.0.7. This method specifies the number of pages in the document. | pages = vtcapp.pdfpagecount(pdf1) |
||||||||||||||||||||||||||
processbi(from: String, to: String, generator: String) |
Method for calculating Bi data for the Business Intelligence module. Corresponds to the calculation of the BI data on a Measure and triggers the calculation of the generator given as parameter. From and To dates are specified as a string in the format “Year-Month”. The generator must be specified the same as for the measures, i.e. “<Modulname>.<Generatorname>,” see example. Requires administrator rights. This method can also be automated, for example, via a planned task. To calculate all generators of all active metrics, see the method vtcapp.standardprocessbi() below. |
Example: From January 2018 to February 2020: vtcapp.processbi("2018-01", "2020-02", "OffersGenerator.OffersGenerator") |
||||||||||||||||||||||||||
querycallback(state): dict |
Queries a callback previously registered via registercallback. As soon as the callback has been performed, the feature returns a dictionary with all supplied parameters (including state). As long as the callback has not yet been performed, the function returns a dictionary with all supplied parameters (including state). |
Example code: state=vtcapp.registercallback() # nur zur Demonstration: der Aufruf sollte natürlich über einen OAuth Authentifizierungs Server gehen vtcapp.executeurl("https://myserver.vertec-mobile.com/callback?State=%s&message=ASecretMessage" % state) time.sleep(3.0) # kurz warten bis browser offen values=vtcapp.querycallback(state) print(values["message"]) |
||||||||||||||||||||||||||
readinvoicedocument(binaryData) |
From version 6.5.0.7. The Python feature
*Optional data: will only be output if the QR code contains additional information. The data object can finally be In addition, the feature can also be used in a planned task. |
Example script: kreditorbeleg = open("C:\Users\Name\Desktop\QrCodeBeleg.pdf",'rb').read() belegdaten = vtcapp.readinvoicedocument(kreditorbeleg) lieferanten = vtcapp.getwithsqlbymember("Adresseintrag", "name", belegdaten.Name) lieferant = lieferanten[0] currency = vtcapp.getwithsqlbymember("Waehrung", "bezeichnung", belegdaten.Currency)[0] kreditor=vtcapp.createobject("Kreditor") kreditor.lieferant = lieferant kreditor.belegbild = kreditorbeleg kreditor.esrteilnehmer = belegdaten.Account kreditor.esrcode = belegdaten.Reference kreditor.waehrung = currency kreditor.betragbrutto = belegdaten.Amount if hasattr(belegdaten, 'DocumentNumber'): kreditor.nummer = belegdaten.DocumentNumber if hasattr(belegdaten, 'DocumentDate'): kreditor.datum = belegdaten.DocumentDate if hasattr(belegdaten, 'DueDate'): kreditor.xfaelligdatum = belegdaten.DueDate if len(kreditor.auslagen) == 1: outlay = kreditor.auslagen[0] outlay.anzahl = None outlay.xwertintfwbrutto = belegdaten['Amount'] |
||||||||||||||||||||||||||
registercallback(): string |
Registers a callback on the Cloud Server to transmit an authentication code. This is needed, for example, for authentication via OAuth. The return value is a randomly generated state string, which must be passed in the callback in order for it to be accepted. The callback is executed as an http get request to the Cloud Server, as an example |
Example code: state=vtcapp.registercallback() # nur zur Demonstration: der Aufruf sollte natürlich über einen OAuth Authentifizierungs Server gehen vtcapp.executeurl("https://myserver.vertec-mobile.com/callback?State=%s&message=ASecretMessage" % state) time.sleep(3.0) # kurz warten bis browser offen values=vtcapp.querycallback(state) print(values["message"]) |
||||||||||||||||||||||||||
rendertemplate(templateString, data): unicode string |
As of version 6.3.0.9 there is a generic template engine in Python. It is based on the Jinja2 template engine (http://jinja.pocoo.org). For ease of use in Vertec there is this method. It is also available in Restricted Scripting mode (cloud Cloud Suite) and returns a Unicode string. The To pass the data, the following options are available as further arguments to the feature:
jinja2 package. However, this application is not Cloud Suite compatible and is not recommended. |
The main structures are as follows:
# Beispiel Code für Ausgabe einer Projektliste templateText = """ My own projects =============== {% for proj in projects %} Project: {{ proj.code }}, {{ proj.beschrieb }} {% endfor %} =============== """ projects = vtcapp.evalocl("timSession->first.login.eigProjekte") rendered_text = vtcapp.rendertemplate(templateText, projects = projects) print rendered_text |
||||||||||||||||||||||||||
requestfilefromclient(dialogTitle: string, directory: string, filter: string [, fileName: string]): (filename, file)Before version 6.4.0.22: |
Starting with version 6.3.0.4. The user can select a local file in the client application, which is then transferred to the server and is available as a binary stream for further processing by the Python method.
The method returns a tuple consisting of file names and file contents (before version 6.4.0.22 the method returns a tuple consisting of absolute file path including file names and file contents). The maximum size of the file to be uploaded is 50 MB. If the user clicks on Cancel in the dialog, the error message appears in Python: Web App If a client-side path is specified (parameter The start directory (parameters In versions prior to 6.4.0.8 the file dialog cannot show a custom dialog title. The parameter For the filter, the designation is not shown, it only says “All support types (...)” and then the suffixes individually. |
A simple syntax is also supported:
Version before Vertec 6.3.0.12:
|
||||||||||||||||||||||||||
roundcurrency(amount, currency=None): float |
Rounds the specified amount, taking into account the Project > Use Use rounding rules setting. If a Currency is optionally entered, the value entered on it is also |
Without currency indication: amount = argobject.total vtcapp.roundcurrency(amount) 5105.89 With currency indication:
amount = argobject.total
curr = argobject.waehrung
vtcapp.roundcurrency(amount, curr)
5105.9 |
||||||||||||||||||||||||||
search(term:string, [language:string, similarsearch:boolean, datetimefrom: date, datetimeto:date]): SearchResultPerforms a Full Text Search in the indexed objects.
Returns a Python object of type SearchResult. It contains the following properties:
A search returns a maximum of 500 business objects (SearchResultItems). These are sorted in descending order of relevance (score). |
results = vtcapp.search("keller", "EN", False, datetimeto=vtcapp.currentdate()) for item in results.items: print item, item.fragments With results = vtcapp.search("consulting") projects = results.objects.evalocl("self->select(oclIsTypeOf(Project))")
|
|||||||||||||||||||||||||||
scriptexecute(scripttext, argobject=None) |
Allows calling a Vertec script.
|
proj = vtcapp.getobjectbyentryid("Projekt", "TemplateProject") scripttext = vtcapp.evalocl("scripteintrag->select(bezeichnung='Projekt kopieren')->first.scripttext") vtcapp.scriptexecute(scripttext, proj) |
||||||||||||||||||||||||||
selectaddress()selectphase()selectproject()selectobjectintree() |
From version 6.4.0.21. Allow calling the different search and selection dialogs for addresses, projects, phases and the tree directly from Python. The methods support the following optional keyword arguments:
Return value is the selected object. |
adresse= vtcapp.selectaddress(title="Adressauswahl", classname="Kontakt", filter="vorname like '%S%'") projekt = vtcapp.selectproject(title="Projektauswahl", filter="code like '%S%'") phase= vtcapp.selectphase(title="Phasenauswahl", filter="code like '%S%'") Kontakte = argobject.subordner Kontaktordner = list(Kontakte) Kontaktordner.append(argobject) selected=vtcapp.selectobjectintree("Objekt wählen",Kontaktordner, "Ordner, Kontakt", selectfilter="Kontakt") |
||||||||||||||||||||||||||
selectfromlist (caption: string, text: string, col1caption: string, col2caption: string, default: string, list: list of tuple): string |
Creates a selection dialog according to the specifications.
*) To pre-select a row, the tuples of the list rows must consist of 3 elements. The third element is then the return value when the row is selected (this third column is invisible). Only in this case does the default parameter have an effect: it then preselects the row whose third column corresponds to the specified default. |
$ vtc__000__999_77 îîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîîî |
||||||||||||||||||||||||||
sendfile(file: string, filename: string, [showsavedialog: boolean], [openfile: boolean]): booleanAs of version 6.2. Send a file or a string (as a file) to a client. The method also works in Restrict Scripting mode.
As of Vertec 6.5.0.11 the suppression of a dialog is only possible for the following file types (extensions). Whitelist:
The combination As of version 6.3.0.8 the method has a return value and returns True or False:
Example of a simple project export: projekte = argobject.evalocl("eintraege.list") projektstr = "" for projekt in projekte: projektstr += projekt.code + "\r\n" vtcapp.sendfile(projektstr, 'projekte.txt', True, True) Example of how to send a locally available image: filename = r"C:\Arbeitsverzeichnis\python_editor.png" # opening for [r]eading as [b]inary with open(filename, 'rb') as afile: vtcapp.sendfile(afile, 'aFilenameHere.jpg', True, True) Files should be explicitly closed after use. Otherwise, they will only be closed by the garbage collector or, in case of failure, on the next exception. It is recommended to use |
||||||||||||||||||||||||||||
sendmail(to, subject, body, [cc, bcc, fromSender, attachments])Allows sending emails from Vertec with the requirements described in System Settings Email. This method can be used with all apps.
Optional:
Examples:
vtcapp.sendmail("dokumentation@vertec.com", "Dokumentation", "Dies ist der einfachste Fall")
1. The corresponding Word document must be created and read: in_file = open("C:\<yourPath>\BeispielWordFürEmail.docx", "rb") dataFileData = in_file.read() 2. Use the method to generate the email: vtcapp.sendmail('dokumentation@vertec.com', 'Test E-Mail from Word', dataFileData) |
||||||||||||||||||||||||||||
setpropertyvalue(name, value) |
Sets a system setting. The corresponding name is specified for each system setting. |
vtcapp.setpropertyvalue('Sperrdatum', vtcapp.incmonth(vtcapp.currentdate(), -1)) |
||||||||||||||||||||||||||
setresourceplanvalue
|
Only Vertec versions before 6.6. From Vertec version 6.6 onward, use the Sets a resource plan value.
|
bearbeiter = vtcapp.currentlogin() projekt = argobject vtcapp.setresourceplanvalue(bearbeiter, projekt, None, vtcapp.firstdayofmonth(vtcapp.currentdate()), 0, 240) |
||||||||||||||||||||||||||
showcustomdialog(dialog definition, initial values) |
Dialog function with which dialogs can be defined in Python scripts and shown by the script. Available from version 6.1. |
a detailed description can be found in the article about the Python dialogs. | ||||||||||||||||||||||||||
showdetailform(obj: object) |
Displays the detail view of the object in a new tab. | leistung = vtcapp.createobject("Offeneleistung") vtcapp.showdetailform(leistung) |
||||||||||||||||||||||||||
standardprocessbi() |
Method for calculating Bi data for the Business Intelligence module. Corresponds to the execution of the planned task supplied by default and triggers the calculation of all generators on all active measures. Requires administrator rights. To calculate individual generators, see the method vtcapp.processbi() above. |
vtcapp.standardprocessbi() |
||||||||||||||||||||||||||
strtominutes(string): integer |
Translates a string to a minute value (integer), taking into account the current set system setting setting. | Display minutes is hours:minutes: print vtcapp.strtominutes('1:30') >>> 90 print vtcapp.strtominutes('1.50') >>> 110 Display minutes is hours.Decimal: print vtcapp.strtominutes('1.50') >>> 90 |
||||||||||||||||||||||||||
sqldateliteral(date: date): string |
This method returns the correct date format for SQL queries, depending on the database server used, which is then converted into a getwithsql statement can be built in. |
aktivitaeten = vtcapp.getwithsql('Aktivitaet', 'datum = %s' % vtcapp.sqldateliteral(vtcapp.currentdate()), '') for akt in aktivitaeten: print akt >>> Support, 30.05.2017, Support Frau Müller Verkauf, 30.05.2017, Rechnung mit Leistungsliste (Word) Verkauf, 30.05.2017, Rechnung mit Leistungsliste (Word) Verkauf, 30.05.2017, Offerte (Word) Verkauf, 30.05.2017, Offerte (Word) Marketing, 30.05.2017, Informationen bezüglich KZU >>> |
||||||||||||||||||||||||||
sqlwhere(where: string): string |
Creates a SQL WHERE clause matching the current used database server, which is then placed in a getwithsql Statement can be incorporated. |
whereclause = vtcapp.sqlwhere("standardadresse like 'Dachsweg%'") leistungen = vtcapp.sqlwherebetweendate('datum', vtcapp.firstdayofmonth(heute), heute) print leistungen, whereclause adressen = vtcapp.getwithsql("Adresseintrag", whereclause, "bold_id") for adresse in adressen: print adresse >>> upper(standardadresse) starting with 'DACHSWEG' Comtelsat AG Comtelsat AG, Lanz André Comtelsat AG, Huber Thomas >>> |
||||||||||||||||||||||||||
query:string, from: date, to: date): string |
Creates a SQL between clause with a date interval corresponding to the database server current in use, which is then |
heute = vtcapp.currentdate() whereclause = vtcapp.sqlwherebetweendate('datum', vtcapp.firstdayofmonth(heute), heute) print whereclause leistungen = vtcapp.getwithsql("Leistung", whereclause, "datum") for leistung in leistungen: print leistung >>> datum between '01.05.2017' and '30.05.2017' COMINSTALL, 09.05.2017, BER Besprechung mit Hr. Müller COMINSTALL, 16.05.2017, TM Telefon mit Hr. Müller >>> |
||||||||||||||||||||||||||
syncpayments() |
Starting with version 6.4.0.22. Perform a global payment import. If no customer interface with payment import is installed, the method reports an error. |
vtcapp.syncpayments() For example, the method can be registered as a planned task. |
||||||||||||||||||||||||||
SystemContext() |
As of version 6.6. Activates Extended user rights within the script.
|
with vtcapp.SystemContext(): ...Code der vom Systemcontext profitiert. |
||||||||||||||||||||||||||
translate(txt: string[, language:string]): string |
Translates a GUI text into the current Vertec language. As of version 6.5.0.20, an optional parameter for the target language of the translation can be used. |
The current Vertec language is English: >>> vtcapp.translate("Leistung") Service From version 6.5.0.20: >>> vtcapp.translate('Offer', 'DD') Angebot |
||||||||||||||||||||||||||
updatedatabase() |
Saves changes to the database. | vtcapp.updatedatabase() |
||||||||||||||||||||||||||
validateobjects() |
Validates rebuild objects. If they do not violate any rules, they are no longer invalid afterwards. |
vtcapp.validateobjects() |
||||||||||||||||||||||||||
versiontointeger(versionstring): int |
Converts a Vertec version string to a number suitable for comparing different versions. | Bsp: "5.5.0.67" wird in 550067 umgesetzt, "5.5" in 550000, "5" in 500000 |
The following date functions are available. They are all located in the vtcapp module.
feature | Explanation | Example | From version |
---|---|---|---|
currentdate(): date |
Returns the current date. | >>> vtcapp.currentdate() 2017-01-23 |
6.1.0.10 |
currentdatetime(): datetime |
Returns the current date and time. | >>> vtcapp.currentdatetime() 2017-01-23 15:01:12.880000 |
6.1.0.10 |
datetostr(date): string |
Converts a date to a string and returns it according to the country settings. | For example, in Australian English: >>> print vtcapp.strtodate('13/06/17') 2017-06-13 >>> print vtcapp.datetostr(datum) 13/06/2017 |
6.1.0.14 |
datetostrgerman(date): string |
Converts a date to a string and returns it in German date format. It sometimes needs German date values in some locations in scripts, regardless of current region settings (see e.g. from/to arguments in groupperformance operators). |
>>> vtcapp.datetostrgerman(argobject.evalocl('creationdatetime')) 13.10.2016 |
6.2 |
firstdayofmonth(date): date |
Returns the date of the first day of the same month | >>> vtcapp.firstdayofmonth(vtcapp.currentdate()) 2018-03-01 |
5.7 |
firstdayofyear(date): date |
Returns the date of the first day of the same year | >>> vtcapp.firstdayofyear(vtcapp.currentdate()) 2018-01-01 |
5.7 |
formatminutes(integer): string |
Returns hour-minute display as settings in Vertec | >>> vtcapp.formatminutes(argobject.minutenext) 1:00 |
5.7 |
incday(date, integer): date |
Increments the day (+ or -) and returns the new date | >>> vtcapp.incday(vtcapp.currentdate(), 1) 2018-03-17 |
5.7 |
incminute(datetime, integer): datetime |
Increments minutes (+ or -) and returns a new date. The date that is passed must be in datetime format, i.e. have a time fraction. |
Adds 4 hours to the current time: >>> vtcapp.incminute(vtcapp.currentdatetime(), 240) 2018-03-16 18:43:44.958000 |
5.7 |
incmonth(date, integer): date |
Increments month (+ or -) and returns the new date Note: If the date is at the end of the month and the respective months have a different quantity of days, the last day of the month is used. Example: |
>>> vtcapp.incmonth(vtcapp.currentdate(), -1) 2018-02-16 |
5.7 |
incyear(date, integer): date |
Increments the year (+ or -) and returns the new date | >>> vtcapp.incyear(vtcapp.currentdate(), -1) 2017-03-16 |
5.7 |
lastdayofmonth(date): date |
Returns the date of the last day of the same month | >>> vtcapp.lastdayofmonth(vtcapp.currentdate()) 2018-03-31 |
5.7 |
lastdayofyear(date): date |
Returns the date of the last day in the same year | >>> vtcapp.lastdayofyear(vtcapp.currentdate()) 2018-12-31 |
5.7 |
ocldate(date): string |
Returns OCL encodedate string based on a date value | >>> import datetime >>> vtcapp.ocldate(datetime.date(2018,01,31)) encodedate(2018,1,31) |
5.7 |
strtodate(string): datetime |
Interprets a date string according to Windows locale settings (see notes on using strtodate below). | print vtcapp.strtodate('1.10.17') >>> 2017-10-01 00:00:00 |
5.7 |
thismonday(date): date |
Returns the date of Monday in the same week | >>> vtcapp.thismonday(vtcapp.currentdate()) 2018-03-12 |
5.7 |
The use of strtodate is tricky because the string is interpreted according to the Windows locale. For example, the expression vtcapp.strtodate('31.01.2017') returns an error if it is not a German locale.
The Python date function datetime.date(year, month, day) should always be used in the code (see the example above). However, if you want to query the user for a specific date via an input box, you can do this by presenting the user with a suggested date in the correct format, which the user can modify accordingly.
For this, the date is formatted according to local country settings (vtcapp.datetostr..
):
# Frage den Benutzer nach dem Datum. Das Datum wird gemäss Windows-locale dargestellt. res = vtcapp.inputbox('Vertec', 'Datum für die Berechnung', vtcapp.datetostr(vtcapp.currentdate())) print vtcapp.strtodate(res)
The datetostr()
method was introduced in Vertec version 6.1.0.14. In earlier Vertec versions, the date can be formatted with strftime
according to local country settings:
import datetime # Frage den Benutzer nach dem Datum. Datum gemäss Windows-locale dargestellt. res = vtcapp.inputbox('Vertec', 'Datum für die Berechnung', datetime.date.today().strftime('%x')) print vtcapp.strtodate(res).date()
executereport(rootObj, optarg, reportObj, [saveAs, showDialog, doPrint, showApp]) | ||||||||
---|---|---|---|---|---|---|---|---|
Reporting system | ReportObj | saveAs | showDialog | doPrint | showApp | Desktop | Cloud | Web |
Office-generated legacy reports (Word, Excel) | Report object in Vertec
or Path to the Office template on the file system. |
If an empty string is specified or the argument is omitted, no file is saved. |
True or False Default=False |
True or False Default=False No longer considered in versions 6.6.0.8 or later. |
True or False
In versions before 6.6.0.8 disregarded if doPrint = True. In this case, the report is always shown. disregarded if report is not saved. In this case, the report is always shown. |
x | x | |
Vertec-generated legacy word reports | Report object in Vertec | Dito | Dito | Not included | Not included | x | x | x |
Office reports (Word, Excel, PDF) | Report object in Vertec | Dito | Dito | Not included | True or False
Disregarded if report is not saved. In this case, the report is always shown. |
x | x | x |
executereport2(rootObj, optarg, reportObj, [saveAs, showDialog, doPrint, showApp]) | ||||||||
---|---|---|---|---|---|---|---|---|
Reporting system | ReportObj | saveAs | showDialog | doPrint | showApp | Desktop | Cloud | Web |
Office-generated legacy reports (Word, Excel) | Report object in Vertec No paths. |
If an empty string is specified or the argument is omitted, no file is saved. If no file is saved, no activity is created. |
True or False
Default=False |
True or False Default=False No longer considered in versions 6.6.0.8 or later. |
True or False
In versions before 6.6.0.8 disregarded if doPrint = True. In this case, the report is always shown. disregarded if report is not saved. In this case, the report is always shown. |
x | x | |
Vertec-generated legacy word reports | Report object in Vertec | Dito | Dito | Not included | Not included | x | x | x |
Office reports (Word, Excel, PDF) | Report object in Vertec | Dito | Dito | Not included | True or False
Disregarded if report is not saved. In this case, the report is always shown. |
x | x | x |
italics: optional parameter
There is a Vertec module called vtcextensions for handling extensions.
It is also available in Restricted Scripting mode starting with version 6.3 and includes the following methods:
Method / feature | description | Example code |
---|---|---|
GetExtension(art:string) or getextension(art:string): extension |
Returns a reference to the extension of the specified type. | import vtcextensions |
CreateVtcExtensionHost(extension:string): host | With this method, the host used for the extensions (example: __init__(self, host)) can be simulated in the code for testing purposes. When using the extensions via Vertec, this happens automatically. |
import vtcextensions |
# Buchungen # Wir fragen den Benutzer, ob er in die Buchhaltung buchen will. Vielleicht will er auch einfach nur die Buchungen anschauen. if vtcapp.msgbox("Die Buchungen wurden erstellt und als .txt Datei am üblichen Ort dokumentiert. Möchten Sie die Buchungen jetzt übertragen?",3, "Vertec") == 6: # Buchungen werden übertragen. ext = vtcextensions.getextension("DEBI") ext.StartLohnBuchung() for rec in reclist: ext.LohnBuchungsZeile(rec.Mandant, rec.Personalnummer, rec.Lohnartnummer, rec.Text, rec.GueltigVon, rec.GueltigBis, rec.Anzahl) # Buchungen werden hier abgesetzt. Vor der Buchung wird überprüft, # ob diese Zeile bereits vorhanden ist, wenn ja, überspringen. ext.EndLohnBuchung()
As of version 6.3.0.2 there is a Vertec module called ziputils, which allows you to compress files by generating ZIP files in Python.
It is also available in Resctict Scripting mode and includes the following methods:
Method / feature | description | Sample code |
---|---|---|
createzip(contentlist: tuples): bytestream | As of version 6.3.0.2. Compress a list of tuples (filename,content) into a ZIP file and return it as a bytestream. This can easily be saved/downloaded with Filename.zip . |
import ziputils zip = ziputils.createzip([('file.txt', 'Hallo das ist ein Text')]) vtcapp.sendfile(zip, 'ziptest.zip', True) |
Starting with version 6.5.0.14 the following 3 features are available:
readnames(zipcontent)
returns a list of the file names contained in the ZIP file. If the ZIP file has a folder structure, the names contain the paths separated by slashes (/).readbyname(zipcontent, name)
reads a file from the ZIP file based on its name.readbyidx(zipcontent, idx)
reads a file based on its index in the name list.As of version 6.6, the Python module vtcplanningcore is available for Resource Planning with the following methods:
Method / feature | description |
---|---|
increment_interval_date(date, increment): date | Feature for incrementing and decrementing period start data. Increment the specified date by the increment specified quantity of intervals. A negative quantity of intervals can be specified for decrementing. |
get_planning_level(): string | Returns the planning layer as a string. Possible results: 'Projekt' or 'ProjektPhase' . |
get_planning_interval_type(): string | Returns the planning interval as a string. Possible results: 'day' , 'week' or 'month' . |
show_bulk_planning_dialog(left_obj, right_obj) | Displays a dialog for efficiently setting multiple planning values for the specified objects. The order in which the objects are provided does not play Role, but the caller must ensure that one of them is an object of type |
For the implementation of the Resource Planning lists, this module also includes a ResourcePlanningProvider
Class available which allows reading and setting of plan data and which can be used in a List Controller.
A ResourcePlanningProvider
Object is created for a list of entries (users, projects or phases) and a time period. The provider then loads all planning data for these source objects and for the specified period. Subsequently, the planned values can be retrieved or set.
A budgeted value in ResourcePlanningProvider
always applies to 2 entries and a date, e.g. for the user “Christoph Keller,” the project “AZZ2” and the month starting with 01.08.2022.
The one entry (the source entry, sourceEntry
) must come from the list of entries specified at the time of initialization. The other entry is called “opposite” (othersideEntry
).
The following methods are available on a ResourcePlanningProvider object:
ResourcePlanningProvider(sourceEntries, start, end) | Constructor, creates a planning provider and loads the planning data for the specified objects and period. |
add_entry(obj) | Adds a new object to the provider’s sourceEntries list. |
add_otherside_entry(obj) | Adds a new object temporarily to the list of otherside entries. This allows this object to be set_planned_minutes() Budgeted values can be entered. |
get_planned_minutes(date, sourceEntry, othersideEntry, subscriber): int | Returns the planned time in minutes for the planning cell with interval date date and the two entries indicated. If no plan data is available, None returned. |
set_planned_minutes(date, sourceEntry, othersideEntry, value) | Sets the planned time in minutes for the planning cell with interval date date and the specified entries.Setting a None Value as value removes the plan data for this cell. |
has_write_access(sourceEntry, othersideEntry, subscriber): boolean | Checks whether the two objects and the date interval have write permissions. |
get_planned_minutes_aggregated (source_entry, otherside_entry, dateFrom, dateTo=None, subscriber=None): int | Returns the aggregated scheduled time for the two specified records in the specified period.
None return if no budgeted values with the specified criteria are found. |
get_net_capacity_minutes(self, worker, dateFrom, dateTo=None, subscriber=None): int | Net capacity in minutes per user.
|
get_custom_net_capacity_minutes(self, worker, dateFrom, dateTo=None, subscriber=None): int | As of Vertec 6.7.0.5. Net Capacity in minutes per user based on the system setting Adjusted Net Capacity (Percentage). Gives |
get_gross_capacity_minutes(self, worker, dateFrom, dateTo=None, subscriber=None): int | Gross capacity in minutes per user.
|
get_remaining_capacity_minutes(worker, dateFrom, dateTo=None, subscriber=None): int | Remaining free capacity in minutes for a given user and a given date range (net_capacity – planned_minutes).
|
get_custom_remaining_capacity_minutes(self,worker, dateFrom, dateTo=None, subscriber=None): int | As of Vertec 6.7.0.5. Remain free capacity in minutes for a specific user and a specific date range, taking into account the system setting Adjusted Net Capacity (Percentage). Gives |
get_otherside_entries(subscriber): list of entries | Returns the list of entries for which plan data already exists, based on the sourceEntries objects specified in the constructor. |
generate_date_range(start, end) | Returns a list of date values for scheduling intervals of start to end . Depend on the system-wide setting of the planning interval (months, weeks, days). |
get_start_preceding_interval(): date | Returns the date of the interval preceding the start interval. |
get_column_title_by_date(date): string | Returns the appropriate column title if the date value for a specific planning interval is specified. |
ResourcePlanningProviders are commonly used in list controllers and custom renderers for planning lists. The list controller instantiates a planning provider, which is then used to show and set the values in plan cells.
The vtcplanningcore module is also available as a Python Stub File. It says vtcplanningcore.py
and is stored like the other Stub Files in the PythonStubs subfolder in the Vertec installation directory.
From version 6.6. there is the Python module vtcplanning
, which provides standard implementations of list controllers for Resource Planning. List Controllers
These all have one initialize_with_period(start, end, interval)
Method which is called by the Vertec core and specifies the planning period and the planning interval to be displayed.
To ensure that a planning list that starts on a new interval (e.g. current month) is not completely empty, the list controllers also load planning data for an interval before the specified start date.
This means that if August – October is specified as the planning period (planning interval “month”) then row objects are also displayed which have planning data in July, but not in August-October.
The Timetables are based on a single object and show one row for each planned opposite object. The columns correspond to the scheduled time intervals.
Time tables can also be shown as read-only sum tables based on a list.
We provide the following list controller classes in the Python module vtcplanning:
list controller | description |
---|---|
vtcplanning.SingleObjectTimeTableController | Used to plan on individual objects (check The controller can handle the different classes (project, project phase, AbstractWorker, project user or PlanningWorker), the same controller can always be specified. |
vtcplanning.ReadonlySingleObjectTimeTableController | Based on a single object, but read-only, not for scheduling. Used for timesheets on single objects that cannot be scheduled. |
vtcplanning.ReadonlyProjectsSingleObjectTimeTableController | For read-only project timesheets on individual objects. Use to show project totals if the planning level is phases. |
vtcplanning.ReadonlyPhasesSingleObjectTimeTableController | For read-only phase time tables on individual objects. Use to show phase totals if the planning type is Processor Phase Assignment. |
vtcplanning.ReadonlyContainerTimeTableController | For read-only timesheets on lists (check Für Listen anzeigen? is set).Used for Total Timesheets. |
vtcplanning.ReadonlyOtherSideContainerTimeTableController | For read-only timesheets on lists (check Für Listen anzeigen? is set).Use for Total Timesheets to show the totals of the opposite side on a list of objects (e.g. editor totals on a project list). |
vtcplanning.ReadonlyPhasesContainerTimeTableController | For read-only timesheets on lists (check Für Listen anzeigen? is set) to show sums of phases on a list of projects or users if the planning level is project (in this case, the normal list controllers on projects would not be shown). |
Starting from a list of entries (AbstractWorker, project or phases), a Resource Planning Pivot Table can be displayed. The pivot table shows the entries as columns and the planned opposing entries as rows. This makes it possible to enter planning data for new opposing entries via star-row.
The following list controller classes are available to implement pivot table views:
list controller | description |
---|---|
vtcplanning.RegularPivotTableController | For pivot tables with the entries in the list as rows and the opposite side as columns. Use to plan on a list (check The controller can handle the different classes (project, project phase, AbstractWorker, project user or PlanningWorker), the same controller can always be specified. |
vtcplanning.MirroredPivotTableController | For pivot tables with the entries in the list as columns and the opposite side as rows. Use to plan on a list (check a star line can be shown in this list to add new objects to be planned. More detailed information can be found here. The controller can handle the different classes (project, project phase, AbstractWorker, project user or PlanningWorker), the same controller can always be specified. |
vtcplanning.ReadonlyRegularPivotTableController | Used to show project user PivotTables when the planning level Phasen is, with the entries of the list as rows and the opposite side as columns. |
vtcplanning.ReadonlyMirroredPivotTableController | Used to show project user pivot tables when the planning level Phasen is, with the entries of the list as columns and the opposite side as rows. |
vtcplanning.RegularSingleObjectPivotTableController | Used to also plan on a single project in pivot tables. Display a pivot table with the single entry as a row and the opposite side as columns. |
vtcplanning.MirroredSingleObjectPivotTableController | Used to also plan on a single project in pivot tables. Show a pivot table with the single entry as a column and the opposite side as rows. |
To match this, the following Custom Renderer are available for use in the resource planning tables. All of these renderers can be used in the list settings in two ways:
%col%
Ja
Displays the value in the cell that matches the row/column combination.
Checkbox Dynamic: Nein
Displays the summed value across all columns per row.
Custom renderer | description |
---|---|
vtcplanning.PlannedMinutesRenderer | Renderer for the planning times. Allows you to enter the planned values in the individual cells. |
vtcplanning.NetCapacityRenderer | Renderer to show the net availability of users. |
vtcplanning.CustomNetCapacityRenderer | As of Vertec 6.7.0.5. Show the net availability of users taking into account the system setting setting. |
vtcplanning.GrossCapacityRenderer | Renderer to show the gross availability of users. |
vtcplanning.RemainingCapacityRenderer | Renderer to show the remaining availability of users. |
vtcplanning.CustomRemainingCapacityRenderer | As of Vertec 6.7.0.5. Show the remaining availability of users taking into account the system setting Adjusted Net Capacity (Percentage). |
The vtcplanning module is also available as a Python Stub File. It says vtcplanning.py
and is stored like the other Stub Files in the PythonStubs subfolder in the Vertec installation directory.
As of Vertec 6.7.0.7 there is the Python module vtccom, which implements the possibilities of COM forwarding.
This includes the feature vtccom.createobject(identifier)
, which provides a forwarding proxy for the COM server on the client.
For more information, see the article on Com forwarding.
From version 6.8 there is the Python module vtcauth
to be able to use OAuth authentication in arbitrary extensions and Python scripts in Vertec.
This contains a decorator authenticate to which a config dictionary is passed as argument. The parameters that can be passed in the config dictionary are the following in vtcauth
existing instance variables:
prefix |
a prefix can be used to automatically read and save the following values from Vertec Property:
The properties, including prefix, must be named exactly as follows: If a prefix is specified in the config, these values are automatically read from or saved in the Vertec properties. If no prefix is specified, these configurations must be specified individually in the config. |
logging |
Default value is |
client_id |
Corresponds to the Application ID. Must be specified only if not covered via prefix. |
client_secret |
Corresponds to the Application Secret. Only to be specified if not covered via prefix. |
individual_login |
Default value is |
scope |
Defines the amount of access the application requires to a user’s resources. Standard (MS Graph): "https://graph.microsoft.com/.default offline_access" Requires only if OAuth is to be used for another endpoint. |
response_mode |
Default value is |
redirect_uri |
Corresponds to the Vertec callback address and cannot be overridden with the config. |
tenant_id |
Required when using MS Graph and must be specified with the config accordingly. |
auth_base_url |
Authorization endpoint. Standard (MS Graph): "https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize" Requires only if OAuth is to be used for another endpoint. |
token_endpoint |
Endpoint for the tokens. Designed for MS Graph by default: "https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token" Requires only if OAuth is to be used for another endpoint. |
access_token |
AccessToken. Must be specified only if not covered via prefix. |
refresh_token |
RefreshToken. Only to be specified if not covered via prefix. |
The minimum call (for MS Graph) in a script looks like this:
from vtcauth import authenticate # config example using vertec properties with prefix config_prefix = { "tenant_id":"xxxxxxxxxxxxxxxxxxx.onmicrosoft.com", "prefix":"DmsSharePoint", "logging":True,} # using decorator from vtcauth with config_prefix dict @authenticate(config_prefix)
The entire OAuth authentication takes place via the decorator @authenticate(config_prefix)
instead.
If the user is not already logged in to the targeted application, he has one minute to authenticate. If he does not log in to the open login dialog of the targeted product within one minute, there is a timeout.
If the token is expired or invalid, a TokenExpiredException
This triggers the OAuth mechanism to fetch new tokens. If a RefreshToken is present and valid, the AccessToken is fetched with the RefreshToken. The exception can be executed a maximum of three times in the same call (by default), after which an error is thrown.
In this example, the first 10 sites of a SharePoint are displayed (MS Graph with OAuth authentication):
import requests from vtcauth import authenticate, TokenExpiredException # config example using vertec properties with prefix config_prefix = { "tenant_id":"xxxxxxxxxxxxxxxxxxx.onmicrosoft.com", "prefix":"DmsSharePoint", "logging":True,} class SharePointSiteQuery: # using decorator from vtcauth with config_prefix dict @authenticate(config_prefix) def get_sites_with_prefix_config(self): return self.get_sites() def get_sites(self): headers = { "Authorization": "Bearer {}".format(self.access_token), "Content-Type": "application/json",} response = requests.get("https://graph.microsoft.com/v1.0/sites?search=*&$top=10", headers=headers) if response.ok: content = response.json() elif: response.status_code == requests.codes.unauthorized: raise TokenExpiredException else: print(response.json().get("error").get("code") + ' - ' + response.json().get("error").get("message")) query = SharePointSiteQuery() query.get_sites_with_prefix_config()
The Vertec SharePoint Extension now also uses the module vtcauth internally. This does not change the operation of the extension.
The module vtcauth
is also supplied as a Stub File.
For individual objects, the following methods are available:
Method/Feature | description | Sample code |
---|---|---|
addtag(tagname) |
As of version 6.1.0.10. Set a tag on the object. For more information, see the article Tag on user records. |
argobject.addtag('mytag') |
checkright(right: string, membername: string): boolean |
Checks whether the logged-in user has the specified right on the specified member name. Possible rights are: 'read’, 'write’, 'create’, 'delete’, 'execute’ Return value: 1 = True, 0 = False |
obj = argobject if obj.checkright('read', 'offeneleistung'): ... |
delete() |
Deletes the object in Vertec |
obj.delete() |
evalocl(OCL:string) |
Evaluates an OCL expression on the object. Before 6.1.0.10 this was called eval() on the individual object. Then the method was aligned to the global method so that it has the same name everywhere. In 6.1.0.10 and later you should always use evalocl(). |
projektcode = argobject.evalocl("code") |
getattr(object, name[, default]) |
Returns the value of a member. getattr(obj, “first name”) is equivalent to obj.vorname. Sometimes you need getattr because you get a member as a parameter in a method, for example, and then query it like this. If there is no member of this name on the object, the method returns the default if one is specified. Otherwise, there is an AttributeError. |
getattr(obj, "vorname", "") projekt = argobject if hasattr(projekt, "offeneleistungen"): liste = getattr(projekt, "offeneleistungen") for leistung in liste: print leistung.text |
getkeystring(key): stringgetkeybool(key): booleangetkeycurr(key): currencygetkeyint(key): integergetkeydate(key): datetime |
As of version 6.1.0.10. These methods are used to access the values stored as key values. Details can be found in the article Key values on user entries. |
>>> argobject.getkeydate('datum') 2017-02-03 00:00:00 |
getmemfootprint(): integer |
As of version 5.8. Return the quantity of bytes that the object occupies in memory (Memory Footprint). The value is determined as follows: Instance of the object + Sum of instances of all members + Size of the value of each member (for strings the length) + MemFootPrint of all owned linked objects (e.g. phases of the project). It should be noted that this is an approximation, since the boundary of what must be counted for an object cannot be drawn exactly. |
The following script displays the memory requirements of all projects in the system: r = vtcapp.evalocl("projekt") for projekt in r: print projekt.code+' '+str(projekt.getmemfootprint()) |
getmlvalue(membername:string, language:string): value |
The so-called multilanguage attributes (MLStrings) can be queried via this method.
Multilanguage attributes are:
To set such an attribute, the method setmlvalue() can be used. |
taetigkeit = argobject print taetigkeit.getmlvalue("text", "FR") >>> Vacances >>> If the member is queried normally, the return value always corresponds to the current Vertec language: print taetigkeit.text >>> Ferien/Urlaub >>> |
hasattr(object, name): boolean |
Checks whether an object has a corresponding member. |
obj = adresse if hasattr(obj, "vorname"): print obj.vorname |
hastag(tagname): boolean |
As of version 6.1.0.10. Check whether an object has set a corresponding tag. For more information, see the article Tags on user entries. |
obj = argobject if obj.hastag('mytag'): ... |
istypeof(Classname:string)or IsTypeOf(Classname:string): boolean |
Checks whether the object is of type Classname. True or False. |
obj = argobject # das aktuelle Objekt ist eine Firma in Vertec obj.IsTypeOf("Projekt") >>> 0 # false obj.istypeof("Firma") >>> 1 # true |
linkto(target, Role) |
Makes a link type from the object to the passed object (target) with the specified Role. |
For detailed information on this topic, see the article Operators and methods for links. |
objid |
Returns the internal ID of the object. |
>>> argobject.objid 3011 |
removetag(tagname) |
As of version 6.1.0.10. Delete the corresponding tag from this object. For more information, see the article Tags on user entries. |
argobject.removetag('mytag') |
setattr(object, name, value) |
Describes the name attribute of the object object with the value value. For example, you can loop through the custom field items of an object and use the found attribute names to describe the attributes. |
This code creates a new object of the same type as the argobject and copies the contents of all additional fields to the new object. source = argobject target = vtcapp.createobject(source.evalocl('ocltype.asstring')) zusatzfelder = source.zusatzfelder for z in zusatzfelder: zName = z.metazusatzfeld.fieldname Now you know the name of the additional field, but if you address it with setattr(target, zName, getattr(source, zName)) vtcapp.showdetailform(target) |
setkeyvalue(key, value) |
As of version 6.1.0.10. With this method, customer-specific values are stored as key values on user entries. These values can be accessed later via the |
argobject.setkeyvalue("datum", "2017-02-03") |
setmemberoutofdate(membername:string) |
If a value is to be read freshly from database, the field out of date must be set. This method does the same as the Notif for a Modified message. |
proj = argobject proj.setmemberoutofdate('code') ensures that the next time you access Projekt.code, this value is loaded freshly from the database. |
setmlvalue(membername:string, value:string, language:string) |
The so-called multilanguage attributes (MLStrings, multilingual attributes) can be set via this method.
Multilanguage attributes are:
To retrieve such an attribute, the method getmlvalue() can be used. |
taetigkeit = argobject taetigkeit.setmlvalue("text", "Vacanze", "IT") |
unlink(target, Role) |
Removes the link from the object to the passed object (target) with the specified link role. |
For detailed information on this topic, see the article Operators and methods for links. |
unload(): None |
Removes the object from the Vertec object store. This method was introduced solely to control memory usage during data migrations. It should be used with caution, as subsequent accesses to the unloaded object can result in errors. |
|
Access to the classname
works in Python only via OCL:
obj.evalocl('ocltype.asstring')
Method/Feature | description | Sample code |
---|---|---|
entrytypeslookup(typidx, phase=None): List of project entry types |
Returns a list of project entry types for the project (and optionally a phase) typeidx: 0: service types, 1: types of expenses, 2: types of expenses. |
proj = argobject taetigkeitenliste = proj.entrytypeslookup(0, None) |
phaseslookup(user, entrytype=None): List of project phases |
Returns a list of project phases for the specified user (and optionally a project entry type). |
proj = argobject bearbeiter= vtcapp.currentlogin() phasenliste = proj.phaseslookup(bearbeiter, None) |
project managerisassigned(user): boolean |
Specifies whether the specified user is authorized to create services etc. on this project. |
proj = argobject bearbeiter= vtcapp.currentlogin() if proj.projektbearbeiterisassigned(bearbeiter): ... |
setresourceplanvalue(worker, date, value) |
As of Vertec 6.6. Allow the setting of resource plan values when the is set to project.
|
bearb = vtcapp.currentlogin() projekt = argobject projekt.setresourceplanvalue(bearb, vtcapp.strtodate('15.05.2023'), 180) |
The following methods are available on Abstractworker, project users and Planningworker:
Method/Feature | description | Example code |
---|---|---|
setresourceplanvalue(project_or_phase, date, value) |
Vertec 6.6 and later. Allows the setting of resource plan values.
|
bearb = vtcapp.currentlogin() projekt = argobject bearb.setresourceplanvalue(projekt, vtcapp.strtodate('15.05.2023'), 180) |
On users, the following methods are available:
Method/Feature | description | Example code |
---|---|---|
setnotification(category, text, link) |
As of Vertec 6.6. Add a Notification (Notification) to the user with specified category, text and optionally linked User Entry. If a notification with the same category and the same linked object already exists on the user, the text is updated.
|
aktivitaet = argobject zustaendig = aktivitaet.zustaendig if zustaendig and not aktivitaet.erledigt: zustaendig.setnotification('pending_activity', aktivitaet.titel, aktivitaet) |
deletenotification(category, link) | As of Vertec 6.6. Delete the Notification (Notification) on the user with the corresponding category and linked object. If no corresponding notification is found, nothing happens. No error message appears. | aktivitaet = argobject zustaendig = aktivitaet.zustaendig if zustaendig and aktivitaet.erledigt: zustaendig.deletenotification('pending_activity', aktivitaet) |
At phases, the following methods are available:
Method/Feature | description | Sample code |
---|---|---|
setresourceplanvalue(worker, date, value) |
As of Vertec 6.6. Allow the setting of resource plan values when the Planning Level is set to phase.
|
bearb = vtcapp.currentlogin() phase = argobject phase.setresourceplanvalue(bearb, vtcapp.strtodate('15.05.2023'), 180) |
Method/Feature | description | Sample code |
---|---|---|
book([raiseException]) |
From version 48th Post an invoice into accounting. The raiseException argument is a Boolean (True/False) that indicates whether errors should be reported when posting or cancelling. raiseException is optional, default is True. If raiseException is False, then errors during posting are ignored, the invoice is simply not posted. |
rechnung = argobject rechnung.buchen() |
import payments() |
From version 5.8. Import the payments to the current invoice. Work only if the customer interface supports payment import. |
argobject.importzahlungen() |
makeoffen([raiseException]) |
As of version 5.8. Set a settled invoice back to open (reverse charge). The raiseException argument is a Boolean (True/False) that specifies whether errors should be reported during charging or undone during charging. raiseException is optional, default is True. If raiseException is False, then errors are reversed and the invoice simply remains charged. |
rechnung = argobject rechnung.makeoffen(False) |
makeverrechnet([raiseException]) |
From version 5.8. Charges an open invoice. The raiseException argument is a Boolean (True/False) that specifies whether errors should be reported during charging or undone during charging. raiseException is optional, default is True. If raiseException is False, then errors will be ignored, leaving the invoice open. |
rechnung = argobject rechnung.makeverrechnet(False) |
cancel([raiseException]) |
As of version 5.8. Cancels a posted invoice. The raiseException argument is a Boolean (True/False) that indicates whether errors should be reported when posting or cancelling. raiseException is optional, default is True. If raiseException is False, then errors in the post are ignored, the invoice is simply not cancelled. |
rechnung = argobject rechnung.stornieren() |
The term project entry is used to summarize services, expenses and outlays.
Method/Feature | description | Example code |
---|---|---|
makeoffen() |
From version 5.8. Set a billed service, expense or outlay to open. This only works if the service, expense or outlay is not on an invoice, otherwise an error will be thrown. |
argobject.makeoffen() |
makecompute() |
As of version 5.8. Set an open service, expense or outlay to charged. This only works if the service, expense or outlay is not on an invoice, otherwise an error will be thrown. |
argobject.makeverrechnet() |
Method/Feature | description | Example code |
---|---|---|
update set() |
From version 6.1.0.14. Hourly rate is recalculated (from rate system). Requires user rights |
argobject.updatesatz() |
Method/function | description | Example code |
---|---|---|
setpath(path: string) |
As of version 6.1.0.14. Set the document path to the activity when the Document Storage is set to |
argobject.setpfad('C:\\Dokumente\\text.txt') |
setdocumentcontent(filename, documentcontent) |
As of Vertec 6.7.0.15. Add a document to the activity if the Document Storage is
The activity will do the following:
After successful execution, the Document page is shown. If a document is already saved on the activity, an error is output. Note: The method can also be used if the document storage is not set to Internal, but the document is in any case saved internally. |
(name, file) = vtcapp.requestfilefromclient("Dokument auswählen", r"C:", "Word|*.docx") activity = vtcapp.createobject("Aktivitaet") activity.setdocumentcontent(name, file) vtcapp.showdetailform(activity) |
setemailcontent(mimecontent) |
As of Vertec 6.7.0.15. Add an email to the activity.
The activity will do the following:
Upon successful completion, the email page will be shown. If a document is already saved on the activity, an error is output. |
(name, file) = vtcapp.requestfilefromclient("Email auswählen", r"C:", "Email|*.msg") mimecontent = vtcapp.msgtomime(file) activity = vtcapp.createobject("Aktivitaet") activity.setemailcontent(mimecontent) vtcapp.showdetailform(activity) |
Method/Feature | description | Sample code |
---|---|---|
getkursto(currency: object, date: date): currency |
As of version 6.1.0.14. Return the conversion rate at the corresponding date. | chf.getkursto(eur, vtcapp.currentdate()) |
Starting with version 6.2.0.7 all Python methods that return lists of business objects directly return a Vertec list and no longer a Python list. The methods from the methods
Resulting lists are directly Vertec lists and no longer need to be created with vtcapp.createlist().
Example
Versions before 6.2.0.7: liste = vtcapp.createlist("Projekt", vtcapp.evalocl("projekt->select(code.sqllike('A%'))"))
Versions from 6.2.0.7: liste = vtcapp.evalocl("projekt->select(code.sqllike('A%'))")
Method/Feature | description | Sample code |
---|---|---|
append(object) |
A list can be populated using the append() method. Only individual objects can be passed, not entire lists with append() . |
mylist = vtcapp.createlist('Projekt') mylist.append(argobject) |
evalocl(OCL:string) |
An OCL expression can be dropped from the Vertec list. | projektIds = argobject.evalocl("eintraege").idstring() leistungen = vtcapp.createlist("OffeneLeistung", vtcapp.getwithsql("OffeneLeistung", "projekt IN (%s)" % projektIds, "")) print leistungen.evalocl("wertext->sum") |
extend(list: list) |
As of version 6.2. With the extend() method, another list can be appended to a Vertec list. This checks whether the vertec list is a derived list (e.g. |
projektIds = argobject.evalocl("eintraege").idstring() leistungen = vtcapp.createlist("OffeneLeistung", vtcapp.getwithsql("OffeneLeistung", "projekt IN (%s)" % projektIds, "")) leistungen.extend(vtcapp.createlist("VerrechneteLeistung", vtcapp.getwithsql("VerrechneteLeistung", "projekt IN (%s)" % projektIds, ""))) print leistungen.evalocl("wertext->sum") |
idstring() |
a common requirement in Python scripts is to formulate a SQL query with To do this, the IDs of a list of objects must be converted to a comma-delimited string.
|
>>> vtcapp.evalocl('Projektbearbeiter->allinstances').idstring() 300,676,7613,682,688,694 |
index(object) |
As of version 6.2.0.7. Return the index of the object in the list. If the object occurs more than once, the lowest index is returned. Introduce for compatibility with Python lists (see below). |
>>> liste = vtcapp.evalocl("projekt.code") >>> print liste.index('COMINSTALL') 25 |
insert(index, object) |
As of version 6.2.0.7. Insert an object into the list at index. Introduce for compatibility with Python lists (see below). |
>>> liste = [123, 'xyz', 'miau', 'abc'] >>> liste.insert(3, 2009) >>> print liste [123, 'xyz', 'miau', 2009, 'abc'] |
remove(object) |
Removes the specified object from the list | projektIds = argobject.evalocl("eintraege").idstring() leistungen = vtcapp.createlist("OffeneLeistung", vtcapp.getwithsql("OffeneLeistung", "projekt IN (%s)" % projektIds, "")) fl = leistungen.evalocl("self->select(bearbeiter.asstring = 'Judith Feller')") for leistung in fl: leistungen.remove(leistung) The example above serves to show the projektIds = argobject.evalocl("eintraege").idstring() leistungen = vtcapp.createlist("OffeneLeistung", vtcapp.getwithsql("OffeneLeistung", "projekt IN (%s)" % projektIds, "")) leistungen = leistungen.evalocl("self->reject(bearbeiter.asstring = 'Judith Feller')") |
Vertec and Python lists differ in the following ways:
The + operator is not applicable to vertec lists. Code of the type projektIds = argobject.evalocl("eintraege").idstring() leistungen = vtcapp.getwithsql("OffeneLeistung", "projekt IN (%s)" % projektIds, "") \ + vtcapp.getwithsql("VerrechneteLeistung", "projekt IN (%s)" % projektIds, "") does not work. An error appears: Instead, use leistungen = vtcapp.getwithsql("OffeneLeistung", "projekt IN (%s)" % projektIds, "") leistungen.extend(vtcapp.getwithsql("VerrechneteLeistung", "projekt IN (%s)" % projektIds, ""))or leistungen = vtcapp.getwithsql("OffeneLeistung", "projekt IN (%s)" % projektIds, "") leistungen += vtcapp.getwithsql("VerrechneteLeistung", "projekt IN (%s)" % projektIds, "") |
Python lists can be created from Vertec lists by using |
It is important to note that Vertec lists are “live”. This means that actions related to the logic of the list calculation can change, as shown in the following examples: With for l in list(argobject.offeneleistungen): l.delete() The following is a list of open services: leistungen = phase.evalocl("offeneleistungen") for l in leistungen: l.makeverrechnet() If they are charged in turn, they will automatically disappear from the list. The effect is the same as above: Only half of the services are charged. Instead, convert to a Python list: for l in list(phase.evalocl("offeneleistungen")): l.makeverrechnet() |
'count’, 'pop’, 'reverse’ and 'sort’ are only available on Python lists. If you use these methods, you would have to rewrite them or make the Vertec list back into a Python list with |