com.rockagen.gnext.service.spring.AccountServImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.rockagen.gnext.service.spring.AccountServImpl.java

Source

/*
 * Copyright 2014-2015 the original author or authors.
 *
 * Licensed 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 com.rockagen.gnext.service.spring;

import com.rockagen.commons.util.CommUtil;
import com.rockagen.gnext.enums.AccountOperationType;
import com.rockagen.gnext.enums.AccountStatus;
import com.rockagen.gnext.enums.AccountType;
import com.rockagen.gnext.exception.AccountException;
import com.rockagen.gnext.po.Account;
import com.rockagen.gnext.po.AccountBill;
import com.rockagen.gnext.po.AuthUser;
import com.rockagen.gnext.qo.QueryObject;
import com.rockagen.gnext.service.AccountBillServ;
import com.rockagen.gnext.service.AccountServ;
import com.rockagen.gnext.service.AuthUserServ;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * Implementation of the {@link AccountServ} interface
 *
 * @author ra
 * @since JDK1.8
 */
@Service("accountServ")
public class AccountServImpl extends QueryObjectGenericServImpl<Account, Long> implements AccountServ {

    @Resource
    private AccountBillServ accountBillServ;
    @Resource
    private AuthUserServ authUserServ;

    @Override
    public Optional<Account> loadByUid(long uid) {
        List<Account> list = loadListByUid(uid);
        return filter(list);
    }

    /**
     * Offer the maximum priority of the list.
     *
     * @param list list
     * @return Account
     */
    private Optional<Account> filter(List<Account> list) {
        Account tmp = list.get(0);
        if (list.size() > 1) {
            tmp = list.stream().filter(x -> x.getStatus() == AccountStatus.OPEN)
                    .min((a, b) -> a.getPriority().compareTo(b.getPriority())).get();
        }
        return Optional.ofNullable(tmp);

    }

    @Override
    public List<Account> loadListByUid(long uid) {
        QueryObject qo = new QueryObject();
        DetachedCriteria dc = qo.generateDetachedCriteria(Account.class);
        dc.createAlias("user", "u");
        dc.add(Restrictions.eq("u.id", uid));
        dc.addOrder(Order.desc("updatedAt"));
        return find(qo);
    }

    @Override
    public void newAccount(long uid, AccountType type) {
        Optional<AuthUser> u = authUserServ.load(uid);
        if (u.isPresent()) {
            Account a = initAccount(u.get(), type);
            add(a);
        }
    }

    @Override
    public Optional<Account> loadByUid(String uid) {
        Optional<AuthUser> u = authUserServ.load(uid);
        if (u.isPresent()) {
            return loadByUid(u.get().getId());
        } else {
            return Optional.empty();
        }
    }

    @Override
    public List<Account> loadListByUid(String uid) {
        Optional<AuthUser> u = authUserServ.load(uid);
        if (u.isPresent()) {
            return loadListByUid(u.get().getId());
        }
        return Collections.emptyList();
    }

    @Override
    public void newAccount(String uid, AccountType type) {
        Optional<AuthUser> u = authUserServ.load(uid);
        if (u.isPresent()) {
            newAccount(u.get().getId(), type);
        }
    }

    /**
     * Initialize account*
     *
     * @param user user
     * @param type type
     * @return Account
     */
    private Account initAccount(AuthUser user, AccountType type) {
        Account a = new Account();
        a.init();
        a.setType(Optional.ofNullable(type).orElse(AccountType.INDIVIDUAL));
        a.setUser(user);
        a.setRemark(user.getName());
        return a;
    }

    @Override
    public void increase(long id, BigDecimal amount, String remark) {
        load(id).ifPresent(acc -> {
            // account
            BigDecimal before = acc.getBalance();
            acc.addBalance(amount);
            genAccountBill(acc, AccountOperationType.DEBIT, before, amount, remark);
        });
    }

