Extending Kuali Document Business Object - ojb

I am facing an issue with extended attributes on a document (trying to extend a document table). I created the original table’s PK (FDOC_NBR) in the extended table and linked the two via a foreignKey of the customized original table’s ojb entry (as an “extension” reference-descriptor). I created the bo and dd for the extension and customized the original document’s dd to add the new attributes. On the extended BO itself I also added members (with setters and getters) for the 2 new columns + for the PK column of documentNumber. I also added the new attributes to the documet’s jsp. The pertinent module definition was already extended to include custom dd, ojb, etc. files.
Indeed, when opening the document the new fields are shown- however, when trying to submit the document (regardless of doing anything with the new fields) I get an error-
Error Details: OJB operation; SQL []; ORA-01400: cannot insert NULL
into ("KFSTEM"."TEM_TRVL_ARRANGER_DOC_EXT_T"."FDOC_NBR") ; nested
exception is java.sql.SQLIntegrityConstraintViolationException:
ORA-01400: cannot insert NULL into
("KFSTEM"."TEM_TRVL_ARRANGER_DOC_EXT_T"."FDOC_NBR")
Seems like somehow the system tries to insert a value of NULL into the extension’s PK field, instead of the actual document number. Trying to debug this, in the action’s route method and all the way down to DocumentDaoOjb.save (which is as far down as I can go) I see the document with the real doc number is passed on, so the problem seems to be purely with ojb trying to set this number to the extension table.
Does anyone have any experience with extended attributes on documents that could help shed some light on this?

KFS is using the KNS, and in the Kuali Nervous System, the primary key on the extended attributes object must be set through manual intervention.
In this case, it looks as if you're adding an extended attribute to a transactional document, the Travel Arranger document (TAA), which simplifies things. Basically, you'll need to extend org.kuali.kfs.module.tem.document.TravelArrangerDocument and override prepareForSave to set the document number there (it may be set already since prepareForSave should be called several times during the routing process, but there's no real harm from overwriting that information as the base document's number will remain the same).
Hope this helps!

Related

Maximo readonly/persistent attribute issues

I have an non-persistent attribute (SITEID) on my WOCHANGE object that originates from the parent object, WORKORDER. For some particular reason, this attribute has a few problems that I've never really seen with other attributes before.
Based on various configurations I have tried in an attempt to remedy the issue, here are the main issues:
It doesn't trigger the WOCHANGE to save when changed.
In addition to the value not being saved, I can change the value on one record, go to another and the value persists on the different record.
The field is readonly unless I define it to have an inputmode of DEFAULT. This is odd to me, because not defining inputmode usually implies default behavior (NOT readonly).
Here are the definitions for the SITEID attribute on both the WORKORDER
and WOCHANGE objects.
SITEID also uses a TABLE domain belonging to the SITE table.
Are there any attribute rules being applied from other sources that I should be checking?
That workorder field class on there may not be desired and may be messing with things, like setting the field to read-only. Site Id is commonly a read-only field, especially when the record is no longer a new record. Because of that, the logic to make that field read-only could be buried deeper in the Maximo business logic than just that field class. You are working with a field that has a lot of special meaning in Maximo, you are likely going to stumble into many built-in business rules.
Since non-persistent fields are not saved in the database (they are in memory fields only), I don't believe they trigger the flag for a record to be saved. What would be saved? Nothing in the database (a save) is to be changed yet.
Your screenshot however shows the field as persistent. Is WOCHANGE a view? I can't recall and no longer have the resources to check.

JSF displaying entities with IDs: how to translate IDs to descriptions?

In a JSF page I have to display the data from an entity.
This entity has some int fields which cannot be displayed directly but need to be translated into a descriptive string.
Between them some can have a limited number of values, others have lots of possible values (such as a wordlwide Country_ID) and deserve a table on the Db with the association (ID, description).
This latter case can easily be solved navigating via relationship from the original entity to the entity corresponding to the dictionary table (ID, description) but I don't want to introduce new entities just to solve translations form ID to description.
Besides another integer field has special needs: the hundred thousand number should be changed with a letter according to a rule such as 100015 -> A00015, 301023 -> C01023.
Initially I put the translation code inside the entity itself but I know the great limits and drawbacks of this solution.
Then I created a singletone (EntityTranslator) with all the methods to translate the different fields. For cases where the field values are a lot I put them inside a table which is loaded from the singletone and transformed in a TreeMap, otherwise the descriptions are in arrays inside the class.
In the ManagedBean I wrote a getter for EntityTranslator and inside the jsf I use quite long el statements like the following:
#{myManagedBean.entityTranslator.translateCountryID(myManagedBean.selectedEntity.countryID)}
I think the problem is quite general and I'm looking for a standard way to solve it but, as already stated, I don't want to create new 'stupid' entities only to associate an ID to a description, I think it is overkill.
Another possibility is the use of converters Object(Integer) <-> String but I'm more comfortable in having all the translation needs for an Entity inside the same class.
Your question boils down to the following simple line:
How can I display a field different from id of my entity in my view and how can I morph an integer field into something more meaningful.
The answer is that it depends on a situation.
If you solely want to input/output data, you don't need id at all apart from the possible view parameter like ?id=12345. In this case you can input/output anything you want in your view: the id is always there.
If you want to create a new entity most possibly you have a way of generating ids via JPA, or database, or elsehow besides the direct input from the user. In this situation you don't need to mess with ids as well.
If you want to use information on other entities like show user a dropdown box with e.g. a list of countries, you always have the option to separate label (let it be name) and value (let it be id), or even have a unique not null column containing the country name in your database table that will serve as a natural identifier. If you'd like to get data from the user using an input text field you always can create a converter that will do the job of transforming user input strings to actual entity objects.
Regarding the transformation of your integers, you've actually got several choices: the first one is to attach a converter for these fields that will roughly do 301023 -> C01023 and C01023 -> 301023 transformations, the second one is to write a custom EL function and the third one is to prepare the right model beforehand / do the transformations on-the-fly.

