|
|
|
@@ -4,6 +4,7 @@ import com.imyeyu.api.bean.ModuleCode;
|
|
|
|
|
import com.imyeyu.api.config.dbsource.TimiServerDBConfig;
|
|
|
|
|
import com.imyeyu.api.modules.common.entity.Attachment;
|
|
|
|
|
import com.imyeyu.api.modules.common.service.AttachmentService;
|
|
|
|
|
import com.imyeyu.api.modules.gao.bean.GaoPermissionCode;
|
|
|
|
|
import com.imyeyu.api.modules.gao.entity.GaoCustomer;
|
|
|
|
|
import com.imyeyu.api.modules.gao.entity.GaoCustomerPackage;
|
|
|
|
|
import com.imyeyu.api.modules.gao.entity.GaoPackageConfig;
|
|
|
|
@@ -44,6 +45,7 @@ import java.util.ArrayList;
|
|
|
|
|
import java.util.Comparator;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.HashSet;
|
|
|
|
|
import java.util.LinkedHashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.Set;
|
|
|
|
@@ -151,10 +153,13 @@ public class GaoCustomerPackageServiceImplement extends AbstractEntityService<Ga
|
|
|
|
|
request.setItemList(defaultPurchaseItems(configItemList));
|
|
|
|
|
}
|
|
|
|
|
List<GaoCustomerPackagePurchaseItem> requestItemList = new ArrayList<>(request.getItemList());
|
|
|
|
|
normalizePurchaseItems(requestItemList);
|
|
|
|
|
verifyPurchaseItems(requestItemList);
|
|
|
|
|
boolean canOverridePriceAndQuantity = permissionChecker.hasAny(ModuleCode.GAO,
|
|
|
|
|
com.imyeyu.api.modules.gao.bean.GaoPermissionCode.CUSTOMER_PACKAGE_PRICE_OVERRIDE.getValue());
|
|
|
|
|
List<GaoCustomerPackagePurchaseItem> itemList = resolvePurchaseItems(config.getStoreId(), requestItemList, configItemList, canOverridePriceAndQuantity);
|
|
|
|
|
GaoPermissionCode.CUSTOMER_PACKAGE_PRICE_OVERRIDE.getValue());
|
|
|
|
|
boolean canCreateGift = permissionChecker.hasAny(ModuleCode.GAO, GaoPermissionCode.CUSTOMER_PACKAGE_GIFT_CREATE.getValue());
|
|
|
|
|
List<GaoCustomerPackagePurchaseItem> itemList = resolvePurchaseItems(config.getStoreId(), requestItemList, configItemList,
|
|
|
|
|
canOverridePriceAndQuantity, canCreateGift);
|
|
|
|
|
itemList.sort(Comparator.comparing(GaoCustomerPackagePurchaseItem::getSort).thenComparing(GaoCustomerPackagePurchaseItem::getSkuId)
|
|
|
|
|
.thenComparing(GaoCustomerPackagePurchaseItem::getSkuUnitId));
|
|
|
|
|
request.setItemList(itemList);
|
|
|
|
@@ -246,6 +251,7 @@ public class GaoCustomerPackageServiceImplement extends AbstractEntityService<Ga
|
|
|
|
|
GaoCustomerPackagePurchaseItem item = new GaoCustomerPackagePurchaseItem();
|
|
|
|
|
item.setSkuId(configItem.getSkuId());
|
|
|
|
|
item.setSkuUnitId(configItem.getSkuUnitId());
|
|
|
|
|
item.setGifted(false);
|
|
|
|
|
item.setProductNameSnapshot(configItem.getProductNameSnapshot());
|
|
|
|
|
item.setProductIdSnapshot(configItem.getProductIdSnapshot());
|
|
|
|
|
item.setSkuCodeSnapshot(configItem.getSkuCodeSnapshot());
|
|
|
|
@@ -265,6 +271,7 @@ public class GaoCustomerPackageServiceImplement extends AbstractEntityService<Ga
|
|
|
|
|
item.setItemType(GaoSalesOrderItem.ItemType.PACKAGE_ENTITLEMENT);
|
|
|
|
|
item.setSkuId(source.getSkuId());
|
|
|
|
|
item.setSkuUnitId(source.getSkuUnitId());
|
|
|
|
|
item.setGifted(Boolean.TRUE.equals(source.getGifted()));
|
|
|
|
|
item.setProductNameSnapshot(source.getProductNameSnapshot());
|
|
|
|
|
item.setProductIdSnapshot(source.getProductIdSnapshot());
|
|
|
|
|
item.setSkuCodeSnapshot(source.getSkuCodeSnapshot());
|
|
|
|
@@ -284,6 +291,32 @@ public class GaoCustomerPackageServiceImplement extends AbstractEntityService<Ga
|
|
|
|
|
return item;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void normalizePurchaseItems(List<GaoCustomerPackagePurchaseItem> itemList) {
|
|
|
|
|
Map<String, Integer> indexMap = new LinkedHashMap<>();
|
|
|
|
|
for (int i = 0; i < itemList.size(); i++) {
|
|
|
|
|
GaoCustomerPackagePurchaseItem item = itemList.get(i);
|
|
|
|
|
if (item == null) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
item.setGifted(Boolean.TRUE.equals(item.getGifted()));
|
|
|
|
|
if (item.getSkuId() == null || item.getSkuUnitId() == null || item.getTotalQuantity() == null) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
String key = item.getSkuId() + "|" + item.getSkuUnitId() + "|" + item.getGifted();
|
|
|
|
|
Integer existingIndex = indexMap.putIfAbsent(key, i);
|
|
|
|
|
if (existingIndex == null) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
GaoCustomerPackagePurchaseItem existingItem = itemList.get(existingIndex);
|
|
|
|
|
if (existingItem == null || existingItem.getTotalQuantity() == null) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
existingItem.setTotalQuantity(existingItem.getTotalQuantity().add(item.getTotalQuantity()));
|
|
|
|
|
itemList.set(i, null);
|
|
|
|
|
}
|
|
|
|
|
itemList.removeIf(item -> item == null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void verifyPurchaseItems(List<GaoCustomerPackagePurchaseItem> itemList) {
|
|
|
|
|
Set<String> keySet = new HashSet<>();
|
|
|
|
|
for (int i = 0; i < itemList.size(); i++) {
|
|
|
|
@@ -294,14 +327,15 @@ public class GaoCustomerPackageServiceImplement extends AbstractEntityService<Ga
|
|
|
|
|
TimiException.required(item.getTotalQuantity(), "购买产品数量不能为空");
|
|
|
|
|
TimiException.requiredTrue(0 <= item.getTotalQuantity().signum(), "购买产品数量不能为负数");
|
|
|
|
|
TimiException.requiredTrue(3 >= item.getTotalQuantity().stripTrailingZeros().scale(), "购买产品数量最多保留三位小数");
|
|
|
|
|
String key = item.getSkuId() + "|" + item.getSkuUnitId();
|
|
|
|
|
item.setGifted(Boolean.TRUE.equals(item.getGifted()));
|
|
|
|
|
String key = item.getSkuId() + "|" + item.getSkuUnitId() + "|" + item.getGifted();
|
|
|
|
|
TimiException.requiredTrue(keySet.add(key), "购买套餐内 SKU 和单位不能重复");
|
|
|
|
|
item.setSort(TimiJava.defaultIfNull(item.getSort(), i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<GaoCustomerPackagePurchaseItem> resolvePurchaseItems(String storeId, List<GaoCustomerPackagePurchaseItem> requestItemList,
|
|
|
|
|
List<GaoPackageConfigItem> configItemList, boolean canOverridePriceAndQuantity) {
|
|
|
|
|
List<GaoPackageConfigItem> configItemList, boolean canOverridePriceAndQuantity, boolean canCreateGift) {
|
|
|
|
|
Map<String, List<GaoPackageConfigItem>> configItemMap = configItemList.stream()
|
|
|
|
|
.collect(Collectors.groupingBy(GaoPackageConfigItem::getSkuId));
|
|
|
|
|
Map<String, BigDecimal> configBaseQuantityMap = new HashMap<>();
|
|
|
|
@@ -312,23 +346,32 @@ public class GaoCustomerPackageServiceImplement extends AbstractEntityService<Ga
|
|
|
|
|
Map<String, BigDecimal> requestBaseQuantityMap = new HashMap<>();
|
|
|
|
|
List<GaoCustomerPackagePurchaseItem> result = new ArrayList<>();
|
|
|
|
|
for (GaoCustomerPackagePurchaseItem requestItem : requestItemList) {
|
|
|
|
|
boolean gifted = Boolean.TRUE.equals(requestItem.getGifted());
|
|
|
|
|
List<GaoPackageConfigItem> skuConfigItemList = configItemMap.get(requestItem.getSkuId());
|
|
|
|
|
if (gifted) {
|
|
|
|
|
TimiException.requiredTrue(canCreateGift, "没有客户套餐创建赠送权限");
|
|
|
|
|
} else {
|
|
|
|
|
TimiException.requiredTrue(skuConfigItemList != null && !skuConfigItemList.isEmpty(), "购买 SKU 不属于套餐配置");
|
|
|
|
|
}
|
|
|
|
|
GaoProductSkuUnitSelection selection = skuService.getSellableSkuUnit(storeId, requestItem.getSkuId(), requestItem.getSkuUnitId());
|
|
|
|
|
if (!gifted) {
|
|
|
|
|
TimiException.requiredTrue(skuConfigItemList.stream().anyMatch(configItem -> 0 <= configItem.getBaseQuantityPerUnitSnapshot()
|
|
|
|
|
.compareTo(selection.getUnit().getBaseQuantityPerUnit())), "套餐权益单位不能高于配置单位");
|
|
|
|
|
}
|
|
|
|
|
BigDecimal requestBaseQuantity = toBaseQuantity(requestItem.getTotalQuantity(), selection.getUnit().getBaseQuantityPerUnit(), "套餐权益基础数量最多保留三位小数");
|
|
|
|
|
if (!gifted) {
|
|
|
|
|
requestBaseQuantityMap.merge(requestItem.getSkuId(), requestBaseQuantity, BigDecimal::add);
|
|
|
|
|
}
|
|
|
|
|
if (requestItem.getTotalQuantity().signum() == 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (!Boolean.TRUE.equals(selection.getSku().getAllowDecimalQuantity())) {
|
|
|
|
|
TimiException.requiredTrue(requestItem.getTotalQuantity().stripTrailingZeros().scale() <= 0, "该 SKU 不允许小数数量");
|
|
|
|
|
}
|
|
|
|
|
GaoPackageConfigItem template = resolveItemTemplate(skuConfigItemList, selection.getUnit().getId());
|
|
|
|
|
GaoCustomerPackagePurchaseItem item = new GaoCustomerPackagePurchaseItem();
|
|
|
|
|
item.setSkuId(selection.getSku().getId());
|
|
|
|
|
item.setSkuUnitId(selection.getUnit().getId());
|
|
|
|
|
item.setGifted(gifted);
|
|
|
|
|
item.setProductNameSnapshot(selection.getProduct().getName());
|
|
|
|
|
item.setProductIdSnapshot(selection.getProduct().getId());
|
|
|
|
|
item.setSkuCodeSnapshot(selection.getSku().getCode());
|
|
|
|
@@ -337,8 +380,14 @@ public class GaoCustomerPackageServiceImplement extends AbstractEntityService<Ga
|
|
|
|
|
item.setUnitSnapshot(selection.getUnit().getName());
|
|
|
|
|
item.setBaseQuantityPerUnitSnapshot(selection.getUnit().getBaseQuantityPerUnit());
|
|
|
|
|
item.setTotalQuantity(requestItem.getTotalQuantity());
|
|
|
|
|
if (gifted) {
|
|
|
|
|
item.setSort(requestItem.getSort());
|
|
|
|
|
item.setRemark(requestItem.getRemark());
|
|
|
|
|
} else {
|
|
|
|
|
GaoPackageConfigItem template = resolveItemTemplate(skuConfigItemList, selection.getUnit().getId());
|
|
|
|
|
item.setSort(template.getSort());
|
|
|
|
|
item.setRemark(template.getRemark());
|
|
|
|
|
}
|
|
|
|
|
result.add(item);
|
|
|
|
|
}
|
|
|
|
|
TimiException.requiredTrue(!result.isEmpty(), "购买套餐至少需要一个产品");
|
|
|
|
@@ -378,9 +427,10 @@ public class GaoCustomerPackageServiceImplement extends AbstractEntityService<Ga
|
|
|
|
|
List<GaoCustomerPackagePurchaseItem> requestItemList = TimiJava.defaultIfNull(request.getItemList(), List.of());
|
|
|
|
|
verifyPurchaseItems(requestItemList);
|
|
|
|
|
TimiException.requiredTrue(existingItemList.size() == requestItemList.size(), "requestNo 对应购买请求内容不一致");
|
|
|
|
|
Map<String, GaoSalesOrderItem> existingItemMap = existingItemList.stream().collect(Collectors.toMap(item -> item.getSkuId() + "|" + item.getSkuUnitId(), Function.identity()));
|
|
|
|
|
Map<String, GaoSalesOrderItem> existingItemMap = existingItemList.stream().collect(Collectors.toMap(item -> item.getSkuId() + "|" + item.getSkuUnitId() + "|"
|
|
|
|
|
+ Boolean.TRUE.equals(item.getGifted()), Function.identity()));
|
|
|
|
|
for (GaoCustomerPackagePurchaseItem item : requestItemList) {
|
|
|
|
|
GaoSalesOrderItem existingItem = existingItemMap.get(item.getSkuId() + "|" + item.getSkuUnitId());
|
|
|
|
|
GaoSalesOrderItem existingItem = existingItemMap.get(item.getSkuId() + "|" + item.getSkuUnitId() + "|" + Boolean.TRUE.equals(item.getGifted()));
|
|
|
|
|
TimiException.required(existingItem, "requestNo 对应购买请求内容不一致");
|
|
|
|
|
TimiException.requiredTrue(existingItem.getItemType() == GaoSalesOrderItem.ItemType.PACKAGE_ENTITLEMENT
|
|
|
|
|
&& existingItem.getQuantity().compareTo(item.getTotalQuantity()) == 0
|
|
|
|
|