/** * ============================================================================= * * ORCID (R) Open Source * http://orcid.org * * Copyright (c) 2012-2014 ORCID, Inc. * Licensed under an MIT-Style License (MIT) * http://orcid.org/open-source-license * * This copyright and license information (including a link to the full license) * shall be included in its entirety in all copies or substantial portion of * the software. * * ============================================================================= */ package org.orcid.core.cli; import java.math.BigDecimal; import java.text.NumberFormat; import java.text.ParsePosition; import java.util.Currency; import java.util.Locale; import java.util.List; import org.apache.commons.lang.StringUtils; import org.orcid.persistence.dao.ProfileFundingDao; import org.orcid.persistence.jpa.entities.ProfileEntity; import org.orcid.pojo.ajaxForm.PojoUtil; import org.orcid.persistence.jpa.entities.ProfileFundingEntity; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; /** * * @author Angel Montenegro * */ public class MigrateFundingAmountToANumericValue { private static final Logger LOGGER = LoggerFactory.getLogger(MigrateFundingAmountToANumericValue.class); private ProfileFundingDao profileFundingDao; private TransactionTemplate transactionTemplate; @SuppressWarnings("resource") private void init() { ApplicationContext context = new ClassPathXmlApplicationContext("orcid-core-context.xml"); profileFundingDao = (ProfileFundingDao) context.getBean("profileFundingDao"); transactionTemplate = (TransactionTemplate) context.getBean("transactionTemplate"); } public void execute() { transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { List<ProfileFundingEntity> allEntityesWithAmount = profileFundingDao.getProfileFundingWithAmount(); for(ProfileFundingEntity entity : allEntityesWithAmount) { //Amount filed was removed by card https://trello.com/c/WxbJLlCt/1884-remove-the-amount-field-from-the-profilefundingentity-since-we-now-use-the-bigdecimal-numericamount //String amount = entity.getAmount(); //So, lets leave this empty just in case we need a rollback later String amount = ""; String currencyCode = entity.getCurrencyCode(); ProfileEntity profile = entity.getProfile(); Locale locale = getLocaleFromProfile(profile); String fixedAmount = fixAmount(amount); try { BigDecimal bigDecimal = getAmountAsBigDecimal(fixedAmount, currencyCode, locale); LOGGER.info("FROM: " + amount + " TO: " + fixedAmount + " BigDecimal: " + bigDecimal); entity.setNumericAmount(bigDecimal); profileFundingDao.merge(entity); } catch (Exception e) { LOGGER.error("Exception migrating: " + entity.getProfile().getId() + ", " + amount + " = " + fixedAmount); } } } }); } private BigDecimal getAmountAsBigDecimal(String amount, String currencyCode, Locale locale) throws Exception { try { ParsePosition parsePosition = new ParsePosition(0); NumberFormat numberFormat = NumberFormat.getInstance(locale); Number number = null; if(!PojoUtil.isEmpty(currencyCode)) { Currency currency = Currency.getInstance(currencyCode); String currencySymbol = currency.getSymbol(); number = numberFormat.parse(amount.replace(currencySymbol, StringUtils.EMPTY), parsePosition); } else { number = numberFormat.parse(amount, parsePosition); } if(parsePosition.getIndex() != amount.length()) throw new Exception("Unable to parse amount into BigDecimal"); return new BigDecimal(number.toString()); } catch(Exception e) { throw e; } } private Locale getLocaleFromProfile(ProfileEntity profile){ org.orcid.jaxb.model.common_v2.Locale orcidLocale = profile.getLocale(); String value = orcidLocale.value(); Locale locale = null; if(value!= null) { if(value.contains("_")){ String [] localeTokens = value.split("_"); locale = new Locale(localeTokens[0], localeTokens[1]); } else { locale = new Locale(value); } } return locale; } public String fixAmount(String amount){ if(StringUtils.isNotBlank(amount)) { amount = amount.trim(); if(amount.contains("$")){ amount = amount.replace("$", StringUtils.EMPTY); } if (amount.contains("€")) { amount = amount.replace("€", StringUtils.EMPTY); } if (amount.contains(":")) { amount = amount.replace(":", "."); } if(amount.contains(" ")) { amount= amount.replaceAll("\\s", ""); } if(amount.matches(".*\\,(\\d{1,2})")) { amount = amount.replaceAll("\\,(\\d{1,2})", "\\.$1"); } if(amount.matches(".*\\.\\d{3}.*")) { amount = amount.replaceAll("\\.(\\d{3})", "\\,$1"); } } return amount; } public void finish() { LOGGER.info("PROCESS FINISHED"); System.exit(0); } public static void main(String[] args) { MigrateFundingAmountToANumericValue process = new MigrateFundingAmountToANumericValue(); process.init(); process.execute(); process.finish(); } }