Preventing fields from Editing Once Record is in Workflow

Preventing fields from Editing Once Record is in Workflow

I like this problem because it involves a few components to make it work.

The business problem that is being solved here is if the user would like a field or fields to not be editable once the work order, in this case, enters workflow.  This example focuses on the WORKTYPE field, but this script could easily be expanded to include other fields.

The components you will need for a successful script are:

  • A list of fields that will be made read only once record is in workflow.
  • A list of viable statuses for the workflow to know when the records should be evaluated.
  • A SQL query to determine if record is on workflow.
  • Setting fields to be read only if evaluation is true.

Creating a list of fields to be made read only

You can create a list of fields to be read only by using an array.  Here I only have one field but using an array gives you the flexibility to quickly add additional fields.

#List of fields that will be read only
readOnlyFields = ['WORKTYPE']
#Example with additional fields
readOnlyFields = ['WORKTYPE', 'DESCRIPTION']

Obtain list of viable workflow statuses

In this scenario we care about records that are actively in workflow.  So we get a list of statuses using the workflow status domain.

# Get a list of valid workflow assignment statuses
statusList = mbo.getTranslator().toExternalList("WFASGNSTATUS", "ACTIVE")

Query to determine if record Is actively in workflow

Construct a query to determine if the record is in workflow.

# Construct a where clause to find the existing workflow assignment 
# for this work order. Ensure that one exists before proceeding. 
whereClause = SqlFormat(mbo.getUserInfo(), "ownertable = :1 and ownerid = " + woId + " and assignstatus in (" + statusList + ")")
whereClause.setObject(1, "WFASSIGNMENT", "OWNERTABLE", "WORKORDER")

Setting field(s) flag to read only

If it is determined that the record is in workflow then we set the fields listed in the array, readOnlyFields to read only.

if not wfAssignmentSet.isEmpty():
    logger.error("WF Assignments assignments for this work order")
    # Make fields read only if the work order is in workflow
 	# There will be more read only fields.  Fields can also be made
    # required using the same principle.
 	mbo.setFieldFlag(readOnlyFields, MboConstants.READONLY, True)

Steps to create automation script

Create a new automation script with Object Launch Point. We called it WOPREVEDIT in this example.

Create a launch point with Initialize Value selected.

Here is the full automation script.

#Script: WORKORDER.INIT
#Make fields read only if record is in workflow
#Launch Point: WORKORDER.INIT
#Launch Point Type: OBJECT
#Launch Point Object: WORKORDER
#Language: Python
#Author: A3J Group
  
  
from psdi.mbo import SqlFormat
from psdi.server import MXServer
from psdi.util.logging import MXLoggerFactory
from psdi.mbo import MboConstants
  
logger = MXLoggerFactory.getLogger("maximo.script.woinit")
  
# Get the associated work order
wo = mbo.getString("WONUM")
woId = mbo.getLong("WORKORDERID")
#woId = str(woId)
#woId = woId.replace(',','')
  
#Logging
logger.info("Value for woId is " + str(woId))
  
#List of fields that will be read only. Add additional fields with a comma.
readOnlyFields = ['WORKTYPE']
  
# Get a list of valid workflow assignment statuses
statusList = mbo.getTranslator().toExternalList("WFASGNSTATUS", "ACTIVE")
  
# Construct a where clause to find the existing workflow assignment 
# for this work order. Ensure that one exists before proceeding. 
whereClause = SqlFormat(mbo.getUserInfo(), "ownertable = :1 and ownerid = " + str(woId) + " and assignstatus in (" + statusList + ")")
whereClause.setObject(1, "WFASSIGNMENT", "OWNERTABLE", "WORKORDER")
  
# Get record set and filter it by the where clause
wfAssignmentSet = mbo.getMboSet("$WOAPPR", "WFASSIGNMENT", whereClause.format())
wfAssignmentSet.reset()
  
if not wfAssignmentSet.isEmpty():
 	logger.info("Found WF Assignments for this WO – settings fields readonly")
 	# Make fields read only if the work order is in workflow
 	# There will be more read only fields.  Fields can also be made
    # required using the same principle.
 	mbo.setFieldFlag(readOnlyFields, MboConstants.READONLY, True)
 	
if mbo.getThisMboSet().getParentApp() == "WOTRACK":
 	woOwner = mbo.getOwner()

 

One of our missions A3J Group is to share knowledge whenever we can. We hope this helps you in your day!

Renewing SSL Certificates for IBM WebSphere and Apache Tomcat

Renewing a certificate for IBM WebSphere or Apache Tomcat is a relatively straightforward process.  There are, however, some subtle differences between renewing and installing a fresh certificate that I would like to document here primarily so I make it easier on myself the next time I need to simply renew a certificate.  If you are looking for more advanced information please consider these articles on configuring IBM WebSphere for SSL and installing or importing certificates into a WebSphere Trust Store.

