(wip) invoice management remake

pull/6221/head
Gauthier LO 2024-03-18 10:37:46 +01:00
parent e5fe9a4989
commit dc5713d5c4
24 changed files with 472 additions and 1 deletions

View File

@ -0,0 +1,23 @@
package org.jeecg.modules.business.controller;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "Security-安全管理")
@RestController
@RequestMapping("/security")
@Slf4j
public class SecurityController {
@GetMapping(value = "/isEmployee")
public Result<?> checkIsEmployee () {
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
return Result.ok(!sysUser.getOrgCode().contains("A04"));
}
}

View File

@ -0,0 +1,39 @@
package org.jeecg.modules.business.controller.admin;
import cn.hutool.core.date.DateTime;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.business.service.DashboardService;
import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;
import java.util.Map;
@Api(tags = "Admin-管理员管理")
@RestController
@RequestMapping("/admin")
@Slf4j
public class AdminController {
@Autowired private DashboardService dashboardService;
@Autowired private SysBaseApiImpl sysBaseApi;
@GetMapping(value = "/kpis")
public Result<?> kpis() {
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
List<String> roles = sysBaseApi.getRolesByUsername(sysUser.getUsername());
LocalDateTime start = LocalDateTime.now(ZoneId.of(ZoneId.SHORT_IDS.get("CTT"))).minusMonths(11).withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
LocalDateTime end = LocalDateTime.now(ZoneId.of(ZoneId.SHORT_IDS.get("CTT")));
Map<String, ?> kpiMap = dashboardService.getKpis(start, end, roles, sysUser.getUsername());
return Result.ok(kpiMap);
}
}

View File

@ -0,0 +1,36 @@
package org.jeecg.modules.business.controller.admin;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.business.entity.Invoice;
import org.jeecg.modules.business.service.InvoiceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@Api(tags = "发票")
@RestController
@RequestMapping("/invoice")
@Slf4j
public class InvoiceViewController {
@Autowired
private InvoiceService invoiceService;
@GetMapping(value = "/list")
public Result<?> list(Invoice invoice, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<Invoice> queryWrapper = QueryGenerator.initQueryWrapper(invoice, req.getParameterMap());
Page<Invoice> page = new Page<>(pageNo, pageSize);
IPage<Invoice> pageList = invoiceService.page(page, queryWrapper);
return Result.ok(pageList);
}
}

View File

@ -519,4 +519,25 @@ public class ShippingInvoiceController {
log.info("End of invoice files deletion.");
return Result.ok("Invoices cancellation finished.");
}
@PostMapping(value = "/setPaid")
public Result<?> setPaid(@RequestBody List<String> invoiceNumbers) {
log.info("Setting invoice numbers : {} to paid.", invoiceNumbers);
System.out.println("Setting invoice numbers list : " + invoiceNumbers + " to paid.");
List<String> purchaseNumbers = invoiceNumbers.stream().filter(invoice -> invoice.charAt(8) == '1' || invoice.charAt(8) == '7').collect(Collectors.toList());
List<String> shippingNumbers = invoiceNumbers.stream().filter(invoice -> invoice.charAt(8) == '2' || invoice.charAt(8) == '7').collect(Collectors.toList());
System.out.println("Purchase numbers : " + purchaseNumbers);
System.out.println("Shipping numbers : " + shippingNumbers);
if(purchaseNumbers.isEmpty() && shippingNumbers.isEmpty()) {
return Result.error("No invoice numbers found.");
}
if(!purchaseNumbers.isEmpty())
purchaseOrderService.setPaid(purchaseNumbers);
if(!shippingNumbers.isEmpty())
shippingInvoiceService.setPaid(shippingNumbers);
return Result.ok("Invoice set to paid.");
}
}

View File

