mirror of https://github.com/jeecgboot/jeecg-boot
feature : (WIP) Expenses Overview + LogisticChannelChoice job
parent
cff04fe906
commit
9d765591a9
|
@ -0,0 +1,54 @@
|
|||
CREATE VIEW transaction as
|
||||
SELECT id, create_by, create_time, update_by, update_time,
|
||||
type, client_id, payment_proof, invoice_number, shipping_fee, purchase_fee, amount, currency
|
||||
FROM
|
||||
(
|
||||
SELECT id as id,
|
||||
create_by,
|
||||
create_time,
|
||||
update_by,
|
||||
update_time,
|
||||
'Credit' as type,
|
||||
client_id,
|
||||
payment_proof,
|
||||
NULL as invoice_number,
|
||||
NULL as shipping_fee,
|
||||
NULL as purchase_fee,
|
||||
amount as amount,
|
||||
(SELECT code FROM currency WHERE credit.currency_id = id) as currency
|
||||
FROM credit
|
||||
UNION ALL
|
||||
SELECT id as id,
|
||||
create_by,
|
||||
create_time,
|
||||
update_by,
|
||||
update_time,
|
||||
'Debit' as type,
|
||||
client_id,
|
||||
NULL as payment_proof,
|
||||
invoice_number,
|
||||
total_amount as shipping_fee,
|
||||
IF(invoice_number LIKE '%%%%-%%-7%%%',
|
||||
purchase_total(invoice_number),
|
||||
NULL) as purchase_fee,
|
||||
IF(invoice_number LIKE '%%%%-%%-7%%%',
|
||||
total_amount + (purchase_total(invoice_number)),
|
||||
total_amount) as amount,
|
||||
(SELECT code FROM currency WHERE shipping_invoice.currency_id = id) as currency
|
||||
FROM shipping_invoice
|
||||
WHERE client_id IS NOT NULL
|
||||
AND shipping_invoice.currency_id IS NOT NULL
|
||||
AND shipping_invoice.currency_id <> ''
|
||||
) as id;
|
||||
|
||||
-- Function that computes the total of purchase by order
|
||||
CREATE FUNCTION purchase_total( invoice_number varchar(12)) RETURNS decimal(10, 2)
|
||||
BEGIN
|
||||
RETURN (
|
||||
SELECT SUM(poc.purchase_fee) as total
|
||||
FROM platform_order_content as poc
|
||||
JOIN platform_order po
|
||||
ON po.id = poc.platform_order_id
|
||||
WHERE po.shipping_invoice_number = invoice_number
|
||||
);
|
||||
END;
|
|
@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -35,31 +36,35 @@ public class UserClientController {
|
|||
private IShopService shopService;
|
||||
@Autowired
|
||||
private IPlatformOrderService platformOrderService;
|
||||
|
||||
/**
|
||||
* Checks if the user is a client and then lists orders of erp_status 1
|
||||
* @return
|
||||
* Checks if the user is a client or internal user
|
||||
* @return the client's info OR a list of clients
|
||||
*/
|
||||
@GetMapping(value = "/getClient")
|
||||
public Result<?> getClientByUserId() {
|
||||
LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
String userId = loginUser.getId();
|
||||
userId = "1698676211346821122";
|
||||
userId = "1708866308713140225";
|
||||
Client client = userClientService.getClientByUserId(userId);
|
||||
if(client == null) {
|
||||
List<SysRole> sysRoles = sysUserRoleService.getUserRole(userId);
|
||||
boolean isAllowed = false;
|
||||
for(SysRole sysRole: sysRoles) {
|
||||
if(sysRole.getRoleCode().equals("admin") || sysRole.getRoleCode().equals("dev")) {
|
||||
if(sysRole.getRoleCode().equals("admin") || sysRole.getRoleCode().equals("dev") || sysRole.getRoleCode().equals("Sales")){
|
||||
isAllowed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(isAllowed)
|
||||
return Result.OK("Permission Granted", "admin");
|
||||
if(isAllowed) {
|
||||
Map<String, List<Client>> internalClientList = new HashMap<>();
|
||||
internalClientList.put("internal", userClientService.listClients());
|
||||
return Result.OK("internal usage", internalClientList);
|
||||
}
|
||||
else
|
||||
return Result.error(403, "Access Denied.");
|
||||
}
|
||||
return Result.ok(client);
|
||||
Map<String, Client> clientMap = new HashMap<>();
|
||||
clientMap.put("client", client);
|
||||
return Result.ok(clientMap);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,11 @@ import lombok.extern.slf4j.Slf4j;
|
|||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.modules.business.domain.shippingInvoice.ShippingInvoiceFactory;
|
||||
import org.jeecg.modules.business.entity.PlatformOrder;
|
||||
import org.jeecg.modules.business.entity.PlatformOrderContent;
|
||||
import org.jeecg.modules.business.entity.SkuPrice;
|
||||
import org.jeecg.modules.business.mapper.*;
|
||||
import org.jeecg.modules.business.service.*;
|
||||
import org.jeecg.modules.business.vo.Estimation;
|
||||
import org.jeecg.modules.business.vo.ShippingFeesEstimation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
@ -14,9 +17,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Api(tags = "Transaction")
|
||||
|
@ -35,6 +38,8 @@ public class TransactionController {
|
|||
@Autowired
|
||||
PlatformOrderMapper platformOrderMapper;
|
||||
@Autowired
|
||||
PlatformOrderContentMapper platformOrderContentMapper;
|
||||
@Autowired
|
||||
ClientMapper clientMapper;
|
||||
@Autowired
|
||||
ShopMapper shopMapper;
|
||||
|
@ -66,12 +71,12 @@ public class TransactionController {
|
|||
public Result<?> list() {
|
||||
return Result.ok(transactionMapper.list());
|
||||
}
|
||||
@GetMapping(value="/listByClient")
|
||||
public Result<?> listByClientId(@RequestParam("clientId") String clientId) {
|
||||
return Result.ok(transactionMapper.listByClientId(clientId));
|
||||
@GetMapping(value="/listByClientAndCurrency")
|
||||
public Result<?> listByClientId(@RequestParam("clientId") String clientId, @RequestParam("currency") String currency) {
|
||||
return Result.ok(transactionMapper.listByClientIdAndCurrency(clientId, currency));
|
||||
}
|
||||
@GetMapping(value="/debit")
|
||||
public Result<?> debit(@RequestParam("clientId") String clientId) {
|
||||
public Result<?> debit(@RequestParam("clientId") String clientId, @RequestParam("currency") String currency) {
|
||||
List<String> errorMessages = new ArrayList<>();
|
||||
List<String> shopIds = shopService.listIdByClient(clientId);
|
||||
List<PlatformOrder> orders = platformOrderService.findUninvoicedOrdersByShopForClient(shopIds, Arrays.asList(1,2,3));
|
||||
|
@ -82,11 +87,43 @@ public class TransactionController {
|
|||
platformOrderService, clientMapper, shopMapper, logisticChannelMapper, logisticChannelPriceMapper,
|
||||
platformOrderContentService, skuDeclaredValueService, countryService, exchangeRatesMapper,
|
||||
purchaseOrderService, purchaseOrderContentMapper, skuPromotionHistoryMapper, savRefundService, savRefundWithDetailService);
|
||||
List<ShippingFeesEstimation> estimations = factory.getEstimations(clientId, orderIds, errorMessages);
|
||||
System.out.println("Estimation size : " + estimations.size());
|
||||
for(ShippingFeesEstimation estimation: estimations) {
|
||||
List<ShippingFeesEstimation> shippingFeesEstimations = factory.getEstimations(clientId, orderIds, errorMessages);
|
||||
System.out.println("Estimation size : " + shippingFeesEstimations.size());
|
||||
for(ShippingFeesEstimation estimation: shippingFeesEstimations) {
|
||||
System.out.println("estimation : " + estimation.getDueForProcessedOrders());
|
||||
}
|
||||
return Result.ok(estimations);
|
||||
// purchase estimation
|
||||
List<String> estimationOrderIds = new ArrayList<>();
|
||||
BigDecimal shippingFeesEstimation = BigDecimal.ZERO;
|
||||
for(ShippingFeesEstimation estimation: shippingFeesEstimations) {
|
||||
estimationOrderIds.addAll(estimation.getOrderIds());
|
||||
shippingFeesEstimation = shippingFeesEstimation.add(estimation.getDueForProcessedOrders());
|
||||
}
|
||||
System.out.println("Estimation order ids : " + estimationOrderIds);
|
||||
List<PlatformOrderContent> orderContents = platformOrderContentMapper.fetchOrderContent(estimationOrderIds);
|
||||
List<String> skuIds = orderContents.stream().map(PlatformOrderContent::getSkuId).collect(Collectors.toList());
|
||||
List<SkuPrice> skuPrices = platformOrderContentMapper.searchSkuPrice(skuIds);
|
||||
BigDecimal exchangeRateEurToRmb = exchangeRatesMapper.getLatestExchangeRate("EUR", "RMB");
|
||||
BigDecimal purchaseEstimation = BigDecimal.ZERO;
|
||||
for(PlatformOrderContent content : orderContents){
|
||||
for (SkuPrice skuPrice : skuPrices) {
|
||||
if(content.getSkuId().equals(skuPrice.getSkuId())) {
|
||||
purchaseEstimation = purchaseEstimation.add(skuPrice.getPrice(content.getQuantity(), exchangeRateEurToRmb));
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!currency.equals("EUR")) {
|
||||
BigDecimal exchangeRate = exchangeRatesMapper.getLatestExchangeRate("EUR", currency);
|
||||
System.out.println("Exchange rate : " + exchangeRate);
|
||||
System.out.println("Purchase Fee : " + purchaseEstimation);
|
||||
System.out.println("Shipping Fee : " + shippingFeesEstimation);
|
||||
|
||||
purchaseEstimation = purchaseEstimation.multiply(exchangeRate).setScale(2, RoundingMode.CEILING);
|
||||
shippingFeesEstimation = shippingFeesEstimation.multiply(exchangeRate).setScale(2, RoundingMode.CEILING);
|
||||
|
||||
System.out.println("Purchase Fee " + currency + " : " + purchaseEstimation);
|
||||
System.out.println("Shipping Fee " + currency + " : " + shippingFeesEstimation);
|
||||
}
|
||||
return Result.ok(new Estimation(shippingFeesEstimation, purchaseEstimation, currency, errorMessages));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,314 @@
|
|||
package org.jeecg.modules.business.domain.job;
|
||||
|
||||
import freemarker.template.Template;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.codehaus.jettison.json.JSONException;
|
||||
import org.codehaus.jettison.json.JSONObject;
|
||||
import org.jeecg.modules.business.entity.*;
|
||||
import org.jeecg.modules.business.mapper.PlatformOrderContentMapper;
|
||||
import org.jeecg.modules.business.service.*;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobDataMap;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
|
||||
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
|
||||
|
||||
import javax.mail.Authenticator;
|
||||
import javax.mail.PasswordAuthentication;
|
||||
import javax.mail.Session;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
/**
|
||||
* @Description: A job that fills all 'invoice_logistic_channel_name' field with 'NULL' value with a default channel
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2023-10-03
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class LogisticChannelChoiceJob implements Job {
|
||||
@Autowired
|
||||
private CountryService countryService;
|
||||
@Autowired
|
||||
private EmailService emailService;
|
||||
@Autowired
|
||||
private ILogisticChannelChoiceService logisticChannelChoiceService;
|
||||
@Autowired
|
||||
private ILogisticChannelService logisticChannelService;
|
||||
@Autowired
|
||||
private IPlatformOrderService platformOrderService;
|
||||
@Autowired
|
||||
private IPlatformOrderContentService platformOrderContentService;
|
||||
@Autowired
|
||||
private ISensitiveAttributeService sensitiveAttributeService;
|
||||
@Autowired
|
||||
private PlatformOrderContentMapper platformOrderContentMapper;
|
||||
@Autowired
|
||||
Environment env;
|
||||
@Autowired
|
||||
private FreeMarkerConfigurer freemarkerConfigurer;
|
||||
private static final Integer DEFAULT_NUMBER_OF_DAYS = 180;
|
||||
@Override
|
||||
public void execute(JobExecutionContext context) throws JobExecutionException {
|
||||
LocalDate endDate = LocalDate.now(ZoneId.of(ZoneId.SHORT_IDS.get("CTT")));
|
||||
LocalDate startDate = LocalDate.now(ZoneId.of(ZoneId.SHORT_IDS.get("CTT"))).minusDays(DEFAULT_NUMBER_OF_DAYS);
|
||||
JobDataMap jobDataMap = context.getMergedJobDataMap();
|
||||
String parameter = ((String) jobDataMap.get("parameter"));
|
||||
if (parameter != null) {
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(parameter);
|
||||
if (!jsonObject.isNull("startDate")) {
|
||||
String startDateStr = jsonObject.getString("startDate");
|
||||
startDate = LocalDate.parse(startDateStr);
|
||||
}
|
||||
if (!jsonObject.isNull("endDate")) {
|
||||
String endDateStr = jsonObject.getString("endDate");
|
||||
endDate = LocalDate.parse(endDateStr);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Error while parsing parameter as JSON, falling back to default parameters.");
|
||||
}
|
||||
}
|
||||
if(!endDate.isAfter(startDate))
|
||||
throw new RuntimeException("EndDate must be strictly greater than StartDate !");
|
||||
|
||||
// 1 : on doit collecter les commandes entres les 2 dates qui n'ont ni logistic_channel_name, ni invoice_logistic_channel_name
|
||||
// 2 : on doit ensuite déterminer quelle ligne utilisée
|
||||
// 2.1 : on doit déterminer quel est le sensitive_attribute avec la priorité la plus elevée dans la commande
|
||||
// 2.2 : on cherche ensuite la ligne par défaut pour le shop, le pays et l'attribut
|
||||
// 3 : on rempli le champs invoice_logistic_channel_name dans la commande
|
||||
|
||||
// commandes sans logistic channel
|
||||
List<PlatformOrder> platformOrders = platformOrderService.fetchEmptyLogisticChannelOrders(startDate.toString(), endDate.toString());
|
||||
log.info("Filling default invoice logistic channel name between ["+startDate+" and "+endDate+"]");
|
||||
if(!platformOrders.isEmpty()) {
|
||||
log.info("Number of orders to process: "+platformOrders.size());
|
||||
List<String> orderIds = platformOrders.stream().map(PlatformOrder::getId).collect(Collectors.toList());
|
||||
Map<String, List<PlatformOrder>> orderMapByAttribute = new HashMap<>();
|
||||
List<PlatformOrder> tempPlatformOrders = new ArrayList<>(platformOrders);
|
||||
for(String orderId: orderIds) {
|
||||
String attributeId = sensitiveAttributeService.getHighestPriorityAttributeId(orderId);
|
||||
PlatformOrder orderToAdd = tempPlatformOrders.stream().filter
|
||||
(
|
||||
order -> order.getId().equals(orderId))
|
||||
.findAny()
|
||||
.orElse(null
|
||||
);
|
||||
if(!orderMapByAttribute.containsKey(attributeId)){
|
||||
orderMapByAttribute.put(attributeId, new ArrayList<>());
|
||||
orderMapByAttribute.get(attributeId).add(orderToAdd);
|
||||
}
|
||||
else {
|
||||
orderMapByAttribute.get(attributeId).add(orderToAdd);
|
||||
}
|
||||
tempPlatformOrders.remove(orderToAdd);
|
||||
}
|
||||
System.out.println("Attributes in orders : ");
|
||||
for(Map.Entry<String, List<PlatformOrder>> entry : orderMapByAttribute.entrySet()) {
|
||||
System.out.println("attribute : " + entry.getKey());
|
||||
if(entry.getKey() != null) {
|
||||
for(PlatformOrder order : entry.getValue()) {
|
||||
System.out.println(order.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
System.gc();
|
||||
Map<String, Map<String, List<PlatformOrder>>> orderMapByShopAndCountry = new HashMap<>();
|
||||
for (PlatformOrder platformOrder : platformOrders) {
|
||||
if (orderMapByShopAndCountry.containsKey(platformOrder.getShopId())) {
|
||||
if (orderMapByShopAndCountry.get(platformOrder.getShopId()).containsKey(platformOrder.getCountry())) {
|
||||
orderMapByShopAndCountry.get(platformOrder.getShopId()).get(platformOrder.getCountry()).add(platformOrder);
|
||||
} else {
|
||||
orderMapByShopAndCountry.get(platformOrder.getShopId()).put(platformOrder.getCountry(), new ArrayList<>());
|
||||
orderMapByShopAndCountry.get(platformOrder.getShopId()).get(platformOrder.getCountry()).add(platformOrder);
|
||||
}
|
||||
} else {
|
||||
orderMapByShopAndCountry.put(platformOrder.getShopId(), new HashMap<>());
|
||||
orderMapByShopAndCountry.get(platformOrder.getShopId()).put(platformOrder.getCountry(), new ArrayList<>());
|
||||
orderMapByShopAndCountry.get(platformOrder.getShopId()).get(platformOrder.getCountry()).add(platformOrder);
|
||||
}
|
||||
}
|
||||
System.gc();
|
||||
List<String> countries = platformOrders.stream().map(PlatformOrder::getCountry).distinct().collect(Collectors.toList());
|
||||
|
||||
List<Country> countryList = countryService.findIdByEnName(countries);
|
||||
Map<String, String> countryNameToIdMap = countryList.stream().collect(toMap(Country::getNameEn, Country::getId));
|
||||
|
||||
Map<String, String> logisticChannelIdToNameMap = logisticChannelService.listByIdAndZhName().stream().collect(toMap(LogisticChannel::getId, LogisticChannel::getZhName));
|
||||
|
||||
Map<String, Integer> attributeIdToPriorityMap = sensitiveAttributeService.listIdAndPriority().stream().collect(toMap(SensitiveAttribute::getId, SensitiveAttribute::getPriority));
|
||||
Map<String, Integer> sortedAttributeIdToPriorityMap = attributeIdToPriorityMap.entrySet()
|
||||
.stream()
|
||||
.sorted(Map.Entry.comparingByValue())
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
Map.Entry::getValue,
|
||||
(oldValue, newValue) -> oldValue, LinkedHashMap::new
|
||||
));
|
||||
ListIterator<Map.Entry<String, Integer>> attributeMapIterator = new LinkedList(sortedAttributeIdToPriorityMap.entrySet()).listIterator();
|
||||
|
||||
List<LogisticChannelChoice> logisticChannelChoiceList = logisticChannelChoiceService.fetchByShopId(platformOrders.stream().map(PlatformOrder::getShopId).collect(Collectors.toList()));
|
||||
|
||||
List<PlatformOrder> ordersToUpdate = new ArrayList<>();
|
||||
List<String> logisticChoiceErrorList = new ArrayList<>();
|
||||
for( Map.Entry<String, Map<String, List<PlatformOrder>>> entry: orderMapByShopAndCountry.entrySet()) {
|
||||
String shopId = entry.getKey();
|
||||
System.out.println("\nShop => " + shopId);
|
||||
Map<String, List<PlatformOrder>> orderMapByCountry = entry.getValue();
|
||||
for(Map.Entry<String, List<PlatformOrder>> countryMapEntry: orderMapByCountry.entrySet()) {
|
||||
String countryName = countryMapEntry.getKey();
|
||||
List<PlatformOrder> orders = countryMapEntry.getValue();
|
||||
System.out.println("---- Country : " + countryName + ", Order number : " + orders.size());
|
||||
for(PlatformOrder order: orders) {
|
||||
// reset iterator
|
||||
attributeMapIterator = new LinkedList(sortedAttributeIdToPriorityMap.entrySet()).listIterator();
|
||||
// for(Map.Entry<String, Integer> attributeEntry: sortedAttributeIdToPriorityMap.entrySet()) {
|
||||
String orderAttributeId = sensitiveAttributeService.getHighestPriorityAttributeId(order.getId());
|
||||
Integer orderAttributePriority = sortedAttributeIdToPriorityMap.get(orderAttributeId);
|
||||
if(orderMapByAttribute.get(orderAttributeId) == null || orderAttributeId == null) {
|
||||
continue;
|
||||
}
|
||||
List<LogisticChannelChoice> choices = logisticChannelChoiceList.stream().filter(
|
||||
c -> c.getShopId().equals(shopId) && c.getCountryId().equals(countryNameToIdMap.get(countryName)) && c.getSensitiveAttributeId().equals(orderAttributeId))
|
||||
.collect(Collectors.toList());
|
||||
if(choices.isEmpty()) {
|
||||
while(attributeMapIterator.hasNext()) {
|
||||
if(attributeMapIterator.next().getKey().equals(orderAttributeId)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// on cherche la ligne avec une priorité plus élevée
|
||||
if(attributeMapIterator.hasNext()) {
|
||||
LogisticChannelChoice choice = getHigherLogisticChannelChoice(shopId, countryName, orderAttributePriority, logisticChannelChoiceList, attributeMapIterator, countryNameToIdMap);
|
||||
if(choice != null){
|
||||
PlatformOrder orderToAdd = new PlatformOrder();
|
||||
orderToAdd.setId(order.getId());
|
||||
orderToAdd.setInvoiceLogisticChannelName(logisticChannelIdToNameMap.get(choice.getLogisticChannelId()));
|
||||
ordersToUpdate.add(orderToAdd);
|
||||
System.out.println("La ligne " + choice.getLogisticChannelId() + " a été attribué à commande : " + order.getId());
|
||||
break;
|
||||
}
|
||||
//reset search to prepare for lower priority search
|
||||
attributeMapIterator = new LinkedList(sortedAttributeIdToPriorityMap.entrySet()).listIterator();
|
||||
while(attributeMapIterator.hasNext()) {
|
||||
if(attributeMapIterator.next().getKey().equals(orderAttributeId)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// on se rabat sur une ligne avec une priorité plus faible
|
||||
if(attributeMapIterator.hasPrevious()){
|
||||
LogisticChannelChoice choice = getLowerLogisticChannelChoice(shopId, countryName, orderAttributePriority, logisticChannelChoiceList, attributeMapIterator, countryNameToIdMap);
|
||||
if(choice != null){
|
||||
PlatformOrder orderToAdd = new PlatformOrder();
|
||||
orderToAdd.setId(order.getId());
|
||||
orderToAdd.setInvoiceLogisticChannelName(logisticChannelIdToNameMap.get(choice.getLogisticChannelId()));
|
||||
System.out.println("La ligne " + choice.getLogisticChannelId() + " a été attribué à commande : " + order.getId());
|
||||
ordersToUpdate.add(orderToAdd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// throw new JobExecutionException("No logistic channel choice found for shop : " + shopId + ", country : " + countryName + ", attribute : " + orderAttributeId);
|
||||
//Send email to admin
|
||||
log.info("No logistic channel choice found for shop : " + shopId + ", country : " + countryName + ", attribute : " + orderAttributeId);
|
||||
logisticChoiceErrorList.add("No logistic channel choice found for shop : " + shopId + ", country : " + countryName + ", attribute : " + orderAttributeId);
|
||||
}
|
||||
else {
|
||||
System.out.println("Trouvé");
|
||||
PlatformOrder orderToAdd = new PlatformOrder();
|
||||
orderToAdd.setId(order.getId());
|
||||
orderToAdd.setInvoiceLogisticChannelName(logisticChannelIdToNameMap.get(choices.get(0).getLogisticChannelId()));
|
||||
ordersToUpdate.add(orderToAdd);
|
||||
System.out.println("La ligne " + choices.get(0).getLogisticChannelId() + " a été attribué à commande : " + order.getId());
|
||||
continue;
|
||||
}
|
||||
} // end for orders
|
||||
} // end for in orderMapByCountry
|
||||
} // end for orderMapByShopAndCountry
|
||||
System.out.println("Orders to Update => ");
|
||||
for(PlatformOrder order : ordersToUpdate) {
|
||||
System.out.println(order.getId());
|
||||
}
|
||||
platformOrderService.updateBatchById(ordersToUpdate);
|
||||
if(!logisticChoiceErrorList.isEmpty()) {
|
||||
String subject = "Invoice logistic channel choice error";
|
||||
String destEmail = env.getProperty("spring.mail.username");
|
||||
Properties prop = emailService.getMailSender();
|
||||
Map<String, Object> templateModel = new HashMap<>();
|
||||
templateModel.put("errors", logisticChoiceErrorList);
|
||||
|
||||
Session session = Session.getInstance(prop, new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(env.getProperty("spring.mail.username"), env.getProperty("spring.mail.password"));
|
||||
}
|
||||
});
|
||||
try {
|
||||
freemarkerConfigurer = emailService.freemarkerClassLoaderConfig();
|
||||
Template freemarkerTemplate = freemarkerConfigurer.getConfiguration()
|
||||
.getTemplate("logisticChannelChoiceError.ftl");
|
||||
String htmlBody = FreeMarkerTemplateUtils.processTemplateIntoString(freemarkerTemplate, templateModel);
|
||||
emailService.sendSimpleMessage(destEmail, subject, htmlBody, session);
|
||||
log.info("Mail sent successfully");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private LogisticChannelChoice getHigherLogisticChannelChoice(String shopId, String countryName, Integer priority,
|
||||
List<LogisticChannelChoice> logisticChannelChoiceList, ListIterator<Map.Entry<String, Integer>> attributeMapIterator,
|
||||
Map<String, String> countryNameToIdMap) throws JobExecutionException {
|
||||
System.out.println("On se rabat sur une priorité plus élevée");
|
||||
Map.Entry<String, Integer> nextEntry = attributeMapIterator.next();
|
||||
System.out.println(nextEntry.getValue() + " ? " + priority);
|
||||
System.out.println(nextEntry.getKey());
|
||||
List<LogisticChannelChoice> logisticChannelChoices;
|
||||
LogisticChannelChoice logisticChannelChoice;
|
||||
if(nextEntry.getValue() > priority) {
|
||||
priority = nextEntry.getValue();
|
||||
String attributeId = nextEntry.getKey();
|
||||
logisticChannelChoices = logisticChannelChoiceList.stream().filter(choice -> choice.getShopId().equals(shopId) && choice.getCountryId().equals(countryNameToIdMap.get(countryName)) && choice.getSensitiveAttributeId().equals(attributeId)).collect(Collectors.toList());
|
||||
logisticChannelChoice = logisticChannelChoices.isEmpty() ? null : logisticChannelChoices.get(0);
|
||||
while(logisticChannelChoice == null && attributeMapIterator.hasNext()) {
|
||||
logisticChannelChoice = getHigherLogisticChannelChoice(shopId, countryName, priority, logisticChannelChoiceList, attributeMapIterator, countryNameToIdMap);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new JobExecutionException("Sort error");
|
||||
}
|
||||
return logisticChannelChoice;
|
||||
}
|
||||
private LogisticChannelChoice getLowerLogisticChannelChoice(String shopId, String countryName, Integer priority,
|
||||
List<LogisticChannelChoice> logisticChannelChoiceList, ListIterator<Map.Entry<String, Integer>> attributeMapIterator,
|
||||
Map<String, String> countryNameToIdMap) throws JobExecutionException {
|
||||
System.out.println("On se rabat sur une priorité plus faible");
|
||||
Map.Entry<String, Integer> previousEntry = attributeMapIterator.previous();
|
||||
System.out.println(previousEntry.getValue() + " ? " + priority);
|
||||
System.out.println(previousEntry.getKey());
|
||||
List<LogisticChannelChoice> logisticChannelChoices;
|
||||
LogisticChannelChoice logisticChannelChoice;
|
||||
if(previousEntry.getValue() <= priority) {
|
||||
priority = previousEntry.getValue();
|
||||
String attributeId = previousEntry.getKey();
|
||||
logisticChannelChoices = logisticChannelChoiceList.stream().filter(choice -> choice.getShopId().equals(shopId) && choice.getCountryId().equals(countryNameToIdMap.get(countryName)) && choice.getSensitiveAttributeId().equals(attributeId)).collect(Collectors.toList());
|
||||
logisticChannelChoice = logisticChannelChoices.isEmpty() ? null : logisticChannelChoices.get(0);
|
||||
while(logisticChannelChoice == null && attributeMapIterator.hasPrevious()) {
|
||||
logisticChannelChoice = getLowerLogisticChannelChoice(shopId, countryName, priority, logisticChannelChoiceList, attributeMapIterator, countryNameToIdMap);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new JobExecutionException("Sort error");
|
||||
}
|
||||
return logisticChannelChoice;
|
||||
}
|
||||
}
|
|
@ -66,6 +66,7 @@ public class ShippingInvoice extends AbstractInvoice<String, Object, Integer, Ob
|
|||
BigDecimal countryPickingFeesPerSKU = BigDecimal.ZERO;
|
||||
BigDecimal countryPackageMatFeePerOrder = BigDecimal.ZERO;
|
||||
for (PlatformOrder po : orders) {
|
||||
System.out.println(po.getId());
|
||||
countryFretFees = countryFretFees.add(po.getFretFee());
|
||||
countryServiceFeesPerOrder = countryServiceFeesPerOrder.add(po.getOrderServiceFee());
|
||||
countryPickingFeesPerOrder = countryPickingFeesPerOrder.add(po.getPickingFee());
|
||||
|
|
|
@ -484,7 +484,7 @@ public class ShippingInvoiceFactory {
|
|||
}
|
||||
}
|
||||
|
||||
private void calculateFees(Map<String, LogisticChannel> logisticChannelMap, Map<PlatformOrder, List<PlatformOrderContent>> orderAndContent,
|
||||
private Map<String, List<String>> calculateFees(Map<String, LogisticChannel> logisticChannelMap, Map<PlatformOrder, List<PlatformOrderContent>> orderAndContent,
|
||||
Map<LogisticChannel, List<LogisticChannelPrice>> channelPriceMap,
|
||||
List<Country> countryList,
|
||||
Map<String, BigDecimal> skuRealWeights,
|
||||
|
@ -495,10 +495,11 @@ public class ShippingInvoiceFactory {
|
|||
Map<String, BigDecimal> shopPackageMatFeeMap,
|
||||
String invoiceCode
|
||||
) throws UserException {
|
||||
Map<String, List<String>> platformOrderIdsWithPb = new HashMap<>();
|
||||
// find logistic channel price for each order based on its content
|
||||
for (PlatformOrder uninvoicedOrder : orderAndContent.keySet()) {
|
||||
List<PlatformOrderContent> contents = orderAndContent.get(uninvoicedOrder);
|
||||
if (contents.size() == 0) {
|
||||
if (contents.isEmpty()) {
|
||||
throw new UserException("Order: {} doesn't have content", uninvoicedOrder.getPlatformOrderId());
|
||||
}
|
||||
log.info("Calculating price for {} of order {}", contents, uninvoicedOrder);
|
||||
|
@ -513,12 +514,24 @@ public class ShippingInvoiceFactory {
|
|||
}
|
||||
|
||||
// calculate weight of an order
|
||||
BigDecimal contentWeight = platformOrderContentService.calculateWeight(
|
||||
Pair<BigDecimal, List<String>> contentWeightResult = platformOrderContentService.calculateWeight(
|
||||
contentMap,
|
||||
skuRealWeights
|
||||
);
|
||||
Pair<LogisticChannel, LogisticChannelPrice> logisticChannelPair = findAppropriatePrice(countryList, logisticChannelMap,
|
||||
channelPriceMap, uninvoicedOrder, contentWeight);
|
||||
if(!contentWeightResult.getValue().isEmpty()) {
|
||||
platformOrderIdsWithPb.put(uninvoicedOrder.getPlatformOrderId(), contentWeightResult.getValue());
|
||||
continue;
|
||||
}
|
||||
BigDecimal contentWeight = contentWeightResult.getKey();
|
||||
Pair<LogisticChannel, LogisticChannelPrice> logisticChannelPair;
|
||||
try {
|
||||
logisticChannelPair = findAppropriatePrice(countryList, logisticChannelMap,
|
||||
channelPriceMap, uninvoicedOrder, contentWeight);
|
||||
}
|
||||
catch (UserException e) {
|
||||
platformOrderIdsWithPb.put(uninvoicedOrder.getPlatformOrderId(), Collections.singletonList(e.getMessage()));
|
||||
continue;
|
||||
}
|
||||
LogisticChannelPrice price = logisticChannelPair.getRight();
|
||||
// update attributes of orders and theirs content
|
||||
BigDecimal packageMatFee = shopPackageMatFeeMap.get(uninvoicedOrder.getShopId());
|
||||
|
@ -557,6 +570,7 @@ public class ShippingInvoiceFactory {
|
|||
vatApplicable, pickingFeePerItem, content, remainingShippingFee);
|
||||
}
|
||||
}
|
||||
return platformOrderIdsWithPb;
|
||||
}
|
||||
|
||||
private void updateOrdersAndContentsInDb(Map<PlatformOrder, List<PlatformOrderContent>> orderAndContent) {
|
||||
|
@ -710,6 +724,8 @@ public class ShippingInvoiceFactory {
|
|||
+ ", delivered at " + uninvoicedOrder.getShippingTime().toString();
|
||||
log.error(msg);
|
||||
throw new UserException(msg);
|
||||
} catch (UserException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return Pair.of(channel, price);
|
||||
}
|
||||
|
@ -782,18 +798,22 @@ public class ShippingInvoiceFactory {
|
|||
shopPackageMatFeeMap.put(shop.getId(), shop.getPackagingMaterialFee());
|
||||
Map<PlatformOrder, List<PlatformOrderContent>> orders = uninvoicedOrdersByShopId.get(shop.getId());
|
||||
try {
|
||||
calculateFees(logisticChannelMap, orders, channelPriceMap, countryList, skuRealWeights, skuServiceFees,
|
||||
Map<String, List<String>> orderIdErrorMap = calculateFees(logisticChannelMap, orders, channelPriceMap, countryList, skuRealWeights, skuServiceFees,
|
||||
latestDeclaredValues, client, shopServiceFeeMap,shopPackageMatFeeMap, null);
|
||||
if(!orderIdErrorMap.isEmpty()) {
|
||||
Map.Entry<String, List<String>> errorEntry = orderIdErrorMap.entrySet().iterator().next();
|
||||
throw new UserException(errorEntry.getValue().toString());
|
||||
}
|
||||
BigDecimal eurToUsd = exchangeRatesMapper.getLatestExchangeRate("EUR", "USD");
|
||||
ShippingInvoice invoice = new ShippingInvoice(client, "", "", orders, null, eurToUsd);
|
||||
// Calculate total amounts
|
||||
invoice.tableData();
|
||||
estimations.add(new ShippingFeesEstimation(
|
||||
client.getInternalCode(), shop.getErpCode(), 0, orders.entrySet().size(), invoice.getTotalAmount(), client.getIsCompleteInvoice(), ""));
|
||||
client.getInternalCode(), shop.getErpCode(), 0, orders.entrySet().size(), invoice.getTotalAmount(), client.getIsCompleteInvoice(), "", new ArrayList<>()));
|
||||
} catch (UserException e) {
|
||||
log.error("Couldn't calculate all fees for shop {} for following reason {}", shop.getErpCode(), e.getMessage());
|
||||
estimations.add(new ShippingFeesEstimation(
|
||||
client.getInternalCode(), shop.getErpCode(), 0, orders.entrySet().size(), BigDecimal.ZERO, client.getIsCompleteInvoice(), e.getMessage()));
|
||||
client.getInternalCode(), shop.getErpCode(), 0, orders.entrySet().size(), BigDecimal.ZERO, client.getIsCompleteInvoice(), e.getMessage(), new ArrayList<>()));
|
||||
errorMessages.add(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
@ -840,14 +860,31 @@ public class ShippingInvoiceFactory {
|
|||
shopPackageMatFeeMap.put(shop.getId(), shop.getPackagingMaterialFee());
|
||||
Map<PlatformOrder, List<PlatformOrderContent>> orders = uninvoicedOrdersByShopId.get(shop.getId());
|
||||
try {
|
||||
calculateFees(logisticChannelMap, orders, channelPriceMap, countryList, skuRealWeights, skuServiceFees,
|
||||
Map<PlatformOrder, List<PlatformOrderContent>> ordersCopy = new HashMap<>(orders);
|
||||
Map<String, List<String>> platformOrderIdErrorMap = calculateFees(logisticChannelMap, orders, channelPriceMap, countryList, skuRealWeights, skuServiceFees,
|
||||
latestDeclaredValues, client, shopServiceFeeMap, shopPackageMatFeeMap, null);
|
||||
System.out.println("Error List : " + platformOrderIdErrorMap);
|
||||
for(Map.Entry<PlatformOrder,List<PlatformOrderContent>> entry : orders.entrySet()) {
|
||||
for(Map.Entry<String, List<String>> errorEntry: platformOrderIdErrorMap.entrySet()) {
|
||||
if(entry.getKey().getPlatformOrderId().equals(errorEntry.getKey())) {
|
||||
errorMessages.addAll(errorEntry.getValue());
|
||||
System.out.println("Error List size before : " + platformOrderIdErrorMap.size());
|
||||
System.out.println("Platform Order Id to remove : " + errorEntry.getKey());
|
||||
ordersCopy.remove(entry.getKey());
|
||||
platformOrderIdErrorMap.remove(errorEntry.getKey());
|
||||
System.out.println("Error List size after : " + platformOrderIdErrorMap.size());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
orders = ordersCopy;
|
||||
List<String> estimationsOrderIds = orders.keySet().stream().map(PlatformOrder::getId).collect(Collectors.toList());
|
||||
BigDecimal eurToUsd = exchangeRatesMapper.getLatestExchangeRate("EUR", "USD");
|
||||
ShippingInvoice invoice = new ShippingInvoice(client, "", "", orders, null, eurToUsd);
|
||||
// Calculate total amounts
|
||||
invoice.tableData();
|
||||
estimations.add(new ShippingFeesEstimation(
|
||||
client.getInternalCode(), shop.getErpCode(), 0, orders.entrySet().size(), invoice.getTotalAmount(), client.getIsCompleteInvoice(), ""));
|
||||
client.getInternalCode(), shop.getErpCode(), 0, orders.entrySet().size(), invoice.getTotalAmount(), client.getIsCompleteInvoice(), "", estimationsOrderIds));
|
||||
} catch (UserException e) {
|
||||
log.error("Couldn't calculate all fees for shop {} for following reason {}", shop.getErpCode(), e.getMessage());
|
||||
errorMessages.add(e.getMessage());
|
||||
|
|
|
@ -1,20 +1,66 @@
|
|||
package org.jeecg.modules.business.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: 国家
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2023-10-06
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
public class Country {
|
||||
private final String id;
|
||||
private final String nameEn;
|
||||
private final String nameZh;
|
||||
private final String code;
|
||||
private final String specialName;
|
||||
@TableName("country")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@ApiModel(value="country对象", description="国家")
|
||||
public class Country implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public Country(String id, String nameEn, String nameZh, String code, String specialName) {
|
||||
this.id = id;
|
||||
this.nameEn = nameEn;
|
||||
this.nameZh = nameZh;
|
||||
this.code = code;
|
||||
this.specialName = specialName;
|
||||
}
|
||||
/**主键*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@ApiModelProperty(value = "主键")
|
||||
private java.lang.String id;
|
||||
/**创建人*/
|
||||
@ApiModelProperty(value = "创建人")
|
||||
private java.lang.String createBy;
|
||||
/**创建日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@ApiModelProperty(value = "创建日期")
|
||||
private java.util.Date createTime;
|
||||
/**更新人*/
|
||||
@ApiModelProperty(value = "更新人")
|
||||
private java.lang.String updateBy;
|
||||
/**更新日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||
@ApiModelProperty(value = "更新日期")
|
||||
private java.util.Date updateTime;
|
||||
/**英语全名*/
|
||||
@Excel(name = "英语全名", width = 15)
|
||||
@ApiModelProperty(value = "英语全名")
|
||||
private java.lang.String nameEn;
|
||||
/**中文全名*/
|
||||
@Excel(name = "中文全名", width = 15)
|
||||
@ApiModelProperty(value = "中文全名")
|
||||
private java.lang.String nameZh;
|
||||
/**ISO 3166 代码*/
|
||||
@Excel(name = "ISO 3166 代码", width = 15)
|
||||
@ApiModelProperty(value = "ISO 3166 代码")
|
||||
private java.lang.String code;
|
||||
/**特殊名称(匹配马帮用)*/
|
||||
@Excel(name = "特殊名称(匹配马帮用)", width = 15)
|
||||
@ApiModelProperty(value = "特殊名称(匹配马帮用)")
|
||||
private java.lang.String specialName;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package org.jeecg.modules.business.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@ApiModel(value = "default_logistic_channel", description = "default logistic channel")
|
||||
@TableName("default_logistic_channel")
|
||||
public class LogisticChannelChoice implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@ApiModelProperty(value = "主键")
|
||||
private String id;
|
||||
/**
|
||||
* 创建人
|
||||
*/
|
||||
@ApiModelProperty(value = "创建人")
|
||||
private String createBy;
|
||||
/**
|
||||
* 创建日期
|
||||
*/
|
||||
@JsonFormat(timezone = "GMT+2", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@ApiModelProperty(value = "创建日期")
|
||||
private Date createTime;
|
||||
/**
|
||||
* 更新人
|
||||
*/
|
||||
@ApiModelProperty(value = "更新人")
|
||||
private String updateBy;
|
||||
/**
|
||||
* 更新日期
|
||||
*/
|
||||
@JsonFormat(timezone = "GMT+2", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@ApiModelProperty(value = "更新日期")
|
||||
private Date updateTime;
|
||||
/**
|
||||
* 店铺ID
|
||||
*/
|
||||
@Excel(name = "店铺ID", width = 15, dictTable = "shop", dicText = "erp_code", dicCode = "id")
|
||||
@Dict(dictTable = "shop", dicText = "erp_code", dicCode = "id")
|
||||
@ApiModelProperty(value = "店铺ID")
|
||||
private String shopId;
|
||||
/**
|
||||
* 物流渠道ID
|
||||
*/
|
||||
@Excel(name = "物流渠道ID", width = 15, dictTable = "logistic_channel", dicText = "zh_name", dicCode = "id")
|
||||
@Dict(dictTable = "logistic_channel", dicText = "zh_name", dicCode = "id")
|
||||
@ApiModelProperty(value = "物流渠道ID")
|
||||
private String logisticChannelId;
|
||||
/**
|
||||
* 订单收件人国家ID
|
||||
*/
|
||||
@Excel(name = "订单收件人国家ID", width = 15, dictTable = "country", dicText = "code", dicCode = "id")
|
||||
@Dict(dictTable = "country", dicText = "code", dicCode = "id")
|
||||
@ApiModelProperty(value = "订单收件人国家ID")
|
||||
private String countryId;
|
||||
/**
|
||||
* sensitive attribute id
|
||||
*/
|
||||
@Excel(name = "sensitive attribute id", width = 15, dictTable = "sensitive_attribute", dicText = "zh_name", dicCode = "id")
|
||||
@Dict(dictTable = "sensitive_attribute", dicText = "sensitive_attribute", dicCode = "id")
|
||||
@ApiModelProperty(value = "sensitive attribute id")
|
||||
private String sensitiveAttributeId;
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package org.jeecg.modules.business.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Date;
|
||||
import java.math.BigDecimal;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import lombok.Data;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* @Description: sensitive_attribute
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2023-10-03
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Data
|
||||
@TableName("sensitive_attribute")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@ApiModel(value="sensitive_attribute对象", description="sensitive_attribute")
|
||||
public class SensitiveAttribute implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**id*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@ApiModelProperty(value = "id")
|
||||
private java.lang.String id;
|
||||
/**中文描述*/
|
||||
@Excel(name = "中文描述", width = 15)
|
||||
@ApiModelProperty(value = "中文描述")
|
||||
private java.lang.String zhName;
|
||||
/**英文描述*/
|
||||
@Excel(name = "英文描述", width = 15)
|
||||
@ApiModelProperty(value = "英文描述")
|
||||
private java.lang.String enName;
|
||||
/**创建人*/
|
||||
@ApiModelProperty(value = "创建人")
|
||||
private java.lang.String createBy;
|
||||
/**创建日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd")
|
||||
@ApiModelProperty(value = "创建日期")
|
||||
private java.util.Date createTime;
|
||||
/**更新人*/
|
||||
@ApiModelProperty(value = "更新人")
|
||||
private java.lang.String updateBy;
|
||||
/**更新日期*/
|
||||
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern="yyyy-MM-dd")
|
||||
@ApiModelProperty(value = "更新日期")
|
||||
private java.util.Date updateTime;
|
||||
/**priority*/
|
||||
@Excel(name = "priority", width = 15)
|
||||
@ApiModelProperty(value = "priority")
|
||||
private java.lang.Integer priority;
|
||||
}
|
|
@ -93,6 +93,13 @@ public class ShippingInvoice implements Serializable {
|
|||
@Excel(name = "已付金额", width = 15)
|
||||
@ApiModelProperty(value = "已付金额")
|
||||
private java.math.BigDecimal paidAmount;
|
||||
/**
|
||||
* currency ID
|
||||
* */
|
||||
@Dict(dictTable = "currency", dicText = "code", dicCode = "id")
|
||||
@Excel(name = "currencyID", width = 15)
|
||||
@ApiModelProperty(value = "currency ID")
|
||||
private java.lang.String currencyId;
|
||||
|
||||
public void setID(String id) {
|
||||
this.id = id;
|
||||
|
|
|
@ -60,6 +60,7 @@ public class SkuPrice implements Serializable {
|
|||
*/
|
||||
@Dict(dictTable = "sku", dicText = "erp_code", dicCode = "id")
|
||||
@ApiModelProperty(value = "SKU ID")
|
||||
@Getter
|
||||
private String skuId;
|
||||
/**
|
||||
* 价格
|
||||
|
|
|
@ -90,6 +90,14 @@ public class Transaction implements Serializable {
|
|||
@Excel(name = "invoice number", width = 15)
|
||||
@ApiModelProperty(value = "invoice number")
|
||||
private java.lang.String invoiceNumber;
|
||||
/**shipping fee*/
|
||||
@Excel(name = "shipping fee", width = 15)
|
||||
@ApiModelProperty(value = "shippingFee")
|
||||
private java.math.BigDecimal shippingFee;
|
||||
/**purchase fee*/
|
||||
@Excel(name = "purchase fee", width = 15)
|
||||
@ApiModelProperty(value = "purchaseFee")
|
||||
private java.math.BigDecimal purchaseFee;
|
||||
/**amount*/
|
||||
@Excel(name = "amount", width = 15)
|
||||
@ApiModelProperty(value = "amount")
|
||||
|
|
|
@ -6,6 +6,8 @@ import org.jeecg.modules.business.entity.Client;
|
|||
import org.jeecg.modules.business.entity.UserClient;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: 客户 登录账户 关系
|
||||
* @Author: jeecg-boot
|
||||
|
@ -21,4 +23,10 @@ public interface ClientUserMapper extends BaseMapper<UserClient> {
|
|||
* @return client entity or null in case that current user is not a client
|
||||
*/
|
||||
Client selectClientByUserId(@Param("userId") String userId);
|
||||
|
||||
/**
|
||||
* List all clients registered in wia_app
|
||||
* @return list of clients
|
||||
*/
|
||||
List<Client> listClients();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.jeecg.modules.business.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.business.entity.Country;
|
||||
import org.jeecg.modules.business.vo.CountryCodeAlias;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
@ -27,6 +28,7 @@ public interface CountryMapper extends BaseMapper<Country> {
|
|||
* @return list of countries
|
||||
*/
|
||||
Country findByEnName(String en_name);
|
||||
List<Country> findIdByEnName(@Param("countries") List<String> countries);
|
||||
|
||||
/**
|
||||
* Find countries by their chinese name.
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package org.jeecg.modules.business.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.business.entity.LogisticChannelChoice;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: logistic channel choice
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2023-10-03
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Repository
|
||||
public interface LogisticChannelChoiceMapper extends BaseMapper<LogisticChannelChoice> {
|
||||
List<LogisticChannelChoice> fetchByShopId(@Param("shopIds") List<String> shopIds);
|
||||
}
|
|
@ -18,4 +18,5 @@ public interface LogisticChannelMapper extends BaseMapper<LogisticChannel> {
|
|||
|
||||
List<LogisticChannel> getAll();
|
||||
|
||||
List<LogisticChannel> listByIdAndZhName();
|
||||
}
|
||||
|
|
|
@ -5,11 +5,13 @@ import io.swagger.models.auth.In;
|
|||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.business.entity.ClientPlatformOrderContent;
|
||||
import org.jeecg.modules.business.entity.PlatformOrderContent;
|
||||
import org.jeecg.modules.business.entity.SkuPrice;
|
||||
import org.jeecg.modules.business.vo.SkuDetail;
|
||||
import org.jeecg.modules.business.vo.SkuQuantity;
|
||||
import org.jeecg.modules.business.vo.SkuWeightDiscountServiceFees;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -76,4 +78,7 @@ public interface PlatformOrderContentMapper extends BaseMapper<PlatformOrderCont
|
|||
void insertPlatformOrderContentsArchives(@Param("orderContents") List<PlatformOrderContent> platformOrderContents);
|
||||
void cancelInvoice(@Param("invoiceNumber") String invoiceNumber);
|
||||
void cancelBatchInvoice(@Param("invoiceNumbers") List<String> invoiceNumbers);
|
||||
List<SkuPrice> searchSkuPrice(@Param("skuIds") List<String> skuIds);
|
||||
|
||||
void fetchHighestPriorityAttribute(PlatformOrderContent content);
|
||||
}
|
||||
|
|
|
@ -188,4 +188,6 @@ public interface PlatformOrderMapper extends BaseMapper<PlatformOrder> {
|
|||
void cancelBatchInvoice(@Param("invoiceNumbers") List<String> invoiceNumbers);
|
||||
|
||||
List<PlatformOrder> findUninvoicedOrdersByShopForClient(@Param("shopIds") List<String> shopIds, @Param("erpStatuses") List<Integer> erpStatuses);
|
||||
|
||||
List<PlatformOrder> fetchEmptyLogisticChannelOrders(@Param("startDate") String startDate,@Param("endDate") String endDate);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package org.jeecg.modules.business.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.jeecg.modules.business.entity.SensitiveAttribute;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @Description: sensitive_attribute
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2023-10-03
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Repository
|
||||
public interface SensitiveAttributeMapper extends BaseMapper<SensitiveAttribute> {
|
||||
SensitiveAttribute getHighestPriorityAttribute(@Param("orderId") String orderId);
|
||||
String getHighestPriorityAttributeId(@Param("orderId") String orderId);
|
||||
|
||||
List<SensitiveAttribute> listIdAndPriority();
|
||||
}
|
|
@ -12,4 +12,5 @@ public interface TransactionMapper extends BaseMapper<Transaction> {
|
|||
List<Transaction> list();
|
||||
|
||||
List<Transaction> listByClientId(@Param("clientId") String clientId);
|
||||
List<Transaction> listByClientIdAndCurrency(@Param("clientId") String clientId, @Param("currency") String currency);
|
||||
}
|
||||
|
|
|
@ -5,8 +5,14 @@
|
|||
resultType="org.jeecg.modules.business.entity.Client">
|
||||
SELECT c.*
|
||||
FROM user_client
|
||||
JOIN client c
|
||||
ON c.id = user_client.client_id
|
||||
JOIN client c
|
||||
ON c.id = user_client.client_id
|
||||
WHERE user_id = #{userId}
|
||||
</select>
|
||||
<select id="listClients" resultType="org.jeecg.modules.business.entity.Client">
|
||||
SELECT c.*
|
||||
FROM user_client
|
||||
JOIN client c
|
||||
ON c.id = user_client.client_id
|
||||
</select>
|
||||
</mapper>
|
|
@ -13,6 +13,29 @@
|
|||
WHERE name_en = #{param1} or special_name = #{param1}
|
||||
</select>
|
||||
|
||||
<select id="findIdByEnName" resultType="org.jeecg.modules.business.entity.Country">
|
||||
SELECT id,
|
||||
CASE
|
||||
WHEN c.name_en IN
|
||||
<foreach collection="countries" separator="," open="(" close=")" item="country">
|
||||
#{country}
|
||||
</foreach> THEN c.name_en
|
||||
WHEN c.special_name IN
|
||||
<foreach collection="countries" separator="," open="(" close=")" item="country">
|
||||
#{country}
|
||||
</foreach> THEN c.special_name
|
||||
END as name_en
|
||||
FROM country as c
|
||||
WHERE c.name_en IN
|
||||
<foreach collection="countries" separator="," open="(" close=")" item="country">
|
||||
#{country}
|
||||
</foreach>
|
||||
OR c.special_name IN
|
||||
<foreach collection="countries" separator="," open="(" close=")" item="country">
|
||||
#{country}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<select id="findByZhName" resultType="org.jeecg.modules.business.entity.Country">
|
||||
SELECT *
|
||||
FROM country
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.jeecg.modules.business.mapper.LogisticChannelChoiceMapper">
|
||||
<select id="fetchByShopId" resultType="org.jeecg.modules.business.entity.LogisticChannelChoice">
|
||||
SELECT * FROM logistic_channel_choice
|
||||
WHERE shop_id IN
|
||||
<foreach collection="shopIds" separator="," open="(" close=")" item="shopId">
|
||||
#{shopId}
|
||||
</foreach>;
|
||||
</select>
|
||||
<update id="updateLogisticChannelBetweenDate">
|
||||
UPDATE platform_order
|
||||
SET update_time = NOW(),
|
||||
invoice_logistic_channel_name = CASE shop_id
|
||||
<foreach collection="products" separator=" " open="" close="" index="index" item="item">
|
||||
WHEN #{item.shop_id} THEN #{item.weight}
|
||||
</foreach>
|
||||
END
|
||||
WHERE invoice_logistic_channel_name IS NULL
|
||||
|
||||
|
||||
</update>
|
||||
</mapper>
|
|
@ -2,5 +2,11 @@
|
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.jeecg.modules.business.mapper.LogisticChannelMapper">
|
||||
<select id="getAll" resultType="org.jeecg.modules.business.entity.LogisticChannel">
|
||||
SELECT * FROM logistic_channel </select>
|
||||
SELECT * FROM logistic_channel
|
||||
</select>
|
||||
|
||||
<select id="listByIdAndZhName" resultType="org.jeecg.modules.business.entity.LogisticChannel">
|
||||
SELECT id, zh_name
|
||||
FROM logistic_channel;
|
||||
</select>
|
||||
</mapper>
|
|
@ -327,4 +327,11 @@
|
|||
#{invoiceNumber}
|
||||
</foreach>);
|
||||
</update>
|
||||
<select id="searchSkuPrice" resultType="org.jeecg.modules.business.entity.SkuPrice">
|
||||
SELECT * FROM sku_price
|
||||
WHERE sku_id IN
|
||||
<foreach collection="skuIds" separator="," open="(" close=")" index="index" item="skuId">
|
||||
#{skuId}
|
||||
</foreach>;
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
@ -646,4 +646,11 @@
|
|||
#{invoiceNumber}
|
||||
</foreach>;
|
||||
</update>
|
||||
<select id="fetchEmptyLogisticChannelOrders" resultType="org.jeecg.modules.business.entity.PlatformOrder">
|
||||
SELECT id, shop_id, country
|
||||
FROM platform_order po
|
||||
WHERE logistic_channel_name = ''
|
||||
AND invoice_logistic_channel_name IS NULL
|
||||
AND create_time BETWEEN #{startDate} AND #{endDate};
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.jeecg.modules.business.mapper.SensitiveAttributeMapper">
|
||||
<select id="getHighestPriorityAttribute" resultType="org.jeecg.modules.business.entity.SensitiveAttribute">
|
||||
SELECT sa.en_name, sa.priority
|
||||
FROM sensitive_attribute sa
|
||||
JOIN product p
|
||||
ON sa.id = p.sensitive_attribute_id
|
||||
JOIN sku s
|
||||
ON p.id = s.product_id
|
||||
JOIN platform_order_content poc
|
||||
ON s.id = poc.sku_id
|
||||
JOIN platform_order po
|
||||
ON poc.platform_order_id = po.id
|
||||
WHERE po.id = #{orderId}
|
||||
ORDER BY sa.priority DESC LIMIT 1;
|
||||
</select>
|
||||
<select id="getHighestPriorityAttributeId" resultType="java.lang.String">
|
||||
SELECT sa.id
|
||||
FROM sensitive_attribute sa
|
||||
JOIN product p
|
||||
ON sa.id = p.sensitive_attribute_id
|
||||
JOIN sku s
|
||||
ON p.id = s.product_id
|
||||
JOIN platform_order_content poc
|
||||
ON s.id = poc.sku_id
|
||||
JOIN platform_order po
|
||||
ON poc.platform_order_id = po.id
|
||||
WHERE po.id = #{orderId}
|
||||
ORDER BY sa.priority DESC LIMIT 1;
|
||||
</select>
|
||||
<select id="listIdAndPriority" resultType="org.jeecg.modules.business.entity.SensitiveAttribute">
|
||||
SELECT id, priority
|
||||
FROM wia_app.sensitive_attribute
|
||||
</select>
|
||||
</mapper>
|
|
@ -10,4 +10,11 @@
|
|||
WHERE client_id = #{clientId}
|
||||
ORDER BY create_time;
|
||||
</select>
|
||||
<select id="listByClientIdAndCurrency" resultType="org.jeecg.modules.business.entity.Transaction">
|
||||
SELECT *
|
||||
FROM transaction
|
||||
WHERE client_id = #{clientId}
|
||||
AND currency = #{currency}
|
||||
ORDER BY create_time;
|
||||
</select>
|
||||
</mapper>
|
|
@ -16,6 +16,9 @@ public class CountryService {
|
|||
public Country findByEnName(String en_name) {
|
||||
return countryMapper.findByEnName(en_name);
|
||||
}
|
||||
public List<Country> findIdByEnName(List<String> countries) {
|
||||
return countryMapper.findIdByEnName(countries);
|
||||
}
|
||||
|
||||
public List<Country> findAll() {
|
||||
return countryMapper.findAll();
|
||||
|
|
|
@ -8,7 +8,7 @@ import java.io.IOException;
|
|||
import java.util.Properties;
|
||||
|
||||
public interface EmailService {
|
||||
public void sendSimpleMessage();
|
||||
public void sendSimpleMessage(String recipient, String subject, String text, Session session) throws MessagingException;
|
||||
public void sendMessageWithAttachment(String recipient, String subject, String text, String attachment, Session session) throws MessagingException, IOException;
|
||||
public Properties getMailSender();
|
||||
public FreeMarkerConfigurer freemarkerClassLoaderConfig() throws IOException;
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package org.jeecg.modules.business.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.jeecg.modules.business.entity.LogisticChannelChoice;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: logistic channel choice
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2023-10-03
|
||||
* @Version: V1.0
|
||||
*/
|
||||
public interface ILogisticChannelChoiceService extends IService<LogisticChannelChoice> {
|
||||
List<LogisticChannelChoice> fetchByShopId(List<String> shopIds);
|
||||
}
|
|
@ -51,5 +51,5 @@ public interface ILogisticChannelService extends IService<LogisticChannel> {
|
|||
|
||||
|
||||
List<CostTrialCalculation> logisticChannelTrial(int weight, int volume, List<String> countryList);
|
||||
|
||||
List<LogisticChannel> listByIdAndZhName();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.jeecg.modules.business.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jeecg.modules.business.controller.UserException;
|
||||
import org.jeecg.modules.business.entity.PlatformOrderContent;
|
||||
import org.jeecg.modules.business.vo.SkuQuantity;
|
||||
|
@ -25,7 +26,7 @@ public interface IPlatformOrderContentService extends IService<PlatformOrderCont
|
|||
* @param skuRealWeights All SKU's real weights
|
||||
* @return weight
|
||||
*/
|
||||
BigDecimal calculateWeight(Map<String, Integer> contentMap, Map<String, BigDecimal> skuRealWeights) throws UserException;
|
||||
Pair<BigDecimal, List<String>> calculateWeight(Map<String, Integer> contentMap, Map<String, BigDecimal> skuRealWeights) throws UserException;
|
||||
|
||||
/**
|
||||
* Retrieve all SKU weights and discounts
|
||||
|
|
|
@ -184,4 +184,12 @@ public interface IPlatformOrderService extends IService<PlatformOrder> {
|
|||
* @return list of orders
|
||||
*/
|
||||
List<PlatformOrder> findUninvoicedOrdersByShopForClient(List<String> shopIds, List<Integer> erpStatuses);
|
||||
|
||||
/**
|
||||
* Find all order with empty logistic_channel_name and invoice_logistic_channel_name
|
||||
* @param startDate
|
||||
* @param endDate
|
||||
* @return
|
||||
*/
|
||||
List<PlatformOrder> fetchEmptyLogisticChannelOrders(String startDate, String endDate);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package org.jeecg.modules.business.service;
|
||||
|
||||
import org.jeecg.modules.business.entity.SensitiveAttribute;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: sensitive_attribute
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2023-10-03
|
||||
* @Version: V1.0
|
||||
*/
|
||||
|
||||
public interface ISensitiveAttributeService extends IService<SensitiveAttribute> {
|
||||
SensitiveAttribute getHighestPriorityAttribute(String orderId);
|
||||
String getHighestPriorityAttributeId(String orderId);
|
||||
|
||||
List<SensitiveAttribute> listIdAndPriority();
|
||||
}
|
|
@ -4,6 +4,10 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
|||
import org.jeecg.modules.business.entity.Client;
|
||||
import org.jeecg.modules.business.entity.UserClient;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IUserClientService extends IService<UserClient> {
|
||||
Client getClientByUserId(String userId);
|
||||
|
||||
List<Client> listClients();
|
||||
}
|
||||
|
|
|
@ -36,8 +36,18 @@ public class EmailServiceImpl implements EmailService {
|
|||
}
|
||||
@Override
|
||||
@Transactional
|
||||
public void sendSimpleMessage() {
|
||||
public void sendSimpleMessage(String recipient, String subject, String text, Session session) throws MessagingException {
|
||||
Message message = new MimeMessage(session);
|
||||
|
||||
message.setFrom(new InternetAddress(Objects.requireNonNull(env.getProperty("spring.mail.username"))));
|
||||
message.setRecipient(Message.RecipientType.TO, InternetAddress.parse(recipient)[0]);
|
||||
if(!recipient.equals(env.getProperty("spring.mail.username")))
|
||||
message.setRecipient(Message.RecipientType.CC, InternetAddress.parse(Objects.requireNonNull(env.getProperty("spring.mail.username")))[0]);
|
||||
|
||||
message.setSubject(subject);
|
||||
message.setContent(text, "text/html; charset=utf-8");
|
||||
|
||||
Transport.send(message);
|
||||
}
|
||||
@Override
|
||||
@Transactional
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package org.jeecg.modules.business.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.jeecg.modules.business.entity.LogisticChannelChoice;
|
||||
import org.jeecg.modules.business.mapper.LogisticChannelChoiceMapper;
|
||||
import org.jeecg.modules.business.service.ILogisticChannelChoiceService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: logistic channel choice
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2023-10-03
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Service
|
||||
public class LogisticChannelChoiceServiceImpl extends ServiceImpl<LogisticChannelChoiceMapper, LogisticChannelChoice> implements ILogisticChannelChoiceService {
|
||||
|
||||
@Autowired
|
||||
private LogisticChannelChoiceMapper logisticChannelChoiceMapper;
|
||||
|
||||
@Override
|
||||
public List<LogisticChannelChoice> fetchByShopId(List<String> shopIds) {
|
||||
return logisticChannelChoiceMapper.fetchByShopId(shopIds);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package org.jeecg.modules.business.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jeecg.modules.business.controller.UserException;
|
||||
import org.jeecg.modules.business.entity.LogisticChannelPrice;
|
||||
import org.jeecg.modules.business.entity.PlatformOrder;
|
||||
|
@ -80,10 +81,11 @@ public class LogisticChannelPriceServiceImpl extends ServiceImpl<LogisticChannel
|
|||
|
||||
String logisticChannelName = order.getInvoiceLogisticChannelName() == null ?
|
||||
order.getLogisticChannelName() : order.getInvoiceLogisticChannelName();
|
||||
BigDecimal weight = platformOrderContentService.calculateWeight(
|
||||
Pair<BigDecimal, List<String>> calculateWeightRes = platformOrderContentService.calculateWeight(
|
||||
contentMap,
|
||||
skuRealWeights
|
||||
);
|
||||
BigDecimal weight = calculateWeightRes.getKey();
|
||||
|
||||
|
||||
String countryCode = countryService.findByEnName(order.getCountry()).getCode();
|
||||
|
|
|
@ -109,4 +109,10 @@ public class LogisticChannelServiceImpl extends ServiceImpl<LogisticChannelMappe
|
|||
.sorted(Comparator.comparing(CostTrialCalculation::getTotalCost))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LogisticChannel> listByIdAndZhName() {
|
||||
return logisticChannelMapper.listByIdAndZhName();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package org.jeecg.modules.business.service.impl;
|
||||
|
||||
import com.amazonaws.services.dynamodbv2.xspec.NULL;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.jeecg.modules.business.controller.UserException;
|
||||
import org.jeecg.modules.business.entity.PlatformOrderContent;
|
||||
import org.jeecg.modules.business.mapper.PlatformOrderContentMapper;
|
||||
|
@ -13,9 +16,7 @@ import org.springframework.stereotype.Service;
|
|||
|
||||
import javax.transaction.Transactional;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
|
@ -36,23 +37,23 @@ public class PlatformOrderContentServiceImpl extends ServiceImpl<PlatformOrderCo
|
|||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal calculateWeight(Map<String, Integer> contentMap,
|
||||
Map<String, BigDecimal> skuRealWeights) throws UserException {
|
||||
public Pair<BigDecimal, List<String>> calculateWeight(Map<String, Integer> contentMap,
|
||||
Map<String, BigDecimal> skuRealWeights)
|
||||
{
|
||||
List<String> errorMessages = new ArrayList<>();
|
||||
List<String> skuIDs = new ArrayList<>(contentMap.keySet());
|
||||
log.info("skus : " + skuIDs);
|
||||
|
||||
try {
|
||||
|
||||
BigDecimal total = contentMap.entrySet().stream()
|
||||
.map(
|
||||
content ->
|
||||
(skuRealWeights.get(content.getKey()).multiply(BigDecimal.valueOf(content.getValue())))
|
||||
).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
log.info("total weight : " + total);
|
||||
return total;
|
||||
} catch (NullPointerException e) {
|
||||
throw new UserException("Can not find weight for one sku in: " + contentMap);
|
||||
BigDecimal total = BigDecimal.ZERO;
|
||||
for(Map.Entry<String, Integer> entry: contentMap.entrySet()) {
|
||||
if(skuRealWeights.get(entry.getKey()) == null) {
|
||||
errorMessages.add("Can not find weight for one sku in: " + contentMap);
|
||||
continue;
|
||||
}
|
||||
total = total.add(skuRealWeights.get(entry.getKey()).multiply(BigDecimal.valueOf(entry.getValue())));
|
||||
}
|
||||
log.info("total weight : " + total);
|
||||
return new MutablePair<>(total, errorMessages);
|
||||
|
||||
}
|
||||
@Override
|
||||
|
|
|
@ -398,4 +398,9 @@ public class PlatformOrderServiceImpl extends ServiceImpl<PlatformOrderMapper, P
|
|||
public List<PlatformOrder> findUninvoicedOrdersByShopForClient(List<String> shopIds, List<Integer> erpStatuses) {
|
||||
return platformOrderMap.findUninvoicedOrdersByShopForClient(shopIds, erpStatuses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PlatformOrder> fetchEmptyLogisticChannelOrders(String startDate, String endDate) {
|
||||
return platformOrderMap.fetchEmptyLogisticChannelOrders(startDate, endDate);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package org.jeecg.modules.business.service.impl;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.jeecg.modules.business.entity.SensitiveAttribute;
|
||||
import org.jeecg.modules.business.mapper.SensitiveAttributeMapper;
|
||||
import org.jeecg.modules.business.service.ISensitiveAttributeService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Description: sensitive_attribute
|
||||
* @Author: jeecg-boot
|
||||
* @Date: 2023-10-03
|
||||
* @Version: V1.0
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class SensitiveAttributeServiceImpl extends ServiceImpl<SensitiveAttributeMapper, SensitiveAttribute> implements ISensitiveAttributeService {
|
||||
@Autowired
|
||||
private SensitiveAttributeMapper sensitiveAttributeMapper;
|
||||
@Override
|
||||
public SensitiveAttribute getHighestPriorityAttribute(String orderId) {
|
||||
return sensitiveAttributeMapper.getHighestPriorityAttribute(orderId);
|
||||
}
|
||||
@Override
|
||||
public String getHighestPriorityAttributeId(String orderId) {
|
||||
return sensitiveAttributeMapper.getHighestPriorityAttributeId(orderId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SensitiveAttribute> listIdAndPriority() {
|
||||
return sensitiveAttributeMapper.listIdAndPriority();
|
||||
}
|
||||
}
|
|
@ -249,6 +249,7 @@ public class SkuListMabangServiceImpl extends ServiceImpl<SkuListMabangMapper, S
|
|||
|
||||
final String electroMagSensitiveAttributeId = skuListMabangMapper.searchSensitiveAttributeId("Electro-magnetic");
|
||||
final String electricSensitiveAttributeId = skuListMabangMapper.searchSensitiveAttributeId("Electronic/Electric");
|
||||
final String normalSensitiveAttributeId = skuListMabangMapper.searchSensitiveAttributeId("Normal goods");
|
||||
// In NameCN field on top of the product name we also get the customer code in the beginning of the string : "XX Description of the product"
|
||||
final Pattern cnNamePattern = Pattern.compile("^([a-zA-Z]{2,5})\\s(.*)$");
|
||||
// IN saleRemark sometimes not only the product weight provided, we can get extra information such as service_fee (eg : "15每件服务费0.2")
|
||||
|
@ -289,7 +290,7 @@ public class SkuListMabangServiceImpl extends ServiceImpl<SkuListMabangMapper, S
|
|||
if (sku.getMagnetic() == 1)
|
||||
p.setSensitiveAttributeId(electroMagSensitiveAttributeId);
|
||||
else
|
||||
p.setSensitiveAttributeId("");
|
||||
p.setSensitiveAttributeId(normalSensitiveAttributeId);
|
||||
}
|
||||
p.setInvoiceName(sku.getNameEN());
|
||||
if (sku.getSaleRemark() != null && !sku.getSaleRemark().equals("")) {
|
||||
|
|
|
@ -8,6 +8,8 @@ import org.jeecg.modules.business.service.IUserClientService;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class UserClientServiceImpl extends ServiceImpl<ClientUserMapper, UserClient> implements IUserClientService {
|
||||
@Autowired
|
||||
|
@ -16,4 +18,9 @@ public class UserClientServiceImpl extends ServiceImpl<ClientUserMapper, UserCl
|
|||
public Client getClientByUserId(String userId) {
|
||||
return clientUserMapper.selectClientByUserId(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Client> listClients() {
|
||||
return clientUserMapper.listClients();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package org.jeecg.modules.business.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class Estimation {
|
||||
private BigDecimal shippingFeesEstimation;
|
||||
private BigDecimal purchaseEstimation;
|
||||
private BigDecimal totalEstimation;
|
||||
private String currency;
|
||||
private List<String> errorMessages;
|
||||
|
||||
public Estimation(@JsonProperty("shippingFeesEstimation") BigDecimal shippingFeesEstimation,
|
||||
@JsonProperty("purchaseEstimation") BigDecimal purchaseEstimation,
|
||||
@JsonProperty("currency") String currency,
|
||||
@JsonProperty("errorMessages") List<String> errorMessages) {
|
||||
this.currency = currency;
|
||||
this.purchaseEstimation = purchaseEstimation;
|
||||
this.shippingFeesEstimation = shippingFeesEstimation;
|
||||
this.errorMessages = errorMessages;
|
||||
totalEstimation = shippingFeesEstimation.add(purchaseEstimation).setScale(2, RoundingMode.CEILING);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class ShippingFeesEstimation {
|
||||
|
@ -22,11 +23,14 @@ public class ShippingFeesEstimation {
|
|||
|
||||
private String errorMessage;
|
||||
|
||||
private List<String> orderIds;
|
||||
|
||||
public ShippingFeesEstimation(@JsonProperty("code") String code, @JsonProperty("shop")String shop,
|
||||
@JsonProperty("ordersToProcess")Integer ordersToProcess, @JsonProperty("processedOrders")Integer processedOrders,
|
||||
@JsonProperty("dueForProcessedOrders")BigDecimal dueForProcessedOrders,
|
||||
@JsonProperty("isCompleteInvoice")String isCompleteInvoice,
|
||||
@JsonProperty(value = "errorMessage")String errorMessage) {
|
||||
@JsonProperty(value = "errorMessage")String errorMessage,
|
||||
@JsonProperty("orderIds")List<String> orderIds) {
|
||||
this.code = code;
|
||||
this.shop = shop;
|
||||
this.ordersToProcess = ordersToProcess;
|
||||
|
@ -34,5 +38,6 @@ public class ShippingFeesEstimation {
|
|||
this.dueForProcessedOrders = dueForProcessedOrders;
|
||||
this.isCompleteInvoice = isCompleteInvoice;
|
||||
this.errorMessage = errorMessage;
|
||||
this.orderIds = orderIds;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
</head>
|
||||
<body>
|
||||
<table align="center" cellpadding="0" cellspacing="0" width="600" bgcolor="#FFF" style="font-family:Arial,Helvetica,sans-serif;text-align:center;table-layout:fixed;font-size: 16px;border: 1px solid #0B49A6">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="600" height="90" bgcolor="#0B49A6" valign="top" align="center" style="padding:20px 0;table-layout:fixed">
|
||||
<a href="http://app.wia-sourcing.com/user/login">
|
||||
<img src="https://wia-sourcing.com/wp-content/uploads/2022/10/Fichier-24Icons.png" alt="logo" width="360" style="width:100%;max-width:360px;">
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<table width="520" align="center" style="color:#000;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="padding:35px 0;">Cher(s) collègue(s),</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:0 0 35px 0;">Des erreurs se sont produites lors de l'attribution d'une ligne de transport à une ou plusieurs commandes :</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:10px 0;"><b>Erreurs :</b>
|
||||
<#if errors?size = 0>
|
||||
No error
|
||||
</#if>
|
||||
</td>
|
||||
</tr>
|
||||
<#list errors as error>
|
||||
<tr>
|
||||
<td style="padding:10px 0;">
|
||||
Error: ${error}
|
||||
</td>
|
||||
</tr>
|
||||
</#list>
|
||||
<tr>
|
||||
<td style="padding:35px 0 5px 0;">Merci d’utiliser nos services.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:5px 0;">Cordialement</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding:5px 0 35px 0;">L’équipe WIA Sourcing.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left" bgcolor="#0B49A6" width="600">
|
||||
<table align="center" width="520">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="font-style: italic;padding: 20px 0;">Ce message a été envoyé automatiquement. Merci de ne pas répondre. Ce message et ainsi que toutes les pièces jointes sont confidentielles.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="padding: 0 0 20px 0;">Si vous avez reçu ce message par erreur, merci de nous avertir immédiatement et de détruire ce message.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Service client :</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Pour obtenir plus d’informations concernant nos services, veuillez nous contacter à l’adresse ci-dessous ou en visitant notre site web.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table align="center" width="520" style="padding: 15px 0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td width="220" style="text-align:center;border-radius:2em;padding:20px 10px 20px 0;;" bgcolor="#EF5A1A"><a href="https://wia-sourcing.com/contactez-nous" style="color:white;text-decoration:none">Nous contacter</a></td>
|
||||
<td width="40" ></td>
|
||||
<td width="220" style="text-align:center;border-radius:2em;padding:20px 0 20px 10px;" bgcolor="#EF5A1A"><a href="https://wia-sourcing.com/" style="color:white;text-decoration:none">Notre site web</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table align="center" width="520" style="padding: 0 0 35px 0;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="color:#EF5A1A;">WIA SOURCING</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>© 2018/2023 par WIA Sourcing Agency.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TOUS DROITS RÉSERVÉS©</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue