package com.fdkankan.ucenter.service.impl;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fdkankan.common.constant.AppConstant;
import com.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.constant.ServerCode;
import com.fdkankan.common.constant.TbStatus;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.ucenter.common.FileUtil;
import com.fdkankan.ucenter.common.OssPath;
import com.fdkankan.ucenter.common.PageInfo;
import com.fdkankan.ucenter.common.RandomCodeUtil;
import com.fdkankan.ucenter.common.constants.NacosProperty;
import com.fdkankan.ucenter.config.ThreadPoolConfig;
import com.fdkankan.ucenter.entity.*;
import com.fdkankan.ucenter.mapper.IInvoiceMapper;
import com.fdkankan.ucenter.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.ucenter.util.MyExcelUtil;
import com.fdkankan.ucenter.vo.request.InvoiceParam;
import com.fdkankan.ucenter.vo.request.PlaceOrderParam;
import com.fdkankan.ucenter.vo.response.OrderVo;
import com.sun.xml.bind.v2.model.core.ID;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.weaver.ast.Or;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
/**
*
* 发票表 服务实现类
*
*
* @author
* @since 2022-07-13
*/
@Service
@Slf4j
public class InvoiceServiceImpl extends ServiceImpl implements IInvoiceService {
@Autowired
IUserService userService;
@Autowired
IOrderService orderService;
@Autowired
IIncrementOrderService incrementOrderService;
@Autowired
IVirtualOrderService virtualOrderService;
@Autowired
IExpansionOrderService expansionOrderService;
@Autowired
IDownloadOrderService downloadOrderService;
@Autowired
IMailTemplateService mailTemplateService;
@Override
public Invoice getByOrderId(Long orderId) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Invoice::getOrderId,orderId);
List list = this.list(wrapper);
if(list != null && list.size() >0){
return list.get(0);
}
return null;
}
@Override
public Invoice getByIncrementOrderId(Long incrementOrderId) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Invoice::getIncrementOrderId,incrementOrderId);
List list = this.list(wrapper);
if(list != null && list.size() >0){
return list.get(0);
}
return null;
}
@Override
public HashMap getByIncrementOrderIds(Set ids) {
HashMap map = new HashMap<>();
if(ids.size() >0){
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.in(Invoice::getIncrementOrderId,ids);
List list = this.list(wrapper);
list.forEach(entity ->map.put(entity.getIncrementOrderId(),entity));
}
return map;
}
@Override
public Invoice getByDownId(Long downId) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Invoice::getDownloadOrderId,downId);
List list = this.list(wrapper);
if(list != null && list.size() >0){
return list.get(0);
}
return null;
}
@Override
public void saveByOrder(Long userId, PlaceOrderParam orderParam) {
InvoiceParam param = orderParam.getInvoice();
Invoice invoiceEntity = new Invoice();
invoiceEntity.setUserId(userId);
invoiceEntity.setType(Integer.valueOf(param.getInvoiceType()));
invoiceEntity.setTitle(param.getTitle());
invoiceEntity.setCode(param.getCode());
invoiceEntity.setEmailAddress(param.getEmailAddress());
if (3 == invoiceEntity.getType()){
invoiceEntity.setOrganizedAddress(param.getOrganizedAddress());
invoiceEntity.setRegisterPhone(param.getRegisterPhone());
invoiceEntity.setBankName(param.getBankName());
invoiceEntity.setBankAccount(param.getBankAccount());
}
invoiceEntity.setConsumeType(0);
invoiceEntity.setOrderId(orderParam.getOrderId());
invoiceEntity.setShipName(orderParam.getReceiver().getShipName());
invoiceEntity.setShipMobile(orderParam.getReceiver().getShipMobile());
invoiceEntity.setShipAddress(orderParam.getReceiver().getShipAddress());
invoiceEntity.setShipAreaPath(orderParam.getReceiver().getShipAreaPath());
invoiceEntity.setEmailAddress(param.getEmailAddress());
invoiceEntity.setMoney(new BigDecimal(param.getAmount()));
this.save(invoiceEntity);
}
@Override
public void checkInvoice(Long orderId, Integer consumeType) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
switch (consumeType){
case 0 : wrapper.eq(Invoice::getOrderId,orderId); break;
case 1 : wrapper.eq(Invoice::getVirtualOrderId,orderId); break;
case 2 :
case 3 : wrapper.eq(Invoice::getIncrementOrderId,orderId); break;
}
long count = this.count(wrapper);
if(count >0){
throw new BusinessException(AppConstant.FAILURE_CODE_4021, AppConstant.FAILURE_MSG_4021);
}
}
public void getMoney(Long orderId, Integer consumeType,Invoice dbEntity) {
dbEntity.setMoney(BigDecimal.ZERO);
switch (consumeType){
case 0 :
Order order = orderService.getById(orderId);
if(order.getPaymentStatus().equals("paid")){
dbEntity.setMoney(order.getTotalAmount());
dbEntity.setOrderSn(order.getOrderSn());
dbEntity.setProductCount(order.getGoodsTotalCount());
dbEntity.setProductName(order.getTradeNum());
dbEntity.setPayType(order.getOrderSn());
}
break;
case 1 :
VirtualOrder virtualOrder = virtualOrderService.getById(orderId);
if(virtualOrder.getPayStatus() == 1){
dbEntity.setMoney(virtualOrder.getAmount());
dbEntity.setOrderSn(virtualOrder.getOrderSn());
dbEntity.setProductCount(virtualOrder.getPoints());
dbEntity.setProductName(virtualOrder.getNumber());
dbEntity.setPayType(virtualOrder.getOrderSn());
}
break;
case 2 :
IncrementOrder incrementOrder = incrementOrderService.getById(orderId);
if(incrementOrder.getPayStatus() == 1){
dbEntity.setMoney(incrementOrder.getAmount());
dbEntity.setOrderSn(incrementOrder.getOrderSn());
dbEntity.setProductCount(incrementOrder.getCount());
if("SE".equals(incrementOrder.getMemberLevels())){
dbEntity.setProductName("Senior (Monthly) *" +incrementOrder.getMonthQy());
}else {
dbEntity.setProductName("Premium (Yearly) *" +incrementOrder.getMonthQy());
}
if(incrementOrder.getPayType() ==2 ){
dbEntity.setPayType("paypal");
}
if(incrementOrder.getPayType() ==6 ){
dbEntity.setPayType("stripe");
}
}
break;
case 3 :
DownloadOrder downloadOrder = downloadOrderService.getById(orderId);
if(downloadOrder.getPayStatus() == 1){
dbEntity.setMoney(downloadOrder.getAmount());
dbEntity.setOrderSn(downloadOrder.getOrderSn());
dbEntity.setProductCount(downloadOrder.getCount());
dbEntity.setProductName("Scene Download");
if(downloadOrder.getPayType() ==2 ){
dbEntity.setPayType("paypal");
}
if(downloadOrder.getPayType() ==6 ){
dbEntity.setPayType("stripe");
}
}
break;
}
}
@Override
public Invoice openInvoice(InvoiceParam param, String token) {
User user = userService.getByToken(token);
//验证是否已经开票
this.checkInvoice(param.getOrderId(),param.getConsumeType());
//获取开票金额
Invoice dbEntity = new Invoice();
this.getMoney(param.getOrderId(),param.getConsumeType(),dbEntity);
BeanUtils.copyProperties(param, dbEntity);
dbEntity.setOrderId(null);
switch (param.getConsumeType()){
case 0: dbEntity.setOrderId(param.getOrderId()); break;
case 1: dbEntity.setVirtualOrderId(param.getOrderId()); break;
case 2: dbEntity.setIncrementOrderId(param.getOrderId());break;
case 3: dbEntity.setDownloadOrderId(param.getOrderId()); break;
}
if (param.getCameraId() != null){
dbEntity.setCameraId(param.getCameraId());
}
dbEntity.setUserId(user.getId());
this.save(dbEntity);
String invoiceNumber = this.updateInvoiceNumber(dbEntity.getId());
dbEntity.setInvoiceNumber(invoiceNumber);
sendEmail(dbEntity);
return dbEntity;
}
@Autowired
ThreadPoolConfig threadPoolConfig;
private void sendEmail(Invoice dbEntity) {
//国际服直接发送邮件
threadPoolConfig.taskExecutor().execute(() -> {
log.info("异步任务执行,当前线程:" + Thread.currentThread().getName());
if("aws".equals(NacosProperty.uploadType) && dbEntity.getEmailAddress() != null){
MailTemplate mailTemplate = mailTemplateService.getTemplate(14, "en");
dbEntity.setCreateTime(DateUtil.format(new Date(),"yyyy-MM-dd"));
String filePath = MyExcelUtil.excelTemplteToPdf(OssPath.localPath +"/invoice", "invoiceTemplate", dbEntity);
mailTemplateService.sendMail(dbEntity.getEmailAddress(),mailTemplate,filePath);
FileUtil.delFile(filePath);
FileUtil.delFile(filePath+".sy");
FileUtil.delFile(filePath.replace(".pdf",".xlsx"));
}
});
}
private String updateInvoiceNumber(Long id) {
String format1 = new SimpleDateFormat("yyMMdd").format(new Date());
String invoiceNumber = "W-"+format1 + id;
LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(Invoice::getId,id);
wrapper.set(Invoice::getInvoiceNumber,invoiceNumber);
this.update(wrapper);
return invoiceNumber;
}
private synchronized String genInVoiceNumber() {
String invoiceNumber = RandomCodeUtil.generateCode("W-", 8);
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Invoice::getInvoiceNumber,invoiceNumber);
List list = this.list(wrapper);
if(list == null || list.isEmpty()){
return invoiceNumber;
}else {
return genInVoiceNumber();
}
}
@Override
public JSONObject getMaxInvoice(InvoiceParam param) {
JSONObject object = new JSONObject();
int maxInvoice = this.getMaxInvoice(param.getCameraId());
object.put("maxInvoice", maxInvoice < 0 ? 0 : maxInvoice);
return object;
}
private Integer getMaxInvoice(Long cameraId){
List virtualOrderList = virtualOrderService.getByCameraId(cameraId);
int maxInvoice = 0;
for (VirtualOrder virtualOrderEntity : virtualOrderList){
if (virtualOrderEntity.getStatus() == 1 && virtualOrderEntity.getPayStatus() == 1){
maxInvoice += virtualOrderEntity.getPoints();
}else if (virtualOrderEntity.getStatus() == -2){
maxInvoice -= virtualOrderEntity.getPoints();
}
}
List expansionOrderList = expansionOrderService.getByCameraId(cameraId);
for(ExpansionOrder expansionOrderEntity : expansionOrderList){
if(expansionOrderEntity.getPayStatus() == 1){
maxInvoice += expansionOrderEntity.getAmount().intValue();
}else if (expansionOrderEntity.getPayStatus() == -2){
maxInvoice -= expansionOrderEntity.getAmount().intValue();
}
}
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Invoice::getCameraId,cameraId);
wrapper.eq(Invoice::getConsumeType,1);
List list = this.list(wrapper);
for (Invoice entity : list){
if (entity.getMoney() != null){
maxInvoice -= entity.getMoney().intValue();
}
}
return maxInvoice;
}
@Override
public PageInfo getInvoices(String token, InvoiceParam param) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
if(StringUtils.isNotBlank(token)){
User user = userService.getByToken(token);
wrapper.eq(Invoice::getUserId,user.getId());
}
if(param.getCameraId() != null){
wrapper.eq(Invoice::getCameraId,param.getCameraId());
}
if(param.getType() != null){
if(param.getType() != 0){
wrapper.ne(Invoice::getType,0);
}else {
wrapper.eq(Invoice::getType,1);
}
}
wrapper.ne(Invoice::getConsumeType ,-1);
wrapper.orderByDesc(Invoice::getCreateTime);
Page page = this.page(new Page<>(param.getPageNum(), param.getPageSize()), wrapper);
return PageInfo.PageInfo(page);
}
@Override
public Invoice getMyInvoiceInfo(String token, InvoiceParam param) {
User user = userService.getByToken(token);
return getMineInvoice(user.getId(),param.getInvoiceType());
}
private Invoice getMineInvoice(Long userId,String invoiceType){
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Invoice::getUserId,userId);
wrapper.eq(Invoice::getConsumeType ,-1);
wrapper.eq(Invoice::getType ,invoiceType);
wrapper.last("LIMIT 1");
List list = this.list(wrapper);
if(list == null || list.size()<=0){
return null;
}
return list.get(0);
}
@Override
public void saveInvoice(String token, InvoiceParam param) {
User user = userService.getByToken(token);
Invoice dbEntity = getMineInvoice(user.getId(),param.getInvoiceType());
if (dbEntity == null){
dbEntity = new Invoice();
}
if (param.getCameraId() != null){
dbEntity.setCameraId(param.getCameraId());
}
dbEntity.setType(Integer.valueOf(param.getInvoiceType()));
dbEntity.setUserId(user.getId());
dbEntity.setBankAccount(param.getBankAccount());
dbEntity.setBankName(param.getBankName());
dbEntity.setRegisterPhone(param.getRegisterPhone());
dbEntity.setOrganizedAddress(param.getOrganizedAddress());
dbEntity.setCode(param.getCode());
dbEntity.setTitle(param.getTitle());
dbEntity.setEmailAddress(param.getEmailAddress());
dbEntity.setConsumeType(-1);
if(!this.saveOrUpdate(dbEntity)){
throw new BusinessException(ErrorCode.ERROR_MSG);
}
}
@Override
public void addInvoice(String token, InvoiceParam param) {
User user = userService.getByToken(token);
if(param.getAmount() == null){
throw new BusinessException(ErrorCode.MISSING_REQUIRED_PARAMETERS);
}
int maxInvoice = this.getMaxInvoice(param.getCameraId());
if(Integer.parseInt(param.getAmount()) > maxInvoice){
throw new BusinessException(ErrorCode.FAILURE_CODE_8003);
}
saveOrUpdateInvoice(user.getId(),param,null);
}
@Override
public void updateInvoice(String token, InvoiceParam param) {
User user = userService.getByToken(token);
if(param.getInvoiceId() != null){
Invoice invoiceEntity = this.getById(param.getInvoiceId());
if(invoiceEntity == null){
throw new BusinessException(ErrorCode.NOT_RECORD);
}
this.saveOrUpdateInvoice(user.getId(), param,invoiceEntity);
}else {
OrderVo order = orderService.getOrderDetail(param.getOrderId());
if(order == null || order.getTotalAmount() == null){
throw new BusinessException(ErrorCode.ERROR_MSG);
}
param.setAmount(order.getTotalAmount().toString());
this.saveOrUpdateInvoice(user.getId(),param,null);
}
}
private void saveOrUpdateInvoice(Long userId, InvoiceParam param, Invoice invoiceEntity){
if(invoiceEntity == null){
invoiceEntity = new Invoice();
invoiceEntity.setUserId(userId);
invoiceEntity.setOrderId(param.getOrderId());
}
invoiceEntity.setType(Integer.valueOf(param.getInvoiceType()));
invoiceEntity.setTitle(param.getTitle());
invoiceEntity.setCode(param.getCode());
if (3 == invoiceEntity.getType()){
invoiceEntity.setOrganizedAddress(param.getOrganizedAddress());
invoiceEntity.setRegisterPhone(param.getRegisterPhone());
invoiceEntity.setBankName(param.getBankName());
invoiceEntity.setBankAccount(param.getBankAccount());
}
invoiceEntity.setCameraId(param.getCameraId());
invoiceEntity.setMoney(new BigDecimal(param.getAmount()));
invoiceEntity.setConsumeType(param.getConsumeType() == null? 1 : param.getConsumeType());
invoiceEntity.setShipName(param.getShipName());
invoiceEntity.setShipMobile(param.getShipMobile());
invoiceEntity.setShipAddress(param.getShipAddress());
invoiceEntity.setShipAreaPath(param.getShipAreaPath());
invoiceEntity.setCameraId(param.getCameraId());
invoiceEntity.setEmailAddress(param.getEmailAddress());
if(!this.saveOrUpdate(invoiceEntity)){
throw new BusinessException(ErrorCode.ERROR_MSG);
}
}
}