| //Licensed to the Apache Software Foundation (ASF) under one |
| //or more contributor license agreements. See the NOTICE file |
| //distributed with this work for additional information |
| //regarding copyright ownership. The ASF licenses this file |
| //to you under the Apache License, Version 2.0 (the |
| //"License"); you may not use this file except in compliance |
| //with the License. You may obtain a copy of the License at |
| // |
| //http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| //Unless required by applicable law or agreed to in writing, |
| //software distributed under the License is distributed on an |
| //"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| //KIND, either express or implied. See the License for the |
| //specific language governing permissions and limitations |
| //under the License. |
| package org.apache.cloudstack.api.response; |
| |
| import java.math.BigDecimal; |
| import java.math.RoundingMode; |
| import java.time.LocalDate; |
| import java.time.ZoneId; |
| import java.util.ArrayList; |
| import java.util.Calendar; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.ListIterator; |
| |
| import javax.inject.Inject; |
| |
| import org.apache.cloudstack.api.command.QuotaBalanceCmd; |
| import org.apache.cloudstack.api.command.QuotaEmailTemplateListCmd; |
| import org.apache.cloudstack.api.command.QuotaEmailTemplateUpdateCmd; |
| import org.apache.cloudstack.api.command.QuotaStatementCmd; |
| import org.apache.cloudstack.api.command.QuotaTariffListCmd; |
| import org.apache.cloudstack.api.command.QuotaTariffUpdateCmd; |
| import org.apache.cloudstack.quota.QuotaManager; |
| import org.apache.cloudstack.quota.QuotaService; |
| import org.apache.cloudstack.quota.QuotaStatement; |
| import org.apache.cloudstack.quota.constant.QuotaConfig; |
| import org.apache.cloudstack.quota.constant.QuotaTypes; |
| import org.apache.cloudstack.quota.dao.QuotaAccountDao; |
| import org.apache.cloudstack.quota.dao.QuotaBalanceDao; |
| import org.apache.cloudstack.quota.dao.QuotaCreditsDao; |
| import org.apache.cloudstack.quota.dao.QuotaEmailTemplatesDao; |
| import org.apache.cloudstack.quota.dao.QuotaTariffDao; |
| import org.apache.cloudstack.quota.dao.QuotaUsageDao; |
| import org.apache.cloudstack.quota.vo.QuotaAccountVO; |
| import org.apache.cloudstack.quota.vo.QuotaBalanceVO; |
| import org.apache.cloudstack.quota.vo.QuotaCreditsVO; |
| import org.apache.cloudstack.quota.vo.QuotaEmailTemplatesVO; |
| import org.apache.cloudstack.quota.vo.QuotaTariffVO; |
| import org.apache.cloudstack.quota.vo.QuotaUsageVO; |
| import org.apache.commons.lang.StringEscapeUtils; |
| import org.apache.log4j.Logger; |
| import org.springframework.stereotype.Component; |
| |
| import com.cloud.domain.DomainVO; |
| import com.cloud.domain.dao.DomainDao; |
| import com.cloud.exception.InvalidParameterValueException; |
| import com.cloud.user.Account; |
| import com.cloud.user.AccountManager; |
| import com.cloud.user.AccountVO; |
| import com.cloud.user.User; |
| import com.cloud.user.dao.AccountDao; |
| import com.cloud.user.dao.UserDao; |
| |
| @Component |
| public class QuotaResponseBuilderImpl implements QuotaResponseBuilder { |
| private static final Logger s_logger = Logger.getLogger(QuotaResponseBuilderImpl.class); |
| |
| @Inject |
| private QuotaTariffDao _quotaTariffDao; |
| @Inject |
| private QuotaBalanceDao _quotaBalanceDao; |
| @Inject |
| private QuotaCreditsDao _quotaCreditsDao; |
| @Inject |
| private QuotaUsageDao _quotaUsageDao; |
| @Inject |
| private QuotaEmailTemplatesDao _quotaEmailTemplateDao; |
| |
| @Inject |
| private UserDao _userDao; |
| @Inject |
| private QuotaService _quotaService; |
| @Inject |
| private AccountDao _accountDao; |
| @Inject |
| private QuotaAccountDao _quotaAccountDao; |
| @Inject |
| private DomainDao _domainDao; |
| @Inject |
| private AccountManager _accountMgr; |
| @Inject |
| private QuotaStatement _statement; |
| @Inject |
| private QuotaManager _quotaManager; |
| |
| @Override |
| public QuotaTariffResponse createQuotaTariffResponse(QuotaTariffVO tariff) { |
| final QuotaTariffResponse response = new QuotaTariffResponse(); |
| response.setUsageType(tariff.getUsageType()); |
| response.setUsageName(tariff.getUsageName()); |
| response.setUsageUnit(tariff.getUsageUnit()); |
| response.setUsageDiscriminator(tariff.getUsageDiscriminator()); |
| response.setTariffValue(tariff.getCurrencyValue()); |
| response.setEffectiveOn(tariff.getEffectiveOn()); |
| response.setDescription(tariff.getDescription()); |
| response.setCurrency(QuotaConfig.QuotaCurrencySymbol.value()); |
| return response; |
| } |
| |
| @Override |
| public List<QuotaSummaryResponse> createQuotaSummaryResponse(final String accountName, final Long domainId) { |
| List<QuotaSummaryResponse> result = new ArrayList<QuotaSummaryResponse>(); |
| |
| if (accountName != null && domainId != null) { |
| Account account = _accountDao.findActiveAccount(accountName, domainId); |
| QuotaSummaryResponse qr = getQuotaSummaryResponse(account); |
| result.add(qr); |
| } |
| |
| return result; |
| } |
| |
| @Override |
| public List<QuotaSummaryResponse> createQuotaSummaryResponse(Boolean listAll) { |
| List<QuotaSummaryResponse> result = new ArrayList<QuotaSummaryResponse>(); |
| |
| if (listAll) { |
| for (final AccountVO account : _accountDao.listAll()) { |
| QuotaSummaryResponse qr = getQuotaSummaryResponse(account); |
| result.add(qr); |
| } |
| } else { |
| for (final QuotaAccountVO quotaAccount : _quotaAccountDao.listAllQuotaAccount()) { |
| AccountVO account = _accountDao.findById(quotaAccount.getId()); |
| if (account == null) { |
| continue; |
| } |
| QuotaSummaryResponse qr = getQuotaSummaryResponse(account); |
| result.add(qr); |
| } |
| } |
| return result; |
| } |
| |
| private QuotaSummaryResponse getQuotaSummaryResponse(final Account account) { |
| Calendar[] period = _statement.getCurrentStatementTime(); |
| |
| if (account != null) { |
| QuotaSummaryResponse qr = new QuotaSummaryResponse(); |
| DomainVO domain = _domainDao.findById(account.getDomainId()); |
| BigDecimal curBalance = _quotaBalanceDao.lastQuotaBalance(account.getAccountId(), account.getDomainId(), period[1].getTime()); |
| BigDecimal quotaUsage = _quotaUsageDao.findTotalQuotaUsage(account.getAccountId(), account.getDomainId(), null, period[0].getTime(), period[1].getTime()); |
| |
| qr.setAccountId(account.getAccountId()); |
| qr.setAccountName(account.getAccountName()); |
| qr.setDomainId(account.getDomainId()); |
| qr.setDomainName(domain.getName()); |
| qr.setBalance(curBalance); |
| qr.setQuotaUsage(quotaUsage); |
| qr.setState(account.getState()); |
| qr.setStartDate(period[0].getTime()); |
| qr.setEndDate(period[1].getTime()); |
| qr.setCurrency(QuotaConfig.QuotaCurrencySymbol.value()); |
| qr.setObjectName("summary"); |
| return qr; |
| } else { |
| return new QuotaSummaryResponse(); |
| } |
| } |
| |
| @Override |
| public QuotaBalanceResponse createQuotaBalanceResponse(List<QuotaBalanceVO> quotaBalance, Date startDate, Date endDate) { |
| if (quotaBalance == null || quotaBalance.isEmpty()) { |
| throw new InvalidParameterValueException("The request period does not contain balance entries."); |
| } |
| Collections.sort(quotaBalance, new Comparator<QuotaBalanceVO>() { |
| @Override |
| public int compare(QuotaBalanceVO o1, QuotaBalanceVO o2) { |
| o1 = o1 == null ? new QuotaBalanceVO() : o1; |
| o2 = o2 == null ? new QuotaBalanceVO() : o2; |
| return o2.getUpdatedOn().compareTo(o1.getUpdatedOn()); // desc |
| } |
| }); |
| |
| boolean have_balance_entries = false; |
| //check that there is at least one balance entry |
| for (Iterator<QuotaBalanceVO> it = quotaBalance.iterator(); it.hasNext();) { |
| QuotaBalanceVO entry = it.next(); |
| if (entry.isBalanceEntry()) { |
| have_balance_entries = true; |
| break; |
| } |
| } |
| //if last entry is a credit deposit then remove that as that is already |
| //accounted for in the starting balance after that entry, note the sort is desc |
| if (have_balance_entries) { |
| ListIterator<QuotaBalanceVO> li = quotaBalance.listIterator(quotaBalance.size()); |
| // Iterate in reverse. |
| while (li.hasPrevious()) { |
| QuotaBalanceVO entry = li.previous(); |
| if (s_logger.isDebugEnabled()) { |
| s_logger.debug("createQuotaBalanceResponse: Entry=" + entry); |
| } |
| if (entry.getCreditsId() > 0) { |
| li.remove(); |
| } else { |
| break; |
| } |
| } |
| } |
| |
| int quota_activity = quotaBalance.size(); |
| QuotaBalanceResponse resp = new QuotaBalanceResponse(); |
| BigDecimal lastCredits = new BigDecimal(0); |
| boolean consecutive = true; |
| for (Iterator<QuotaBalanceVO> it = quotaBalance.iterator(); it.hasNext();) { |
| QuotaBalanceVO entry = it.next(); |
| if (s_logger.isDebugEnabled()) { |
| s_logger.debug("createQuotaBalanceResponse: All Credit Entry=" + entry); |
| } |
| if (entry.getCreditsId() > 0) { |
| if (consecutive) { |
| lastCredits = lastCredits.add(entry.getCreditBalance()); |
| } |
| resp.addCredits(entry); |
| it.remove(); |
| } else { |
| consecutive = false; |
| } |
| } |
| |
| if (quota_activity > 0 && quotaBalance.size() > 0) { |
| // order is desc last item is the start item |
| QuotaBalanceVO startItem = quotaBalance.get(quotaBalance.size() - 1); |
| QuotaBalanceVO endItem = quotaBalance.get(0); |
| resp.setStartDate(startDate); |
| resp.setStartQuota(startItem.getCreditBalance()); |
| resp.setEndDate(endDate); |
| if (s_logger.isDebugEnabled()) { |
| s_logger.debug("createQuotaBalanceResponse: Start Entry=" + startItem); |
| s_logger.debug("createQuotaBalanceResponse: End Entry=" + endItem); |
| } |
| resp.setEndQuota(endItem.getCreditBalance().add(lastCredits)); |
| } else if (quota_activity > 0) { |
| // order is desc last item is the start item |
| resp.setStartDate(startDate); |
| resp.setStartQuota(new BigDecimal(0)); |
| resp.setEndDate(endDate); |
| resp.setEndQuota(new BigDecimal(0).add(lastCredits)); |
| } else { |
| resp.setStartDate(startDate); |
| resp.setEndDate(endDate); |
| resp.setStartQuota(new BigDecimal(0)); |
| resp.setEndQuota(new BigDecimal(0)); |
| } |
| resp.setCurrency(QuotaConfig.QuotaCurrencySymbol.value()); |
| resp.setObjectName("balance"); |
| return resp; |
| } |
| |
| @Override |
| public QuotaStatementResponse createQuotaStatementResponse(final List<QuotaUsageVO> quotaUsage) { |
| if (quotaUsage == null || quotaUsage.isEmpty()) { |
| throw new InvalidParameterValueException("There is no usage data found for period mentioned."); |
| } |
| |
| QuotaStatementResponse statement = new QuotaStatementResponse(); |
| |
| HashMap<Integer, QuotaTypes> quotaTariffMap = new HashMap<Integer, QuotaTypes>(); |
| Collection<QuotaTypes> result = QuotaTypes.listQuotaTypes().values(); |
| |
| for (QuotaTypes quotaTariff : result) { |
| quotaTariffMap.put(quotaTariff.getQuotaType(), quotaTariff); |
| // add dummy record for each usage type |
| QuotaUsageVO dummy = new QuotaUsageVO(quotaUsage.get(0)); |
| dummy.setUsageType(quotaTariff.getQuotaType()); |
| dummy.setQuotaUsed(new BigDecimal(0)); |
| quotaUsage.add(dummy); |
| } |
| |
| if (s_logger.isDebugEnabled()) { |
| s_logger.debug( |
| "createQuotaStatementResponse Type=" + quotaUsage.get(0).getUsageType() + " usage=" + quotaUsage.get(0).getQuotaUsed().setScale(2, RoundingMode.HALF_EVEN) |
| + " rec.id=" + quotaUsage.get(0).getUsageItemId() + " SD=" + quotaUsage.get(0).getStartDate() + " ED=" + quotaUsage.get(0).getEndDate()); |
| } |
| |
| Collections.sort(quotaUsage, new Comparator<QuotaUsageVO>() { |
| @Override |
| public int compare(QuotaUsageVO o1, QuotaUsageVO o2) { |
| if (o1.getUsageType() == o2.getUsageType()) { |
| return 0; |
| } |
| return o1.getUsageType() < o2.getUsageType() ? -1 : 1; |
| } |
| }); |
| |
| List<QuotaStatementItemResponse> items = new ArrayList<QuotaStatementItemResponse>(); |
| QuotaStatementItemResponse lineitem; |
| int type = -1; |
| BigDecimal usage = new BigDecimal(0); |
| BigDecimal totalUsage = new BigDecimal(0); |
| quotaUsage.add(new QuotaUsageVO());// boundary |
| QuotaUsageVO prev = quotaUsage.get(0); |
| if (s_logger.isDebugEnabled()) { |
| s_logger.debug("createQuotaStatementResponse record count=" + quotaUsage.size()); |
| } |
| for (final QuotaUsageVO quotaRecord : quotaUsage) { |
| if (type != quotaRecord.getUsageType()) { |
| if (type != -1) { |
| lineitem = new QuotaStatementItemResponse(type); |
| lineitem.setQuotaUsed(usage); |
| lineitem.setAccountId(prev.getAccountId()); |
| lineitem.setDomainId(prev.getDomainId()); |
| lineitem.setUsageUnit(quotaTariffMap.get(type).getQuotaUnit()); |
| lineitem.setUsageName(quotaTariffMap.get(type).getQuotaName()); |
| lineitem.setObjectName("quotausage"); |
| items.add(lineitem); |
| totalUsage = totalUsage.add(usage); |
| usage = new BigDecimal(0); |
| } |
| type = quotaRecord.getUsageType(); |
| } |
| prev = quotaRecord; |
| usage = usage.add(quotaRecord.getQuotaUsed()); |
| } |
| |
| statement.setLineItem(items); |
| statement.setTotalQuota(totalUsage); |
| statement.setCurrency(QuotaConfig.QuotaCurrencySymbol.value()); |
| statement.setObjectName("statement"); |
| return statement; |
| } |
| |
| @Override |
| public List<QuotaTariffVO> listQuotaTariffPlans(final QuotaTariffListCmd cmd) { |
| List<QuotaTariffVO> result = new ArrayList<QuotaTariffVO>(); |
| Date effectiveDate = cmd.getEffectiveDate() == null ? new Date() : cmd.getEffectiveDate(); |
| Date adjustedEffectiveDate = _quotaService.computeAdjustedTime(effectiveDate); |
| if (s_logger.isDebugEnabled()) { |
| s_logger.debug("Effective datec=" + effectiveDate + " quotatype=" + cmd.getUsageType() + " Adjusted date=" + adjustedEffectiveDate); |
| } |
| if (cmd.getUsageType() != null) { |
| QuotaTariffVO tariffPlan = _quotaTariffDao.findTariffPlanByUsageType(cmd.getUsageType(), adjustedEffectiveDate); |
| if (tariffPlan != null) { |
| result.add(tariffPlan); |
| } |
| } else { |
| result = _quotaTariffDao.listAllTariffPlans(adjustedEffectiveDate); |
| } |
| return result; |
| } |
| |
| @Override |
| public QuotaTariffVO updateQuotaTariffPlan(QuotaTariffUpdateCmd cmd) { |
| final int quotaType = cmd.getUsageType(); |
| final BigDecimal quotaCost = new BigDecimal(cmd.getValue()); |
| final Date effectiveDate = _quotaService.computeAdjustedTime(cmd.getStartDate()); |
| final Date now = _quotaService.computeAdjustedTime(new Date()); |
| // if effective date is in the past return error |
| if (effectiveDate.compareTo(now) < 0) { |
| throw new InvalidParameterValueException("Incorrect effective date for tariff " + effectiveDate + " is less than now " + now); |
| } |
| QuotaTypes quotaConstant = QuotaTypes.listQuotaTypes().get(quotaType); |
| if (quotaConstant == null) { |
| throw new InvalidParameterValueException("Quota type does not exists " + quotaType); |
| } |
| |
| QuotaTariffVO result = null; |
| result = new QuotaTariffVO(quotaType); |
| result.setUsageName(quotaConstant.getQuotaName()); |
| result.setUsageUnit(quotaConstant.getQuotaUnit()); |
| result.setUsageDiscriminator(quotaConstant.getDiscriminator()); |
| result.setCurrencyValue(quotaCost); |
| result.setEffectiveOn(effectiveDate); |
| result.setUpdatedOn(now); |
| result.setUpdatedBy(cmd.getEntityOwnerId()); |
| |
| if (s_logger.isDebugEnabled()) { |
| s_logger.debug(String.format("Updating Quota Tariff Plan: New value=%s for resource type=%d effective on date=%s", quotaCost, quotaType, effectiveDate)); |
| } |
| _quotaTariffDao.addQuotaTariff(result); |
| |
| return result; |
| } |
| |
| @Override |
| public QuotaCreditsResponse addQuotaCredits(Long accountId, Long domainId, Double amount, Long updatedBy, Boolean enforce) { |
| Date despositedOn = _quotaService.computeAdjustedTime(new Date()); |
| QuotaBalanceVO qb = _quotaBalanceDao.findLaterBalanceEntry(accountId, domainId, despositedOn); |
| |
| if (qb != null) { |
| throw new InvalidParameterValueException("Incorrect deposit date: " + despositedOn + " there are balance entries after this date"); |
| } |
| |
| QuotaCreditsVO credits = new QuotaCreditsVO(accountId, domainId, new BigDecimal(amount), updatedBy); |
| credits.setUpdatedOn(despositedOn); |
| QuotaCreditsVO result = _quotaCreditsDao.saveCredits(credits); |
| |
| final AccountVO account = _accountDao.findById(accountId); |
| if (account == null) { |
| throw new InvalidParameterValueException("Account does not exist with account id " + accountId); |
| } |
| final boolean lockAccountEnforcement = "true".equalsIgnoreCase(QuotaConfig.QuotaEnableEnforcement.value()); |
| final BigDecimal currentAccountBalance = _quotaBalanceDao.lastQuotaBalance(accountId, domainId, startOfNextDay(new Date(despositedOn.getTime()))); |
| if (s_logger.isDebugEnabled()) { |
| s_logger.debug("AddQuotaCredits: Depositing " + amount + " on adjusted date " + despositedOn + ", current balance " + currentAccountBalance); |
| } |
| // update quota account with the balance |
| _quotaService.saveQuotaAccount(account, currentAccountBalance, despositedOn); |
| if (lockAccountEnforcement) { |
| if (currentAccountBalance.compareTo(new BigDecimal(0)) >= 0) { |
| if (account.getState() == Account.State.locked) { |
| s_logger.info("UnLocking account " + account.getAccountName() + " , due to positive balance " + currentAccountBalance); |
| _accountMgr.enableAccount(account.getAccountName(), domainId, accountId); |
| } |
| } else { // currentAccountBalance < 0 then lock the account |
| if (_quotaManager.isLockable(account) && account.getState() == Account.State.enabled && enforce) { |
| s_logger.info("Locking account " + account.getAccountName() + " , due to negative balance " + currentAccountBalance); |
| _accountMgr.lockAccount(account.getAccountName(), domainId, accountId); |
| } |
| } |
| } |
| |
| String creditor = String.valueOf(Account.ACCOUNT_ID_SYSTEM); |
| User creditorUser = _userDao.getUser(updatedBy); |
| if (creditorUser != null) { |
| creditor = creditorUser.getUsername(); |
| } |
| QuotaCreditsResponse response = new QuotaCreditsResponse(result, creditor); |
| response.setCurrency(QuotaConfig.QuotaCurrencySymbol.value()); |
| return response; |
| } |
| |
| private QuotaEmailTemplateResponse createQuotaEmailResponse(QuotaEmailTemplatesVO template) { |
| QuotaEmailTemplateResponse response = new QuotaEmailTemplateResponse(); |
| response.setTemplateType(template.getTemplateName()); |
| response.setTemplateSubject(template.getTemplateSubject()); |
| response.setTemplateText(template.getTemplateBody()); |
| response.setLocale(template.getLocale()); |
| response.setLastUpdatedOn(template.getLastUpdated()); |
| return response; |
| } |
| |
| @Override |
| public List<QuotaEmailTemplateResponse> listQuotaEmailTemplates(QuotaEmailTemplateListCmd cmd) { |
| final String templateName = cmd.getTemplateName(); |
| List<QuotaEmailTemplatesVO> templates = _quotaEmailTemplateDao.listAllQuotaEmailTemplates(templateName); |
| final List<QuotaEmailTemplateResponse> responses = new ArrayList<QuotaEmailTemplateResponse>(); |
| for (final QuotaEmailTemplatesVO template : templates) { |
| responses.add(createQuotaEmailResponse(template)); |
| } |
| return responses; |
| } |
| |
| @Override |
| public boolean updateQuotaEmailTemplate(QuotaEmailTemplateUpdateCmd cmd) { |
| final String templateName = cmd.getTemplateName(); |
| final String templateSubject = StringEscapeUtils.escapeJavaScript(cmd.getTemplateSubject()); |
| final String templateBody = StringEscapeUtils.escapeJavaScript(cmd.getTemplateBody()); |
| final String locale = cmd.getLocale(); |
| |
| final List<QuotaEmailTemplatesVO> templates = _quotaEmailTemplateDao.listAllQuotaEmailTemplates(templateName); |
| if (templates.size() == 1) { |
| final QuotaEmailTemplatesVO template = templates.get(0); |
| template.setTemplateSubject(templateSubject); |
| template.setTemplateBody(templateBody); |
| if (locale != null) { |
| template.setLocale(locale); |
| } |
| return _quotaEmailTemplateDao.updateQuotaEmailTemplate(template); |
| } |
| return false; |
| } |
| |
| @Override |
| public QuotaBalanceResponse createQuotaLastBalanceResponse(List<QuotaBalanceVO> quotaBalance, Date startDate) { |
| if (quotaBalance == null) { |
| throw new InvalidParameterValueException("There are no balance entries on or before the requested date."); |
| } |
| if (startDate == null) { |
| startDate = new Date(); |
| } |
| QuotaBalanceResponse resp = new QuotaBalanceResponse(); |
| BigDecimal lastCredits = new BigDecimal(0); |
| for (QuotaBalanceVO entry : quotaBalance) { |
| if (s_logger.isDebugEnabled()) { |
| s_logger.debug("createQuotaLastBalanceResponse Date=" + entry.getUpdatedOn() + " balance=" + entry.getCreditBalance() + " credit=" + entry.getCreditsId()); |
| } |
| lastCredits = lastCredits.add(entry.getCreditBalance()); |
| } |
| resp.setStartQuota(lastCredits); |
| resp.setStartDate(startDate); |
| resp.setCurrency(QuotaConfig.QuotaCurrencySymbol.value()); |
| resp.setObjectName("balance"); |
| return resp; |
| } |
| |
| @Override |
| public List<QuotaUsageVO> getQuotaUsage(QuotaStatementCmd cmd) { |
| return _quotaService.getQuotaUsage(cmd.getAccountId(), cmd.getAccountName(), cmd.getDomainId(), cmd.getUsageType(), cmd.getStartDate(), cmd.getEndDate()); |
| } |
| |
| @Override |
| public List<QuotaBalanceVO> getQuotaBalance(QuotaBalanceCmd cmd) { |
| return _quotaService.findQuotaBalanceVO(cmd.getAccountId(), cmd.getAccountName(), cmd.getDomainId(), cmd.getStartDate(), cmd.getEndDate()); |
| } |
| @Override |
| public Date startOfNextDay(Date date) { |
| LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); |
| return createDateAtTheStartOfNextDay(localDate); |
| } |
| |
| @Override |
| public Date startOfNextDay() { |
| LocalDate localDate = LocalDate.now(); |
| return createDateAtTheStartOfNextDay(localDate); |
| } |
| |
| private Date createDateAtTheStartOfNextDay(LocalDate localDate) { |
| LocalDate nextDayLocalDate = localDate.plusDays(1); |
| return Date.from(nextDayLocalDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant()); |
| } |
| |
| } |