If an IBM WebSphere or Apache Tomcat application server is nearing the validation end of their SSL certificates you can follow these steps to ensure that your servers remain secure and your user’s experiences are not interrupted.

IBM WebSphere

Step 1: Backup the existing certificate in case you need to revert.

  • Connect to the server where IBM WebSphere HTTP Server is installed. Navigate to the folder [IBM_HTTPServer_Home]\.
  • Backup or move the existing SSL certificate to an expired_certs folder Ex: C:\IBM\HTTPServer

renewing_ssl_certificate_websphere_apache_tomcat_ibm_maximo_update_ugrade_support_blog_help_tip_troubleshoot

Step 2: Copy the new certificate to IBM WebSphere HTTP Server home folder.

  • Copy the new Maximo SSL certificate to the [IBM_HTTPServer_Home]\ folder. If you need help requesting a new certificate, please refer to our article configuring IBM WebSphere for SSL.

Step 3: Launch IBM Key Management application to import new certificate

  • Launch the IBM Key Management application.
  • Click Export/Import button from the right-side button menu.
  • Select the Import Key radio button.
  • Change the Key file type to PKCS S12 using the drop-down menu.
  • Browser to the file name of the certificate that was copied in Step 3

ibm_maximo_blog_updating_ssl_certificate_websphere_server_security_renew_maximosecrets

  • Click the OK button. Supply the password associated with this certificate.

ibm_maximo_blog_renew_ssl_certificate_security_update_credentials_managed_service_self_help_how to

  • Click the OK button.
  • Select the label under Select a label to change. In the Enter a new label textbox provide a new label for this certificate.

  • Click the OK button.
  • Double-click the certificate that was just added with the new label.

ibm_maximo_blog_supprt_troubleshoot_fix_security_renew_ssl_certificate_update_websphere_apache_tomcat

  • Click the Set the certificate as the default checkbox at the bottom left.

ibm_maximo_blog_validation_of_ssl_certificate_update_websphere_apache_tomcat_troubleshoot_security

  • Click the OK button.
  • The certificate that was just added with the new label should now have an * next to its name.

ibm_maximo_websphere_update_apache_tomcat_renew_ssl_certificate_blog_troubleshoot_support

  • Click the OK button.
  • The certificate that was just added with the new label should now have an * next to its name.

 

Apache Tomcat

Step 1: Backup the existing certificate in case you need to revert.

  • Connect to the server where Apache Tomcat server is installed. Navigate to the folder [Apache_Tomcat_Home]\conf. Ex: C:\Apache\Tomcat\conf
  • Backup or move the existing SSL certificate to a certs folder.
  • Open the server xml file using a text editor.

ibm_maximo_suppprt_renew_new_ssl_cerificate_server_security_validation_websphere_apache_tomcat_blog

 

Step 2: Edit the server.xml file.

  • Locate the section <Connector port=”443” scheme=”https” . Change the name of the certificate if necessary.  Update the keystorePass value to the new password for the certificate.
  • NOTE: This is an XML document. Consequently, any ampersand or quote characters will need to be replaced.  For example, if your password is 1234”& then the value for keystorePass would be keystorePass=”1234&quot;&amp;”

How_to_renew_ssl_certificate_websphere_apache_tomcat_ibm_maximo

  • Save the server xml document and restart the Apache Tomcat service.

A3J Group Launches New Ninja Fix Solution: Approval Summary Tab Creator

A3J Group continues to produce products that can be purchased through our Ninja Fix suite of self-service IBM Maximo configuration options. The Approval Summary Tab solution was released March of 2022 and acts as a one-stop shop for viewing specific records in IBM Maximo.

The A3J Approval Summary solution introduces a new tab, Approval Summary, to the Work Order Tracking, Purchase Requisition, Purchase Order and Invoice applications. The Approval Summary tab is designed to show both the Active Assignee, to whom the record is currently assigned, and a history of approvals. At a glance you will know immediately who is responsible for approving the record as well as where the record is at in the approval chain. Instead of having users navigate the workflow history and assignment applications to determine the approval status for a record you can simply point them to the Approval Summary tab for all the pertinent information.

The Approval Summary solution consists of a tab with two tables. The first table displays the current active assignee(s) for the record.

ibm-maximo-self-service-managed-service-configuration

This table contains the user ID and display name of the active assignee(s). In addition, a description of the assignment is included for easy reference.

The second table lists the approval history of the record. The user can see who previously approved the record, any memo that was included with approval of the record as well as some workflow details.

ibm-maximo-automation-scripts-work-order-tracking-purchase-requistion-purchase-order-invoice-application

