package com.kaidi.oa.seed; import com.kaidi.oa.common.Money; import com.kaidi.oa.domain.ArApItem; import com.kaidi.oa.domain.TaxFiling; import com.kaidi.oa.repository.ArApItemRepository; import com.kaidi.oa.repository.TaxFilingRepository; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.core.annotation.Order; import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.time.Instant; import java.time.temporal.ChronoUnit; /** * 财务部缺口种子补充(W8批次)。 * * 补全: * ① TaxFiling:补充 8 条多税种/多状态(报表附注 §12 "应交税费明细" 需多条数据演示)。 * ② ArApItem:补充 12 条带 [CERT:*] 发票认证状态标记的应付款(§3 进项税抵扣台账演示)。 * * 幂等:各表通过 code 前缀判断跳过。 * * @Order(215) 在既有 FinDeptSeeder(@Order 12)、BranchFinDemoSeeder(@Order 15) 之后。 */ @DemoSeed @Order(215) public class FinDeptGapSeeder implements ApplicationRunner { private final TaxFilingRepository taxRepo; private final ArApItemRepository arApRepo; public FinDeptGapSeeder(TaxFilingRepository taxRepo, ArApItemRepository arApRepo) { this.taxRepo = taxRepo; this.arApRepo = arApRepo; } @Override @Transactional public void run(ApplicationArguments args) { seedTaxFilings(); seedApWithInvoiceCert(); } // ===================== TaxFiling 多税种演示 ===================== private void seedTaxFilings() { // 幂等:若已有超过2条则跳过 if (taxRepo.count() > 2) return; Object[][] data = { // code, taxType, period, taxBase, taxRate, taxAmount, status, filingDate, payDate, remark { "TAX-VAT-2026-04", "增值税", "2026-04", new BigDecimal("1820000.00"), 13.0, new BigDecimal("236600.00"), TaxFiling.S_PAID, "2026-04-15", "2026-04-20", "2026年4月增值税主申报 | 销项税额265460-进项税额28860=应纳236600" }, { "TAX-VAT-2026-05", "增值税", "2026-05", new BigDecimal("2105000.00"), 13.0, new BigDecimal("273650.00"), TaxFiling.S_FILED, "2026-05-15", null, "2026年5月增值税申报(已申报待缴款)" }, { "TAX-VAT-2026-06", "增值税", "2026-06", new BigDecimal("1680000.00"), 13.0, new BigDecimal("218400.00"), TaxFiling.S_PENDING, null, null, "2026年6月增值税(待申报)" }, { "TAX-CIT-2026-Q1", "企业所得税", "2026-Q1", new BigDecimal("4200000.00"), 15.0, new BigDecimal("630000.00"), TaxFiling.S_PAID, "2026-04-25", "2026-04-28", "2026Q1企业所得税季报(高新技术企业15%税率)" }, { "TAX-CIT-2026-Q2", "企业所得税", "2026-Q2", new BigDecimal("3650000.00"), 15.0, new BigDecimal("547500.00"), TaxFiling.S_PENDING, null, null, "2026Q2企业所得税季报(待申报)" }, { "TAX-STAMP-2026-H1", "印花税", "2026-H1", new BigDecimal("120000000.00"), 0.03, new BigDecimal("36000.00"), TaxFiling.S_PAID, "2026-06-30", "2026-06-30", "2026上半年购销合同印花税(税率0.03‰×合同额)" }, { "TAX-URB-2026-04", "城市维护建设税", "2026-04", new BigDecimal("236600.00"), 7.0, new BigDecimal("16562.00"), TaxFiling.S_PAID, "2026-04-15", "2026-04-20", "2026年4月城建税(增值税236600×7%)" }, { "TAX-EDUC-2026-04", "教育费附加", "2026-04", new BigDecimal("236600.00"), 3.0, new BigDecimal("7098.00"), TaxFiling.S_PAID, "2026-04-15", "2026-04-20", "2026年4月教育费附加(增值税236600×3%)" }, }; for (Object[] row : data) { String code = (String) row[0]; boolean exists = taxRepo.findAll().stream().anyMatch(t -> code.equals(t.getCode())); if (exists) continue; TaxFiling t = new TaxFiling(); t.setCode(code); t.setTaxType((String) row[1]); t.setPeriod((String) row[2]); t.setTaxBase((BigDecimal) row[3]); t.setTaxRate((Double) row[4]); t.setTaxAmount((BigDecimal) row[5]); t.setStatus((String) row[6]); t.setFilingDate((String) row[7]); t.setPayDate((String) row[8]); t.setRemark((String) row[9]); t.setCompanySubject("凯迪科技股份有限公司"); t.setOwner("税务会计"); taxRepo.save(t); } } // ===================== 带发票认证状态的应付单 ===================== private void seedApWithInvoiceCert() { // 幂等:若已有 AP-CERT 前缀的记录则跳过 boolean certExists = arApRepo.findAll().stream() .anyMatch(i -> i.getCode() != null && i.getCode().startsWith("AP-CERT-")); if (certExists) return; Object[][] data = { // code, party, ref, amount, dueDate, certStatus, remark { "AP-CERT-001", "武汉凯博机械有限公司", "INV-2026-0401", new BigDecimal("182000.00"), "2026-05-31", "已认证", "[CERT:已认证] 增值税专用发票 INV-2026-0401 已通过税局认证,进项税额23660元可抵扣" }, { "AP-CERT-002", "湖南振华电气设备公司", "INV-2026-0402", new BigDecimal("95600.00"), "2026-06-15", "已抵扣", "[CERT:已抵扣] INV-2026-0402 进项税额12428元已在4月增值税申报中抵扣" }, { "AP-CERT-003", "长沙天宇科技有限公司", "INV-2026-0415", new BigDecimal("268000.00"), "2026-06-30", "已认证", "[CERT:已认证] INV-2026-0415 增值税专票,进项税额34840元已认证待抵扣" }, { "AP-CERT-004", "岳阳联盛原材料公司", "INV-2026-0420", new BigDecimal("135000.00"), "2026-05-20", "未认证", "[CERT:未认证] INV-2026-0420 普通发票(非专票),不可抵扣进项税" }, { "AP-CERT-005", "广州正泰电气集团", "INV-2026-0428", new BigDecimal("412000.00"), "2026-07-15", "未认证", "[CERT:未认证] INV-2026-0428 专票已收到,尚未提交税局认证(请务必在当月认证截止前提交)" }, { "AP-CERT-006", "深圳鑫泰电子元器件", "INV-2026-0501", new BigDecimal("88500.00"), "2026-06-30", "已认证", "[CERT:已认证] INV-2026-0501 电子增值税专用发票,进项税额11505元已认证" }, { "AP-CERT-007", "成都博远机电制造", "INV-2026-0505", new BigDecimal("326000.00"), "2026-07-31", "未认证", "[CERT:未认证] INV-2026-0505 金额较大,专票正在邮寄途中,待收票后认证" }, { "AP-CERT-008", "北京华控仪器仪表", "INV-2026-0512", new BigDecimal("67800.00"), "2026-06-20", "已抵扣", "[CERT:已抵扣] INV-2026-0512 进项税额8814元已在5月增值税申报中抵扣" }, { "AP-CERT-009", "济南钢铁集团贸易", "INV-2026-0515", new BigDecimal("520000.00"), "2026-08-15", "已认证", "[CERT:已认证] INV-2026-0515 大额原材料采购专票,进项税额67600元,已认证待下月抵扣" }, { "AP-CERT-010", "上海绿洲环保科技", "INV-2026-0520", new BigDecimal("42000.00"), "2026-07-01", "未认证", "[CERT:未认证] INV-2026-0520 服务费增值税专票(6%税率),待认证" }, { "AP-CERT-011", "天津港航物流集团", "INV-2026-0522", new BigDecimal("185000.00"), "2026-07-31", "已认证", "[CERT:已认证] INV-2026-0522 运输服务9%增值税,进项税额16606元已认证" }, { "AP-CERT-012", "武汉宏达建设集团", "INV-2026-0525", new BigDecimal("1250000.00"), "2026-09-30", "未认证", "[CERT:未认证] INV-2026-0525 工程服务9%增值税,金额较大,需财务总监签批后认证" }, }; for (Object[] row : data) { ArApItem item = new ArApItem(); item.setCode((String) row[0]); item.setArApType(ArApItem.T_AP); item.setPartyName((String) row[1]); item.setRelatedRef((String) row[2]); BigDecimal amt = (BigDecimal) row[3]; // 已抵扣的标记为已结清(已核销),其余未核销 String certStatus = (String) row[5]; boolean settled = "已抵扣".equals(certStatus); item.setAmount(amt); item.setWrittenOff(settled ? amt : BigDecimal.ZERO); item.setUnwrittenOff(settled ? BigDecimal.ZERO : amt); item.setStatus(settled ? ArApItem.S_SETTLED : ArApItem.S_OPEN); item.setDueDate((String) row[4]); item.setRemark((String) row[6]); item.setCompanySubject("凯迪科技股份有限公司"); item.setOwner("应付会计"); item.setCreatedAt(Instant.now().minus(15 + (long)(Math.random() * 30), ChronoUnit.DAYS)); arApRepo.save(item); } } }