From 67cb86e25b2e3944bde15cda35bcc0df5364a46e Mon Sep 17 00:00:00 2001 From: Gauthier LO Date: Thu, 4 Jan 2024 15:57:15 +0100 Subject: [PATCH] feature : feature : Self-service invoicing rework + Purchase Order Registration Page + ShippingFeeBillableNotificationJob --- .../admin/PurchaseOrderController.java | 121 ++++++--- .../admin/UserClientController.java | 4 - .../shippingInvoice/InvoiceController.java | 230 ++++++++++++++---- .../admin/shippingInvoice/InvoiceDatas.java | 2 + .../ShippingInvoiceController.java | 89 +------ .../client/TransactionController.java | 5 +- .../ShippingFeeBillableNotificationJob.java | 81 ++++++ .../domain/job/SkuShippingQtyJob.java | 9 +- .../ShippingInvoiceFactory.java | 9 - .../business/entity/ClientCategory.java | 2 +- .../business/entity/OrderContentDetail.java | 3 - .../modules/business/mapper/ClientMapper.java | 5 + .../business/mapper/PlatformOrderMapper.java | 9 + .../mapper/PurchaseOrderContentMapper.java | 2 + .../business/mapper/PurchaseOrderMapper.java | 7 + .../business/mapper/xml/ClientMapper.xml | 26 ++ .../mapper/xml/PlatformOrderMapper.xml | 33 ++- .../mapper/xml/PurchaseOrderContentMapper.xml | 19 ++ .../mapper/xml/PurchaseOrderMapper.xml | 15 ++ .../modules/business/mapper/xml/SkuMapper.xml | 3 + .../business/service/IClientService.java | 6 + .../service/IPlatformOrderService.java | 11 + .../service/IPurchaseOrderService.java | 16 +- .../service/IShippingInvoiceService.java | 7 + .../PlatformOrderShippingInvoiceService.java | 10 +- .../service/impl/BalanceServiceImpl.java | 6 - .../service/impl/ClientServiceImpl.java | 15 ++ .../impl/PlatformOrderServiceImpl.java | 26 +- .../impl/ShippingInvoiceServiceImpl.java | 162 ++++++++++++ .../business/service/impl/SkuServiceImpl.java | 5 +- .../purchase/PurchaseOrderServiceImpl.java | 184 ++++++++++++-- .../vo/ShippingFeeBillableOrders.java | 10 + .../templates/admin/invoiceNotification.ftl | 17 ++ .../shippingFeeBillableNotification.ftl | 20 ++ 34 files changed, 946 insertions(+), 223 deletions(-) create mode 100644 jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/job/ShippingFeeBillableNotificationJob.java create mode 100644 jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/vo/ShippingFeeBillableOrders.java create mode 100644 jeecg-module-system/jeecg-system-biz/src/main/resources/templates/admin/invoiceNotification.ftl create mode 100644 jeecg-module-system/jeecg-system-biz/src/main/resources/templates/client/shippingFeeBillableNotification.ftl diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/PurchaseOrderController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/PurchaseOrderController.java index f0343d451..532e89375 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/PurchaseOrderController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/PurchaseOrderController.java @@ -8,20 +8,15 @@ import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.SecurityUtils; -import org.apache.shiro.authz.annotation.RequiresPermissions; import org.jeecg.common.api.vo.Result; import org.jeecg.common.aspect.annotation.AutoLog; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.business.controller.UserException; -import org.jeecg.modules.business.domain.purchase.invoice.InvoiceData; import org.jeecg.modules.business.entity.*; import org.jeecg.modules.business.service.*; -import org.jeecg.modules.business.vo.InventoryImport; -import org.jeecg.modules.business.vo.PromotionCouple; -import org.jeecg.modules.business.vo.PurchaseOrderPage; -import org.jeecg.modules.business.vo.SkuQuantity; +import org.jeecg.modules.business.vo.*; import org.jeecg.modules.business.vo.clientPlatformOrder.PurchaseConfirmation; import org.jeecg.modules.business.vo.clientPlatformOrder.section.ClientInfo; import org.jeecgframework.poi.excel.ExcelImportUtil; @@ -55,27 +50,22 @@ import java.util.stream.Collectors; @RequestMapping("/purchaseOrder") @Slf4j public class PurchaseOrderController { - private final IPurchaseOrderService purchaseOrderService; - private final IPurchaseOrderSkuService purchaseOrderSkuService; - private final ISkuPromotionHistoryService skuPromotionHistoryService; - private final ISkuService skuService; - private final IImportedInventoryService importedInventoryService; - private final IClientService clientService; - private final IPlatformOrderService platformOrderService; - @Autowired - public PurchaseOrderController(IPurchaseOrderService purchaseOrderService, - IPurchaseOrderSkuService purchaseOrderSkuService, - ISkuPromotionHistoryService skuPromotionHistoryService, ISkuService skuService, - IImportedInventoryService importedInventoryService, IClientService clientService, IPlatformOrderService platformOrderService) { - this.purchaseOrderService = purchaseOrderService; - this.purchaseOrderSkuService = purchaseOrderSkuService; - this.skuPromotionHistoryService = skuPromotionHistoryService; - this.skuService = skuService; - this.importedInventoryService = importedInventoryService; - this.clientService = clientService; - this.platformOrderService = platformOrderService; - } + private IPurchaseOrderService purchaseOrderService; + @Autowired + private IPurchaseOrderSkuService purchaseOrderSkuService; + @Autowired + private ISkuPromotionHistoryService skuPromotionHistoryService; + @Autowired + private ISkuService skuService; + @Autowired + private IImportedInventoryService importedInventoryService; + @Autowired + private IClientService clientService; + @Autowired + private IPlatformOrderService platformOrderService; + @Autowired + private IShippingInvoiceService shippingInvoiceService; /** * Page query for purchase order @@ -121,12 +111,21 @@ public class PurchaseOrderController { @AutoLog(value = "商品采购订单-添加") @ApiOperation(value="商品采购订单-添加", notes="商品采购订单-添加") @PostMapping(value = "/addPurchaseAndOrder") - public Result addPurchaseAndOrder(@RequestBody PurchaseOrderPage purchaseOrderPage) { + public Result addPurchaseAndOrder( @RequestBody PurchaseOrderPage purchaseOrderPage) { PurchaseOrder purchaseOrder = new PurchaseOrder(); BeanUtils.copyProperties(purchaseOrderPage, purchaseOrder); - List platformOrderIds = new ArrayList<>(Arrays.asList(purchaseOrderPage.getPlatformOrderId().split(","))); + purchaseOrder.setPaymentDocumentString(new String(purchaseOrderPage.getPaymentDocument())); + purchaseOrder.setInventoryDocumentString(new String(purchaseOrderPage.getInventoryDocument())); + String purchaseID = UUID.randomUUID().toString(); + purchaseOrder.setId(purchaseID); + purchaseOrderService.save(purchaseOrder); + if(purchaseOrderPage.getPlatformOrderId() == null) { + return Result.OK("sys.api.entryAddSuccess"); + } + List platformOrderIds = Arrays.stream(purchaseOrderPage.getPlatformOrderId().split(",")) + .map(String::trim) + .collect(Collectors.toList()); log.info("Creating new purchase order and attributing it to orders: {}", platformOrderIds); - // test 5757661446491 & 5757658267995 poId List platformOrders = platformOrderService.selectByPlatformOrderIds(platformOrderIds); Map> platformOrderIdUpdateMap = new HashMap<>(); if(!platformOrders.isEmpty()) { @@ -145,8 +144,6 @@ public class PurchaseOrderController { log.error("Platform orders not found: {}", platformOrderIds); platformOrderIdUpdateMap.put("fail", platformOrderIds); } - - purchaseOrderService.save(purchaseOrder); return Result.OK("sys.api.entryAddSuccess", platformOrderIdUpdateMap); } // /** @@ -187,17 +184,23 @@ public class PurchaseOrderController { * @param purchaseOrderPage * @return */ + @Transactional @AutoLog(value = "purchase_order-编辑") @ApiOperation(value="purchase_order-编辑", notes="purchase_order-编辑") @RequestMapping(value = "/editPurchaseAndOrder", method = {RequestMethod.PUT,RequestMethod.POST}) public Result editPurchaseAndOrder(@RequestBody PurchaseOrderPage purchaseOrderPage) { PurchaseOrder purchaseOrder = new PurchaseOrder(); BeanUtils.copyProperties(purchaseOrderPage, purchaseOrder); + purchaseOrder.setPaymentDocumentString(new String(purchaseOrderPage.getPaymentDocument())); + purchaseOrder.setInventoryDocumentString(new String(purchaseOrderPage.getInventoryDocument())); + if(purchaseOrderPage.getPlatformOrderId() == null) { + purchaseOrderService.updateById(purchaseOrder); + return Result.OK("sys.api.entryEditSuccess"); + } List platformOrderIds = new ArrayList<>(Arrays.asList(purchaseOrderPage.getPlatformOrderId().split(","))); log.info("Editing purchase order and attributing it to orders : {}", platformOrderIds); log.info("Removing previous attribution to orders"); platformOrderService.removePurchaseInvoiceNumber(purchaseOrder.getInvoiceNumber()); - // test 5757661446491 & 5757658267995 poId List platformOrders = platformOrderService.selectByPlatformOrderIds(platformOrderIds); log.info("Platform orders found for attribution : {}", platformOrders.stream().map(PlatformOrder::getPlatformOrderId).collect(Collectors.toList())); Map> platformOrderIdUpdateMap = new HashMap<>(); @@ -216,7 +219,6 @@ public class PurchaseOrderController { log.error("Platform orders not found: {}", platformOrderIds); platformOrderIdUpdateMap.put("fail", platformOrderIds); } - purchaseOrderService.updateById(purchaseOrder); return Result.OK("sys.api.entryEditSuccess", platformOrderIdUpdateMap); } @@ -231,6 +233,11 @@ public class PurchaseOrderController { @ApiOperation(value = "商品采购订单-通过id删除", notes = "商品采购订单-通过id删除") @DeleteMapping(value = "/delete") public Result delete(@RequestParam(name = "id", required = true) String id) { + PurchaseOrder po = purchaseOrderService.getById(id); + if(po.getInventoryDocumentString() != null && !po.getInventoryDocumentString().isEmpty()) + shippingInvoiceService.deleteAttachmentFile(po.getInventoryDocumentString()); + if(po.getPaymentDocumentString() != null && !po.getPaymentDocumentString().isEmpty()) + shippingInvoiceService.deleteAttachmentFile(po.getPaymentDocumentString()); purchaseOrderService.delMain(id); return Result.OK("sys.api.entryDeleteSuccess"); } @@ -245,10 +252,56 @@ public class PurchaseOrderController { @ApiOperation(value = "商品采购订单-批量删除", notes = "商品采购订单-批量删除") @DeleteMapping(value = "/deleteBatch") public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + List purchaseOrders = purchaseOrderService.listByIds(Arrays.asList(ids.split(","))); + for(PurchaseOrder po : purchaseOrders) { + if(po.getInventoryDocumentString() != null && !po.getInventoryDocumentString().isEmpty()) + shippingInvoiceService.deleteAttachmentFile(po.getInventoryDocumentString()); + if(po.getPaymentDocumentString() != null && !po.getPaymentDocumentString().isEmpty()) + shippingInvoiceService.deleteAttachmentFile(po.getPaymentDocumentString()); + } this.purchaseOrderService.delBatchMain(Arrays.asList(ids.split(","))); return Result.OK("sys.api.entryBatchDeleteSuccess"); } + /** + * Cancel a purchase order's invoice. + * @param purchaseId purchase ID + * @param invoiceNumber invoice number + * @return + */ + @AutoLog(value = "商品采购订单-通过id删除") + @ApiOperation(value = "商品采购订单-通过id删除", notes = "商品采购订单-通过id删除") + @DeleteMapping(value = "/cancelInvoice") + public Result cancelInvoice(@RequestParam("id") String purchaseId, + @RequestParam("invoiceNumber") String invoiceNumber) { + PurchaseOrder po = purchaseOrderService.getById(purchaseId); + if(po.getInventoryDocumentString() != null && !po.getInventoryDocumentString().isEmpty()) + shippingInvoiceService.deleteAttachmentFile(po.getInventoryDocumentString()); + if(po.getPaymentDocumentString() != null && !po.getPaymentDocumentString().isEmpty()) + shippingInvoiceService.deleteAttachmentFile(po.getPaymentDocumentString()); + purchaseOrderService.cancelInvoice(purchaseId, invoiceNumber); + return Result.OK("sys.api.entryDeleteSuccess"); + } + /** + * Cancel multiple purchase order's invoice. + * @param purchaseIds list of purchase IDs + * @return + */ + @AutoLog(value = "商品采购订单-批量删除") + @ApiOperation(value = "商品采购订单-批量删除", notes = "商品采购订单-批量删除") + @DeleteMapping(value = "/cancelBatchInvoice") + public Result cancelBatchInvoice(@RequestParam("ids") String purchaseIds) { + List purchaseOrders = purchaseOrderService.listByIds(Arrays.asList(purchaseIds.split(","))); + for(PurchaseOrder po : purchaseOrders) { + if(po.getInventoryDocumentString() != null && !po.getInventoryDocumentString().isEmpty()) + shippingInvoiceService.deleteAttachmentFile(po.getInventoryDocumentString()); + if(po.getPaymentDocumentString() != null && !po.getPaymentDocumentString().isEmpty()) + shippingInvoiceService.deleteAttachmentFile(po.getPaymentDocumentString()); + } + purchaseOrderService.cancelBatchInvoice(purchaseIds); + return Result.OK("sys.api.entryDeleteSuccess"); + } + /** * 通过id查询 * @@ -447,7 +500,7 @@ public class PurchaseOrderController { * @param purchaseID purchaseID */ @RequestMapping(value = "/invoiceMeta", method = RequestMethod.GET) - public InvoiceData getInvoiceMetaData(@RequestParam String purchaseID, HttpServletResponse response) throws IOException, URISyntaxException { + public InvoiceMetaData getInvoiceMetaData(@RequestParam String purchaseID, HttpServletResponse response) throws IOException, URISyntaxException { return purchaseOrderService.makeInvoice(purchaseID); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/UserClientController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/UserClientController.java index 184640fd5..738ebd789 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/UserClientController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/UserClientController.java @@ -35,10 +35,6 @@ public class UserClientController { public Result getClientByUserId() { LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); String userId = loginUser.getId(); -// userId = "1708866308713140225"; //EP -// userId = "1724445090933100545"; //ND -// userId = "1730541854207422465"; // OV - userId = "1731689285213171713"; // JW Client client = userClientService.getClientMinInfoByUserId(userId); if(client == null) { List sysRoles = sysUserRoleService.getUserRole(userId); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceController.java index d56bebda4..de815f4bc 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceController.java @@ -1,12 +1,12 @@ package org.jeecg.modules.business.controller.admin.shippingInvoice; -import cn.hutool.core.date.DateTime; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.alibaba.fastjson.JSONObject; import freemarker.template.Template; +import freemarker.template.TemplateException; import io.swagger.annotations.Api; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.MutableTriple; @@ -18,11 +18,12 @@ import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.modules.business.controller.UserException; import org.jeecg.modules.business.domain.api.mabang.getorderlist.OrderStatus; -import org.jeecg.modules.business.domain.purchase.invoice.InvoiceData; +import org.jeecg.modules.business.domain.purchase.invoice.PurchaseInvoiceEntry; import org.jeecg.modules.business.entity.*; import org.jeecg.modules.business.mapper.ExchangeRatesMapper; import org.jeecg.modules.business.mapper.PlatformOrderContentMapper; import org.jeecg.modules.business.mapper.PlatformOrderMapper; +import org.jeecg.modules.business.mapper.PurchaseOrderContentMapper; import org.jeecg.modules.business.service.*; import org.jeecg.modules.business.vo.*; import org.jeecg.modules.quartz.entity.QuartzJob; @@ -44,6 +45,7 @@ import javax.servlet.http.HttpServletRequest; import java.io.*; import java.math.BigDecimal; import java.math.RoundingMode; +import java.net.StandardSocketOptions; import java.net.URISyntaxException; import java.text.ParseException; import java.time.LocalDate; @@ -90,6 +92,8 @@ public class InvoiceController { @Autowired private IPurchaseOrderService purchaseOrderService; @Autowired + private PurchaseOrderContentMapper purchaseOrderContentMapper; + @Autowired private IShippingInvoiceService iShippingInvoiceService; @Autowired private ISavRefundService iSavRefundService; @@ -280,17 +284,40 @@ public class InvoiceController { if(clientCategory.equals(ClientCategory.CategoryName.CONFIRMED.getName()) || clientCategory.equals(ClientCategory.CategoryName.VIP.getName())) { balanceService.updateBalance(param.clientID(), metaData.getInvoiceCode(), "shipping"); } + if(clientCategory.equals(ClientCategory.CategoryName.SELF_SERVICE.getName())) { + String subject = "Self-service shipping invoice"; + String destEmail = env.getProperty("spring.mail.username"); + Properties prop = emailService.getMailSender(); + Map templateModel = new HashMap<>(); + templateModel.put("invoiceType", "shipping invoice"); + templateModel.put("invoiceEntity", clientService.getById(param.clientID()).getInternalCode()); + templateModel.put("invoiceNumber", metaData.getInvoiceCode()); + + Session session = Session.getInstance(prop, new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(env.getProperty("spring.mail.username"), env.getProperty("spring.mail.password")); + } + }); + freemarkerConfigurer = emailService.freemarkerClassLoaderConfig(); + Template template = freemarkerConfigurer.getConfiguration().getTemplate("admin/invoiceNotification.ftl"); + String htmlBody = FreeMarkerTemplateUtils.processTemplateIntoString(template, templateModel); + emailService.sendSimpleMessage(destEmail, subject, htmlBody, session); + log.info("Mail sent successfully"); + } return Result.OK(metaData); } catch (UserException e) { return Result.error(e.getMessage()); } catch (IOException | ParseException e) { log.error(e.getMessage()); return Result.error("Sorry, server error, please try later"); + } catch (TemplateException | MessagingException e) { + throw new RuntimeException(e); } } /** - * Make invoice for specified orders and type - * + * Make purchase invoice for specified orders and type + * used by self-service clients * @param param Parameters for creating an invoice * @return Result of the generation, in case of error, message will be contained, * in case of success, data will contain filename. @@ -298,26 +325,45 @@ public class InvoiceController { @Transactional @PostMapping(value = "/makeManualPurchaseInvoice") public Result makeManualPurchaseInvoice(@RequestBody ShippingInvoiceOrderParam param) { + InvoiceMetaData metaData; try { - // todo : au final on facture les sku directement sans checker s'il y en aura trop - String currency = clientService.getById(param.clientID()).getCurrency(); - List orderContents = platformOrderContentMap.fetchOrderContent(param.orderIds()); - List skuIds = orderContents.stream().map(PlatformOrderContent::getSkuId).collect(Collectors.toList()); - List skuQuantities = skuService.getSkuQuantitiesFromOrderIds(param.orderIds()); String purchaseId = purchaseOrderService.addPurchase(skuQuantities ,param.orderIds()); + metaData = purchaseOrderService.makeInvoice(purchaseId); + platformOrderService.updatePurchaseInvoiceNumber(param.orderIds(), metaData.getInvoiceCode()); + String clientCategory = clientCategoryService.getClientCategoryByClientId(param.clientID()); - InvoiceData metaData = purchaseOrderService.makeInvoice(purchaseId); - if(clientCategory.equals(ClientCategory.CategoryName.CONFIRMED.getName()) || clientCategory.equals(ClientCategory.CategoryName.VIP.getName())) { - balanceService.updateBalance(param.clientID(), metaData.getCode(), "shipping"); +// if(clientCategory.equals(ClientCategory.CategoryName.CONFIRMED.getName()) || clientCategory.equals(ClientCategory.CategoryName.VIP.getName())) { +// balanceService.updateBalance(param.clientID(), metaData.getCode(), "purchase"); +// } + if(clientCategory.equals(ClientCategory.CategoryName.SELF_SERVICE.getName())) { + String subject = "Self-service purchase invoice"; + String destEmail = env.getProperty("spring.mail.username"); + Properties prop = emailService.getMailSender(); + Map templateModel = new HashMap<>(); + templateModel.put("invoiceType", "purchase invoice"); + templateModel.put("invoiceEntity", clientService.getById(param.clientID()).getInternalCode()); + templateModel.put("invoiceNumber", metaData.getInvoiceCode()); + + Session session = Session.getInstance(prop, new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(env.getProperty("spring.mail.username"), env.getProperty("spring.mail.password")); + } + }); + freemarkerConfigurer = emailService.freemarkerClassLoaderConfig(); + Template template = freemarkerConfigurer.getConfiguration().getTemplate("admin/invoiceNotification.ftl"); + String htmlBody = FreeMarkerTemplateUtils.processTemplateIntoString(template, templateModel); + emailService.sendSimpleMessage(destEmail, subject, htmlBody, session); + log.info("Mail sent successfully"); } - return Result.OK(); + return Result.OK(metaData); } catch (UserException e) { return Result.error(e.getMessage()); } catch (IOException e) { log.error(e.getMessage()); return Result.error("Sorry, server error, please try later"); - } catch (URISyntaxException e) { + } catch (URISyntaxException | MessagingException | TemplateException e) { throw new RuntimeException(e); } } @@ -337,7 +383,28 @@ public class InvoiceController { InvoiceMetaData metaData = shippingInvoiceService.makeCompleteInvoice(param); String clientCategory = clientCategoryService.getClientCategoryByClientId(param.clientID()); if(clientCategory.equals(ClientCategory.CategoryName.CONFIRMED.getName()) || clientCategory.equals(ClientCategory.CategoryName.VIP.getName())) { - balanceService.updateBalance(param.clientID(), metaData.getInvoiceCode(), "complete"); + balanceService.updateBalance(param.clientID(), metaData.getInvoiceCode(), "complete"); + } + if(clientCategory.equals(ClientCategory.CategoryName.SELF_SERVICE.getName())) { + String subject = "Self-service complete invoice"; + String destEmail = env.getProperty("spring.mail.username"); + Properties prop = emailService.getMailSender(); + Map templateModel = new HashMap<>(); + templateModel.put("invoiceType", "complete invoice"); + templateModel.put("invoiceEntity", clientService.getById(param.clientID()).getInternalCode()); + templateModel.put("invoiceNumber", metaData.getInvoiceCode()); + + Session session = Session.getInstance(prop, new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(env.getProperty("spring.mail.username"), env.getProperty("spring.mail.password")); + } + }); + freemarkerConfigurer = emailService.freemarkerClassLoaderConfig(); + Template template = freemarkerConfigurer.getConfiguration().getTemplate("admin/invoiceNotification.ftl"); + String htmlBody = FreeMarkerTemplateUtils.processTemplateIntoString(template, templateModel); + emailService.sendSimpleMessage(destEmail, subject, htmlBody, session); + log.info("Mail sent successfully"); } return Result.OK(metaData); } catch (UserException e) { @@ -345,7 +412,7 @@ public class InvoiceController { } catch (IOException | ParseException e) { log.error(e.getMessage()); return Result.error("Sorry, server error, please try later"); - } catch (MessagingException e) { + } catch (MessagingException | TemplateException e) { throw new RuntimeException(e); } } @@ -356,7 +423,6 @@ public class InvoiceController { " and erpStatuses : " + erpStatuses.toString()); Period period = shippingInvoiceService.getValidOrderTimePeriod(shopIDs, erpStatuses); if (period.isValid()) { - System.out.println("start : " + period.start() + "; end : " + period.end()); return Result.OK(period); } return Result.error("No package in the selected period"); @@ -489,7 +555,8 @@ public class InvoiceController { errorMessages.add(orderAndStatus.getRight()); } } - + // sorting by order time ascending + finalOrderAndStatus = finalOrderAndStatus.stream().sorted(Comparator.comparing(o -> o.getLeft().getOrderTime())).collect(Collectors.toList()); // system notification String errors = SECTION_START; int max_entries = 100; @@ -508,7 +575,7 @@ public class InvoiceController { templateParam.put("errors", errors); templateParam.put("current_page", String.valueOf(current_page)); templateParam.put("total_page", String.valueOf(total_page)); - TemplateMessageDTO message = new TemplateMessageDTO("admin", "Gauthier", "Self Service invoicing estimation Errors", templateParam, "expenses_overview_errors"); + TemplateMessageDTO message = new TemplateMessageDTO("admin", "admin", "Self Service invoicing estimation Errors", templateParam, "expenses_overview_errors"); ISysBaseApi.sendTemplateAnnouncement(message); } } @@ -554,10 +621,11 @@ public class InvoiceController { * @return byte array, in case of error, an empty array will be returned. */ @GetMapping(value = "/download") - public byte[] downloadInvoice(@RequestParam("filename") String filename) { + public byte[] downloadInvoice(@RequestParam("filename") String filename, @RequestParam(value = "type", required = false) String type) { log.info("request for downloading shipping invoice"); + String invoiceType = type == null ? "shipping" : type; try { - return shippingInvoiceService.getInvoiceBinary(filename); + return shippingInvoiceService.getInvoiceBinary(filename, invoiceType); } catch (IOException e) { log.error(e.getMessage()); return new byte[0]; @@ -761,22 +829,9 @@ public class InvoiceController { public Result getPurchaseFeesEstimateByOrders(@RequestBody ShippingInvoiceOrderParam param) { String currency = clientService.getById(param.clientID()).getCurrency(); List orders = platformOrderMapper.fetchByIds(param.orderIds()); - Map> orderIdsMapByShop = new HashMap<>(); - for(PlatformOrder order : orders) { - String shopId = order.getShopId(); - System.out.println("Adding order " + order.getId() + " to shop " + shopId); - if(orderIdsMapByShop.containsKey(shopId)) { - System.out.println(orderIdsMapByShop.get(shopId)); - orderIdsMapByShop.get(shopId).add(order); - } - else { - List orderIds = new ArrayList<>(); - orderIds.add(order); - orderIdsMapByShop.put(shopId, orderIds); - } - } + Map> ordersMapByShop = orders.stream().collect(Collectors.groupingBy(PlatformOrder::getShopId)); Map estimationsByShop = new HashMap<>(); - for(Map.Entry> entry : orderIdsMapByShop.entrySet()) { + for(Map.Entry> entry : ordersMapByShop.entrySet()) { String shopId = entry.getKey(); List orderIds = entry.getValue().stream().map(PlatformOrder::getId).collect(Collectors.toList()); ShippingInvoiceOrderParam finalParam = new ShippingInvoiceOrderParam(param.clientID(), orderIds, param.getType()); @@ -787,8 +842,13 @@ public class InvoiceController { return Result.OK("No estimation found."); // purchase estimation - // only calculate purchase estimation if products are not available, else it's already been paid - List orderIdsWithProductUnavailable = entry.getValue().stream().filter(order -> order.getProductAvailable().equals("0")).map(PlatformOrder::getId).collect(Collectors.toList()); + // only calculate purchase estimation if products are not available and purchaseInvoiceNumber is null, else it's already been paid + List orderIdsWithProductUnavailable = entry.getValue().stream() + .filter( + order -> order.getProductAvailable().equals("0") + && order.getPurchaseInvoiceNumber() == null + && order.getVirtualProductAvailable().equals("0")) + .map(PlatformOrder::getId).collect(Collectors.toList()); BigDecimal shippingFeesEstimation = BigDecimal.ZERO; BigDecimal purchaseEstimation = BigDecimal.ZERO; boolean isCompleteInvoiceReady = true; @@ -829,21 +889,33 @@ public class InvoiceController { } @GetMapping(value = "/checkInvoiceValidity") - public Result checkInvoiceValidity(@RequestParam("invoiceNumber") String invoiceNumber, @RequestParam("email") String email, @RequestParam("orgCode") String orgCode) { + public Result checkInvoiceValidity(@RequestParam("invoiceNumber") String invoiceNumber) { + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String orgCode = sysUser.getOrgCode(); + String email = sysUser.getEmail(); String invoiceID; String customerFullName; - invoiceID = iShippingInvoiceService.getShippingInvoiceId(invoiceNumber); + boolean isShippingInvoice = invoiceNumber.charAt(8) == '7' || invoiceNumber.charAt(8) == '2'; + if(isShippingInvoice) + invoiceID = iShippingInvoiceService.getShippingInvoiceId(invoiceNumber); + else + invoiceID = purchaseOrderService.getInvoiceId(invoiceNumber); // if invoice exists if (invoiceID == null) { - return Result.error("Error 404 page not found."); + return Result.error(404,"Error 404 page not found."); } // if user is a customer, we check if he's the owner of the shops - Client client = iShippingInvoiceService.getShopOwnerFromInvoiceNumber(invoiceNumber); + Client client; + if(isShippingInvoice) + client = iShippingInvoiceService.getShopOwnerFromInvoiceNumber(invoiceNumber); + else + client = clientService.getClientFromPurchase(invoiceID); customerFullName = client.fullName(); String destEmail; if(orgCode.contains("A04")) { + System.out.println(email + " - " + client.getEmail()); if(!client.getEmail().equals(email)) { - return Result.error("Not authorized to view this page."); + return Result.error(403,"Not authorized to view this page."); } else { destEmail = client.getEmail(); @@ -943,6 +1015,67 @@ public class InvoiceController { return Result.OK(invoiceDatas); } + @GetMapping(value = "/purchaseInvoiceData") + public Result getPurchaseInvoiceData(@RequestParam("invoiceNumber") String invoiceNumber, + @RequestParam("originalCurrency") String originalCurrency, + @RequestParam("targetCurrency") String targetCurrency + ){ + InvoiceDatas invoiceDatas = new InvoiceDatas(); + + List invoices = purchaseOrderService.getPurchasesByInvoiceNumber(invoiceNumber); + if(invoices == null) { + return Result.error("No data for product found."); + } + List invoiceData = new ArrayList<>(); + for(PurchaseOrder order : invoices) { + invoiceData.addAll(purchaseOrderContentMapper.selectInvoiceDataByID(order.getId())); + } + List refundList = iSavRefundService.getRefundAmount(invoiceNumber); + Map> feeAndQtyPerSku = new HashMap<>(); // it maps number of order and purchase fee per item : >, > + BigDecimal refund = BigDecimal.ZERO; + + // on parcours toutes les commandes pour récupérer : country, purchaseFee + for(PurchaseInvoiceEntry data : invoiceData) { + String sku = data.getSku_en_name(); + BigDecimal purchaseFeePerSku = data.getTotalAmount(); + Integer qty = data.getQuantity(); + // On vérifie si on a déjà ce pays dans la map + // si oui on additionne la "qty" et "purchase fee" + // sinon on ajoute juste à la map + if(!feeAndQtyPerSku.containsKey(sku)) { + feeAndQtyPerSku.put(sku, new AbstractMap.SimpleEntry<>(qty, purchaseFeePerSku)); + } + else { + BigDecimal existingGlobalFee = feeAndQtyPerSku.get(sku).getValue(); + Integer existingOrderQuantity = feeAndQtyPerSku.get(sku).getKey(); + existingOrderQuantity += qty; + existingGlobalFee = existingGlobalFee.add(purchaseFeePerSku); + feeAndQtyPerSku.remove(sku); + feeAndQtyPerSku.put(sku, new AbstractMap.SimpleEntry<>(existingOrderQuantity, existingGlobalFee)); + } + } + // on fait la somme des remboursements + if(!refundList.isEmpty()) { + for (BigDecimal amount : refundList) { + refund = refund.add(amount); + } + } + + // si la monnaie utilisé par le client n'est pas l'euro on calcul le total dans sa monnaie + if(!targetCurrency.equals(originalCurrency)) { + BigDecimal exchangeRate = iExchangeRatesService.getExchangeRate(originalCurrency,targetCurrency); + BigDecimal finalAmount = invoices.stream().map(PurchaseOrder::getFinalAmount).reduce(BigDecimal.ZERO, BigDecimal::add).multiply(exchangeRate); + finalAmount = finalAmount.setScale(2, RoundingMode.DOWN); + invoiceDatas.setFinalAmount(finalAmount); + } + invoiceDatas.setInvoiceNumber(invoiceNumber); + invoiceDatas.setDiscount(invoices.stream().map(PurchaseOrder::getDiscountAmount).reduce(BigDecimal.ZERO, BigDecimal::add)); + invoiceDatas.setRefund(refund); + invoiceDatas.setFinalAmountEur(invoices.stream().map(PurchaseOrder::getFinalAmount).reduce(BigDecimal.ZERO, BigDecimal::add)); + invoiceDatas.setFeeAndQtyPerSku(feeAndQtyPerSku); + + return Result.OK(invoiceDatas); + } public String countryNameFormatting(String country) { Pattern p = Pattern.compile("(\\w*)", Pattern.UNICODE_CHARACTER_CLASS); Matcher m = p.matcher(country); @@ -979,4 +1112,15 @@ public class InvoiceController { } return Result.OK().success("sys.api.syncRequestSubmitted"); } + @GetMapping(value = "/duplicateInvoiceNumberCheck") + public Result duplicateInvoiceNumberCheck(@RequestParam("invoiceNumber") String invoiceNumber) { + if(iShippingInvoiceService.getShippingInvoice(invoiceNumber) != null + || purchaseOrderService.getInvoiceId(invoiceNumber) != null + || !platformOrderService.getPlatformOrdersByInvoiceNumber(invoiceNumber).isEmpty()) { + return Result.error("Invoice number already exists."); + } + else { + return Result.OK("Invoice number is available."); + } + } } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceDatas.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceDatas.java index f4cbfa8a7..8984d4380 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceDatas.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/InvoiceDatas.java @@ -10,6 +10,8 @@ import java.util.Map; public class InvoiceDatas { @JSONField(name = "invoiceNumber") private String invoiceNumber; + @JSONField(name = "feeAndQtyPerSku") + private Map> feeAndQtyPerSku; @JSONField(name = "feeAndQtyPerCountry") private Map> feeAndQtyPerCountry; @JSONField(name = "vat") diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/ShippingInvoiceController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/ShippingInvoiceController.java index 24f39bd6d..4807cb3e6 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/ShippingInvoiceController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/admin/shippingInvoice/ShippingInvoiceController.java @@ -84,7 +84,6 @@ public class ShippingInvoiceController { private FreeMarkerConfigurer freemarkerConfigurer; @Autowired private EmailService emailService; - private static final String EXTENSION = ".xlsx"; @Value("${jeecg.path.shippingInvoiceDir}") private String INVOICE_LOCATION; @Value("${jeecg.path.shippingInvoiceDetailDir}") @@ -281,81 +280,7 @@ public class ShippingInvoiceController { return Result.OK("文件导入失败!"); } - /** Finds the absolute path of invoice file by recursively walking the directory and it's subdirectories - * - * @param dirPath - * @param invoiceNumber - * @return List of paths for the file but should only find one result - */ - public List getPath(String dirPath, String invoiceNumber) { - List pathList = new ArrayList<>(); - //Recursively list all files - //The walk() method returns a Stream by walking the file tree beginning with a given starting file/directory in a depth-first manner. - try (Stream stream = Files.walk(Paths.get(dirPath))) { - pathList = stream.map(Path::normalize) - .filter(Files::isRegularFile) // directories, hidden files and files without extension are not included - .filter(path -> path.getFileName().toString().contains(invoiceNumber)) - .filter(path -> path.getFileName().toString().endsWith(EXTENSION)) - .collect(Collectors.toList()); - } - catch(IOException e) { - e.printStackTrace(); - } - return pathList; - } - /** Finds the absolute path of invoice file by recursively walking the directory and it's subdirectories - * - * @param dirPath - * @param invoiceNumber - * @return List of paths for the file but should only find one result - */ - public List getPath(String dirPath, String invoiceNumber, String invoiceEntity) { - List pathList = new ArrayList<>(); - //Recursively list all files - //The walk() method returns a Stream by walking the file tree beginning with a given starting file/directory in a depth-first manner. - try (Stream stream = Files.walk(Paths.get(dirPath))) { - pathList = stream.map(Path::normalize) - .filter(Files::isRegularFile) // directories, hidden files and files without extension are not included - .filter(path -> path.getFileName().toString().contains(invoiceNumber)) - .filter(path -> path.getFileName().toString().contains(invoiceEntity)) - .filter(path -> path.getFileName().toString().endsWith(EXTENSION)) - .collect(Collectors.toList()); - } - catch(IOException e) { - e.printStackTrace(); - } - return pathList; - } - - /** - * Finds the absolute path of invoice file and return the path - * @param invoiceNumber - * @param filetype if it's an invoice or invoice detail - * @return String returns the path of the invoice file - */ - public String getInvoiceList(String invoiceNumber, String filetype) { - log.info("Invoice number : " + invoiceNumber); - List pathList = new ArrayList<>(); - if(filetype.equals("invoice")) { - log.info("File asked is of type invoice"); - pathList = getPath(INVOICE_LOCATION, invoiceNumber); - } - if(filetype.equals("detail")) { - log.info("File asked is of type invoice detail"); - pathList = getPath(INVOICE_DETAIL_LOCATION, invoiceNumber); - } - if(pathList.isEmpty()) { - log.error("NO INVOICE FILE FOUND : " + invoiceNumber); - return "ERROR"; - } - else { - for (Path path : pathList) { - log.info(path.toString()); - } - return pathList.get(0).toString(); - } - } /** * Downloads the invoice and returns it in form of bytearray @@ -366,7 +291,7 @@ public class ShippingInvoiceController { */ @GetMapping(value = "/downloadCompleteInvoiceExcel") public ResponseEntity download(@RequestParam("invoiceNumber") String invoiceNumber, @RequestParam("filetype") String filetype) throws IOException { - String filename = getInvoiceList(invoiceNumber, filetype); + String filename = shippingInvoiceService.getInvoiceList(invoiceNumber, filetype); if(!filename.equals("ERROR")) { File file = new File(filename); @@ -398,7 +323,7 @@ public class ShippingInvoiceController { } public String convertToPdf(String invoiceNumber, String fileType) throws Exception { - String excelFilePath = getInvoiceList(invoiceNumber, fileType);// (C:\PATH\filename.xlsx) + String excelFilePath = shippingInvoiceService.getInvoiceList(invoiceNumber, fileType);// (C:\PATH\filename.xlsx) if(!excelFilePath.equals("ERROR")) { String pdfFilePath= INVOICE_PDF_LOCATION + "/" + invoiceNumber + ".pdf"; @@ -457,7 +382,7 @@ public class ShippingInvoiceController { public Result sendDetailsByEmail(@RequestParam("invoiceNumber") String invoiceNumber, @RequestParam("email") String email, @RequestParam("invoiceEntity") String invoiceEntity) throws Exception { - String filePath = getInvoiceList(invoiceNumber, "detail"); + String filePath = shippingInvoiceService.getInvoiceList(invoiceNumber, "detail"); String fileType = "Détails de facture"; String subject = "Détails de facture N°" + invoiceNumber; Properties prop = emailService.getMailSender(); @@ -519,8 +444,8 @@ public class ShippingInvoiceController { balanceService.deleteBalance(id, OperationType.Debit.name()); log.info("Deleting invoice files ..."); String invoiceEntity = clientService.getClientEntity(clientId); - List invoicePathList = getPath(INVOICE_LOCATION, invoiceNumber, invoiceEntity); - List detailPathList = getPath(INVOICE_DETAIL_LOCATION, invoiceNumber, invoiceEntity); + List invoicePathList = shippingInvoiceService.getPath(INVOICE_LOCATION, invoiceNumber, invoiceEntity); + List detailPathList = shippingInvoiceService.getPath(INVOICE_DETAIL_LOCATION, invoiceNumber, invoiceEntity); boolean invoiceDeleted = false, detailDeleted = false; if(invoicePathList.isEmpty()) { @@ -586,8 +511,8 @@ public class ShippingInvoiceController { for(int i = 0; i < ids.size(); i++) { String invoiceNumber = invoiceNumbers.get(i); String invoiceEntity = clientService.getClientEntity(clientIds.get(i)); - List invoicePathList = getPath(INVOICE_LOCATION, invoiceNumber, invoiceEntity); - List detailPathList = getPath(INVOICE_DETAIL_LOCATION, invoiceNumber, invoiceEntity); + List invoicePathList = shippingInvoiceService.getPath(INVOICE_LOCATION, invoiceNumber, invoiceEntity); + List detailPathList = shippingInvoiceService.getPath(INVOICE_DETAIL_LOCATION, invoiceNumber, invoiceEntity); if(invoicePathList.isEmpty()) { log.error("FILE NOT FOUND : " + invoiceNumber + ", " + invoiceEntity); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/client/TransactionController.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/client/TransactionController.java index cc40c13e2..a7b10e04d 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/client/TransactionController.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/controller/client/TransactionController.java @@ -98,8 +98,7 @@ public class TransactionController { Date startDate = orders.stream().map(PlatformOrder::getOrderTime).min(Date::compareTo).get(); Date endDate = orders.stream().map(PlatformOrder::getOrderTime).max(Date::compareTo).get(); List orderIds = orders.stream().map(PlatformOrder::getId).collect(Collectors.toList()); - System.out.println("Orders size : " + orderIds.size()); - System.out.println("Orders : " + orderIds); + log.info("{} Orders to be estimated", orderIds.size()); ShippingInvoiceFactory factory = new ShippingInvoiceFactory( platformOrderService, clientMapper, shopMapper, logisticChannelMapper, logisticChannelPriceMapper, platformOrderContentService, skuDeclaredValueService, countryService, exchangeRatesMapper, @@ -158,7 +157,7 @@ public class TransactionController { param.put("errors", errors); param.put("current_page", String.valueOf(current_page)); param.put("total_page", String.valueOf(total_page)); - TemplateMessageDTO message = new TemplateMessageDTO("admin", "Gauthier", "Expenses Overview Errors", param, "expenses_overview_errors"); + TemplateMessageDTO message = new TemplateMessageDTO("admin", "admin", "Expenses Overview Errors", param, "expenses_overview_errors"); ISysBaseApi.sendTemplateAnnouncement(message); } } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/job/ShippingFeeBillableNotificationJob.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/job/ShippingFeeBillableNotificationJob.java new file mode 100644 index 000000000..809586238 --- /dev/null +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/job/ShippingFeeBillableNotificationJob.java @@ -0,0 +1,81 @@ +package org.jeecg.modules.business.domain.job; + +import freemarker.template.Template; +import lombok.extern.slf4j.Slf4j; +import org.jeecg.modules.business.service.EmailService; +import org.jeecg.modules.business.service.IPlatformOrderService; +import org.jeecg.modules.business.vo.ShippingFeeBillableOrders; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.transaction.annotation.Transactional; +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.util.*; +import java.util.stream.Collectors; + +import static java.util.stream.Collectors.*; + +@Slf4j +public class ShippingFeeBillableNotificationJob implements Job { + @Autowired + private IPlatformOrderService platformOrderService; + @Autowired + private EmailService emailService; + + @Autowired + private FreeMarkerConfigurer freemarkerConfigurer; + @Autowired + Environment env; + + /** + * Job that finds all order contents from uninvoiced orders with missing stock and checks if products have been ordered + * @param jobExecutionContext + * @throws JobExecutionException + */ + @Transactional + @Override + public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { + log.info("Shipping Fee Billable Notification Job started ..."); + + List shippingFeeBillableOrders = platformOrderService.fetchShippingFeeBillableOrders(); + if (shippingFeeBillableOrders.isEmpty()) { + log.info("No orders awaiting shipping fees to be billed."); + return; + } + Map> ordersByClientEmail = shippingFeeBillableOrders.stream().collect(groupingBy(ShippingFeeBillableOrders::getEmail)); + + + Properties prop = emailService.getMailSender(); + Session session = Session.getInstance(prop, new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(env.getProperty("spring.mail.username"), env.getProperty("spring.mail.password")); + } + }); + + for(Map.Entry> entry : ordersByClientEmail.entrySet()) { + String subject = "Shipping Fee Billable Notification"; + String destEmail = entry.getKey(); + Map templateModel = new HashMap<>(); + templateModel.put("fullName", entry.getValue().get(0).getFullName()); + templateModel.put("orderNumbers", entry.getValue().stream().map(ShippingFeeBillableOrders::getOrderNumber).collect(Collectors.toList())); + try { + freemarkerConfigurer = emailService.freemarkerClassLoaderConfig(); + Template template = freemarkerConfigurer.getConfiguration().getTemplate("client/shippingFeeBillableNotification.ftl"); + String htmlBody = FreeMarkerTemplateUtils.processTemplateIntoString(template, templateModel); + emailService.sendSimpleMessage(destEmail, subject, htmlBody, session); + log.info("Mail sent successfully"); + } catch (Exception e) { + log.error("Error sending mail: " + e.getMessage()); + } + } + log.info("Shipping Fee Billable Notification Job finished ..."); + } +} diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/job/SkuShippingQtyJob.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/job/SkuShippingQtyJob.java index e2bd931b5..681a79c8f 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/job/SkuShippingQtyJob.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/job/SkuShippingQtyJob.java @@ -140,10 +140,6 @@ public class SkuShippingQtyJob implements Job { } skuData.setStockAfterDistribution(skuData.getStockQuantity() - content.getQuantity()); skuData.calculateVirtualQuantity(); - if(skuData.getStockAfterDistribution() < 0) { - System.out.println("===================== ERRRRRRRRRRRRRRRROOOOOOOOOOOOOOOOOORRR ======================"); - System.out.println("Order : " + orderMapEntry.getKey().getPlatformOrderId() + " --- Sku : " + skuIdToErpCodeMap.get(content.getSkuId()) + " --- Stock : " + skuData.getStockQuantity() + " --- Stock after subtracting : " + skuData.getStockAfterDistribution() + " --- Virtual Stock : " + skuData.getVirtualQuantity() + " --- Shipping Quantity : " + skuData.getShippingQuantity()); - } } } log.info("Sku Shipping Quantity after subtracting the quantity from orders with product available"); @@ -164,14 +160,12 @@ public class SkuShippingQtyJob implements Job { List orderContentsToUpdate = new ArrayList<>(); // Subtract the virtual stock quantity from the orders with missing stock, then update stock availability for (Map.Entry> orderMapEntry : orderMapWithMissingStock.entrySet()) { - System.out.println("Order time : " + orderMapEntry.getKey().getOrderTime()); boolean allContentsHaveStock = true; for(PlatformOrderContent content : orderMapEntry.getValue()) { // subtract the quantity from skuShippingQtyDataMap, if enough stock, set virtualProductAvailable to 1 SkuShippingQtyData skuData = skuShippingQtyDataMap.get(skuIdToErpCodeMap.get(content.getSkuId())); if(skuData == null) { - System.out.println("SKU DATA IS NULL for Sku : " + skuIdToErpCodeMap.get(content.getSkuId())); - System.out.println("Sku ID : " + content.getSkuId()); + log.info("SKU data is null for Sku erpCode : {} - Sku ID : {}", skuIdToErpCodeMap.get(content.getSkuId()), content.getSkuId()); allContentsHaveStock = false; continue; } @@ -197,7 +191,6 @@ public class SkuShippingQtyJob implements Job { // Update the database if(!ordersToUpdate.isEmpty()) { platformOrderService.updateBatchById(ordersToUpdate); - // TODO : send email to client and ask him to pay for shipping fees } if(!orderContentsToUpdate.isEmpty()) { platformOrderContentService.updateBatchById(orderContentsToUpdate); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/shippingInvoice/ShippingInvoiceFactory.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/shippingInvoice/ShippingInvoiceFactory.java index 1079c2753..3712fdb63 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/shippingInvoice/ShippingInvoiceFactory.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/domain/shippingInvoice/ShippingInvoiceFactory.java @@ -370,14 +370,11 @@ public class ShippingInvoiceFactory { emailService.newSendSimpleMessage(destEmail, emailSubject, templateName, templateModel); } // removing orders that can't be invoiced - System.out.println("Orders and content size BEFORE : " + orderAndContent.size()); - System.out.println("Orders to remove size : " + ordersToRemove.size()); for(Map.Entry> entry : ordersToRemove.entrySet()) { for(String platformOrderId : entry.getValue()) { orderAndContent.keySet().removeIf(order -> order.getPlatformOrderId().equals(platformOrderId)); } } - System.out.println("Orders and content size AFTER : " + orderAndContent.size()); BigDecimal eurToUsd = exchangeRatesMapper.getLatestExchangeRate("EUR", "USD"); if(orderAndContent.isEmpty()) { @@ -635,11 +632,9 @@ public class ShippingInvoiceFactory { shops.forEach(shop -> shopPackageMatFeeMap.put(shop.getId(), shop.getPackagingMaterialFee())); String invoiceCode = generateInvoiceCode(); log.info("New invoice code: {}", invoiceCode); - System.out.println("Order and content size BEFORE : " + orderAndContent.size()); Map> ordersWithPB = calculateFees(balance, logisticChannelMap, orderAndContent, channelPriceMap, countryList, skuRealWeights, skuServiceFees, latestDeclaredValues, client, shopServiceFeeMap, shopPackageMatFeeMap, invoiceCode); orderAndContent.entrySet().removeIf(entries -> ordersWithPB.containsKey(entries.getKey().getId())); - System.out.println("Order and content size AFTER : " + orderAndContent.size()); if(orderAndContent.isEmpty()) { log.error("No order was invoiced for customer {} because : {}", client.getInternalCode(), ordersWithPB); throw new UserException("Customer " + customerId + " errors : " + ordersWithPB); @@ -730,9 +725,6 @@ public class ShippingInvoiceFactory { // find logistic channel price for each order based on its content for (PlatformOrder uninvoicedOrder : orderContentMap.keySet()) { if(skip) { - if(client.getInternalCode().equals("FT")) { - System.out.println("uninvoicedOrder order time : " + uninvoicedOrder.getOrderTime()); - } platformOrderIdsWithPb.put(uninvoicedOrder.getId(), Collections.singletonList("Skipped")); continue; } @@ -847,7 +839,6 @@ public class ShippingInvoiceFactory { } // removing orders that can't be invoiced log.info("Number of orders with problem for client {} : {}", client.getInternalCode(), platformOrderIdsWithPb.size()); - platformOrderIdsWithPb.keySet().forEach(System.out::println); return platformOrderIdsWithPb; } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/entity/ClientCategory.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/entity/ClientCategory.java index 8a25ee1e4..ae1ac56b7 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/entity/ClientCategory.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/entity/ClientCategory.java @@ -68,7 +68,7 @@ public class ClientCategory implements Serializable { @Getter public enum CategoryName { - SELF_SERVICE("self_service"), + SELF_SERVICE("self-service"), CONFIRMED ("confirmed"), VIP("vip"); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/entity/OrderContentDetail.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/entity/OrderContentDetail.java index 387e26474..783a70c40 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/entity/OrderContentDetail.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/entity/OrderContentDetail.java @@ -38,9 +38,6 @@ public class OrderContentDetail { */ public BigDecimal totalPrice() { BigDecimal unit = skuDetail.getPrice().getPrice(quantity, exchangeRate); - if(unit == null) { - System.out.println("Unit is null : " + skuDetail.getSkuId() + "sku price: " + skuDetail.getPrice() + "quantity: " + quantity); - } BigDecimal total = unit.multiply(new BigDecimal(quantity)); log.info("unit: {}", unit); log.info("total: {}", total); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/ClientMapper.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/ClientMapper.java index a54760dd0..954e6802e 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/ClientMapper.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/ClientMapper.java @@ -22,4 +22,9 @@ public interface ClientMapper extends BaseMapper { String getClientIdByCode(@Param("code") String code); List getClientByType(@Param("type") String type); Client getClientByCode(@Param("code") String internalCode); + Client getClientFromOrder(@Param("orderId")String orderId); + + Client getClientFromPurchase(@Param("purchaseId") String purchaseId); + + List getClientsFromPurchases(@Param("purchaseIds") List purchaseIds); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PlatformOrderMapper.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PlatformOrderMapper.java index d005af3df..0508b74a5 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PlatformOrderMapper.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PlatformOrderMapper.java @@ -5,6 +5,7 @@ import org.apache.ibatis.annotations.Param; import org.jeecg.modules.business.domain.api.mabang.getorderlist.Order; import org.jeecg.modules.business.entity.PlatformOrder; import org.jeecg.modules.business.entity.PlatformOrderShopSync; +import org.jeecg.modules.business.vo.ShippingFeeBillableOrders; import org.jeecg.modules.business.vo.clientPlatformOrder.ClientPlatformOrderPage; import org.jeecg.modules.business.vo.clientPlatformOrder.section.OrderQuantity; import org.springframework.stereotype.Repository; @@ -200,4 +201,12 @@ public interface PlatformOrderMapper extends BaseMapper { List selectByPlatformOrderIds(@Param("platformOrderIds") List platformOrderIds); void removePurchaseInvoiceNumber(@Param("invoiceNumber") String purchaseInvoiceNumber); + + void removePurchaseInvoiceNumbers(@Param("invoiceNumbers") List invoiceNumbers); + + void updatePurchaseInvoiceNumber(@Param("orderIds") List orderIds, @Param("invoiceNumber") String invoiceNumber); + + List fetchShippingFeeBillableOrders(); + + List getPlatformOrdersByInvoiceNumber(@Param("invoiceNumber") String invoiceNumber); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PurchaseOrderContentMapper.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PurchaseOrderContentMapper.java index bd95433a3..d0d710197 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PurchaseOrderContentMapper.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PurchaseOrderContentMapper.java @@ -25,4 +25,6 @@ public interface PurchaseOrderContentMapper extends BaseMapper void addAll(@Param("creator") String creator, @Param("purchaseID") String purchaseID, @Param("data") List orderContent); List selectInvoiceDataByID(@Param("purchaseID") String purchaseID); + + void deleteFromPurchaseIds(@Param("purchaseIds") List purchaseIds); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PurchaseOrderMapper.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PurchaseOrderMapper.java index 217a7a822..9703f87c1 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PurchaseOrderMapper.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/PurchaseOrderMapper.java @@ -4,6 +4,7 @@ import java.math.BigDecimal; import java.util.List; import org.apache.ibatis.annotations.Param; +import org.jeecg.modules.business.entity.PlatformOrder; import org.jeecg.modules.business.entity.PurchaseOrder; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.springframework.stereotype.Repository; @@ -97,4 +98,10 @@ public interface PurchaseOrderMapper extends BaseMapper { void deleteInvoice(@Param("invoiceNumber") String invoiceNumber); void deleteBatchInvoice(@Param("invoiceNumbers") List invoiceNumbers); + + String getInvoiceId(@Param("invoiceNumber") String invoiceNumber); + + List getPurchasesByInvoiceNumber(@Param("invoiceNumber") String invoiceNumber); + + List getPlatformOrder(@Param("invoiceNumber") String invoiceNumber); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/ClientMapper.xml b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/ClientMapper.xml index a0a5b92a1..31045d414 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/ClientMapper.xml +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/ClientMapper.xml @@ -32,4 +32,30 @@ WHERE cc.name = #{type} AND c.active = 1; + + + \ No newline at end of file diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PlatformOrderMapper.xml b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PlatformOrderMapper.xml index 7abd3c1f9..c9dcd2b91 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PlatformOrderMapper.xml +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PlatformOrderMapper.xml @@ -664,7 +664,7 @@ AND create_time BETWEEN #{startDate} AND #{endDate}; + SELECT CONCAT(c.first_name, ' ', c.surname) as full_name, c.email, po.platform_order_number as order_number + FROM platform_order po + JOIN shop s ON po.shop_id = s.id + JOIN client c ON s.owner_id = c.id + WHERE po.shipping_invoice_number IS NULL + AND po.purchase_invoice_number IS NOT NULL + AND po.erp_status IN (1,2) + AND po.product_available = 1 + + diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PurchaseOrderContentMapper.xml b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PurchaseOrderContentMapper.xml index 7171d6b66..178c19d59 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PurchaseOrderContentMapper.xml +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PurchaseOrderContentMapper.xml @@ -19,6 +19,17 @@ JOIN product p on s.product_id = p.id WHERE purchase_order_id = #{purchaseID} + INSERT INTO purchase_order_sku(id, create_by, create_time, update_by, update_time, purchase_order_id, quantity, @@ -29,4 +40,12 @@ #{item.skuID}) + + DELETE + FROM purchase_order_sku + WHERE purchase_order_id IN + + #{purchaseId} + + diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PurchaseOrderMapper.xml b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PurchaseOrderMapper.xml index b339db052..cef617321 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PurchaseOrderMapper.xml +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/PurchaseOrderMapper.xml @@ -81,4 +81,19 @@ #{invoiceNumber} + + + diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/SkuMapper.xml b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/SkuMapper.xml index d7f3f192d..4f8889007 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/SkuMapper.xml +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/mapper/xml/SkuMapper.xml @@ -146,6 +146,9 @@ #{orderId} + AND erp_status IN ('1','2', '3') + AND product_available = 0 + AND virtual_product_available = 0 GROUP BY sku_id; diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IClientService.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IClientService.java index 0a991e808..2b3151202 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IClientService.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IClientService.java @@ -48,4 +48,10 @@ public interface IClientService extends IService { Client getCurrentClient(); List getClientsByType(String type); + + Client getClientFromOrder(String orderId); + + Client getClientFromPurchase(String purchaseId); + + List getClientsFromPurchases(List purchaseIds); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IPlatformOrderService.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IPlatformOrderService.java index 06ed3ff7a..900055a72 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IPlatformOrderService.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IPlatformOrderService.java @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import org.jeecg.modules.business.controller.UserException; import org.jeecg.modules.business.entity.*; import org.jeecg.modules.business.vo.PlatformOrderQuantity; +import org.jeecg.modules.business.vo.ShippingFeeBillableOrders; import org.jeecg.modules.business.vo.SkuQuantity; import org.jeecg.modules.business.vo.clientPlatformOrder.ClientPlatformOrderPage; import org.jeecg.modules.business.vo.clientPlatformOrder.PurchaseConfirmation; @@ -208,4 +209,14 @@ public interface IPlatformOrderService extends IService { List selectByPlatformOrderIds(List platformOrderIds); void removePurchaseInvoiceNumber(String purchaseInvoiceNumber); + void removePurchaseInvoiceNumbers(List invoiceNumbers); + + void updatePurchaseInvoiceNumber(List orderIds, String invoiceCode); + + /** + * Fetch all orders with productAvailable = 1, purchaseInvoiceNumber NOT NULL, invoiceNumber NULL and erp_status IN (1,2) + * @return + */ + List fetchShippingFeeBillableOrders(); + List getPlatformOrdersByInvoiceNumber(String invoiceNumber); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IPurchaseOrderService.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IPurchaseOrderService.java index de8628a1c..58514970c 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IPurchaseOrderService.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IPurchaseOrderService.java @@ -3,8 +3,8 @@ package org.jeecg.modules.business.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; import org.jeecg.modules.business.controller.UserException; -import org.jeecg.modules.business.domain.purchase.invoice.InvoiceData; import org.jeecg.modules.business.entity.*; +import org.jeecg.modules.business.vo.InvoiceMetaData; import org.jeecg.modules.business.vo.SkuQuantity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -44,6 +44,12 @@ public interface IPurchaseOrderService extends IService { */ public void delBatchMain(Collection idList); + @Transactional + void cancelInvoice(String purchaseId, String invoiceNumber); + + @Transactional + void cancelBatchInvoice(String ids); + /** * Set purchase orders to the page indicated by argument. * @@ -104,7 +110,7 @@ public interface IPurchaseOrderService extends IService { * @return the file in binary * @throws IOException IO error while reading the file. */ - InvoiceData makeInvoice(String purchaseID) throws IOException, URISyntaxException; + InvoiceMetaData makeInvoice(String purchaseID) throws IOException, URISyntaxException; byte[] getInvoiceByte(String invoiceCode) throws IOException; @@ -113,4 +119,10 @@ public interface IPurchaseOrderService extends IService { void cancelInvoice(String invoiceNumber); void cancelBatchInvoice(List invoiceNumbers); + + String getInvoiceId(String invoiceNumber); + + List getPurchasesByInvoiceNumber(String invoiceNumber); + + List getPlatformOrder(String invoiceNumber); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IShippingInvoiceService.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IShippingInvoiceService.java index 940e758dd..652a3dd6f 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IShippingInvoiceService.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/IShippingInvoiceService.java @@ -4,6 +4,7 @@ import org.jeecg.modules.business.entity.*; import com.baomidou.mybatisplus.extension.service.IService; import java.io.Serializable; +import java.nio.file.Path; import java.util.Collection; import java.util.List; @@ -40,4 +41,10 @@ public interface IShippingInvoiceService extends IService { public List getPlatformOrderContent(String platformOrderId); public Client getShopOwnerFromInvoiceNumber(String invoiceNumber); Currency getInvoiceCurrencyByCode(String invoiceCode); + + // Utils + public List getPath(String dirPath, String invoiceNumber); + public List getPath(String dirPath, String invoiceNumber, String invoiceEntity); + public String getInvoiceList(String invoiceNumber, String filetype); + boolean deleteAttachmentFile(String filename); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/PlatformOrderShippingInvoiceService.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/PlatformOrderShippingInvoiceService.java index 446f101a4..f97b2abb5 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/PlatformOrderShippingInvoiceService.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/PlatformOrderShippingInvoiceService.java @@ -3,7 +3,6 @@ package org.jeecg.modules.business.service; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import lombok.extern.slf4j.Slf4j; import org.apache.shiro.SecurityUtils; -import org.apache.shiro.subject.Subject; import org.jeecg.common.system.vo.LoginUser; import org.jeecg.modules.business.controller.UserException; import org.jeecg.modules.business.domain.excel.SheetManager; @@ -102,6 +101,9 @@ public class PlatformOrderShippingInvoiceService { @Value("${jeecg.path.shippingInvoiceDir}") private String INVOICE_DIR; + @Value("${jeecg.path.purchaseInvoiceDir}") + private String PURCHASE_INVOICE_DIR; + @Value("${jeecg.path.shippingInvoiceDetailDir}") private String INVOICE_DETAIL_DIR; @@ -343,8 +345,9 @@ public class PlatformOrderShippingInvoiceService { * @return byte array of the file * @throws IOException error when reading file */ - public byte[] getInvoiceBinary(String filename) throws IOException { - Path out = Paths.get(INVOICE_DIR, filename); + public byte[] getInvoiceBinary(String filename, String type) throws IOException { + String path = type.equals("shipping") ? INVOICE_DIR : PURCHASE_INVOICE_DIR; + Path out = Paths.get(path, filename); return Files.readAllBytes(out); } @@ -529,7 +532,6 @@ public class PlatformOrderShippingInvoiceService { invoiceList.add(new InvoiceMetaData("", "error", internalCode, clientId, "No order to invoice.")); continue; } - System.out.println("Period: [" + period.start() + " - " + period.end() + "]"); Calendar calendar = Calendar.getInstance(); calendar.setTime(period.start()); String start = calendar.get(Calendar.YEAR) + "-" + (calendar.get(Calendar.MONTH)+1 < 10 ? "0" : "") + (calendar.get(Calendar.MONTH)+1) + "-" + (calendar.get(Calendar.DAY_OF_MONTH) < 10 ? "0" : "") + (calendar.get(Calendar.DAY_OF_MONTH)); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/BalanceServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/BalanceServiceImpl.java index bbd270076..366e194ab 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/BalanceServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/BalanceServiceImpl.java @@ -1,7 +1,6 @@ package org.jeecg.modules.business.service.impl; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.tuple.Pair; import org.jeecg.modules.business.entity.*; import org.jeecg.modules.business.mapper.BalanceMapper; import org.jeecg.modules.business.mapper.ClientCategoryMapper; @@ -18,8 +17,6 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; /** * @Description: balance @@ -92,15 +89,12 @@ public class BalanceServiceImpl extends ServiceImpl impl SysUser sysUser = new SysUser(); String currency = currencyService.getCodeById(currencyId); Balance balance = balanceMapper.getBalanceByOperation(operationId, operationType); - System.out.println("balance exist ? : " + balance); if(balance == null) { throw new Exception("Balance not found !"); } balanceMapper.deleteBalance(operationId, operationType); BigDecimal currentBalance = balanceMapper.getBalanceByClientIdAndCurrency(clientId, currency); - System.out.println("current balance : " + currentBalance); BigDecimal finalBalance = operationType.equals(Balance.OperationType.Credit.name()) ? currentBalance.add(amount) : currentBalance.subtract(amount); - System.out.println("final balance : " + finalBalance); Balance newBalance = Balance.of(sysUser.getUsername(), clientId, currencyId, operationType, operationId, finalBalance); balanceMapper.insert(newBalance); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/ClientServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/ClientServiceImpl.java index 9a141aa2e..bf763d972 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/ClientServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/ClientServiceImpl.java @@ -123,6 +123,21 @@ public class ClientServiceImpl extends ServiceImpl impleme return clientMapper.getClientByType(type); } + @Override + public Client getClientFromOrder(String orderId) { + return clientMapper.getClientFromOrder(orderId); + } + + @Override + public Client getClientFromPurchase(String purchaseId) { + return clientMapper.getClientFromPurchase(purchaseId); + } + + @Override + public List getClientsFromPurchases(List purchaseIds) { + return clientMapper.getClientsFromPurchases(purchaseIds); + } + @Override public String getClientEntity(String id) { return clientMapper.getClientEntity(id); diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/PlatformOrderServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/PlatformOrderServiceImpl.java index 62ad1e1f2..b6ebfc842 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/PlatformOrderServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/PlatformOrderServiceImpl.java @@ -13,10 +13,7 @@ import org.jeecg.modules.business.mapper.PlatformOrderMapper; import org.jeecg.modules.business.service.IClientService; import org.jeecg.modules.business.service.IPlatformOrderService; import org.jeecg.modules.business.service.IShippingFeesWaiverProductService; -import org.jeecg.modules.business.vo.PlatformOrderQuantity; -import org.jeecg.modules.business.vo.SkuDetail; -import org.jeecg.modules.business.vo.SkuQuantity; -import org.jeecg.modules.business.vo.SkuShippingFeesWaiver; +import org.jeecg.modules.business.vo.*; import org.jeecg.modules.business.vo.clientPlatformOrder.ClientPlatformOrderPage; import org.jeecg.modules.business.vo.clientPlatformOrder.PurchaseConfirmation; import org.jeecg.modules.business.vo.clientPlatformOrder.section.ClientInfo; @@ -290,7 +287,6 @@ public class PlatformOrderServiceImpl extends ServiceImpl>> findUninvoicedOrders() { List orderList = platformOrderMap.findUninvoicedShippedOrders(); - System.out.println("orderList size : " + orderList.size()); List orderContents = platformOrderContentMap.findUninvoicedShippedOrderContents(); Map orderMap = orderList.stream().collect(toMap(PlatformOrder::getId, Function.identity())); Map orderMapByShopId = orderList.stream().collect(toMap(PlatformOrder::getId, PlatformOrder::getShopId)); @@ -441,4 +437,24 @@ public class PlatformOrderServiceImpl extends ServiceImpl invoiceNumbers) { + platformOrderMap.removePurchaseInvoiceNumbers(invoiceNumbers); + } + + @Override + public void updatePurchaseInvoiceNumber(List orderIds, String invoiceCode) { + platformOrderMap.updatePurchaseInvoiceNumber(orderIds, invoiceCode); + } + + @Override + public List fetchShippingFeeBillableOrders() { + return platformOrderMap.fetchShippingFeeBillableOrders(); + } + + @Override + public List getPlatformOrdersByInvoiceNumber(String invoiceNumber) { + return platformOrderMap.getPlatformOrdersByInvoiceNumber(invoiceNumber); + } } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/ShippingInvoiceServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/ShippingInvoiceServiceImpl.java index cde94b7fb..a6c5cedc5 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/ShippingInvoiceServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/ShippingInvoiceServiceImpl.java @@ -1,17 +1,27 @@ package org.jeecg.modules.business.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.jeecg.modules.business.entity.*; import org.jeecg.modules.business.mapper.ShippingInvoiceMapper; import org.jeecg.modules.business.service.IShippingInvoiceService; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.io.File; +import java.io.IOException; import java.io.Serializable; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * @Description: 物流发票 @@ -25,7 +35,31 @@ public class ShippingInvoiceServiceImpl extends ServiceImpl getPath(String dirPath, String invoiceNumber) { + List pathList = new ArrayList<>(); + //Recursively list all files + //The walk() method returns a Stream by walking the file tree beginning with a given starting file/directory in a depth-first manner. + try (Stream stream = Files.walk(Paths.get(dirPath))) { + pathList = stream.map(Path::normalize) + .filter(Files::isRegularFile) // directories, hidden files and files without extension are not included + .filter(path -> path.getFileName().toString().contains(invoiceNumber)) + .filter(path -> path.getFileName().toString().endsWith(EXTENSION.XLSX.getExtension())) + .collect(Collectors.toList()); + } + catch(IOException e) { + e.printStackTrace(); + } + return pathList; + } + + /** Finds the absolute path of invoice file by recursively walking the directory and it's subdirectories + * + * @param dirPath + * @param invoiceNumber + * @return List of paths for the file but should only find one result + */ + public List getPath(String dirPath, String invoiceNumber, String invoiceEntity) { + List pathList = new ArrayList<>(); + //Recursively list all files + //The walk() method returns a Stream by walking the file tree beginning with a given starting file/directory in a depth-first manner. + try (Stream stream = Files.walk(Paths.get(dirPath))) { + pathList = stream.map(Path::normalize) + .filter(Files::isRegularFile) // directories, hidden files and files without extension are not included + .filter(path -> path.getFileName().toString().contains(invoiceNumber)) + .filter(path -> path.getFileName().toString().contains(invoiceEntity)) + .filter(path -> path.getFileName().toString().endsWith(EXTENSION.XLSX.getExtension())) + .collect(Collectors.toList()); + } + catch(IOException e) { + e.printStackTrace(); + } + return pathList; + } + /** Finds the absolute path of any file by recursively walking the directory and it's subdirectories + * + * @param dirPath + * @param filename + * @param extension + * @return List of paths for the file but should only find one result + */ + public List getAttachementPath(String dirPath, String filename, String extension) { + List pathList = new ArrayList<>(); + //Recursively list all files + //The walk() method returns a Stream by walking the file tree beginning with a given starting file/directory in a depth-first manner. + try (Stream stream = Files.walk(Paths.get(dirPath))) { + pathList = stream.map(Path::normalize) + .filter(Files::isRegularFile) // directories, hidden files and files without extension are not included + .filter(path -> path.getFileName().toString().contains(filename)) + .filter(path -> path.getFileName().toString().endsWith(extension)) + .collect(Collectors.toList()); + } + catch(IOException e) { + e.printStackTrace(); + } + return pathList; + } + + /** + * Finds the absolute path of invoice file and return the path + * @param invoiceNumber + * @param filetype if it's an invoice or invoice detail + * @return String returns the path of the invoice file + */ + public String getInvoiceList(String invoiceNumber, String filetype) { + log.info("Invoice number : " + invoiceNumber); + List pathList = new ArrayList<>(); + if(filetype.equals("invoice")) { + log.info("File asked is of type invoice"); + pathList = getPath(INVOICE_LOCATION, invoiceNumber); + } + if(filetype.equals("detail")) { + log.info("File asked is of type invoice detail"); + pathList = getPath(INVOICE_DETAIL_LOCATION, invoiceNumber); + } + if(pathList.isEmpty()) { + log.error("NO INVOICE FILE FOUND : " + invoiceNumber); + return "ERROR"; + } + else { + for (Path path : pathList) { + log.info(path.toString()); + } + return pathList.get(0).toString(); + } + } + + @Override + public boolean deleteAttachmentFile(String filepath) { + String filename = filepath.substring(filepath.lastIndexOf("/")+1, filepath.lastIndexOf(".")); + System.out.println(filename); + String extension = filepath.substring(filepath.lastIndexOf(".")); + + List attachmentPathList = getAttachementPath(UPLOAD_DIR, filename, extension); + boolean isFileDeleted = false; + + if(attachmentPathList.isEmpty()) { + log.error("FILE NOT FOUND : " + filepath); + } else { + for (Path path : attachmentPathList) { + log.info(path.toString()); + } + try { + File attachmentFile = new File(attachmentPathList.get(0).toString()); + if(attachmentFile.delete()) { + log.info("Attachment file {} delete successful.", attachmentPathList.get(0).toString()); + isFileDeleted = true; + } else { + log.error("Attachment file delete fail."); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return isFileDeleted; + } } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/SkuServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/SkuServiceImpl.java index 2bf3ea48c..8f86e0bda 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/SkuServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/SkuServiceImpl.java @@ -181,7 +181,6 @@ public class SkuServiceImpl extends ServiceImpl implements ISkuS public void addInventory(List skuQuantities, List platformOrderIDs) { Objects.requireNonNull(skuQuantities); Objects.requireNonNull(platformOrderIDs); - Map quantityPurchased = skuQuantities.stream() .collect( Collectors.toMap( @@ -189,11 +188,13 @@ public class SkuServiceImpl extends ServiceImpl implements ISkuS SkuQuantity::getQuantity ) ); - // Add surplus of purchased quantity to SKU's "purchasing amount" if (!platformOrderIDs.isEmpty()) { List used = platformOrderContentMapper.searchOrderContent(platformOrderIDs); for (SkuQuantity sq : used) { + if(!quantityPurchased.containsKey(sq.getID())) { + break; + } int quantity = quantityPurchased.get(sq.getID()); quantityPurchased.put(sq.getID(), quantity - sq.getQuantity()); } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/purchase/PurchaseOrderServiceImpl.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/purchase/PurchaseOrderServiceImpl.java index 00fef69cc..7868b1290 100644 --- a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/purchase/PurchaseOrderServiceImpl.java +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/service/impl/purchase/PurchaseOrderServiceImpl.java @@ -2,18 +2,17 @@ package org.jeecg.modules.business.service.impl.purchase; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.SecurityUtils; +import org.jeecg.common.system.vo.LoginUser; import org.jeecg.modules.business.controller.UserException; import org.jeecg.modules.business.domain.codeGeneration.PurchaseInvoiceCodeRule; -import org.jeecg.modules.business.domain.purchase.invoice.InvoiceData; import org.jeecg.modules.business.domain.purchase.invoice.PurchaseInvoice; import org.jeecg.modules.business.domain.purchase.invoice.PurchaseInvoiceEntry; import org.jeecg.modules.business.entity.*; import org.jeecg.modules.business.mapper.*; import org.jeecg.modules.business.service.*; -import org.jeecg.modules.business.vo.OrderContentEntry; -import org.jeecg.modules.business.vo.PromotionDetail; -import org.jeecg.modules.business.vo.PromotionHistoryEntry; -import org.jeecg.modules.business.vo.SkuQuantity; +import org.jeecg.modules.business.vo.*; import org.jeecg.modules.business.vo.clientPlatformOrder.section.OrdersStatisticData; import org.jeecg.modules.message.handle.enums.SendMsgTypeEnum; import org.jeecg.modules.message.util.PushMsgUtil; @@ -41,6 +40,7 @@ import java.util.stream.Collectors; * @Date: 2021-04-03 * @Version: V1.0 */ +@Slf4j @Service public class PurchaseOrderServiceImpl extends ServiceImpl implements IPurchaseOrderService { private final PurchaseOrderMapper purchaseOrderMapper; @@ -55,7 +55,9 @@ public class PurchaseOrderServiceImpl extends ServiceImpl idList) { for (Serializable id : idList) { + String invoiceNumber = purchaseOrderMapper.getInvoiceNumber(id.toString()); purchaseOrderContentMapper.deleteByMainId(id.toString()); skuPromotionHistoryMapper.deleteByMainId(id.toString()); purchaseOrderMapper.deleteById(id); + platformOrderService.removePurchaseInvoiceNumber(invoiceNumber); } } @@ -165,6 +180,114 @@ public class PurchaseOrderServiceImpl extends ServiceImpl invoicePathList = shippingInvoiceService.getPath(INVOICE_DIR, invoiceNumber, invoiceEntity); + List detailPathList = shippingInvoiceService.getPath(INVOICE_DETAIL_DIR, invoiceNumber, invoiceEntity); + boolean invoiceDeleted = false, detailDeleted = false; + + if(invoicePathList.isEmpty()) { + log.error("FILE NOT FOUND : " + invoiceNumber); + } else { + for (Path path : invoicePathList) { + log.info(path.toString()); + } + try { + File invoiceFile = new File(invoicePathList.get(0).toString()); + if(invoiceFile.delete()) { + log.info("Invoice file {} delete successful.", invoicePathList.get(0).toString()); + invoiceDeleted = true; + } else { + log.error("Invoice file delete fail."); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + if(detailPathList.isEmpty()) { + log.error("DETAIL FILE NOT FOUND : " + invoiceNumber); + } else { + for (Path path : detailPathList) { + log.info(path.toString()); + } + try { + File detailFile = new File(detailPathList.get(0).toString()); + if(detailFile.delete()) { + log.info("Detail file {} delete successful.", detailPathList.get(0).toString()); + detailDeleted = true; + } else { + log.error("Detail file delete fail."); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + log.info("Invoice cancel successful." + (invoiceDeleted ? "" : " Failed to delete invoice file.") + (detailDeleted ? "" : " Failed to delete detail file.")); + } + + @Transactional + @Override + public void cancelBatchInvoice(String purchaseIds) { + List purchaseIdList = Arrays.asList(purchaseIds.split(",")); + List purchaseOrders = purchaseOrderMapper.selectBatchIds(purchaseIdList); + List invoiceNumbers = purchaseOrders.stream().map(PurchaseOrder::getInvoiceNumber).collect(Collectors.toList()); + log.info("Cancelling invoices : {}", invoiceNumbers); + platformOrderService.removePurchaseInvoiceNumbers(invoiceNumbers); + cancelBatchInvoice(invoiceNumbers); + purchaseOrderContentMapper.deleteFromPurchaseIds(purchaseIdList); + + log.info("Deleting invoice files ..."); + for(PurchaseOrder purchaseOrder : purchaseOrders) { + if(purchaseOrder.getInvoiceNumber() == null) + continue; + String invoiceNumber = purchaseOrder.getInvoiceNumber(); + String invoiceEntity = clientService.getClientEntity(purchaseOrder.getClientId()); + List invoicePathList = shippingInvoiceService.getPath(INVOICE_DIR, invoiceNumber, invoiceEntity); + List detailPathList = shippingInvoiceService.getPath(INVOICE_DETAIL_DIR, invoiceNumber, invoiceEntity); + + if(invoicePathList.isEmpty()) { + log.error("FILE NOT FOUND : " + invoiceNumber + ", " + invoiceEntity); + } else { + for (Path path : invoicePathList) { + log.info(path.toString()); + } + try { + File invoiceFile = new File(invoicePathList.get(0).toString()); + if(invoiceFile.delete()) { + log.info("Invoice file {} delete successful.", invoicePathList.get(0).toString()); + } else { + log.error("Invoice file delete fail."); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + if(detailPathList.isEmpty()) { + log.error("DETAIL FILE NOT FOUND : " + invoiceNumber + ", " + invoiceEntity); + } else { + for (Path path : detailPathList) { + log.info(path.toString()); + } + try { + File detailFile = new File(detailPathList.get(0).toString()); + if(detailFile.delete()) { + log.info("Detail file {} delete successful.", detailPathList.get(0).toString()); + } else { + log.error("Detail file {} delete fail.", detailPathList.get(0).toString()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + System.gc(); + } + log.info("End of invoice files deletion."); + } @Transactional @Override public void confirmPayment(String purchaseID) { @@ -233,7 +356,16 @@ public class PurchaseOrderServiceImpl extends ServiceImpl details = platformOrderService.searchPurchaseOrderDetail(skuQuantities); OrdersStatisticData data = OrdersStatisticData.makeData(details, null); @@ -245,8 +377,8 @@ public class PurchaseOrderServiceImpl extends ServiceImpl orderContentDetail.getSkuDetail().getPromotion() != Promotion.ZERO_PROMOTION) .map(orderContentDetail -> { String promotion = orderContentDetail.getSkuDetail().getPromotion().getId(); - System.out.println(promotion); int count = orderContentDetail.promotionCount(); return new PromotionHistoryEntry(promotion, count); }).collect(Collectors.toList()); @@ -327,13 +458,13 @@ public class PurchaseOrderServiceImpl extends ServiceImpl orderContentDetail.getSkuDetail().getPromotion() != Promotion.ZERO_PROMOTION) .map(orderContentDetail -> { String promotion = orderContentDetail.getSkuDetail().getPromotion().getId(); - System.out.println(promotion); int count = orderContentDetail.promotionCount(); return new PromotionHistoryEntry(promotion, count); }).collect(Collectors.toList()); @@ -450,22 +580,29 @@ public class PurchaseOrderServiceImpl extends ServiceImpl purchaseOrderSkuList = purchaseOrderContentMapper.selectInvoiceDataByID(purchaseID); List promotionDetails = skuPromotionHistoryMapper.selectPromotionByPurchase(purchaseID); String invoiceCode = purchaseOrderMapper.selectById(purchaseID).getInvoiceNumber(); BigDecimal eurToUsd = exchangeRatesMapper.getLatestExchangeRate("EUR", "USD"); + String filename = "Invoice N°" + invoiceCode + " (" + client.getInvoiceEntity() + ").xlsx"; Path template = Paths.get(INVOICE_TEMPLATE); - Path newInvoice = Paths.get(INVOICE_DIR, invoiceCode + ".xlsx"); + Path newInvoice = Paths.get(INVOICE_DIR, filename); if (Files.notExists(newInvoice)) { Files.copy(template, newInvoice); PurchaseInvoice pv = new PurchaseInvoice(client, invoiceCode, "Purchase Invoice", purchaseOrderSkuList, promotionDetails, eurToUsd); pv.toExcelFile(newInvoice); - return new InvoiceData(pv.client().getInvoiceEntity(), invoiceCode); + return new InvoiceMetaData(filename,invoiceCode, pv.client().getInternalCode(), pv.client().getInvoiceEntity(), ""); } - return new InvoiceData(client.getInvoiceEntity(), invoiceCode); + return new InvoiceMetaData(filename, invoiceCode, client.getInternalCode(), client.getInvoiceEntity(), ""); } @Override @@ -488,4 +625,19 @@ public class PurchaseOrderServiceImpl extends ServiceImpl invoiceNumbers) { purchaseOrderMapper.deleteBatchInvoice(invoiceNumbers); } + + @Override + public String getInvoiceId(String invoiceNumber) { + return purchaseOrderMapper.getInvoiceId(invoiceNumber); + } + + @Override + public List getPurchasesByInvoiceNumber(String invoiceNumber) { + return purchaseOrderMapper.getPurchasesByInvoiceNumber(invoiceNumber); + } + + @Override + public List getPlatformOrder(String invoiceNumber) { + return purchaseOrderMapper.getPlatformOrder(invoiceNumber); + } } diff --git a/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/vo/ShippingFeeBillableOrders.java b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/vo/ShippingFeeBillableOrders.java new file mode 100644 index 000000000..beb7a0599 --- /dev/null +++ b/jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/modules/business/vo/ShippingFeeBillableOrders.java @@ -0,0 +1,10 @@ +package org.jeecg.modules.business.vo; + +import lombok.Data; + +@Data +public class ShippingFeeBillableOrders { + private String fullName; + private String email; + private String orderNumber; +} diff --git a/jeecg-module-system/jeecg-system-biz/src/main/resources/templates/admin/invoiceNotification.ftl b/jeecg-module-system/jeecg-system-biz/src/main/resources/templates/admin/invoiceNotification.ftl new file mode 100644 index 000000000..97c956ad9 --- /dev/null +++ b/jeecg-module-system/jeecg-system-biz/src/main/resources/templates/admin/invoiceNotification.ftl @@ -0,0 +1,17 @@ +<#include "../components/header.ftl"> + + Cher Collègue + + + Un client vient de créer une facture, merci de vérifier les informations liées à la facture : + + + Type de facture : ${invoiceType} + + + Client : ${invoiceEntity} + + + Numéro de facture : ${invoiceNumber} + +<#include "../components/footer.ftl"> \ No newline at end of file diff --git a/jeecg-module-system/jeecg-system-biz/src/main/resources/templates/client/shippingFeeBillableNotification.ftl b/jeecg-module-system/jeecg-system-biz/src/main/resources/templates/client/shippingFeeBillableNotification.ftl new file mode 100644 index 000000000..95066cc71 --- /dev/null +++ b/jeecg-module-system/jeecg-system-biz/src/main/resources/templates/client/shippingFeeBillableNotification.ftl @@ -0,0 +1,20 @@ +<#include "../components/header.ftl"> + + Cher(e) ${fullName}, + + + Vous pouvez dès à présent facturer les frais de livraisons pour ${orderNumbers?size} commande<#if orderNumbers?size > 1>s : + + + +
    + <#list orderNumbers as orderNumber> +
  • ${orderNumber}
  • + +
+ + + + Pour toute information complémentaire nous vous invitons à vous rapprocher de votre conseiller. + +<#include "../components/footer.ftl"> \ No newline at end of file