The Approval Summary tab focuses only on workflow transactions originating from an Input node and that are either assigned or reassigned in order to reduce clutter and help the user focus solely on the assignment. Additional nodes may be included by simply updating the A3JWFTRANSACTION relationship on the parent object. You can also contact A3J Group for assistance with expanding the Approval Summary design to other use cases.

 

ibm-maximo-configuration-approval-summary-tab-record-approval-status-history-assignment

 

Learn more about the Approval Summary Tab creator and other solutions from Ninja Fix here. If the solution is a fit, purchase, download and experience immediate IBM Maximo enhancements from A3J Group today!

Product Launch: Automated Label Printing from NinjaFix

The A3J Label Printing report solution includes a report and an automated process to print labels as items
and materials are received. The printer used by the storeroom is defined on the storeroom record. If only
a single printer is used across all storerooms, then the automation script may be adjusted to use a system
property.

The goal of the automation is to proactively notify warehouse personnel when an item or material is
received through a printed label report. The label report should contain information about the received
item or material with bar-coded fields to enable scanning. The labels can automatically be fixed to parts
(materials) that are received.

The report that prints at the storeroom will have all the information that the warehouse operations staff
will need to fulfill the request. It will also have bar codes for key fields that will enable mobile applications
to quickly scan and perform inventory transactions against the reservation. A3J recommends pairing this
report solution with its own suite of mobile applications called MxMobile.

This solution includes a report built and tested to work with a Zebra printer. Specifically, a Zebra 410 and
520 portable printers but should work with any label printer that supports a 4.09”x2.00” format.

The report label is built to print the following fields:

• Item number (with barcode)
• Item description
• Purchase Order number (with barcode)
• Purchase Order line number
• Bin number if received into a bin
• Quantity at receipt (custom field included in solution)
• Work Order number (with barcode)

If either item number or work order number fields are blank the label rows will be blank saving space for
additional information. To purchase click here!

A3J Group Launches Ninja Fix

Ninja Fix is a suite of useful Maximo solutions that tackle the everyday needs of Maximo users. The efficiency and effectiveness of these solutions give way to the name, “Ninja Fix.”

Continue reading

Unable to Find Records in IBM Maximo

If you are searching for items and your descriptions do not present any search returns then you may need to read this article…

IBM Maximo attributes such as the Description field are natively configured to use TEXT search instead of WILDCARD.  A text search will use the database’s text search engine.  This is important because text searches are more efficient due to the database using indexes to locate records.  In addition, a text search is not case-sensitive so users typically prefer this type of search over WILDCARD.

I recently had an experience where an IBM Maximo environment using a Microsoft SQL Server database was unable to locate item records using the search term ‘WELL PUMP’ on the Description field.  A search for ‘WELL’, ‘%WELL%’, or ‘WELL PUMP’ brought back zero records.  The pump could only be found by searching for ‘PUMP’.

Since ITEM.DESCRIPTION is a text search enabled attribute, I knew it had to be full text search related. However I was unsure how it was related.  I first rebuilt the text catalog located under Databases > [database_name] > Storage > Full Text Catalogs > [text_catalog_name].

Maximo-Object-Explorer

A rebuild of the catalog had no effect.  Next I increased logging on the ITEM object so I could get the exact query IBM Maximo was sending to the Microsoft SQL Server.  This produced the following query:

select *

from item 

where ((status != 'OBSOLETE' and contains(description , 'FORMSOF(INFLECTIONAL,"WELL")') 

and itemsetid = ITEMSET1))

and (itemtype in (select value from synonymdomain where domainid='ITEMTYPE' and maxvalue = 'ITEM'))

Running the above query in SQL Server Management Studio produces zero records.  I was getting closer! The complexity of some of IBM Maximo enterprise asset management system requires much patience, and thoroughness, especially when troubleshooting…

The downside is that there is no shortage of articles on the Web discussing SQL Servers Full Text search capabilities.  I found myself down quite the rabbit hole.  My esteemed coworker, Kelly Nimmo, dropped in to set me down the correct path as she so often does.  She suggested I look into something called a Stop List.

A Stop List in SQL Server is a list of commonly occurring words that SQL Server will discard while searching.  These words are omitted from the full-text index.  A query of the SYS.FULLTEXT_SYSTEM_STOPWORDS table

SELECT * FROM sys.fulltext_system_stopwords where stopword = 'WELL'

for the word ‘WELL’ reveals the following entries:

Search-feature-Stopword

Bingo!  I now had a decision to make.  I could look at removing these entries from the table. Instead, I chose to omit the ITEM table from using the Stop Word list via the following statement:

ALTER FULLTEXT INDEX ON dbo.item SET STOPLIST = OFF

I will roll this out to other tables where WELL may be used to prevent this behavior in the future.

Maximo Bug with Start Center Result Set and Custom Application

