Microsystems Technology Laboratories > OpenCoral
Opencoral
 

Configuring and Running XCRML-based Cost Recovery

XCRML-based Cost Recovery Overview

XCRML makes use of an XCRML Cost Policy document that, in effect, controls the algorithm that is used to determine costs for laboratory usage. This works in concert with data taken from the database to determine actual rates to be charged or additional data (specifically rundata) that may also be used in the determination of rates. Additionally, becuase the capabilites of XCRML may be enhanced over time, there may the possiblity that the actual schema that defines a legal XCRML document may change over time. As a result, there are four main components that are used in a functioning XCRML based Cost Recovery system. The first three are required and the fourth one is optional. Those components are:

  • The Cost Recovery Schema, that will be stored in the table named cost_recovery_schema owned by actmgr. The cost schema specifies the legal elements of a cost policy and will typically only rarely change.
  • The Cost Recovery Policy, that will be stored in the table named cost_recovery_policy owned by actmgr. The cost policy specifies the algorithm that you use to calculate charges for laboratory usage. In most laboratories, the cost policy likely changes infrequently but will likely change on occasion.
  • The actual rates that are used during the calcualtion of charges for laboratory usage. This data will be found in the table named xcrml_rates owned by actmgr. In many laboratories, these rates will likely change annually and may change more frequently. Note: an important element of XCRML-based cost calculations is that the rates that are in effect at the start of an accounting period (typically a month) are the rates that will be used for the entire month. If you try to specify that a rate changes on May 15, you will get the rate that was in effect on May 1 for the entire month of May and the rate that you specified as becoming effective on May 15 will actually become effective on June 1. As a result, it is safesto to only specify changes in rates (and policies) on month boundaries. The tools that help you work with XCRML have this capability built into them.

XCRML is a "standard" that has been developed internally as a part of Coral because we could find no pre-existing capability that allowed us to describe the algorithm that will be used to calculate appropriate charges for laboratory activities. In our experience, there is a large variation from facility to facility in the way that charges are calculated and, as a result, there is a need to support a flexible means of specifying and applying a wide range of algorithms to determine charges for laboratory usage.

XCRML Schema and Policy Files

Discussion of why XCRML schema and policy fiels are stored in the database rather than in the file systm like XACML-based policy files (such as ReservationPolicy.xml). The short answer is: XACML-based policy files are always in effect "now". If the policy file is changed and deployed, the new policy goes into effect and controls whether someone can take an action now. It doesnt't matter what the policy was last week, last month, or last year. What is relevant is "Can I take action X now with my current privileges.

XCRML-based accounting is different. If I want to re-run accounting for last month, for example, I want to use the rates and policy that were in effect last month. As a result, unlike XACML-based policies, we need to track which Cost Schema, Cost Policy, and Rates are applicable over time so that we can always use the proper schema, policy, and rates that were applicable at that point in time.

Installing XCRML Schema and Policy Files

Before installing your Schema and Policy Files you likely want to install them with an effective date that is earlier than your oldest Coral activity records. If you have a brand new Coral installation, that is likely "the first of this month". If some of you have been running Coral for some period and are now beginning to use XCRML for Cost Recovery, you almost certainly want to install your Cost Schema with an effective date earlier than your first activities in Coral. Your Cost Policy will also likely be installed with that same effective date. Note: if your Cost Policy has actually changed between when you started using Coral and now, you likely need to ask that question on the forum because that is a more advanced topic. In the remainder of this section I am going to assume that you want to install both your Cost Schema and Cost Policy with an effective date earlier that your oldest Coral activity record.

How do you determine your oldest Coral activity and then determine an effecive date that is the beginning of that month?

If you are running a Postgresl database, start up 'psql coral actmgr' and issue the following SQL command:

SELECT to_date(date_trunc('month', min(bdate)), 'YYYY-MM-DD') FROM activity;

If you are running an Oracle database, start up 'sqlplus actmgr' and issue the following SQL command:

ALTER SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD';
SELECT trunc(min(bdate),'month') from activity;

Record this date in YYYY-MM-DD format and type it in in the following commands in place of the string ${MY_EARLIEST_DATE}.

Make sure that your Cost Recovery policy in /path-to-opencoral-src/opencoral/src/xml/policy/xcrml/CostPolicy.${site}.xml is what you want to use or confirm that the default Cost Recovery policy found in /path-to-opencoral-src/opencoral/src/xml/policy/xcrml/CostPolicy.xml is what you want to use. Once they are the files that you want to use, you need to deploy them with 'ant deploy'. This doesn't actually load them into the database, but puts them in a location where they are ready to be installed into the database.

Now load the CostSchema with the following command:

ant -Dcost_schema_bdate=${MY_EARLIEST_DATE} loadCostSchema

In other words, if your value of MY_EARLIEST_DATE was 2010-01-01 you would have entered the command: 'ant -Dcost_schema_bdate=2010-01-01 loadCostSchema. This will first confirm the values of bdate, edate, and active which should be your value of MY_EARLIEST_DATE, NULL, and true, respectively. Hit 'y' to continue and load that schema into the database and 'n' to cancel (in particular, if you mis-typed the MY_EARLIEST_DATE value.

Now you are ready to load the CostPolicy with the following command:

ant -Dcost_policy_bdate=${MY_EARLIEST_DATE} -Dcost_policy_edate=2999-01-01 loadCostPolicy

