private Map<String, Object> makeCall(String json, String method) throws PluggableTaskException { LOG.debug("Calling method: '%s', with JSON: %s", method, json); MultiValueMap<String, String> postParameters = new LinkedMultiValueMap<String, String>(); postParameters.add("rest_data", json); postParameters.add("input_type", "JSON"); postParameters.add("method", method); postParameters.add("response_type", "JSON"); RestTemplate restTemplate = new RestTemplate(); String resultString = restTemplate.postForObject( ENTRY_POINT, postParameters, String.class, getParameter(PARAM_SERVER.getName()), getParameter(PARAM_SUGARINSTANCE.getName())); LOG.debug("Result contents: %s", resultString); // Tried to use Spring MappingJacksonHttpMessageConverter, but // server sends text/html mime type. Using Jackson directly: ObjectMapper mapper = new ObjectMapper(); Map<String, Object> result = null; try { result = mapper.readValue(resultString, Map.class); } catch (IOException ioe) { throw new PluggableTaskException(ioe); } return result; }
@Override protected PaymentTask selectDelegate(PaymentDTOEx paymentInfo) throws PluggableTaskException { Integer userId = paymentInfo.getUserId(); String processorName = getProcessorName(userId); if (processorName == null) { return null; } Integer selectedTaskId; try { // it is a task parameter the id of the processor selectedTaskId = intValueOf(parameters.get(processorName)); } catch (NumberFormatException e) { throw new PluggableTaskException( "Invalid payment task id :" + processorName + " for userId: " + userId); } if (selectedTaskId == null) { LOG.warn("Could not find processor for " + parameters.get(processorName)); return null; } LOG.debug("Delegating to task id " + selectedTaskId); PaymentTask selectedTask = instantiateTask(selectedTaskId); return selectedTask; }
/** * Removes all customer prices for the plan's current set of plan items. This will remove prices * for subscribed customers AND orphaned prices where the customers order has been deleted in a * non-standard way (DB delete, non API usage). */ public void purgeCustomerPrices() { if (plan != null) { LOG.debug("Removing ALL remaining customer prices for plan %s", plan.getId()); new CustomerPriceBL().removeAllPrices(plan.getPlanItems()); } else { LOG.error("Cannot purge customer prices, PlanDTO not found or not set!"); } }
/** * Refreshes the customer plan item price mappings for all customers that have subscribed to this * plan. This method will remove all existing prices for the plan and insert the current list of * plan items into the customer price map. */ public void refreshCustomerPrices() { if (plan != null) { LOG.debug("Refreshing customer prices for subscribers to plan %s", plan.getId()); for (CustomerDTO customer : getCustomersByPlan(plan.getId())) { CustomerPriceBL bl = new CustomerPriceBL(customer); bl.removePrices(plan.getId()); bl.addPrices(plan.getPlanItems()); } } else { LOG.error("Cannot update customer prices, PlanDTO not found or not set!"); } }
/** * Creates a Suretax request from inputs from the invoice. * * @param invoice Invoice for which tax lines need to be calculated. * @return Returns instance of com.sapienter.jbilling.client.suretax.request.SuretaxRequest * @throws TaskException */ private SuretaxRequest getAssembledRequest(NewInvoiceContext invoice, Integer userId) throws TaskException { // Construct a suretax request to get the tax lines. SuretaxRequest suretaxRequest = new SuretaxRequest(); // Get the pluggable task parameters here. String clientNumber = getParameter(CLIENT_NUMBER, ""); String validationKey = getParameter(VALIDATION_KEY, ""); String responseGroup = getParameter(RESPONSE_GROUP, "03"); String responseType = getParameter(RESPONSE_TYPE, "D"); String numberOfDecimals = getParameter(NUMBER_OF_DECIMAL, "2"); Integer dataYear = null; Integer dataMonth = null; try { dataYear = getParameter(DATA_YEAR, Calendar.getInstance().get(Calendar.YEAR)); dataMonth = getParameter(DATA_MONTH, Calendar.getInstance().get(Calendar.MONTH) + 1); } catch (PluggableTaskException e) { LOG.debug("Exception while retrieving Data Year or Data Month"); } suretaxRequest.setClientNumber(clientNumber); suretaxRequest.setValidationKey(validationKey); String uniqueTrackingCode = System.currentTimeMillis() + ""; suretaxRequest.setClientTracking(uniqueTrackingCode); suretaxRequest.setDataMonth(dataMonth.toString()); suretaxRequest.setDataYear(dataYear.toString()); suretaxRequest.setIndustryExemption(""); suretaxRequest.setBusinessUnit(""); suretaxRequest.setResponseGroup(responseGroup); suretaxRequest.setResponseType(responseType + numberOfDecimals); suretaxRequest.setReturnFileCode("0"); suretaxRequest.setTotalRevenue(getTotalRevenue(invoice).floatValue()); List<LineItem> itemList = new ArrayList<LineItem>(); for (InvoiceLineDTO invoiceLine : (List<InvoiceLineDTO>) invoice.getResultLines()) { if (invoiceLine.getInvoiceLineType().getId() != ServerConstants.INVOICE_LINE_TYPE_TAX.intValue()) { LOG.debug("Populating itemlist for invoice line: %s", invoiceLine); itemList.add( getLineItem(invoiceLine.getItem().getId(), invoiceLine, uniqueTrackingCode, userId)); } } suretaxRequest.setItemList(itemList); return suretaxRequest; }
// use it when you need only currency objects public List<CurrencyDTO> getCurrenciesWithoutRates( Integer languageId, Integer entityId, boolean inUseOnly) throws NamingException, SQLException { String cacheKey = "without rates " + getCacheKey(languageId, entityId, new Date()); List<CurrencyDTO> cachedCurrencies = (List<CurrencyDTO>) cache.getFromCache(cacheKey, cacheModel); if (cachedCurrencies != null && !cachedCurrencies.isEmpty()) { LOG.debug("Cache hit for %s", cacheKey); return cachedCurrencies; } List<CurrencyDTO> currencies = new CurrencyDAS().findAll(); boolean inUse; for (CurrencyDTO currency : currencies) { set(currency.getId()); inUse = entityHasCurrency(entityId, currency.getId()); if (inUseOnly && !inUse) continue; currency.setInUse(inUse); currency.setName(this.currency.getDescription(languageId)); // find system rate if (currency.getId() == SYSTEM_CURRENCY_ID.intValue()) { currency.setSysRate(SYSTEM_CURRENCY_RATE_DEFAULT); } } cache.putInCache(cacheKey, cacheModel, currencies); return currencies; }
public Integer create(CurrencyDTO dto, Integer entityId) { if (dto != null) { /* Simplify currency creation; Set exchange rates from transient CurrencyDTO#getRate() and CurrencyDTO#getSysRate() if no currency exchanges have been mapped. */ if (dto.getCurrencyExchanges().isEmpty()) { // set system rate CurrencyExchangeDTO sysRate = new CurrencyExchangeDTO(); sysRate.setEntityId(SYSTEM_RATE_ENTITY_ID); sysRate.setRate(dto.getSysRate() != null ? dto.getSysRate() : BigDecimal.ONE); sysRate.setValidSince( com.sapienter.jbilling.common.Util.truncateDate(CommonConstants.EPOCH_DATE)); sysRate.setCurrency(dto); dto.getCurrencyExchanges().add(sysRate); } this.currency = currencyDas.save(dto); // add active currencies to the company map if (dto.getInUse()) { CompanyDTO company = new CompanyDAS().find(entityId); company.getCurrencies().add(this.currency); } invalidateCache(); return this.currency.getId(); } LOG.error("Cannot save a null CurrencyDTO!"); return null; }
/** * Returns a list of all active and finished one-time orders going back n number of months, for * all direct immediate of the given parent user id. This is useful for determining usage across * all child users. * * @param parentUserId parent user id * @param itemId item id of order lines * @param months previous number of months to include (1 = 1 month period starting from today) * @return list of found one-time orders, empty list if none found */ @SuppressWarnings("unchecked") public List<OrderLineDTO> findOnetimeByParentUserItem( Integer parentUserId, Integer itemId, Integer months) { UserDTO parent = new UserBL(parentUserId).getEntity(); if (parent == null || parent.getCustomer() == null) { LOG.warn("Parent user %s does not exist or is not a customer!", parentUserId); return Collections.emptyList(); } final String hql = "select line " + " from OrderLineDTO line " + " where line.deleted = 0 " + " and line.item.id = :itemId " + " and line.purchaseOrder.baseUserByUserId.customer.parent.id = :parentId" + " and line.purchaseOrder.orderPeriod.id = :period " + " and (line.purchaseOrder.orderStatus.orderStatusFlag = :active_status" + " or line.purchaseOrder.orderStatus.orderStatusFlag = :finished_status)" + " and line.purchaseOrder.deleted = 0 " + " and line.purchaseOrder.createDate > :startdate "; Query query = getSession().createQuery(hql); query.setParameter("itemId", itemId); query.setParameter("parentId", parent.getCustomer().getId()); query.setParameter("period", ServerConstants.ORDER_PERIOD_ONCE); query.setParameter("active_status", OrderStatusFlag.INVOICE.ordinal()); query.setParameter("finished_status", OrderStatusFlag.FINISHED); DateMidnight startdate = new DateMidnight().minusMonths(months); query.setParameter("startdate", startdate.toDate()); return query.list(); }
/** * Un-subscribes a customer from all plans held by the given "plan subscription" item, removing * all plan item prices from the customer price map. * * @param userId user id of the customer to un-subscribe * @param itemId item representing the subscription to a plan */ public static void unsubscribe(Integer userId, Integer itemId) { LOG.debug("Un-subscribing customer %s from plan subscription item %s", userId, itemId); CustomerPriceBL customerPriceBl = new CustomerPriceBL(userId); for (PlanDTO plan : new PlanBL().getPlansBySubscriptionItem(itemId)) customerPriceBl.removePrices(plan.getId()); }
public void update(CurrencyDTO dto, Integer entityId) { if (currency != null) { currency.setSymbol(dto.getSymbol()); currency.setCode(dto.getCode()); currency.setCountryCode(dto.getCountryCode()); // set system rate if (dto.getSysRate() != null) { final CurrencyExchangeDTO systemExchangeRate = findExchange(SYSTEM_RATE_ENTITY_ID, currency.getId(), new Date()); systemExchangeRate.setRate(dto.getSysRate()); } // add active currencies to the company map CompanyDTO company = new CompanyDAS().find(entityId); if (dto.getInUse()) { company.getCurrencies().add(currency); } else { company.getCurrencies().remove(currency); } invalidateCache(); ; } else { LOG.error("Cannot update, CurrencyDTO not found or not set!"); } }
private String login() throws PluggableTaskException { String json = "{" + " \"user_auth\": {" + " \"user_name\": \"" + getParameter(PARAM_USER_NAME.getName()) + "\", " + " \"password\": \"" + getParameter(PARAM_PASSWORD.getName()) + "\", " + " \"encryption\": \"PLAIN\" " + " }, " + " \"application_name\": \"JBilling\"," + " \"name_value_list\": null " + "}"; Map<String, Object> result = makeCall(json, "login"); if (result.get("id") == null) { String message = "No session id. Error calling SugarCRM: " + result.get("description"); LOG.error(message); throw new PluggableTaskException(message); } return result.get("id").toString(); }
private String getProcessorName(Integer userId) throws PluggableTaskException { ContactBL contactLoader; String processorName = null; contactLoader = new ContactBL(); contactLoader.set(userId); UserDTO user = new UserDAS().find(userId); if (user.getCustomer() != null && user.getCustomer().getMetaFields() != null) { String metaFieldName = parameters.get(PARAM_CUSTOM_FIELD_PAYMENT_PROCESSOR.getName()); MetaFieldValue customField = user.getCustomer().getMetaField(metaFieldName); if (customField == null) { // todo: try to search by id, may be temporary (now is applied) try { Integer metaFieldNameId = Integer.valueOf(metaFieldName); customField = user.getCustomer().getMetaField(metaFieldNameId); } catch (Exception ex) { // do nothing } } if (customField == null) { LOG.warn( "Can't find Custom Field with type " + parameters.get(PARAM_CUSTOM_FIELD_PAYMENT_PROCESSOR.getName()) + " user = " + userId); processorName = null; } else { processorName = (String) customField.getValue(); } } return processorName; }
public void addPrice(PlanItemDTO planItem) { if (plan != null) { PriceModelBL.validateAttributes(planItem.getModels().values()); plan.addPlanItem(planItem); LOG.debug("Saving updates to plan %s", plan.getId()); this.plan = planDas.save(plan); refreshCustomerPrices(); // trigger internal event EventManager.process(new PlanUpdatedEvent(plan)); } else { LOG.error("Cannot add price, PlanDTO not found or not set!"); } }
private String getParameter(String name) throws PluggableTaskException { String value = parameters.get(name); if (value == null || value.equals("")) { String message = "Parameter '" + name + "' required"; LOG.error(message); throw new PluggableTaskException(message); } return value; }
/** * Called for every object that was skipped. Increments total users failed value in context and * adds user id to failed user list in context. */ @Override public void onSkipInProcess(Object obj, Throwable th) { Integer userId = (Integer) obj; Integer billingProcessId = this.getIntegerFromContext(Constants.JOBCONTEXT_BILLING_PROCESS_ID_KEY); logger.debug( "BillingProcessId # " + billingProcessId + " || UserId # " + userId + " +++ Entering onSkipProcess()"); logger.info( "BillingProcessId # " + billingProcessId + " || UserId # " + userId + " +++ Skipped due to Exception # " + th); Integer failed = this.getIntegerFromContext(Constants.JOBCONTEXT_TOTAL_USERS_FAILED_KEY); this.addIntegerToContext(Constants.JOBCONTEXT_TOTAL_USERS_FAILED_KEY, failed + 1); List<Integer> list = this.getIntegerListFromContext(Constants.JOBCONTEXT_FAILED_USERS_LIST_KEY); synchronized (list) { list.add(userId); logger.debug( "BillingProcessId # " + billingProcessId + " || UserId # " + userId + " +++ Failed users list size # " + list.size()); this.addIntegerListToContext(Constants.JOBCONTEXT_FAILED_USERS_LIST_KEY, list); } local.addProcessRunUser(billingProcessId, userId, ProcessRunUserDTO.STATUS_FAILED); logger.debug( "BillingProcessId # " + billingProcessId + " || UserId # " + userId + " +++ Leaving onSkipProcess()"); }
/** * Subscribes a customer to this plan, adding all plan item prices to the customer price map. * * @param userId user id of the customer to subscribe * @return list of saved customer price entries, empty if no prices applied to customer. */ public List<CustomerPriceDTO> subscribe(Integer userId) { LOG.debug("Subscribing customer %s to plan %s", userId, plan.getId()); List<CustomerPriceDTO> saved = new ArrayList<CustomerPriceDTO>(); CustomerPriceBL customerPriceBl = new CustomerPriceBL(userId); saved.addAll(customerPriceBl.addPrices(plan.getPlanItems())); return saved; }
public void delete() { if (plan != null) { purgeCustomerPrices(); planDas.delete(plan); // trigger internal event EventManager.process(new PlanDeletedEvent(plan)); } else { LOG.error("Cannot delete, PlanDTO not found or not set!"); } }
/** * Subscribes a customer to all plans held by the given "plan subscription" item, adding all plan * item prices to a customer price map. * * @param userId user id of the customer to subscribe * @param itemId item representing the subscription to a plan * @return list of saved customer price entries, empty if no prices applied to customer. */ public static List<CustomerPriceDTO> subscribe(Integer userId, Integer itemId) { LOG.debug("Subscribing customer %s to plan subscription item %s", userId, itemId); List<CustomerPriceDTO> saved = new ArrayList<CustomerPriceDTO>(); CustomerPriceBL customerPriceBl = new CustomerPriceBL(userId); for (PlanDTO plan : new PlanBL().getPlansBySubscriptionItem(itemId)) saved.addAll(customerPriceBl.addPrices(plan.getPlanItems())); return saved; }
/** * restarts a failed job * * @param billingProcessId : id of the failed billing process * @param entityId : id of the entity to which billing process belongs * @return : true - if restart was successful */ public boolean restartFailedJobByBillingProcessId( Integer billingProcessId, final Integer entityId) { logger.debug("Entering restartFailedJobByBillingProcessId() with id # " + billingProcessId); final Date jobRunDate = this.getDateFromJbParametersByExecutionId( this.getExecutionIdByBillingProcessId(billingProcessId)); if (jobRunDate != null) { Thread restartThread = new Thread() { @Override public void run() { getProcessBean().trigger(jobRunDate, entityId); } }; restartThread.start(); return true; } logger.debug("Job Restart was successful...job running in background"); return false; }
@Override protected PaymentTask selectDelegate(PaymentDTOEx paymentInfo) throws PluggableTaskException { String currencyCode = paymentInfo.getCurrency().getCode(); Integer selectedTaskId = null; try { // try to get the task id for this currency selectedTaskId = intValueOf(parameters.get(currencyCode)); } catch (NumberFormatException e) { throw new PluggableTaskException("Invalid task id for currency " + "code: " + currencyCode); } if (selectedTaskId == null) { LOG.warn("Could not find processor for " + parameters.get(currencyCode)); return null; } LOG.debug("Delegating to task id " + selectedTaskId); PaymentTask selectedTask = instantiateTask(selectedTaskId); return selectedTask; }
public void trigger() throws SessionInternalError { LOG.debug("calling ProvisioningProcessSessionBean trigger() method"); try { ProvisioningProcessBL processBL = new ProvisioningProcessBL(); processBL.activateOrders(); processBL.deActivateOrders(); } catch (Exception e) { throw new SessionInternalError(e); } }
public boolean delete() { if (currency != null && currency.isDeletable()) { currency.getEntities_1().clear(); currencyDas.delete(currency); invalidateCache(); return true; } else { LOG.error("Cannot delete, CurrencyDTO not found or not deletable!"); } return false; }
/** * Here we will have the initial credentials for a user be created * * @param user */ @Override public void createPassword(UserDTO user) { ResetPasswordCodeDAS resetCodeDAS = new ResetPasswordCodeDAS(); ResetPasswordCodeDTO resetCode = new ResetPasswordCodeDTO(); resetCode.setUser(user); resetCode.setDateCreated(new Date()); resetCode.setToken(RandomStringUtils.random(32, true, true)); resetCodeDAS.save(resetCode); try { new UserBL() .sendCredentials( user.getCompany().getId(), user.getId(), 1, generateLink(resetCode.getToken())); } catch (SessionInternalError e) { LOG.error(e.getMessage(), e); throw new SessionInternalError("Exception while sending notification : " + e.getMessage()); } catch (NotificationNotFoundException e) { LOG.error(e.getMessage(), e); throw new SessionInternalError("createCredentials.notification.not.found"); } }
@Override public void process(Event event) { if (false == event instanceof AbstractPaymentEvent) { return; } // the alarm does not care about entered payments. Filter them out if (event instanceof PaymentSuccessfulEvent) { PaymentSuccessfulEvent success = (PaymentSuccessfulEvent) event; if (new Integer(success.getPayment().getPaymentResult().getId()) .equals(Constants.RESULT_ENTERED)) { return; } } AbstractPaymentEvent paymentEvent = (AbstractPaymentEvent) event; ProcessorAlarm alarm = getPluggableTask(event.getEntityId(), Constants.PLUGGABLE_TASK_PROCESSOR_ALARM); if (alarm == null) { // it is OK not to have an alarm configured LOG.info("Alarm not present for entity " + event.getEntityId()); return; } String paymentProcessor = paymentEvent.getPaymentProcessor(); if (paymentProcessor == null) { LOG.warn("Payment event without payment processor id : " + event); return; } alarm.init(paymentProcessor, event.getEntityId()); if (event instanceof PaymentFailedEvent) { alarm.fail(); } else if (event instanceof PaymentProcessorUnavailableEvent) { alarm.unavailable(); } else if (event instanceof PaymentSuccessfulEvent) { alarm.successful(); } }
/** * Converts all currencies to Pivot currency i.e. 1 * * @param currencyId * @param amount * @param toDate * @param entityId * @return * @throws SessionInternalError */ private BigDecimal convertToPivot( Integer currencyId, BigDecimal amount, Date toDate, Integer entityId) throws SessionInternalError { if (currencyId.equals(SYSTEM_CURRENCY_ID)) { LOG.debug("this currency is already in the pivot"); return amount; } // make the conversion itself CurrencyExchangeDTO exchange = findExchange(entityId, currencyId, toDate); return amount.divide( exchange.getRate(), Constants.BIGDECIMAL_SCALE, Constants.BIGDECIMAL_ROUND); }
public void update(PlanDTO dto) { if (plan != null) { // un-subscribe existing customers before updating List<CustomerDTO> subscribers = getCustomersByPlan(plan.getId()); for (CustomerDTO customer : subscribers) { unsubscribe(customer.getBaseUser().getUserId()); } // clean all remaining prices just-in-case there's an orphaned record if (plan.getPlanItems().size() > 0) { purgeCustomerPrices(); } // do update validateAttributes(dto); plan.setDescription(dto.getDescription()); plan.setItem(dto.getItem()); plan.setPeriod(dto.getPeriod()); plan.getPlanItems().clear(); plan.getPlanItems().addAll(dto.getPlanItems()); LOG.debug("Saving updates to plan %s", plan.getId()); this.plan = planDas.save(plan); // re-subscribe customers after plan has been saved for (CustomerDTO customer : subscribers) { subscribe(customer.getBaseUser().getUserId()); } // trigger internal event EventManager.process(new PlanUpdatedEvent(plan)); } else { LOG.error("Cannot update, PlanDTO not found or not set!"); } }
private CurrencyExchangeDTO findExchange(Integer entityId, Integer currencyId, Date toDate) throws SessionInternalError { // check for system currency exchange if (SYSTEM_CURRENCY_ID.equals(currencyId)) { return new CurrencyExchangeDTO( 0, currency, entityId, SYSTEM_CURRENCY_RATE_DEFAULT, new Date()); } LOG.debug("Get exchange rate for %s for entity %s for date %s", currencyId, entityId, toDate); CurrencyExchangeDTO exchange = exchangeDas.getExchangeRateForDate(entityId, currencyId, toDate); if (exchange == null) { // this entity doesn't have this exchange defined // 0 is the default, don't try to use null, it won't work exchange = exchangeDas.findExchange(SYSTEM_RATE_ENTITY_ID, currencyId); if (exchange == null) { throw new SessionInternalError( "Currency " + currencyId + " doesn't have a default exchange"); } } LOG.debug("Exchange found %s", exchange.getId()); return exchange; }
public Integer create(PlanDTO plan) { if (plan != null) { validateAttributes(plan); this.plan = planDas.save(plan); // trigger internal event EventManager.process(new NewPlanEvent(plan)); return this.plan.getId(); } LOG.error("Cannot save a null PlanDTO!"); return null; }
public boolean process(PaymentDTOEx paymentInfo) throws PluggableTaskException { FormatLogger log = new FormatLogger(Logger.getLogger(PaymentEmailAuthorizeNetTask.class)); boolean retValue = super.process(paymentInfo); String address = (String) parameters.get(PARAMETER_EMAIL_ADDRESS.getName()); try { UserBL user = new UserBL(paymentInfo.getUserId()); String message; if (new Integer(paymentInfo.getPaymentResult().getId()).equals(Constants.RESULT_OK)) { message = "payment.success"; } else { message = "payment.fail"; } String params[] = new String[6]; params[0] = paymentInfo.getUserId().toString(); params[1] = user.getEntity().getUserName(); params[2] = paymentInfo.getId() + ""; params[3] = paymentInfo.getAmount().toString(); if (paymentInfo.getAuthorization() != null) { params[4] = paymentInfo.getAuthorization().getTransactionId(); params[5] = paymentInfo.getAuthorization().getApprovalCode(); } else { params[4] = "Not available"; params[5] = "Not available"; } log.debug( "Bkp 6 " + params[0] + " " + params[1] + " " + params[2] + " " + params[3] + " " + params[4] + " " + params[5] + " "); NotificationBL.sendSapienterEmail( address, user.getEntity().getEntity().getId(), message, null, params); } catch (Exception e) { log.warn("Cant send receit email"); } return retValue; }
/* Currency conversion */ public BigDecimal convert( Integer fromCurrencyId, Integer toCurrencyId, BigDecimal amount, Date toDate, Integer entityId) throws SessionInternalError { LOG.debug( "Converting %s to %s , amount %s ,entity %s", fromCurrencyId, toCurrencyId, amount, entityId); if (fromCurrencyId.equals(toCurrencyId)) { return amount; // mmm.. no conversion needed } if (amount.compareTo(BigDecimal.ZERO) == 0) { return BigDecimal.ZERO; // mmm.. conversion doth not make sense } // make the conversions final BigDecimal pivotAmount = convertToPivot(fromCurrencyId, amount, toDate, entityId); LOG.debug("Pivot Amount %s", pivotAmount); return convertPivotToCurrency(toCurrencyId, pivotAmount, toDate, entityId); }