/** * Copyright (c) 2015 Mustafa DUMLUPINAR, mdumlupinar@gmail.com * * This file is part of seyhan project. * * seyhan 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/>. */ package controllers.global; import static play.data.Form.form; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.persistence.OptimisticLockException; import meta.GridHeader; import meta.PageExtend; import models.GlobalCurrency; import models.GlobalCurrencyRate; import models.GlobalCurrencyRateDetail; import models.search.CurrencyRateSearchParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import play.data.Form; import play.data.validation.ValidationError; import play.i18n.Messages; import play.mvc.Controller; import play.mvc.Http; import play.mvc.Result; import utils.AuthManager; import utils.CacheUtils; import utils.DateUtils; import utils.GlobalCons; import utils.NumericUtils; import views.html.globals.currency_rate.form; import views.html.globals.currency_rate.list; import com.avaje.ebean.Ebean; import com.avaje.ebean.Page; import controllers.Application; import controllers.admin.Settings; import enums.Right; import enums.RightLevel; import enums.TransType; import external.TCMBExchanges; import external.model.TCMBRate; /** * @author mdpinar */ public class CurrencyRates extends Controller { private final static Right RIGHT_SCOPE = Right.GNEL_DOVIZ_KURLARI; private final static Logger log = LoggerFactory.getLogger(CurrencyRates.class); private final static Form<GlobalCurrencyRate> dataForm = form(GlobalCurrencyRate.class); private final static Form<CurrencyRateSearchParam> paramForm = form(CurrencyRateSearchParam.class); private static Map<String, GlobalCurrencyRateDetail> actualExchangeRatesMap; /** * Liste formu basliklarini doner * * @return List<GridHeader> */ private static List<GridHeader> getHeaderList() { List<GridHeader> headerList = new ArrayList<GridHeader>(); headerList.add(new GridHeader(Messages.get("date"), "7%", "center", "red").sortable("date")); headerList.add(new GridHeader(Messages.get("source"), true)); return headerList; } /** * Liste formunda gosterilecek verileri doner * * @return PageExtend */ private static PageExtend<GlobalCurrencyRate> buildPage(CurrencyRateSearchParam searchParam) { List<Map<Integer, String>> dataList = new ArrayList<Map<Integer, String>>(); Page<GlobalCurrencyRate> page = GlobalCurrencyRate.page(searchParam); List<GlobalCurrencyRate> modelList = page.getList(); if (modelList != null && modelList.size() > 0) { for (GlobalCurrencyRate model : modelList) { Map<Integer, String> dataMap = new HashMap<Integer, String>(); int i = -1; dataMap.put(i++, model.id.toString()); dataMap.put(i++, DateUtils.formatDateStandart(model.date)); dataMap.put(i++, model.source); dataList.add(dataMap); } } return new PageExtend<GlobalCurrencyRate>(getHeaderList(), dataList, page); } public static Result GO_HOME = redirect( controllers.global.routes.CurrencyRates.list() ); /** * Uzerinde veri bulunan liste formunu doner */ public static Result list() { Result hasProblem = AuthManager.hasProblem(RIGHT_SCOPE, RightLevel.Enable); if (hasProblem != null) return hasProblem; Form<CurrencyRateSearchParam> filledParamForm = paramForm.bindFromRequest(); return ok( list.render(buildPage(filledParamForm.get()), filledParamForm) ); } /** * Kayit formundaki bilgileri kaydeder */ public static Result save() { if (! CacheUtils.isLoggedIn()) return Application.login(); Form<GlobalCurrencyRate> filledForm = dataForm.bindFromRequest(); if(filledForm.hasErrors()) { return badRequest(form.render(filledForm)); } else { GlobalCurrencyRate model = filledForm.get(); Result hasProblem = AuthManager.hasProblem(RIGHT_SCOPE, (model.id == null ? RightLevel.Insert : RightLevel.Update)); if (hasProblem != null) return hasProblem; checkConstraints(filledForm); if(filledForm.hasErrors()) { return badRequest(form.render(filledForm)); } try { if (model.id == null) { model.save(); } else { model.update(); } } catch (OptimisticLockException e) { flash("error", Messages.get("exception.optimistic.lock")); return badRequest(form.render(dataForm.fill(model))); } actualExchangeRatesMap = null; flash("success", Messages.get("saved", model.date)); if (Profiles.chosen().gnel_continuouslyRecording) return create(); else return GO_HOME; } } /** * Yeni bir kayit formu olusturur */ public static Result create() { Result hasProblem = AuthManager.hasProblem(RIGHT_SCOPE, RightLevel.Insert); if (hasProblem != null) return hasProblem; GlobalCurrencyRate neu = GlobalCurrencyRate.findByDate(DateUtils.today()); if (neu == null) { neu = new GlobalCurrencyRate(); neu.init(); } return ok(form.render(dataForm.fill(neu))); } /** * Secilen kayit icin duzenleme formunu acar * * @param id */ public static Result edit(Integer id) { Result hasProblem = AuthManager.hasProblem(RIGHT_SCOPE, RightLevel.Enable); if (hasProblem != null) return hasProblem; if (id == null) { flash("error", Messages.get("id.is.null")); } else { GlobalCurrencyRate model = GlobalCurrencyRate.findById(id); if (model == null) { flash("error", Messages.get("not.found", Messages.get("exchange_rate"))); } else { return ok(form.render(dataForm.fill(model))); } } return GO_HOME; } /** * Duzenlemek icin acilmis olan kaydi siler * * @param id */ public static Result remove(Integer id) { Result hasProblem = AuthManager.hasProblem(RIGHT_SCOPE, RightLevel.Delete); if (hasProblem != null) return hasProblem; if (id == null) { flash("error", Messages.get("id.is.null")); } else { GlobalCurrencyRate model = GlobalCurrencyRate.findById(id); if (model == null) { flash("error", Messages.get("not.found", Messages.get("exchange_rate"))); } else { try { model.delete(); actualExchangeRatesMap = null; flash("success", Messages.get("deleted", model.date)); } catch (Exception pe) { log.error(pe.getMessage()); flash("error", Messages.get("delete.violation", model.date) + " " + pe.getMessage()); return badRequest(form.render(dataForm.fill(model))); } } } return GO_HOME; } /** * Kayit isleminden once form uzerinde bulunan verilerin uygunlugunu kontrol eder * * @param filledForm */ private static void checkConstraints(Form<GlobalCurrencyRate> filledForm) { GlobalCurrencyRate model = filledForm.get(); if (GlobalCurrencyRate.isUsedForElse("date", model.date, model.id)) { filledForm.reject("date", Messages.get("not.unique", model.date)); } if (model.details != null || model.details.size() > 0) { List<ValidationError> veList = new ArrayList<ValidationError>(); for (int i = 0; i < model.details.size(); i++) { GlobalCurrencyRateDetail detail = model.details.get(i); detail.currencyRate = model; detail.date = model.date; if (detail.buying == 0) { veList.add(new ValidationError("xmlDetail", Messages.get("table.zero.value.alert", i+1, Messages.get("buying")))); } if (detail.selling == 0) { veList.add(new ValidationError("xmlDetail", Messages.get("table.zero.value.alert", i+1, Messages.get("selling")))); } } if (veList.size() > 0) { filledForm.errors().put("xmlDetail", veList); } } else { filledForm.reject("xmlDetail", Messages.get("table.min.row.alert")); } } public static Map<String, GlobalCurrencyRateDetail> getActualExchangeRatesMap() { if (actualExchangeRatesMap == null) { GlobalCurrencyRate lastRate = GlobalCurrencyRate.getLastRate(); actualExchangeRatesMap = new HashMap<String, GlobalCurrencyRateDetail>(); Set<String> actCurSet = new HashSet<String>(); List<GlobalCurrency> actCurList = GlobalCurrency.getAll(); for (GlobalCurrency cur: actCurList) { actCurSet.add(cur.code); } if (lastRate != null) { for (GlobalCurrencyRateDetail crd : lastRate.details) { if (actCurSet.contains(crd.code)) { actualExchangeRatesMap.put(crd.code, new GlobalCurrencyRateDetail(crd.code, crd.buying, crd.selling)); } } actualExchangeRatesMap.put("info", new GlobalCurrencyRateDetail("info", DateUtils.formatReverseDate(lastRate.date) + " - " + lastRate.source)); actualExchangeRatesMap.put(Profiles.chosen().gnel_excCode, new GlobalCurrencyRateDetail(Profiles.chosen().gnel_excCode, 1d, 1d)); } else { actualExchangeRatesMap.put("info", new GlobalCurrencyRateDetail("info", Messages.get("not.found", Messages.get("actual_exchange_rates")))); } } return actualExchangeRatesMap; } public static double getExchangeRate(String code, TransType transType) { double result = 1d; if (getActualExchangeRatesMap() != null) { GlobalCurrencyRateDetail actualCRD = actualExchangeRatesMap.get(code); if (actualCRD != null) { if (transType.equals(TransType.Debt) || transType.equals(TransType.Input)) { result = actualCRD.buying; } else { result = actualCRD.selling; } } } return result; } public static Result pullTCMBExcange() { String result = getExchangeRates(true); if (Http.Context.current.get() != null) { if (result == null) { flash("success", Messages.get("pulled", Messages.get("pull.TCMB.exchange"))); log.info(Messages.get("pulled", Messages.get("pull.TCMB.exchange"))); } else { flash("error", result); log.error(result); } } return GO_HOME; } public static Result pullTCMBEffective() { String result = getExchangeRates(false); if (Http.Context.current.get() != null) { if (result == null) { flash("success", Messages.get("pulled", Messages.get("pull.TCMB.effective"))); log.info(Messages.get("pulled", Messages.get("pull.TCMB.effective"))); } else { flash("error", result); log.error(result); } } return GO_HOME; } private static String getExchangeRates(boolean isExchange) { String error = null; List<TCMBRate> rates = null; try { rates = TCMBExchanges.getRates(); } catch (Exception e) { error = e.getMessage(); log.error(error); return error; } if (rates != null && rates.size() > 0) { Ebean.beginTransaction(); try { GlobalCurrencyRate old = GlobalCurrencyRate.findByDate(rates.get(0).getDate()); if (old != null) old.delete(); GlobalCurrencyRate cr = new GlobalCurrencyRate(); cr.date = rates.get(0).getDate(); if (Http.Context.current.get() != null) { cr.source = "15:30:00 - " + Messages.get("pull.TCMB." + (isExchange ? "exchange" : "effective")); } else { cr.source = "15:30:00 - " + GlobalCons.getMessages().getString("pull.TCMB." + (isExchange ? "exchange" : "effective")); } cr.details = new ArrayList<GlobalCurrencyRateDetail>(); Map<String, GlobalCurrency> curMap = Currencies.getCurrencyMap(); for (int i = 0; i < rates.size(); i++) { TCMBRate rate = rates.get(i); GlobalCurrency cur = curMap.get(rate.getCode()); if (cur != null) { GlobalCurrencyRateDetail crd = new GlobalCurrencyRateDetail(cur.code, cur.name); crd.date = cr.date; if (isExchange) { crd.buying = new Double(rate.getExcBuying()); crd.selling = new Double(rate.getExcSelling()); } else { crd.buying = new Double(rate.getEffBuying()); crd.selling = new Double(rate.getEffSelling()); } if (Settings.getGlobal().exchangeDiffRateForBuying != null && Settings.getGlobal().exchangeDiffRateForBuying.doubleValue() != 0) { crd.buying = new Double(crd.buying + ((crd.buying * Settings.getGlobal().exchangeDiffRateForBuying) / 100)); } if (Settings.getGlobal().exchangeDiffRateForBuying != null && Settings.getGlobal().exchangeDiffRateForBuying.doubleValue() != 0) { crd.selling = new Double(crd.selling + ((crd.selling * Settings.getGlobal().exchangeDiffRateForSelling) / 100)); } crd.buying = NumericUtils.round(crd.buying, 4); crd.selling = NumericUtils.round(crd.selling, 4); cr.details.add(crd); } } cr.save(); Ebean.commitTransaction(); actualExchangeRatesMap = null; } catch (Exception e) { log.error(e.getMessage(), e); Ebean.rollbackTransaction(); } } return null; } }