/* * 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.currency; import com.google.web.bindery.event.shared.EventBus; import com.google.gwt.user.client.rpc.AsyncCallback; import javax.inject.Inject; import org.fourthline.konto.client.currency.event.MonetaryUnitModified; import org.fourthline.konto.client.currency.view.MonetaryUnitView; import org.seamless.gwt.notify.client.Message; import org.seamless.gwt.notify.client.ValidationErrorNotifyEvent; import org.seamless.gwt.notify.client.ServerFailureNotifyEvent; import org.seamless.gwt.notify.client.NotifyEvent; import org.fourthline.konto.client.service.CurrencyServiceAsync; import org.fourthline.konto.shared.entity.MonetaryUnit; import org.seamless.gwt.validation.shared.Validatable; import org.seamless.gwt.validation.shared.ValidationError; import org.seamless.gwt.validation.shared.ValidationException; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; /** * @author Christian Bauer */ public class MonetaryUnitPresenter implements MonetaryUnitView.Presenter { final MonetaryUnitView view; final EventBus bus; final CurrencyServiceAsync service; MonetaryUnit unit; @Inject public MonetaryUnitPresenter(MonetaryUnitView view, EventBus bus, CurrencyServiceAsync service) { this.view = view; this.bus = bus; this.service = service; } @Override public void startWith(MonetaryUnit unit) { this.unit = unit; view.setPresenter(this); view.reset(unit == null); if (unit != null) { view.getCodeProperty().set(unit.getCurrencyCode()); view.getFractionDigitsProperty().set(unit.getFractionDigits()); view.getPrefixProperty().set(unit.getPrefix()); } else { view.getFractionDigitsProperty().set(new MonetaryUnit().getFractionDigits()); } view.focus(); } @Override public void save() { clearValidationErrors(); // Client-side validation including view/model data binding List<ValidationError> errors = flushView(); if (errors.size() > 0) { bus.fireEvent(new NotifyEvent( new Message(Level.WARNING, "Can't save currency", "Please correct your input.") )); showValidationErrors(errors); return; } service.store(unit, new AsyncCallback<Void>() { @Override public void onFailure(Throwable caught) { if (caught instanceof ValidationException) { ValidationException ex = (ValidationException) caught; // This is probably a FK violation if (!ex.hasErrors()) { bus.fireEvent(new NotifyEvent( new Message( Level.WARNING, "Can't save currency, errors on server", ex.getMessage() ) )); } showValidationErrors(ex.getErrors()); } else { bus.fireEvent(new ServerFailureNotifyEvent(caught)); } } @Override public void onSuccess(Void result) { bus.fireEvent(new NotifyEvent( new Message( Level.INFO, "Currency saved", "Modifications have been stored." ) )); bus.fireEvent(new MonetaryUnitModified(unit)); } }); } @Override public void delete() { service.remove(unit, new AsyncCallback<Boolean>() { @Override public void onFailure(Throwable caught) { bus.fireEvent(new ServerFailureNotifyEvent(caught)); } @Override public void onSuccess(Boolean result) { if (!result) { bus.fireEvent(new NotifyEvent( new Message( Level.WARNING, "Currency '" + unit.getCurrencyCode() + "' removal failed", "First delete all accounts using this currency." ) )); } else { bus.fireEvent(new NotifyEvent( new Message( Level.INFO, "Currency deleted", "The currency has been permanently removed." ) )); bus.fireEvent(new MonetaryUnitModified(unit)); } } }); } @Override public void cancel() { bus.fireEvent(new MonetaryUnitModified(null)); } protected void clearValidationErrors() { view.getCodeProperty().clearValidationError(); view.getFractionDigitsProperty().clearValidationError(); view.getPrefixProperty().clearValidationError(); } protected void showValidationErrors(List<ValidationError> errors) { List<ValidationError> entityErrors = ValidationError.filterEntity(errors, MonetaryUnit.class.getName()); for (ValidationError error: entityErrors) { if (MonetaryUnit.Property.currencyCode.equals(error.getProperty())) view.getCodeProperty().showValidationError(error); else if (MonetaryUnit.Property.fractionDigits.equals(error.getProperty())) view.getFractionDigitsProperty().showValidationError(error); else if (MonetaryUnit.Property.prefix.equals(error.getProperty())) view.getPrefixProperty().showValidationError(error); else errors.add(error); } for (ValidationError error : errors) { bus.fireEvent(new ValidationErrorNotifyEvent(error)); } } protected List<ValidationError> flushView() { List<ValidationError> errors = new ArrayList(); if (unit == null) unit = new MonetaryUnit(); unit.setCurrencyCode(view.getCodeProperty().get()); Integer fractionDigits = view.getFractionDigitsProperty().get(); unit.setFractionDigits(fractionDigits == null ? -1 : fractionDigits); unit.setPrefix(view.getPrefixProperty().get()); errors.addAll(unit.validate(Validatable.GROUP_CLIENT)); return errors; } }