Note: this will again give you a y/n option after confirming the bdate, edate, and active values. Note: in this case, we explicitly enter a value of the edate that is VERY far in the future: 2999-01-01.

At this point, you should be able to restart your Coral servers and you will be able to use make use of your CostPolicy. The first use of the policy, however, will be to set applicable rates as described in the following section.

Setting, inspecting, and changing XCRML rates

The tools described in this section will look at all of your CostPolicies ... you need at least one but may have more than one ... and allows you to select the applicable policy. It then loads and parses that policy and creates a list of the named rate parameters used in your policy. For example, you might have declared in your policy that you will be using equipment_hourly_rate, staff_hourly_rate and training_hourly_rate. A key element of what rates need to be set is determined by the indexing that you have specified for each rate in your Cost Policy.

Rates specified in your policy may be unindexed or indexed by one or more indexes. Additionally, you can specify default values for any of these rates.

Let's start by considering the simplest of all rates: an unindexed rate. For example, if we charge a fixed hourly rate for staff to train lab members to use euqipment and that rates is independent of who is doing the training and is also indpendent of the tool on which the member is being trained, that is an example of an unindexed rate. In a Cost Policy that might bes specified as:

            <Algorithm>
                <Apply OperatorId="opencoral:xcrml:1.0:operator:double-divide">
                    <Apply OperatorId="opencoral:xcrml:1.0:operator:double-multiply">
                        <ActivityAttributeDesignator
                            AttributeId="opencoral:xcrml:1.0:names:activity:amount"
                            DataType="double"/>
                        <Apply OperatorId="opencoral:xcrml:1.0:operator:double-lookup">
                            <Table TableId="training_hourly_rate" DataType="double">
                            </Table>
                        </Apply>
                    </Apply>
                    <AttributeValue DataType="double">60</AttributeValue>
                </Apply>
            </Algorithm>
 

In the rate table, that rate will be defined by a single row at any one point in time.

In many cases, a rate will be indexed along a single "axis". For example, you may wish to charge people for training based on the staff member doing the training, but independent of the tool on which someone is being trained. In this case, the policy would look like:

            <Algorithm>
                <Apply OperatorId="opencoral:xcrml:1.0:operator:double-divide">
                    <Apply OperatorId="opencoral:xcrml:1.0:operator:double-multiply">
                        <ActivityAttributeDesignator
                            AttributeId="opencoral:xcrml:1.0:names:activity:amount"
                            DataType="double"/>
                        <Apply OperatorId="opencoral:xcrml:1.0:operator:double-lookup">
                            <Table TableId="training_hourly_rate" DataType="double">
                                <Indexes>
                                    <Index>
                                        <ActivityAttributeDesignator
                                            AttributeId="opencoral:xcrml:1.0:names:activity:agent"
                                            DataType="string"/>
                                    </Index>
                                </Indexes>
                            </Table>
                        </Apply>
                    </Apply>
                    <AttributeValue DataType="double">60</AttributeValue>
                </Apply>
            </Algorithm>
 

In this case, the tools that allow you to examine, set, and alter rates, will read your Cost Policy and know that the equipment hourly rate is indexed by the staff member doing the training. In fact, it will set up the table with that information and expect that you will enter a rate for each staff member.

Note
While the XCRML rate tools know how each rate is indexed, they DON'T populate your table with all possible staff members that may be able to train others. Knowing that you need to set rates for staff members 'bob_smith', 'mary_jones', and 'fred_flintstone' is your job.

Rates can be indexed along more than one axis. For example, you might charge a different hourly rate depending on the tool on which the member is being trained AND the staff member doing the training. If you have defined to use a rate class dependent on the type of project: 'local', 'other academic', 'industrial', for example, you can charge a different rate indexed by the tool, the staff member doing the training, and the rate class of the project to which the member is charging that activity. Of course, in this case, if you have 50 tools, 10 staff members, and 3 rate classes, you would need to specify as many as 1500 (50 x 10 x 3) different rates for training_hourly_rate to cover each tool, staff member, rate class combination.

Setting up XCRML rates is done in the coral-admin tool that, at present, must be run on your Coral server. Once you have started coral-admin and authenticated yourself, you should see a menu along the top labeled "Cost Recovery" that has three sub-menu items. The name and general functional description of each of those menu items is:

  • Terminate rates. This function is rarely used and is really only useful when you change the level of indexing of one of your rates. For example, if you change a rate that was previously indexed only by the tool to one that is now going to be indexed by both tool and reate class, you probably want to terminate the rates (with an appropriate termination date) of the singly-indexed rate and then add the new rates for the new policy that specifies two levels of indexing.
  • Set new rates. Particularly for setting up a brand new XCRML installation, this is the menu item that you will use to set up those rates. This will also be used when you are changing from one set of rates to another, for example, if you change rates on an annual basis. In general, this will prompt you for the "effective" date which, if you are setting up rates for the very first time, should be the value that you used for MY_EARLIEST_DATE in setting up your policy. If you are changing rates, you will typically set the effective date as the date during which you want those new rates to become effective.
  • Display and correct rates. This menu item will be used primarily to examine existing rates at any effective date. It will also be used, but hopefully, only occasionally, for correcting a rate that was incorrectly set. If you are changing rates ... that is you want to increase a particular rate by, for example, $5 per hour, starting next month, you want to be using the "Set new rates" function described above.