/* * Copyright (C) 2011 4th Line GmbH, Switzerland * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.fourthline.konto.client.ledger; import com.google.gwt.activity.shared.AbstractActivity; import com.google.web.bindery.event.shared.EventBus; import com.google.gwt.place.shared.Place; import com.google.gwt.place.shared.PlaceController; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.AcceptsOneWidget; import com.google.inject.Provider; import org.fourthline.konto.client.dashboard.DashboardPlace; import org.fourthline.konto.client.ledger.entry.event.EntryEditCanceled; import org.fourthline.konto.client.ledger.entry.event.EntryEditStarted; import org.fourthline.konto.client.ledger.entry.event.EntryModified; import org.fourthline.konto.client.ledger.entry.event.EntryRemoved; import org.fourthline.konto.client.ledger.entry.view.EntryView; import org.fourthline.konto.client.ledger.event.AccountSelectionModeChange; import org.fourthline.konto.client.ledger.view.LedgerView; import org.seamless.gwt.notify.client.Message; import org.seamless.gwt.notify.client.ServerFailureNotifyEvent; import org.seamless.gwt.notify.client.NotifyEvent; import org.fourthline.konto.client.service.LedgerServiceAsync; import org.fourthline.konto.client.settings.GlobalSettings; import org.fourthline.konto.client.settings.event.GlobalSettingsRefreshedEvent; import org.seamless.util.time.DateRange; import org.fourthline.konto.shared.LedgerCoordinates; import org.fourthline.konto.shared.LedgerEntry; import org.fourthline.konto.shared.entity.Entry; import org.fourthline.konto.shared.entity.settings.GlobalOption; import org.fourthline.konto.shared.query.LedgerLinesQueryCriteria; import org.fourthline.konto.shared.result.LedgerLine; import org.fourthline.konto.shared.result.LedgerLines; import javax.inject.Inject; import java.util.Date; import java.util.logging.Level; /** * @author Christian Bauer */ public class LedgerActivity extends AbstractActivity implements LedgerView.Presenter, GlobalSettingsRefreshedEvent.Handler, EntryEditStarted.Handler, EntryEditCanceled.Handler, EntryModified.Handler, EntryRemoved.Handler { final LedgerView view; final PlaceController placeController; final EventBus bus; final LedgerServiceAsync ledgerService; // Sub-presenter final Provider<EntryView.Presenter> entryPresenterProvider; EntryView.Presenter entryPresenter; LedgerCoordinates coordinates; LedgerLines lines; DateRange effectiveOnFilter; String descriptionFilter; @Inject public LedgerActivity(LedgerView view, Provider<EntryView.Presenter> entryPresenterProvider, PlaceController placeController, EventBus bus, LedgerServiceAsync ledgerService, GlobalSettings globalSettings) { this.view = view; this.entryPresenterProvider = entryPresenterProvider; this.placeController = placeController; this.bus = bus; this.ledgerService = ledgerService; onSettingsRefreshed(globalSettings); } public LedgerActivity init(LedgerPlace place) { this.coordinates = place.getLedgerCoordinates(); return this; } @Override public void start(AcceptsOneWidget containerWidget, com.google.gwt.event.shared.EventBus activityBus) { view.setPresenter(this); activityBus.addHandler(GlobalSettingsRefreshedEvent.TYPE, this); activityBus.addHandler(EntryEditStarted.TYPE, this); activityBus.addHandler(EntryEditCanceled.TYPE, this); activityBus.addHandler(EntryModified.TYPE, this); activityBus.addHandler(EntryRemoved.TYPE, this); bus.fireEvent(new AccountSelectionModeChange()); if (coordinates.getEntryId() != null) { loadLedgerLines(containerWidget, true, coordinates.getEntryId(), coordinates.getSplitId() ); } else { loadLedgerLines(containerWidget, true, null, null); } } @Override public void onStop() { super.onStop(); view.hideEntryEditContainer(); // Memorizing its size! if (entryPresenter != null) { entryPresenter.stop(); entryPresenter = null; } } @Override public void onSettingsRefreshed(GlobalSettings gs) { view.setDateFormat(gs.getValue(GlobalOption.OPT_DATE_FORMAT)); } @Override public void selectLine(LedgerLine line) { editEntry(line.getLedgerEntry()); } @Override public void addLine() { editEntry(null); } protected void editEntry(LedgerEntry ledgerEntry) { if (entryPresenter != null) { entryPresenter.stop(); } entryPresenter = entryPresenterProvider.get(); // If this was a filtered ledger view, we might not have loaded all the // splits of an entry, so load them now if necessary if (ledgerEntry != null && ledgerEntry instanceof Entry && descriptionFilter != null && descriptionFilter.length() > 0) { ledgerService.populateSplits((Entry) ledgerEntry, new AsyncCallback<Entry>() { @Override public void onFailure(Throwable caught) { bus.fireEvent(new ServerFailureNotifyEvent(caught)); } @Override public void onSuccess(Entry result) { entryPresenter.startWith(lines.getAccount(), result, getLastEntryDate()); } }); } else { entryPresenter.startWith(lines.getAccount(), ledgerEntry, getLastEntryDate()); } } @Override public void filterEffectiveOn(DateRange dateRange) { if ((effectiveOnFilter == null && dateRange != null) || (effectiveOnFilter != null && dateRange == null) || (effectiveOnFilter != null && !effectiveOnFilter.equals(dateRange))) { effectiveOnFilter = dateRange; loadLedgerLines(false); } else { effectiveOnFilter = dateRange; } } @Override public void filterDescription(String filter) { if ((descriptionFilter == null && filter != null) || (descriptionFilter != null && filter == null) || (descriptionFilter != null && !descriptionFilter.equals(filter))) { this.descriptionFilter = filter; loadLedgerLines(false); } else { descriptionFilter = filter; } } @Override public void onEntryModified(EntryModified event) { bus.fireEvent(new NotifyEvent( new Message("Entry saved", "Modifications have been stored in the ledger.") )); hideEntryEditContainer(); loadLedgerLines(true); } @Override public void onEntryRemoved(EntryRemoved event) { bus.fireEvent(new NotifyEvent( new Message("Entry removed", "The entry has been permanently removed from the ledger.") )); hideEntryEditContainer(); loadLedgerLines(true); } @Override public void onEntryEditStarted(EntryEditStarted event) { view.getEntryEditContainer().setWidget(null); view.getEntryEditContainer().setWidget(entryPresenter.getView().asWidget()); view.showEntryEditContainer(event.isLargeEdit(), event.isScrollBottom()); } @Override public void onEntryEditCanceled(EntryEditCanceled event) { entryPresenter.stop(); hideEntryEditContainer(); loadLedgerLines(true); } @Override public void goTo(Place place) { placeController.goTo(place); } protected void hideEntryEditContainer() { view.hideEntryEditContainer(); view.getEntryEditContainer().setWidget(null); } protected Date getLastEntryDate() { // Find the last entry line with a date not in the future if (lines == null || lines.size() == 0) return new Date(); long currentTime = new Date().getTime(); for (LedgerLine line : lines) { if (line.getDate().getTime() < currentTime) return line.getDate(); } return lines.get(0).getDate(); } protected void loadLedgerLines(final boolean init) { loadLedgerLines(null, init, null, null); } protected void loadLedgerLines(final AcceptsOneWidget container, final boolean init, final Long selectEntryId, final Long selectSplitId) { bus.fireEvent(new NotifyEvent( new Message( true, Level.INFO, "Loading entries of account", "Please wait..." ) )); ledgerService.getLedgerLines( new LedgerLinesQueryCriteria(descriptionFilter, true, coordinates.getAccountId(), effectiveOnFilter, selectEntryId), new AsyncCallback<LedgerLines>() { @Override public void onFailure(Throwable caught) { bus.fireEvent(new ServerFailureNotifyEvent(caught)); } @Override public void onSuccess(LedgerLines result) { bus.fireEvent(new NotifyEvent()); if (result != null) { if (container != null) container.setWidget(view.asWidget()); view.setLedgerLines(result, selectEntryId, selectSplitId); if (init) { LedgerActivity.this.lines = result; LedgerActivity.this.effectiveOnFilter = result.getEffectiveOn(); view.hideEntryEditContainer(); view.focus(); } } else { bus.fireEvent(new NotifyEvent( new Message( Level.WARNING, "Account or entry has been removed", "You have been redirected to the dashboard." ) )); placeController.goTo(new DashboardPlace()); } } } ); } }