001 /*
002 * Copyright 2011 The Kuali Foundation.
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.kfs.module.purap.document.authorization;
017
018 import java.util.List;
019 import java.util.Set;
020
021 import org.apache.commons.lang.StringUtils;
022 import org.kuali.kfs.module.purap.PurapAuthorizationConstants;
023 import org.kuali.kfs.module.purap.PurapConstants;
024 import org.kuali.kfs.module.purap.PurapParameterConstants;
025 import org.kuali.kfs.module.purap.PurapWorkflowConstants;
026 import org.kuali.kfs.module.purap.PurapAuthorizationConstants.PurchaseOrderEditMode;
027 import org.kuali.kfs.module.purap.PurapConstants.PurchaseOrderStatuses;
028 import org.kuali.kfs.module.purap.PurapConstants.RequisitionSources;
029 import org.kuali.kfs.module.purap.document.PurchaseOrderDocument;
030 import org.kuali.kfs.module.purap.document.service.PurapService;
031 import org.kuali.kfs.sys.context.SpringContext;
032 import org.kuali.kfs.sys.service.impl.KfsParameterConstants;
033 import org.kuali.rice.kns.document.Document;
034 import org.kuali.rice.kns.service.ParameterService;
035 import org.kuali.rice.kns.util.ObjectUtils;
036 import org.kuali.rice.kns.workflow.service.KualiWorkflowDocument;
037
038
039 public class PurchaseOrderDocumentPresentationController extends PurchasingAccountsPayableDocumentPresentationController {
040
041 @Override
042 protected boolean canEdit(Document document) {
043 PurchaseOrderDocument poDocument = (PurchaseOrderDocument)document;
044
045 if (!PurchaseOrderStatuses.IN_PROCESS.equals(poDocument.getStatusCode()) &&
046 !PurchaseOrderStatuses.WAITING_FOR_DEPARTMENT.equals(poDocument.getStatusCode()) &&
047 !PurchaseOrderStatuses.WAITING_FOR_VENDOR.equals(poDocument.getStatusCode()) &&
048 !PurchaseOrderStatuses.QUOTE.equals(poDocument.getStatusCode()) &&
049 !PurchaseOrderStatuses.AWAIT_PURCHASING_REVIEW.equals(poDocument.getStatusCode()) &&
050 !PurchaseOrderStatuses.AWAIT_NEW_UNORDERED_ITEM_REVIEW.equals(poDocument.getStatusCode()) &&
051 !PurchaseOrderStatuses.CHANGE_IN_PROCESS.equals(poDocument.getStatusCode())) {
052 return false;
053 }
054 return super.canEdit(document);
055 }
056
057 @Override
058 protected boolean canFyi(Document document) {
059 PurchaseOrderDocument poDocument = (PurchaseOrderDocument) document;
060 if (PurchaseOrderStatuses.PENDING_PRINT.equals(poDocument.getStatusCode())) {
061 return false;
062 }
063 return super.canFyi(document);
064 }
065
066 @Override
067 protected boolean canCancel(Document document) {
068 PurchaseOrderDocument poDocument = (PurchaseOrderDocument)document;
069
070 if (poDocument.isPendingSplit() || poDocument.getAssigningSensitiveData()) {
071 return false;
072 }
073
074 return super.canCancel(document);
075 }
076
077 @Override
078 protected boolean canClose(Document document) {
079 PurchaseOrderDocument poDocument = (PurchaseOrderDocument)document;
080
081 if (poDocument.isPendingSplit() || poDocument.getAssigningSensitiveData()) {
082 return false;
083 }
084
085 return super.canClose(document);
086 }
087
088 @Override
089 protected boolean canReload(Document document) {
090 PurchaseOrderDocument poDocument = (PurchaseOrderDocument)document;
091
092 if (poDocument.isPendingSplit() || poDocument.getAssigningSensitiveData()) {
093 return false;
094 }
095
096 return super.canReload(document);
097 }
098
099 @Override
100 protected boolean canSave(Document document) {
101 PurchaseOrderDocument poDocument = (PurchaseOrderDocument)document;
102
103 if (poDocument.isPendingSplit() || poDocument.getAssigningSensitiveData()) {
104 return false;
105 }
106
107 return super.canSave(document);
108 }
109
110 @Override
111 protected boolean canRoute(Document document) {
112 PurchaseOrderDocument poDocument = (PurchaseOrderDocument)document;
113 String statusCode = poDocument.getStatusCode();
114
115 if (StringUtils.equals(statusCode, PurchaseOrderStatuses.WAITING_FOR_DEPARTMENT) ||
116 StringUtils.equals(statusCode, PurchaseOrderStatuses.WAITING_FOR_VENDOR) ||
117 StringUtils.equals(statusCode, PurchaseOrderStatuses.QUOTE)) {
118 return false;
119 }
120
121 if (poDocument.isPendingSplit()) {
122 return false;
123 }
124
125 return super.canRoute(document);
126 }
127
128 @Override
129 public Set<String> getEditModes(Document document) {
130 Set<String> editModes = super.getEditModes(document);
131 KualiWorkflowDocument workflowDocument = document.getDocumentHeader().getWorkflowDocument();
132 PurchaseOrderDocument poDocument = (PurchaseOrderDocument)document;
133 String statusCode = poDocument.getStatusCode();
134
135 editModes.add(PurchaseOrderEditMode.ASSIGN_SENSITIVE_DATA);
136
137 //if the ENABLE_COMMODITY_CODE_IND system parameter is Y then add this edit mode so that the commodity code fields would display on the document.
138 boolean enableCommodityCode = SpringContext.getBean(ParameterService.class).getIndicatorParameter(KfsParameterConstants.PURCHASING_DOCUMENT.class, PurapParameterConstants.ENABLE_COMMODITY_CODE_IND);
139 if (enableCommodityCode) {
140 editModes.add(PurchaseOrderEditMode.ENABLE_COMMODITY_CODE);
141 }
142
143 if (canFirstTransmitPrintPo(poDocument)) {
144 editModes.add(PurchaseOrderEditMode.PRINT_PURCHASE_ORDER);
145 }
146
147 if (canPreviewPrintPo(poDocument)) {
148 editModes.add(PurchaseOrderEditMode.PREVIEW_PRINT_PURCHASE_ORDER);
149 }
150
151 if (canResendCxml(poDocument)) {
152 editModes.add(PurchaseOrderEditMode.RESEND_PURCHASE_ORDER);
153 }
154
155 // if vendor has been selected from DB, certain vendor fields are not allowed to be edited
156 if (ObjectUtils.isNotNull(poDocument.getVendorHeaderGeneratedIdentifier())) {
157 editModes.add(PurchaseOrderEditMode.LOCK_VENDOR_ENTRY);
158 }
159
160 // if B2B purchase order, certain fields are not allowed to be edited
161 if (RequisitionSources.B2B.equals(poDocument.getRequisitionSourceCode())) {
162 editModes.add(PurchaseOrderEditMode.LOCK_B2B_ENTRY);
163 }
164
165 // if not B2B requisition, users can edit the posting year if within a given amount of time set in a parameter
166 if (!RequisitionSources.B2B.equals(poDocument.getRequisitionSourceCode()) &&
167 SpringContext.getBean(PurapService.class).allowEncumberNextFiscalYear() &&
168 (PurchaseOrderStatuses.IN_PROCESS.equals(statusCode) ||
169 PurchaseOrderStatuses.WAITING_FOR_VENDOR.equals(statusCode) ||
170 PurchaseOrderStatuses.WAITING_FOR_DEPARTMENT.equals(statusCode) ||
171 PurchaseOrderStatuses.QUOTE.equals(statusCode) ||
172 PurchaseOrderStatuses.AWAIT_PURCHASING_REVIEW.equals(statusCode))) {
173 editModes.add(PurchaseOrderEditMode.ALLOW_POSTING_YEAR_ENTRY);
174 }
175
176 // check if purap tax is enabled
177 boolean salesTaxInd = SpringContext.getBean(ParameterService.class).getIndicatorParameter(KfsParameterConstants.PURCHASING_DOCUMENT.class, PurapParameterConstants.ENABLE_SALES_TAX_IND);
178 if (salesTaxInd) {
179 editModes.add(PurapAuthorizationConstants.PURAP_TAX_ENABLED);
180
181 if (poDocument.isUseTaxIndicator()) {
182 // if use tax, don't allow editing of tax fields
183 editModes.add(PurchaseOrderEditMode.LOCK_TAX_AMOUNT_ENTRY);
184 }
185 else {
186 // display the "clear all taxes" button if doc is not using use tax
187 editModes.add(PurchaseOrderEditMode.CLEAR_ALL_TAXES);
188 }
189 }
190
191 // set display mode for Receiving Address section according to parameter value
192 boolean displayReceivingAddress = SpringContext.getBean(ParameterService.class).getIndicatorParameter(KfsParameterConstants.PURCHASING_DOCUMENT.class, PurapParameterConstants.ENABLE_RECEIVING_ADDRESS_IND);
193 if (displayReceivingAddress) {
194 editModes.add(PurchaseOrderEditMode.DISPLAY_RECEIVING_ADDRESS);
195 }
196
197 // PRE_ROUTE_CHANGEABLE mode is used for fields that are editable only before PO is routed
198 // for ex, contract manager, manual status change, and quote etc
199 //if (workflowDocument.stateIsInitiated() || workflowDocument.stateIsSaved()) {
200 if (PurchaseOrderStatuses.IN_PROCESS.equals(statusCode) ||
201 PurchaseOrderStatuses.WAITING_FOR_VENDOR.equals(statusCode) ||
202 PurchaseOrderStatuses.WAITING_FOR_DEPARTMENT.equals(statusCode) ||
203 PurchaseOrderStatuses.QUOTE.equals(statusCode)) {
204 editModes.add(PurchaseOrderEditMode.PRE_ROUTE_CHANGEABLE);
205 }
206
207 // INTERNAL PURCHASING ROUTE LEVEL - Approvers can edit full detail on Purchase Order except they cannot change the CHART/ORG.
208 if (poDocument.isDocumentStoppedInRouteNode(PurapWorkflowConstants.PurchaseOrderDocument.NodeDetailEnum.INTERNAL_PURCHASING_REVIEW)) {
209 editModes.add(PurchaseOrderEditMode.LOCK_INTERNAL_PURCHASING_ENTRY);
210 }
211
212 //FIXME figure out how to get this to work
213 // /**
214 // * CONTRACTS & GRANTS ROUTE LEVEL, BUDGET OFFICE ROUTE LEVEL, VENDOR TAX ROUTE LEVEL, DOCUMENT TRANSMISSION ROUTE LEVEL,
215 // * and Adhoc - Approvers in these route levels cannot edit any detail on PO.
216 // */
217 // else {
218 // // VIEW_ENTRY that is already being set is sufficient, but need to remove FULL_ENTRY
219 // editModeMap.remove(AuthorizationConstants.EditMode.FULL_ENTRY);
220 // }
221
222 // Set display mode for Split PO.
223 if (poDocument.isPendingSplit()) {
224 editModes.add(PurchaseOrderEditMode.SPLITTING_ITEM_SELECTION);
225 }
226
227 return editModes;
228 }
229
230 /**
231 * Determines whether to display the button to print the pdf for the first time transmit.
232 * Conditions: PO status is Pending Print or the transmission method is changed to PRINT during the amendment.
233 *
234 * @return boolean true if the print first transmit button can be displayed.
235 */
236 protected boolean canFirstTransmitPrintPo(PurchaseOrderDocument poDocument) {
237 // status shall be Pending Print, or the transmission method is changed to PRINT during amendment,
238 boolean can = PurchaseOrderStatuses.PENDING_PRINT.equals(poDocument.getStatusCode());
239 if (!can) {
240 can = PurchaseOrderStatuses.OPEN.equals(poDocument.getStatusCode());
241 can = can && poDocument.getDocumentHeader().getWorkflowDocument().stateIsFinal();
242 can = can && poDocument.getPurchaseOrderLastTransmitTimestamp() == null;
243 can = can && PurapConstants.POTransmissionMethods.PRINT.equals(poDocument.getPurchaseOrderTransmissionMethodCode());
244 }
245
246 return can;
247 }
248
249 /**
250 * Determines whether to display the print preview button for the first time transmit. Conditions are:
251 * available while the document is saved or enroute;
252 * available for only a certain number of PO transmission types which are stored in a parameter (default to PRIN and FAX)
253 *
254 * @return boolean true if the preview print button can be displayed.
255 */
256 protected boolean canPreviewPrintPo(PurchaseOrderDocument poDocument) {
257 // PO is saved or enroute
258 boolean can = poDocument.getDocumentHeader().getWorkflowDocument().stateIsSaved() || poDocument.getDocumentHeader().getWorkflowDocument().stateIsEnroute();
259
260 // transmission method must be one of those specified by the parameter
261 if (can) {
262 List<String> methods = SpringContext.getBean(ParameterService.class).getParameterValues(PurchaseOrderDocument.class, PurapParameterConstants.PURAP_PO_PRINT_PREVIEW_TRANSMISSION_METHOD_TYPES);
263 String method = poDocument.getPurchaseOrderTransmissionMethodCode();
264 can = (methods == null || methods.contains(method));
265 }
266
267 return can;
268 }
269
270 /**
271 * Determines whether to display the resend po button for the purchase order document.
272 * Conditions: PO status must be error sending cxml and must be current and not pending.
273 *
274 * @return boolean true if the resend po button shall be displayed.
275 */
276 protected boolean canResendCxml(PurchaseOrderDocument poDocument) {
277 // check PO status etc
278 boolean can = PurchaseOrderStatuses.CXML_ERROR.equals(poDocument.getStatusCode());
279 can = can && poDocument.isPurchaseOrderCurrentIndicator() && !poDocument.isPendingActionIndicator();
280
281 return can;
282 }
283
284 }