    @Override
    public void decrease(long id, BigDecimal amount, String remark) throws AccountException {
        Optional<Account> acc = load(id);
        if (acc.isPresent()) {
            // account
            BigDecimal before = acc.get().getBalance();
            acc.get().subtractBalance(amount);
            genAccountBill(acc.get(), AccountOperationType.CREDIT, before, amount, remark);
        }
    }

    @Override
    public void preTakeAmount(long id, BigDecimal amount, String remark) throws AccountException {
        lockedBalance(id, amount);
    }

    @Override
    public void takePreAmount(long id, BigDecimal amount, String remark) throws AccountException {
        unLockedBalance(id, amount);
        decrease(id, amount, remark);
    }

    @Override
    public boolean checkBalance(long id, BigDecimal amount) {
        Optional<Account> account = load(id);
        if (account.isPresent()) {
            return checkBalance(account.get(), amount);
        }
        return false;
    }

    @Override
    public boolean checkBalance(String uid, BigDecimal amount) {
        Optional<Account> account = loadByUid(uid);
        if (account.isPresent()) {
            return checkBalance(account.get(), amount);
        }
        return false;
    }

    @Override
    public void lockedBalance(long id, BigDecimal amount) throws AccountException {
        Optional<Account> acc = load(id);
        if (acc.isPresent()) {
            // account
            acc.get().lockedBalance(amount);
        }
    }

    @Override
    public void unLockedBalance(long id, BigDecimal amount) throws AccountException {
        Optional<Account> acc = load(id);
        if (acc.isPresent()) {
            // account
            acc.get().unLockedBalance(amount);
        }
    }

    @Override
    public void lockedAccount(long id) {
        load(id).ifPresent(acc -> {
            // account
            Date now = new Date();
            acc.setStatus(AccountStatus.LOCKED);
            acc.setLockedAt(now);
            acc.setUpdatedAt(now);
        });
    }

    @Override
    public void unLockedAccount(long id) {
        load(id).ifPresent(acc -> {
            // account
            Date now = new Date();
            acc.setStatus(AccountStatus.OPEN);
            acc.setEnabledAt(now);
            acc.setUpdatedAt(now);
        });

    }

    @Override
    public void expiredAccount(long id) {
        load(id).ifPresent(acc -> {
            // account
            Date now = new Date();
            acc.setStatus(AccountStatus.EXPIRED);
            acc.setExpiredAt(now);
            acc.setUpdatedAt(now);
        });
    }

    @Override
    public void invalidAccount(long id) {
        load(id).ifPresent(acc -> {
            // account
            Date now = new Date();
            acc.setStatus(AccountStatus.INVALID);
            acc.setInvalidAt(now);
            acc.setUpdatedAt(now);
        });
    }

    /**
     * Balance enough?
     *
     * @param account Account
     * @param amount  amount
     * @return true if enough
     */
    private boolean checkBalance(Account account, BigDecimal amount) {
        BigDecimal tmp = account.getAvailableBalance().subtract(amount.abs());
        if ((tmp.compareTo(BigDecimal.ZERO)) < 0) {
            return false;
        }
        return true;

    }

    /**
     * Account bill
     *
     * @param po     po
     * @param amount before balance
     * @param amount amount
     * @param remark remark
     */
    private void genAccountBill(Account po, AccountOperationType opType, BigDecimal beforeBalance,
            BigDecimal amount, String remark) {
        // account bill
        Date now = new Date();
        AccountBill ab = new AccountBill();
        ab.setRemark(remark);
        ab.setAccount(po);
        ab.setAmount(amount.abs());
        ab.setCreatedAt(now);
        ab.setOperationType(opType);
        ab.setBeforeBalance(beforeBalance);
        ab.setAfterBalance(po.getBalance());
        ab.setSn(getBillSn(po.getUser().getId()));
        accountBillServ.add(ab);

    }

    private String getBillSn(long uid) {
        Date now = new Date();
        String tmp = CommUtil.dateTime2StringFS(now);
        StringBuilder sb = new StringBuilder(tmp);
        String suid = String.format("%08d", uid);
        sb.insert(8, suid);
        return sb.toString();
    }
}