|
|
@@ -13,7 +13,11 @@ import org.springframework.stereotype.Service;
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
|
|
|
|
+import java.math.MathContext;
|
|
|
+import java.math.RoundingMode;
|
|
|
import java.sql.Timestamp;
|
|
|
+import java.text.ParseException;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
import java.util.*;
|
|
|
;
|
|
|
|
|
|
@@ -42,13 +46,34 @@ public class OrdersService {
|
|
|
ShopPaymentRecordService shopPaymentRecordService;
|
|
|
|
|
|
public List<OrdersVo> getAllByPayAt(OrderInParameter orderInParameter) {
|
|
|
- List<Orders> ordersList = getOrdersList(orderInParameter);
|
|
|
List<OrdersVo> ordersVos = new ArrayList<>();
|
|
|
+ List<Orders> ordersList = getOrdersList(orderInParameter);
|
|
|
+ if (ordersList.size()==0) {
|
|
|
+ return ordersVos;
|
|
|
+ }
|
|
|
for (Orders order : ordersList) {
|
|
|
OrdersVo ordersVo = new OrdersVo();
|
|
|
List<GoodsInfoVo> goodsInfo=new ArrayList<>();
|
|
|
List<OrdersGoods> orderGoodsList = ordersGoodsService.getOrderGoodsList(order.getId());
|
|
|
- ordersVo.setOrderId(order.getId());
|
|
|
+ ShopPaymentRecord shopPaymentRecord = shopPaymentRecordService.getShopPaymentRecordById(order.getId());
|
|
|
+ if (shopPaymentRecord == null||order.getStatus()==100||orderGoodsList.size()==0||order.getPayStatus()==0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (!"10.00".equals(String.valueOf(order.getOrderDiscount()))){
|
|
|
+ BigDecimal orderDiscount = order.getOrderDiscount();
|
|
|
+ BigDecimal allTotalFee = calculateDiscountedPrice(order.getTotalFee(), String.valueOf(orderDiscount));
|
|
|
+ ordersVo.setOrderDiscountFee(allTotalFee);
|
|
|
+ }else {
|
|
|
+ ordersVo.setOrderDiscountFee(new BigDecimal("0.00"));
|
|
|
+ }
|
|
|
+ ordersVo.setOrderFee(shopPaymentRecord.getFree());
|
|
|
+ ordersVo.setOrderEraseFee(order.getReduceFee());
|
|
|
+ ordersVo.setPayMemberFee(order.getBuyerDiscount());
|
|
|
+ ordersVo.setPayCashFee(shopPaymentRecord.getCash());
|
|
|
+ ordersVo.setPayWxFee(shopPaymentRecord.getWeixin());
|
|
|
+ ordersVo.setPayAlipayFee(shopPaymentRecord.getAlipay());
|
|
|
+ ordersVo.setPayTagFee(shopPaymentRecord.getZjdcodecard());
|
|
|
+ ordersVo.setOrderId(order.getNumber());
|
|
|
ordersVo.setShopId(order.getShopId());
|
|
|
ordersVo.setCount(order.getGoodsAmount());
|
|
|
ordersVo.setAmount(order.getPayFeeOrigin());
|
|
|
@@ -57,126 +82,158 @@ public class OrdersService {
|
|
|
ordersVo.setPaymentTime(String.valueOf(order.getPayAt().getTime()));
|
|
|
ordersVo.setPaymentType(order.getPayment());
|
|
|
ordersVo.setPaymentUser(order.getPayPersonName());
|
|
|
-
|
|
|
for (OrdersGoods orderGoods : orderGoodsList) {
|
|
|
GoodsInfoVo goodsInfoVo=new GoodsInfoVo();
|
|
|
goodsInfoVo.setGoodsId(orderGoods.getGoodsId());
|
|
|
goodsInfoVo.setPrice(orderGoods.getSalePrice());
|
|
|
goodsInfoVo.setCount(orderGoods.getGoodsAmount());
|
|
|
goodsInfoVo.setAmount(orderGoods.getGoodsTotalPrice());
|
|
|
+ goodsInfoVo.setGoodsUnit(orderGoods.getGoodsUnit());
|
|
|
goodsInfo.add(goodsInfoVo);
|
|
|
}
|
|
|
ordersVo.setGoodsInfo(goodsInfo);
|
|
|
ordersVos.add(ordersVo);
|
|
|
}
|
|
|
-
|
|
|
return ordersVos;
|
|
|
}
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
GoodsMapper goodsMapper;
|
|
|
- public Goods getTest(){
|
|
|
- return goodsMapper.selectById("05eb20dc-c38e-11eb-8816-0242ac170006");
|
|
|
+ public String getTest(){
|
|
|
+ return "测试成功";
|
|
|
}
|
|
|
|
|
|
- public List<OrdersStatementOfAccount> getOrdersStatementOfAccount(OrderInParameter orderInParameter) {
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * 这是一个报表,暂时是不规范的,目前只需要拼接数据,以后再改(需要单独抽取配置文件)
|
|
|
+ * **/
|
|
|
+
|
|
|
+ public List<OrdersStatementOfAccount> getOrdersStatementOfAccountNew(OrderInParameter orderInParameter) {
|
|
|
if (orderInParameter == null) {
|
|
|
- return null;
|
|
|
+ return Collections.emptyList(); // 返回空列表而不是null
|
|
|
}
|
|
|
+
|
|
|
List<String> dayString = printDatesBetween(orderInParameter.getStartTimestamp(), orderInParameter.getEndTimestamp());
|
|
|
- ArrayList<OrdersStatementOfAccount> ordersStatementOfAccounts = new ArrayList<>();
|
|
|
+ if (dayString == null || dayString.isEmpty()) {
|
|
|
+ return Collections.emptyList(); // 如果日期列表为空,则直接返回空列表
|
|
|
+ }
|
|
|
+
|
|
|
List<Shop> shopList = getShopList(orderInParameter, this.shopService);
|
|
|
- BigDecimal number = new BigDecimal("0.01"); // 使用字符串来避免精度问题
|
|
|
+ if (shopList == null || shopList.isEmpty()) {
|
|
|
+ return Collections.emptyList(); // 如果店铺列表为空,则直接返回空列表
|
|
|
+ }
|
|
|
+
|
|
|
+ List<OrdersStatementOfAccount> ordersStatementOfAccounts = new ArrayList<>();
|
|
|
+ BigDecimal shopRate = new BigDecimal(0.05); // 平台固定抽成,不需要读取数据库
|
|
|
|
|
|
- for (String day : dayString){
|
|
|
- //一天一天的统计
|
|
|
- for (Shop Shop : shopList) {
|
|
|
+ for (String day : dayString) {
|
|
|
+ for (Shop shop : shopList) {
|
|
|
OrdersStatementOfAccount ordersStatementOfAccount = new OrdersStatementOfAccount();
|
|
|
- //BigDecimal lakalaRate = shopPayConfigService.getShopPayConfigById(Shop.getId()).getLakalaRate();
|
|
|
- BigDecimal shopRate = shopPayConfigService.getShopPayConfigById(Shop.getId()).getShopRate();
|
|
|
- ArrayList<String> startAndEndTimeStamps = getStartAndEndTimeStamps(day);
|
|
|
- ArrayList<OrdersDTO> ordersDTOS = new ArrayList<>();
|
|
|
- List<ShopPaymentRecord> shopPaymentRecordList = shopPaymentRecordService.getShopPaymentRecordListByDay(Shop.getId(),startAndEndTimeStamps);
|
|
|
- //订单总营收 总付款-线上退款-线下退款
|
|
|
+ Map<String, Long> stringLongMap = convertToTimestamps(day);
|
|
|
+ if (stringLongMap == null || !stringLongMap.containsKey("start") || !stringLongMap.containsKey("end")) {
|
|
|
+ continue; // 如果转换后的时间戳映射无效,则跳过当前循环
|
|
|
+ }
|
|
|
+
|
|
|
+ OrderInParameter orderInParameterTime = new OrderInParameter();
|
|
|
+ orderInParameterTime.setStartTimestamp(stringLongMap.get("start"));
|
|
|
+ orderInParameterTime.setEndTimestamp(stringLongMap.get("end"));
|
|
|
+ orderInParameterTime.setShopId(shop.getId());
|
|
|
+
|
|
|
+ List<OrdersVo> allByPayAt = getAllByPayAt(orderInParameterTime);
|
|
|
+ if (allByPayAt == null || allByPayAt.isEmpty()) {
|
|
|
+ continue; // 如果没有订单,则跳过当前循环
|
|
|
+ }
|
|
|
+
|
|
|
BigDecimal amount = BigDecimal.ZERO;
|
|
|
- //线上支付总额 微信、支付宝等线上渠道
|
|
|
BigDecimal online_amount = BigDecimal.ZERO;
|
|
|
- //现金总收取 现金渠道
|
|
|
BigDecimal offline_amount = BigDecimal.ZERO;
|
|
|
- ordersStatementOfAccount.setPlatformSeparateRate(shopRate);
|
|
|
- //记录订单数量
|
|
|
- Integer countOrderSize=0;
|
|
|
- for (ShopPaymentRecord shopPaymentRecord : shopPaymentRecordList) {
|
|
|
- Orders orders = ordersMapper.selectById(shopPaymentRecord.getOrderId());
|
|
|
- //订单金额如果为0 表示这个订单已经退款完毕 收徒为0 不需要统计
|
|
|
- if (String.valueOf(orders.getPayFee()).equals("0.00")) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- countOrderSize++;
|
|
|
- if(!orders.getPayment().equals("free")){
|
|
|
- amount=amount.add(orders.getPayFee());
|
|
|
- }
|
|
|
- if(orders.getPayment().equals("cash")){
|
|
|
- offline_amount=offline_amount.add(shopPaymentRecord.getCash().subtract(shopPaymentRecord.getReturnCash()).subtract(shopPaymentRecord.getReturnOrigin()));
|
|
|
- }
|
|
|
- if(orders.getPayment().equals("weixin")){
|
|
|
- online_amount= online_amount.add(shopPaymentRecord.getWeixin().subtract(shopPaymentRecord.getReturnCash()).subtract(shopPaymentRecord.getReturnOrigin()));
|
|
|
- }
|
|
|
- if(orders.getPayment().equals("alipay")){
|
|
|
- online_amount= online_amount.add(shopPaymentRecord.getAlipay().subtract(shopPaymentRecord.getReturnCash()).subtract(shopPaymentRecord.getReturnOrigin()));
|
|
|
- }
|
|
|
- if(orders.getPayment().equals("YunShanFu")){
|
|
|
- online_amount=online_amount.add(shopPaymentRecord.getYunshanfu().subtract(shopPaymentRecord.getReturnCash()).subtract(shopPaymentRecord.getReturnOrigin()));
|
|
|
- }
|
|
|
- if(orders.getPayment().equals("membercard")){
|
|
|
- online_amount= online_amount.add(shopPaymentRecord.getMembercard().subtract(shopPaymentRecord.getReturnCash()).subtract(shopPaymentRecord.getReturnOrigin()));
|
|
|
- }
|
|
|
- if(orders.getPayment().equals("zjdcodecard")){
|
|
|
- online_amount= online_amount.add(shopPaymentRecord.getZjdcodecard().subtract(shopPaymentRecord.getReturnCash()).subtract(shopPaymentRecord.getReturnOrigin()));
|
|
|
- }
|
|
|
- if (orders.getPayment().equals("bank")) {
|
|
|
- online_amount= online_amount.add(shopPaymentRecord.getBank().subtract(shopPaymentRecord.getReturnCash()).subtract(shopPaymentRecord.getReturnOrigin()));
|
|
|
- }
|
|
|
- if(orders.getPayment().equals("mixed")){
|
|
|
- //获取第一次支付方式
|
|
|
- if (orders.getPayment1Name().equals("cash")&&!orders.getPayment2Name().equals("cash")) {
|
|
|
- offline_amount= offline_amount.add(orders.getPayment1Fee());
|
|
|
- online_amount= online_amount.add(orders.getPayment2Fee());
|
|
|
- }else if (orders.getPayment2Name().equals("cash")&&!orders.getPayment1Name().equals("cash")){ //第二次支付
|
|
|
- offline_amount= offline_amount.add(orders.getPayment2Fee());
|
|
|
- online_amount= online_amount.add(orders.getPayment1Fee());
|
|
|
- }else {
|
|
|
- online_amount= online_amount.add(orders.getPayment2Fee()).add(orders.getPayment1Fee());
|
|
|
- }
|
|
|
- }
|
|
|
- OrdersDTO ordersDTO=new OrdersDTO();
|
|
|
- ordersDTO.setOrderId(orders.getId());
|
|
|
- ordersDTO.setOrderCreateTime(orders.getCreateAt().getTime());
|
|
|
+ Integer countOrderSize = allByPayAt.size();
|
|
|
+ ArrayList<OrdersDTO> orderDetailList = new ArrayList<>();
|
|
|
+
|
|
|
+ for (OrdersVo ordersVo : allByPayAt) {
|
|
|
+ amount = amount.add(ordersVo.getPayAmount());
|
|
|
+ online_amount = online_amount.add(ordersVo.getPayWxFee().add(ordersVo.getPayAlipayFee()));
|
|
|
+
|
|
|
+ OrdersDTO ordersDTO = new OrdersDTO();
|
|
|
+ ordersDTO.setOrderId(ordersVo.getOrderId());
|
|
|
+ ordersDTO.setOrderCreateTime(Long.valueOf(ordersVo.getCreateTime()));
|
|
|
ordersDTO.setPlatformSeparateRate(shopRate);
|
|
|
- ordersDTO.setAmount(orders.getPayFee());
|
|
|
- //门店收入等于 订单总营业额 *费率 比如费率百分之6.8 则需要转换 成0.068
|
|
|
- ordersDTO.setShopIncome(new BigDecimal(1).subtract(shopRate.multiply(number)).multiply(orders.getPayFee()));
|
|
|
- ordersDTO.setPlatformIncome(orders.getPayFee().multiply(shopRate.multiply(number)));
|
|
|
- ordersDTOS.add(ordersDTO);
|
|
|
+ ordersDTO.setAmount(ordersVo.getPayAmount());
|
|
|
+ BigDecimal shopIncome =( new BigDecimal(1).subtract(shopRate)).multiply(ordersVo.getPayAmount());
|
|
|
+ BigDecimal platformIncome = ordersVo.getPayAmount().multiply(shopRate);
|
|
|
+ ordersDTO.setShopIncome(shopIncome);
|
|
|
+ ordersDTO.setPlatformIncome(platformIncome);
|
|
|
+ orderDetailList.add(ordersDTO);
|
|
|
}
|
|
|
+
|
|
|
+ offline_amount = amount.subtract(online_amount);
|
|
|
+
|
|
|
+
|
|
|
ordersStatementOfAccount.setStatisticsDate(day);
|
|
|
- ordersStatementOfAccount.setShopId(Shop.getId());
|
|
|
+ ordersStatementOfAccount.setShopId(shop.getId());
|
|
|
+ ordersStatementOfAccount.setPlatformSeparateRate(shopRate);
|
|
|
ordersStatementOfAccount.setOrderCount(countOrderSize);
|
|
|
ordersStatementOfAccount.setAmount(amount);
|
|
|
ordersStatementOfAccount.setOnlineAmount(online_amount);
|
|
|
ordersStatementOfAccount.setOfflineAmount(offline_amount);
|
|
|
- ordersStatementOfAccount.setOrderDetailList(ordersDTOS);
|
|
|
- ordersStatementOfAccount.setShopAmount(new BigDecimal(1).subtract(shopRate.multiply(number)).multiply(amount));
|
|
|
- ordersStatementOfAccount.setPlatformAmount(shopRate.multiply(number).multiply(amount));
|
|
|
+ MathContext mc = new MathContext(2, RoundingMode.DOWN);
|
|
|
+ BigDecimal shopAmount = (new BigDecimal(1).subtract(shopRate)).multiply(amount).setScale(mc.getPrecision(), mc.getRoundingMode());;
|
|
|
+ BigDecimal platformAmount = shopRate.multiply(amount).setScale(mc.getPrecision(), mc.getRoundingMode());;
|
|
|
+ ordersStatementOfAccount.setShopAmount(shopAmount);
|
|
|
+ ordersStatementOfAccount.setPlatformAmount(platformAmount);
|
|
|
ordersStatementOfAccounts.add(ordersStatementOfAccount);
|
|
|
+ ordersStatementOfAccount.setOrderDetailList(orderDetailList);
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
|
|
|
return ordersStatementOfAccounts;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据日期获取当天开始和结束的时间戳
|
|
|
+ * */
|
|
|
+ public static Map<String, Long> convertToTimestamps(String dateStr) {
|
|
|
+ SimpleDateFormat inputFormat = new SimpleDateFormat("yyyyMMdd");
|
|
|
+ inputFormat.setTimeZone(TimeZone.getTimeZone("UTC")); // Set to UTC if needed
|
|
|
+ Map<String, Long> timestampMap = new HashMap<>();
|
|
|
+ try {
|
|
|
+ Date date = inputFormat.parse(dateStr);
|
|
|
+
|
|
|
+ Calendar calendar = Calendar.getInstance();
|
|
|
+ calendar.setTime(date);
|
|
|
+
|
|
|
+ // Set day (00:00:00)
|
|
|
+ calendar.set(Calendar.HOUR_OF_DAY, 0);
|
|
|
+ calendar.set(Calendar.MINUTE, 0);
|
|
|
+ calendar.set(Calendar.SECOND, 0);
|
|
|
+ calendar.set(Calendar.MILLISECOND, 0);
|
|
|
+ Date startOfDay = calendar.getTime();
|
|
|
+
|
|
|
+ // Set day (23:59:59.999)
|
|
|
+ calendar.set(Calendar.HOUR_OF_DAY, 23);
|
|
|
+ calendar.set(Calendar.MINUTE, 59);
|
|
|
+ calendar.set(Calendar.SECOND, 59);
|
|
|
+ calendar.set(Calendar.MILLISECOND, 999);
|
|
|
+ Date endOfDay = calendar.getTime();
|
|
|
+
|
|
|
+
|
|
|
+ timestampMap.put("start", startOfDay.getTime());
|
|
|
+ timestampMap.put("end", endOfDay.getTime());
|
|
|
+
|
|
|
+ return timestampMap;
|
|
|
+
|
|
|
+ } catch (ParseException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ return new HashMap<>();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
public Orders getByIdOrder(String orderId){
|
|
|
return ordersMapper.selectById(orderId);
|
|
|
}
|
|
|
@@ -194,16 +251,55 @@ public class OrdersService {
|
|
|
}
|
|
|
|
|
|
static List<Shop> getShopList(OrderInParameter orderInParameter, ShopService shopService) {
|
|
|
- List<Shop> qgShopAll=new ArrayList<>();
|
|
|
+ List<Shop> qgShopAll = new ArrayList<>();
|
|
|
+
|
|
|
+ // 判断shopId是否为null,并做相应处理
|
|
|
if (orderInParameter.getShopId() == null) {
|
|
|
+ // 如果shopId为null,获取全部"qg"类型的商店列表
|
|
|
List<Shop> qgShop = shopService.getShopQgList("qg");
|
|
|
- qgShopAll.addAll(qgShop);
|
|
|
- }
|
|
|
- if (orderInParameter.getShopId()!= null) {
|
|
|
+ if (qgShop != null) {
|
|
|
+ qgShopAll.addAll(qgShop);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 如果shopId不为null,获取单个商店
|
|
|
Shop shopOne = shopService.getShopOne(orderInParameter.getShopId());
|
|
|
- qgShopAll.add(shopOne);
|
|
|
+ if (shopOne != null) {
|
|
|
+ qgShopAll.add(shopOne);
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
return qgShopAll;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算折扣后的价格
|
|
|
+ *
|
|
|
+ * @param originalPrice 原价,作为BigDecimal传入
|
|
|
+ * @param discountStr 折扣,作为字符串传入(可以是整数如"8"或小数如"8.00",表示80%的折扣保留,
|
|
|
+ * 即原价的80%被计算为折扣后价格;也可以是"9.5"或"9.50",表示95%的折扣保留)
|
|
|
+ * @return 折扣后的价格,作为BigDecimal返回,保留两位小数
|
|
|
+ * @throws IllegalArgumentException 如果折扣格式无效或不在0到100之间
|
|
|
+ */
|
|
|
+ public static BigDecimal calculateDiscountedPrice(BigDecimal originalPrice, String discountStr) {
|
|
|
+ // 尝试将折扣字符串转换为BigDecimal,允许小数点但不允许其他非数字字符(除了负号,但在这里我们不需要负号)
|
|
|
+ try {
|
|
|
+ BigDecimal discount = new BigDecimal(discountStr.replaceAll("[^0-9.]", "")); // 仅保留数字和小数点
|
|
|
+
|
|
|
+ // 验证折扣值在0到100之间(包含0和100,表示无折扣和全额折扣)
|
|
|
+ if (discount.compareTo(BigDecimal.ZERO) < 0 || discount.compareTo(new BigDecimal("100")) > 0) {
|
|
|
+ throw new IllegalArgumentException("折扣必须在0到100之间(包含0和100)");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将折扣百分比转换为折扣因子(例如,"8"或"8.00"都转换为0.8)
|
|
|
+ BigDecimal discountFactor = discount.divide(new BigDecimal(10), 2, RoundingMode.HALF_UP);
|
|
|
+
|
|
|
+ // 计算并返回折扣后的价格(即原价乘以折扣因子,结果保留两位小数)
|
|
|
+ return originalPrice.multiply(discountFactor).setScale(2, RoundingMode.HALF_UP);
|
|
|
+
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ // 如果转换失败(尽管上面的正则表达式应该已经避免了这种情况),则抛出异常
|
|
|
+ throw new IllegalArgumentException("折扣格式无效,必须是数字(可选包含小数点)", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|