| doc/20260511_sales_ledger_add_fields.sql | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| doc/销售订单模块-前端联调文档-20260511.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/sales/dto/SalesLedgerImportDto.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/sales/dto/SalesLedgerProductImportDto.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/sales/pojo/SalesLedger.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/resources/mapper/sales/SalesLedgerMapper.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/resources/static/销售台账导入模板.xlsx | 补丁 | 查看 | 原始文档 | blame | 历史 |
doc/20260511_sales_ledger_add_fields.sql
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,128 @@ -- éå®è®¢åæ¨¡åæ°å¢å段ï¼2026-05-11ï¼ -- 说æï¼ -- 1) èæ¬æâåå¨åè·³è¿ï¼ä¸åå¨åæ°å¢âæ§è¡ï¼å¯é夿§è¡ã -- 2) ç©æå·ç»ä¸å段为 material_noï¼è¥åå²åå¨ materialï¼ä¼åå¡«å° material_noã SET @db_name = DATABASE(); -- ---------------------------- -- sales_ledger æ°å¢å段 -- ---------------------------- SELECT COUNT(*) INTO @cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @db_name AND TABLE_NAME = 'sales_ledger' AND COLUMN_NAME = 'order_type'; SET @sql = IF(@cnt = 0, 'ALTER TABLE sales_ledger ADD COLUMN order_type VARCHAR(64) NULL COMMENT ''订åç±»å''', 'SELECT ''skip: sales_ledger.order_type exists'''); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; SELECT COUNT(*) INTO @cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @db_name AND TABLE_NAME = 'sales_ledger' AND COLUMN_NAME = 'order_line'; SET @sql = IF(@cnt = 0, 'ALTER TABLE sales_ledger ADD COLUMN order_line VARCHAR(64) NULL COMMENT ''订åè¡''', 'SELECT ''skip: sales_ledger.order_line exists'''); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; SELECT COUNT(*) INTO @cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @db_name AND TABLE_NAME = 'sales_ledger' AND COLUMN_NAME = 'demand_date'; SET @sql = IF(@cnt = 0, 'ALTER TABLE sales_ledger ADD COLUMN demand_date DATE NULL COMMENT ''éæ±æ¥æ''', 'SELECT ''skip: sales_ledger.demand_date exists'''); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- ---------------------------- -- sales_ledger_product æ°å¢å段 -- ---------------------------- SELECT COUNT(*) INTO @cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @db_name AND TABLE_NAME = 'sales_ledger_product' AND COLUMN_NAME = 'delivery_quantity'; SET @sql = IF(@cnt = 0, 'ALTER TABLE sales_ledger_product ADD COLUMN delivery_quantity DECIMAL(18,6) NULL COMMENT ''交货æ°é''', 'SELECT ''skip: sales_ledger_product.delivery_quantity exists'''); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; SELECT COUNT(*) INTO @cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @db_name AND TABLE_NAME = 'sales_ledger_product' AND COLUMN_NAME = 'remaining_quantity'; SET @sql = IF(@cnt = 0, 'ALTER TABLE sales_ledger_product ADD COLUMN remaining_quantity DECIMAL(18,6) NULL COMMENT ''å©ä½æ°é''', 'SELECT ''skip: sales_ledger_product.remaining_quantity exists'''); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; SELECT COUNT(*) INTO @cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @db_name AND TABLE_NAME = 'sales_ledger_product' AND COLUMN_NAME = 'sub_inventory'; SET @sql = IF(@cnt = 0, 'ALTER TABLE sales_ledger_product ADD COLUMN sub_inventory VARCHAR(128) NULL COMMENT ''ååºå''', 'SELECT ''skip: sales_ledger_product.sub_inventory exists'''); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; SELECT COUNT(*) INTO @cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @db_name AND TABLE_NAME = 'sales_ledger_product' AND COLUMN_NAME = 'location'; SET @sql = IF(@cnt = 0, 'ALTER TABLE sales_ledger_product ADD COLUMN location VARCHAR(128) NULL COMMENT ''è´§ä½''', 'SELECT ''skip: sales_ledger_product.location exists'''); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; SELECT COUNT(*) INTO @cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @db_name AND TABLE_NAME = 'sales_ledger_product' AND COLUMN_NAME = 'is_spray'; SET @sql = IF(@cnt = 0, 'ALTER TABLE sales_ledger_product ADD COLUMN is_spray TINYINT(1) NULL COMMENT ''æ¯å¦å·ç ''', 'SELECT ''skip: sales_ledger_product.is_spray exists'''); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; SELECT COUNT(*) INTO @cnt FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @db_name AND TABLE_NAME = 'sales_ledger_product' AND COLUMN_NAME = 'material_no'; SET @sql = IF(@cnt = 0, 'ALTER TABLE sales_ledger_product ADD COLUMN material_no VARCHAR(128) NULL COMMENT ''ç©æå·''', 'SELECT ''skip: sales_ledger_product.material_no exists'''); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- ---------------------------- -- å岿°æ®å ¼å®¹ï¼material -> material_no -- ---------------------------- SELECT COUNT(*) INTO @has_old_material FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @db_name AND TABLE_NAME = 'sales_ledger_product' AND COLUMN_NAME = 'material'; SELECT COUNT(*) INTO @has_new_material_no FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = @db_name AND TABLE_NAME = 'sales_ledger_product' AND COLUMN_NAME = 'material_no'; SET @sql = IF(@has_old_material = 1 AND @has_new_material_no = 1, 'UPDATE sales_ledger_product SET material_no = material WHERE (material_no IS NULL OR material_no = '''') AND material IS NOT NULL', 'SELECT ''skip: material -> material_no backfill'''); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; -- å¯éï¼ç¡®è®¤å端/å端é½å·²åæ¢åï¼åè¯ä¼°æ¯å¦å 餿§å material -- ALTER TABLE sales_ledger_product DROP COLUMN material; doc/ÏúÊÛ¶©µ¥Ä£¿é-ǰ¶ËÁªµ÷Îĵµ-20260511.md
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,108 @@ # éå®è®¢å模åå端èè°ææ¡£ï¼2026-05-11ï¼ ## 1. æ¬æ¬¡åæ´èå´ - 模åï¼`éå®è®¢å / éå®äº§å` - ç¸å ³æ¥å£åç¼ï¼`/sales/ledger`ã`/sales/product` - æ¬æ¬¡æ ¸å¿å£å¾ï¼`åä»· = å«ç¨åä»·`ï¼`æ»ä»· = å«ç¨æ»ä»·` ## 2. æ°å¢/è°æ´å段 ### 2.1 éå®ä¸»è¡¨ï¼sales_ledgerï¼ 1. `orderType`ï¼è®¢åç±»åï¼`VARCHAR`ï¼ 2. `orderLine`ï¼è®¢åè¡ï¼`VARCHAR`ï¼ 3. `demandDate`ï¼éæ±æ¥æï¼`yyyy-MM-dd`ï¼ ### 2.2 éå®äº§å表ï¼sales_ledger_productï¼ 1. `deliveryQuantity`ï¼äº¤è´§æ°éï¼`DECIMAL`ï¼ 2. `remainingQuantity`ï¼å©ä½æ°éï¼`DECIMAL`ï¼ 3. `subInventory`ï¼ååºåï¼`VARCHAR`ï¼ 4. `location`ï¼è´§ä½ï¼`VARCHAR`ï¼ 5. `isSpray`ï¼æ¯å¦å·ç ï¼`Boolean`ï¼ 6. `materialNo`ï¼ç©æå·ï¼`VARCHAR`ï¼ ## 3. æ¥å£èè°æ¸ å ### 3.1 æ°å¢/ç¼è¾éå®è®¢å - `POST /sales/ledger/addOrUpdateSalesLedger` - `Content-Type: application/json` 请æ±ç¤ºä¾ï¼ ```json { "id": null, "salesContractNo": "XS20260511001", "customerId": 10001, "customerName": "åéæå®¢æ·", "projectName": "XX项ç®", "entryDate": "2026-05-11", "salesman": "å¼ ä¸", "paymentMethod": "æç»30天", "orderType": "常è§è®¢å", "orderLine": "10", "demandDate": "2026-05-25", "deliveryDate": "2026-05-30", "type": 1, "productData": [ { "productCategory": "æåA", "specificationModel": "A-001", "unit": "ä»¶", "quantity": 100, "taxRate": 13, "taxInclusiveUnitPrice": 11.30, "taxInclusiveTotalPrice": 1130.00, "invoiceType": "å¢å¼ç¨ä¸ç¥¨", "materialNo": "MAT-001", "deliveryQuantity": 60, "remainingQuantity": 40, "subInventory": "FG", "location": "A-01-01", "isSpray": false } ] } ``` ### 3.2 éå®è®¢å详æ ï¼ä¸»åï¼ - `GET /sales/ledger/getSalesLedgerWithProducts?id={id}` - è¿åä¸ä¼å å«ä¸»è¡¨æ°å¢å段ï¼`orderType/orderLine/demandDate` - `productData` ä¸ä¼å å«äº§åæ°å¢å段ï¼`materialNo/deliveryQuantity/remainingQuantity/subInventory/location/isSpray` ### 3.3 éå®è®¢åå页å表 - `GET /sales/ledger/listPage` - åæ¡è®°å½è¿åæ°å¢å段ï¼`orderType/orderLine/demandDate` ### 3.4 éå®äº§åå表 - `GET /sales/product/list?salesLedgerId={id}&type=1` - åæ¡è®°å½è¿åæ°å¢å段ï¼`materialNo/deliveryQuantity/remainingQuantity/subInventory/location/isSpray` ### 3.5 Excel å¯¼å ¥ - `POST /sales/ledger/import`ï¼`form-data`ï¼åæ°åï¼`file`ï¼ - å¯¼å ¥æ¨¡æ¿ä¸éå®äº§å页忮µå£å¾ï¼ 1. `åä»·` -> `taxInclusiveUnitPrice` 2. `æ»ä»·` -> `taxInclusiveTotalPrice` åç«¯å¯¼å ¥é»è¾å£å¾å·²ç»ä¸ä¸ºå«ç¨ï¼ 1. `noInvoiceAmount = taxInclusiveTotalPrice` 2. `pendingInvoiceTotal = taxInclusiveTotalPrice` ## 4. å端èè°æ³¨æç¹ 1. æ¥æåæ®µç»ä¸ä¼ `yyyy-MM-dd`ï¼`demandDate`ã`deliveryDate`ï¼ã 2. `isSpray` æå¸å°å¼ä¼ éï¼`true/false`ï¼ã 3. `deliveryQuantity`ã`remainingQuantity`ã`quantity`ã`taxInclusiveUnitPrice`ã`taxInclusiveTotalPrice` 建议ç»ä¸ `Number` 精度å¤çã 4. 页é¢å±ç¤ºâåä»·/æ»ä»·âæ¶ï¼ç´æ¥ä½¿ç¨ `taxInclusiveUnitPrice/taxInclusiveTotalPrice`ã ## 5. æ¬æ¬¡å¯¹åº SQL - è§æä»¶ï¼`doc/20260511_sales_ledger_add_fields.sql` src/main/java/com/ruoyi/sales/dto/SalesLedgerDto.java
@@ -56,6 +56,16 @@ @ApiModelProperty(value = "仿¬¾æ¹å¼") private String paymentMethod; @ApiModelProperty(value = "订åç±»å") private String orderType; @ApiModelProperty(value = "订åè¡") private String orderLine; @ApiModelProperty(value = "éæ±æ¥æ") @JsonFormat(pattern = "yyyy-MM-dd") private Date demandDate; @ApiModelProperty(value = "äº¤è´§æ¥æ") private LocalDate deliveryDate; } src/main/java/com/ruoyi/sales/dto/SalesLedgerImportDto.java
@@ -47,5 +47,19 @@ @Excel(name = "仿¬¾æ¹å¼") private String paymentMethod; @Excel(name = "订åç±»å") private String orderType; @Excel(name = "订åè¡") private String orderLine; @Excel(name = "éæ±æ¥æ", width = 30, dateFormat = "yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd") private Date demandDate; @Excel(name = "äº¤è´§æ¥æ", width = 30, dateFormat = "yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd") private Date deliveryDate; } src/main/java/com/ruoyi/sales/dto/SalesLedgerProductImportDto.java
@@ -22,13 +22,13 @@ /** * 产å大类 */ @Excel(name = "产å大类") @Excel(name = "产ååç§°") private String productCategory; /** * è§æ ¼åå· */ @Excel(name = "è§æ ¼åå·") @Excel(name = "å¾çº¸ç¼å·") private String specificationModel; /** @@ -52,13 +52,13 @@ /** * å«ç¨åä»· */ @Excel(name = "å«ç¨åä»·") @Excel(name = "åä»·") private BigDecimal taxInclusiveUnitPrice; /** * å«ç¨æ»ä»· */ @Excel(name = "å«ç¨æ»ä»·") @Excel(name = "æ»ä»·") private BigDecimal taxInclusiveTotalPrice; /** @@ -73,6 +73,24 @@ @Excel(name = "æ¯å¦è´¨æ£", readConverterExp = "0=å¦,1=æ¯") private Boolean isChecked; @Excel(name = "ç©æå·") private String materialNo; @Excel(name = "交货æ°é") private BigDecimal deliveryQuantity; @Excel(name = "å©ä½æ°é") private BigDecimal remainingQuantity; @Excel(name = "ååºå") private String subInventory; @Excel(name = "è´§ä½") private String location; @Excel(name = "æ¯å¦å·ç ") private Boolean isSpray; } src/main/java/com/ruoyi/sales/pojo/SalesLedger.java
@@ -127,6 +127,21 @@ @ApiModelProperty(value = "仿¬¾æ¹å¼") private String paymentMethod; @ApiModelProperty(value = "订åç±»å") @Excel(name = "订åç±»å") private String orderType; @ApiModelProperty(value = "订åè¡") @Excel(name = "订åè¡") private String orderLine; @ApiModelProperty(value = "éæ±æ¥æ") @Excel(name = "éæ±æ¥æ", width = 30, dateFormat = "yyyy-MM-dd") @JsonFormat(pattern = "yyyy-MM-dd") @DateTimeFormat(pattern = "yyyy-MM-dd") @TableField(value = "demand_date") private Date demandDate; @TableField(exist = false) @ApiModelProperty(value = "çäº§ç¶æ") private String productionStatus = "æªå¼å§"; src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -96,6 +96,26 @@ @Excel(name = "å«ç¨æ»ä»·") private BigDecimal taxInclusiveTotalPrice; @ApiModelProperty(value = "交货æ°é") @Excel(name = "交货æ°é") private BigDecimal deliveryQuantity; @ApiModelProperty(value = "å©ä½æ°é") @Excel(name = "å©ä½æ°é") private BigDecimal remainingQuantity; @ApiModelProperty(value = "ååºå") @Excel(name = "ååºå") private String subInventory; @ApiModelProperty(value = "è´§ä½") @Excel(name = "è´§ä½") private String location; @ApiModelProperty(value = "æ¯å¦å·ç ") @Excel(name = "æ¯å¦å·ç ") private Boolean isSpray; /** * ä¸å«ç¨æ»ä»· */ @@ -250,5 +270,6 @@ private BigDecimal returnNum; @ApiModelProperty(value = "ç©æå·") private String material; @Excel(name = "ç©æå·") private String materialNo; } src/main/java/com/ruoyi/sales/service/impl/SalesLedgerProductServiceImpl.java
@@ -317,6 +317,7 @@ productStructures.forEach(item ->{ ProductStructureRecord item1 = new ProductStructureRecord(); BeanUtils.copyProperties(item, item1); item1.setId( null); item1.setProductOrderId(productOrder.getId()); item1.setDemandedQuantity(item.getUnitQuantity().multiply(productOrder.getQuantity())); item1.setBomId(Long.valueOf(productBom.getId())); src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -412,9 +412,19 @@ salesLedgerProduct.setSalesLedgerId(salesLedger.getId()); salesLedgerProduct.setType(1); // 计ç®ä¸å«ç¨æ»ä»· salesLedgerProduct.setTaxExclusiveTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice().divide(new BigDecimal(1).add(salesLedgerProduct.getTaxRate().divide(new BigDecimal(100))), 2, RoundingMode.HALF_UP)); if (salesLedgerProduct.getTaxInclusiveTotalPrice() != null && salesLedgerProduct.getTaxRate() != null) { salesLedgerProduct.setTaxExclusiveTotalPrice( salesLedgerProduct.getTaxInclusiveTotalPrice().divide( new BigDecimal(1).add(salesLedgerProduct.getTaxRate().divide(new BigDecimal(100))), 2, RoundingMode.HALF_UP ) ); } else { salesLedgerProduct.setTaxExclusiveTotalPrice(salesLedgerProduct.getTaxInclusiveTotalPrice()); } salesLedgerProduct.setNoInvoiceNum(salesLedgerProduct.getQuantity()); salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxExclusiveTotalPrice()); salesLedgerProduct.setNoInvoiceAmount(salesLedgerProduct.getTaxInclusiveTotalPrice()); list.stream() .filter(map -> map.get("productName").equals(salesLedgerProduct.getProductCategory()) && map.get("model").equals(salesLedgerProduct.getSpecificationModel())) .findFirst() @@ -435,7 +445,7 @@ salesLedgerProduct.setRegister(loginUser.getNickName()); salesLedgerProduct.setRegisterDate(LocalDateTime.now()); salesLedgerProduct.setApproveStatus(0); salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProductImportDto.getTaxInclusiveTotalPrice()); salesLedgerProduct.setPendingInvoiceTotal(salesLedgerProduct.getTaxInclusiveTotalPrice()); salesLedgerProductMapper.insert(salesLedgerProduct); // æ·»å çäº§æ°æ® salesLedgerProductServiceImpl.addProductionData(salesLedgerProduct); src/main/resources/mapper/sales/SalesLedgerMapper.xml
@@ -31,6 +31,10 @@ T1.execution_date, T2.nick_name AS entry_person_name, T1.payment_method, T1.order_type, T1.order_line, T1.demand_date, T1.delivery_date, DATEDIFF(T1.delivery_date, CURDATE()) AS delivery_days_diff FROM sales_ledger T1 @@ -60,6 +64,9 @@ T1.execution_date, T2.nick_name AS entry_person_name, T1.payment_method, T1.order_type, T1.order_line, T1.demand_date, T1.delivery_date, DATEDIFF(T1.delivery_date, CURDATE()) AS delivery_days_diff, CASE @@ -111,4 +118,4 @@ FROM sales_ledger GROUP BY customer_name </select> </mapper> </mapper> src/main/resources/static/ÏúÊŲ̂Õ˵¼ÈëÄ£°å.xlsxBinary files differ