feat: export invoice detail

pull/8040/head
Gauthier LO 2024-12-11 16:45:08 +01:00
parent 8cf45c1389
commit f1e4e4467a
7 changed files with 50 additions and 37 deletions

View File

@ -45,6 +45,8 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.jeecg.modules.business.entity.Invoice.isInvoiceNumber;
/** /**
* @Description: API Handler related admin purchase order * @Description: API Handler related admin purchase order
* @Author: Wenke * @Author: Wenke
@ -596,7 +598,7 @@ public class PurchaseOrderController {
.collect(Collectors.toList()); .collect(Collectors.toList());
List<String> results = future.stream().map(CompletableFuture::join).collect(Collectors.toList()); List<String> results = future.stream().map(CompletableFuture::join).collect(Collectors.toList());
long nbSuccesses = results.stream().filter(PurchaseOrderController::isInvoiceNumber).count(); long nbSuccesses = results.stream().filter(Invoice::isInvoiceNumber).count();
log.info("{}/{} purchase order requests have succeeded.", nbSuccesses, invoiceNumbers.size()); log.info("{}/{} purchase order requests have succeeded.", nbSuccesses, invoiceNumbers.size());
Map<String, List<String>> data = new HashMap<>(); Map<String, List<String>> data = new HashMap<>();
@ -616,7 +618,4 @@ public class PurchaseOrderController {
data.put("success", successInvoices); data.put("success", successInvoices);
return Result.OK(data); return Result.OK(data);
} }
public static boolean isInvoiceNumber(String invoiceNumber) {
return invoiceNumber.matches("^[0-9]{4}-[0-9]{2}-[127][0-9]{3}$");
}
} }

View File

@ -763,11 +763,11 @@ public class InvoiceController {
@RequestParam("endDate") String endDate, @RequestParam("endDate") String endDate,
@RequestParam("type") String type @RequestParam("type") String type
) throws IOException, UserException { ) throws IOException, UserException {
// TODO : fix this + fix missing sku_price log.info("Request for downloading invoice detail by client and period : \nclient : {} \nshops : {}\nstart date : {}\nend date : {}\ntype : {}", clientId, shopIds, startDate, endDate, type);
System.out.println("Request for downloading invoice detail by client and period : " + clientId + " " + shopIds + " " + startDate + " " + endDate + " " + type);
List<FactureDetail> invoiceDetails = shippingInvoiceService.getInvoiceDetailByShopsAndPeriod(shopIds, startDate, endDate, type); List<FactureDetail> invoiceDetails = shippingInvoiceService.getInvoiceDetailByShopsAndPeriod(shopIds, startDate, endDate, type);
Client client = clientService.getById(clientId); Client client = clientService.getById(clientId);
return shippingInvoiceService.exportToExcel(invoiceDetails, Collections.emptyList(), Collections.emptyList(), "", client.getInvoiceEntity(), client.getInternalCode()); String period = startDate + "-" + endDate;
return shippingInvoiceService.exportToExcel(invoiceDetails, Collections.emptyList(), Collections.emptyList(), period, client.getInvoiceEntity(), client.getInternalCode());
} }
@GetMapping(value = "/downloadInvoiceInventory") @GetMapping(value = "/downloadInvoiceInventory")

View File

@ -97,22 +97,29 @@ public class Invoice implements Serializable {
@Getter @Getter
public enum InvoiceType { public enum InvoiceType {
PURCHASE('1'), PURCHASE(1, "purchase_invoice"),
SHIPPING('2'), SHIPPING(2, "shipping_invoice"),
COMPLETE('7'); COMPLETE(7, "complete_invoice");
private final char type; private final int type;
private final String text;
InvoiceType(char type) { InvoiceType(int type, String text) {
this.type = type; this.type = type;
this.text = text;
} }
} }
public static String getType(String invoiceNumber) { public static String getType(String invoiceNumber) {
for(InvoiceType type : InvoiceType.values()) { for(InvoiceType type : InvoiceType.values()) {
if(type.getType() == invoiceNumber.charAt(8)) // you can get the int value of a decimal digit char by subtracting '0'
int typeNumber = invoiceNumber.charAt(8) - '0';
if(type.getType() == typeNumber)
return type.name(); return type.name();
} }
throw new IllegalArgumentException("Incorrect invoice number : " + invoiceNumber); throw new IllegalArgumentException("Incorrect invoice number : " + invoiceNumber);
} }
public static boolean isInvoiceNumber(String invoiceNumber) {
return invoiceNumber.matches("^[0-9]{4}-[0-9]{2}-[127][0-9]{3}$");
}
} }

View File

@ -2,6 +2,16 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.business.mapper.FactureDetailMapper"> <mapper namespace="org.jeecg.modules.business.mapper.FactureDetailMapper">
<select id="selectByShopsAndPeriod" resultType="org.jeecg.modules.business.vo.FactureDetail"> <select id="selectByShopsAndPeriod" resultType="org.jeecg.modules.business.vo.FactureDetail">
WITH LatestPrices AS (
SELECT sp.sku_id, sp.price, sp.date
FROM sku_price sp
JOIN (
SELECT sku_id, MAX(date) AS max_date
FROM sku_price
WHERE date &lt;= #{end} -- Upper limit of date range
GROUP BY sku_id
) latest ON sp.sku_id = latest.sku_id AND sp.date = latest.max_date
)
SELECT s.name AS 'Boutique', SELECT s.name AS 'Boutique',
po.platform_order_id AS 'N° de Mabang', po.platform_order_id AS 'N° de Mabang',
po.platform_order_number AS 'N° de commande', po.platform_order_number AS 'N° de commande',
@ -14,19 +24,12 @@
JSON_ARRAYAGG(sku.erp_code) AS 'SKU', JSON_ARRAYAGG(sku.erp_code) AS 'SKU',
JSON_ARRAYAGG(sku.en_name) AS 'Nom produits', JSON_ARRAYAGG(sku.en_name) AS 'Nom produits',
JSON_ARRAYAGG(poc.quantity) AS 'Quantité', JSON_ARRAYAGG(poc.quantity) AS 'Quantité',
SUM( COALESCE(SUM(
IF (poc.purchase_fee = 0, CASE
poc.quantity * WHEN poc.purchase_fee = 0 THEN poc.quantity * lp.price
(SELECT price ELSE poc.purchase_fee
FROM sku_price sp END
WHERE sku_id = poc.sku_id ),0) AS 'Frais d\'achat',
AND sp.date &lt;= po.order_time
ORDER BY sp.date DESC
LIMIT 1
),
poc.purchase_fee
)
) AS 'Frais d\'achat',
po.fret_fee AS 'Frais de FRET', po.fret_fee AS 'Frais de FRET',
SUM(poc.shipping_fee) AS 'Frais de livraison', SUM(poc.shipping_fee) AS 'Frais de livraison',
po.order_service_fee + SUM(poc.service_fee) AS 'Frais de service', po.order_service_fee + SUM(poc.service_fee) AS 'Frais de service',
@ -38,6 +41,7 @@
JOIN shop s ON po.shop_id = s.id JOIN shop s ON po.shop_id = s.id
RIGHT JOIN platform_order_content poc ON po.id = poc.platform_order_id RIGHT JOIN platform_order_content poc ON po.id = poc.platform_order_id
JOIN sku ON poc.sku_id = sku.id JOIN sku ON poc.sku_id = sku.id
LEFT JOIN LatestPrices lp ON poc.sku_id = lp.sku_id AND lp.date &lt;= po.order_time
WHERE shipping_invoice_number IS NOT NULL WHERE shipping_invoice_number IS NOT NULL
AND poc.erp_status &lt;&gt; 5 AND poc.erp_status &lt;&gt; 5
AND po.order_time &gt; #{start} AND po.order_time &gt; #{start}

View File

@ -129,6 +129,8 @@ public class PlatformOrderShippingInvoiceService {
private String INVOICE_PDF_DIR; private String INVOICE_PDF_DIR;
@Value("${jeecg.path.shippingInvoiceDetailPdfDir}") @Value("${jeecg.path.shippingInvoiceDetailPdfDir}")
private String INVOICE_DETAIL_PDF_DIR; private String INVOICE_DETAIL_PDF_DIR;
@Value("${jeecg.path.invoiceDetailExportDir}")
private String INVOICE_DETAIL_EXPORT_DIR;
private static final String EXTENSION = ".xlsx"; private static final String EXTENSION = ".xlsx";
private final static String[] DETAILS_TITLES = { private final static String[] DETAILS_TITLES = {
@ -431,12 +433,12 @@ public class PlatformOrderShippingInvoiceService {
} }
public List<FactureDetail> getInvoiceDetailByShopsAndPeriod(List<String> shopIds, String startDate, String endDate, String type) throws UserException { public List<FactureDetail> getInvoiceDetailByShopsAndPeriod(List<String> shopIds, String startDate, String endDate, String type) throws UserException {
if(!type.equals(InvoiceType.SHIPPING_INVOICE.getCode()) && !type.equals(InvoiceType.COMPLETE_INVOICE.getCode())) if(!type.equals(String.valueOf(SHIPPING.getType())) && !type.equals(String.valueOf(COMPLETE.getType())))
throw new UserException("Invalid invoice type"); throw new UserException("Invalid invoice type");
return factureDetailMapper.selectByShopsAndPeriod(shopIds, startDate, endDate, type); return factureDetailMapper.selectByShopsAndPeriod(shopIds, startDate, endDate, type);
} }
public byte[] exportToExcel(List<FactureDetail> details, List<SavRefundWithDetail> refunds, List<ExtraFeeResult> extraFees, String invoiceNumber, String invoiceEntity, String internalCode) throws IOException { public byte[] exportToExcel(List<FactureDetail> details, List<SavRefundWithDetail> refunds, List<ExtraFeeResult> extraFees, String fileNameInfo, String invoiceEntity, String internalCode) throws IOException {
SheetManager sheetManager = SheetManager.createXLSX(); SheetManager sheetManager = SheetManager.createXLSX();
sheetManager.startDetailsSheet(); sheetManager.startDetailsSheet();
for (String title : DETAILS_TITLES) { for (String title : DETAILS_TITLES) {
@ -545,11 +547,11 @@ public class PlatformOrderShippingInvoiceService {
sheetManager.moveCol(0); sheetManager.moveCol(0);
sheetManager.nextRow(); sheetManager.nextRow();
} }
String dir = Invoice.isInvoiceNumber(fileNameInfo) ? INVOICE_DETAIL_DIR : INVOICE_DETAIL_EXPORT_DIR;
Path target = Paths.get(INVOICE_DETAIL_DIR, internalCode + "_(" + invoiceEntity + ")_" + invoiceNumber + "_Détail_calcul_de_facture.xlsx"); Path target = Paths.get(dir, internalCode + "_(" + invoiceEntity + ")_" + fileNameInfo + "_Détail_calcul_de_facture.xlsx");
int i = 2; int i = 2;
while (Files.exists(target)) { while (Files.exists(target)) {
target = Paths.get(INVOICE_DETAIL_DIR, internalCode + "_(" + invoiceEntity + ")_" + invoiceNumber + "_Détail_calcul_de_facture_(" + i + ").xlsx"); target = Paths.get(dir, internalCode + "_(" + invoiceEntity + ")_" + fileNameInfo + "_Détail_calcul_de_facture_(" + i + ").xlsx");
i++; i++;
} }
Files.createFile(target); Files.createFile(target);

View File

@ -53,15 +53,15 @@ public class DashboardServiceImpl implements DashboardService {
BigDecimal growthPurchaseInvoicesQty = BigDecimal.ZERO; BigDecimal growthPurchaseInvoicesQty = BigDecimal.ZERO;
BigDecimal growthPlatformOrders = BigDecimal.ZERO; BigDecimal growthPlatformOrders = BigDecimal.ZERO;
if ((shipTotalLag.compareTo(BigDecimal.ZERO) > 0)) if (shipTotalLag.compareTo(BigDecimal.ZERO) > 0)
growthShippingInvoicesTotal = shipTotal.subtract(shipTotalLag).divide(shipTotalLag, 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)); growthShippingInvoicesTotal = shipTotal.subtract(shipTotalLag).divide(shipTotalLag, 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
if ((shippingInvoicesLag.getQty() > 0)) if (shippingInvoicesLag.getQty() > 0)
growthShippingInvoicesQty = BigDecimal.valueOf(shippingInvoices.getQty()).subtract(BigDecimal.valueOf(shippingInvoicesLag.getQty())).divide(BigDecimal.valueOf(shippingInvoicesLag.getQty()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)); growthShippingInvoicesQty = BigDecimal.valueOf(shippingInvoices.getQty()).subtract(BigDecimal.valueOf(shippingInvoicesLag.getQty())).divide(BigDecimal.valueOf(shippingInvoicesLag.getQty()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
if (!(purchaseTotalLag.compareTo(BigDecimal.ZERO) > 0)) if (purchaseTotalLag.compareTo(BigDecimal.ZERO) > 0)
growthPurchaseInvoicesTotal = purchaseTotal.subtract(purchaseTotalLag).divide(purchaseTotalLag, 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)); growthPurchaseInvoicesTotal = purchaseTotal.subtract(purchaseTotalLag).divide(purchaseTotalLag, 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
if ((purchaseInvoicesLag.getQty() > 0)) if (purchaseInvoicesLag.getQty() > 0)
growthPurchaseInvoicesQty = BigDecimal.valueOf(purchaseInvoices.getQty()).subtract(BigDecimal.valueOf(purchaseInvoicesLag.getQty())).divide(BigDecimal.valueOf(purchaseInvoicesLag.getQty()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)); growthPurchaseInvoicesQty = BigDecimal.valueOf(purchaseInvoices.getQty()).subtract(BigDecimal.valueOf(purchaseInvoicesLag.getQty())).divide(BigDecimal.valueOf(purchaseInvoicesLag.getQty()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
if ((platformOrdersLag.getProcessed() > 0)) if (platformOrdersLag.getProcessed() > 0)
growthPlatformOrders = BigDecimal.valueOf(platformOrders.getProcessed()).subtract(BigDecimal.valueOf(platformOrdersLag.getProcessed())).divide(BigDecimal.valueOf(platformOrdersLag.getProcessed()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100)); growthPlatformOrders = BigDecimal.valueOf(platformOrders.getProcessed()).subtract(BigDecimal.valueOf(platformOrdersLag.getProcessed())).divide(BigDecimal.valueOf(platformOrdersLag.getProcessed()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
shippingInvoices.setGrowthTotal(growthShippingInvoicesTotal); shippingInvoices.setGrowthTotal(growthShippingInvoicesTotal);

View File

@ -238,6 +238,7 @@ jeecg:
shippingInvoiceDetailDir: /wia/invoices/shippingDetail shippingInvoiceDetailDir: /wia/invoices/shippingDetail
shippingInvoicePdfDir: /wia/invoices/pdf/shipping shippingInvoicePdfDir: /wia/invoices/pdf/shipping
shippingInvoiceDetailPdfDir: /wia/invoices/pdf/shippingDetail shippingInvoiceDetailPdfDir: /wia/invoices/pdf/shippingDetail
invoiceDetailExportDir: /wia/invoices/invoiceDetailExport
# sku csv file for image search # sku csv file for image search
skuCsvPath: /mnt/wia/products/sku.csv skuCsvPath: /mnt/wia/products/sku.csv
# CDG location # CDG location