package org.activityinfo.ui.client.page.entry; /* * #%L * ActivityInfo Server * %% * Copyright (C) 2009 - 2013 UNICEF * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import com.extjs.gxt.ui.client.data.BaseListLoader; import com.extjs.gxt.ui.client.data.ListLoader; import com.extjs.gxt.ui.client.data.RpcProxy; import com.extjs.gxt.ui.client.event.BaseEvent; import com.extjs.gxt.ui.client.event.Events; import com.extjs.gxt.ui.client.event.FieldEvent; import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.state.StateManager; import com.extjs.gxt.ui.client.store.GroupingStore; import com.extjs.gxt.ui.client.store.ListStore; import com.extjs.gxt.ui.client.store.Record; import com.extjs.gxt.ui.client.store.Store; import com.extjs.gxt.ui.client.util.DateWrapper; import com.extjs.gxt.ui.client.widget.ContentPanel; import com.extjs.gxt.ui.client.widget.layout.FitLayout; import com.extjs.gxt.ui.client.widget.toolbar.LabelToolItem; import com.google.common.base.Predicate; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.user.client.rpc.AsyncCallback; import org.activityinfo.i18n.shared.I18N; import org.activityinfo.legacy.client.Dispatcher; import org.activityinfo.legacy.client.monitor.MaskingAsyncMonitor; import org.activityinfo.legacy.shared.command.*; import org.activityinfo.legacy.shared.command.result.MonthlyReportResult; import org.activityinfo.legacy.shared.command.result.VoidResult; import org.activityinfo.legacy.shared.model.*; import org.activityinfo.ui.client.page.common.toolbar.ActionListener; import org.activityinfo.ui.client.page.common.toolbar.ActionToolBar; import org.activityinfo.ui.client.page.common.toolbar.UIActions; import org.activityinfo.ui.client.style.legacy.icon.IconImageBundle; import org.activityinfo.ui.client.widget.legacy.MappingComboBox; import java.util.ArrayList; public class MonthlyReportsPanel extends ContentPanel implements ActionListener { private final Dispatcher service; private ListLoader<MonthlyReportResult> loader; private ListStore<IndicatorRowDTO> store; private MonthlyGrid grid; private ReportingPeriodProxy proxy; private MappingComboBox<Month> monthCombo; private int currentSiteId; private ActivityFormDTO currentActivity; private ActionToolBar toolBar; private boolean readOnly; public MonthlyReportsPanel(Dispatcher service) { this.service = service; setHeadingText(I18N.CONSTANTS.monthlyReports()); setIcon(IconImageBundle.ICONS.table()); setLayout(new FitLayout()); proxy = new ReportingPeriodProxy(); loader = new BaseListLoader<MonthlyReportResult>(proxy); store = new GroupingStore<IndicatorRowDTO>(loader); store.setMonitorChanges(true); store.addListener(Store.Update, new Listener<BaseEvent>() { @Override public void handleEvent(BaseEvent be) { toolBar.setDirty(store.getModifiedRecords().size() != 0); } }); grid = new MonthlyGrid(store); add(grid); addToolBar(); } private void addToolBar() { toolBar = new ActionToolBar(); toolBar.setListener(this); toolBar.addSaveSplitButton(); toolBar.add(new LabelToolItem(I18N.CONSTANTS.month() + ": ")); monthCombo = new MappingComboBox<Month>(); monthCombo.setEditable(false); monthCombo.addListener(Events.Select, new Listener<FieldEvent>() { @Override public void handleEvent(FieldEvent be) { selectStartMonth(monthCombo.getMappedValue()); } }); DateWrapper today = new DateWrapper(); DateTimeFormat monthFormat = DateTimeFormat.getFormat("MMM yyyy"); for (int year = today.getFullYear(); year != today.getFullYear() - 3; --year) { for (int month = 12; month != 0; --month) { DateWrapper d = new DateWrapper(year, month, 1); Month m = new Month(year, month); monthCombo.add(m, monthFormat.format(d.asDate())); } } toolBar.add(monthCombo); toolBar.setDirty(false); setTopComponent(toolBar); } public void load(final SiteDTO site) { this.currentSiteId = site.getId(); this.grid.getStore().removeAll(); service.execute(new GetActivityForm(site.getActivityId()), new MaskingAsyncMonitor(this, I18N.CONSTANTS.loading()), new AsyncCallback<ActivityFormDTO>() { @Override public void onFailure(Throwable caught) { // caught by monitor } @Override public void onSuccess(ActivityFormDTO result) { currentActivity = result; populateGrid(site, currentActivity); } }); } private void populateGrid(SiteDTO site, ActivityFormDTO activity) { Month startMonth = getInitialStartMonth(site); monthCombo.setMappedValue(startMonth); grid.setLockedPredicate(createLockPredicate(new LockedPeriodSet(activity))); grid.updateMonthColumns(startMonth); proxy.setStartMonth(startMonth); proxy.setSiteId(site.getId()); loader.load(); } private Predicate<Month> createLockPredicate(final LockedPeriodSet lockedPeriodSet) { return new Predicate<Month>() { @Override public boolean apply(Month input) { DateWrapper date = new DateWrapper(input.getYear(), input.getMonth() - 1, 1).getLastDateOfMonth(); return lockedPeriodSet.isActivityLocked(currentActivity.getId(), date.asDate()); } }; } private void selectStartMonth(Month startMonth) { proxy.setStartMonth(startMonth); grid.updateMonthColumns(startMonth); loader.load(); } private Month getInitialStartMonth(SiteDTO site) { String stateKey = "monthlyView" + site.getActivityId() + "startMonth"; if (StateManager.get().getString(stateKey) != null) { try { return Month.parseMonth(StateManager.get().getString(stateKey)); } catch (NumberFormatException e) { } } DateWrapper today = new DateWrapper(); return new Month(today.getFullYear(), today.getMonth()); } @Override public void onUIAction(String actionId) { if (UIActions.SAVE.equals(actionId)) { save(); } else if (UIActions.DISCARD_CHANGES.equals(actionId)) { store.rejectChanges(); } } private void save() { ArrayList<UpdateMonthlyReports.Change> changes = new ArrayList<UpdateMonthlyReports.Change>(); for (Record record : store.getModifiedRecords()) { IndicatorRowDTO report = (IndicatorRowDTO) record.getModel(); for (String property : record.getChanges().keySet()) { UpdateMonthlyReports.Change change = new UpdateMonthlyReports.Change(); change.setIndicatorId(report.getIndicatorId()); change.setMonth(IndicatorRowDTO.monthForProperty(property)); change.setValue((Double) report.get(property)); changes.add(change); } } service.execute(new UpdateMonthlyReports(currentSiteId, changes), new MaskingAsyncMonitor(this, I18N.CONSTANTS.saving()), new AsyncCallback<VoidResult>() { @Override public void onFailure(Throwable caught) { // handled by monitor } @Override public void onSuccess(VoidResult result) { store.commitChanges(); } }); } public void setReadOnly(boolean readOnly) { this.readOnly = readOnly; this.grid.setReadOnly(readOnly); // this.toolBar.setActionEnabled(UIActions.SAVE, !readOnly); } public void onNoSelection() { this.grid.getStore().removeAll(); this.grid.getView().setEmptyText(I18N.MESSAGES.SelectSiteAbove()); } private class ReportingPeriodProxy extends RpcProxy<MonthlyReportResult> { private Month startMonth; private int siteId; public void setSiteId(int siteId) { this.siteId = siteId; } public void setStartMonth(Month startMonth) { this.startMonth = startMonth; } @Override protected void load(Object loadConfig, AsyncCallback<MonthlyReportResult> callback) { service.execute(new GetMonthlyReports(siteId, startMonth, 7), callback); } } }