@ -0,0 +1,96 @@
package org.jeecg.modules.business.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* @Description:
* @Author: jeecg-boot
* @Date: 2022-12-20
* @Version: V1.0
*/
@ApiModel(value = "invoice对象", description = "发票")
@Data
@TableName("all_invoices")
public class Invoice implements Serializable {
private static final long serialVersionUID = 1L;
/**
*
*/
@TableId(type = IdType.ASSIGN_UUID)
@ApiModelProperty(value = "主键")
private String id;
/**
*
*/
@ApiModelProperty(value = "创建人")
private String createBy;
/**
*
*/
@JsonFormat(timezone = "GMT+2", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建日期")
private Date createTime;
/**
* ID
*/
@Dict(dictTable = "client", dicText = "internal_code", dicCode = "id")
@Excel(name = "客户", width = 15)
@ApiModelProperty(value = "客户")
private String clientId;
/**
* currency ID
* */
@Dict(dictTable = "currency", dicText = "code", dicCode = "id")
@Excel(name = "currencyID", width = 15)
@ApiModelProperty(value = "currency ID")
private String currencyId;
/**
*
*/
@Excel(name = "发票号码", width = 15)
@ApiModelProperty(value = "发票号码")
private String invoiceNumber;
/**
*
*/
@Excel(name = "应付金额", width = 15)
@ApiModelProperty(value = "应付金额")
private BigDecimal totalAmount;
/**
*
*/
@Excel(name = "减免金额", width = 15)
@ApiModelProperty(value = "减免金额")
private BigDecimal discountAmount;
/**
*
*/
@Excel(name = "最终金额", width = 15)
@ApiModelProperty(value = "最终金额")
private BigDecimal finalAmount;
/**
*
*/
@Excel(name = "已付金额", width = 15)
@ApiModelProperty(value = "已付金额")
private BigDecimal paidAmount;
@Excel(name = "type", width = 15)
@ApiModelProperty(value = "type")
private String type;
}

View File

@ -30,7 +30,7 @@ public class ShippingInvoice implements Serializable {
/**
*
*/
@TableId(type = IdType.ASSIGN_ID)
@TableId(type = IdType.ASSIGN_UUID)
@ApiModelProperty(value = "主键")
private String id;
/**

View File

@ -0,0 +1,9 @@
package org.jeecg.modules.business.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.business.entity.Invoice;
import org.springframework.stereotype.Repository;
@Repository
public interface InvoiceMapper extends BaseMapper<Invoice> {
}

View File

@ -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.OrderKpi;
import org.jeecg.modules.business.vo.ShippingFeeBillableOrders;
import org.jeecg.modules.business.vo.clientPlatformOrder.ClientPlatformOrderPage;
import org.jeecg.modules.business.vo.clientPlatformOrder.section.OrderQuantity;
@ -13,6 +14,7 @@ import org.springframework.stereotype.Repository;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* @Description:
@ -214,4 +216,5 @@ public interface PlatformOrderMapper extends BaseMapper<PlatformOrder> {
List<PlatformOrder> getPlatformOrdersByInvoiceNumber(@Param("invoiceNumber") String invoiceNumber);
OrderKpi countPlatformOrders(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end, @Param("showAllData") boolean showAllData, @Param("username") String username);
}

View File

@ -1,12 +1,15 @@
package org.jeecg.modules.business.mapper;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
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.jeecg.modules.business.vo.InvoiceKpi;
import org.jeecg.modules.business.vo.InvoiceMetaData;
import org.jeecg.modules.business.vo.PurchaseOrderPage;
import org.jeecg.modules.business.vo.SkuQuantity;
@ -118,4 +121,7 @@ public interface PurchaseOrderMapper extends BaseMapper<PurchaseOrder> {
long countPurchaseOrders();
void updatePurchaseOrderStatus(@Param("invoiceNumber") String invoiceNumber, @Param("isOrdered") boolean isOrdered);
InvoiceKpi countPurchaseInvoices(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end, @Param("showAllData") boolean showAllData, @Param("username") String username);
void setPaid(@Param("invoiceNumbers") List<String> invoiceNumbers);
}

View File

@ -3,9 +3,13 @@ package org.jeecg.modules.business.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.business.entity.*;
import org.jeecg.modules.business.vo.InvoiceKpi;
import org.springframework.stereotype.Repository;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
/**
* @Description:
@ -21,4 +25,7 @@ public interface ShippingInvoiceMapper extends BaseMapper<ShippingInvoice> {
List<PlatformOrderContent> fetchPlatformOrderContent(@Param("platformOrderId") String platformOrderId);
Client fetchShopOwnerFromInvoiceNumber(@Param("invoiceNumber") String invoiceNumber);
Currency fetchInvoiceCurrencyByCode(@Param("invoiceNumber") String invoiceCode);
InvoiceKpi countShippingInvoices(@Param("start") LocalDateTime start, @Param("end") LocalDateTime end, @Param("showAllData") boolean showAllData, @Param("username") String username);
void setPaid(@Param("invoiceNumbers") List<String> invoiceNumbers);
}

View File

@ -839,4 +839,22 @@
FROM platform_order
WHERE shipping_invoice_number = #{invoiceNumber};
</select>
<select id="countPlatformOrders" resultType="org.jeecg.modules.business.vo.OrderKpi">
WITH processed AS (
SELECT COUNT(*) AS processed
FROM platform_order
WHERE erp_status = 4
AND shipping_invoice_number IS NOT NULL
AND order_time BETWEEN #{start} AND #{end}
AND IF(#{showAllData} = false, create_by = #{username}, true)
), processing AS (
SELECT COUNT(*) AS processing
FROM platform_order
WHERE erp_status IN (1,2,3)
AND order_time BETWEEN #{start} AND #{end}
AND IF(#{showAllData} = false, create_by = #{username}, true)
)
SELECT processed, processing
FROM processed, processing;
</select>
</mapper>

View File

@ -139,4 +139,34 @@
SET ordered = #{isOrdered}
WHERE invoice_number = #{invoiceNumber}
</update>
<select id="countPurchaseInvoices" resultType="org.jeecg.modules.business.vo.InvoiceKpi">
WITH shippingEur AS (
SELECT IFNULL(count(*),0) as qty, IFNULL(sum(final_amount),0) as total
FROM purchase_order
WHERE create_time BETWEEN #{start} AND #{end}
AND currency_id = (SELECT id FROM currency WHERE code = 'EUR')
AND IF(#{showAllData} = false, create_by = #{username}, true)
), usdExchangeRate AS (
SELECT rate
FROM exchange_rates
WHERE original_currency = 'EUR' AND target_currency = 'USD'
ORDER BY create_time DESC LIMIT 1
), shippingUsd AS (
SELECT IFNULL(count(*),0) as qty, IFNULL(sum(final_amount/(SELECT rate FROM usdExchangeRate)),0) as total
FROM shipping_invoice
WHERE create_time BETWEEN #{start} AND #{end}
AND currency_id = (SELECT id FROM currency WHERE code = 'USD')
AND IF(#{showAllData} = false, create_by = #{username}, true)
)
SELECT (shippingEur.qty + shippingUsd.qty) as qty, ROUND(shippingEur.total + shippingUsd.total, 2) as total
FROM shippingEur, usdExchangeRate, shippingUsd
</select>
<update id="setPaid">
UPDATE purchase_order
SET paid_amount = final_amount
WHERE invoice_number IN
<foreach collection="invoiceNumbers" item="invoiceNumber" index="index" open="(" separator="," close=")">
#{invoiceNumber}
</foreach>
</update>
</mapper>

View File

@ -35,4 +35,34 @@
JOIN currency c ON s.currency_id = c.id
WHERE invoice_number = #{invoiceNumber}
</select>
<select id="countShippingInvoices" resultType="org.jeecg.modules.business.vo.InvoiceKpi">
WITH shippingEur AS (
SELECT IFNULL(count(*),0) as qty, IFNULL(sum(final_amount),0) as total
FROM shipping_invoice
WHERE create_time BETWEEN #{start} AND #{end}
AND currency_id = (SELECT id FROM currency WHERE code = 'EUR')
AND IF(#{showAllData} = false, create_by = #{username}, true)
), usdExchangeRate AS (
SELECT rate
FROM exchange_rates
WHERE original_currency = 'EUR' AND target_currency = 'USD'
ORDER BY create_time DESC LIMIT 1
), shippingUsd AS (
SELECT IFNULL(count(*),0) as qty, IFNULL(sum(final_amount/(SELECT rate FROM usdExchangeRate)),0) as total
FROM shipping_invoice
WHERE create_time BETWEEN #{start} AND #{end}
AND currency_id = (SELECT id FROM currency WHERE code = 'USD')
AND IF(#{showAllData} = false, create_by = #{username}, true)
)
SELECT (shippingEur.qty + shippingUsd.qty) as qty, ROUND(shippingEur.total + shippingUsd.total, 2) as total
FROM shippingEur, usdExchangeRate, shippingUsd
</select>
<update id="setPaid">
UPDATE shipping_invoice
SET paid_amount = final_amount
WHERE invoice_number IN
<foreach collection="invoiceNumbers" item="invoiceNumber" open="(" separator="," close=")">
#{invoiceNumber}
</foreach>
</update>
</mapper>

View File

@ -0,0 +1,9 @@
package org.jeecg.modules.business.service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
public interface DashboardService {
Map<String,?> getKpis(LocalDateTime start, LocalDateTime end, List<String> roles, String username);
}

View File

@ -137,4 +137,6 @@ public interface IPurchaseOrderService extends IService<PurchaseOrder> {
void setPageForList(Page<PurchaseOrderPage> page);
void updatePurchaseOrderStatus(String invoiceNumber, boolean isOrdered);
void setPaid(List<String> invoiceNumbers);
}

View File

@ -47,4 +47,6 @@ public interface IShippingInvoiceService extends IService<ShippingInvoice> {
public List<Path> getPath(String dirPath, String invoiceNumber, String invoiceEntity);
public String getInvoiceList(String invoiceNumber, String filetype);
boolean deleteAttachmentFile(String filename);
void setPaid(List<String> invoiceNumbers);
}

View File

@ -0,0 +1,8 @@
package org.jeecg.modules.business.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.business.entity.Invoice;
public interface InvoiceService extends IService<Invoice> {
}

View File

@ -0,0 +1,67 @@
package org.jeecg.modules.business.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.business.mapper.PlatformOrderMapper;
import org.jeecg.modules.business.mapper.PurchaseOrderMapper;
import org.jeecg.modules.business.mapper.ShippingInvoiceMapper;
import org.jeecg.modules.business.service.DashboardService;
import org.jeecg.modules.business.vo.InvoiceKpi;
import org.jeecg.modules.business.vo.Kpi;
import org.jeecg.modules.business.vo.OrderKpi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@Slf4j
@Service
public class DashboardServiceImpl implements DashboardService {
@Autowired
private ShippingInvoiceMapper shippingInvoiceMapper;
@Autowired
private PurchaseOrderMapper purchaseOrderMapper;
@Autowired
private PlatformOrderMapper platformOrderMapper;
@Override
public Map<String,?> getKpis(LocalDateTime start, LocalDateTime end, List<String> roles, String username) {
boolean showAllData = roles.contains("admin") || roles.contains("dev");
LocalDateTime startLag = start.minusYears(1);
LocalDateTime endLag = end.minusYears(1);
InvoiceKpi shippingInvoices = shippingInvoiceMapper.countShippingInvoices(start, end, showAllData, username);
InvoiceKpi purchaseInvoices = purchaseOrderMapper.countPurchaseInvoices(start, end, showAllData, username);
OrderKpi platformOrders = platformOrderMapper.countPlatformOrders(start, end, showAllData, username);
InvoiceKpi shippingInvoicesLag = shippingInvoiceMapper.countShippingInvoices(startLag, endLag, showAllData, username);
InvoiceKpi purchaseInvoicesLag = purchaseOrderMapper.countPurchaseInvoices(startLag, endLag, showAllData, username);
OrderKpi platformOrdersLag = platformOrderMapper.countPlatformOrders(startLag, endLag, showAllData, username);
BigDecimal shipTotal = BigDecimal.valueOf(shippingInvoices.getTotal().doubleValue());
BigDecimal shipTotalLag = BigDecimal.valueOf(shippingInvoicesLag.getTotal().doubleValue());
BigDecimal purchaseTotal = BigDecimal.valueOf(purchaseInvoices.getTotal().doubleValue());
BigDecimal purchaseTotalLag = BigDecimal.valueOf(purchaseInvoicesLag.getTotal().doubleValue());
BigDecimal growthShippingInvoicesTotal = shipTotal.subtract(shipTotalLag).divide(shipTotalLag, 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
BigDecimal growthShippingInvoicesQty = BigDecimal.valueOf(shippingInvoices.getQty()).subtract(BigDecimal.valueOf(shippingInvoicesLag.getQty())).divide(BigDecimal.valueOf(shippingInvoicesLag.getQty()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
BigDecimal growthPurchaseInvoicesTotal = purchaseTotal.subtract(purchaseTotalLag).divide(purchaseTotalLag, 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
BigDecimal growthPurchaseInvoicesQty = BigDecimal.valueOf(purchaseInvoices.getQty()).subtract(BigDecimal.valueOf(purchaseInvoicesLag.getQty())).divide(BigDecimal.valueOf(purchaseInvoicesLag.getQty()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
BigDecimal 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.setGrowthQty(growthShippingInvoicesQty);
purchaseInvoices.setGrowthTotal(growthPurchaseInvoicesTotal);
purchaseInvoices.setGrowthQty(growthPurchaseInvoicesQty);
platformOrders.setGrowth(growthPlatformOrders);
Map<String, Kpi> kpis = new HashMap<>();
kpis.put("shippingInvoices", shippingInvoices);
kpis.put("purchaseInvoices", purchaseInvoices);
kpis.put("platformOrders", platformOrders);
return kpis;
}
}

View File

@ -0,0 +1,14 @@
package org.jeecg.modules.business.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.business.entity.Invoice;
import org.jeecg.modules.business.mapper.InvoiceMapper;
import org.jeecg.modules.business.service.InvoiceService;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class InvoiceServiceImpl extends ServiceImpl<InvoiceMapper, Invoice> implements InvoiceService {
}

View File

@ -257,4 +257,9 @@ public class ShippingInvoiceServiceImpl extends ServiceImpl<ShippingInvoiceMappe
}
return isFileDeleted;
}
@Override
public void setPaid(List<String> invoiceNumbers) {
shippingInvoiceMapper.setPaid(invoiceNumbers);
}
}

View File

@ -742,4 +742,9 @@ public class PurchaseOrderServiceImpl extends ServiceImpl<PurchaseOrderMapper, P
public void updatePurchaseOrderStatus(String invoiceNumber, boolean isOrdered) {
purchaseOrderMapper.updatePurchaseOrderStatus(invoiceNumber, isOrdered);
}
@Override
public void setPaid(List<String> invoiceNumber) {
purchaseOrderMapper.setPaid(invoiceNumber);
}
}

View File

@ -0,0 +1,19 @@
package org.jeecg.modules.business.vo;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class InvoiceKpi extends Kpi{
private Long qty;
private Long total;
private BigDecimal growthQty;
private BigDecimal growthTotal;
public InvoiceKpi(Long qty, Long total) {
this.qty = qty;
this.total = total;
}
}

View File

@ -0,0 +1,4 @@
package org.jeecg.modules.business.vo;
public class Kpi {
}

View File

@ -0,0 +1,18 @@
package org.jeecg.modules.business.vo;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class OrderKpi extends Kpi {
private Long processed;
private Long processing;
private BigDecimal growth;
public OrderKpi(Long processed, Long processing) {
this.processed = processed;
this.processing = processing;
}
}