=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/PeriodType.java' --- dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/PeriodType.java 2011-06-07 13:52:04 +0000 +++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/period/PeriodType.java 2011-07-19 21:49:16 +0000 @@ -28,6 +28,8 @@ */ import java.io.Serializable; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; @@ -218,17 +220,62 @@ } /** + * Parses a date from a String on the format YYYY-MM-DD. + * + * @param dateString the String to parse. + * @return a Date based on the given String. + */ + public static Date getMediumDate( String dateString ) + { + try + { + final SimpleDateFormat format = new SimpleDateFormat(); + format.applyPattern( "yyyy-MM-dd" ); + return dateString != null ? format.parse( dateString ) : null; + } + catch ( ParseException ex ) + { + throw new RuntimeException( "Failed to parse medium date", ex ); + } + } + + /** * Returns an iso8601 formatted string representation of the period * - * @param period + * @param period the period. * @return the period as string */ public abstract String getIsoDate( Period period ); + /** + * Generates a period based on the given iso8601 formatted string. + * + * @param isoDate the iso8601 string. + * @return the period. + */ public abstract Period createPeriod( String isoDate ); public abstract String getIsoFormat(); + /** + * Creates a period based on the given external identifier, which is on the + * format [PeriodType]_[StartDate]. The start date is on the form yyyy-MM-dd. + * + * @param externalId the external identifier. + * @return the period. + */ + public static Period createPeriodExternalId( String externalId ) + { + if ( externalId == null || externalId.split( "_" ).length <= 1 ) + { + return null; + } + + final String[] id = externalId.split( "_" ); + final PeriodType periodType = getPeriodTypeByName( id[0] ); + return periodType.createPeriod( getMediumDate( id[1] ) ); + } + // ------------------------------------------------------------------------- // hashCode and equals // ------------------------------------------------------------------------- === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/period/DefaultPeriodService.java' --- dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/period/DefaultPeriodService.java 2011-04-22 21:04:14 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/period/DefaultPeriodService.java 2011-07-20 21:38:30 +0000 @@ -226,19 +226,19 @@ { List periods = new ArrayList( historyLength ); + lastPeriod = periodStore.reloadForceAddPeriod( lastPeriod ); + CalendarPeriodType periodType = (CalendarPeriodType) lastPeriod.getPeriodType(); - Period period = lastPeriod; - Period p = new Period(); for ( int i = 0; i < historyLength; ++i ) { - p = getPeriodFromDates( period.getStartDate(), period.getEndDate(), periodType ); - - periods.add( p != null ? p : period ); - - period = periodType.getPreviousPeriod( period ); + p = getPeriodFromDates( lastPeriod.getStartDate(), lastPeriod.getEndDate(), periodType ); + + periods.add( p != null ? p : lastPeriod ); + + lastPeriod = periodType.getPreviousPeriod( lastPeriod ); } Collections.reverse( periods ); === modified file 'dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml' --- dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml 2011-07-18 07:54:57 +0000 +++ dhis-2/dhis-services/dhis-service-core/src/main/resources/META-INF/dhis/beans.xml 2011-07-19 06:11:23 +0000 @@ -1014,7 +1014,7 @@ - + === modified file 'dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/chart/impl/DefaultChartService.java' --- dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/chart/impl/DefaultChartService.java 2011-07-21 03:29:35 +0000 +++ dhis-2/dhis-services/dhis-service-reporting/src/main/java/org/hisp/dhis/chart/impl/DefaultChartService.java 2011-07-21 11:52:46 +0000 @@ -286,6 +286,8 @@ DataElementCategoryOptionCombo categoryOptionCombo, Period lastPeriod, OrganisationUnit organisationUnit, int historyLength, I18nFormat format ) { + lastPeriod = periodService.reloadPeriod( lastPeriod ); + List periods = periodService.getPeriods( lastPeriod, historyLength ); MinMaxDataElement minMax = minMaxDataElementService.getMinMaxDataElement( organisationUnit, dataElement, === added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.date.js' --- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.date.js 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.date.js 2011-07-18 14:08:54 +0000 @@ -0,0 +1,135 @@ +/* + * jQuery Date + * + * Copyright 2010 Marc Grabanski + * Licensed under the MIT license + * + * + * Depends: + * jquery.glob.js + */ +(function( $, undefined ) { + +if ( typeof( $.global.culture ) == "undefined" ) { + $.global.culture = $.global.cultures[ "default" ]; +} + +$.date = function ( datestring, formatstring ) { + var calendar = $.global.culture.calendar, + format = formatstring ? formatstring : calendar.patterns.d, + date = datestring ? $.global.parseDate(datestring, format) : new Date(); + return { + refresh: function() { + calendar = $.global.culture.calendar; + format = formatstring || calendar.patterns.d; + return this; + }, + setFormat: function( formatstring ) { + if ( formatstring ) { + format = formatstring; + } + return this; + }, + setDay: function( day ) { + date = new Date( date.getFullYear(), date.getMonth(), day ); + return this; + }, + adjust: function( period, offset ) { + var day = period == "D" ? date.getDate() + offset : date.getDate(), + month = period == "M" ? date.getMonth() + offset : date.getMonth(), + year = period == "Y" ? date.getFullYear() + offset : date.getFullYear(); + date = new Date( year, month, day ); + return this; + }, + daysInMonth: function( year, month ) { + year = year || date.getFullYear(); + month = month || date.getMonth(); + return 32 - new Date( year, month, 32 ).getDate(); + }, + monthname: function() { + return calendar.months.names[ date.getMonth() ]; + }, + year: function() { + return date.getFullYear(); + }, + weekdays: function() { + // TODO take firstDay into account + var result = []; + for ( var dow = 0; dow < 7; dow++ ) { + var day = ( dow + calendar.firstDay ) % 7; + result.push( { + shortname: calendar.days.namesShort[ day ], + fullname: calendar.days.names[ day ], + }); + } + return result; + }, + days: function() { + var result = [], + firstDayOfMonth = new Date( this.year(), date.getMonth(), 1 ).getDay(), + leadDays = ( firstDayOfMonth - calendar.firstDay + 7 ) % 7, + rows = Math.ceil( ( leadDays + this.daysInMonth() ) / 7), + printDate = new Date( this.year(), date.getMonth(), 1 - leadDays ); + for ( var row = 0; row < rows; row++ ) { + var week = result[ result.length ] = { + number: this.iso8601Week( printDate ), + days: [] + }; + for ( var dayx = 0; dayx < 7; dayx++ ) { + var day = week.days[ week.days.length ] = { + lead: printDate.getMonth() != date.getMonth(), + date: printDate.getDate(), + current: this.selected && this.selected.equal( printDate ), + today: today.equal( printDate ) + }; + day.render = day.selectable = !day.lead; + this.eachDay( day ); + // TODO use adjust("D", 1)? + printDate.setDate( printDate.getDate() + 1 ); + } + } + return result; + }, + iso8601Week: function( date ) { + var checkDate = new Date( date.getTime() ); + // Find Thursday of this week starting on Monday + checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) ); + var time = checkDate.getTime(); + checkDate.setMonth( 0 ); // Compare with Jan 1 + checkDate.setDate( 1 ); + return Math.floor( Math.round( ( time - checkDate ) / 86400000) / 7 ) + 1; + }, + select: function() { + this.selected = this.clone(); + return this; + }, + // TODO create new Date with year, month, day instead + clone: function() { + return $.date( this.format(), format ); + }, + // TODO compare year, month, day each for better performance + equal: function( other ) { + function format( date ) { + return $.global.format( date, "d" ); + } + return format( date ) == format( other ); + }, + date: function() { + return date; + }, + format: function( formatstring ) { + return $.global.format( date, formatstring ? formatstring : format ); + }, + calendar: function( newcalendar ) { + if ( newcalendar ) { + calendar = newcalendar; + return this; + } + return calendar; + } + } +} + +var today = $.date(); + +}( jQuery )); \ No newline at end of file === added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.glob.js' --- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.glob.js 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/jQuery/jquery.glob.js 2011-07-18 14:08:54 +0000 @@ -0,0 +1,1342 @@ +/*! + * jQuery Globalization Plugin + * http://github.com/jquery/jquery-global + * + * Copyright Software Freedom Conservancy, Inc. + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + */ +(function() { + +var Globalization = {}, localized = { en: {} }; +localized["default"] = localized.en; + +Globalization.extend = function( deep ) { + var target = arguments[ 1 ] || {}; + for ( var i = 2, l = arguments.length; i < l; i++ ) { + var source = arguments[ i ]; + if ( source ) { + for ( var field in source ) { + var sourceVal = source[ field ]; + if ( typeof sourceVal !== "undefined" ) { + if ( deep && (isObject( sourceVal ) || isArray( sourceVal )) ) { + var targetVal = target[ field ]; + // extend onto the existing value, or create a new one + targetVal = targetVal && (isObject( targetVal ) || isArray( targetVal )) + ? targetVal + : (isArray( sourceVal ) ? [] : {}); + target[ field ] = this.extend( true, targetVal, sourceVal ); + } + else { + target[ field ] = sourceVal; + } + } + } + } + } + return target; +} + +Globalization.findClosestCulture = function(name) { + var match; + if ( !name ) { + return this.culture || this.cultures["default"]; + } + if ( isString( name ) ) { + name = name.split( ',' ); + } + if ( isArray( name ) ) { + var lang, + cultures = this.cultures, + list = name, + i, l = list.length, + prioritized = []; + for ( i = 0; i < l; i++ ) { + name = trim( list[ i ] ); + var pri, parts = name.split( ';' ); + lang = trim( parts[ 0 ] ); + if ( parts.length === 1 ) { + pri = 1; + } + else { + name = trim( parts[ 1 ] ); + if ( name.indexOf("q=") === 0 ) { + name = name.substr( 2 ); + pri = parseFloat( name, 10 ); + pri = isNaN( pri ) ? 0 : pri; + } + else { + pri = 1; + } + } + prioritized.push( { lang: lang, pri: pri } ); + } + prioritized.sort(function(a, b) { + return a.pri < b.pri ? 1 : -1; + }); + for ( i = 0; i < l; i++ ) { + lang = prioritized[ i ].lang; + match = cultures[ lang ]; + // exact match? + if ( match ) { + return match; + } + } + for ( i = 0; i < l; i++ ) { + lang = prioritized[ i ].lang; + // for each entry try its neutral language + do { + var index = lang.lastIndexOf( "-" ); + if ( index === -1 ) { + break; + } + // strip off the last part. e.g. en-US => en + lang = lang.substr( 0, index ); + match = cultures[ lang ]; + if ( match ) { + return match; + } + } + while ( 1 ); + } + } + else if ( typeof name === 'object' ) { + return name; + } + return match || null; +} +Globalization.preferCulture = function(name) { + this.culture = this.findClosestCulture( name ) || this.cultures["default"]; +} +Globalization.localize = function(key, culture, value) { + // usign default culture in case culture is not provided + if (typeof culture !== 'string') { + culture = this.culture.name || this.culture || "default"; + } + culture = this.cultures[ culture ] || { name: culture }; + + var local = localized[ culture.name ]; + if ( arguments.length === 3 ) { + if ( !local) { + local = localized[ culture.name ] = {}; + } + local[ key ] = value; + } + else { + if ( local ) { + value = local[ key ]; + } + if ( typeof value === 'undefined' ) { + var language = localized[ culture.language ]; + if ( language ) { + value = language[ key ]; + } + if ( typeof value === 'undefined' ) { + value = localized["default"][ key ]; + } + } + } + return typeof value === "undefined" ? null : value; +} +Globalization.format = function(value, format, culture) { + culture = this.findClosestCulture( culture ); + if ( typeof value === "number" ) { + value = formatNumber( value, format, culture ); + } + else if ( value instanceof Date ) { + value = formatDate( value, format, culture ); + } + return value; +} +Globalization.parseInt = function(value, radix, culture) { + return Math.floor( this.parseFloat( value, radix, culture ) ); +} +Globalization.parseFloat = function(value, radix, culture) { + // make radix optional + if (typeof radix === "string") { + culture = radix; + radix = 10; + } + + culture = this.findClosestCulture( culture ); + var ret = NaN, + nf = culture.numberFormat; + + if (value.indexOf(culture.numberFormat.currency.symbol) > -1) { + // remove currency symbol + value = value.replace(culture.numberFormat.currency.symbol, ""); + // replace decimal seperator + value = value.replace(culture.numberFormat.currency["."], culture.numberFormat["."]); + } + + // trim leading and trailing whitespace + value = trim( value ); + + // allow infinity or hexidecimal + if (regexInfinity.test(value)) { + ret = parseFloat(value, radix); + } + else if (!radix && regexHex.test(value)) { + ret = parseInt(value, 16); + } + else { + var signInfo = parseNegativePattern( value, nf, nf.pattern[0] ), + sign = signInfo[0], + num = signInfo[1]; + // determine sign and number + if ( sign === "" && nf.pattern[0] !== "-n" ) { + signInfo = parseNegativePattern( value, nf, "-n" ); + sign = signInfo[0]; + num = signInfo[1]; + } + sign = sign || "+"; + // determine exponent and number + var exponent, + intAndFraction, + exponentPos = num.indexOf( 'e' ); + if ( exponentPos < 0 ) exponentPos = num.indexOf( 'E' ); + if ( exponentPos < 0 ) { + intAndFraction = num; + exponent = null; + } + else { + intAndFraction = num.substr( 0, exponentPos ); + exponent = num.substr( exponentPos + 1 ); + } + // determine decimal position + var integer, + fraction, + decSep = nf['.'], + decimalPos = intAndFraction.indexOf( decSep ); + if ( decimalPos < 0 ) { + integer = intAndFraction; + fraction = null; + } + else { + integer = intAndFraction.substr( 0, decimalPos ); + fraction = intAndFraction.substr( decimalPos + decSep.length ); + } + // handle groups (e.g. 1,000,000) + var groupSep = nf[","]; + integer = integer.split(groupSep).join(''); + var altGroupSep = groupSep.replace(/\u00A0/g, " "); + if ( groupSep !== altGroupSep ) { + integer = integer.split(altGroupSep).join(''); + } + // build a natively parsable number string + var p = sign + integer; + if ( fraction !== null ) { + p += '.' + fraction; + } + if ( exponent !== null ) { + // exponent itself may have a number patternd + var expSignInfo = parseNegativePattern( exponent, nf, "-n" ); + p += 'e' + (expSignInfo[0] || "+") + expSignInfo[1]; + } + if ( regexParseFloat.test( p ) ) { + ret = parseFloat( p ); + } + } + return ret; +} +Globalization.parseDate = function(value, formats, culture) { + culture = this.findClosestCulture( culture ); + + var date, prop, patterns; + if ( formats ) { + if ( typeof formats === "string" ) { + formats = [ formats ]; + } + if ( formats.length ) { + for ( var i = 0, l = formats.length; i < l; i++ ) { + var format = formats[ i ]; + if ( format ) { + date = parseExact( value, format, culture ); + if ( date ) { + break; + } + } + } + } + } + else { + patterns = culture.calendar.patterns; + for ( prop in patterns ) { + date = parseExact( value, patterns[prop], culture ); + if ( date ) { + break; + } + } + } + return date || null; +} + +// 1. When defining a culture, all fields are required except the ones stated as optional. +// 2. You can use Globalization.extend to copy an existing culture and provide only the differing values, +// a good practice since most cultures do not differ too much from the 'default' culture. +// DO use the 'default' culture if you do this, as it is the only one that definitely +// exists. +// 3. Other plugins may add to the culture information provided by extending it. However, +// that plugin may extend it prior to the culture being defined, or after. Therefore, +// do not overwrite values that already exist when defining the baseline for a culture, +// by extending your culture object with the existing one. +// 4. Each culture should have a ".calendars" object with at least one calendar named "standard" +// which serves as the default calendar in use by that culture. +// 5. Each culture should have a ".calendar" object which is the current calendar being used, +// it may be dynamically changed at any time to one of the calendars in ".calendars". + +// To define a culture, use the following pattern, which handles defining the culture based +// on the 'default culture, extending it with the existing culture if it exists, and defining +// it if it does not exist. +// Globalization.cultures.foo = Globalization.extend(true, Globalization.extend(true, {}, Globalization.cultures['default'], fooCulture), Globalization.cultures.foo) + +var cultures = Globalization.cultures = Globalization.cultures || {}; +var en = cultures["default"] = cultures.en = Globalization.extend(true, { + // A unique name for the culture in the form - + name: "en", + // the name of the culture in the english language + englishName: "English", + // the name of the culture in its own language + nativeName: "English", + // whether the culture uses right-to-left text + isRTL: false, + // 'language' is used for so-called "specific" cultures. + // For example, the culture "es-CL" means "Spanish, in Chili". + // It represents the Spanish-speaking culture as it is in Chili, + // which might have different formatting rules or even translations + // than Spanish in Spain. A "neutral" culture is one that is not + // specific to a region. For example, the culture "es" is the generic + // Spanish culture, which may be a more generalized version of the language + // that may or may not be what a specific culture expects. + // For a specific culture like "es-CL", the 'language' field refers to the + // neutral, generic culture information for the language it is using. + // This is not always a simple matter of the string before the dash. + // For example, the "zh-Hans" culture is netural (Simplified Chinese). + // And the 'zh-SG' culture is Simplified Chinese in Singapore, whose lanugage + // field is "zh-CHS", not "zh". + // This field should be used to navigate from a specific culture to it's + // more general, neutral culture. If a culture is already as general as it + // can get, the language may refer to itself. + language: "en", + // numberFormat defines general number formatting rules, like the digits in + // each grouping, the group separator, and how negative numbers are displayed. + numberFormat: { + // [negativePattern] + // Note, numberFormat.pattern has no 'positivePattern' unlike percent and currency, + // but is still defined as an array for consistency with them. + // negativePattern: one of "(n)|-n|- n|n-|n -" + pattern: ["-n"], + // number of decimal places normally shown + decimals: 2, + // string that separates number groups, as in 1,000,000 + ',': ",", + // string that separates a number from the fractional portion, as in 1.99 + '.': ".", + // array of numbers indicating the size of each number group. + // TODO: more detailed description and example + groupSizes: [3], + // symbol used for positive numbers + '+': "+", + // symbol used for negative numbers + '-': "-", + percent: { + // [negativePattern, positivePattern] + // negativePattern: one of "-n %|-n%|-%n|%-n|%n-|n-%|n%-|-% n|n %-|% n-|% -n|n- %" + // positivePattern: one of "n %|n%|%n|% n" + pattern: ["-n %","n %"], + // number of decimal places normally shown + decimals: 2, + // array of numbers indicating the size of each number group. + // TODO: more detailed description and example + groupSizes: [3], + // string that separates number groups, as in 1,000,000 + ',': ",", + // string that separates a number from the fractional portion, as in 1.99 + '.': ".", + // symbol used to represent a percentage + symbol: "%" + }, + currency: { + // [negativePattern, positivePattern] + // negativePattern: one of "($n)|-$n|$-n|$n-|(n$)|-n$|n-$|n$-|-n $|-$ n|n $-|$ n-|$ -n|n- $|($ n)|(n $)" + // positivePattern: one of "$n|n$|$ n|n $" + pattern: ["($n)","$n"], + // number of decimal places normally shown + decimals: 2, + // array of numbers indicating the size of each number group. + // TODO: more detailed description and example + groupSizes: [3], + // string that separates number groups, as in 1,000,000 + ',': ",", + // string that separates a number from the fractional portion, as in 1.99 + '.': ".", + // symbol used to represent currency + symbol: "$" + } + }, + // calendars defines all the possible calendars used by this culture. + // There should be at least one defined with name 'standard', and is the default + // calendar used by the culture. + // A calendar contains information about how dates are formatted, information about + // the calendar's eras, a standard set of the date formats, + // translations for day and month names, and if the calendar is not based on the Gregorian + // calendar, conversion functions to and from the Gregorian calendar. + calendars: { + standard: { + // name that identifies the type of calendar this is + name: "Gregorian_USEnglish", + // separator of parts of a date (e.g. '/' in 11/05/1955) + '/': "/", + // separator of parts of a time (e.g. ':' in 05:44 PM) + ':': ":", + // the first day of the week (0 = Sunday, 1 = Monday, etc) + firstDay: 0, + days: { + // full day names + names: ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], + // abbreviated day names + namesAbbr: ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], + // shortest day names + namesShort: ["Su","Mo","Tu","We","Th","Fr","Sa"] + }, + months: { + // full month names (13 months for lunar calendards -- 13th month should be "" if not lunar) + names: ["January","February","March","April","May","June","July","August","September","October","November","December",""], + // abbreviated month names + namesAbbr: ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""] + }, + // AM and PM designators in one of these forms: + // The usual view, and the upper and lower case versions + // [standard,lowercase,uppercase] + // The culture does not use AM or PM (likely all standard date formats use 24 hour time) + // null + AM: ["AM", "am", "AM"], + PM: ["PM", "pm", "PM"], + eras: [ + // eras in reverse chronological order. + // name: the name of the era in this culture (e.g. A.D., C.E.) + // start: when the era starts in ticks (gregorian, gmt), null if it is the earliest supported era. + // offset: offset in years from gregorian calendar + { "name": "A.D.", "start": null, "offset": 0 } + ], + // when a two digit year is given, it will never be parsed as a four digit + // year greater than this year (in the appropriate era for the culture) + // Set it as a full year (e.g. 2029) or use an offset format starting from + // the current year: "+19" would correspond to 2029 if the current year 2010. + twoDigitYearMax: 2029, + // set of predefined date and time patterns used by the culture + // these represent the format someone in this culture would expect + // to see given the portions of the date that are shown. + patterns: { + // short date pattern + d: "M/d/yyyy", + // long date pattern + D: "dddd, MMMM dd, yyyy", + // short time pattern + t: "h:mm tt", + // long time pattern + T: "h:mm:ss tt", + // long date, short time pattern + f: "dddd, MMMM dd, yyyy h:mm tt", + // long date, long time pattern + F: "dddd, MMMM dd, yyyy h:mm:ss tt", + // month/day pattern + M: "MMMM dd", + // month/year pattern + Y: "yyyy MMMM", + // S is a sortable format that does not vary by culture + S: "yyyy\u0027-\u0027MM\u0027-\u0027dd\u0027T\u0027HH\u0027:\u0027mm\u0027:\u0027ss" + } + // optional fields for each calendar: + /* + monthsGenitive: + Same as months but used when the day preceeds the month. + Omit if the culture has no genitive distinction in month names. + For an explaination of genitive months, see http://blogs.msdn.com/michkap/archive/2004/12/25/332259.aspx + convert: + Allows for the support of non-gregorian based calendars. This convert object is used to + to convert a date to and from a gregorian calendar date to handle parsing and formatting. + The two functions: + fromGregorian(date) + Given the date as a parameter, return an array with parts [year, month, day] + corresponding to the non-gregorian based year, month, and day for the calendar. + toGregorian(year, month, day) + Given the non-gregorian year, month, and day, return a new Date() object + set to the corresponding date in the gregorian calendar. + */ + } + } +}, cultures.en); +en.calendar = en.calendar || en.calendars.standard; + +var regexTrim = /^\s+|\s+$/g, + regexInfinity = /^[+-]?infinity$/i, + regexHex = /^0x[a-f0-9]+$/i, + regexParseFloat = /^[+-]?\d*\.?\d*(e[+-]?\d+)?$/, + toString = Object.prototype.toString; + +function startsWith(value, pattern) { + return value.indexOf( pattern ) === 0; +} + +function endsWith(value, pattern) { + return value.substr( value.length - pattern.length ) === pattern; +} + +function trim(value) { + return (value+"").replace( regexTrim, "" ); +} + +function zeroPad(str, count, left) { + for (var l=str.length; l < count; l++) { + str = (left ? ('0' + str) : (str + '0')); + } + return str; +} + +function isArray(obj) { + return toString.call(obj) === "[object Array]"; +} + +function isString(obj) { + return toString.call(obj) === "[object String]"; +} + +function isObject(obj) { + return toString.call(obj) === "[object Object]"; +} + +function arrayIndexOf( array, item ) { + if ( array.indexOf ) { + return array.indexOf( item ); + } + for ( var i = 0, length = array.length; i < length; i++ ) { + if ( array[ i ] === item ) { + return i; + } + } + return -1; +} + +// *************************************** Numbers *************************************** + +function expandNumber(number, precision, formatInfo) { + var groupSizes = formatInfo.groupSizes, + curSize = groupSizes[ 0 ], + curGroupIndex = 1, + factor = Math.pow( 10, precision ), + rounded = Math.round( number * factor ) / factor; + if ( !isFinite(rounded) ) { + rounded = number; + } + number = rounded; + + var numberString = number+"", + right = "", + split = numberString.split(/e/i), + exponent = split.length > 1 ? parseInt( split[ 1 ], 10 ) : 0; + numberString = split[ 0 ]; + split = numberString.split( "." ); + numberString = split[ 0 ]; + right = split.length > 1 ? split[ 1 ] : ""; + + var l; + if ( exponent > 0 ) { + right = zeroPad( right, exponent, false ); + numberString += right.slice( 0, exponent ); + right = right.substr( exponent ); + } + else if ( exponent < 0 ) { + exponent = -exponent; + numberString = zeroPad( numberString, exponent + 1 ); + right = numberString.slice( -exponent, numberString.length ) + right; + numberString = numberString.slice( 0, -exponent ); + } + + if ( precision > 0 ) { + right = formatInfo['.'] + + ((right.length > precision) ? right.slice( 0, precision ) : zeroPad( right, precision )); + } + else { + right = ""; + } + + var stringIndex = numberString.length - 1, + sep = formatInfo[","], + ret = ""; + + while ( stringIndex >= 0 ) { + if ( curSize === 0 || curSize > stringIndex ) { + return numberString.slice( 0, stringIndex + 1 ) + ( ret.length ? ( sep + ret + right ) : right ); + } + ret = numberString.slice( stringIndex - curSize + 1, stringIndex + 1 ) + ( ret.length ? ( sep + ret ) : "" ); + + stringIndex -= curSize; + + if ( curGroupIndex < groupSizes.length ) { + curSize = groupSizes[ curGroupIndex ]; + curGroupIndex++; + } + } + return numberString.slice( 0, stringIndex + 1 ) + sep + ret + right; +} + + +function parseNegativePattern(value, nf, negativePattern) { + var neg = nf["-"], + pos = nf["+"], + ret; + switch (negativePattern) { + case "n -": + neg = ' ' + neg; + pos = ' ' + pos; + // fall through + case "n-": + if ( endsWith( value, neg ) ) { + ret = [ '-', value.substr( 0, value.length - neg.length ) ]; + } + else if ( endsWith( value, pos ) ) { + ret = [ '+', value.substr( 0, value.length - pos.length ) ]; + } + break; + case "- n": + neg += ' '; + pos += ' '; + // fall through + case "-n": + if ( startsWith( value, neg ) ) { + ret = [ '-', value.substr( neg.length ) ]; + } + else if ( startsWith(value, pos) ) { + ret = [ '+', value.substr( pos.length ) ]; + } + break; + case "(n)": + if ( startsWith( value, '(' ) && endsWith( value, ')' ) ) { + ret = [ '-', value.substr( 1, value.length - 2 ) ]; + } + break; + } + return ret || [ '', value ]; +} + +function formatNumber(value, format, culture) { + if ( !format || format === 'i' ) { + return culture.name.length ? value.toLocaleString() : value.toString(); + } + format = format || "D"; + + var nf = culture.numberFormat, + number = Math.abs(value), + precision = -1, + pattern; + if (format.length > 1) precision = parseInt( format.slice( 1 ), 10 ); + + var current = format.charAt( 0 ).toUpperCase(), + formatInfo; + + switch (current) { + case "D": + pattern = 'n'; + if (precision !== -1) { + number = zeroPad( ""+number, precision, true ); + } + if (value < 0) number = -number; + break; + case "N": + formatInfo = nf; + // fall through + case "C": + formatInfo = formatInfo || nf.currency; + // fall through + case "P": + formatInfo = formatInfo || nf.percent; + pattern = value < 0 ? formatInfo.pattern[0] : (formatInfo.pattern[1] || "n"); + if (precision === -1) precision = formatInfo.decimals; + number = expandNumber( number * (current === "P" ? 100 : 1), precision, formatInfo ); + break; + default: + throw "Bad number format specifier: " + current; + } + + var patternParts = /n|\$|-|%/g, + ret = ""; + for (;;) { + var index = patternParts.lastIndex, + ar = patternParts.exec(pattern); + + ret += pattern.slice( index, ar ? ar.index : pattern.length ); + + if (!ar) { + break; + } + + switch (ar[0]) { + case "n": + ret += number; + break; + case "$": + ret += nf.currency.symbol; + break; + case "-": + // don't make 0 negative + if ( /[1-9]/.test( number ) ) { + ret += nf["-"]; + } + break; + case "%": + ret += nf.percent.symbol; + break; + } + } + + return ret; +} + +// *************************************** Dates *************************************** + +function outOfRange(value, low, high) { + return value < low || value > high; +} + +function expandYear(cal, year) { + // expands 2-digit year into 4 digits. + var now = new Date(), + era = getEra(now); + if ( year < 100 ) { + var twoDigitYearMax = cal.twoDigitYearMax; + twoDigitYearMax = typeof twoDigitYearMax === 'string' ? new Date().getFullYear() % 100 + parseInt( twoDigitYearMax, 10 ) : twoDigitYearMax; + var curr = getEraYear( now, cal, era ); + year += curr - ( curr % 100 ); + if ( year > twoDigitYearMax ) { + year -= 100; + } + } + return year; +} + +function getEra(date, eras) { + if ( !eras ) return 0; + var start, ticks = date.getTime(); + for ( var i = 0, l = eras.length; i < l; i++ ) { + start = eras[ i ].start; + if ( start === null || ticks >= start ) { + return i; + } + } + return 0; +} + +function toUpper(value) { + // 'he-IL' has non-breaking space in weekday names. + return value.split( "\u00A0" ).join(' ').toUpperCase(); +} + +function toUpperArray(arr) { + var results = []; + for ( var i = 0, l = arr.length; i < l; i++ ) { + results[i] = toUpper(arr[i]); + } + return results; +} + +function getEraYear(date, cal, era, sortable) { + var year = date.getFullYear(); + if ( !sortable && cal.eras ) { + // convert normal gregorian year to era-shifted gregorian + // year by subtracting the era offset + year -= cal.eras[ era ].offset; + } + return year; +} + +function getDayIndex(cal, value, abbr) { + var ret, + days = cal.days, + upperDays = cal._upperDays; + if ( !upperDays ) { + cal._upperDays = upperDays = [ + toUpperArray( days.names ), + toUpperArray( days.namesAbbr ), + toUpperArray( days.namesShort ) + ]; + } + value = toUpper( value ); + if ( abbr ) { + ret = arrayIndexOf( upperDays[ 1 ], value ); + if ( ret === -1 ) { + ret = arrayIndexOf( upperDays[ 2 ], value ); + } + } + else { + ret = arrayIndexOf( upperDays[ 0 ], value ); + } + return ret; +} + +function getMonthIndex(cal, value, abbr) { + var months = cal.months, + monthsGen = cal.monthsGenitive || cal.months, + upperMonths = cal._upperMonths, + upperMonthsGen = cal._upperMonthsGen; + if ( !upperMonths ) { + cal._upperMonths = upperMonths = [ + toUpperArray( months.names ), + toUpperArray( months.namesAbbr ) + ]; + cal._upperMonthsGen = upperMonthsGen = [ + toUpperArray( monthsGen.names ), + toUpperArray( monthsGen.namesAbbr ) + ]; + } + value = toUpper( value ); + var i = arrayIndexOf( abbr ? upperMonths[ 1 ] : upperMonths[ 0 ], value ); + if ( i < 0 ) { + i = arrayIndexOf( abbr ? upperMonthsGen[ 1 ] : upperMonthsGen[ 0 ], value ); + } + return i; +} + +function appendPreOrPostMatch(preMatch, strings) { + // appends pre- and post- token match strings while removing escaped characters. + // Returns a single quote count which is used to determine if the token occurs + // in a string literal. + var quoteCount = 0, + escaped = false; + for ( var i = 0, il = preMatch.length; i < il; i++ ) { + var c = preMatch.charAt( i ); + switch ( c ) { + case '\'': + if ( escaped ) { + strings.push( "'" ); + } + else { + quoteCount++; + } + escaped = false; + break; + case '\\': + if ( escaped ) { + strings.push( "\\" ); + } + escaped = !escaped; + break; + default: + strings.push( c ); + escaped = false; + break; + } + } + return quoteCount; +} + +function expandFormat(cal, format) { + // expands unspecified or single character date formats into the full pattern. + format = format || "F"; + var pattern, + patterns = cal.patterns, + len = format.length; + if ( len === 1 ) { + pattern = patterns[ format ]; + if ( !pattern ) { + throw "Invalid date format string '" + format + "'."; + } + format = pattern; + } + else if ( len === 2 && format.charAt(0) === "%" ) { + // %X escape format -- intended as a custom format string that is only one character, not a built-in format. + format = format.charAt( 1 ); + } + return format; +} + +function getParseRegExp(cal, format) { + // converts a format string into a regular expression with groups that + // can be used to extract date fields from a date string. + // check for a cached parse regex. + var re = cal._parseRegExp; + if ( !re ) { + cal._parseRegExp = re = {}; + } + else { + var reFormat = re[ format ]; + if ( reFormat ) { + return reFormat; + } + } + + // expand single digit formats, then escape regular expression characters. + var expFormat = expandFormat( cal, format ).replace( /([\^\$\.\*\+\?\|\[\]\(\)\{\}])/g, "\\\\$1" ), + regexp = ["^"], + groups = [], + index = 0, + quoteCount = 0, + tokenRegExp = getTokenRegExp(), + match; + + // iterate through each date token found. + while ( (match = tokenRegExp.exec( expFormat )) !== null ) { + var preMatch = expFormat.slice( index, match.index ); + index = tokenRegExp.lastIndex; + + // don't replace any matches that occur inside a string literal. + quoteCount += appendPreOrPostMatch( preMatch, regexp ); + if ( quoteCount % 2 ) { + regexp.push( match[ 0 ] ); + continue; + } + + // add a regex group for the token. + var m = match[ 0 ], + len = m.length, + add; + switch ( m ) { + case 'dddd': case 'ddd': + case 'MMMM': case 'MMM': + case 'gg': case 'g': + add = "(\\D+)"; + break; + case 'tt': case 't': + add = "(\\D*)"; + break; + case 'yyyy': + case 'fff': + case 'ff': + case 'f': + add = "(\\d{" + len + "})"; + break; + case 'dd': case 'd': + case 'MM': case 'M': + case 'yy': case 'y': + case 'HH': case 'H': + case 'hh': case 'h': + case 'mm': case 'm': + case 'ss': case 's': + add = "(\\d\\d?)"; + break; + case 'zzz': + add = "([+-]?\\d\\d?:\\d{2})"; + break; + case 'zz': case 'z': + add = "([+-]?\\d\\d?)"; + break; + case '/': + add = "(\\" + cal["/"] + ")"; + break; + default: + throw "Invalid date format pattern '" + m + "'."; + break; + } + if ( add ) { + regexp.push( add ); + } + groups.push( match[ 0 ] ); + } + appendPreOrPostMatch( expFormat.slice( index ), regexp ); + regexp.push( "$" ); + + // allow whitespace to differ when matching formats. + var regexpStr = regexp.join( '' ).replace( /\s+/g, "\\s+" ), + parseRegExp = {'regExp': regexpStr, 'groups': groups}; + + // cache the regex for this format. + return re[ format ] = parseRegExp; +} + +function getTokenRegExp() { + // regular expression for matching date and time tokens in format strings. + return /\/|dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|fff|ff|f|zzz|zz|z|gg|g/g; +} + +function parseExact(value, format, culture) { + // try to parse the date string by matching against the format string + // while using the specified culture for date field names. + value = trim( value ); + var cal = culture.calendar, + // convert date formats into regular expressions with groupings. + // use the regexp to determine the input format and extract the date fields. + parseInfo = getParseRegExp(cal, format), + match = new RegExp(parseInfo.regExp).exec(value); + if (match === null) { + return null; + } + // found a date format that matches the input. + var groups = parseInfo.groups, + era = null, year = null, month = null, date = null, weekDay = null, + hour = 0, hourOffset, min = 0, sec = 0, msec = 0, tzMinOffset = null, + pmHour = false; + // iterate the format groups to extract and set the date fields. + for ( var j = 0, jl = groups.length; j < jl; j++ ) { + var matchGroup = match[ j + 1 ]; + if ( matchGroup ) { + var current = groups[ j ], + clength = current.length, + matchInt = parseInt( matchGroup, 10 ); + switch ( current ) { + case 'dd': case 'd': + // Day of month. + date = matchInt; + // check that date is generally in valid range, also checking overflow below. + if ( outOfRange( date, 1, 31 ) ) return null; + break; + case 'MMM': + case 'MMMM': + month = getMonthIndex( cal, matchGroup, clength === 3 ); + if ( outOfRange( month, 0, 11 ) ) return null; + break; + case 'M': case 'MM': + // Month. + month = matchInt - 1; + if ( outOfRange( month, 0, 11 ) ) return null; + break; + case 'y': case 'yy': + case 'yyyy': + year = clength < 4 ? expandYear( cal, matchInt ) : matchInt; + if ( outOfRange( year, 0, 9999 ) ) return null; + break; + case 'h': case 'hh': + // Hours (12-hour clock). + hour = matchInt; + if ( hour === 12 ) hour = 0; + if ( outOfRange( hour, 0, 11 ) ) return null; + break; + case 'H': case 'HH': + // Hours (24-hour clock). + hour = matchInt; + if ( outOfRange( hour, 0, 23 ) ) return null; + break; + case 'm': case 'mm': + // Minutes. + min = matchInt; + if ( outOfRange( min, 0, 59 ) ) return null; + break; + case 's': case 'ss': + // Seconds. + sec = matchInt; + if ( outOfRange( sec, 0, 59 ) ) return null; + break; + case 'tt': case 't': + // AM/PM designator. + // see if it is standard, upper, or lower case PM. If not, ensure it is at least one of + // the AM tokens. If not, fail the parse for this format. + pmHour = cal.PM && ( matchGroup === cal.PM[0] || matchGroup === cal.PM[1] || matchGroup === cal.PM[2] ); + if ( !pmHour && ( !cal.AM || (matchGroup !== cal.AM[0] && matchGroup !== cal.AM[1] && matchGroup !== cal.AM[2]) ) ) return null; + break; + case 'f': + // Deciseconds. + case 'ff': + // Centiseconds. + case 'fff': + // Milliseconds. + msec = matchInt * Math.pow( 10, 3-clength ); + if ( outOfRange( msec, 0, 999 ) ) return null; + break; + case 'ddd': + // Day of week. + case 'dddd': + // Day of week. + weekDay = getDayIndex( cal, matchGroup, clength === 3 ); + if ( outOfRange( weekDay, 0, 6 ) ) return null; + break; + case 'zzz': + // Time zone offset in +/- hours:min. + var offsets = matchGroup.split( /:/ ); + if ( offsets.length !== 2 ) return null; + hourOffset = parseInt( offsets[ 0 ], 10 ); + if ( outOfRange( hourOffset, -12, 13 ) ) return null; + var minOffset = parseInt( offsets[ 1 ], 10 ); + if ( outOfRange( minOffset, 0, 59 ) ) return null; + tzMinOffset = (hourOffset * 60) + (startsWith( matchGroup, '-' ) ? -minOffset : minOffset); + break; + case 'z': case 'zz': + // Time zone offset in +/- hours. + hourOffset = matchInt; + if ( outOfRange( hourOffset, -12, 13 ) ) return null; + tzMinOffset = hourOffset * 60; + break; + case 'g': case 'gg': + var eraName = matchGroup; + if ( !eraName || !cal.eras ) return null; + eraName = trim( eraName.toLowerCase() ); + for ( var i = 0, l = cal.eras.length; i < l; i++ ) { + if ( eraName === cal.eras[ i ].name.toLowerCase() ) { + era = i; + break; + } + } + // could not find an era with that name + if ( era === null ) return null; + break; + } + } + } + var result = new Date(), defaultYear, convert = cal.convert; + defaultYear = convert ? convert.fromGregorian( result )[ 0 ] : result.getFullYear(); + if ( year === null ) { + year = defaultYear; + } + else if ( cal.eras ) { + // year must be shifted to normal gregorian year + // but not if year was not specified, its already normal gregorian + // per the main if clause above. + year += cal.eras[ (era || 0) ].offset; + } + // set default day and month to 1 and January, so if unspecified, these are the defaults + // instead of the current day/month. + if ( month === null ) { + month = 0; + } + if ( date === null ) { + date = 1; + } + // now have year, month, and date, but in the culture's calendar. + // convert to gregorian if necessary + if ( convert ) { + result = convert.toGregorian( year, month, date ); + // conversion failed, must be an invalid match + if ( result === null ) return null; + } + else { + // have to set year, month and date together to avoid overflow based on current date. + result.setFullYear( year, month, date ); + // check to see if date overflowed for specified month (only checked 1-31 above). + if ( result.getDate() !== date ) return null; + // invalid day of week. + if ( weekDay !== null && result.getDay() !== weekDay ) { + return null; + } + } + // if pm designator token was found make sure the hours fit the 24-hour clock. + if ( pmHour && hour < 12 ) { + hour += 12; + } + result.setHours( hour, min, sec, msec ); + if ( tzMinOffset !== null ) { + // adjust timezone to utc before applying local offset. + var adjustedMin = result.getMinutes() - ( tzMinOffset + result.getTimezoneOffset() ); + // Safari limits hours and minutes to the range of -127 to 127. We need to use setHours + // to ensure both these fields will not exceed this range. adjustedMin will range + // somewhere between -1440 and 1500, so we only need to split this into hours. + result.setHours( result.getHours() + parseInt( adjustedMin / 60, 10 ), adjustedMin % 60 ); + } + return result; +} + +function formatDate(value, format, culture) { + var cal = culture.calendar, + convert = cal.convert; + if ( !format || !format.length || format === 'i' ) { + var ret; + if ( culture && culture.name.length ) { + if ( convert ) { + // non-gregorian calendar, so we cannot use built-in toLocaleString() + ret = formatDate( value, cal.patterns.F, culture ); + } + else { + var eraDate = new Date( value.getTime() ), + era = getEra( value, cal.eras ); + eraDate.setFullYear( getEraYear( value, cal, era ) ); + ret = eraDate.toLocaleString(); + } + } + else { + ret = value.toString(); + } + return ret; + } + + var eras = cal.eras, + sortable = format === "s"; + format = expandFormat( cal, format ); + + // Start with an empty string + ret = []; + var hour, + zeros = ['0','00','000'], + foundDay, + checkedDay, + dayPartRegExp = /([^d]|^)(d|dd)([^d]|$)/g, + quoteCount = 0, + tokenRegExp = getTokenRegExp(), + converted; + + function padZeros(num, c) { + var r, s = num+''; + if ( c > 1 && s.length < c ) { + r = ( zeros[ c - 2 ] + s); + return r.substr( r.length - c, c ); + } + else { + r = s; + } + return r; + } + + function hasDay() { + if ( foundDay || checkedDay ) { + return foundDay; + } + foundDay = dayPartRegExp.test( format ); + checkedDay = true; + return foundDay; + } + + function getPart( date, part ) { + if ( converted ) { + return converted[ part ]; + } + switch ( part ) { + case 0: return date.getFullYear(); + case 1: return date.getMonth(); + case 2: return date.getDate(); + } + } + + if ( !sortable && convert ) { + converted = convert.fromGregorian( value ); + } + + for (;;) { + // Save the current index + var index = tokenRegExp.lastIndex, + // Look for the next pattern + ar = tokenRegExp.exec( format ); + + // Append the text before the pattern (or the end of the string if not found) + var preMatch = format.slice( index, ar ? ar.index : format.length ); + quoteCount += appendPreOrPostMatch( preMatch, ret ); + + if ( !ar ) { + break; + } + + // do not replace any matches that occur inside a string literal. + if ( quoteCount % 2 ) { + ret.push( ar[ 0 ] ); + continue; + } + + var current = ar[ 0 ], + clength = current.length; + + switch ( current ) { + case "ddd": + //Day of the week, as a three-letter abbreviation + case "dddd": + // Day of the week, using the full name + names = (clength === 3) ? cal.days.namesAbbr : cal.days.names; + ret.push( names[ value.getDay() ] ); + break; + case "d": + // Day of month, without leading zero for single-digit days + case "dd": + // Day of month, with leading zero for single-digit days + foundDay = true; + ret.push( padZeros( getPart( value, 2 ), clength ) ); + break; + case "MMM": + // Month, as a three-letter abbreviation + case "MMMM": + // Month, using the full name + var part = getPart( value, 1 ); + ret.push( (cal.monthsGenitive && hasDay()) + ? cal.monthsGenitive[ clength === 3 ? "namesAbbr" : "names" ][ part ] + : cal.months[ clength === 3 ? "namesAbbr" : "names" ][ part ] ); + break; + case "M": + // Month, as digits, with no leading zero for single-digit months + case "MM": + // Month, as digits, with leading zero for single-digit months + ret.push( padZeros( getPart( value, 1 ) + 1, clength ) ); + break; + case "y": + // Year, as two digits, but with no leading zero for years less than 10 + case "yy": + // Year, as two digits, with leading zero for years less than 10 + case "yyyy": + // Year represented by four full digits + part = converted ? converted[ 0 ] : getEraYear( value, cal, getEra( value, eras ), sortable ); + if ( clength < 4 ) { + part = part % 100; + } + ret.push( padZeros( part, clength ) ); + break; + case "h": + // Hours with no leading zero for single-digit hours, using 12-hour clock + case "hh": + // Hours with leading zero for single-digit hours, using 12-hour clock + hour = value.getHours() % 12; + if ( hour === 0 ) hour = 12; + ret.push( padZeros( hour, clength ) ); + break; + case "H": + // Hours with no leading zero for single-digit hours, using 24-hour clock + case "HH": + // Hours with leading zero for single-digit hours, using 24-hour clock + ret.push( padZeros( value.getHours(), clength ) ); + break; + case "m": + // Minutes with no leading zero for single-digit minutes + case "mm": + // Minutes with leading zero for single-digit minutes + ret.push( padZeros( value.getMinutes(), clength ) ); + break; + case "s": + // Seconds with no leading zero for single-digit seconds + case "ss": + // Seconds with leading zero for single-digit seconds + ret.push( padZeros(value .getSeconds(), clength ) ); + break; + case "t": + // One character am/pm indicator ("a" or "p") + case "tt": + // Multicharacter am/pm indicator + part = value.getHours() < 12 ? (cal.AM ? cal.AM[0] : " ") : (cal.PM ? cal.PM[0] : " "); + ret.push( clength === 1 ? part.charAt( 0 ) : part ); + break; + case "f": + // Deciseconds + case "ff": + // Centiseconds + case "fff": + // Milliseconds + ret.push( padZeros( value.getMilliseconds(), 3 ).substr( 0, clength ) ); + break; + case "z": + // Time zone offset, no leading zero + case "zz": + // Time zone offset with leading zero + hour = value.getTimezoneOffset() / 60; + ret.push( (hour <= 0 ? '+' : '-') + padZeros( Math.floor( Math.abs( hour ) ), clength ) ); + break; + case "zzz": + // Time zone offset with leading zero + hour = value.getTimezoneOffset() / 60; + ret.push( (hour <= 0 ? '+' : '-') + padZeros( Math.floor( Math.abs( hour ) ), 2 ) + + // Hard coded ":" separator, rather than using cal.TimeSeparator + // Repeated here for consistency, plus ":" was already assumed in date parsing. + ":" + padZeros( Math.abs( value.getTimezoneOffset() % 60 ), 2 ) ); + break; + case "g": + case "gg": + if ( cal.eras ) { + ret.push( cal.eras[ getEra(value, eras) ].name ); + } + break; + case "/": + ret.push( cal["/"] ); + break; + default: + throw "Invalid date format pattern '" + current + "'."; + break; + } + } + return ret.join( '' ); +} + +// EXPORTS +jQuery.global = Globalization; + +})(); + + === added file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/periodType.js' --- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/periodType.js 1970-01-01 00:00:00 +0000 +++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/dhis-web-commons/javascripts/periodType.js 2011-07-21 11:52:46 +0000 @@ -0,0 +1,216 @@ + +function PeriodType() +{ + var dateFormat = 'yyyy-MM-dd'; + + var periodTypes = []; + periodTypes['Daily'] = new DailyPeriodType( dateFormat ); + periodTypes['Weekly'] = new WeeklyPeriodType( dateFormat ); + periodTypes['Monthly'] = new MonthlyPeriodType( dateFormat ); + periodTypes['Quarterly'] = new QuarterlyPeriodType( dateFormat ); + periodTypes['SixMonthly'] = new SixMonthlyPeriodType( dateFormat ); + periodTypes['Yearly'] = new YearlyPeriodType( dateFormat ); + + this.get = function( key ) + { + return periodTypes[key]; + } + + this.reverse = function( array ) + { + var reversed = []; + var i = 0; + + for ( var j = array.length - 1; j >= 0; j-- ) + { + reversed[i++] = array[j]; + } + + return reversed; + } + + this.filterFuturePeriods = function( periods ) + { + var array = []; + var i = 0; + + var now = new Date().getTime(); + + for ( var j = 0; j < periods.length; j++ ) + { + var c = periods[j]; + var d = periods[j]['startDate']; + var e = null; + + if ( $.date( periods[j]['startDate'], dateFormat ).date().getTime() < now ) + { + array[i++] = periods[j]; + } + } + + return array; + } +} + +function DailyPeriodType( dateFormat ) +{ + this.generatePeriods = function( offset ) + { + var periods = []; + var year = new Date().getFullYear() + offset; + var startDate = $.date( year + '-01-01', dateFormat ); + var i = 0; + + while ( startDate.date().getFullYear() <= year ) + { + var period = []; + period['startDate'] = startDate.format( dateFormat ); + period['name'] = startDate.format( dateFormat ); + period['id'] = 'Daily_' + period['startDate']; + periods[i]= period; + + startDate.adjust( 'D', +1 ); + i++; + } + + return periods; + } +} + +function WeeklyPeriodType( dateFormat ) +{ + this.generatePeriods = function( offset ) + { + var periods = []; + var year = new Date().getFullYear() + offset; + var startDate = $.date( year + '-01-01', dateFormat ); + var day = startDate.date().getDay(); + var i = 0; + + if ( day == 0 ) // Sunday, forward to Monday + { + startDate.adjust( 'D', +1 ); + } + else if ( day <= 4 ) // Monday - Thursday, rewind to Monday + { + startDate.adjust( 'D', ( ( day - 1 ) * -1 ) ); + } + else // Friday - Saturday, forward to Monday + { + startDate.adjust( 'D', ( 8 - day ) ); + } + + while ( startDate.date().getFullYear() <= year ) + { + var period = []; + period['startDate'] = startDate.format( dateFormat ); + period['name'] = 'W' + ( i + 1 ) + ' - ' + startDate.format( dateFormat ); + period['id'] = 'Weekly_' + period['startDate']; + periods[i] = period; + + startDate.adjust( 'D', +7 ); + i++; + } + + return periods; + } +} + +function MonthlyPeriodType( dateFormat ) +{ + this.generatePeriods = function( offset ) + { + var periods = []; + var year = new Date().getFullYear() + offset; + var startDate = $.date( year + '-01-01', dateFormat ); + var i = 0; + + while ( startDate.date().getFullYear() == year ) + { + var period = []; + period['startDate'] = startDate.format( dateFormat ); + period['name'] = monthNames[i] + ' ' + year; + period['id'] = 'Monthly_' + period['startDate']; + periods[i] = period; + + startDate.adjust( 'M', +1 ); + i++; + } + + return periods; + } +} + +function QuarterlyPeriodType( dateFormat ) +{ + this.generatePeriods = function( offset ) + { + var periods = []; + var year = new Date().getFullYear() + offset; + var startDate = $.date( year + '-01-01', dateFormat ); + var i = 0; + var j = 0; + + while ( startDate.date().getFullYear() == year ) + { + var period = []; + period['startDate'] = startDate.format( dateFormat ); + period['name'] = monthNames[i] + ' - ' + monthNames[i+2] + ' ' + year; + period['id'] = 'Quarterly_' + period['startDate']; + periods[j] = period; + + startDate.adjust( 'M', +3 ); + i += 3; + j++; + } + + return periods; + } +} + +function SixMonthlyPeriodType( dateFormat ) +{ + this.generatePeriods = function( offset ) + { + var periods = []; + var year = new Date().getFullYear() + offset; + + var period = []; + period['startDate'] = year + '-01-01'; + period['name'] = monthNames[0] + ' - ' + monthNames[5] + ' ' + year; + period['id'] = 'SixMonthly_' + period['startDate']; + periods[0] = period; + + period = []; + period['startDate'] = year + '-06-01'; + period['name'] = monthNames[6] + ' - ' + monthNames[11] + ' ' + year; + period['id'] = 'SixMonthly_' + period['startDate']; + periods[1] = period; + + return periods; + } +} + +function YearlyPeriodType( dateFormat ) +{ + this.generatePeriods = function( offset ) + { + var periods = []; + var year = new Date().getFullYear() + offset; + var startDate = $.date( year + '-01-01', dateFormat ).adjust( 'Y', -5 ); + var i = 0; + + for ( var i = 0; i < 11; i++ ) + { + var period = []; + period['startDate'] = startDate.format( dateFormat ); + period['name'] = startDate.date().getFullYear(); + period['id'] = 'Yearly_' + period['startDate']; + periods[i] = period; + + startDate.adjust( 'Y', +1 ); + } + + return periods; + } +} === modified file 'dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/main.vm' --- dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/main.vm 2011-06-16 08:08:02 +0000 +++ dhis-2/dhis-web/dhis-web-commons-resources/src/main/webapp/main.vm 2011-07-21 11:52:46 +0000 @@ -34,11 +34,14 @@ + + + === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetDataValuesForDataSetAction.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetDataValuesForDataSetAction.java 2011-07-13 15:09:37 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetDataValuesForDataSetAction.java 2011-07-19 21:49:16 +0000 @@ -30,13 +30,15 @@ import java.util.Collection; import org.hisp.dhis.dataset.DataSet; +import org.hisp.dhis.dataset.DataSetService; import org.hisp.dhis.datavalue.DataValue; import org.hisp.dhis.datavalue.DataValueService; -import org.hisp.dhis.de.state.SelectedStateManager; import org.hisp.dhis.minmax.MinMaxDataElement; import org.hisp.dhis.minmax.MinMaxDataElementService; import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager; import org.hisp.dhis.period.Period; +import org.hisp.dhis.period.PeriodType; import com.opensymphony.xwork2.Action; @@ -64,24 +66,38 @@ this.minMaxDataElementService = minMaxDataElementService; } - private SelectedStateManager selectedStateManager; - - public void setSelectedStateManager( SelectedStateManager selectedStateManager ) - { - this.selectedStateManager = selectedStateManager; + private DataSetService dataSetService; + + public void setDataSetService( DataSetService dataSetService ) + { + this.dataSetService = dataSetService; + } + + private OrganisationUnitSelectionManager selectionManager; + + public void setSelectionManager( OrganisationUnitSelectionManager selectionManager ) + { + this.selectionManager = selectionManager; } // ------------------------------------------------------------------------- // Input // ------------------------------------------------------------------------- - private Integer selectedPeriodIndex; - - public void setSelectedPeriodIndex( Integer selectedPeriodIndex ) - { - this.selectedPeriodIndex = selectedPeriodIndex; - } - + private String periodId; + + public void setPeriodId( String periodId ) + { + this.periodId = periodId; + } + + private Integer dataSetId; + + public void setDataSetId( Integer dataSetId ) + { + this.dataSetId = dataSetId; + } + // ------------------------------------------------------------------------- // Output // ------------------------------------------------------------------------- @@ -106,14 +122,9 @@ public String execute() { - if ( selectedPeriodIndex != null ) - { - selectedStateManager.setSelectedPeriodIndex( selectedPeriodIndex ); - } - - Period period = selectedStateManager.getSelectedPeriod(); - DataSet dataSet = selectedStateManager.getSelectedDataSet(); - OrganisationUnit unit = selectedStateManager.getSelectedOrganisationUnit(); + Period period = PeriodType.createPeriodExternalId( periodId ); + DataSet dataSet = dataSetService.getDataSet( dataSetId ); + OrganisationUnit unit = selectionManager.getSelectedOrganisationUnit(); dataValues = dataValueService.getDataValues( unit, period, dataSet.getDataElements() ); === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetHistoryChartAction.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetHistoryChartAction.java 2010-04-12 21:23:33 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/GetHistoryChartAction.java 2011-07-20 21:38:30 +0000 @@ -32,10 +32,11 @@ import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo; import org.hisp.dhis.dataelement.DataElementCategoryService; import org.hisp.dhis.dataelement.DataElementService; -import org.hisp.dhis.de.state.SelectedStateManager; import org.hisp.dhis.i18n.I18nFormat; import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager; import org.hisp.dhis.period.Period; +import org.hisp.dhis.period.PeriodType; import org.jfree.chart.JFreeChart; import com.opensymphony.xwork2.Action; @@ -73,13 +74,13 @@ this.categoryService = categoryService; } - private SelectedStateManager selectedStateManager; + private OrganisationUnitSelectionManager selectionManager; - public void setSelectedStateManager( SelectedStateManager selectedStateManager ) + public void setSelectionManager( OrganisationUnitSelectionManager selectionManager ) { - this.selectedStateManager = selectedStateManager; + this.selectionManager = selectionManager; } - + private I18nFormat format; public void setFormat( I18nFormat format ) @@ -105,6 +106,12 @@ this.categoryOptionComboId = categoryOptionComboId; } + private String periodId; + + public void setPeriodId( String periodId ) + { + this.periodId = periodId; + } // ------------------------------------------------------------------------- // Output @@ -140,8 +147,9 @@ DataElement dataElement = dataElementService.getDataElement( dataElementId ); DataElementCategoryOptionCombo categoryOptionCombo = categoryService.getDataElementCategoryOptionCombo( categoryOptionComboId ); - Period period = selectedStateManager.getSelectedPeriod(); - OrganisationUnit organisationUnit = selectedStateManager.getSelectedOrganisationUnit(); + Period period = PeriodType.createPeriodExternalId( periodId ); + + OrganisationUnit organisationUnit = selectionManager.getSelectedOrganisationUnit(); chart = chartService.getJFreeChartHistory( dataElement, categoryOptionCombo, period, organisationUnit, HISTORY_LENGTH, format ); === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/HistoryAction.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/HistoryAction.java 2011-06-27 10:39:01 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/HistoryAction.java 2011-07-20 21:38:30 +0000 @@ -40,9 +40,10 @@ import org.hisp.dhis.datavalue.DataValueService; import org.hisp.dhis.de.history.DataElementHistory; import org.hisp.dhis.de.history.HistoryRetriever; -import org.hisp.dhis.de.state.SelectedStateManager; import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager; import org.hisp.dhis.period.Period; +import org.hisp.dhis.period.PeriodType; import com.opensymphony.xwork2.Action; @@ -86,13 +87,6 @@ { this.categoryService = categoryService; } - - private SelectedStateManager selectedStateManager; - - public void setSelectedStateManager( SelectedStateManager selectedStateManager ) - { - this.selectedStateManager = selectedStateManager; - } private DataValueAuditService dataValueAuditService; @@ -100,7 +94,14 @@ { this.dataValueAuditService = dataValueAuditService; } - + + private OrganisationUnitSelectionManager selectionManager; + + public void setSelectionManager( OrganisationUnitSelectionManager selectionManager ) + { + this.selectionManager = selectionManager; + } + // ------------------------------------------------------------------------- // Input // ------------------------------------------------------------------------- @@ -131,6 +132,18 @@ return showComment; } + private String periodId; + + public String getPeriodId() + { + return periodId; + } + + public void setPeriodId( String periodId ) + { + this.periodId = periodId; + } + // ------------------------------------------------------------------------- // Output // ------------------------------------------------------------------------- @@ -191,9 +204,9 @@ throw new Exception( "DataElement doesn't exist: " + dataElementId ); } - Period period = selectedStateManager.getSelectedPeriod(); + Period period = PeriodType.createPeriodExternalId( periodId ); - OrganisationUnit organisationUnit = selectedStateManager.getSelectedOrganisationUnit(); + OrganisationUnit organisationUnit = selectionManager.getSelectedOrganisationUnit(); dataValue = dataValueService.getDataValue( organisationUnit, dataElement, period, optionCombo ); === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadDataSetsAction.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadDataSetsAction.java 2011-05-20 13:28:27 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadDataSetsAction.java 2011-07-19 21:49:16 +0000 @@ -30,12 +30,17 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Iterator; import java.util.List; import org.hisp.dhis.dataset.DataSet; +import org.hisp.dhis.dataset.DataSetService; import org.hisp.dhis.dataset.comparator.DataSetNameComparator; -import org.hisp.dhis.de.state.SelectedStateManager; import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager; +import org.hisp.dhis.period.CalendarPeriodType; +import org.hisp.dhis.user.CurrentUserService; +import org.hisp.dhis.user.User; import com.opensymphony.xwork2.Action; @@ -49,13 +54,38 @@ // Dependencies // ------------------------------------------------------------------------- - private SelectedStateManager selectedStateManager; - - public void setSelectedStateManager( SelectedStateManager selectedStateManager ) - { - this.selectedStateManager = selectedStateManager; - } - + private OrganisationUnitSelectionManager selectionManager; + + public void setSelectionManager( OrganisationUnitSelectionManager selectionManager ) + { + this.selectionManager = selectionManager; + } + + private CurrentUserService currentUserService; + + public void setCurrentUserService( CurrentUserService currentUserService ) + { + this.currentUserService = currentUserService; + } + + private DataSetService dataSetService; + + public void setDataSetService( DataSetService dataSetService ) + { + this.dataSetService = dataSetService; + } + + // ------------------------------------------------------------------------- + // Input + // ------------------------------------------------------------------------- + + private Integer dataSetId; + + public void setDataSetId( Integer dataSetId ) + { + this.dataSetId = dataSetId; + } + // ------------------------------------------------------------------------- // Output // ------------------------------------------------------------------------- @@ -94,7 +124,7 @@ public String execute() { - organisationUnit = selectedStateManager.getSelectedOrganisationUnit(); + organisationUnit = selectionManager.getSelectedOrganisationUnit(); if ( organisationUnit != null ) { @@ -102,7 +132,7 @@ // Load data sets for selected org unit // ----------------------------------------------------------------- - dataSets = selectedStateManager.loadDataSetsForSelectedOrgUnit(); + dataSets = loadDataSetsForSelectedOrgUnit( organisationUnit ); Collections.sort( dataSets, new DataSetNameComparator() ); @@ -110,21 +140,51 @@ // Check if selected data set is associated with selected org unit // ----------------------------------------------------------------- - DataSet selectedDataSet = selectedStateManager.getSelectedDataSet(); - - if ( selectedDataSet != null && dataSets.contains( selectedDataSet ) ) + if ( dataSetId != null ) { - dataSetValid = true; + DataSet selectedDataSet = dataSetService.getDataSet( dataSetId ); - periodValid = selectedStateManager.getSelectedPeriod() != null; - } - else - { - selectedStateManager.clearSelectedDataSet(); - selectedStateManager.clearSelectedPeriod(); + if ( selectedDataSet != null && dataSets.contains( selectedDataSet ) ) + { + dataSetValid = true; + } } } return SUCCESS; } + + private List loadDataSetsForSelectedOrgUnit( OrganisationUnit organisationUnit ) + { + List dataSets = new ArrayList( organisationUnit.getDataSets() ); + + // --------------------------------------------------------------------- + // Retain only DataSets from current user's authority groups + // --------------------------------------------------------------------- + + User currentUser = currentUserService.getCurrentUser(); + + if ( currentUser != null && !currentUserService.currentUserIsSuper() ) + { + dataSets.retainAll( currentUser.getUserCredentials().getAllDataSets() ); + } + + // --------------------------------------------------------------------- + // Remove DataSets which don't have a CalendarPeriodType + // --------------------------------------------------------------------- + + Iterator iterator = dataSets.iterator(); + + while ( iterator.hasNext() ) + { + DataSet dataSet = iterator.next(); + + if ( !( dataSet.getPeriodType() instanceof CalendarPeriodType) ) + { + iterator.remove(); + } + } + + return dataSets; + } } === removed file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadDisplayModesAction.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadDisplayModesAction.java 2011-05-20 13:28:27 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadDisplayModesAction.java 1970-01-01 00:00:00 +0000 @@ -1,94 +0,0 @@ -package org.hisp.dhis.de.action; - -/* - * Copyright (c) 2004-2010, University of Oslo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the HISP project nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -import org.hisp.dhis.dataset.DataSet; -import org.hisp.dhis.de.state.SelectedStateManager; - -import com.opensymphony.xwork2.Action; - -/** - * @author Lars Helge Overland - */ -public class LoadDisplayModesAction - implements Action -{ - // ------------------------------------------------------------------------- - // Dependencies - // ------------------------------------------------------------------------- - - private SelectedStateManager selectedStateManager; - - public void setSelectedStateManager( SelectedStateManager selectedStateManager ) - { - this.selectedStateManager = selectedStateManager; - } - - // ------------------------------------------------------------------------- - // Output - // ------------------------------------------------------------------------- - - private boolean customForm; - - public boolean isCustomForm() - { - return customForm; - } - - private boolean sectionForm; - - public boolean isSectionForm() - { - return sectionForm; - } - - private String displayMode; - - public String getDisplayMode() - { - return displayMode; - } - - // ------------------------------------------------------------------------- - // Action implementation - // ------------------------------------------------------------------------- - - @Override - public String execute() - { - DataSet dataSet = selectedStateManager.getSelectedDataSet(); - - customForm = dataSet.hasDataEntryForm(); - - sectionForm = dataSet.hasSections(); - - displayMode = selectedStateManager.getSelectedDisplayMode(); - - return SUCCESS; - } -} === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadFormAction.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadFormAction.java 2011-07-14 06:29:58 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadFormAction.java 2011-07-21 11:52:46 +0000 @@ -54,14 +54,15 @@ import org.hisp.dhis.dataset.CompleteDataSetRegistration; import org.hisp.dhis.dataset.CompleteDataSetRegistrationService; import org.hisp.dhis.dataset.DataSet; +import org.hisp.dhis.dataset.DataSetService; import org.hisp.dhis.dataset.Section; import org.hisp.dhis.dataset.comparator.SectionOrderComparator; -import org.hisp.dhis.datavalue.DataValue; -import org.hisp.dhis.de.state.SelectedStateManager; import org.hisp.dhis.i18n.I18n; import org.hisp.dhis.options.displayproperty.DisplayPropertyHandler; import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager; import org.hisp.dhis.period.Period; +import org.hisp.dhis.period.PeriodType; import com.opensymphony.xwork2.Action; @@ -74,8 +75,6 @@ { private static final Log log = LogFactory.getLog( LoadFormAction.class ); - private static final String SECTION_FORM = "sectionform"; - // ------------------------------------------------------------------------- // Dependencies // ------------------------------------------------------------------------- @@ -93,6 +92,13 @@ { this.dataElementService = dataElementService; } + + private DataSetService dataSetService; + + public void setDataSetService( DataSetService dataSetService ) + { + this.dataSetService = dataSetService; + } private DataSetLockService dataSetLockService; @@ -101,11 +107,11 @@ this.dataSetLockService = dataSetLockService; } - private SelectedStateManager selectedStateManager; + private OrganisationUnitSelectionManager selectionManager; - public void setSelectedStateManager( SelectedStateManager selectedStateManager ) + public void setSelectionManager( OrganisationUnitSelectionManager selectionManager ) { - this.selectedStateManager = selectedStateManager; + this.selectionManager = selectionManager; } private CompleteDataSetRegistrationService registrationService; @@ -169,13 +175,6 @@ return this.customDataEntryFormCode; } - private String displayMode; - - public void setDisplayMode( String displayMode ) - { - this.displayMode = displayMode; - } - private OrganisationUnit organisationUnit; public OrganisationUnit getOrganisationUnit() @@ -218,42 +217,25 @@ return sections; } - private Map dataValueMap; - - public Map getDataValueMap() - { - return dataValueMap; - } - - private List standardComments; - - public List getStandardComments() - { - return standardComments; - } - - private Integer selectedDataSetId; - - public void setSelectedDataSetId( Integer selectedDataSetId ) - { - this.selectedDataSetId = selectedDataSetId; - } - - public Integer getSelectedDataSetId() - { - return selectedDataSetId; - } - - private Integer selectedPeriodIndex; - - public void setSelectedPeriodIndex( Integer selectedPeriodIndex ) - { - this.selectedPeriodIndex = selectedPeriodIndex; - } - - public Integer getSelectedPeriodIndex() - { - return selectedPeriodIndex; + private Integer dataSetId; + + public void setDataSetId( Integer dataSetId ) + { + this.dataSetId = dataSetId; + } + + private String periodId; + + public void setPeriodId( String periodId ) + { + this.periodId = periodId; + } + + private boolean defaultForm; + + public void setDefaultForm( boolean defaultForm ) + { + this.defaultForm = defaultForm; } private Map>> orderedOptionsMap = new HashMap>>(); @@ -326,13 +308,6 @@ return greyedFields; } - private Integer defaultOptionComboId; - - public Integer getDefaultOptionComboId() - { - return defaultOptionComboId; - } - // ------------------------------------------------------------------------- // Action implementation // ------------------------------------------------------------------------- @@ -340,47 +315,25 @@ public String execute() throws Exception { - organisationUnit = selectedStateManager.getSelectedOrganisationUnit(); - - DataSet selectedDataSet = selectedStateManager.getSelectedDataSet(); - - // --------------------------------------------------------------------- - // Validate selected period - // --------------------------------------------------------------------- - - if ( selectedPeriodIndex == null ) - { - selectedPeriodIndex = selectedStateManager.getSelectedPeriodIndex(); - } - - if ( selectedPeriodIndex != null && selectedPeriodIndex >= 0 ) - { - selectedStateManager.setSelectedPeriodIndex( selectedPeriodIndex ); - - period = selectedStateManager.getSelectedPeriod(); - } - else - { - selectedStateManager.clearSelectedPeriod(); - - return INPUT; - } + organisationUnit = selectionManager.getSelectedOrganisationUnit(); + + DataSet dataSet = dataSetService.getDataSet( dataSetId ); + + Period period = PeriodType.createPeriodExternalId( periodId ); // --------------------------------------------------------------------- // Get data locking info // --------------------------------------------------------------------- - if ( selectedDataSet != null ) + if ( dataSet != null && period != null ) { - period = selectedStateManager.getSelectedPeriod(); - - DataSetLock dataSetLock = dataSetLockService.getDataSetLockByDataSetAndPeriod( selectedDataSet, period ); + DataSetLock dataSetLock = dataSetLockService.getDataSetLockByDataSetAndPeriod( dataSet, period ); if ( dataSetLock != null && dataSetLock.getSources().contains( organisationUnit ) ) { locked = true; - log.info( "Dataset '" + selectedDataSet.getName() + "' is locked " ); + log.info( "Dataset '" + dataSet.getName() + "' is locked " ); } } @@ -388,9 +341,9 @@ // Get data set completeness info // --------------------------------------------------------------------- - if ( selectedDataSet != null && period != null && organisationUnit != null ) + if ( dataSet != null && period != null && organisationUnit != null ) { - registration = registrationService.getCompleteDataSetRegistration( selectedDataSet, period, + registration = registrationService.getCompleteDataSetRegistration( dataSet, period, organisationUnit ); registrationDate = registration != null ? registration.getDate() : new Date(); @@ -400,23 +353,9 @@ // Get display mode // --------------------------------------------------------------------- - if ( !selectedStateManager.displayModeIsValid( displayMode ) ) - { - displayMode = selectedStateManager.getSelectedDisplayMode(); - } - - if ( !selectedStateManager.displayModeIsValid( displayMode ) ) - { - displayMode = selectedStateManager.getDisplayMode(); - } - - selectedStateManager.setSelectedDisplayMode( displayMode ); - - // --------------------------------------------------------------------- - // Get entry form - // --------------------------------------------------------------------- - - List dataElements = new ArrayList( selectedDataSet.getDataElements() ); + String displayMode = defaultForm ? DataSet.TYPE_DEFAULT : dataSet.getDataSetType(); + + List dataElements = new ArrayList( dataSet.getDataElements() ); if ( dataElements.isEmpty() ) { @@ -425,10 +364,6 @@ Collections.sort( dataElements, dataElementComparator ); - // --------------------------------------------------------------------- - // Get the min/max values - // --------------------------------------------------------------------- - orderedDataElements = dataElementService.getGroupedDataElementsByCategoryCombo( dataElements ); orderedCategoryCombos = dataElementService.getDataElementCategoryCombos( dataElements ); @@ -499,13 +434,13 @@ // Get data entry form // --------------------------------------------------------------------- - if ( displayMode.equals( SECTION_FORM ) ) + if ( displayMode.equals( DataSet.TYPE_SECTION ) ) { - getSectionForm( dataElements, selectedDataSet ); + getSectionForm( dataElements, dataSet ); } else { - getOtherDataEntryForm( dataElements, selectedDataSet ); + getOtherDataEntryForm( dataElements, dataSet, locked ); } return displayMode; @@ -517,18 +452,10 @@ private void getSectionForm( Collection dataElements, DataSet dataSet ) { - // --------------------------------------------------------------------- - // Order the Sections - // --------------------------------------------------------------------- - sections = new ArrayList
( dataSet.getSections() ); Collections.sort( sections, new SectionOrderComparator() ); - // --------------------------------------------------------------------- - // Get the category combos for the sections - // --------------------------------------------------------------------- - for ( Section section : sections ) { DataElementCategoryCombo sectionCategoryCombo = section.getCategoryCombo(); @@ -551,20 +478,11 @@ true ); } } - - defaultOptionComboId = categoryService.getDefaultDataElementCategoryOptionCombo().getId(); - } - private void getOtherDataEntryForm( List dataElements, DataSet dataSet ) + private void getOtherDataEntryForm( List dataElements, DataSet dataSet, boolean locked ) { - DataSetLock dataSetLock = dataSetLockService.getDataSetLockByDataSetAndPeriod( dataSet, period ); - - String disabled = dataSetLock != null && dataSetLock.getSources().contains( organisationUnit ) ? "disabled" : ""; - - // --------------------------------------------------------------------- - // Get the custom data entry form (if any) - // --------------------------------------------------------------------- + String disabled = locked ? "disabled" : ""; DataEntryForm dataEntryForm = dataSet.getDataEntryForm(); @@ -574,10 +492,6 @@ dataEntryForm.getHtmlCode(), disabled, i18n, dataSet ); } - // --------------------------------------------------------------------- - // Working on the display of data elements - // --------------------------------------------------------------------- - List des = new ArrayList(); for ( DataElementCategoryCombo categoryCombo : orderedCategoryCombos ) === removed file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadNextPreviousPeriodsAction.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadNextPreviousPeriodsAction.java 2011-05-20 13:28:27 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadNextPreviousPeriodsAction.java 1970-01-01 00:00:00 +0000 @@ -1,117 +0,0 @@ -package org.hisp.dhis.de.action; - -/* - * Copyright (c) 2004-2010, University of Oslo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the HISP project nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.hisp.dhis.de.state.SelectedStateManager; -import org.hisp.dhis.i18n.I18nFormat; -import org.hisp.dhis.period.Period; - -import com.opensymphony.xwork2.Action; - -/** - * @author Lars Helge Overland - */ -public class LoadNextPreviousPeriodsAction - implements Action -{ - // ------------------------------------------------------------------------- - // Dependencies - // ------------------------------------------------------------------------- - - private SelectedStateManager selectedStateManager; - - public void setSelectedStateManager( SelectedStateManager selectedStateManager ) - { - this.selectedStateManager = selectedStateManager; - } - - private I18nFormat format; - - public void setFormat( I18nFormat format ) - { - this.format = format; - } - - // ------------------------------------------------------------------------- - // Input - // ------------------------------------------------------------------------- - - private boolean next; - - public void setNext( boolean next ) - { - this.next = next; - } - - private boolean previous; - - public void setPrevious( boolean previous ) - { - this.previous = previous; - } - - // ------------------------------------------------------------------------- - // Output - // ------------------------------------------------------------------------- - - private List periods = new ArrayList(); - - public Collection getPeriods() - { - return periods; - } - - // ------------------------------------------------------------------------- - // Action implementation - // ------------------------------------------------------------------------- - - public String execute() - { - if ( next ) - { - selectedStateManager.nextPeriodSpan(); - } - else if ( previous ) - { - selectedStateManager.previousPeriodSpan(); - } - - periods = selectedStateManager.getPeriodList(); - - for ( Period period : periods ) - { - period.setName( format.formatPeriod( period ) ); - } - - return SUCCESS; - } -} === removed file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadPeriodsAction.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadPeriodsAction.java 2011-07-14 10:34:09 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/LoadPeriodsAction.java 1970-01-01 00:00:00 +0000 @@ -1,149 +0,0 @@ -package org.hisp.dhis.de.action; - -/* - * Copyright (c) 2004-2010, University of Oslo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the HISP project nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.hisp.dhis.dataset.DataSet; -import org.hisp.dhis.dataset.DataSetService; -import org.hisp.dhis.de.state.SelectedStateManager; -import org.hisp.dhis.i18n.I18nFormat; -import org.hisp.dhis.period.Period; - -import com.opensymphony.xwork2.Action; - -/** - * @author Lars Helge Overland - */ -public class LoadPeriodsAction - implements Action -{ - // ------------------------------------------------------------------------- - // Dependencies - // ------------------------------------------------------------------------- - - private SelectedStateManager selectedStateManager; - - public void setSelectedStateManager( SelectedStateManager selectedStateManager ) - { - this.selectedStateManager = selectedStateManager; - } - - private DataSetService dataSetService; - - public void setDataSetService( DataSetService dataSetService ) - { - this.dataSetService = dataSetService; - } - - private I18nFormat format; - - public void setFormat( I18nFormat format ) - { - this.format = format; - } - - // ------------------------------------------------------------------------- - // Input - // ------------------------------------------------------------------------- - - private Integer dataSetId; - - public void setDataSetId( Integer dataSetId ) - { - this.dataSetId = dataSetId; - } - - // ------------------------------------------------------------------------- - // Output - // ------------------------------------------------------------------------- - - private List periods = new ArrayList(); - - public Collection getPeriods() - { - return periods; - } - - private boolean periodValid; - - public boolean isPeriodValid() - { - return periodValid; - } - - // ------------------------------------------------------------------------- - // Action implementation - // ------------------------------------------------------------------------- - - public String execute() - { - DataSet selectedDataSet = dataSetService.getDataSet( dataSetId ); - - if ( selectedDataSet != null ) - { - // ----------------------------------------------------------------- - // Check if previous data set has same period type as selected - // ----------------------------------------------------------------- - - DataSet previousDataSet = selectedStateManager.getSelectedDataSet(); - - if ( previousDataSet != null && previousDataSet.getPeriodType().equals( selectedDataSet.getPeriodType() ) ) - { - periodValid = true; - } - else - { - selectedStateManager.clearSelectedPeriod(); - } - - // ----------------------------------------------------------------- - // Load periods for period type of selected data set - // ----------------------------------------------------------------- - - selectedStateManager.setSelectedDataSet( selectedDataSet ); - - periods = selectedStateManager.getPeriodList(); - - for ( Period period : periods ) - { - period.setName( format.formatPeriod( period ) ); - } - - // ----------------------------------------------------------------- - // Clear display mode when loading new data set - // ----------------------------------------------------------------- - - selectedStateManager.clearSelectedDisplayMode(); - } - - return SUCCESS; - } -} === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/PageInitAction.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/PageInitAction.java 2011-07-14 10:31:16 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/PageInitAction.java 2011-07-19 21:49:16 +0000 @@ -31,7 +31,8 @@ import org.hisp.dhis.dataelement.DataElement; import org.hisp.dhis.dataelement.DataElementService; -import org.hisp.dhis.de.state.SelectedStateManager; +import org.hisp.dhis.dataset.DataSet; +import org.hisp.dhis.dataset.DataSetService; import org.hisp.dhis.expression.ExpressionService; import org.hisp.dhis.indicator.Indicator; import org.hisp.dhis.indicator.IndicatorService; @@ -47,13 +48,6 @@ // ------------------------------------------------------------------------- // Dependencies // ------------------------------------------------------------------------- - - private SelectedStateManager selectedStateManager; - - public void setSelectedStateManager( SelectedStateManager selectedStateManager ) - { - this.selectedStateManager = selectedStateManager; - } private DataElementService dataElementService; @@ -75,6 +69,13 @@ { this.expressionService = expressionService; } + + private DataSetService dataSetService; + + public void setDataSetService( DataSetService dataSetService ) + { + this.dataSetService = dataSetService; + } // ------------------------------------------------------------------------- // Output @@ -93,21 +94,26 @@ { return indicators; } + + private Collection dataSets; + + public Collection getDataSets() + { + return dataSets; + } // ------------------------------------------------------------------------- // Action implementation // ------------------------------------------------------------------------- public String execute() - { - selectedStateManager.clearSelectedOrganisationUnits(); - selectedStateManager.clearSelectedDataSet(); - selectedStateManager.clearSelectedPeriod(); - + { significantZeros = dataElementService.getDataElementsByZeroIsSignificant( true ); indicators = indicatorService.getIndicatorsWithDataSets(); + dataSets = dataSetService.getAllDataSets(); + for ( Indicator indicator : indicators ) { indicator.setExplodedNumerator( expressionService.explodeExpression( indicator.getNumerator() ) ); === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/RegisterCompleteDataSetAction.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/RegisterCompleteDataSetAction.java 2011-01-25 16:02:32 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/RegisterCompleteDataSetAction.java 2011-07-20 19:58:06 +0000 @@ -33,7 +33,9 @@ import org.apache.commons.logging.LogFactory; import org.hisp.dhis.dataset.CompleteDataSetRegistration; import org.hisp.dhis.dataset.CompleteDataSetRegistrationService; -import org.hisp.dhis.de.state.SelectedStateManager; +import org.hisp.dhis.dataset.DataSetService; +import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager; +import org.hisp.dhis.period.PeriodType; import com.opensymphony.xwork2.Action; @@ -57,11 +59,36 @@ this.registrationService = registrationService; } - private SelectedStateManager selectedStateManager; - - public void setSelectedStateManager( SelectedStateManager selectedStateManager ) - { - this.selectedStateManager = selectedStateManager; + private OrganisationUnitSelectionManager selectionManager; + + public void setSelectionManager( OrganisationUnitSelectionManager selectionManager ) + { + this.selectionManager = selectionManager; + } + + private DataSetService dataSetService; + + public void setDataSetService( DataSetService dataSetService ) + { + this.dataSetService = dataSetService; + } + + // ------------------------------------------------------------------------- + // Input + // ------------------------------------------------------------------------- + + private String periodId; + + public void setPeriodId( String periodId ) + { + this.periodId = periodId; + } + + private Integer dataSetId; + + public void setDataSetId( Integer dataSetId ) + { + this.dataSetId = dataSetId; } // ------------------------------------------------------------------------- @@ -72,9 +99,9 @@ { CompleteDataSetRegistration registration = new CompleteDataSetRegistration(); - registration.setDataSet( selectedStateManager.getSelectedDataSet() ); - registration.setPeriod( selectedStateManager.getSelectedPeriod() ); - registration.setSource( selectedStateManager.getSelectedOrganisationUnit() ); + registration.setDataSet( dataSetService.getDataSet( dataSetId ) ); + registration.setPeriod( PeriodType.createPeriodExternalId( periodId ) ); + registration.setSource( selectionManager.getSelectedOrganisationUnit() ); registration.setDate( new Date() ); registrationService.saveCompleteDataSetRegistration( registration ); === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveCommentAction.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveCommentAction.java 2011-01-25 16:14:19 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveCommentAction.java 2011-07-20 21:38:30 +0000 @@ -37,10 +37,10 @@ import org.hisp.dhis.dataelement.DataElementService; import org.hisp.dhis.datavalue.DataValue; import org.hisp.dhis.datavalue.DataValueService; -import org.hisp.dhis.de.state.SelectedStateManager; import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.organisationunit.OrganisationUnitService; import org.hisp.dhis.period.Period; +import org.hisp.dhis.period.PeriodType; import org.hisp.dhis.user.CurrentUserService; import com.opensymphony.xwork2.Action; @@ -79,13 +79,6 @@ this.dataValueService = dataValueService; } - private SelectedStateManager selectedStateManager; - - public void setSelectedStateManager( SelectedStateManager selectedStateManager ) - { - this.selectedStateManager = selectedStateManager; - } - private DataElementCategoryService categoryService; public void setCategoryService( DataElementCategoryService categoryService ) @@ -104,6 +97,13 @@ // Input/output // ------------------------------------------------------------------------- + private String periodId; + + public void setPeriodId( String periodId ) + { + this.periodId = periodId; + } + private String comment; public void setComment( String comment ) @@ -152,7 +152,7 @@ { OrganisationUnit organisationUnit = organisationUnitService.getOrganisationUnit( organisationUnitId ); - Period period = selectedStateManager.getSelectedPeriod(); + Period period = PeriodType.createPeriodExternalId( periodId ); DataElement dataElement = dataElementService.getDataElement( dataElementId ); === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveValueAction.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveValueAction.java 2011-07-18 10:22:08 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/SaveValueAction.java 2011-07-19 21:49:16 +0000 @@ -35,10 +35,10 @@ import org.hisp.dhis.dataelement.DataElementService; import org.hisp.dhis.datavalue.DataValue; import org.hisp.dhis.datavalue.DataValueService; -import org.hisp.dhis.de.state.SelectedStateManager; import org.hisp.dhis.organisationunit.OrganisationUnit; import org.hisp.dhis.organisationunit.OrganisationUnitService; import org.hisp.dhis.period.Period; +import org.hisp.dhis.period.PeriodType; import org.hisp.dhis.user.CurrentUserService; import com.opensymphony.xwork2.Action; @@ -74,13 +74,6 @@ this.dataValueService = dataValueService; } - private SelectedStateManager selectedStateManager; - - public void setSelectedStateManager( SelectedStateManager selectedStateManager ) - { - this.selectedStateManager = selectedStateManager; - } - private DataElementCategoryService categoryService; public void setCategoryService( DataElementCategoryService categoryService ) @@ -126,6 +119,13 @@ { this.optionComboId = optionComboId; } + + private String periodId; + + public void setPeriodId( String periodId ) + { + this.periodId = periodId; + } // ------------------------------------------------------------------------- // Output @@ -146,7 +146,7 @@ { OrganisationUnit organisationUnit = organisationUnitService.getOrganisationUnit( organisationUnitId ); - Period period = selectedStateManager.getSelectedPeriod(); + Period period = PeriodType.createPeriodExternalId( periodId ); DataElement dataElement = dataElementService.getDataElement( dataElementId ); === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/UndoCompleteDataSetAction.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/UndoCompleteDataSetAction.java 2011-05-20 13:28:27 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/UndoCompleteDataSetAction.java 2011-07-20 19:58:06 +0000 @@ -32,9 +32,11 @@ import org.hisp.dhis.dataset.CompleteDataSetRegistration; import org.hisp.dhis.dataset.CompleteDataSetRegistrationService; import org.hisp.dhis.dataset.DataSet; -import org.hisp.dhis.de.state.SelectedStateManager; +import org.hisp.dhis.dataset.DataSetService; import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager; import org.hisp.dhis.period.Period; +import org.hisp.dhis.period.PeriodType; import com.opensymphony.xwork2.Action; @@ -56,23 +58,48 @@ { this.registrationService = registrationService; } - - private SelectedStateManager selectedStateManager; - - public void setSelectedStateManager( SelectedStateManager selectedStateManager ) - { - this.selectedStateManager = selectedStateManager; - } - + + private OrganisationUnitSelectionManager selectionManager; + + public void setSelectionManager( OrganisationUnitSelectionManager selectionManager ) + { + this.selectionManager = selectionManager; + } + + private DataSetService dataSetService; + + public void setDataSetService( DataSetService dataSetService ) + { + this.dataSetService = dataSetService; + } + + // ------------------------------------------------------------------------- + // Input + // ------------------------------------------------------------------------- + + private String periodId; + + public void setPeriodId( String periodId ) + { + this.periodId = periodId; + } + + private Integer dataSetId; + + public void setDataSetId( Integer dataSetId ) + { + this.dataSetId = dataSetId; + } + // ------------------------------------------------------------------------- // Action implementation // ------------------------------------------------------------------------- public String execute() { - DataSet dataSet = selectedStateManager.getSelectedDataSet(); - Period period = selectedStateManager.getSelectedPeriod(); - OrganisationUnit unit = selectedStateManager.getSelectedOrganisationUnit(); + DataSet dataSet = dataSetService.getDataSet( dataSetId ); + Period period = PeriodType.createPeriodExternalId( periodId ); + OrganisationUnit unit = selectionManager.getSelectedOrganisationUnit(); CompleteDataSetRegistration registration = registrationService.getCompleteDataSetRegistration( dataSet, period, unit ); === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/ValidationAction.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/ValidationAction.java 2011-06-12 08:23:05 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/action/ValidationAction.java 2011-07-20 19:58:06 +0000 @@ -39,16 +39,18 @@ import org.apache.commons.logging.LogFactory; import org.hisp.dhis.dataanalysis.DataAnalysisService; import org.hisp.dhis.dataset.DataSet; +import org.hisp.dhis.dataset.DataSetService; import org.hisp.dhis.datavalue.DeflatedDataValue; -import org.hisp.dhis.de.state.SelectedStateManager; import org.hisp.dhis.expression.ExpressionService; import org.hisp.dhis.minmax.MinMaxDataElement; import org.hisp.dhis.minmax.MinMaxDataElementService; import org.hisp.dhis.minmax.validation.MinMaxValuesGenerationService; import org.hisp.dhis.options.SystemSettingManager; import org.hisp.dhis.organisationunit.OrganisationUnit; +import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager; import org.hisp.dhis.period.Period; import org.hisp.dhis.period.PeriodService; +import org.hisp.dhis.period.PeriodType; import org.hisp.dhis.system.util.ListUtils; import org.hisp.dhis.validation.ValidationResult; import org.hisp.dhis.validation.ValidationRule; @@ -78,13 +80,6 @@ this.validationRuleService = validationRuleService; } - private SelectedStateManager selectedStateManager; - - public void setSelectedStateManager( SelectedStateManager selectedStateManager ) - { - this.selectedStateManager = selectedStateManager; - } - private ExpressionService expressionService; public void setExpressionService( ExpressionService expressionService ) @@ -134,6 +129,38 @@ this.minMaxDataElementService = minMaxDataElementService; } + private OrganisationUnitSelectionManager selectionManager; + + public void setSelectionManager( OrganisationUnitSelectionManager selectionManager ) + { + this.selectionManager = selectionManager; + } + + private DataSetService dataSetService; + + public void setDataSetService( DataSetService dataSetService ) + { + this.dataSetService = dataSetService; + } + + // ------------------------------------------------------------------------- + // Input + // ------------------------------------------------------------------------- + + private String periodId; + + public void setPeriodId( String periodId ) + { + this.periodId = periodId; + } + + private Integer dataSetId; + + public void setDataSetId( Integer dataSetId ) + { + this.dataSetId = dataSetId; + } + // ------------------------------------------------------------------------- // Output // ------------------------------------------------------------------------- @@ -174,16 +201,16 @@ public String execute() throws Exception { - OrganisationUnit orgUnit = selectedStateManager.getSelectedOrganisationUnit(); + OrganisationUnit orgUnit = selectionManager.getSelectedOrganisationUnit(); - Period selectedPeriod = selectedStateManager.getSelectedPeriod(); + Period selectedPeriod = PeriodType.createPeriodExternalId( periodId ); if ( orgUnit != null && selectedPeriod != null ) { Period period = periodService.getPeriod( selectedPeriod.getStartDate(), selectedPeriod.getEndDate(), selectedPeriod.getPeriodType() ); - DataSet dataSet = selectedStateManager.getSelectedDataSet(); + DataSet dataSet = dataSetService.getDataSet( dataSetId ); // --------------------------------------------------------------------- // Min-max and outlier analysis === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/history/DefaultHistoryRetriever.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/history/DefaultHistoryRetriever.java 2010-04-12 21:23:33 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/history/DefaultHistoryRetriever.java 2011-07-20 21:38:30 +0000 @@ -81,13 +81,7 @@ { if ( !dataElement.getType().equals( DataElement.VALUE_TYPE_INT ) ) { - return null; - - /* - * throw new HistoryRetrieverException( - * "DataElement is not of type " + DataElement.TYPE_INT + ": " + - * dataElement.getShortName() ) ; - */ + return null; // TODO } // --------------------------------------------------------------------- @@ -143,10 +137,8 @@ history.setMaxHistoryValue( max ); - // get the maxValue double maxValue = getMaxValue( history ); - // if there was any entred values, set minValue and maxValue if ( maxValue != Double.NEGATIVE_INFINITY ) { history.setMaxValue( maxValue ); === removed directory 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state' === removed file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state/DefaultSelectedStateManager.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state/DefaultSelectedStateManager.java 2011-07-14 11:21:28 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state/DefaultSelectedStateManager.java 1970-01-01 00:00:00 +0000 @@ -1,354 +0,0 @@ -package org.hisp.dhis.de.state; - -/* - * Copyright (c) 2004-2010, University of Oslo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the HISP project nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.hisp.dhis.dataset.DataSet; -import org.hisp.dhis.dataset.DataSetService; -import org.hisp.dhis.organisationunit.OrganisationUnit; -import org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager; -import org.hisp.dhis.period.CalendarPeriodType; -import org.hisp.dhis.period.Period; -import org.hisp.dhis.period.PeriodService; -import org.hisp.dhis.period.PeriodType; -import org.hisp.dhis.user.CurrentUserService; -import org.hisp.dhis.user.User; - -import com.opensymphony.xwork2.ActionContext; - -/** - * @author Torgeir Lorange Ostby - * @version $Id: DefaultSelectedStateManager.java 5282 2008-05-28 10:41:06Z - * larshelg $ - */ -public class DefaultSelectedStateManager - implements SelectedStateManager -{ - public static final String SESSION_KEY_SELECTED_DATASET_ID = "data_entry_selected_dataset_id"; - public static final String SESSION_KEY_SELECTED_PERIOD_INDEX = "data_entry_selected_period_index"; - public static final String SESSION_KEY_BASE_PERIOD = "data_entry_base_period"; - public static final String SESSION_KEY_SELECTED_DISPLAY_MODE = "data_entry_selected_display_mode"; - - // ------------------------------------------------------------------------- - // Dependencies - // ------------------------------------------------------------------------- - - private DataSetService dataSetService; - - public void setDataSetService( DataSetService dataSetService ) - { - this.dataSetService = dataSetService; - } - - private OrganisationUnitSelectionManager selectionManager; - - public void setSelectionManager( OrganisationUnitSelectionManager selectionManager ) - { - this.selectionManager = selectionManager; - } - - private CurrentUserService currentUserService; - - public void setCurrentUserService( CurrentUserService currentUserService ) - { - this.currentUserService = currentUserService; - } - - public PeriodService periodService; - - public void setPeriodService( PeriodService periodService ) - { - this.periodService = periodService; - } - - // ------------------------------------------------------------------------- - // SelectedStateManager implementation - // ------------------------------------------------------------------------- - - // ------------------------------------------------------------------------- - // OrganisationUnit - // ------------------------------------------------------------------------- - - public OrganisationUnit getSelectedOrganisationUnit() - { - return selectionManager.getSelectedOrganisationUnit(); - } - - public void clearSelectedOrganisationUnits() - { - selectionManager.clearSelectedOrganisationUnits(); - } - - // ------------------------------------------------------------------------- - // DataSet - // ------------------------------------------------------------------------- - - public void setSelectedDataSet( DataSet dataSet ) - { - getSession().put( SESSION_KEY_SELECTED_DATASET_ID, dataSet.getId() ); - } - - public DataSet getSelectedDataSet() - { - Integer id = (Integer) getSession().get( SESSION_KEY_SELECTED_DATASET_ID ); - - return id != null ? dataSetService.getDataSet( id ) : null; - } - - public void clearSelectedDataSet() - { - getSession().remove( SESSION_KEY_SELECTED_DATASET_ID ); - } - - public List loadDataSetsForSelectedOrgUnit() - { - List dataSets = new ArrayList( getSelectedOrganisationUnit().getDataSets() ); - - // --------------------------------------------------------------------- - // Retain only DataSets from current user's authority groups - // --------------------------------------------------------------------- - - User currentUser = currentUserService.getCurrentUser(); - - if ( currentUser != null && !currentUserService.currentUserIsSuper() ) - { - dataSets.retainAll( currentUser.getUserCredentials().getAllDataSets() ); - } - - // --------------------------------------------------------------------- - // Remove DataSets which don't have a CalendarPeriodType - // --------------------------------------------------------------------- - - Iterator iterator = dataSets.iterator(); - - while ( iterator.hasNext() ) - { - DataSet dataSet = iterator.next(); - - if ( !( dataSet.getPeriodType() instanceof CalendarPeriodType) ) - { - iterator.remove(); - } - } - - return dataSets; - } - - // ------------------------------------------------------------------------- - // Period - // ------------------------------------------------------------------------- - - public void setSelectedPeriodIndex( Integer index ) - { - getSession().put( SESSION_KEY_SELECTED_PERIOD_INDEX, index ); - } - - public Integer getSelectedPeriodIndex() - { - return (Integer) getSession().get( SESSION_KEY_SELECTED_PERIOD_INDEX ); - } - - public Period getSelectedPeriod() - { - Integer index = getSelectedPeriodIndex(); - - if ( index == null ) - { - return null; - } - - List periods = getPeriodList(); - - if ( index >= 0 && index < periods.size() ) - { - return periods.get( index ); - } - - return null; - } - - public void clearSelectedPeriod() - { - getSession().remove( SESSION_KEY_SELECTED_PERIOD_INDEX ); - } - - public List getPeriodList() - { - if ( getSelectedDataSet() == null ) - { - return new ArrayList(); - } - - Period basePeriod = getBasePeriod(); - - CalendarPeriodType periodType = (CalendarPeriodType) getPeriodType(); - - List periods = periodType.generatePeriods( basePeriod ); - - Date now = new Date(); - - Iterator iterator = periods.iterator(); - - while ( iterator.hasNext() ) - { - if ( iterator.next().getStartDate().after( now ) ) - { - iterator.remove(); - } - } - - return periods; - } - - public void nextPeriodSpan() - { - if ( getSelectedDataSet() != null ) - { - List periods = getPeriodList(); - CalendarPeriodType periodType = (CalendarPeriodType) getPeriodType(); - - Period basePeriod = periods.get( periods.size() - 1 ); - Period newBasePeriod = periodType.getNextPeriod( basePeriod ); - - if ( newBasePeriod.getStartDate().before( new Date() ) ) // Future periods not allowed - { - getSession().put( SESSION_KEY_BASE_PERIOD, newBasePeriod ); - } - } - } - - public void previousPeriodSpan() - { - if ( getSelectedDataSet() != null ) - { - List periods = getPeriodList(); - CalendarPeriodType periodType = (CalendarPeriodType) getPeriodType(); - - Period basePeriod = periods.get( 0 ); - Period newBasePeriod = periodType.getPreviousPeriod( basePeriod ); - - getSession().put( SESSION_KEY_BASE_PERIOD, newBasePeriod ); - } - } - - public Period reloadPeriod() - { - Period period = getSelectedPeriod(); - - return periodService.reloadPeriod( period ); - } - - // ------------------------------------------------------------------------- - // DisplayMode - // ------------------------------------------------------------------------- - - public void setSelectedDisplayMode( String displayMode ) - { - getSession().put( SESSION_KEY_SELECTED_DISPLAY_MODE, displayMode ); - } - - public String getSelectedDisplayMode() - { - return (String) getSession().get( SESSION_KEY_SELECTED_DISPLAY_MODE ); - } - - public void clearSelectedDisplayMode() - { - getSession().remove( SESSION_KEY_SELECTED_DISPLAY_MODE ); - } - - public boolean displayModeIsValid( String displayMode ) - { - DataSet dataSet = getSelectedDataSet(); - - final Map map = new HashMap(); - map.put( CUSTOM_FORM, dataSet.hasDataEntryForm() ); - map.put( SECTION_FORM, dataSet.hasSections() ); - map.put( DEFAULT_FORM, true ); - - return displayMode != null && map.containsKey( displayMode ) ? map.get( displayMode ) : false; - } - - public String getDisplayMode() - { - DataSet dataSet = getSelectedDataSet(); - - if ( dataSet.hasDataEntryForm() ) - { - return CUSTOM_FORM; - } - else if ( dataSet.hasSections() ) - { - return SECTION_FORM; - } - - return DEFAULT_FORM; - } - - // ------------------------------------------------------------------------- - // Support methods - // ------------------------------------------------------------------------- - - private PeriodType getPeriodType() - { - DataSet dataSet = getSelectedDataSet(); - - return dataSet != null ? dataSet.getPeriodType() : null; - } - - private Period getBasePeriod() - { - Period basePeriod = (Period) getSession().get( SESSION_KEY_BASE_PERIOD ); - - PeriodType periodType = getPeriodType(); - - if ( basePeriod == null ) - { - basePeriod = periodType.createPeriod(); - getSession().put( SESSION_KEY_BASE_PERIOD, basePeriod ); - } - else if ( !basePeriod.getPeriodType().equals( periodType ) ) - { - basePeriod = periodType.createPeriod( basePeriod.getStartDate() ); - getSession().put( SESSION_KEY_BASE_PERIOD, basePeriod ); - } - - return basePeriod; - } - - private static final Map getSession() - { - return ActionContext.getContext().getSession(); - } -} === removed file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state/SelectedStateManager.java' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state/SelectedStateManager.java 2011-01-24 19:40:35 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/java/org/hisp/dhis/de/state/SelectedStateManager.java 1970-01-01 00:00:00 +0000 @@ -1,102 +0,0 @@ -package org.hisp.dhis.de.state; - -/* - * Copyright (c) 2004-2010, University of Oslo - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the HISP project nor the names of its contributors may - * be used to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -import java.util.Arrays; -import java.util.List; - -import org.hisp.dhis.dataset.DataSet; -import org.hisp.dhis.organisationunit.OrganisationUnit; -import org.hisp.dhis.period.Period; - -/** - * @author Torgeir Lorange Ostby - * @version $Id: SelectedStateManager.java 3311 2007-05-18 14:08:01Z torgeilo $ - */ -public interface SelectedStateManager -{ - final String CUSTOM_FORM = "customform"; - final String SECTION_FORM = "sectionform"; - final String DEFAULT_FORM = "defaultform"; - - final List ALLOWED_FORM_TYPES = Arrays.asList( CUSTOM_FORM, SECTION_FORM, DEFAULT_FORM ); - - // ------------------------------------------------------------------------- - // OrganisationUnit - // ------------------------------------------------------------------------- - - OrganisationUnit getSelectedOrganisationUnit(); - - void clearSelectedOrganisationUnits(); - - // ------------------------------------------------------------------------- - // DataSet - // ------------------------------------------------------------------------- - - void setSelectedDataSet( DataSet dataSet ); - - DataSet getSelectedDataSet(); - - void clearSelectedDataSet(); - - List loadDataSetsForSelectedOrgUnit(); - - // ------------------------------------------------------------------------- - // Period - // ------------------------------------------------------------------------- - - void setSelectedPeriodIndex( Integer index ); - - Integer getSelectedPeriodIndex(); - - Period getSelectedPeriod(); - - void clearSelectedPeriod(); - - List getPeriodList(); - - void nextPeriodSpan(); - - void previousPeriodSpan(); - - Period reloadPeriod(); - - // ------------------------------------------------------------------------- - // DisplayMode - // ------------------------------------------------------------------------- - - void setSelectedDisplayMode( String displayMode ); - - String getSelectedDisplayMode(); - - void clearSelectedDisplayMode(); - - boolean displayModeIsValid( String displayMode ); - - String getDisplayMode(); -} === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/META-INF/dhis/beans.xml' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/META-INF/dhis/beans.xml 2011-07-14 10:34:09 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/META-INF/dhis/beans.xml 2011-07-20 21:38:30 +0000 @@ -9,54 +9,36 @@ - - - - - - - - + - + + - - - - - - - - - - - - - - + + + + - + @@ -65,7 +47,6 @@ - @@ -74,7 +55,6 @@ - @@ -98,7 +78,7 @@ - + @@ -107,25 +87,28 @@ - + + - + + - + + - + === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/struts.xml' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/struts.xml 2011-07-14 07:33:23 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/resources/struts.xml 2011-07-21 11:52:46 +0000 @@ -26,22 +26,10 @@ /dhis-web-dataentry/responseDataSets.vm - - /dhis-web-dataentry/responsePeriods.vm - - - - ../dhis-web-commons/ajax/jsonPeriods.vm - - - - /dhis-web-dataentry/responseDisplayModes.vm - - - /dhis-web-dataentry/customForm.vm - /dhis-web-dataentry/sectionForm.vm - /dhis-web-dataentry/defaultForm.vm + /dhis-web-dataentry/customForm.vm + /dhis-web-dataentry/sectionForm.vm + /dhis-web-dataentry/defaultForm.vm /dhis-web-dataentry/responseVoid.vm === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/history.vm' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/history.vm 2011-06-27 10:39:01 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/history.vm 2011-07-20 21:38:30 +0000 @@ -2,6 +2,7 @@ var currentOrganisationUnitId = $!{dataElementHistory.organisationUnit.id}; var currentDataElementId = $!{dataElementHistory.dataElement.id}; var currentOptionComboId = $!{dataElementHistory.optionCombo.id}; + var currentPeriodId = '${periodId}'; var i18n_enter_digits = '$encoder.jsEscape( $i18n.getString( "enter_digits" ) , "'")'; var i18n_max_must_be_greater_than_min = '$encoder.jsEscape( $i18n.getString( "max_must_be_greater_than_min" ) , "'")'; @@ -84,7 +85,7 @@

$encoder.htmlEncode( $i18n.getString( "history_not_valid" ) )

#end - + === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/entry.js' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/entry.js 2011-07-14 10:31:16 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/entry.js 2011-07-19 21:49:16 +0000 @@ -99,6 +99,8 @@ $( fieldId ).css( 'background-color', COLOR_YELLOW ); + var periodId = $( '#selectedPeriodId' ).val(); + if ( value ) { if ( type == 'int' || type == 'number' || type == 'positiveNumber' || type == 'negativeNumber' ) @@ -144,7 +146,7 @@ if ( valueNo < min ) { - var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, value, COLOR_ORANGE ); + var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, periodId, value, COLOR_ORANGE ); valueSaver.save(); window.alert( i18n_value_of_data_element_less + ': ' + min + '\n\n' + dataElementName ); @@ -153,7 +155,7 @@ if ( valueNo > max ) { - var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, value, COLOR_ORANGE ); + var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, periodId, value, COLOR_ORANGE ); valueSaver.save(); window.alert( i18n_value_of_data_element_greater + ': ' + max + '\n\n' + dataElementName ); @@ -162,7 +164,7 @@ } } - var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, value, COLOR_GREEN ); + var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, periodId, value, COLOR_GREEN ); valueSaver.save(); updateIndicators(); // Update indicators in case of custom form @@ -176,7 +178,9 @@ $( fieldId ).css( 'background-color', COLOR_YELLOW ); - var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, value, COLOR_GREEN ); + var periodId = $( '#selectedPeriodId' ).val(); + + var valueSaver = new ValueSaver( dataElementId, optionComboId, currentOrganisationUnitId, periodId, value, COLOR_GREEN ); valueSaver.save(); } @@ -197,18 +201,19 @@ // Saver objects // ----------------------------------------------------------------------------- -function ValueSaver( dataElementId_, optionComboId_, organisationUnitId_, value_, resultColor_ ) +function ValueSaver( dataElementId_, optionComboId_, organisationUnitId_, periodId_, value_, resultColor_ ) { var dataElementId = dataElementId_; var optionComboId = optionComboId_; var value = value_; var resultColor = resultColor_; var organisationUnitId = organisationUnitId_; + var periodId = periodId_; this.save = function() { var url = 'saveValue.action?organisationUnitId=' + organisationUnitId + '&dataElementId=' + dataElementId - + '&optionComboId=' + optionComboId + '&value=' + value; + + '&optionComboId=' + optionComboId + '&periodId=' + periodId + '&value=' + value; $.ajax( { url : url, === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/form.js' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/form.js 2011-07-14 10:31:16 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/form.js 2011-07-21 11:52:46 +0000 @@ -1,15 +1,27 @@ // Identifiers for which zero values are, insignificant, also used in entry.js, populated in select.vm var significantZeros = []; -// Associative array with [indicator id, expression] for indicators in form, also used in entry.js +// Associative array with [indicator id, expression] for indicators in form, also used in entry.js, populated in select.vm var indicatorFormulas = []; +// Array with associative arrays for each data set, populated in select.vm +var dataSets = []; + // Indicates whether any data entry form has been loaded var dataEntryFormIsLoaded = false; // Currently selected organisation unit identifier var currentOrganisationUnitId = null; +// Currently selected data set identifier +var currentDataSetId = null; + +// Current offset, next or previous corresponding to increasing or decreasing value with one +var currentPeriodOffset = 0; + +// Period type object +var periodTypeFactory = new PeriodType(); + var COLOR_GREEN = '#b9ffb9'; var COLOR_YELLOW = '#fffe8c'; var COLOR_RED = '#ff8a8a'; @@ -24,7 +36,7 @@ function clearPeriod() { - clearListById( 'selectedPeriodIndex' ); + clearListById( 'selectedPeriodId' ); clearEntryForm(); } @@ -32,9 +44,26 @@ { $( '#contentDiv' ).html( '' ); + currentPeriodOffset = 0; + dataEntryFormIsLoaded = false; } +function loadForm( periodId, dataSetId ) +{ + var defaultForm = $( '#defaultForm' ).is( ':checked' ); + + $( '#contentDiv' ).load( 'loadForm.action', { periodId:periodId, dataSetId:dataSetId, defaultForm:defaultForm }, loadDataValues ); +} + +function loadDefaultForm() +{ + var dataSetId = $( '#selectedDataSetId' ).val(); + var periodId = $( '#selectedPeriodId' ).val(); + + loadForm( periodId, dataSetId ); +} + // ----------------------------------------------------------------------------- // OrganisationUnit Selection // ----------------------------------------------------------------------------- @@ -46,12 +75,13 @@ $( '#selectedDataSetId' ).removeAttr( 'disabled' ); var dataSetId = $( '#selectedDataSetId' ).val(); + var periodId = $( '#selectedPeriodId' ).val(); var url = 'loadDataSets.action'; clearListById( 'selectedDataSetId' ); - $.getJSON( url, function( json ) + $.getJSON( url, { dataSetId:dataSetId }, function( json ) { $( '#selectedOrganisationUnit' ).val( json.organisationUnit.name ); $( '#currentOrganisationUnit' ).html( json.organisationUnit.name ); @@ -67,7 +97,7 @@ { $( '#selectedDataSetId' ).val( dataSetId ); - if ( json.periodValid && dataEntryFormIsLoaded ) + if ( periodId && periodId != -1 && dataEntryFormIsLoaded ) //TODO if period valid { showLoader(); loadDataValues(); @@ -88,45 +118,34 @@ function nextPeriodsSelected() { - displayPeriodsInternal( true, false ); + if ( currentPeriodOffset < 0 ) // Cannot display future periods + { + currentPeriodOffset++; + displayPeriodsInternal(); + } } function previousPeriodsSelected() { - displayPeriodsInternal( false, true ); + currentPeriodOffset--; + displayPeriodsInternal(); } -function displayPeriodsInternal( next, previous ) +function displayPeriodsInternal() { - disableNextPrevButtons(); - - var url = 'loadNextPreviousPeriods.action?next=' + next + '&previous=' + previous; - - clearListById( 'selectedPeriodIndex' ); - - $.getJSON( url, function( json ) + var dataSetId = $( '#selectedDataSetId' ).val(); + var periodType = dataSets[dataSetId].periodType; + var periods = periodTypeFactory.get( periodType ).generatePeriods( currentPeriodOffset ); + periods = periodTypeFactory.filterFuturePeriods( periods ); + + clearListById( 'selectedPeriodId' ); + + addOptionById( 'selectedPeriodId', '-1', '[ ' + i18n_select_period + ' ]' ); + + for ( i in periods ) { - addOptionById( 'selectedPeriodIndex', '-1', '[ ' + i18n_select_period + ' ]' ); - - for ( i in json.periods ) - { - addOptionById( 'selectedPeriodIndex', i, json.periods[i].name ); - } - - enableNextPrevButtons(); - } ); -} - -function disableNextPrevButtons() -{ - $( '#nextButton' ).attr( 'disabled', 'disabled' ); - $( '#prevButton' ).attr( 'disabled', 'disabled' ); -} - -function enableNextPrevButtons() -{ - $( '#nextButton' ).removeAttr( 'disabled' ); - $( '#prevButton' ).removeAttr( 'disabled' ); + addOptionById( 'selectedPeriodId', periods[i].id, periods[i].name ); + } } // ----------------------------------------------------------------------------- @@ -135,80 +154,68 @@ function dataSetSelected() { - $( '#selectedPeriodIndex' ).removeAttr( 'disabled' ); + $( '#selectedPeriodId' ).removeAttr( 'disabled' ); $( '#prevButton' ).removeAttr( 'disabled' ); $( '#nextButton' ).removeAttr( 'disabled' ); var dataSetId = $( '#selectedDataSetId' ).val(); - var periodIndex = $( '#selectedPeriodIndex' ).val(); + var periodId = $( '#selectedPeriodId' ).val(); + var periodType = dataSets[dataSetId].periodType; + var periods = periodTypeFactory.get( periodType ).generatePeriods( currentPeriodOffset ); + periods = periodTypeFactory.filterFuturePeriods( periods ); if ( dataSetId && dataSetId != -1 ) { - var url = 'loadPeriods.action?dataSetId=' + dataSetId; - - clearListById( 'selectedPeriodIndex' ); - - $.getJSON( url, function( json ) - { - addOptionById( 'selectedPeriodIndex', '-1', '[ ' + i18n_select_period + ' ]' ); - - for ( i in json.periods ) - { - addOptionById( 'selectedPeriodIndex', i, json.periods[i].name ); - } - - if ( json.periodValid && periodIndex != null ) - { - showLoader(); - $( '#selectedPeriodIndex' ).val( periodIndex ); - $( '#contentDiv' ).load( 'loadForm.action', loadDataValuesAndDisplayModes ); - } - else - { - clearEntryForm(); - } - } ); + clearListById( 'selectedPeriodId' ); + + addOptionById( 'selectedPeriodId', '-1', '[ ' + i18n_select_period + ' ]' ); + + for ( i in periods ) + { + addOptionById( 'selectedPeriodId', periods[i].id, periods[i].name ); + } + + var previousPeriodType = currentDataSetId ? dataSets[currentDataSetId].periodType : null; + + if ( periodId && periodId != -1 && previousPeriodType && previousPeriodType == periodType ) //TODO if periodValid + { + showLoader(); + $( '#selectedPeriodId' ).val( periodId ); + loadForm( periodId, dataSetId ); + } + else + { + clearEntryForm(); + } + + currentDataSetId = dataSetId; } } // ----------------------------------------------------------------------------- -// DisplayMode Selection -// ----------------------------------------------------------------------------- - -function displayModeSelected() -{ - showLoader(); - - var url = 'loadForm.action?displayMode=' + $( "input[name='displayMode']:checked" ).val(); - - $( '#contentDiv' ).load( url, loadDataValues ); -} - -// ----------------------------------------------------------------------------- // Period Selection // ----------------------------------------------------------------------------- function periodSelected() { - var periodName = $( '#selectedPeriodIndex :selected' ).text(); + var periodName = $( '#selectedPeriodId :selected' ).text(); + var dataSetId = $( '#selectedDataSetId' ).val(); $( '#currentPeriod' ).html( periodName ); - var periodIndex = $( '#selectedPeriodIndex' ).val(); + var periodId = $( '#selectedPeriodId' ).val(); - if ( periodIndex && periodIndex != -1 ) + if ( periodId && periodId != -1 ) { showLoader(); if ( dataEntryFormIsLoaded ) { - loadDataValuesAndDisplayModes(); + loadDataValues(); } else { - var url = 'loadForm.action?selectedPeriodIndex=' + periodIndex; - - $( '#contentDiv' ).load( url, loadDataValuesAndDisplayModes ); + loadForm( periodId, dataSetId ); } } } @@ -223,18 +230,12 @@ displayEntryFormCompleted(); } -function loadDataValuesAndDisplayModes() -{ - insertDataValues(); - setDisplayModes(); - displayEntryFormCompleted(); -} - function insertDataValues() { var valueMap = new Array(); - var periodIndex = $( '#selectedPeriodIndex' ).val(); + var periodId = $( '#selectedPeriodId' ).val(); + var dataSetId = $( '#selectedDataSetId' ).val(); // Clear existing values and colors @@ -247,7 +248,7 @@ $( '[name="min"]' ).html( '' ); $( '[name="max"]' ).html( '' ); - $.getJSON( 'getDataValues.action', { selectedPeriodIndex:periodIndex }, function( json ) + $.getJSON( 'getDataValues.action', { periodId:periodId, dataSetId:dataSetId }, function( json ) { // Set data values, works for select lists too as data value = select value @@ -296,46 +297,12 @@ } ); } -function setDisplayModes() -{ - $.getJSON( 'loadDisplayModes.action', function( json ) - { - $( '#displayModeCustom' ).removeAttr( 'disabled' ); - $( '#displayModeSection' ).removeAttr( 'disabled' ); - $( '#displayModeDefault' ).removeAttr( 'disabled' ); - - $( '#displayModeCustom' ).removeAttr( 'checked' ); - $( '#displayModeSection' ).removeAttr( 'checked' ); - $( '#displayModeDefault' ).removeAttr( 'checked' ); - - if ( json.displayMode == 'customform' ) - { - $( '#displayModeCustom' ).attr( 'checked', 'checked' ); - } - else if ( json.displayMode == 'sectionform' ) - { - $( '#displayModeSection' ).attr( 'checked', 'checked' ); - } - else - { - $( '#displayModeDefault' ).attr( 'checked', 'checked' ); - } - - if ( !json.customForm ) - { - $( '#displayModeCustom' ).attr( 'disabled', 'disabled' ); - } - if ( !json.sectionForm ) - { - $( '#displayModeSection' ).attr( 'disabled', 'disabled' ); - } - } ); -} - function displayEntryFormCompleted() { addEventListeners(); - enable( 'validationButton' ); + $( '#validationButton' ).removeAttr( 'disabled' ); + $( '#defaultForm' ).removeAttr( 'disabled' ); + dataEntryFormIsLoaded = true; hideLoader(); } @@ -416,10 +383,13 @@ if ( confirmed ) { + var periodId = $( '#selectedPeriodId' ).val(); + var dataSetId = $( '#selectedDataSetId' ).val(); + $( '#completeButton' ).attr( 'disabled', 'disabled' ); $( '#undoButton' ).removeAttr( 'disabled' ); - $.getJSON( 'getValidationViolations.action', registerCompleteDataSet ).error( function() + $.getJSON( 'getValidationViolations.action', { periodId:periodId, dataSetId:dataSetId }, registerCompleteDataSet ).error( function() { $( '#completeButton' ).removeAttr( 'disabled' ); $( '#undoButton' ).attr( 'disabled', 'disabled' ); @@ -431,9 +401,12 @@ function registerCompleteDataSet( json ) { + var periodId = $( '#selectedPeriodId' ).val(); + var dataSetId = $( '#selectedDataSetId' ).val(); + if ( json.response == 'success' ) { - $.getJSON( 'registerCompleteDataSet.action', function() + $.getJSON( 'registerCompleteDataSet.action', { periodId:periodId, dataSetId:dataSetId }, function() { } ).error( function() { @@ -445,7 +418,9 @@ } else { - window.open( 'validate.action', '_blank', 'width=800, height=400, scrollbars=yes, resizable=yes' ); + var url = 'validate.action?periodId=' + periodId + '&dataSetId=' + dataSetId; + + window.open( url, '_blank', 'width=800, height=400, scrollbars=yes, resizable=yes' ); } } @@ -455,10 +430,13 @@ if ( confirmed ) { + var periodId = $( '#selectedPeriodId' ).val(); + var dataSetId = $( '#selectedDataSetId' ).val(); + $( '#completeButton' ).removeAttr( 'disabled' ); $( '#undoButton' ).attr( 'disabled', 'disabled' ); - $.getJSON( 'undoCompleteDataSet.action', function() + $.getJSON( 'undoCompleteDataSet.action', { periodId:periodId, dataSetId:dataSetId }, function() { } ).error( function() { @@ -476,7 +454,12 @@ function validate() { - window.open( 'validate.action', '_blank', 'width=800, height=400, scrollbars=yes, resizable=yes' ); + var periodId = $( '#selectedPeriodId' ).val(); + var dataSetId = $( '#selectedDataSetId' ).val(); + + var url = 'validate.action?periodId=' + periodId + '&dataSetId=' + dataSetId; + + window.open( url, '_blank', 'width=800, height=400, scrollbars=yes, resizable=yes' ); } // ----------------------------------------------------------------------------- @@ -485,13 +468,10 @@ function viewHist( dataElementId, optionComboId ) { - viewHistory( dataElementId, optionComboId, true ); -} - -function viewHistory( dataElementId, optionComboId, showComment ) -{ + var periodId = $( '#selectedPeriodId' ).val(); + window.open( 'viewHistory.action?dataElementId=' + dataElementId + '&optionComboId=' + optionComboId - + '&showComment=' + showComment, '_blank', 'width=580,height=710,scrollbars=yes' ); + + '&periodId=' + periodId + '&showComment=true', '_blank', 'width=580,height=710,scrollbars=yes' ); } function closeCurrentSelection() === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/history.js' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/history.js 2011-07-12 14:04:13 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/javascript/history.js 2011-07-20 21:38:30 +0000 @@ -11,16 +11,17 @@ { var commentValue = $( '#commentTextArea' ).val(); - var commentSaver = new CommentSaver( currentDataElementId, currentOptionComboId, currentOrganisationUnitId, commentValue ); + var commentSaver = new CommentSaver( currentDataElementId, currentOptionComboId, currentOrganisationUnitId, currentPeriodId, commentValue ); commentSaver.save(); } -function CommentSaver( dataElementId_, optionComboId_, organisationUnitId_, value_ ) +function CommentSaver( dataElementId_, optionComboId_, organisationUnitId_, periodId_, value_ ) { var dataElementId = dataElementId_; var optionComboId = optionComboId_; var organisationUnitId = organisationUnitId_; + var periodId = periodId_; var value = value_; this.save = function() @@ -28,7 +29,7 @@ markComment( COLOR_YELLOW ); var url = 'saveComment.action?organisationUnitId=' + organisationUnitId + '&dataElementId=' + - dataElementId + '&optionComboId=' + optionComboId + '&comment=' + value; + dataElementId + '&optionComboId=' + optionComboId + '&periodId=' + periodId + '&comment=' + value; $.ajax( { url: url, dataType: 'json', success: handleResponse, error: handleError } ); }; === modified file 'dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/select.vm' --- dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/select.vm 2011-07-18 10:22:08 +0000 +++ dhis-2/dhis-web/dhis-web-dataentry/src/main/webapp/dhis-web-dataentry/select.vm 2011-07-21 11:52:46 +0000 @@ -27,6 +27,17 @@ #foreach( $indicator in $indicators ) indicatorFormulas['${indicator.id}'] = '($!{indicator.explodedNumerator})/($!{indicator.explodedDenominator})*($!{indicator.indicatorType.factor})'; #end + +dataSets = { +#set( $size3 = $dataSets.size() ) +#foreach( $dataSet in $dataSets ) +"${dataSet.id}": { +"id":"${dataSet.id}", +"name":"$!encoder.jsonEncode( ${dataSet.name} )", +"periodType":"$!encoder.jsonEncode( ${dataSet.periodType.name} )" +}#if( $velocityCount < $size3 ),#end +#end }; +

$i18n.getString( "data_entry" ) #openHelp( "dataEntry" )

@@ -38,14 +49,9 @@
-

+

- -
- -
- -

+
@@ -58,8 +64,8 @@ - - +
+