I created a query and then added a result set to the Start Center for our custom application.   In the Result Set portlet the query was chosen but no fields were displaying in the Available List or objects in the Object List.

The reason for the empty fields was ultimately due to a database length field issue on two objects: RESULTSETCOLS and RSCONFIGSELECT.  The APP attribute field length is 10 but our custom application name length was 11.

 

Increasing the attribute length for APP in RESULTSETCOLS and RSCONFIGSELECT followed by a database configuration corrected the problem which resulted in the Object List and Available Fields list displaying the appropriate information.

 

This was in Maximo 7.6.0.8 so the problem may already be corrected in a patch.

 

 

 

Enable Logging to Capture Report Data Set Queries in Maximo 7.6

You upload your awesome new report in Maximo, click the Preview button or run the report and…. you get no results.  Is the problem in the Maximo Where clause, the report query or …?  Naturally you turn to the Maximo Logging application, crank up the SQL and Report loggers to DEBUG then sit back and comb through all those juicy log statements that pinpoint exactly where the problem resides.  Sound familiar?  

Of course not!  You crank up all that logging and comb through a whole bunch of nothing.   

This article will detail one way to coax Maximo into giving up all the information you need to properly diagnose your report running in Maximo 7.6.  You may not need to perform all these steps; however, I was not able to see exactly what I needed until I performed the last step.  

The report I was developing was based on the ASSET application and was rather complicated.  Consequently I wanted a lot of information ouof Maximo.  You may not need or want all these loggers running to diagnose your report so feel free to adjust these steps to suit your specific requirements. Keep in mind that if you do not see what you want in the log execute all these steps and get it working.  Then you can pare it down to be more efficient. 

Set appropriate loggers to DEBUG using the Maximo Logging application. 

 

As I mentioned, the report I was working on was based on ASSET. I wanted to see both ASSET object queries and report queries.  Navigate to the Logging application Maximo and filter the Logger list to show sql. 

 

 

Change the log level to Debug anApply Settings so the changes take effect. 

If you execute the report now all you will see is some SQL statements as you navigate around the ASSET object filtering the records for your eventual report.  While potentially useful in providing a complete picture of the data being requested it is most likely not what we need to figure out why our report is not displaying any records.  In order to see Birt and report related log statements we need to adjust the log level of the report logger. 

Filter the Logging application by report and adjust the log level to DEBUG for the report logger as well as the birt and directprint loggers.  Do not forget to Apply Settings. 

 

Setting additional Report loggers to DEBUG. 

 

If you, like me, run your report you still will not see what you want in the log.   

In order to see the report parameters, where clauseactual DataSet query being used and a whole bunch of other report information I had to execute the following sql statement against my Maximo database. 

update maxlogger set loglevel = ‘DEBUG’ where logkey like ‘log4j.logger.maximo.report%; 

Be sure to commit the update if not using SQL Server.   

You will need to restart the Maximo application server after this update.  The logger update will not take effect until the Maximo application is restarted.   

Now if you run the report you will see the actual queries being executed from within Maximo.       

Better Error Messaging from Maximo Web Service Response

You are ready to test drive your perfect web service that you just spent the last few minutes constructing in Maximo.  A final comparison is performed on your test message to ensure that the structure of the XML is aligned with your object structure.  You are satisfied with the message and it is placed in SOAPUI or your favorite XML test engine.  The message is sent and the response you receive is:

Internal Error

In this example I am trying to add my labor code using an organization identifier that does not exist in my Maximo system.  The response in no way helps me understand the problem however.

Internal Error?  How “internal” should I look?  Could the message possibly be vaguer?  With a sigh it’s off to the logs in order to find more information.  All the while hoping that the message hasn’t rolled off into a backup log.

Thankfully there is a way to configure WebSphere 8.5.X and newer to display the Maximo error code in the response message.

Log in to the WebSphere Administration Console and navigate to WebSphere Application Servers.  Click on your application server.

On the right side under Server Infrastructure expand Java and Process Management and select Process Definition.

 

Select Java Virtual Machine.

Select Custom Properties.

 

Click New and enter the following information.

Name: webservices.unify.faults

Value: false

Click Apply or Ok.  Save and restart the WebSphere Application Server.  Note that all you have to do is navigate to WebSphere application servers and restart the server from there.  You do not have to restart all WebSphere services or the Cell or Node.

After the application server has restarted retry your message in SOAPUI.  You should see a Maximo error code along with a more helpful message.

Considerations

The property is set to true by default in order to restrict the information that is sent as part of the error code.  Consequently, this is a property that should most likely not be available in a production setting or in an environment with sensitive data that is exposed as a web service.  However, in a development environment this setting can speed up the creation and testing of web services.

This information can also be found in the IBM Upgrade Guide Maximo Products V7.5 to V7.6.