001/**
002 * Copyright 2005-2018 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 */
016package org.kuali.rice.krad.uif.util;
017
018import org.kuali.rice.krad.datadictionary.parse.BeanTag;
019import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute;
020import org.kuali.rice.krad.datadictionary.parse.BeanTags;
021import org.kuali.rice.krad.datadictionary.uif.UifDictionaryBeanBase;
022import org.kuali.rice.krad.uif.field.MessageField;
023
024import java.io.Serializable;
025
026/**
027 * ColumnCalculationInfo is used to specify which columns and what types of calculations are performed on those columns
028 * of table collection.  This functionality can only be used when the dataTables plugin is being used
029 * (richTable.render="true" for TableLayoutManager)
030 *
031 * @author Kuali Rice Team (rice.collab@kuali.org)
032 */
033@BeanTags({@BeanTag(name = "columnCalculation", parent = "Uif-ColumnCalculationInfo"),
034        @BeanTag(name = "columnCalculationSum", parent = "Uif-ColumnCalculationInfo-Sum"),
035        @BeanTag(name = "columnCalculationAverage", parent = "Uif-ColumnCalculationInfo-Average"),
036        @BeanTag(name = "columnCalculationMax", parent = "Uif-ColumnCalculationInfo-Max"),
037        @BeanTag(name = "columnCalculationMin", parent = "Uif-ColumnCalculationInfo-Min")})
038public class ColumnCalculationInfo extends UifDictionaryBeanBase implements Serializable {
039    private static final long serialVersionUID = 148856717025808296L;
040    private Integer columnNumber;
041    private String propertyName;
042
043    private boolean showTotal;
044    private boolean showPageTotal;
045    private boolean showGroupTotal;
046
047    private MessageField totalField;
048    private MessageField pageTotalField;
049    private MessageField groupTotalFieldPrototype;
050
051    private String calculationFunctionName;
052    private String calculationFunctionExtraData;
053
054    private boolean calculateOnKeyUp;
055    private boolean recalculateTotalClientSide;
056
057    /**
058     * Gets the column number.  This should not be set through configuration as it is overridden by the
059     * propertyName's caclculated column number.  <b>Do not set through xml configuration</b>
060     *
061     * @return columnNumber to perform calculations on
062     */
063    @BeanTagAttribute(name = "columnNumber")
064    public Integer getColumnNumber() {
065        return columnNumber;
066    }
067
068    /**
069     * Sets the column number. <b>Do not set through xml configuration</b>
070     *
071     * @param columnNumber
072     */
073    public void setColumnNumber(Integer columnNumber) {
074        this.columnNumber = columnNumber;
075    }
076
077    /**
078     * Gets showTotal. showTotal shows/calculates the total field when true, otherwise it is not rendered.
079     *
080     * @return true if showing the total, false otherwise.
081     */
082    @BeanTagAttribute(name = "showTotal")
083    public boolean isShowTotal() {
084        return showTotal;
085    }
086
087    /**
088     * Sets showTotal. showTotal shows/calculates the total field when true, otherwise it is not rendered.
089     *
090     * @param showTotal
091     */
092    public void setShowTotal(boolean showTotal) {
093        this.showTotal = showTotal;
094    }
095
096    /**
097     * Gets showTotal. showTotal shows/calculates the total field when true, otherwise it is not rendered.
098     *
099     * @return true if showing the page total, false otherwise.
100     */
101    @BeanTagAttribute(name = "showPageTotal")
102    public boolean isShowPageTotal() {
103        return showPageTotal;
104    }
105
106    /**
107     * Sets showPageTotal. showPageTotal shows/calculates the total field for the page when true (and only
108     * when the table actually has pages), otherwise it is not rendered.
109     *
110     * @param showPageTotal
111     */
112    public void setShowPageTotal(boolean showPageTotal) {
113        this.showPageTotal = showPageTotal;
114    }
115
116    /**
117     * Gets showGroupTotal. showGroupTotal shows/calculates the total field for each grouping when true (and only
118     * when the table actually has grouping turned on), otherwise it is not rendered.
119     *
120     * @return true if showing the group total, false otherwise.
121     */
122    @BeanTagAttribute(name = "showGroupTotal")
123    public boolean isShowGroupTotal() {
124        return showGroupTotal;
125    }
126
127    /**
128     * Sets showGroupTotal. showGroupTotal shows/calculates the total field for each grouping when true (and only
129     * when the table actually has grouping turned on), otherwise it is not rendered.
130     *
131     * @param showGroupTotal
132     */
133    public void setShowGroupTotal(boolean showGroupTotal) {
134        this.showGroupTotal = showGroupTotal;
135    }
136
137    /**
138     * Gets the js calculationFunctionName.  This is the name of the js function to use in column calculations.
139     *
140     * <p>
141     * <b>This must be ONLY the function by name (no parenthesis or params)</b><br/>
142     * The actual js function declaration MUST take in an array of values as its first parameter.  The values passed in
143     * will be all the relavant values for the calculation.  Optionally, the function can also take a second parameter
144     * which can be specified by calculationFunctionExtraData.  This parameter can take any valid javascript value
145     * (integer, string, JSON object, etc).  In either case, the values parameter MUST be the first parameter.
146     * </p>
147     *
148     * @return calculatinoFunctionName to call for column calculations in js
149     */
150    @BeanTagAttribute(name = "calculationFunctionName")
151    public String getCalculationFunctionName() {
152        return calculationFunctionName;
153    }
154
155    /**
156     * Sets the calculationFunctionName to call when doing column calculations
157     *
158     * @param calculationFunctionName
159     */
160    public void setCalculationFunctionName(String calculationFunctionName) {
161        this.calculationFunctionName = calculationFunctionName;
162    }
163
164    /**
165     * Gets the totalField.  This field is the field which holds the total for the column and specifies its label.
166     * This SHOULD NOT BE SET except by the base bean (in MOST cases).
167     *
168     * @return the totalField
169     */
170    @BeanTagAttribute(name = "totalField", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
171    public MessageField getTotalField() {
172        return totalField;
173    }
174
175    /**
176     * Sets the totalField.  This SHOULD NOT BE SET except by the base bean (in MOST cases).  Setting this property
177     * without the appropriate settings WILL break functionality.
178     *
179     * @param totalField
180     */
181    public void setTotalField(MessageField totalField) {
182        this.totalField = totalField;
183    }
184
185    /**
186     * Gets the pageTotalField.  This field is the field which holds the pageTotal for the column
187     * and specifies its label. This SHOULD NOT BE SET except by the base bean (in MOST cases).
188     *
189     * @return the pageTotalField
190     */
191    @BeanTagAttribute(name = "pageTotalField", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
192    public MessageField getPageTotalField() {
193        return pageTotalField;
194    }
195
196    /**
197     * Sets the pageTotalField.  This SHOULD NOT BE SET except by the base bean (in MOST cases).  Setting this property
198     * without the appropriate settings WILL break functionality.
199     *
200     * @param pageTotalField
201     */
202    public void setPageTotalField(MessageField pageTotalField) {
203        this.pageTotalField = pageTotalField;
204    }
205
206    /**
207     * Gets the groupTotalFieldPrototype.  This field is copied and holds the groupTotal for the column
208     * and specifies its label. This SHOULD NOT BE SET except by the base bean (in MOST cases).
209     *
210     * @return the groupTotalFieldPrototype
211     */
212    @BeanTagAttribute(name = "groupTotalFieldPrototype", type = BeanTagAttribute.AttributeType.SINGLEBEAN)
213    public MessageField getGroupTotalFieldPrototype() {
214        return groupTotalFieldPrototype;
215    }
216
217    /**
218     * Sets the groupTotalFieldPrototype.  This SHOULD NOT BE SET except by the base bean (in MOST cases).
219     * Setting this property without the appropriate settings WILL break functionality.
220     *
221     * @param groupTotalFieldPrototype
222     */
223    public void setGroupTotalFieldPrototype(MessageField groupTotalFieldPrototype) {
224        this.groupTotalFieldPrototype = groupTotalFieldPrototype;
225    }
226
227    /**
228     * If true, the column is calculated when the user enters a character on each key up.  There is a small delay
229     * built in to prevent calculations from being fired for each key stroke.
230     *
231     * @return true if calculated the column on key up, false if calculating on change (default)
232     */
233    @BeanTagAttribute(name = "calculationOnKeyUp")
234    public boolean isCalculateOnKeyUp() {
235        return calculateOnKeyUp;
236    }
237
238    /**
239     * Sets calculateOnKeyUp which controls the type of handler used
240     *
241     * @param calculateOnKeyUp
242     */
243    public void setCalculateOnKeyUp(boolean calculateOnKeyUp) {
244        this.calculateOnKeyUp = calculateOnKeyUp;
245    }
246
247    /**
248     * When set to false, calculations will not be fired for the totalField client-side.  This ONLY effects the
249     * totalField.  If page and group totals are still shown, they will (and can only) be calculated client-side.
250     *
251     * <p>
252     * To use this particular feature: set this to false, and use springEL in the totalField's message.messageText
253     * to get a pre-calculated total from a field on the form.  This will be refreshed when the table is refreshed,
254     * but will not be updated by client-side interactions - used for complex or special calculation mechanisms
255     * that may require server only information.
256     * </p>
257     *
258     * @return true if calculating the totalField client-side, false otherwise
259     */
260    @BeanTagAttribute(name = "recalculateTotalClientSide")
261    public boolean isRecalculateTotalClientSide() {
262        return recalculateTotalClientSide;
263    }
264
265    /**
266     * Set the recalculateTotalClientSide flag
267     *
268     * @param recalculateTotalClientSide
269     */
270    public void setRecalculateTotalClientSide(boolean recalculateTotalClientSide) {
271        this.recalculateTotalClientSide = recalculateTotalClientSide;
272    }
273
274    /**
275     * This specifies extra data to be sent to the calculation function.  This can be any valid javascript value
276     * (number, string, JSON - for passing multiple settings, etc).
277     * <br/>
278     * <b>The function specified by calculationFunctionName MUST take a second parameter when using this option.</b>
279     *
280     * @return the extra data to pass into the function specified by name in calculationFunctionName
281     */
282    @BeanTagAttribute(name = "calculationFunctionExtraData")
283    public String getCalculationFunctionExtraData() {
284        return calculationFunctionExtraData;
285    }
286
287    /**
288     * Sets the calculationFunctionExtraData which specifies additional data to pass into the calculationFunction.
289     *
290     * @param calculationFunctionExtraData
291     */
292    public void setCalculationFunctionExtraData(String calculationFunctionExtraData) {
293        this.calculationFunctionExtraData = calculationFunctionExtraData;
294    }
295
296    /**
297     * Get the propertyName of the field to do calculations.  This field MUST exist as one of the fields
298     * of the collection.  <b>This property must be set or an exception will be thrown.</b>
299     *
300     * @return propertyName of the field(the column) to do calculations on
301     */
302    @BeanTagAttribute(name = "propertyName")
303    public String getPropertyName() {
304        return propertyName;
305    }
306
307    /**
308     * Set the propertyName of the field to do calculations on
309     *
310     * @param propertyName
311     */
312    public void setPropertyName(String propertyName) {
313        this.propertyName = propertyName;
314    }
315
316}