Service sums

Use of service sums, groupservices OCL operator

Product line

Standard

|

Expert

Operating mode

CLOUD ABO

|

ON-PREMISES

Modules

Services & CRM

Budget & Phases

Purchases

Resource Planning

Business Intelligence

Created: 14.11.2003
Updated: 16.07.2024 | Shadow attributes sqlDiscountAmount and sqlCurrencyDate on invoice are no longer used as of version 6.4.0.17.

Accelerated summation and grouping in the form of an OCL operator is available for optimizing customer-specific evaluations or for use in user-defined reports.

Operators

The groupServices operator exists in several variants, which differ mainly in that they are applicable to different types of objects:

Operatordescription
groupServicesGlobal service sum operator. Refer to all services in the system. Since OCL operators must always be based on a specific data type, the operator is registered to Tim Session. The fee values are output in key currency.
groupServicesPPerformance sum operator for projects. Can be applied to a single project or to a list of projects. The fee values are output in key currency.
groupServicesPWStarting with version 5.3.1.19. Performance sum operator for projects. Can be applied to a single project or to a list of projects. The fee values are output in project currency.
If this operator is applied to a list of projects, make sure that all projects in the list have the same currency. Otherwise, the amounts in the different currencies will simply be added together, resulting in nonsensical numbers.
groupServicesPWGStarting with version 5.7. Calculate all numbers in project currency, i.e. without currency conversion. It is a global operator; that is, the operator is called not on a single object, but on Tim Session. Care
must be taken to group by projects, otherwise the numbers in different currencies will be summed. For example, the call is done as follows: Timsession.allInstances->first->groupPerformancePWG('01.01.2011', '31.12.2011', 'PROJECT’)
groupServicesBOperator for payroll operators. Can be applied to objects of type project users or to lists thereof. The fee values are output in key currency.
groupServicesPhPerformance sum operator for phases. Can be applied to a single project phase or to a list of phases. The fee values are output in key currency.
groupServicesPhWStarting with version 5.7. This operator is called on project phases and calculates the numbers in project currency.
groupServicesW

Starting with version 6.0. Can be accessed on projects, phases and users. Return results in any currency.

groupBenefitsW(from, to, group, currency)

expects a string argument for currency. An empty string returns the results in the key currency. Example in the column of an editor list:

self->groupServicesW('01.01.2016','31.12.2016', '', 'EUR’)->collect(valuetextOpen+valueExtCalculated)->sum

outputs the fee values of all services rendered by the user in 2016 converted into EUR.

Syntax

The syntax for all these operators is as follows:

<obj>->groupservices(<von>, <bis>, <group>)

The arguments (in square brackets) of the groupPerformance operator have the following meanings:

obj the base object to which the operator is applied. Can be of type project, user, or phase, and lists of them. Often the base object is the result of a partial OCL expression. For groupPerformance, the operator must be called on the session. The current session can be called via Timsession.allInstances->first:
Timsession.allInstances->first->groupPerformance(...
from, to from, To date of a date period. The services are summed only from the period indicated.

The data from and to must be passed as a string in the format dd.mm.yyyy. If an empty string is specified, all services are used.

It must be ensured that the German date format (dd.mm.yyyy) is passed also with other language settings, otherwise there will be an error. For this purpose there is (from Vertec 6.2) the method dateToStrGerman:

<obj>->groupServices(encodeDate(2019,01,01).dateToStrGerman, date.dateToStrGerman, 'PROJECT’)

In older Vertec versions this can be ensured, for example, with the following code:

Import datetime

def DateGermanFormat(date):
    “"”Returns the date in German format, dd.mm.yyy, as a string. 
       If the date is empty, an empty string is returned.”"”“
       
    if date:
        return datum.strftime(“%d.%m.%Y”)
    else:
        return
group Grouping statement. Contains different grouping terms, separated by commas, and controls the grouping and sorting of the result totals. If an empty string is specified, the list is not grouped. The
following grouping terms can be used:
  • PROJECT: groups the service sums by project
  • USERS: grouped by users
  • PHASE: grouped by phase
  • TYPE: grouped by service type
  • INVOICE: groups the totals by invoice
  • YEAR: grouped by year
  • MONTH: grouped by months
  • DAY: grouped by days

The result is a list of Servicesum objects, sorted according to the specified grouping.

ServiceSum

These performance sum objects have different sum attributes as well as a value for each grouping term. More specifically, these are the following properties:

Memberdescription
minutesExtOpenTotal of external minutes not yet billed.
minutesExtOpenUnprodTotal of the external, not yet charged minutes of services entered on projects with non-productive project types.
minutesExtBilledTotal of external billed minutes.
minutesExtBilledUnprodTotal of external billed minutes of services entered on projects with non-productive project types.
minutesIntOpenTotal of internal minutes that have not yet been billed.
minutesIntOpenUnprodThe sum of internal minutes of services that have not yet been entered on projects with non-productive project types.
minutesIntBilledTotal internal billed minutes.
minutesIntBilledUnprodTotal internal billed minutes of services entered on projects with non-productive project types.
powerCountQuantity of services included in this sub-total.
projectProject of this subtotal, if grouped by project.
UserUser, if grouped by user.
phasePhase if grouped by phases.
typeService type if grouped by service type.
invoiceInvoice if grouped by invoices.
dateStart date of the date group (year, month, day), if appropriate grouping.
valueEditorOpenTotal of fee values by user rate, not charged.
valueEditorInvoicedTotal of fee values by user rate, charged.
valueExtOpenTotal of external fee values not yet charged.
valueExtOpenUnprodTotal of the external, not yet charged, fee values of services entered on projects with non-productive project types.
valueExtCalculatedTotal of external charged fee values.
valueExtCalculatedUnprodTotal of external, charged fee values of services entered on projects with non-productive project types.
valueIntOpenTotal of internal fee values not yet charged.
valueIntOpenUnprodThe sum of the internal, not yet charged, fee values of services entered on projects with non-productive project types.
valueIntCalculatedTotal of internal charged fee values.
valueIntBilledUnprodThe sum of the internal invoiced fee values of services entered on projects with non-productive project types.
valueCostOpenTotal fee values according to cost rate, not charged.
valueCostsBilledTotal fee values according to cost rate, charged.

Example

On a project (or a list of projects) the operator groupPerformanceP is applied. The date period is January to December. We want the totals grouped by months and projects, the given grouping statement ('MONTH,PROJECT’) does this.

->groupServicesP('01.01.2016','31.12.2016','MONTH,PROJECT’)

As a result, we get a list of Servicesum objects. These include, for example, the following attributes:

  • Month: datum.formatDateTime('mm.yyyy’)
  • Project: project
  • Internal hours: minutesintOpen + minutesIntBled
  • Value external: valueExtOpen + valueExtCalculated

Special cases

Special cases for calculation arise, for example, in the case of fixed-price invoices without services or in the case of invoice discounts. In this case, the external value of the services cannot simply be used to calculate the service sums. How these special cases are dealt with in detail is explained below:

Special case Calculation

Flat-rate phases without services

(if the phase is on a fixed-price invoice without services, see there)

Is shown as total service sum as follows:

  • Date: End date of the phase
  • User: Project leader of the project. In case of invoice, fixed project leader of the invoice (verrProject manager)
  • ValueExt: PlanvalueExt of the phase. If there is a discount on the invoice, it will be deducted from the Valueext proportionally (phase.planvaluetext / invoice.ActvalueExt).
  • ValueInt: PlanvalueInt of the phase
  • Costs: PlanValueCosts of the phase
This applies to fixed-price phases without services which have no sub-phases. As soon as a fixed-price phase without services has sub-phases, the calculation is carried out on the sub-phases. There is then no calculation or service sum for the parent phase.
Fixed-price invoice without services

Is shown as total service sum as follows:

  • Date: Invoice value date
  • User: Project leader of the project. In case of invoice, fixed project leader of the invoice (verrProject manager)
  • ValueExt: Fixed amount of the invoice. If there is a discount on the invoice, it will be deducted again (total discount amount).
  • ValueInt: Fixed amount of the invoice.
Invoices with discount

If it has an invoice, the discount will be deducted proportionately from the Valueext of the service sum.
This percentage is calculated as follows:

valueExt – (invoice.totalDiscountAmount * valueExt / invoice.serviceValueExt)

Flat-rate phases and invoices with fixed services

In the case of fixed-price invoices or flat-rate phases, the flat-rate value is always distributed proportionally to the external values of the services on which they are located (see also Value in flat-rate phases and -invoices), which are not fixed, i.e. have not checked the Fix external value check mark. Therefore, this does not Role for the calculation of the service sums, the value of the services is simply taken. However,

if ALL the benefit services of an invoice are fixed, then the flat-rate amount fixed amount cannot be services allocated to the benefits. In this case, the service sums cannot reflect the fixed amount.

Total services sum <> Total services

As a result of these special cases, there may of course be deviations between the sum of services and the sum of service sums. In this case, for example:

openbenefits->union(offsetbenefits)->select((date >= encodedate(1990,1,1)) 
and (date < encodedate(2018,1,1))).wertExt->sum

a value other than:

self->groupleistungenP('01.01.1990','01.01.2018','')->collect(valueExtOpen + valueExtCalculated)->sum

If this is the case for you, check if it has any of the above-mentioned special cases in the analyzed period.

In the case of fixed services on fixed-price phases or invoices, no difference can be found here, since neither the services nor the service sums contain the fixed amount. In this case, you will only recognize the difference if you compare the totals of the services with the totals of the invoices.

Limitation for large amounts of data and Firebird

When a groupPerformanceX operator is called on a list of projects, phases, or users, there are the following restrictions:

If the list of calling objects (i.e. not the quantity of services in the result, but the projects, phases or users on which the operator is called) is greater than 1500 entries, there is an error from the Firebird server due to invalid SQL:

General SQL Error.
Implementation limit exceeded
too many values (more than 1500) in member list
to match against.

One way to work around this problem is to use the global groupServices operator, which applies to all services.

Example: If there are more than 1500 projects and you want to call project->groupPerformanceP(...) you can work around this:

TimSession.allInstances->first->groupServices('', '', 'PROJECT’)

Returns a list of achievements over all services in the system, grouped by projects.

Performance Behaviour of service sums

Since the service sums are calculated optimally via SQL, the behavior of changes to basic data is slightly different than usual in Vertec.

In principle, service sums are recalculated as soon as any service is changed in the system. However, the recalculation only takes place when the service sum numbers are also visible. For example, it is not advisable to have a list of service sums on the screen at the same time when entering new services, as it would be recalculated for each new service. The calculation of service sums is relatively fast, but the delay is still noticeable if the benefit total is recalculated unnecessarily frequently.

In particular, it is not recommended to use groupPerformance operators in column expressions of lists, since the performance gain when calculating the sum is usually overcompensated by the large quantity of individual SQL queries.

Shadow Attributes

Various values in the Vertec are derived, that is, they are calculated each time they are accessed. This means that they are always up-to-date, but not retrievable in the database.

To ensure that these values are still available for accelerated summing, there are so-called shadow attributes, which are written when calculating the derived attributes. These shadow attributes are persistent, i.e. they are located in the database and can be queried directly.

The following shadow attributes are available. They are prefixed with sql.

Attributes Classes

sqlValueExt

Services, expenses, outlays

sqlMinutesExt

service

sqlValueInt, sqlDiscountAmount

Expenses and outlays

sqlDiscount Amount (only versions before 6.4.0.17)

invoice

sqlCurrencyDate (only versions before 6.4.0.17)

invoice

Bitte wählen Sie Ihren Standort