diff --git a/bms-back/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TmsPriceController.java b/bms-back/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TmsPriceController.java index 3bb2ddfa..50bcd4d7 100644 --- a/bms-back/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TmsPriceController.java +++ b/bms-back/ruoyi-admin/src/main/java/com/ruoyi/web/controller/api/TmsPriceController.java @@ -2,10 +2,13 @@ package com.ruoyi.web.controller.api; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.ruoyi.common.annotation.Anonymous; import com.ruoyi.common.core.controller.BaseController; @@ -13,8 +16,10 @@ import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.config.properties.TmsApiProperties; +import com.ruoyi.price.domain.vo.TmsPriceBillRequest; import com.ruoyi.price.domain.vo.TmsPriceQuoteRequest; import com.ruoyi.price.domain.vo.TmsPriceQuoteResult; +import com.ruoyi.price.service.IPrcBillService; import com.ruoyi.price.service.ITmsPriceQuoteService; /** @@ -35,6 +40,9 @@ public class TmsPriceController extends BaseController @Autowired private ITmsPriceQuoteService tmsPriceQuoteService; + @Autowired + private IPrcBillService prcBillService; + @Autowired private TmsApiProperties tmsApiProperties; @@ -52,6 +60,33 @@ public class TmsPriceController extends BaseController return success(result); } + /** + * Sync order and persist receivable bill (prc_bill / prc_bill_fee). + * Same price match as quote. Same orderNo upserts. + */ + @PostMapping("/bill") + public AjaxResult bill( + @RequestHeader(value = HEADER_API_CODE, required = false) String headerApiCode, + @Validated @RequestBody TmsPriceBillRequest request) + { + assertApiCode(headerApiCode, request == null ? null : request.getApiCode()); + TmsPriceQuoteResult result = prcBillService.bill(request); + return success(result); + } + + /** + * Query receivable bill by orderNo after sync. + */ + @GetMapping("/bill/by-order/{orderNo}") + public AjaxResult getBillByOrder( + @RequestHeader(value = HEADER_API_CODE, required = false) String headerApiCode, + @PathVariable("orderNo") String orderNo, + @RequestParam(value = "apiCode", required = false) String apiCode) + { + assertApiCode(headerApiCode, apiCode); + return success(prcBillService.getBillByOrderNo(orderNo)); + } + private void assertApiCode(String headerApiCode, String bodyApiCode) { String expected = tmsApiProperties.getApiCode(); diff --git a/bms-back/ruoyi-admin/src/main/java/com/ruoyi/web/controller/price/BillingController.java b/bms-back/ruoyi-admin/src/main/java/com/ruoyi/web/controller/price/BillingController.java index a2e25cd0..cc833a23 100644 --- a/bms-back/ruoyi-admin/src/main/java/com/ruoyi/web/controller/price/BillingController.java +++ b/bms-back/ruoyi-admin/src/main/java/com/ruoyi/web/controller/price/BillingController.java @@ -13,9 +13,12 @@ import org.springframework.web.bind.annotation.RestController; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.price.domain.PrcBill; import com.ruoyi.price.domain.PrcQuote; +import com.ruoyi.price.domain.vo.TmsPriceBillRequest; import com.ruoyi.price.domain.vo.TmsPriceQuoteRequest; import com.ruoyi.price.domain.vo.TmsPriceQuoteResult; +import com.ruoyi.price.service.IPrcBillService; import com.ruoyi.price.service.ITmsPriceQuoteService; /** @@ -30,6 +33,9 @@ public class BillingController extends BaseController @Autowired private ITmsPriceQuoteService tmsPriceQuoteService; + @Autowired + private IPrcBillService prcBillService; + /** * Historical quote list. */ @@ -62,4 +68,28 @@ public class BillingController extends BaseController TmsPriceQuoteResult result = tmsPriceQuoteService.quote(request); return success(result); } + + @PreAuthorize("@ss.hasPermi('price:billing:bill')") + @GetMapping("/bill/list") + public TableDataInfo billList(PrcBill query) + { + startPage(); + List list = prcBillService.selectBillList(query); + return getDataTable(list); + } + + @PreAuthorize("@ss.hasPermi('price:billing:bill')") + @GetMapping("/bill/{billId}") + public AjaxResult getBill(@PathVariable String billId) + { + return success(prcBillService.getBill(billId)); + } + + @PreAuthorize("@ss.hasPermi('price:billing:bill')") + @PostMapping("/bill") + public AjaxResult bill(@Validated @RequestBody TmsPriceBillRequest request) + { + TmsPriceQuoteResult result = prcBillService.bill(request); + return success(result); + } } diff --git a/bms-back/ruoyi-admin/src/main/resources/application.yml b/bms-back/ruoyi-admin/src/main/resources/application.yml index 67fceba1..1edbe948 100644 --- a/bms-back/ruoyi-admin/src/main/resources/application.yml +++ b/bms-back/ruoyi-admin/src/main/resources/application.yml @@ -150,4 +150,4 @@ xss: bms: tms: # Agreed API identification code for TMS callers - api-code: BMS.TMS._Q2WnPXiXwGW2Dl-iSGNzLfrhUgQogNo + api-code: BMS.TMS.ZYaOvlQzpcfau8TUaCFfO3Hp8ieHIqGw diff --git a/bms-back/ruoyi-admin/src/main/resources/i18n/messages.properties b/bms-back/ruoyi-admin/src/main/resources/i18n/messages.properties index 3479f047..ad05c55f 100644 --- a/bms-back/ruoyi-admin/src/main/resources/i18n/messages.properties +++ b/bms-back/ruoyi-admin/src/main/resources/i18n/messages.properties @@ -77,6 +77,7 @@ price.set.customer.customerId.empty=客户ID不能为空 price.set.customer.beginDate.empty=客户绑定生效日期不能为空 price.set.customer.date.invalid=客户绑定生效日期不能晚于失效日期 price.set.customer.alreadyBound=该客户已绑定套餐,一个客户只能绑定一个套餐 +price.set.customer.masterNotFound=客户主数据不存在 price.set.customer.priority.invalid=优先级必须大于等于 1 # 重量段 PrcWeight price.weight.range.empty=起始重量和结束重量不能为空 @@ -118,4 +119,9 @@ price.quote.quoteIdRequired=报价ID为空 price.quote.hitCustomerFixedPackageDetail=命中客户套餐固定价格明细 # ---- 状态自动刷新 ---- -price.status.refresh.success=状态刷新完成:bms_product 更新 {0} 行,bms_product_country 更新 {1} 行 \ No newline at end of file +price.status.refresh.success=状态刷新完成:bms_product 更新 {0} 行,bms_product_country 更新 {1} 行 +# receivable bill +price.bill.orderNoRequired=订单号为空 +price.bill.billIdRequired=计费ID为空 +price.bill.notFound=计费记录不存在 +price.bill.bizDateRequired=业务日期为空 diff --git a/bms-back/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/TmsApiProperties.java b/bms-back/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/TmsApiProperties.java index b2569feb..e87b516f 100644 --- a/bms-back/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/TmsApiProperties.java +++ b/bms-back/ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/TmsApiProperties.java @@ -15,7 +15,7 @@ public class TmsApiProperties /** * Agreed API identification code (header X-Api-Code or body apiCode). */ - private String apiCode = "BMS.TMS._Q2WnPXiXwGW2Dl-iSGNzLfrhUgQogNo"; + private String apiCode = "BMS.TMS.ZYaOvlQzpcfau8TUaCFfO3Hp8ieHIqGw"; public String getApiCode() { diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/PrcBill.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/PrcBill.java new file mode 100644 index 00000000..cde433cc --- /dev/null +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/PrcBill.java @@ -0,0 +1,74 @@ +package com.ruoyi.price.domain; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** receivable bill header prc_bill */ +@Data +@EqualsAndHashCode(callSuper = true) +public class PrcBill extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + private String billId; + private String billKey; + private String orderNo; + private String trackingNo; + private Long customerId; + private String customerCode; + private String customerName; + private Integer pieces; + private BigDecimal actualWeight; + private BigDecimal volume; + private BigDecimal volumeWeight; + private BigDecimal pkgLength; + private BigDecimal pkgWidth; + private BigDecimal pkgHeight; + private String shipperName; + private String consigneeName; + private String destPostcode; + private String warehouseCode; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date orderTime; + private String orderRemark; + private String productCode; + private String productName; + private String countryCode; + private String countryName; + private BigDecimal weight; + @JsonFormat(pattern = "yyyy-MM-dd") + private Date bizDate; + private Long tmsId; + + private String matchSource; + private String matchMessage; + private Long priceSetId; + private String priceSetCode; + private String priceSetName; + private String setType; + private Integer bindPriority; + private Long customerPricesetId; + private Long productCountryId; + private BigDecimal weightMin; + private BigDecimal weightMax; + private String weightLabel; + @JsonFormat(pattern = "yyyy-MM-dd") + private Date effectiveDate; + private BigDecimal chargeWeight; + private BigDecimal freightRate; + private BigDecimal baseFreightRate; + private BigDecimal discountPercent; + private BigDecimal registrationFee; + private BigDecimal freightAmount; + private BigDecimal surchargeAmount; + private BigDecimal payableTotal; + private String currency; + private String roundMode; + + private List fees; +} diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/PrcBillFee.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/PrcBillFee.java new file mode 100644 index 00000000..b026905e --- /dev/null +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/PrcBillFee.java @@ -0,0 +1,26 @@ +package com.ruoyi.price.domain; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +/** receivable bill fee detail prc_bill_fee */ +@Data +public class PrcBillFee implements Serializable +{ + private static final long serialVersionUID = 1L; + + private String feeId; + private String billId; + private String feeType; + private String feeName; + private Long scId; + private BigDecimal amount; + private String currency; + private String roundMode; + private String remark; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createdAt; +} diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/vo/TmsPriceBillRequest.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/vo/TmsPriceBillRequest.java new file mode 100644 index 00000000..0fdf1c87 --- /dev/null +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/vo/TmsPriceBillRequest.java @@ -0,0 +1,46 @@ +package com.ruoyi.price.domain.vo; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.validation.constraints.AssertTrue; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** Sync order -> receivable bill. Quote fields plus order snapshot. */ +@Data +@EqualsAndHashCode(callSuper = true) +public class TmsPriceBillRequest extends TmsPriceQuoteRequest +{ + private static final long serialVersionUID = 1L; + + @NotBlank(message = "orderNo is required") + private String orderNo; + + private String trackingNo; + private String customerName; + private Integer pieces; + private BigDecimal actualWeight; + private BigDecimal volume; + private BigDecimal volumeWeight; + private BigDecimal pkgLength; + private BigDecimal pkgWidth; + private BigDecimal pkgHeight; + private String shipperName; + private String consigneeName; + private String destPostcode; + private String warehouseCode; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date orderTime; + private String orderRemark; + + @JsonIgnore + @AssertTrue(message = "bizDate is required") + public boolean isBizDatePresent() + { + String bizDate = getBizDate(); + return bizDate != null && !bizDate.trim().isEmpty(); + } +} diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/vo/TmsPriceQuoteResult.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/vo/TmsPriceQuoteResult.java index 84b6eda5..bf1d318c 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/vo/TmsPriceQuoteResult.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/domain/vo/TmsPriceQuoteResult.java @@ -53,6 +53,24 @@ public class TmsPriceQuoteResult implements Serializable /** 费用明细:运费/挂号费各一行,附加费按具体名称各一行 */ private List feeDetails; private String quoteId; - /** true=命中已落库试算 */ + private String billId; + private String orderNo; + private String trackingNo; + private String customerCode; + private String customerName; + private Integer pieces; + private BigDecimal actualWeight; + private BigDecimal volume; + private BigDecimal volumeWeight; + private BigDecimal pkgLength; + private BigDecimal pkgWidth; + private BigDecimal pkgHeight; + private String shipperName; + private String consigneeName; + private String destPostcode; + private String warehouseCode; + private Date orderTime; + private String orderRemark; + /** true=hit stored quote */ private Boolean fromCache; } diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/mapper/PrcBillFeeMapper.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/mapper/PrcBillFeeMapper.java new file mode 100644 index 00000000..dfb6ac1c --- /dev/null +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/mapper/PrcBillFeeMapper.java @@ -0,0 +1,17 @@ +package com.ruoyi.price.mapper; + +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.ruoyi.price.domain.PrcBillFee; + +/** receivable bill fee detail mapper */ +public interface PrcBillFeeMapper +{ + public List selectByBillId(String billId); + + public int insertPrcBillFee(PrcBillFee fee); + + public int insertBatch(@Param("list") List fees); + + public int deleteByBillId(String billId); +} diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/mapper/PrcBillMapper.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/mapper/PrcBillMapper.java new file mode 100644 index 00000000..3f266e23 --- /dev/null +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/mapper/PrcBillMapper.java @@ -0,0 +1,24 @@ +package com.ruoyi.price.mapper; + +import java.math.BigDecimal; +import java.util.List; +import org.apache.ibatis.annotations.Param; +import com.ruoyi.price.domain.PrcBill; + +/** receivable bill header mapper */ +public interface PrcBillMapper +{ + public PrcBill selectPrcBillByOrderNo(String orderNo); + + public PrcBill selectPrcBillById(String billId); + + public List selectPrcBillList(PrcBill bill); + + public int insertPrcBill(PrcBill bill); + + public int updatePrcBill(PrcBill bill); + + public int updateBillAmounts(@Param("billId") String billId, + @Param("surchargeAmount") BigDecimal surchargeAmount, + @Param("payableTotal") BigDecimal payableTotal); +} diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/IPrcBillService.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/IPrcBillService.java new file mode 100644 index 00000000..ad4e43d9 --- /dev/null +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/IPrcBillService.java @@ -0,0 +1,18 @@ +package com.ruoyi.price.service; + +import java.util.List; +import com.ruoyi.price.domain.PrcBill; +import com.ruoyi.price.domain.vo.TmsPriceBillRequest; +import com.ruoyi.price.domain.vo.TmsPriceQuoteResult; + +/** Receivable billing from synced orders. Same price match as quote, persist prc_bill. */ +public interface IPrcBillService +{ + TmsPriceQuoteResult bill(TmsPriceBillRequest request); + + List selectBillList(PrcBill query); + + TmsPriceQuoteResult getBill(String billId); + + TmsPriceQuoteResult getBillByOrderNo(String orderNo); +} diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/ITmsPriceQuoteService.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/ITmsPriceQuoteService.java index 2f50ddac..d8486d1a 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/ITmsPriceQuoteService.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/ITmsPriceQuoteService.java @@ -18,6 +18,9 @@ public interface ITmsPriceQuoteService { TmsPriceQuoteResult quote(TmsPriceQuoteRequest request); + /** Calc only, no prc_quote persist. Used by receivable billing. */ + TmsPriceQuoteResult calculate(TmsPriceQuoteRequest request); + List selectQuoteList(PrcQuote query); TmsPriceQuoteResult getQuote(String quoteId); diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/impl/PrcBillServiceImpl.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/impl/PrcBillServiceImpl.java new file mode 100644 index 00000000..33d9150a --- /dev/null +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/impl/PrcBillServiceImpl.java @@ -0,0 +1,291 @@ +package com.ruoyi.price.service.impl; + +import java.math.BigDecimal; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.MessageUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.sign.Md5Utils; +import com.ruoyi.price.domain.PrcBill; +import com.ruoyi.price.domain.PrcBillFee; +import com.ruoyi.price.domain.vo.TmsPriceBillRequest; +import com.ruoyi.price.domain.vo.TmsPriceQuoteFeeLine; +import com.ruoyi.price.domain.vo.TmsPriceQuoteResult; +import com.ruoyi.price.mapper.PrcBillFeeMapper; +import com.ruoyi.price.mapper.PrcBillMapper; +import com.ruoyi.price.service.IPrcBillService; +import com.ruoyi.price.service.ITmsPriceQuoteService; + +@Service +public class PrcBillServiceImpl implements IPrcBillService +{ + @Autowired + private ITmsPriceQuoteService tmsPriceQuoteService; + + @Autowired + private PrcBillMapper billMapper; + + @Autowired + private PrcBillFeeMapper billFeeMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public TmsPriceQuoteResult bill(TmsPriceBillRequest request) + { + if (request == null || StringUtils.isEmpty(request.getOrderNo())) + { + throw new ServiceException(MessageUtils.message("price.bill.orderNoRequired")); + } + request.setOrderNo(request.getOrderNo().trim()); + if (StringUtils.isEmpty(request.getBizDate())) + { + throw new ServiceException(MessageUtils.message("price.bill.bizDateRequired")); + } + Date bizDate = resolveBizDate(request.getBizDate()); + BigDecimal weight = request.getWeight(); + TmsPriceQuoteResult result = tmsPriceQuoteService.calculate(request); + persistBill(request, weight, bizDate, result); + return result; + } + + @Override + public List selectBillList(PrcBill query) + { + return billMapper.selectPrcBillList(query); + } + + @Override + public TmsPriceQuoteResult getBill(String billId) + { + if (billId == null) + { + throw new ServiceException(MessageUtils.message("price.bill.billIdRequired")); + } + PrcBill bill = billMapper.selectPrcBillById(billId); + if (bill == null) + { + throw new ServiceException(MessageUtils.message("price.bill.notFound")); + } + return toResult(bill, billFeeMapper.selectByBillId(billId)); + } + + @Override + public TmsPriceQuoteResult getBillByOrderNo(String orderNo) + { + if (StringUtils.isEmpty(orderNo)) + { + throw new ServiceException(MessageUtils.message("price.bill.orderNoRequired")); + } + PrcBill bill = billMapper.selectPrcBillByOrderNo(orderNo.trim()); + if (bill == null) + { + throw new ServiceException(MessageUtils.message("price.bill.notFound")); + } + return toResult(bill, billFeeMapper.selectByBillId(bill.getBillId())); + } + + private void persistBill(TmsPriceBillRequest request, BigDecimal weight, Date bizDate, + TmsPriceQuoteResult result) + { + String orderNo = request.getOrderNo(); + String billKey = Md5Utils.hash(orderNo); + PrcBill existed = billMapper.selectPrcBillByOrderNo(orderNo); + PrcBill bill = existed == null ? new PrcBill() : existed; + if (existed == null) + { + bill.setBillId(UUID.randomUUID().toString()); + } + bill.setBillKey(billKey); + bill.setOrderNo(orderNo); + bill.setCustomerId(request.getCustomerId() == null ? Long.valueOf(0L) : request.getCustomerId()); + bill.setCustomerCode(request.getCustomerCode()); + bill.setCustomerName(request.getCustomerName()); + bill.setTrackingNo(request.getTrackingNo()); + bill.setPieces(request.getPieces()); + bill.setActualWeight(request.getActualWeight()); + bill.setVolume(request.getVolume()); + bill.setVolumeWeight(request.getVolumeWeight()); + bill.setPkgLength(request.getPkgLength()); + bill.setPkgWidth(request.getPkgWidth()); + bill.setPkgHeight(request.getPkgHeight()); + bill.setShipperName(request.getShipperName()); + bill.setConsigneeName(request.getConsigneeName()); + bill.setDestPostcode(request.getDestPostcode()); + bill.setWarehouseCode(request.getWarehouseCode()); + bill.setOrderTime(request.getOrderTime()); + bill.setOrderRemark(request.getOrderRemark()); + bill.setProductCode(result.getProductCode()); + bill.setProductName(result.getProductName()); + bill.setCountryCode(result.getCountryCode()); + bill.setCountryName(result.getCountryName()); + bill.setWeight(weight); + bill.setBizDate(bizDate); + bill.setTmsId(request.getTmsId() == null ? null : Long.valueOf(request.getTmsId())); + bill.setMatchSource(result.getMatchSource()); + bill.setMatchMessage(result.getMatchMessage()); + bill.setPriceSetId(result.getPriceSetId()); + bill.setPriceSetCode(result.getPriceSetCode()); + bill.setPriceSetName(result.getPriceSetName()); + bill.setSetType(result.getSetType()); + bill.setBindPriority(result.getBindPriority()); + bill.setCustomerPricesetId(result.getCustomerPricesetId()); + bill.setProductCountryId(result.getProductCountryId()); + bill.setWeightMin(result.getWeightMin()); + bill.setWeightMax(result.getWeightMax()); + bill.setWeightLabel(result.getWeightLabel()); + bill.setEffectiveDate(result.getEffectiveDate()); + bill.setChargeWeight(result.getChargeWeight()); + bill.setFreightRate(result.getFreightRate()); + bill.setBaseFreightRate(result.getBaseFreightRate()); + bill.setDiscountPercent(result.getDiscountPercent()); + bill.setRegistrationFee(result.getRegistrationFee()); + bill.setFreightAmount(result.getFreightAmount()); + bill.setSurchargeAmount(result.getSurchargeAmount()); + bill.setPayableTotal(result.getPayableTotal()); + bill.setCurrency(result.getCurrency()); + bill.setRoundMode(result.getRoundMode()); + if (existed == null) + { + billMapper.insertPrcBill(bill); + } + else + { + billMapper.updatePrcBill(bill); + billFeeMapper.deleteByBillId(bill.getBillId()); + } + List fees = toFeeRows(bill.getBillId(), result); + if (!fees.isEmpty()) + { + billFeeMapper.insertBatch(fees); + } + result.setBillId(bill.getBillId()); + result.setOrderNo(orderNo); + result.setCustomerCode(request.getCustomerCode()); + fillResultOrder(result, bill); + result.setFromCache(Boolean.valueOf(existed != null)); + } + + private List toFeeRows(String billId, TmsPriceQuoteResult result) + { + List fees = new ArrayList(); + if (result.getFeeDetails() == null) + { + return fees; + } + for (TmsPriceQuoteFeeLine line : result.getFeeDetails()) + { + PrcBillFee fee = new PrcBillFee(); + fee.setFeeId(UUID.randomUUID().toString()); + fee.setBillId(billId); + fee.setFeeType(line.getFeeType()); + fee.setFeeName(line.getFeeName()); + fee.setScId(line.getScId() == null ? 0L : line.getScId()); + fee.setAmount(line.getAmount() == null ? BigDecimal.ZERO : line.getAmount()); + fee.setCurrency(line.getCurrency()); + fee.setRoundMode(line.getRoundMode()); + fee.setRemark(line.getRemark()); + fees.add(fee); + } + return fees; + } + + private TmsPriceQuoteResult toResult(PrcBill bill, List fees) + { + TmsPriceQuoteResult r = new TmsPriceQuoteResult(); + r.setBillId(bill.getBillId()); + r.setOrderNo(bill.getOrderNo()); + r.setCustomerCode(bill.getCustomerCode()); + fillResultOrder(r, bill); + r.setFromCache(Boolean.TRUE); + r.setMatchSource(bill.getMatchSource()); + r.setMatchMessage(bill.getMatchMessage()); + r.setCustomerId(bill.getCustomerId()); + r.setPriceSetId(bill.getPriceSetId()); + r.setPriceSetCode(bill.getPriceSetCode()); + r.setPriceSetName(bill.getPriceSetName()); + r.setSetType(bill.getSetType()); + r.setBindPriority(bill.getBindPriority()); + r.setCustomerPricesetId(bill.getCustomerPricesetId()); + r.setProductCode(bill.getProductCode()); + r.setProductName(bill.getProductName()); + r.setCountryCode(bill.getCountryCode()); + r.setCountryName(bill.getCountryName()); + r.setProductCountryId(bill.getProductCountryId()); + r.setWeightMin(bill.getWeightMin()); + r.setWeightMax(bill.getWeightMax()); + r.setWeightLabel(bill.getWeightLabel()); + r.setEffectiveDate(bill.getEffectiveDate()); + r.setWeight(bill.getWeight()); + r.setChargeWeight(bill.getChargeWeight()); + r.setFreightRate(bill.getFreightRate()); + r.setBaseFreightRate(bill.getBaseFreightRate()); + r.setDiscountPercent(bill.getDiscountPercent()); + r.setRegistrationFee(bill.getRegistrationFee()); + r.setFreightAmount(bill.getFreightAmount()); + r.setSurchargeAmount(bill.getSurchargeAmount()); + r.setPayableTotal(bill.getPayableTotal()); + r.setCurrency(bill.getCurrency()); + r.setRoundMode(bill.getRoundMode()); + List lines = new ArrayList(); + if (fees != null) + { + for (PrcBillFee fee : fees) + { + TmsPriceQuoteFeeLine line = new TmsPriceQuoteFeeLine(); + line.setFeeType(fee.getFeeType()); + line.setFeeName(fee.getFeeName()); + line.setScId(fee.getScId()); + line.setAmount(fee.getAmount()); + line.setCurrency(fee.getCurrency()); + line.setRoundMode(fee.getRoundMode()); + line.setRemark(fee.getRemark()); + lines.add(line); + } + } + r.setFeeDetails(lines); + return r; + } + + private void fillResultOrder(TmsPriceQuoteResult r, PrcBill bill) + { + r.setTrackingNo(bill.getTrackingNo()); + r.setCustomerName(bill.getCustomerName()); + r.setPieces(bill.getPieces()); + r.setActualWeight(bill.getActualWeight()); + r.setVolume(bill.getVolume()); + r.setVolumeWeight(bill.getVolumeWeight()); + r.setPkgLength(bill.getPkgLength()); + r.setPkgWidth(bill.getPkgWidth()); + r.setPkgHeight(bill.getPkgHeight()); + r.setShipperName(bill.getShipperName()); + r.setConsigneeName(bill.getConsigneeName()); + r.setDestPostcode(bill.getDestPostcode()); + r.setWarehouseCode(bill.getWarehouseCode()); + r.setOrderTime(bill.getOrderTime()); + r.setOrderRemark(bill.getOrderRemark()); + } + + private Date resolveBizDate(String bizDate) + { + if (StringUtils.isEmpty(bizDate)) + { + throw new ServiceException(MessageUtils.message("price.bill.bizDateRequired")); + } + try + { + return new SimpleDateFormat("yyyy-MM-dd").parse(bizDate.trim()); + } + catch (ParseException e) + { + throw new ServiceException(MessageUtils.message("price.quote.bizDateInvalid")); + } + } +} diff --git a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/impl/TmsPriceQuoteServiceImpl.java b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/impl/TmsPriceQuoteServiceImpl.java index 80053a4a..ad1ac544 100644 --- a/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/impl/TmsPriceQuoteServiceImpl.java +++ b/bms-back/ruoyi-system/src/main/java/com/ruoyi/price/service/impl/TmsPriceQuoteServiceImpl.java @@ -113,6 +113,16 @@ public class TmsPriceQuoteServiceImpl implements ITmsPriceQuoteService return result; } + @Override + public TmsPriceQuoteResult calculate(TmsPriceQuoteRequest request) + { + validateRequest(request); + Date bizDate = resolveBizDate(request.getBizDate()); + TmsPriceQuoteResult result = doQuote(request, bizDate); + applySurchargesAndFees(result); + return result; + } + @Override public List selectQuoteList(PrcQuote query) { diff --git a/bms-back/ruoyi-system/src/main/resources/mapper/price/PrcBillFeeMapper.xml b/bms-back/ruoyi-system/src/main/resources/mapper/price/PrcBillFeeMapper.xml new file mode 100644 index 00000000..5875acad --- /dev/null +++ b/bms-back/ruoyi-system/src/main/resources/mapper/price/PrcBillFeeMapper.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + insert into prc_bill_fee ( + fee_id, bill_id, fee_type, fee_name, sc_id, amount, currency, round_mode, remark, created_at + ) values ( + #{feeId}, #{billId}, #{feeType}, #{feeName}, #{scId}, #{amount}, #{currency}, #{roundMode}, #{remark}, sysdate() + ) + + + + insert into prc_bill_fee ( + fee_id, bill_id, fee_type, fee_name, sc_id, amount, currency, round_mode, remark, created_at + ) values + + (#{item.feeId}, #{item.billId}, #{item.feeType}, #{item.feeName}, #{item.scId}, #{item.amount}, + #{item.currency}, #{item.roundMode}, #{item.remark}, sysdate()) + + + + + delete from prc_bill_fee where bill_id = #{billId} + + diff --git a/bms-back/ruoyi-system/src/main/resources/mapper/price/PrcBillMapper.xml b/bms-back/ruoyi-system/src/main/resources/mapper/price/PrcBillMapper.xml new file mode 100644 index 00000000..612217b0 --- /dev/null +++ b/bms-back/ruoyi-system/src/main/resources/mapper/price/PrcBillMapper.xml @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + select bill_id, bill_key, order_no, tracking_no, customer_id, customer_code, customer_name, + pieces, actual_weight, volume, volume_weight, pkg_length, pkg_width, pkg_height, + shipper_name, consignee_name, dest_postcode, warehouse_code, order_time, order_remark, + product_code, product_name, country_code, country_name, weight, biz_date, tms_id, + match_source, match_message, price_set_id, price_set_code, price_set_name, + set_type, bind_priority, customer_priceset_id, product_country_id, + weight_min, weight_max, weight_label, effective_date, charge_weight, + freight_rate, base_freight_rate, discount_percent, registration_fee, + freight_amount, surcharge_amount, payable_total, currency, round_mode, + created_by, created_at, updated_by, updated_at + from prc_bill + + + + + + + + + + insert into prc_bill ( + bill_id, bill_key, order_no, tracking_no, customer_id, customer_code, customer_name, + pieces, actual_weight, volume, volume_weight, pkg_length, pkg_width, pkg_height, + shipper_name, consignee_name, dest_postcode, warehouse_code, order_time, order_remark, + product_code, product_name, country_code, country_name, weight, biz_date, tms_id, + match_source, match_message, price_set_id, price_set_code, price_set_name, + set_type, bind_priority, customer_priceset_id, product_country_id, + weight_min, weight_max, weight_label, effective_date, charge_weight, + freight_rate, base_freight_rate, discount_percent, registration_fee, + freight_amount, surcharge_amount, payable_total, currency, round_mode, + created_at + ) values ( + #{billId}, #{billKey}, #{orderNo}, #{trackingNo}, #{customerId}, #{customerCode}, #{customerName}, + #{pieces}, #{actualWeight}, #{volume}, #{volumeWeight}, #{pkgLength}, #{pkgWidth}, #{pkgHeight}, + #{shipperName}, #{consigneeName}, #{destPostcode}, #{warehouseCode}, #{orderTime}, #{orderRemark}, + #{productCode}, #{productName}, #{countryCode}, #{countryName}, #{weight}, #{bizDate}, #{tmsId}, + #{matchSource}, #{matchMessage}, #{priceSetId}, #{priceSetCode}, #{priceSetName}, + #{setType}, #{bindPriority}, #{customerPricesetId}, #{productCountryId}, + #{weightMin}, #{weightMax}, #{weightLabel}, #{effectiveDate}, #{chargeWeight}, + #{freightRate}, #{baseFreightRate}, #{discountPercent}, #{registrationFee}, + #{freightAmount}, #{surchargeAmount}, #{payableTotal}, #{currency}, #{roundMode}, + sysdate() + ) + + + + update prc_bill + set bill_key = #{billKey}, + tracking_no = #{trackingNo}, + customer_id = #{customerId}, + customer_code = #{customerCode}, + customer_name = #{customerName}, + pieces = #{pieces}, + actual_weight = #{actualWeight}, + volume = #{volume}, + volume_weight = #{volumeWeight}, + pkg_length = #{pkgLength}, + pkg_width = #{pkgWidth}, + pkg_height = #{pkgHeight}, + shipper_name = #{shipperName}, + consignee_name = #{consigneeName}, + dest_postcode = #{destPostcode}, + warehouse_code = #{warehouseCode}, + order_time = #{orderTime}, + order_remark = #{orderRemark}, + product_code = #{productCode}, + product_name = #{productName}, + country_code = #{countryCode}, + country_name = #{countryName}, + weight = #{weight}, + biz_date = #{bizDate}, + tms_id = #{tmsId}, + match_source = #{matchSource}, + match_message = #{matchMessage}, + price_set_id = #{priceSetId}, + price_set_code = #{priceSetCode}, + price_set_name = #{priceSetName}, + set_type = #{setType}, + bind_priority = #{bindPriority}, + customer_priceset_id = #{customerPricesetId}, + product_country_id = #{productCountryId}, + weight_min = #{weightMin}, + weight_max = #{weightMax}, + weight_label = #{weightLabel}, + effective_date = #{effectiveDate}, + charge_weight = #{chargeWeight}, + freight_rate = #{freightRate}, + base_freight_rate = #{baseFreightRate}, + discount_percent = #{discountPercent}, + registration_fee = #{registrationFee}, + freight_amount = #{freightAmount}, + surcharge_amount = #{surchargeAmount}, + payable_total = #{payableTotal}, + currency = #{currency}, + round_mode = #{roundMode}, + updated_at = sysdate() + where bill_id = #{billId} + + + + update prc_bill + set surcharge_amount = #{surchargeAmount}, + payable_total = #{payableTotal}, + updated_at = sysdate() + where bill_id = #{billId} + + diff --git a/bms-back/sql/price/bill.sql b/bms-back/sql/price/bill.sql new file mode 100644 index 00000000..bc3c5aa1 --- /dev/null +++ b/bms-back/sql/price/bill.sql @@ -0,0 +1,82 @@ +-- prc_bill / prc_bill_fee: receivable billing from synced orders +-- fields follow prc_quote / prc_quote_fee; extra order_no + customer_code +SET NAMES utf8mb4; + +CREATE TABLE IF NOT EXISTS prc_bill ( + bill_id VARCHAR(36) NOT NULL COMMENT '计费ID', + bill_key CHAR(32) NOT NULL COMMENT 'MD5(order_no)', + order_no VARCHAR(64) NOT NULL COMMENT '订单号', + tracking_no VARCHAR(64) DEFAULT NULL COMMENT '运单号', + customer_id BIGINT(20) NOT NULL DEFAULT 0 COMMENT '客户ID', + customer_code VARCHAR(50) DEFAULT NULL COMMENT '客户代码', + customer_name VARCHAR(100) DEFAULT NULL COMMENT '客户名称', + pieces INT(11) DEFAULT NULL COMMENT '件数', + actual_weight DECIMAL(10,3) DEFAULT NULL COMMENT '实际重量KG', + volume DECIMAL(12,4) DEFAULT NULL COMMENT '体积m3', + volume_weight DECIMAL(10,3) DEFAULT NULL COMMENT '材积重KG', + pkg_length DECIMAL(10,2) DEFAULT NULL COMMENT '长CM', + pkg_width DECIMAL(10,2) DEFAULT NULL COMMENT '宽CM', + pkg_height DECIMAL(10,2) DEFAULT NULL COMMENT '高CM', + shipper_name VARCHAR(100) DEFAULT NULL COMMENT '发件人', + consignee_name VARCHAR(100) DEFAULT NULL COMMENT '收件人', + dest_postcode VARCHAR(20) DEFAULT NULL COMMENT '目的邮编', + warehouse_code VARCHAR(50) DEFAULT NULL COMMENT '仓库', + order_time DATETIME DEFAULT NULL COMMENT '下单时间', + order_remark VARCHAR(500) DEFAULT NULL COMMENT '订单备注', + product_code VARCHAR(20) NOT NULL COMMENT '产品代码', + product_name VARCHAR(100) DEFAULT NULL COMMENT '产品名称', + country_code CHAR(2) DEFAULT NULL COMMENT '国家二字码', + country_name VARCHAR(50) DEFAULT NULL COMMENT '国家名称', + weight DECIMAL(10,3) NOT NULL COMMENT '计费重量KG', + biz_date DATE NOT NULL COMMENT '计费日期', + tms_id BIGINT(20) DEFAULT NULL COMMENT '多租户系统ID', + match_source VARCHAR(30) DEFAULT NULL COMMENT '命中来源', + match_message VARCHAR(200) DEFAULT NULL COMMENT '命中说明', + price_set_id BIGINT(20) DEFAULT NULL COMMENT '价格套餐ID', + price_set_code VARCHAR(20) DEFAULT NULL COMMENT '套餐编码', + price_set_name VARCHAR(50) DEFAULT NULL COMMENT '套餐名称', + set_type VARCHAR(10) DEFAULT NULL COMMENT '计价类型', + bind_priority INT(11) DEFAULT NULL COMMENT '客户套餐优先级', + customer_priceset_id BIGINT(20) DEFAULT NULL COMMENT '客户套餐绑定ID', + product_country_id BIGINT(20) DEFAULT NULL COMMENT '关联 bms_product_country.detail_id', + weight_min DECIMAL(10,4) DEFAULT NULL COMMENT '重量段下限', + weight_max DECIMAL(10,4) DEFAULT NULL COMMENT '重量段上限', + weight_label VARCHAR(50) DEFAULT NULL COMMENT '重量段展示', + effective_date DATE DEFAULT NULL COMMENT '产品明细生效日', + charge_weight DECIMAL(10,3) DEFAULT NULL COMMENT '计费重量', + freight_rate DECIMAL(10,4) DEFAULT NULL COMMENT '运费单价', + base_freight_rate DECIMAL(10,4) DEFAULT NULL COMMENT '折扣前单价', + discount_percent DECIMAL(5,2) DEFAULT NULL COMMENT '折扣百分数', + registration_fee DECIMAL(10,2) DEFAULT NULL COMMENT '挂号费', + freight_amount DECIMAL(10,2) DEFAULT NULL COMMENT '运费金额', + surcharge_amount DECIMAL(10,2) DEFAULT NULL COMMENT '附加费合计', + payable_total DECIMAL(10,2) DEFAULT NULL COMMENT '应收总额', + currency VARCHAR(10) NOT NULL DEFAULT 'CNY' COMMENT '币种', + round_mode VARCHAR(20) NOT NULL DEFAULT 'HALF_UP' COMMENT '取值方式', + created_by VARCHAR(64) DEFAULT '' COMMENT '创建人', + created_at DATETIME DEFAULT NULL COMMENT '创建时间', + updated_by VARCHAR(64) DEFAULT '' COMMENT '更新人', + updated_at DATETIME DEFAULT NULL COMMENT '更新时间', + PRIMARY KEY (bill_id), + UNIQUE KEY uk_bill_order (order_no), + UNIQUE KEY uk_bill_key (bill_key), + INDEX idx_bill_customer (customer_code, biz_date), + INDEX idx_bill_product (product_code, country_code) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='计费应收主表-订单同步计费'; + +CREATE TABLE IF NOT EXISTS prc_bill_fee ( + fee_id VARCHAR(36) NOT NULL COMMENT '费用明细ID', + bill_id VARCHAR(36) NOT NULL COMMENT '计费ID', + fee_type VARCHAR(30) NOT NULL COMMENT '费用类型(字典bms_fee_type)', + fee_name VARCHAR(100) DEFAULT NULL COMMENT '费用名称', + sc_id BIGINT(20) NOT NULL DEFAULT 0 COMMENT '附加费配置ID', + amount DECIMAL(12,2) NOT NULL DEFAULT 0 COMMENT '金额', + currency VARCHAR(10) NOT NULL DEFAULT 'CNY' COMMENT '币种', + round_mode VARCHAR(20) DEFAULT 'HALF_UP' COMMENT '取值方式', + remark VARCHAR(500) DEFAULT NULL COMMENT '备注', + created_at DATETIME DEFAULT NULL COMMENT '创建时间', + PRIMARY KEY (fee_id), + UNIQUE KEY uk_bill_fee_item (bill_id, fee_type, sc_id), + INDEX idx_bill_fee_type (fee_type), + CONSTRAINT fk_bill_fee_bill FOREIGN KEY (bill_id) REFERENCES prc_bill (bill_id) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='计费应收费用明细'; diff --git a/bms-back/sql/price/bill_menu.sql b/bms-back/sql/price/bill_menu.sql new file mode 100644 index 00000000..ff9a738e --- /dev/null +++ b/bms-back/sql/price/bill_menu.sql @@ -0,0 +1,23 @@ +SET NAMES utf8mb4; + +-- visible C menu under billing center (2300) +INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark) +SELECT 2310, N'同步计费', 2300, 2, 'bill', 'price/billing/bill', '', 'BillingBill', 1, 0, 'C', '0', '0', 'price:billing:bill', 'list', 'admin', sysdate(), N'订单同步计费应收' +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2310); + +UPDATE sys_menu SET menu_name = N'同步计费', parent_id = 2300, order_num = 2, path = 'bill', component = 'price/billing/bill', route_name = 'BillingBill', menu_type = 'C', visible = '0', perms = 'price:billing:bill', remark = N'订单同步计费应收' +WHERE menu_id = 2310; + +INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time) +SELECT 2311, N'计费查询', 2310, 1, '', NULL, 1, 0, 'F', '0', '0', 'price:billing:bill', '#', 'admin', sysdate() +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2311); + +UPDATE sys_menu SET menu_name = N'计费查询', parent_id = 2310, menu_type = 'F', path = '', component = NULL, perms = 'price:billing:bill' WHERE menu_id = 2311; + +INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time) +SELECT 2312, N'计费详情', 2310, 2, '', NULL, 1, 0, 'F', '0', '0', 'price:billing:bill', '#', 'admin', sysdate() +FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM sys_menu WHERE menu_id = 2312); + +INSERT INTO sys_role_menu (role_id, menu_id) +SELECT 1, m.menu_id FROM (SELECT 2310 AS menu_id UNION SELECT 2311 UNION SELECT 2312) m +WHERE NOT EXISTS (SELECT 1 FROM sys_role_menu rm WHERE rm.role_id = 1 AND rm.menu_id = m.menu_id); diff --git a/bms-back/sql/price/bill_order_info_alter.sql b/bms-back/sql/price/bill_order_info_alter.sql new file mode 100644 index 00000000..00b221ce --- /dev/null +++ b/bms-back/sql/price/bill_order_info_alter.sql @@ -0,0 +1,21 @@ +-- prc_bill add order snapshot columns +SET NAMES utf8mb4; + +ALTER TABLE prc_bill + ADD COLUMN tracking_no VARCHAR(64) DEFAULT NULL COMMENT '运单号' AFTER order_no, + ADD COLUMN customer_name VARCHAR(100) DEFAULT NULL COMMENT '客户名称' AFTER customer_code, + ADD COLUMN pieces INT(11) DEFAULT NULL COMMENT '件数' AFTER customer_name, + ADD COLUMN actual_weight DECIMAL(10,3) DEFAULT NULL COMMENT '实际重量KG' AFTER pieces, + ADD COLUMN volume DECIMAL(12,4) DEFAULT NULL COMMENT '体积m3' AFTER actual_weight, + ADD COLUMN volume_weight DECIMAL(10,3) DEFAULT NULL COMMENT '材积重KG' AFTER volume, + ADD COLUMN pkg_length DECIMAL(10,2) DEFAULT NULL COMMENT '长CM' AFTER volume_weight, + ADD COLUMN pkg_width DECIMAL(10,2) DEFAULT NULL COMMENT '宽CM' AFTER pkg_length, + ADD COLUMN pkg_height DECIMAL(10,2) DEFAULT NULL COMMENT '高CM' AFTER pkg_width, + ADD COLUMN shipper_name VARCHAR(100) DEFAULT NULL COMMENT '发件人' AFTER pkg_height, + ADD COLUMN consignee_name VARCHAR(100) DEFAULT NULL COMMENT '收件人' AFTER shipper_name, + ADD COLUMN dest_postcode VARCHAR(20) DEFAULT NULL COMMENT '目的邮编' AFTER consignee_name, + ADD COLUMN warehouse_code VARCHAR(50) DEFAULT NULL COMMENT '仓库' AFTER dest_postcode, + ADD COLUMN order_time DATETIME DEFAULT NULL COMMENT '下单时间' AFTER warehouse_code, + ADD COLUMN order_remark VARCHAR(500) DEFAULT NULL COMMENT '订单备注' AFTER order_time; + +ALTER TABLE prc_bill ADD INDEX idx_bill_tracking (tracking_no); diff --git a/bms-front/src/api/price/billing.js b/bms-front/src/api/price/billing.js index 5cfca5b1..71fed597 100644 --- a/bms-front/src/api/price/billing.js +++ b/bms-front/src/api/price/billing.js @@ -25,3 +25,29 @@ export function getQuote(quoteId) { method: 'get' }) } + +/** Sync order receivable bill */ +export function billOrder(data) { + return request({ + url: '/price/billing/bill', + method: 'post', + data + }) +} + +/** Receivable bill list */ +export function listBill(query) { + return request({ + url: '/price/billing/bill/list', + method: 'get', + params: query + }) +} + +/** Receivable bill detail */ +export function getBill(billId) { + return request({ + url: '/price/billing/bill/' + billId, + method: 'get' + }) +} diff --git a/bms-front/src/views/price/billing/bill.vue b/bms-front/src/views/price/billing/bill.vue new file mode 100644 index 00000000..0afa54dd --- /dev/null +++ b/bms-front/src/views/price/billing/bill.vue @@ -0,0 +1,244 @@ + + + + +