Sharepoint Extenal List and Custom Field Types

I have an odd issue.
I have client that wants a sharepoint list what is populated from a WCFService. That part is working quite well.
I have a bdcmodel that is mapping the WCF data and I can create an external list from the bdcmodel as well so that is working fine.
The issue I have is that one of the properties in the model is actually a collection of entities called Attributes. The objects in this collection simply have 2 properties Name and Value so really they are just a key value pair.
The client wants to see the list of attributes of the parent entity in the external list. So there would be an Attributes column and within that column would be the list of attributes for each parent object.
Is there even a way to do this? I am looking into Custom Field Types, but it seems like these are really intended to be singular values.
How would I create a list within and external list?
Any help anyone can give would be great even if its just to tell me that there really isn't a stable way to do this so I can go back to the client and tell them we will need to build a custom list to support this because the OOB external list and custom fields and custom field types won't support this kind of nested listing.
I decided to set up the custom field as a string and when I get my collection in from the BdcModel I am serializing it to JSON and then passing it to the field. When the field is viewed in display, edit or new I have overridden the FieldRenderingControl and I am tiling the collection out that way.

What are the rules of mapping from PersistEntity/PersistField to column and table names in the DB

I need to work with an existing (MySql) db, where the names of tables and columns are already defined.
If I understand the documentation properly (and I didn't find good documentation on this subject, so links will be highly appreciated), table names are related to PersistIdentity, and must therefore begin with a capital letter (which is not the case I'm facing).
Column names, however, are automatically un-capitalized (at least that's what is implied in the Yesod book, Persistent chapter, in the code snippet describing the code automatically generated from declarations), so columns in the DB must begin with a lowercase letter.
Is the description above indeed true?
Can I control specifically the mapping of tables to identities and columns to fields?
If not then what are the rules automatically applied for the naming? What names are therefore forbidden?
Also, one of the fields is a VARCHAR(30). How can I communicate that to Persistent? It currently complains (through yesod devel) that:
errMessage = "BLOB/TEXT column 'my_field' used in key specification without a key length"}
Which is the result of auto-migration (which I probably should disable anyway). However, if I do want to declare a bounded VARCHAR field - can I do that through Persistent and its auto-migration tool?
Thanks,
I'm not an authority on the MySQL backend, but IIRC (and based on the code), you can control the maximum length by using the maxlen=... attribute. Similarly, you can have direct control of the name the field will have in the database by using the sql=... attribute. So, for example, the following might work:
Person sql=people
name Text sql=full_name maxlen=40
age Int
I also agree that you should disable the automigration code if you're dealing with a pre-existing schema.

non-database field on ClearQuest form

Is there a way to use form fields that does not correspond to database field for temporary processings?
I.e. I want to add:
temp fields item1, item2
database field sum
button with record hook that sets sum = item1 + item2
As far as I know it's simply not possible with ClearQuest.
I've tried to do something similar and was told by our IBM consultant that the only way is to create a DB field for all variables.
You can't attach data to form fields really - those are representations of the underlying data, not something scripts interact with directly.
Adding temporary data to the underlying record (entity) itself sounds unlikely as well. Perhaps it's possible to abuse the perl API and dynamically attach data to entity objects but I personally wouldn't try it, you're liable to lose your data at the whim of CQ then ;-)
That does not however mean it's impossible to have temporary data.
The best way seems to me to be using the session object, which is explicitly intended for that purpose.
From the helpfile:
IBM Rational ClearQuest supports the
use of sessionwide variables for
storing information. After you create
sessionwide variables, you can access
them through the current Session
object using functions or subroutines,
including hooks, that have access to
the Session object. When the current
session ends, all of the variables
associated with that Session object
are deleted. The session ends when the
user logs out or the final reference
to the Session object ceases to exist.
There's some helpful documentation on this subject in file:///C:/Program%20Files/Rational/ClearQuest/doc/help/cq_api/c_session_vars.htm (Presuming a default installation on a windows machine, of course.)
Translating the code example in there into what you seem to be wanting, first you store the data you have calculated inside the session object:
$session->SetNameValue("item1", $value1);
$session->SetNameValue("item2", $value2);
Then in your calculation hook you retrieve the stored values and set the value of that totals field like this:
my $item1 = GetNameValue("item1");
my $item2 = GetNameValue("item2");
my $sum = $item1 + $item2;
$entity->SetFieldValue("some_totals_record", $sum);
Adjust to taste of course ;-)
ClearQuest schema designers often include 'temporary' fields in their record types. They do this so they perform operations on hooks to generate another value.
For example, for the Notes fields, there is a 'temporary' Notes_entry field that the user types the most recent note into, and when the record is saved, the value is added to the Notes_Log field. The next time the record is edited the Notes_entry field is cleared so the user can type a new Notes_entry.

Resources