diff --git a/oms_web/oms_vue/src/api/finance/invoiceWriteoff.js b/oms_web/oms_vue/src/api/finance/invoiceWriteoff.js new file mode 100644 index 00000000..f5a66030 --- /dev/null +++ b/oms_web/oms_vue/src/api/finance/invoiceWriteoff.js @@ -0,0 +1,26 @@ +import request from '@/utils/request' + +// 查询核销记录列表 +export function listInvoiceWriteOff(query) { + return request({ + url: '/finance/invoice/writeoff/list', + method: 'get', + params: query + }) +} + +// 查询核销详情 +export function getInvoiceWriteoff(id) { + return request({ + url: '/finance/invoice/writeoff/' + id, + method: 'get' + }) +} + +// 删除核销记录 +export function delInvoiceWriteoff(ids) { + return request({ + url: '/finance/invoice/writeoff/' + ids, + method: 'delete' + }) +} diff --git a/oms_web/oms_vue/src/views/finance/writeoff/invoice/WriteOffDetailDrawer.vue b/oms_web/oms_vue/src/views/finance/writeoff/invoice/WriteOffDetailDrawer.vue new file mode 100644 index 00000000..04564d59 --- /dev/null +++ b/oms_web/oms_vue/src/views/finance/writeoff/invoice/WriteOffDetailDrawer.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/oms_web/oms_vue/src/views/finance/writeoff/invoice/writeoffRecord.vue b/oms_web/oms_vue/src/views/finance/writeoff/invoice/writeoffRecord.vue new file mode 100644 index 00000000..6cf24e46 --- /dev/null +++ b/oms_web/oms_vue/src/views/finance/writeoff/invoice/writeoffRecord.vue @@ -0,0 +1,236 @@ + + + diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/controller/OmsReceivableInvoiceWriteOffController.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/controller/OmsReceivableInvoiceWriteOffController.java new file mode 100644 index 00000000..aef3a397 --- /dev/null +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/controller/OmsReceivableInvoiceWriteOffController.java @@ -0,0 +1,99 @@ +package com.ruoyi.sip.controller; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.ruoyi.sip.service.IOmsInvoiceBillService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.sip.domain.OmsReceivableInvoiceWriteOff; +import com.ruoyi.sip.service.IOmsReceivableInvoiceWriteOffService; + +/** + * 应收票据核销单Controller + * + * @author zghz + * @date 2025-12-24 + */ +@RestController +@RequestMapping("/finance/invoice/writeoff") +public class OmsReceivableInvoiceWriteOffController extends BaseController +{ + @Autowired + private IOmsReceivableInvoiceWriteOffService omsReceivableInvoiceWriteOffService; + + /** + * 查询应收票据核销单列表 + */ + @GetMapping("/list") + public TableDataInfo list(OmsReceivableInvoiceWriteOff omsReceivableInvoiceWriteOff) + { + startPage(); + List list = omsReceivableInvoiceWriteOffService.selectOmsReceivableInvoiceWriteOffList(omsReceivableInvoiceWriteOff); + return getDataTable(list); + } + + /** + * 导出应收票据核销单列表 + */ + @Log(title = "应收票据核销单", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, OmsReceivableInvoiceWriteOff omsReceivableInvoiceWriteOff) + { + List list = omsReceivableInvoiceWriteOffService.selectOmsReceivableInvoiceWriteOffList(omsReceivableInvoiceWriteOff); + ExcelUtil util = new ExcelUtil(OmsReceivableInvoiceWriteOff.class); + util.exportExcel(response, list, "应收票据核销单数据"); + } + + /** + * 获取应收票据核销单详细信息 + */ + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") Long id) + { + return AjaxResult.success(omsReceivableInvoiceWriteOffService.selectOmsReceivableInvoiceWriteOffById(id)); + } + + /** + * 新增应收票据核销单 + */ + @Log(title = "应收票据核销单", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody OmsReceivableInvoiceWriteOff omsReceivableInvoiceWriteOff) + { + return toAjax(omsReceivableInvoiceWriteOffService.insertOmsReceivableInvoiceWriteOff(omsReceivableInvoiceWriteOff)); + } + + /** + * 修改应收票据核销单 + */ + @Log(title = "应收票据核销单", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody OmsReceivableInvoiceWriteOff omsReceivableInvoiceWriteOff) + { + return toAjax(omsReceivableInvoiceWriteOffService.updateOmsReceivableInvoiceWriteOff(omsReceivableInvoiceWriteOff)); + } + + /** + * 删除应收票据核销单 + */ + @Log(title = "应收票据核销单", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable Long[] ids) + { + return toAjax(omsReceivableInvoiceWriteOffService.deleteOmsReceivableInvoiceWriteOffByIds(ids)); + } +} \ No newline at end of file diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsInvoiceBill.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsInvoiceBill.java index 68c1ca9e..3f3af466 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsInvoiceBill.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsInvoiceBill.java @@ -101,7 +101,6 @@ public class OmsInvoiceBill extends BaseEntity /** 关联的原始开票单ID */ private Long originalBillId; - private List detailList; private Long approveUser; private Date applyTime; private Date todoApproveTime; diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableInvoiceDetail.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableInvoiceDetail.java index f8951fcd..b026a08d 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableInvoiceDetail.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableInvoiceDetail.java @@ -67,6 +67,8 @@ public class OmsReceivableInvoiceDetail extends BaseEntity private Date actualInvoiceTime; private OmsFinAttachment attachment; + private Long writeOffId; + private List writeOffIdList; @Getter public enum ReceivableDetailTypeEnum { diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableInvoiceWriteOff.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableInvoiceWriteOff.java new file mode 100644 index 00000000..50e8398d --- /dev/null +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/domain/OmsReceivableInvoiceWriteOff.java @@ -0,0 +1,93 @@ +package com.ruoyi.sip.domain; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; +import com.ruoyi.sip.domain.dto.ReceiptDetailDTO; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 应收票据核销单对象 oms_receivable_invoice_write_off + * + * @author zghz + * @date 2025-12-24 + */ +@Data +public class OmsReceivableInvoiceWriteOff extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键ID */ + private Long id; + + /** 核销单编号 */ + @Excel(name = "核销单编号") + private String writeOffCode; + + /** 核销类型 AUTO:系统自动核销 USER:用户手动核销 */ + @Excel(name = "核销类型") + private String writeOffType; + + /** 开票单编号 */ + @Excel(name = "开票单编号") + private String invoiceBillCode; + private String receivableBillCode; + + /** 客户编码 */ + @Excel(name = "客户编码") + private String partnerCode; + private String partnerName; + + /** 本次核销总金额 */ + @Excel(name = "本次核销总金额") + private BigDecimal writeOffAmount; + + /** 本次核销未税总金额 */ + @Excel(name = "本次核销未税总金额") + private BigDecimal writeOffAmountWithoutTax; + + /** 本次核销税额 */ + @Excel(name = "本次核销税额") + private BigDecimal writeOffTaxAmount; + + /** 核销时间 */ + @Excel(name = "核销时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") + private Date writeOffTime; + + /** 备注 */ + @Excel(name = "备注") + private String remark; + + /** 开票单信息(关联查询) */ + private OmsInvoiceBill invoiceBill; + + /** 核销明细列表 */ + private List detailList; + + public enum WriteOffTypeEnum { + AUTO("AUTO", "系统自动核销"), + USER("USER", "用户手动核销"); + + private final String code; + private final String info; + + WriteOffTypeEnum(String code, String info) { + this.code = code; + this.info = info; + } + + public String getCode() { + return code; + } + + public String getInfo() { + return info; + } + } + + +} \ No newline at end of file diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/dto/WriteOffInvoiceRequestDto.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/dto/WriteOffInvoiceRequestDto.java new file mode 100644 index 00000000..c3f0c9ce --- /dev/null +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/dto/WriteOffInvoiceRequestDto.java @@ -0,0 +1,43 @@ +package com.ruoyi.sip.dto; + +import com.ruoyi.sip.domain.OmsPayableTicketDetail; +import com.ruoyi.sip.domain.OmsReceivableInvoiceDetail; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 采购应付核销单请求DTO + * + * @author zghz + * @date 2025-12-16 + */ +@Data +public class WriteOffInvoiceRequestDto +{ + /** + * 付款单ID + */ + @NotNull(message = "开票单ID不能为空") + private Long invoiceBillId; + + /** + * 核销项列表 + */ + private List detailList; + + /** + * 供应商代码 + */ + @NotBlank(message = "供应商代码不能为空") + private String partnerCode; + private String partnerName; + + /** + * 备注 + */ + private String remark; + +} \ No newline at end of file diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsInvoiceBillMapper.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsInvoiceBillMapper.java index bef645ee..558c1dac 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsInvoiceBillMapper.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsInvoiceBillMapper.java @@ -93,4 +93,6 @@ public interface OmsInvoiceBillMapper void clearApprove(OmsInvoiceBill invoiceBill); + void updateReturnWriteOffBatch(List updateBills); + } \ No newline at end of file diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsReceivableInvoiceDetailMapper.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsReceivableInvoiceDetailMapper.java index 050c02b9..6a2b4717 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsReceivableInvoiceDetailMapper.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsReceivableInvoiceDetailMapper.java @@ -2,6 +2,7 @@ package com.ruoyi.sip.mapper; import java.util.List; +import com.ruoyi.sip.domain.OmsPayableTicketDetail; import com.ruoyi.sip.domain.OmsReceivableInvoiceDetail; import com.ruoyi.sip.domain.dto.ReceiptDetailDTO; @@ -75,4 +76,10 @@ public interface OmsReceivableInvoiceDetailMapper List listReceivableByInvoiceBillCode(List strings); + List listReceivableByInvoiceWriteOffId(List lists); + + void clearWriteOff(List writeOffIdList); + + void updateWriteOffIdBatch(List updateList); + } \ No newline at end of file diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsReceivableInvoiceWriteOffMapper.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsReceivableInvoiceWriteOffMapper.java new file mode 100644 index 00000000..5ff0d417 --- /dev/null +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/mapper/OmsReceivableInvoiceWriteOffMapper.java @@ -0,0 +1,73 @@ +package com.ruoyi.sip.mapper; + +import java.util.List; +import com.ruoyi.sip.domain.OmsReceivableInvoiceWriteOff; + +/** + * 应收票据核销单Mapper接口 + * + * @author zghz + * @date 2025-12-24 + */ +public interface OmsReceivableInvoiceWriteOffMapper +{ + /** + * 查询应收票据核销单 + * + * @param id 应收票据核销单主键 + * @return 应收票据核销单 + */ + public OmsReceivableInvoiceWriteOff selectOmsReceivableInvoiceWriteOffById(Long id); + + + + /** + * 查询应收票据核销单列表 + * + * @param omsReceivableInvoiceWriteOff 应收票据核销单 + * @return 应收票据核销单集合 + */ + public List selectOmsReceivableInvoiceWriteOffList(OmsReceivableInvoiceWriteOff omsReceivableInvoiceWriteOff); + + /** + * 新增应收票据核销单 + * + * @param omsReceivableInvoiceWriteOff 应收票据核销单 + * @return 结果 + */ + public int insertOmsReceivableInvoiceWriteOff(OmsReceivableInvoiceWriteOff omsReceivableInvoiceWriteOff); + + /** + * 修改应收票据核销单 + * + * @param omsReceivableInvoiceWriteOff 应收票据核销单 + * @return 结果 + */ + public int updateOmsReceivableInvoiceWriteOff(OmsReceivableInvoiceWriteOff omsReceivableInvoiceWriteOff); + + /** + * 删除应收票据核销单 + * + * @param id 应收票据核销单主键 + * @return 结果 + */ + public int deleteOmsReceivableInvoiceWriteOffById(Long id); + + /** + * 批量删除应收票据核销单 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteOmsReceivableInvoiceWriteOffByIds(Long[] ids); + + /** + * 根据ID数组查询应收票据核销单列表 + * + * @param ids 需要查询的数据主键集合 + * @return 应收票据核销单集合 + */ + List listByIds(Long[] ids); + + int selectMaxCodeByPrefix(String codePrefix); +} \ No newline at end of file diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsInvoiceBillService.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsInvoiceBillService.java index e11f9953..9c01631e 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsInvoiceBillService.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsInvoiceBillService.java @@ -2,6 +2,7 @@ package com.ruoyi.sip.service; import java.util.List; import com.ruoyi.sip.domain.OmsInvoiceBill; +import com.ruoyi.sip.domain.OmsReceivableInvoiceDetail; import com.ruoyi.sip.domain.ProjectProductInfo; import com.ruoyi.sip.domain.dto.InvoiceProductDto; import org.springframework.web.multipart.MultipartFile; @@ -119,4 +120,6 @@ public interface IOmsInvoiceBillService AjaxResult revokeInvoice(Long id); + void returnTicketWriteOff(List collect, List omsReceivableInvoiceDetails); + } \ No newline at end of file diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsReceivableInvoiceDetailService.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsReceivableInvoiceDetailService.java index 3a073ae7..16127575 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsReceivableInvoiceDetailService.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsReceivableInvoiceDetailService.java @@ -78,4 +78,12 @@ public interface IOmsReceivableInvoiceDetailService void applyRefund(String invoiceBillCode, String invoiceBillCode1); List listReceivableByInvoiceBillCode(String invoiceBillCode); + + List listReceivableByInvoiceWriteOffId(List longs); + + List listByWriteOffIds(Long[] ids); + + void clearWriteOff(List writeOffIdList); + + void updateWriteOffIdBatch(List updateList); } \ No newline at end of file diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsReceivableInvoiceWriteOffService.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsReceivableInvoiceWriteOffService.java new file mode 100644 index 00000000..89a44778 --- /dev/null +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/IOmsReceivableInvoiceWriteOffService.java @@ -0,0 +1,69 @@ +package com.ruoyi.sip.service; + +import java.util.List; +import com.ruoyi.sip.domain.OmsReceivableInvoiceWriteOff; +import com.ruoyi.sip.dto.WriteOffInvoiceRequestDto; +import com.ruoyi.sip.dto.WriteOffTicketRequestDto; + +/** + * 应收票据核销单Service接口 + * + * @author zghz + * @date 2025-12-24 + */ +public interface IOmsReceivableInvoiceWriteOffService +{ + /** + * 查询应收票据核销单 + * + * @param id 应收票据核销单主键 + * @return 应收票据核销单 + */ + public OmsReceivableInvoiceWriteOff selectOmsReceivableInvoiceWriteOffById(Long id); + + /** + * 查询应收票据核销单列表 + * + * @param omsReceivableInvoiceWriteOff 应收票据核销单 + * @return 应收票据核销单集合 + */ + public List selectOmsReceivableInvoiceWriteOffList(OmsReceivableInvoiceWriteOff omsReceivableInvoiceWriteOff); + + /** + * 新增应收票据核销单 + * + * @param omsReceivableInvoiceWriteOff 应收票据核销单 + * @return 结果 + */ + public int insertOmsReceivableInvoiceWriteOff(OmsReceivableInvoiceWriteOff omsReceivableInvoiceWriteOff); + + /** + * 修改应收票据核销单 + * + * @param omsReceivableInvoiceWriteOff 应收票据核销单 + * @return 结果 + */ + public int updateOmsReceivableInvoiceWriteOff(OmsReceivableInvoiceWriteOff omsReceivableInvoiceWriteOff); + + /** + * 批量删除应收票据核销单 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteOmsReceivableInvoiceWriteOffByIds(Long[] ids); + + /** + * 删除应收票据核销单信息 + * + * @param id 应收票据核销单主键 + * @return 结果 + */ + public int deleteOmsReceivableInvoiceWriteOffById(Long id); + + /** + * 系统自动收票核销 + * @param writeOffRequestDto 核销请求数据 + */ + public void autoTicketWriteOff(WriteOffInvoiceRequestDto writeOffRequestDto); +} \ No newline at end of file diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsInvoiceBillServiceImpl.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsInvoiceBillServiceImpl.java index 656ee06d..002ec323 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsInvoiceBillServiceImpl.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsInvoiceBillServiceImpl.java @@ -17,10 +17,12 @@ import com.ruoyi.common.utils.StringUtils; import com.ruoyi.sip.domain.*; import com.ruoyi.sip.domain.dto.InvoiceProductDto; import com.ruoyi.sip.domain.dto.ReceiptDetailDTO; +import com.ruoyi.sip.dto.WriteOffInvoiceRequestDto; import com.ruoyi.sip.flowable.domain.Todo; import com.ruoyi.sip.service.*; import org.flowable.engine.runtime.ProcessInstance; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -60,6 +62,11 @@ public class OmsInvoiceBillServiceImpl implements IOmsInvoiceBillService, TodoCo private IInventoryOuterService outerService; @Autowired private IProjectProductInfoService productInfoService; + @Autowired + @Lazy + private IOmsReceivableInvoiceWriteOffService writeOffService; + + /** * 查询销售开票单 @@ -177,25 +184,32 @@ public class OmsInvoiceBillServiceImpl implements IOmsInvoiceBillService, TodoCo @Override @Transactional(rollbackFor = Exception.class) public AjaxResult uploadReceipt(OmsInvoiceBill bill, MultipartFile file) throws Exception { - OmsInvoiceBill omsInvoiceBill = selectOmsInvoiceBillById(bill.getId()); - if (omsInvoiceBill == null) { + OmsInvoiceBill existBill = selectOmsInvoiceBillById(bill.getId()); + if (existBill == null) { throw new ServiceException("开票单不存在"); } // 检查开票金额是否与应收单一致 - if (omsInvoiceBill.getTotalPriceWithTax().compareTo(bill.getInvoicePriceWithTax()) != 0){ + if (existBill.getTotalPriceWithTax().compareTo(bill.getInvoicePriceWithTax()) != 0){ return AjaxResult.error("开票金额与应收单金额不一致"); } // 这里可以添加上传附件的逻辑 - omsFinAttachmentService.uploadAttachment(file, omsInvoiceBill.getId(), OmsFinAttachment.RelatedBillTypeEnum.RECEIVE_INVOICE, bill.getRemark()); - omsInvoiceBill.setActualInvoiceTime(DateUtils.getNowDate()); - omsInvoiceBill.setInvoiceStatus(OmsInvoiceBill.InvoiceStatusEnum.INVOICE.getCode()); - omsInvoiceBill.setInvoicePriceWithTax(bill.getInvoicePriceWithTax()); - omsInvoiceBill.setInvoicePriceWithoutTax(bill.getInvoicePriceWithoutTax()); - omsInvoiceBill.setInvoiceType(bill.getInvoiceType()); - updateOmsInvoiceBill(omsInvoiceBill); - + omsFinAttachmentService.uploadAttachment(file, existBill.getId(), OmsFinAttachment.RelatedBillTypeEnum.RECEIVE_INVOICE, bill.getRemark()); + existBill.setActualInvoiceTime(DateUtils.getNowDate()); + existBill.setInvoiceStatus(OmsInvoiceBill.InvoiceStatusEnum.INVOICE.getCode()); + existBill.setInvoicePriceWithTax(bill.getInvoicePriceWithTax()); + existBill.setInvoicePriceWithoutTax(bill.getInvoicePriceWithoutTax()); + existBill.setInvoiceType(bill.getInvoiceType()); + updateOmsInvoiceBill(existBill); + WriteOffInvoiceRequestDto writeOffInvoiceRequestDto = new WriteOffInvoiceRequestDto(); + writeOffInvoiceRequestDto.setInvoiceBillId(existBill.getId()); + writeOffInvoiceRequestDto.setPartnerCode(existBill.getPartnerCode()); + writeOffInvoiceRequestDto.setPartnerName(existBill.getPartnerName()); + writeOffInvoiceRequestDto.setRemark("系统自动核销"); + List omsReceivableInvoiceDetails = detailService.listByInvoiceBillCode(existBill.getInvoiceBillCode()); + writeOffInvoiceRequestDto.setDetailList(omsReceivableInvoiceDetails); + writeOffService.autoTicketWriteOff(writeOffInvoiceRequestDto); return AjaxResult.success("上传成功"); } @@ -422,6 +436,88 @@ public class OmsInvoiceBillServiceImpl implements IOmsInvoiceBillService, TodoCo return AjaxResult.success("撤销成功"); } + @Override + public void returnTicketWriteOff(List collect, List omsReceivableInvoiceDetails) { + OmsInvoiceBill queryBill = new OmsInvoiceBill(); + queryBill.setInvoiceBillCodeList(collect); + List existBillList = selectOmsInvoiceBillList(queryBill); + Map> listMap = existBillList.stream() + .collect(Collectors.groupingBy(OmsInvoiceBill::getInvoiceBillType)); + + // 处理预付 + + +// // 预付处理逻辑 +// // 1:通过omsPayablePaymentDetailService查询对应的详情,然后根据paymentBillCode分组, +// // 将含税金额总和计算出来,加在预付单的剩余额度上 +// if (CollUtil.isNotEmpty(prePaymentBillList)) { +// // 按付款单code分组核销详情 +// Map> groupedDetails = +// omsPayablePaymentDetails.stream() +// .filter(detail -> detail.getPaymentBillCode() != null) +// .collect(Collectors.groupingBy(OmsPayablePaymentDetail::getPaymentBillCode)); +// +// // 计算每个付款单的核销金额合计 +// Map paymentBillWriteOffAmountMap = groupedDetails.entrySet().stream() +// .collect(Collectors.toMap( +// Map.Entry::getKey, +// entry -> entry.getValue().stream() +// .map(OmsPayablePaymentDetail::getPaymentAmount) +// .reduce(BigDecimal.ZERO, BigDecimal::add) +// )); +// +// // 更新预付单的剩余额度 - 批量操作 +// List updateBills = prePaymentBillList.stream() +// .map(prePaymentBill -> { +// BigDecimal increaseAmount = paymentBillWriteOffAmountMap.getOrDefault( +// prePaymentBill.getPaymentBillCode(), BigDecimal.ZERO); +// +// if (increaseAmount.compareTo(BigDecimal.ZERO) > 0) { +// OmsPaymentBill updateBill = new OmsPaymentBill(); +// updateBill.setId(prePaymentBill.getId()); +// // 在原剩余额度基础上加回本次核销金额 +// BigDecimal newResidueAmount = prePaymentBill.getPreResidueAmount() +// .add(increaseAmount); +// updateBill.setPreResidueAmount(newResidueAmount); +// return updateBill; +// } +// return null; +// }) +// .filter(Objects::nonNull) +// .collect(Collectors.toList()); +// +// if (CollUtil.isNotEmpty(updateBills)) { +// for (OmsPaymentBill bill : updateBills) { +// updateOmsPaymentBill(bill); +// } +// } +// } + //处理其余数据 + if (CollUtil.isNotEmpty(listMap.values())) { + List updateBills = new ArrayList<>(); + + for (List omsPaymentBillList : listMap.values()) { + for (OmsInvoiceBill tempBill : omsPaymentBillList) { + + OmsInvoiceBill updateBill = new OmsInvoiceBill(); + updateBill.setId(tempBill.getId()); + updateBill.setInvoiceStatus(OmsInvoiceBill.InvoiceStatusEnum.WAIT_INVOICE.getCode()); + updateBill.setApproveStatus(ApproveStatusEnum.WAIT_COMMIT.getCode()); + updateBill.setApproveTime(null); + updateBill.setActualInvoiceTime(null); + updateBills.add(updateBill); + } + } + if (CollUtil.isNotEmpty(updateBills)) { + omsInvoiceBillMapper.updateReturnWriteOffBatch(updateBills); + omsFinAttachmentService.deleteOmsFinAttachmentByPayment(updateBills.stream().map(OmsInvoiceBill::getId).collect(Collectors.toList()), + OmsFinAttachment.RelatedBillTypeEnum.RECEIVE_INVOICE.getCode()); + } + //清理detail数据 + detailService.clearWriteOff(omsReceivableInvoiceDetails.stream().map(OmsReceivableInvoiceDetail::getWriteOffId).distinct().filter(Objects::nonNull).collect(Collectors.toList())); + } + } + @Override public Object todoDetail(String businessKey, String processKey, String todoId) { return null; diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableInvoiceDetailServiceImpl.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableInvoiceDetailServiceImpl.java index 1ee2ae4f..b9c6b63a 100644 --- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableInvoiceDetailServiceImpl.java +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableInvoiceDetailServiceImpl.java @@ -1,10 +1,7 @@ package com.ruoyi.sip.service.impl; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -186,4 +183,38 @@ public class OmsReceivableInvoiceDetailServiceImpl implements IOmsReceivableInvo } return receiptDetailDTOS; } + + @Override + public List listReceivableByInvoiceWriteOffId(List longs) { + List receiptDetailDTOS = omsReceivableInvoiceDetailMapper.listReceivableByInvoiceWriteOffId(longs); + for (ReceiptDetailDTO detailDTO : receiptDetailDTOS) { + detailDTO.setReceiptRate(detailDTO.getReceiptAmount() + .divide(detailDTO.getTotalPriceWithTax(), 4, java.math.RoundingMode.HALF_UP) + .multiply(new BigDecimal("100"))); + } + return receiptDetailDTOS; + } + + @Override + public List listByWriteOffIds(Long[] ids) { + if (ids == null || ids.length == 0) { + return new ArrayList<>(); + } + OmsReceivableInvoiceDetail query = new OmsReceivableInvoiceDetail(); + query.setWriteOffIdList(Arrays.asList(ids)); + return omsReceivableInvoiceDetailMapper.list(query); + } + + @Override + public void clearWriteOff(List writeOffIdList) { + if (CollUtil.isEmpty(writeOffIdList)) { + return; + } + omsReceivableInvoiceDetailMapper.clearWriteOff(writeOffIdList); + } + + @Override + public void updateWriteOffIdBatch(List updateList) { + omsReceivableInvoiceDetailMapper.updateWriteOffIdBatch(updateList); + } } \ No newline at end of file diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableInvoiceWriteOffServiceImpl.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableInvoiceWriteOffServiceImpl.java new file mode 100644 index 00000000..2bf1bf32 --- /dev/null +++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/OmsReceivableInvoiceWriteOffServiceImpl.java @@ -0,0 +1,227 @@ +package com.ruoyi.sip.service.impl; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Date; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.ShiroUtils; +import com.ruoyi.sip.domain.*; +import com.ruoyi.sip.domain.dto.ReceiptDetailDTO; +import com.ruoyi.sip.dto.WriteOffInvoiceRequestDto; +import com.ruoyi.sip.service.IOmsInvoiceBillService; +import com.ruoyi.sip.service.IOmsReceivableBillService; +import com.ruoyi.sip.service.IOmsReceivableInvoiceDetailService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.sip.mapper.OmsReceivableInvoiceWriteOffMapper; +import com.ruoyi.sip.service.IOmsReceivableInvoiceWriteOffService; + +/** + * 应收票据核销单Service业务层处理 + * + * @author zghz + * @date 2025-12-24 + */ +@Service +public class OmsReceivableInvoiceWriteOffServiceImpl implements IOmsReceivableInvoiceWriteOffService +{ + @Autowired + private OmsReceivableInvoiceWriteOffMapper omsReceivableInvoiceWriteOffMapper; + + @Autowired + private IOmsInvoiceBillService omsInvoiceBillService; + @Autowired + private IOmsReceivableInvoiceDetailService invoiceDetailService; + @Autowired + private IOmsReceivableBillService receivableBillService; + + + + /** + * 查询应收票据核销单 + * + * @param id 应收票据核销单主键 + * @return 应收票据核销单 + */ + @Override + public OmsReceivableInvoiceWriteOff selectOmsReceivableInvoiceWriteOffById(Long id) + { + OmsReceivableInvoiceWriteOff omsReceivableInvoiceWriteOff = omsReceivableInvoiceWriteOffMapper.selectOmsReceivableInvoiceWriteOffById(id); + // 查询关联的开票单信息 + OmsInvoiceBill omsInvoiceBill = omsInvoiceBillService.selectOmsInvoiceBillByCode(omsReceivableInvoiceWriteOff.getInvoiceBillCode()); + omsReceivableInvoiceWriteOff.setInvoiceBill(omsInvoiceBill); + List receiptDetailDTOS = invoiceDetailService.listReceivableByInvoiceWriteOffId(Collections.singletonList(id)); + omsReceivableInvoiceWriteOff.setDetailList(receiptDetailDTOS); + return omsReceivableInvoiceWriteOff; + } + + /** + * 查询应收票据核销单列表 + * + * @param omsReceivableInvoiceWriteOff 应收票据核销单 + * @return 应收票据核销单 + */ + @Override + public List selectOmsReceivableInvoiceWriteOffList(OmsReceivableInvoiceWriteOff omsReceivableInvoiceWriteOff) + { + return omsReceivableInvoiceWriteOffMapper.selectOmsReceivableInvoiceWriteOffList(omsReceivableInvoiceWriteOff); + } + + /** + * 新增应收票据核销单 + * + * @param omsReceivableInvoiceWriteOff 应收票据核销单 + * @return 结果 + */ + @Override + public int insertOmsReceivableInvoiceWriteOff(OmsReceivableInvoiceWriteOff omsReceivableInvoiceWriteOff) + { + omsReceivableInvoiceWriteOff.setCreateTime(DateUtils.getNowDate()); + omsReceivableInvoiceWriteOff.setCreateBy(ShiroUtils.getUserId().toString()); + return omsReceivableInvoiceWriteOffMapper.insertOmsReceivableInvoiceWriteOff(omsReceivableInvoiceWriteOff); + } + + /** + * 修改应收票据核销单 + * + * @param omsReceivableInvoiceWriteOff 应收票据核销单 + * @return 结果 + */ + @Override + public int updateOmsReceivableInvoiceWriteOff(OmsReceivableInvoiceWriteOff omsReceivableInvoiceWriteOff) + { + omsReceivableInvoiceWriteOff.setUpdateTime(DateUtils.getNowDate()); + return omsReceivableInvoiceWriteOffMapper.updateOmsReceivableInvoiceWriteOff(omsReceivableInvoiceWriteOff); + } + + /** + * 批量删除应收票据核销单 + * + * @param ids 需要删除的应收票据核销单主键 + * @return 结果 + */ + @Override + public int deleteOmsReceivableInvoiceWriteOffByIds(Long[] ids) + { + if (ids == null || ids.length == 0) { + return 0; + } + List omsReceivableInvoiceWriteOffs = omsReceivableInvoiceWriteOffMapper.listByIds(ids); + if (CollUtil.isEmpty(omsReceivableInvoiceWriteOffs)) { + return 0; + } + List omsReceivableInvoiceDetails = invoiceDetailService.listByWriteOffIds(ids); + // 反核销处理:恢复收票单状态 + omsInvoiceBillService.returnTicketWriteOff(omsReceivableInvoiceWriteOffs.stream() + .map(OmsReceivableInvoiceWriteOff::getInvoiceBillCode).collect(java.util.stream.Collectors.toList()), + omsReceivableInvoiceDetails); + List payableBillIds = omsReceivableInvoiceDetails.stream() + .map(OmsReceivableInvoiceDetail::getReceivableBillId) + .distinct() + .collect(java.util.stream.Collectors.toList()); + + // 更新应付单的收票金额 + if (CollUtil.isNotEmpty(payableBillIds)) { + receivableBillService.updateInvoiceAmount(payableBillIds); + } + // 再删除主记录 + return omsReceivableInvoiceWriteOffMapper.deleteOmsReceivableInvoiceWriteOffByIds(ids); + } + + /** + * 删除应收票据核销单信息 + * + * @param id 应收票据核销单主键 + * @return 结果 + */ + @Override + public int deleteOmsReceivableInvoiceWriteOffById(Long id) + { + return omsReceivableInvoiceWriteOffMapper.deleteOmsReceivableInvoiceWriteOffById(id); + } + + @Override + public void autoTicketWriteOff(WriteOffInvoiceRequestDto writeOffRequestDto) { + if (CollUtil.isEmpty(writeOffRequestDto.getDetailList())) { + throw new ServiceException("请选择核销明细"); + } + // 获取收票单信息 + OmsInvoiceBill invoiceBill = omsInvoiceBillService.selectOmsInvoiceBillById(writeOffRequestDto.getInvoiceBillId()); + if (invoiceBill == null) { + throw new ServiceException("开票单不存在"); + } +// +// // 创建核销主记录 + OmsReceivableInvoiceWriteOff writeOff = new OmsReceivableInvoiceWriteOff(); + writeOff.setWriteOffCode(generateWriteOffCode()); + writeOff.setWriteOffType(OmsPayableTicketWriteOff.WriteOffTypeEnum.AUTO.getCode()); + writeOff.setInvoiceBillCode(invoiceBill.getInvoiceBillCode()); + writeOff.setPartnerCode(writeOffRequestDto.getPartnerCode()); + writeOff.setPartnerName(writeOffRequestDto.getPartnerName()); + writeOff.setWriteOffTime(new Date()); + writeOff.setRemark(writeOffRequestDto.getRemark()); +// +// // 计算总金额和相关税额 + BigDecimal totalAmount = BigDecimal.ZERO; + BigDecimal totalAmountWithoutTax = BigDecimal.ZERO; + BigDecimal totalTaxAmount = BigDecimal.ZERO; + + for (OmsReceivableInvoiceDetail item : writeOffRequestDto.getDetailList()) { + totalAmount = totalAmount.add(item.getInvoiceAmount()); + if (item.getInvoiceAmountWithoutTax() != null) { + totalAmountWithoutTax = totalAmountWithoutTax.add(item.getInvoiceAmountWithoutTax()); + } + if (item.getInvoiceAmountTax() != null) { + totalTaxAmount = totalTaxAmount.add(item.getInvoiceAmountTax()); + } + } + + writeOff.setWriteOffAmount(totalAmount); + writeOff.setWriteOffAmountWithoutTax(totalAmountWithoutTax); + writeOff.setWriteOffTaxAmount(totalTaxAmount); + // 设置创建时间 + writeOff.setCreateTime(new Date()); + writeOff.setCreateBy(ShiroUtils.getUserId().toString()); + writeOff.setUpdateTime(new Date()); + // 保存核销主记录 + omsReceivableInvoiceWriteOffMapper.insertOmsReceivableInvoiceWriteOff(writeOff); + + List updateList = new ArrayList<>(); + // 保存核销明细 + + + // 保存核销明细 + for (OmsReceivableInvoiceDetail omsReceivableInvoiceDetail : writeOffRequestDto.getDetailList()) { + OmsPayableTicketDetail temp = new OmsPayableTicketDetail(); + temp.setId(omsReceivableInvoiceDetail.getId()); + temp.setWriteOffId(writeOff.getId()); + updateList.add(temp); + } + if (CollUtil.isNotEmpty(updateList)) { + invoiceDetailService.updateWriteOffIdBatch(updateList); + } + // 更新对应应付单的收票金额 + receivableBillService.updateInvoiceAmount(writeOffRequestDto.getDetailList().stream() + .map(OmsReceivableInvoiceDetail::getReceivableBillId).distinct() + .collect(java.util.stream.Collectors.toList())); + } + + private String generateWriteOffCode() { + String prefix = "HX"; + // 查询当天已有的最大序列号 + String codePrefix = prefix + DateUtil.format(DateUtil.date(), DatePattern.PURE_DATE_PATTERN); + int maxSequence = omsReceivableInvoiceWriteOffMapper.selectMaxCodeByPrefix(codePrefix); + // 生成新的序列号 + int newSequence = maxSequence + 1; + // 序列号补零到4位 + String sequenceStr = String.format("%04d", newSequence); + return codePrefix + sequenceStr; + } +} \ No newline at end of file diff --git a/ruoyi-sip/src/main/resources/mapper/sip/OmsInvoiceBillMapper.xml b/ruoyi-sip/src/main/resources/mapper/sip/OmsInvoiceBillMapper.xml index 9d43fef9..826bb827 100644 --- a/ruoyi-sip/src/main/resources/mapper/sip/OmsInvoiceBillMapper.xml +++ b/ruoyi-sip/src/main/resources/mapper/sip/OmsInvoiceBillMapper.xml @@ -498,6 +498,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" approve_time=null where id = #{id} + + + update oms_invoice_bill + set + invoice_status=#{item.invoiceStatus}, + approve_status=#{item.approveStatus}, + approve_time=null, + actual_invoice_time=null, + update_time=now() + where id = #{item.id} + + delete from oms_invoice_bill where id = #{id} @@ -532,7 +544,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + insert into oms_receivable_invoice_detail @@ -171,6 +194,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" where id = #{id} + + update oms_receivable_invoice_detail set write_off_id = null where write_off_id in + + #{item} + + + + + update oms_receivable_invoice_detail set write_off_id = #{item.writeOffId} where id = #{item.id} + + delete from oms_receivable_invoice_detail where id = #{id} diff --git a/ruoyi-sip/src/main/resources/mapper/sip/OmsReceivableInvoiceWriteOffMapper.xml b/ruoyi-sip/src/main/resources/mapper/sip/OmsReceivableInvoiceWriteOffMapper.xml new file mode 100644 index 00000000..04832d60 --- /dev/null +++ b/ruoyi-sip/src/main/resources/mapper/sip/OmsReceivableInvoiceWriteOffMapper.xml @@ -0,0 +1,249 @@ + + + + + + + + + + + + + + + + + + + + + + + + + select + o.id, + o.write_off_code, + o.write_off_type, + o.invoice_bill_code, + o.partner_code, + o.partner_name, + o.write_off_amount, + o.write_off_amount_without_tax, + o.write_off_tax_amount, + o.write_off_time, + o.remark, + o.create_by, + o.create_time, + o.update_by, + o.update_time, + su.user_name as create_by_name + from oms_receivable_invoice_write_off o + left join sys_user su on o.create_by=su.user_id + + + + + + + + + + insert into oms_receivable_invoice_write_off + + + write_off_code, + + + write_off_type, + + + invoice_bill_code, + + + partner_code, + + + partner_name, + + + + write_off_amount, + + + write_off_amount_without_tax, + + + write_off_tax_amount, + + + write_off_time, + + + remark, + + + create_by, + + + create_time, + + + update_by, + + + update_time, + + + + + #{writeOffCode}, + + + #{writeOffType}, + + + #{invoiceBillCode}, + + + #{partnerCode}, + + + #{partnerName}, + + + #{writeOffAmount}, + + + #{writeOffAmountWithoutTax}, + + + #{writeOffTaxAmount}, + + + #{writeOffTime}, + + + #{remark}, + + + #{createBy}, + + + #{createTime}, + + + #{updateBy}, + + + #{updateTime}, + + + + + + update oms_receivable_invoice_write_off + + + write_off_code = #{writeOffCode}, + + + write_off_type = #{writeOffType}, + + + invoice_bill_code = #{invoiceBillCode}, + + + partner_code = #{partnerCode}, + + + write_off_amount = #{writeOffAmount}, + + + write_off_amount_without_tax = #{writeOffAmountWithoutTax}, + + + write_off_tax_amount = #{writeOffTaxAmount}, + + + write_off_time = #{writeOffTime}, + + + remark = #{remark}, + + + update_by = #{updateBy}, + + + update_time = #{updateTime}, + + + where id = #{id} + + + + delete from oms_receivable_invoice_write_off where id = #{id} + + + + delete from oms_receivable_invoice_write_off where id in + + #{id} + + + + + + \ No newline at end of file