In Workorder tracking , there is a field "LEAD" which will display ID of lead.
In our requirement we have to display Leadname along with Lead ID.
SO I created a new field for Leadname in Workorder and used crossover domain with a new relation between Wordorder and Person. Relation where clause being personid=:lead
The crossover domain copies over the value of Leadname from Displayname attribute of PERSON object and is working fine when we give an ID in Lead attribute of Workorder.
However in case if I give a Lead ID and then remove the lead ID in WO , then leadname still remains It doesnt get modified to null.
I believe its because the crossover condition (personid=:lead ) is not satisfied and hence no action is being performed. I tried setting condition on Source and Destination as well but that also is not working.
Is there any way to default a field to null in case if crossover where clause condition is not met.
I was able to get this implemented by using automation script , but would like to know whether same can be achieved by some other means.
If it is just displaying the information you should use a multipart textbox to show lead and displayname of the person. You need to add a relation from workorder to person using the lead attribute. Then normal Maximo logic will clear the 'description' when you clear the actual lead field.
There is a way to cross-over fixed values, including null, to clear another field on a crossover action. Just make an ALNDOMAIN with a empty value (leave description empty) In the crossover domain use a relation that points to this specific domain/value and use dot-notation to crossover the description. Use relationname.description as the sourcefield in your crossover
RFE 72680 / crossovers, option to set targets to null or default value when trigger field becomes null is intended to address this shortfall in functionality. Please cast your vote!
Related
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.
According to the help pop up:
ID
This field's value represents the script ID, used to identify this
record for scripting purposes. It is a text field.
Internal ID
This field's value is a read-only system-generated unique identifier.
It is an integer field.
Both fields seem to uniquely identity a record type.
One is a string, one a integer.
The string ID is used for searches and
loading of records, but I've also seen Internal ID used when
referring to a record type from a lists point of view.
Can anyone provide the reasoning behind having two identifiers and when to use one versus the other when scripting?
The major difference is that you (as the creator of a custom record or script) are in complete control of the text ID. You can establish patterns and best practices for defining these IDs, and it will make it very easy for developers to identify record types just by looking at the string ID. You have no control over the numeric ID. When looking at code, it is much easier for me to determine what records I am referring to if it looks like:
nlapiSearchRecord('customrecord_product', null, filters, columns);
nlapiResolveURL('SUITELET', 'customscript_sl_orderservice', 'customdeploy_sl_orderservice')
as opposed to looking at:
nlapiSearchRecord(118, null, filters, columns);
nlapiResolveURL('SUITELET', 13, 1)
I'm not even sure the second nlapiSearchRecord actually works, but I know that nlapiResolveURL can be written that way.
That said, if you simply let NetSuite generate the text ID, you'll end up with generic IDs like customrecord1, which I find no more useful than the numeric ID. It is a good practice to explicitly specify your own IDs.
Furthermore, the numeric ID can vary between environments (e.g. Sandbox could be different than Production, until a subsequent refresh occurs). If you are following good migration practices, then the text ID should never vary between environments, so your code would not have to make any kind of decision on which ID to use based on environment.
Rarely have I found myself referencing any record, whether native or custom, by its numeric ID; scripts are always using the text ID to reference a record type.
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.
I am designing an application that will display dynamically-generated forms to the user who will then enter values into the form fields and submit those values for persistence. The form represents an employee evaluation.
One use case allows an administrator (from HR) to define the form fields. They should be able to create a new form, add/remove fields from a form and mark a form as 'deleted'.
The second use case is when a manager views the form and enters values into the form fields for a specific employee. They should be able to save the values at any time and recall the saved values when viewing the form again for the same employee.
Finally, when the manager is satisfied with the values they've entered for that employee, they can 'submit' the form data which persists the flattened data into the data warehouse for reporting purposes. When this is done, the 'working' copy of the data is removed so the form will display empty the next time they view it for that employee.
I am not concerned with the front-end at this point and working on the back-end service application that sits between the client and the data store. The application must provide a course-grained interface for all of the behavior required.
My question is how many aggregate roots do I actually have (and from that, how many repositories, etc)? Do I separate the form definition from the form data even though I need both when displaying the form to the user?
I see two main entities, 'EmployeeEvaluationSchema' and 'EmployeeEvaluation'. The 'EmployeeEvaluationSchema' entity would have a collection of 'FieldDefinition' value objects which would contain the properties that define a field, the most basic being the name of the field. The 'EmployeeEvaluation' entity would have a collection of 'FieldValue' value objects which contain the values for each field from the definition. In the simplest case, it would have a field name and value property. Next, the 'EmployeeEvaluation' could have a reference to 'EmployeeEvaluationSchema' to specify which definition the particular evaluation is based on. This can also be used to enforce the form definition in each evaluation. You would have two repositories - one for each entity. If you were to use an ORM such as NHibernate, then when you retrieve a 'EmployeeEvaluation' entity, the associated 'EmployeeEvaluationSchema' would also be retrieved even though there is a dedicated repository for it.
From your description it sounds like your objects don't have any behavior and are simple DTOs. If that is the case maybe you should not bother doing DDD. Can you imagine your entities without having getters? There are better ways to do CRUDish application than DDD. Again this is only valid if your "domain" does not have relevant behavior.
I am trying to do exactly same thing as post in NSFetchResultsController + sectionNameKeyPath + section order, i.e. basically use 2 tables, let's say Categories <-->> Events. Category table consists of category field only, while Event consists of name, dateTimestamp.
I defined relationship 'category' in Events table and try to use that relationship as sectionNameKeyPath when creating fetchedResultsController:
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:#"category.category" cacheName:#"Root"];
Finally, I pre-populated Category table with some categories upon loading of the app (and verified with .dump that table is populated correctly)
Yet, I simulator fails on:
return [[self.fetchedResultsController sections] count];
I did extensive search and most people either suggest using one of the fields in the table as sectionNameKeyPath (this works!) or transient property (works too!) However, I just want to use relationship as it seems very logical to me in this case where events belong to some categories and there could be categories without events. Am I wrong in my assumption that relationship can be used as sectionNameKeyPath? The original link at the top of the question suggests it works, but guy does not know why or how. Documentation is very weak on what can be used as sectionNameKeyPath, so any help will be highly appreciated.
A relationship gets you a pointer to a managed object. It seems logical, though, that the sectionNameKeyPath parameter should be a key path that leads to a string, since NSFetchedResultsSectionInfo's name property is a string. The fetched results controller will follow that key path for each fetched object and group the objects into sections based on what they return for that key path, and it'll also use those strings as the names of their respective sections. You can't use a managed object for the name -- you have to use some string property of the managed object.
So, your Category entity must have an attribute that distinguishes one category from another, right? Use that as the key path and (as you've seen) everything will work out.
BTW, I think it's useful to try to get out of the database (rows/fields) mindset and try to think in object-oriented terms like entity and attribute. A big selling point of Core Data is that it provides an abstraction layer that hides the storage mechanism. Thinking in terms of tables is like thinking about blocks and sectors when you're reading or writing a file.
Caleb, thank you for your answer. I do believe my understanding was wrong to some degree. What I had was an entity Category and entity Event. Category has a string field 'category', thus 'category.category' path (first 'category' is relationship in the Event entity)
What I did not take in account, though, is that if there are no events, fetchresultscontroller cannot fetch anything (similar to 'left join')
What I wanted is to show categories even if there are no events. Relationship 'category' will not return anything in this case as there is nothing to return/sort/categorize.
What I had to do (wrong or right - not sure yet) is to treat [managed] object created from Category entity as a separate object in case there are no events and place in the table. When there is one event per category, I can switch to the original method of [automatic] showing events sorted by categories.
This is interesting issue of starting point (empty entities with relationships) where I feel core data is more confusing than traditional relationship database. I also believe that's why all books/articles/reports carefully stay away from this topic. In other words, I could not find analog of "left join" in core data. May be I am wrong because I am relatively new to all this. Below is the description of the entities:
Category <-->> Event
Category - parent
Category.category - attribute of type String
Category.event - relationship to Event entity
Event - child
Event.name - attribute of type String
Event.category - relationship to Category entity
Each event belongs to one category. Category may have multiple events.
Categories should be shown even if there are no events for this category.
I was trying to put Events under fetchresultscontroller. May be I should switch to Category first and then calculate cell based on category.event relationship, not the other way around - did not try that yet.