Download presentation
Presentation is loading. Please wait.
Published byLeonard Benson Modified over 9 years ago
1
1 Customizing Kuali: A Technical Perspective Naser Alavi (Michigan State University) Warren Liang (University of California, Irvine)
2
2 Customizing Kuali Outline: System Parameters Business Rules Authorization class Pre-Rules
3
3 Customizing Kuali Which aspects of Kuali are we customizing in this presentation? –Customizing business rules –Customizing authorization –Customizing system parameters
4
4 System Parameters/Rules Purpose: Externalizing constants out of code They may be maintained by a non- developer via a maintenance document. The code must be programmed to access the constant value(s) by its unique key.
5
5 System Parameters Use Cases Where they may be used: Business rule checks Any place where runtime changes to values displayed within the application will be needed without a restart of the application server
6
6 System Parameters The System Parameters can be used in the following manners: Key-value constants –(key=DEBIT, value=D) Key-value group constants –(key=VALID_OBJECT_CODES_FOR_XYZ, value=5000;5001;3400;2300)
7
7 System Parameters Use Cases Where they may not / should not be used: System configuration values that can’t be represented as constants/literals in the code Core constants that will not change no matter what the installation Spring XML configuration files - you cannot have XML files use this mechanism OJB XML configuration or descriptor files - you cannot have XML files use this mechanism
8
8 System Parameters Table A single parameter record has a composite key made up of: –Parameter Name –Parameter Security Grouping This composite key helps to categorize our constants. –As an enhancement for next phase to further modularize these parameters a new “Module Code” field will be added to this table
9
9 Using System Parameters Using the System Parameters for Key-Value Constants: String MANDATORY_TRANSFER = kualiConfigurationService.getApplicationParameter("TransactionProcessingEDocs", "Chart.SubObjectCode.MandatoryTransfer"); if (financialSubObjectCode.equals(MANDATORY_TRANSFER)) {...
10
10 Using System Parameters Using the System Parameters for Key- Value Lists of Constants (array of values) String[] VALID_OBJ_SUB_TYPES_FOR_TOF = SpringServiceLocator.getKualiConfigurationService().getApplicationParameters("TransactionProcessing", "ValidObjectSubTypeCodesForTofAccountingLines"); if(ArrayUtils.contains(VALID_OBJ_SUB_TYPES_FOR_TOF, accountingLine.getFinancialSubObjectCode())) {...
11
11 System Parameter Security Class/Table The following class represents a security grouping which is identified by its security group name. Each security grouping has a workgroup associated with it for authorization purposes.
12
12 System Parameter Security Class/Table public class FinancialSystemParameterSecurity extends PersistableBusinessObjectBase { … // script name is the security group private String financialSystemScriptName; private String workgroupName; private String financialSystemScriptDescription; private List financialSystemParameters; …
13
13 System Parameter Attributes The following class represents a KFS parameter with an associated text value. This text value can be interpreted as a single value or a semicolon delimited list of values The parameter name and the security group name make up the primary key for this business object The security group name is the link to the System Parameter Security Table
14
14 System Parameter Attributes public class FinancialSystemParameter extends PersistableBusinessObjectBase { … private String financialSystemScriptName; private String financialSystemParameterName; private String financialSystemParameterText; private String financialSystemParameterDescription; private boolean financialSystemMultipleValueIndicator; private FinancialSystemParameterSecurity financialSystemParameterSecurity; …
15
15 Business Rules Maintained by Business Rules Tables Allows Functional Users to maintain and create business rules (to some extent). Allows institutions to customize out of the box business rules based on their codes and policies.
16
16 Business Rules Uses KualiParameterRule object for evaluating business rules This object holds the underlying rule record values and provides a convenience method for the evaluation of the rule You can retrieve the values of a rule record as a KualiParameterRule by using the KualiConfigurationService method: KualiParameterRule getApplicationParameterRule(String scriptName, String parameter)
17
17 Business Rule From Administration Tab
18
18 Business Rule Security Example
19
19 Business Rule Example
20
20 Business Rule Examples
21
21 Sample Code Using Business Rule in TaxNumberService /** * Splits the set of tax number formats which are returned * from the rule service as a semicolon-delimited String * into a String array. * * @return A String array of the tax number format regular expressions. */ public String[] parseSSNFormats() { if(taxNumberFormats == null) { taxNumberFormats = SpringServiceLocator.getKualiConfigurationService().getAppl icationRule("PurapAdminGroup","PURAP.TAX_NUMBER_FORMATS"); } String taxFormats = taxNumberFormats.getRuleText(); return taxFormats.split(";"); }
22
22 Sample Code Using Business Rule in TaxNumberService public boolean isValidTaxNumber( String taxNbr, String taxType ) { String[] ssnFormats = parseSSNFormats(); String[] feinFormats = parseFEINFormats(); Integer defaultTaxNbrDigits = new Integer (SpringServiceLocator.getKualiConfigurationService().getApplicationParameterValue("PurapAdminGroup", "PURAP.DEFAULT_TAX_NUM_DIGITS")); if (taxNbr.length() != defaultTaxNbrDigits || !isStringAllNumbers(taxNbr)) { return false; }
23
23 Business Rule Attributes package org.kuali.core.bo; public class BusinessRule extends PersistableBusinessObjectBase { private String ruleGroupName; private String ruleName; private String ruleText; private String ruleDescription; private String ruleOperatorCode; private boolean financialSystemMultipleValueIndicator; private boolean financialSystemParameterActiveIndicator; BusinessRuleSecurity ruleGroup;
24
24 System Parameters/Rules Summary: Create and populate workgroup that should have maintenance permission Create corresponding security group Create parameter (value to control runtime system behavior) or rule (definition of legal/illegal values)
25
25 Customizing Kuali Outline: System Parameters Business Rules Authorization class Pre-Rules
26
26 Putting It All Together Defining a Transactional Document –Payment Request Doc DD XML –Payment Request Rule –Payment Request Authorizer –Payment Request Pre-Rule (using question framework) –Demo New Payment Request Document functionality and sample code
27
27 Plugging Business Rules Class “Pluggable” business rules –Specify business rule implementation in document’s data dictionary file – Registering your business rule class with a document type. –The fully qualified classname of the business rule class must be specified with the tag in the document's data dictionary file.
28
28 Plugging Business Rules Class Example, KualiPaymentRequestDocument.xml: org.kuali.module.purap.document.PaymentRequestDocument org.kuali.module.purap.rules.PaymentRequestDocumentRule
29
29 Plugging Business Rules Class “Pluggable” business rules –Normally used to detect errors on a form –Since these are written in Java, it is much more expressive than just matching –Has access to all Kuali services –The rules framework creates a copy of the document so that any changes made during rule application will not affect the document when it is persisted.
30
30 Payment Request Rule Hierarchy
31
31 Business Rule Framework
32
32 DocumentRuleBase DocumentRuleBase implements common checks that should be run after every event, and rule implementations should extend this class Instead of overriding the methods defined by the *DocumentRule interfaces, override the processCustom* methods defined in this class (e.g. to define new save rules, override processCustomSaveDocumentBusinessRules instead of processSaveDocument)
33
33 Associating Rules with Events (Save Example) package org.kuali.core.rule; /** * Defines a rule which gets invoked immediately before a document gets saved. */ public interface SaveDocumentRule extends BusinessRule { /** * @param document * @return false if the rule fails */ public boolean processSaveDocument(Document document); }
34
34 Associating Rules with Events and Using Common Services /** * This class contains all of the business rules that are common to all documents. */ public abstract class DocumentRuleBase implements SaveDocumentRule, RouteDocumentRule, ApproveDocumentRule, AddNoteRule, AddAdHocRoutePersonRule, AdHocRouteWorkgroupRule { private static UniversalUserService universalUserService; private static KualiModuleService kualiModuleService; private static DictionaryValidationService dictionaryValidationService; private static KualiWorkflowInfo workflowInfoService; private static KualiConfigurationService kualiConfigurationService;
35
35 DocumentRuleBase Rule Implementation public abstract class DocumentRuleBase implements SaveDocumentRule, … { public boolean processSaveDocument(Document document) { boolean isValid = true; isValid &= isDocumentOverviewValid(document); if (isValid) { isValid &= processCustomSaveDocumentBusinessRules(document); } return isValid; } protected boolean processCustomSaveDocumentBusinessRules (Document document) { return true; }
36
36 DocumentRule Sample public class PaymentRequestDocumentRule extends AccountsPayableDocumentRuleBase { @Override protected boolean processCustomSaveDocumentBusinessRules (Document document) { PaymentRequestDocument paymentRequestDocument = (PaymentRequestDocument) document; return processValidation(paymentRequestDocument); }
37
37 DocumentRule Sample public class PaymentRequestDocumentRule extends AccountsPayableDocumentRuleBase { …. @Override public boolean processValidation(PurchasingAccountsPayableDocument purapDocument) { boolean valid = super.processValidation(purapDocument); valid &= processInvoiceValidation((PaymentRequestDocument)pura pDocument); valid &= processPurchaseOrderIDValidation((PaymentRequestDocum ent)purapDocument); valid &= processPaymentRequestDateValidation((PaymentRequestDo cument)purapDocument); return valid; }
38
38 Customizing Kuali Outline: System Parameters Business Rules Authorization class Pre-Rules
39
39 Plugging Authorizer Class Modifying Authorizations for a Document Type –Payment Request Document Initiators in Doc DD XML Complex Rules in Document Authorizer Class Approvals in Workflow
40
40 Plugging Authorizer Class Authorization DD File Code Sample: org.kuali.module.purap.document.PaymentRequestDocument org.kuali.module.purap.document.PaymentRequestDocumentAuthorizer kualiUniversalGroup KualiPaymentRequestDocument PREQ
41
41 Document Authorizer The document authorizer framework: –Determines a user can initiate a document –How document fields are rendered –What buttons are displayed
42
42 Create New Payment Request
43
43 Checking for Duplication
44
44 Showing Other Action Buttons
45
45 Code Modules for PaymentRequest The functionality demoed was accomplished through codes in: PaymentRequestDocumentAuthorizer PaymentRequestDocumentRule (already discussed) PaymentRequestAction
46
46 PaymentRequestDocumentAuthorizer Overrode these methods: hasInitiateAuthorization –Simple true/false value getEditMode –A map of mode -> value mappings. The JSP layer uses these mappings to determine how it should render the document getDocumentActionFlags –Returns an object with numerous boolean flags, indicating whether a button may be rendered
47
47 PaymentRequestDocumentAuthorizer @Override public boolean hasInitiateAuthorization(Document document, UniversalUser user) { String authorizedWorkgroup = SpringServiceLocator.getKualiConfigurationService().getAppl icationParameterValue(PurapRuleConstants.PURAP_ADMIN_GROUP, PurapRuleConstants.PURAP_DOCUMENT_PO_ACTIONS); try { return SpringServiceLocator.getKualiGroupService().getByGroupName( authorizedWorkgroup).hasMember(user); } catch (GroupNotFoundException e) { throw new RuntimeException("Workgroup " + authorizedWorkgroup + " not found",e); }
48
48 PaymentRequestDocumentAuthorizer @Override public Map getEditMode(Document document, UniversalUser user, List sourceAccountingLines, List targetAccountingLines) { Map editModeMap = super.getEditMode(document, user, sourceAccountingLines, targetAccountingLines); PaymentRequestDocument paymentRequestDocument = (PaymentRequestDocument)document; if (StringUtils.equals(paymentRequestDocument.getStatusCode(), PurapConstants.PaymentRequestStatuses.INITIATE)){ editModeMap.put(PurapAuthorizationConstants.PaymentRequestE ditMode.DISPLAY_INIT_TAB, "TRUE"); } else { editModeMap.put(PurapAuthorizationConstants.PaymentRequestE ditMode.DISPLAY_INIT_TAB, "FALSE"); } return editModeMap; }
49
49 PaymentRequestDocumentAuthorizer The JSP uses the values in the edit mode map to determine how to render the document. Example from PaymentRequest.jsp
50
50 PaymentRequestDocumentAuthorizer @Override public DocumentActionFlags getDocumentActionFlags(Document document, UniversalUser user) { DocumentActionFlags flags = super.getDocumentActionFlags(document, user); KualiWorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument(); PaymentRequestDocument paymentRequestDocument = (PaymentRequestDocument)document; if (StringUtils.equals(paymentRequestDocument.getStatusCode(), INITIATE)){ flags.setCanSave(false); flags.setCanClose(false); flags.setCanCancel(true); } else { flags.setCanSave(true); } return flags; }
51
51 Payment Request Duplication Scenario Needed to check for Payment Request duplication before even validating business rules In case of duplication give the user a warning and the option of override the warning and continue or to cancel We used the question framework for this Demo this in action in Payment Request Demo the code (paymentRequestAction.continuePREQ())
52
52 PaymentRequestAction public ActionForward continuePREQ(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { PaymentRequestForm preqForm = (PaymentRequestForm) form; PaymentRequestDocument paymentRequestDocument = (PaymentRequestDocument) preqForm.getDocument(); Map editMode = preqForm.getEditingMode(); Object question = request.getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_N AME); PaymentRequestService paymentRequestService = SpringServiceLocator.getPaymentRequestService(); HashMap duplicateMessages = paymentRequestService.paymentRequestDuplicateMessages(payme ntRequestDocument);
53
53 PaymentRequestAction (Continued) if (!duplicateMessages.isEmpty()){ if (question == null) { // ask question if not already asked return this.performQuestionWithoutInput(mapping, form, request, response, PREQDocumentsStrings.DUPLICATE_INVOICE_QUESTION, duplicateMessages.get(PREQDocumentsStrings.DUPLICATE_INVOICE_QUESTIO N), KFSConstants.CONFIRMATION_QUESTION, KFSConstants.ROUTE_METHOD, ""); } Object buttonClicked = request.getParameter(KFSConstants.QUESTION_CLICKED_BUTTON); if ((PurapConstants.PREQDocumentsStrings.DUPLICATE_INVOICE_QUESTION.equ als(question)) && ConfirmationQuestion.NO.equals(buttonClicked)) { // if no button clicked just reload the doc in the // INITIATE status and let the user to change the // input values paymentRequestDocument.setStatusCode(PurapConstants.PaymentRequestSt atuses.INITIATE); return mapping.findForward(KFSConstants.MAPPING_BASIC); }
54
54 Customizing Kuali Outline: System Parameters Business Rules Authorization class Pre-Rules
55
55 Pre-Rules Use Cases Pre-Rules allow –Modification of values after form submission (e.g. auto-fill values, possibly based on other values on the form) –Switching to another page after clicking the button (e.g. go to a confirmation page)
56
56 Pre-Rules Configuration Pre-rules for documents are configured in the data dictionary by specifying a class name for the implementation Example: in UniversalUserMaintenanceDocument.xml org.kuali.core.rules.UniversalUserPreRules
57
57 Pre Rule Checks Architecture
58
58 PreRulesCheck Interface public interface PreRulesCheck { /** * Callback method from Maintenance action that allows checks to be done and response redirected via the PreRulesCheckEvent * * @param form * @param request * @param event * @return boolean indicating whether routing should stop or continue */ public boolean processPreRuleChecks(ActionForm form, HttpServletRequest request, PreRulesCheckEvent event); }
59
59 PreRulesContinuationBase This class simplifies requesting clarifying user input prior to applying business rules. It mostly shields the classes that extend it from being aware of the web layer, even though the input is collected via a series of one or more request/response cycles.
60
60 PreRulesContinuationBase
61
61 PreRulesContinuationBase public abstract class PreRulesContinuationBase implements PreRulesCheck { protected String question; protected String buttonClicked; protected PreRulesCheckEvent event; protected KualiForm form; public abstract boolean doRules(Document document);
62
62 PreRulesContinuationBase public boolean processPreRuleChecks(ActionForm form, HttpServletRequest request, PreRulesCheckEvent event) { … try { result = doRules(event.getDocument()); } catch (IsAskingException e) { return false; } if (isAborting) { return false; } return result; }
63
63 PreRulesCheckEvent
64
64 Putting PreRules* in Action Pre-rules are invoked automatically by the framework before routing, approving, and blanket approving a document. Can also force the invocation of a pre-rule by overriding the Struts action handler of the document.
65
65 Example 1: Adding a pre-rule check public class BudgetParametersAction extends BudgetAction { public ActionForward deletePeriodLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { // do some processing ActionForward preRulesForward = preRulesCheck(mapping, form, request, response); if (preRulesForward != null) { return preRulesForward; } return mapping.findForward(KFSConstants.MAPPING_BASIC); } …
66
66 Example 2: UniversalUserPreRules public class UniversalUserPreRules extends PreRulesContinuationBase { public boolean doRules(Document document) { MaintenanceDocument maintenanceDocument = (MaintenanceDocument) document; UniversalUser newUser = (UniversalUser) maintenanceDocument.getNewMaintainableObject().getBusinessO bject(); Field nameField = FieldUtils.getPropertyField( UniversalUser.class, PropertyConstants.PERSON_NAME, false ); ControlDefinition controlDef = KNSServiceLocator.getDataDictionaryService().getAttributeCo ntrolDefinition(UniversalUser.class, PropertyConstants.PERSON_NAME );
67
67 Example 2: UniversalUserPreRules (continued) if ( controlDef.isHidden() || nameField.isReadOnly() || StringUtils.isBlank( newUser.getPersonName() ) ){ if ( !StringUtils.isBlank( newUser.getPersonFirstName() ) && !StringUtils.isBlank( newUser.getPersonLastName() ) ){ if ( !StringUtils.isBlank( newUser.getPersonMiddleName() ) ) { newUser.setPersonName( newUser.getPersonLastName()+"," +newUser.getPersonFirstName() + " " + newUser.getPersonMiddleName() ); } else { newUser.setPersonName( newUser.getPersonLastName()+"," +newUser.getPersonFirstName() ); } boolean success = true; List modules = KNSServiceLocator.getKualiModuleService().getInstalledModules(); PreRulesContinuationBase rule = null; for ( KualiModule module : modules ) { rule = (PreRulesContinuationBase) module.getModuleUserPreRules(); if ( rule != null ) { success &= rule.doRules( document ); }
68
68 Pre-Rule Scenario Sample 3 Pre-Rules could be used to derive values based on other values, or Setting a default value where needed and the user didn’t enter any value –See next sample code
69
69 Example 3: Set Unconditional Defaults public class DelegateChangePreRules implements PreRulesCheck {... private void setUnconditionalDefaults(DelegateChangeContainer newDelegateChangeContainer) { for (DelegateChangeDocument newDelegateChange : newDelegateChangeContainer.getDelegateChanges()) { // FROM amount defaults to zero if (newDelegateChange.getApprovalFromThisAmount()==null) { newDelegateChange.setApprovalFromThisAmount(new KualiDecimal(0)); } // TO amount defaults to zero if (newDelegateChange.getApprovalToThisAmount()==null) { newDelegateChange.setApprovalToThisAmount(new KualiDecimal(0)); }
70
70 Summary System parameters –Provides on-the-fly configuration of certain components Business Rules –Provides business rules based on matching values
71
71 Summary “Pluggable” business rules –Java-based implementation of rules that are more complicated than simple matching Pre-rules –Allows modification of form values prior to processing –Allows “redirection” to a different page
72
72 Questions? kualitestdrive@oncourse.iu.edu
73
73 References System parameters/ business rules https://test.kuali.org/confluence/x/-kw Pluggable business rules https://test.kuali.org/confluence/x/5l Pre-rules https://test.kuali.org/confluence/x/WFE Kuali Nervous System (KNS) https://test.kuali.org/confluence/x/EU8
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.