Creating an attribute against WHEREUSED Non Persistent Object - Maximo - jython

I have added an attribute against the NP WHEREUSED object.
I'm adding a New Row and the field is getting populated using a LKP and on Save Maximo gets rid of the value.
How can I ensure to maintain the value of the spare fieldon save?
Thanks,
Keepgv

First, you need to understand that it takes code to move anything from a non-persistent (NP) object or attribute to somewhere where it will get saved. Second, you need to understand that the save() method is never called on NP objects; execute() is called instead.
I think the problem you are running into is that Maximo does not currently (as of Maximo 7.6.0.8) offer "Execute" in the selection of events for Object Launch Points. If you would like to see that changed, please vote for this RFE: https://www.ibm.com/developerworks/rfe/execute?use_case=viewRfe&CR_ID=77559
Then, you'll have to find a workaround until IBM implements that RFE.

Related

Select from ProblemFactCollectionProperty and PlanningEntityCollectionProperty in ShadowVariableListener like in ContraintProvider

For the update of my shadow variable I have to take into account some constraints which I can get from Objects saved in a ProblemFactCollectionProperty/PlanningEntityCollectionProperty.
Is it possible to select from ProblemFactCollectionProperty and PlanningEntityCollectionProperty inside of a ShadowVariableListener like it can be done with the ContraintProvider? Or do I have to add a pointer pointing to these collections to each object which has this shadow variable listener so that the listener can access the ProblemFactCollectionProperty/PlanningEntityCollectionProperty?
All methods in VariableListener have a ScoreDirector parameter, so you can use scoreDirector.getWorkingSolution() to fetch your working solution.
Don't cache that solution instance or it's entity list instances in the VariableListener, as solution cloning might affect what's the real instance.

How to add directory?

I am trying to add information to a directory is this the correct method of doing it? Seems to not be working
ADSearchResult.GetDirectoryEntry().Properties.Item("mobile").Add("5555555555")
ADSearchResult.GetDirectoryEntry().CommitChanges()
You called GetDirectoryEntry() twice. That means when you call CommitChangegs(), you're committing from a different object in memory than the one where you updated the phone number. Even if the two objects represent the same AD record, they're still different objects. Only one of them has your changes. You need to commit from the same object you updated:
Dim ADEntry = ADSearchResult.GetDirectoryEntry()
ADEntry.Properties.Item("mobile").Add("5555555555")
ADEntry.CommitChanges()

Yii CActiveRecord with Column Named "attributes"

I used the CRUD generator from a legacy database. When searching for a column value I get the following error:
htmlspecialchars() expects parameter 1 to be string, array given (/usr/local/share/yii/framework/web/helpers/CHtml.php:103)
The problem is that the model has an existing column named "attributes" which is creating a conflict. I removed the entry from the _search.php and commented out all instances in the model hoping to at least get it working but no luck. Any suggestions would be appreciated.
Thanks.
Every CActiveRecord instance (or CModel instance for that matter) has a getter/setter named attributes with which all the attributes can be set. This leads to a conflict because the generated crud code uses the attributes attribute expecting it works as described before.
The controller does something like:
$model->attributes=$_POST['ModelClassName'];
// or
$model->attributes=$_GET['ModelClassName'];
This is meant to set al the (safe) attributes of the model at once. Instead this overwrites the database attribute attributes of your legacy DB model.
This in turn leads to the error you describe, because $_GET['ModelClassName'] and $_POST['ModelClassName'] typically contain arrays of data.
I guess the easiest fix would be to directly call the setter function for the "normal" attributes behavior which would lead to replacing the lines mentioned above with something like the following:
// in the controller
$model->setAttributes($_POST['ModelClassName']);
// and
$model->setAttributes($_GET['ModelClassName']);
I think rest of the generated CRUD code (the views) could and should be left untouched to make it work.
If you want to know how and why this works, it's best to do some research into the __get and __set magic functions and how they're used in the yii framework.

ABAP Objects - access message class of a class?

In the header information of an ABAP Objects class, I can enter a message class to use with the MESSAGE statement. This works like the MESSAGE-ID statement of a report or a function pool. Since I can't find the message class I entered in the header data anywhere in the generated sections, I assume that it's generated into the top-level CLASS-POOL statement somewhere.
For some libraries (for examples, the BAL application logging), it's necessary to specify the message class using a variable or a method parameter. Up to now, I've defined a constant that specified the message class and used that constant. I'm wondering if it's possible to access the message class specified in the header data in some other way so that I can get rid of that redundant variable.
Has anyone found a way to do so?
EDIT: The new way should be easier than the old one - I'm not crazy enough to add a CLASS-CONSTRUCTOR and perform some database access or SEO_* function calls just to get rid of that constant.
I think you need a CLASS-CONSTRUCTOR to set a class attribute with the message class.
The MESSAGE statement with INTO clause has the side effect of setting the SY- system variables. So you could put into your CLASS-CONSTRUCTOR something like:
DATA: lf_dummy TYPE string.
MESSAGE s999 INTO lf_dummy.
af_msgid = sy-msgid.
You could use the class builder API:
data the_class type ref to cl_oo_class.
create object the_class
exporting
clsname = `ZCL_SOMECLASS`.
data message_class type arbgb.
message_class = the_class->class-msg_id.
I haven't come across any syntax to do what you ask. For the reasons I outline below, I could believe that SAP never saw a need to include such functionality.
In my experience, the message class is an attribute of the message, not of the object that raises it, so it should be kept together with the type, number, and variables of the message. For example if my object is returning the number of an error, it should be returning the id (class) as well.
In this light I cannot see a reason why you would ever need to know the message-class assigned to an ABAP-OO class, you would only ever need to know the message-class of the messages returned by the ABAP-OO class.
The way I usually manage this is to raise my messages into a dummy field, and then use a subroutine to populate the contents of the sy-msg* fields into a BAPIRETURN structure. Then I return this BAPIRETURN structure to the caller. This way the type, id, number, and variables of the message are all kept together.

Are there any "gotchas" to watch for in using a Class (object) within itself?

I've got a Registry class and there are a few Registry values that I want to access from within that Registry class. (There is a bit of a calculation with these values so I thought I'd just put all that code right in the Registry Class itself).
So we might have something within our RegistryRoutine.cls like:
Function GetMyValue() as integer
Dim R as new RegistryRoutine
<calculations>
GetMyValue=R.GetRegisetryValue (HKEY, key, value, etc.)
End Function
No, in general you won't see any problems (like member variables being overwritten or anything weird like that).
Where you could run into issues is if you have explicity shared variables that are being written to multiple times. But that's dangerous no matter what you do.
Do watch out for recursive cases - e.g., GetMyValue() should not call R.GetMyValue(), nor should GetRegistryValue() call GetMyValue().
It's rare that you actually want to do this, however.
Since you're not passing any arguments into GetMyValue(), we can assume that the current instance already has all the information it needs.
Since you're only returning an integer, not a RegistryRoutine instance, the client has no need for a new instance.
So, why not just call GetRegistryValue (without the R.)?
It's quite common for classes to work with instances of themselves. Consider, for example, how a tree structure works. Either a Node class has to keep track of its children, or has to keep track of its parent (or both). All the nodes are the same class.