From a19c88e810d727638d6d432163418f6f4e65f5ab Mon Sep 17 00:00:00 2001
From: orangebabu <2409692770@qq.com>
Date: Thu, 12 Jun 2025 11:48:04 +0800
Subject: [PATCH] =?UTF-8?q?=E5=85=BC=E8=81=8C=E5=87=AD=E8=AF=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/api/system/hr/employee-salary.ts | 7 +
jinbooks-ui/src/views/hr/salary-detail.vue | 79 ++++++-
jinbooks-ui/src/views/hr/salary-summary.vue | 12 +-
.../jinbooks/entity/hr/EmployeeSalary.java | 22 +-
.../service/EmployeeSalaryService.java | 11 +-
.../impl/EmployeeSalaryServiceImpl.java | 222 +++++++++++++++++-
.../controller/EmployeeSalaryController.java | 20 +-
7 files changed, 333 insertions(+), 40 deletions(-)
diff --git a/jinbooks-ui/src/api/system/hr/employee-salary.ts b/jinbooks-ui/src/api/system/hr/employee-salary.ts
index 06623f9..f120729 100644
--- a/jinbooks-ui/src/api/system/hr/employee-salary.ts
+++ b/jinbooks-ui/src/api/system/hr/employee-salary.ts
@@ -57,3 +57,10 @@ export function exportSalary(query: any): any {
})
}
+export function generateVoucherSubmit(data: any) {
+ return request({
+ url: '/employee/salary/generate-voucher',
+ method: 'post',
+ data: data
+ })
+}
diff --git a/jinbooks-ui/src/views/hr/salary-detail.vue b/jinbooks-ui/src/views/hr/salary-detail.vue
index 34d8bb4..2b1742a 100644
--- a/jinbooks-ui/src/views/hr/salary-detail.vue
+++ b/jinbooks-ui/src/views/hr/salary-detail.vue
@@ -205,6 +205,36 @@
{{ formatAmount(scope.row.businessExpenditureCosts) }}
+
+
+
+ 生成
+
+
+ 查看
+
+
+
+
+
+
+ 生成
+
+
+ 查看
+
+
+
+
+
+
+ {{ voucherTitle }}
+
+
+
diff --git a/jinbooks-ui/src/views/hr/salary-summary.vue b/jinbooks-ui/src/views/hr/salary-summary.vue
index d81f3ed..f4bcb4b 100644
--- a/jinbooks-ui/src/views/hr/salary-summary.vue
+++ b/jinbooks-ui/src/views/hr/salary-summary.vue
@@ -182,11 +182,11 @@
-
+
生成
-
查看
@@ -194,11 +194,11 @@
-
+
生成
-
查看
diff --git a/jinbooks/jinbooks-core/src/main/java/com/jinbooks/entity/hr/EmployeeSalary.java b/jinbooks/jinbooks-core/src/main/java/com/jinbooks/entity/hr/EmployeeSalary.java
index 809dda5..2155923 100644
--- a/jinbooks/jinbooks-core/src/main/java/com/jinbooks/entity/hr/EmployeeSalary.java
+++ b/jinbooks/jinbooks-core/src/main/java/com/jinbooks/entity/hr/EmployeeSalary.java
@@ -1,12 +1,12 @@
/*
* Copyright [2025] [JinBooks of copyright http://www.jinbooks.com]
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,7 +14,7 @@
* limitations under the License.
*
*/
-
+
package com.jinbooks.entity.hr;
@@ -113,6 +113,18 @@ public class EmployeeSalary extends BaseEntity {
*/
private BigDecimal insuranceUnemployment;
+ /**
+ * 收票工资凭证编码
+ */
+ @TableField(updateStrategy = FieldStrategy.ALWAYS)
+ private String accrualVoucherId;
+
+ /**
+ * 发放工资凭证编码
+ */
+ @TableField(updateStrategy = FieldStrategy.ALWAYS)
+ private String salaryVoucherId;
+
@TableField(fill = FieldFill.INSERT)
@TableLogic(value = "n", delval = "y")
@@ -126,7 +138,7 @@ public class EmployeeSalary extends BaseEntity {
@TableField(exist = false)
private String employeeNumber;
-
+
@TableField(exist = false)
private String employeeType;
}
diff --git a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/EmployeeSalaryService.java b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/EmployeeSalaryService.java
index fdaaf98..6243698 100644
--- a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/EmployeeSalaryService.java
+++ b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/EmployeeSalaryService.java
@@ -1,12 +1,12 @@
/*
* Copyright [2025] [JinBooks of copyright http://www.jinbooks.com]
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,10 +14,11 @@
* limitations under the License.
*
*/
-
+
package com.jinbooks.persistence.service;
+import com.jinbooks.entity.voucher.dto.GenerateVoucherDto;
import org.apache.ibatis.annotations.Param;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -45,4 +46,6 @@ public interface EmployeeSalaryService extends IService {
Message exportTaxItems(SalaryDetailPageDto dto, HttpServletResponse response);
+
+ Message generateVoucher(GenerateVoucherDto dto);
}
diff --git a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/EmployeeSalaryServiceImpl.java b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/EmployeeSalaryServiceImpl.java
index 37c621e..8664bc0 100644
--- a/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/EmployeeSalaryServiceImpl.java
+++ b/jinbooks/jinbooks-persistence/src/main/java/com/jinbooks/persistence/service/impl/EmployeeSalaryServiceImpl.java
@@ -1,12 +1,12 @@
/*
* Copyright [2025] [JinBooks of copyright http://www.jinbooks.com]
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,11 +14,25 @@
* limitations under the License.
*
*/
-
+
package com.jinbooks.persistence.service.impl;
import cn.hutool.core.bean.BeanUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.jinbooks.entity.book.Book;
+import com.jinbooks.entity.book.BookSubject;
+import com.jinbooks.entity.hr.*;
+import com.jinbooks.entity.voucher.dto.GenerateVoucherDto;
+import com.jinbooks.entity.voucher.dto.VoucherChangeDto;
+import com.jinbooks.entity.voucher.dto.VoucherItemChangeDto;
+import com.jinbooks.enums.SalaryVoucherTemplateEnum;
+import com.jinbooks.enums.VoucherStatusEnum;
+import com.jinbooks.persistence.mapper.*;
+import com.jinbooks.persistence.service.VoucherService;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
@@ -30,17 +44,12 @@ import com.jinbooks.constants.ConstsUser;
import com.jinbooks.constants.ContentType;
import com.jinbooks.entity.Message;
import com.jinbooks.entity.dto.ListIdsDto;
-import com.jinbooks.entity.hr.EmployeeSalary;
-import com.jinbooks.entity.hr.EmployeeSalarySummary;
-import com.jinbooks.entity.hr.Employee;
import com.jinbooks.entity.hr.dto.SalaryDetailChangeDto;
import com.jinbooks.entity.hr.dto.SalaryDetailPageDto;
import com.jinbooks.entity.hr.dto.SalarySummaryChangeDto;
import com.jinbooks.entity.PeriodStr;
import com.jinbooks.entity.hr.vo.TaxDeductionExportVo;
import com.jinbooks.exception.BusinessException;
-import com.jinbooks.persistence.mapper.EmployeeSalaryMapper;
-import com.jinbooks.persistence.mapper.EmployeeMapper;
import com.jinbooks.persistence.service.EmployeeSalaryService;
import com.jinbooks.util.PeriodDateUtils;
import com.jinbooks.util.DateUtils;
@@ -62,11 +71,11 @@ import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.io.Serializable;
+import java.math.BigDecimal;
import java.net.URLEncoder;
+import java.text.ParseException;
import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.List;
-import java.util.Objects;
+import java.util.*;
/**
* @description:
@@ -83,6 +92,21 @@ public class EmployeeSalaryServiceImpl extends ServiceImpl> pageList(SalaryDetailPageDto dto) {
@@ -278,4 +302,178 @@ public class EmployeeSalaryServiceImpl extends ServiceImpl generateVoucher(GenerateVoucherDto dto) {
+ String bookId = dto.getBookId();
+ Book book = bookMapper.selectById(bookId);
+ Integer voucherType = dto.getVoucherType();
+ EmployeeSalary summary = super.getById(dto.getId());
+
+ if (voucherType == 0 && StringUtils.isNotBlank(summary.getAccrualVoucherId())) {
+ return Message.ok("计提凭证已生成");
+ } else if (voucherType == 1 && StringUtils.isNotBlank(summary.getSalaryVoucherId())) {
+ return Message.ok("发放凭证已生成");
+ } else if (voucherType == 2 && StringUtils.isNotBlank(summary.getAccrualVoucherId())) {
+ return Message.ok("收票(兼职)凭证已生成");
+ } else if (voucherType == 3 && StringUtils.isNotBlank(summary.getSalaryVoucherId())) {
+ return Message.ok("发放(兼职)凭证已生成");
+ }
+
+ Date formattedDate = getFormattedCurrentDate();
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(formattedDate);
+ int year = calendar.get(Calendar.YEAR);
+ int month = calendar.get(Calendar.MONTH) + 1;
+
+ List rules = getSalaryVoucherRules(bookId, voucherType);
+ BigDecimal debitAmount = BigDecimal.ZERO;
+ BigDecimal creditAmount = BigDecimal.ZERO;
+
+ List voucherItems = new ArrayList<>();
+
+ for (EmployeeSalaryVoucherRule rule : rules) {
+ rule.setSummary(generateVoucherItemSummary(rule.getSummary(), year, month));
+
+ String selectedValue = rule.getSelectedValue();
+ SalaryVoucherTemplateEnum matchedEnum = SalaryVoucherTemplateEnum.fromValue(selectedValue);
+ if (matchedEnum == null) {
+ throw new BusinessException(50001, "凭证模板明细数据有误,请联系管理员");
+ }
+
+ BigDecimal amount = switch (matchedEnum) {
+ case COMPANY_COSTS -> summary.getBusinessExpenditureCosts();
+ case SALARY_PAYABLE -> summary.getTotalAmount().add(summary.getTotalSocialInsurance()).add(summary.getProvidentFund()).add(summary.getPersonalTax());
+ case ACTUAL_SALARY -> summary.getTotalAmount();
+ case PERSONAL_INCOME_TAX -> summary.getPersonalTax();
+ case PERSONAL_WITHHOLDING_SOCIAL_SECURITY -> summary.getTotalSocialInsurance();
+ case PERSONAL_WITHHOLDING_PROVIDENT_FUND -> summary.getProvidentFund();
+ case ENTERPRISES_PAY_SOCIAL_INSURANCE -> summary.getBusinessSocialInsurance();
+ case PROVIDENT_FUND_PAID_BY_ENTERPRISES -> summary.getBusinessProvidentFund();
+ };
+
+ boolean isDebit = "1".equals(rule.getDirection());
+ voucherItems.add(createVoucherItemDto(bookId, rule, isDebit, amount));
+
+ if (isDebit) {
+ debitAmount = debitAmount.add(amount);
+ } else {
+ creditAmount = creditAmount.add(amount);
+ }
+ }
+
+ if (debitAmount.compareTo(creditAmount) != 0) {
+ throw new BusinessException(50001, "借贷不平衡,请调整工资凭证模板");
+ }
+
+ VoucherChangeDto voucherChangeDto = createVoucherChangeDto(book, bookId, formattedDate, year, month, debitAmount);
+ voucherChangeDto.setRemark(rules.get(0).getSummary());
+ voucherChangeDto.setItems(voucherItems);
+ voucherChangeDto.setStatus(VoucherStatusEnum.DRAFT.getValue());
+
+ voucherService.save(voucherChangeDto);
+
+ LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
+ if (voucherType == 0 || voucherType == 2) {
+ updateWrapper.set(EmployeeSalary::getAccrualVoucherId, voucherChangeDto.getId());
+ } else if (voucherType == 1 || voucherType == 3) {
+ updateWrapper.set(EmployeeSalary::getSalaryVoucherId, voucherChangeDto.getId());
+ }
+ updateWrapper.eq(EmployeeSalary::getId, dto.getId());
+ super.update(updateWrapper);
+
+ return Message.ok(voucherChangeDto.getId());
+ }
+
+ public String generateVoucherItemSummary(String summary, int year, int month) {
+ return summary.replace("{yy}", (year + "").substring(2)).replace("{yyyy}", year + "").replace("{mm}", month + "");
+ }
+
+ /**
+ * Gets the current date formatted as yyyy-MM-dd with time set to 00:00:00
+ */
+ private Date getFormattedCurrentDate() {
+ try {
+ Date currentDate = new Date();
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ String formattedDateStr = dateFormat.format(currentDate);
+ return dateFormat.parse(formattedDateStr);
+ } catch (ParseException e) {
+ log.error("Error formatting date");
+ return new Date();
+ }
+ }
+
+ private List getSalaryVoucherRules(String bookId, Integer voucherType) {
+ List employeeSalaryVoucherRuleTemplates = employeeSalaryVoucherRuleTemplateMapper.selectList(Wrappers.lambdaQuery()
+ .eq(EmployeeSalaryVoucherRuleTemplate::getBookId, bookId)
+ .eq(EmployeeSalaryVoucherRuleTemplate::getStatus, 1)
+ .eq(EmployeeSalaryVoucherRuleTemplate::getVoucherType, voucherType));
+ if (ObjectUtils.isEmpty(employeeSalaryVoucherRuleTemplates)) {
+ if (Objects.equals(voucherType, 0)) {
+ throw new BusinessException(50001, "缺少计提工资凭证模板,请先在工资凭证规则处生成");
+ } else {
+ throw new BusinessException(50001, "缺少发放工资凭证模板,请先在工资凭证规则处生成");
+ }
+ }
+
+ String id = employeeSalaryVoucherRuleTemplates.get(0).getId();
+ List employeeSalaryVoucherRules = employeeSalaryVoucherRuleMapper.selectList(Wrappers.lambdaQuery()
+ .eq(EmployeeSalaryVoucherRule::getTemplateId, id));
+
+ if (employeeSalaryVoucherRules.size() < 2) {
+ throw new BusinessException(50001, "请添加模板明细数据");
+ }
+
+ return employeeSalaryVoucherRules;
+ }
+
+ private VoucherItemChangeDto createVoucherItemDto(String bookId,
+ EmployeeSalaryVoucherRule rule, boolean isDebit, BigDecimal amount) {
+
+ LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(BookSubject::getBookId, bookId);
+ wrapper.eq(BookSubject::getCode, rule.getSubjectCode());
+ BookSubject bookSubject = bookSubjectMapper.selectOne(wrapper);
+
+ if (Objects.isNull(bookSubject)) {
+ throw new BusinessException(50001, "查询不到该工资凭证规则设置的账套科目,请检查。");
+ }
+
+ VoucherItemChangeDto itemDto = new VoucherItemChangeDto();
+ itemDto.setSummary(rule.getSummary());
+ itemDto.setSubjectId(bookSubject.getId());
+ if (isDebit) {
+ itemDto.setDebitAmount(amount);
+ } else {
+ itemDto.setCreditAmount(amount);
+ }
+ itemDto.setAuxiliary(List.of());
+ itemDto.setSubjectCode(bookSubject.getCode());
+ itemDto.setSubjectName(bookSubject.getCode() + "-" + bookSubject.getName());
+ itemDto.setDetailedAccounts("");
+// itemDto.setSubjectBalance(BigDecimal.ZERO);
+
+ return itemDto;
+ }
+
+ private VoucherChangeDto createVoucherChangeDto(Book book, String bookId,
+ Date voucherDate, Integer year, Integer month, BigDecimal amount) {
+
+ Integer wordNum = voucherService.getAbleWordNum(bookId, "记", null, null).getData();
+
+ VoucherChangeDto dto = new VoucherChangeDto();
+ dto.setWordHead("记");
+ dto.setWordNum(wordNum);
+ dto.setBookId(bookId);
+ dto.setCompanyName(book.getCompanyName());
+ dto.setVoucherDate(voucherDate);
+ dto.setVoucherYear(year);
+ dto.setVoucherMonth(month);
+ dto.setDebitAmount(amount);
+ dto.setCreditAmount(amount);
+
+ return dto;
+ }
}
diff --git a/jinbooks/jinbooks-web/src/main/java/com/jinbooks/web/hr/controller/EmployeeSalaryController.java b/jinbooks/jinbooks-web/src/main/java/com/jinbooks/web/hr/controller/EmployeeSalaryController.java
index 2b3a6f2..ee25257 100644
--- a/jinbooks/jinbooks-web/src/main/java/com/jinbooks/web/hr/controller/EmployeeSalaryController.java
+++ b/jinbooks/jinbooks-web/src/main/java/com/jinbooks/web/hr/controller/EmployeeSalaryController.java
@@ -1,12 +1,12 @@
/*
* Copyright [2025] [JinBooks of copyright http://www.jinbooks.com]
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,7 +14,7 @@
* limitations under the License.
*
*/
-
+
package com.jinbooks.web.hr.controller;
@@ -28,6 +28,7 @@ import com.jinbooks.entity.hr.dto.SalaryDetailChangeDto;
import com.jinbooks.entity.hr.dto.SalaryDetailPageDto;
import com.jinbooks.entity.hr.dto.SalarySummaryChangeDto;
import com.jinbooks.entity.idm.UserInfo;
+import com.jinbooks.entity.voucher.dto.GenerateVoucherDto;
import com.jinbooks.persistence.service.EmployeeSalaryService;
import com.jinbooks.validate.AddGroup;
import com.jinbooks.validate.EditGroup;
@@ -86,7 +87,7 @@ public class EmployeeSalaryController {
public Message getById(@PathVariable(name = "id") String id) {
return Message.ok(employeeSalaryService.getById(id));
}
-
+
@GetMapping("/summary")
public Message summary(@ParameterObject SalarySummaryChangeDto dto,@CurrentUser UserInfo currentUser) {
if(dto.getBelongDateRange()!= null && dto.getBelongDateRange().length ==2
@@ -96,7 +97,7 @@ public class EmployeeSalaryController {
dto.setBookId(currentUser.getBookId());
return Message.ok(employeeSalaryService.selectSalarySummary(dto));
}
-
+
@GetMapping("/export")
public Message exportTaxItems(@ParameterObject SalaryDetailPageDto dto,
HttpServletResponse response, @CurrentUser UserInfo currentUser) {
@@ -108,4 +109,11 @@ public class EmployeeSalaryController {
public Message delete(@RequestBody ListIdsDto dto) {
return employeeSalaryService.delete(dto);
}
+
+
+ @PostMapping("/generate-voucher")
+ public Message generateVoucher(@Validated @RequestBody GenerateVoucherDto dto, @CurrentUser UserInfo currentUser) {
+ dto.setBookId(currentUser.getBookId());
+ return employeeSalaryService.generateVoucher(dto);
+ }
}