Merge branch 'main' of https://gitee.com/jinbooks/jinbooks
This commit is contained in:
@ -2213,9 +2213,13 @@ const distData: DistData = {
|
|||||||
value: "companyCosts"
|
value: "companyCosts"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "实发工资",
|
label: "应发工资",
|
||||||
value: "salaryPayable"
|
value: "salaryPayable"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: "实发工资",
|
||||||
|
value: "actualSalary"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: "个人所得税",
|
label: "个人所得税",
|
||||||
value: "personalIncomeTax"
|
value: "personalIncomeTax"
|
||||||
@ -2237,6 +2241,20 @@ const distData: DistData = {
|
|||||||
value: "providentFundPaidByEnterprises"
|
value: "providentFundPaidByEnterprises"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"labor_fee_values": [
|
||||||
|
{
|
||||||
|
label: "劳务费总额",
|
||||||
|
value: "companyCosts"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "实发劳务费",
|
||||||
|
value: "actualSalary"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "代扣个人所得税",
|
||||||
|
value: "personalIncomeTax"
|
||||||
|
}
|
||||||
|
],
|
||||||
"salary_directions": [
|
"salary_directions": [
|
||||||
{
|
{
|
||||||
label: "借",
|
label: "借",
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
<div class="queryForm">
|
<div class="queryForm">
|
||||||
<el-form :model="form" ref="formRef" :inline="true" label-width="68px">
|
<el-form :model="form" ref="formRef" :inline="true" label-width="68px">
|
||||||
<el-form-item label="凭证类型">
|
<el-form-item label="凭证类型">
|
||||||
<el-select v-model="form.voucherType" style="width: 200px">
|
<el-select v-model="form.voucherType" style="width: 200px" @change="handleChangeType">
|
||||||
<el-option v-for="item in voucherTypes" :label="item.label" :value="item.value"/>
|
<el-option v-for="item in voucherTypes" :label="item.label" :value="item.value"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -47,7 +47,7 @@
|
|||||||
:show-overflow-tooltip="true">
|
:show-overflow-tooltip="true">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-select v-model="scope.row.selectedValue" style="width: 100%">
|
<el-select v-model="scope.row.selectedValue" style="width: 100%">
|
||||||
<el-option v-for="item in salary_values" :label="item.label" :value="item.value"/>
|
<el-option v-for="item in salaryValuesList" :label="item.label" :value="item.value"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@ -89,10 +89,17 @@ import modal from "@/plugins/modal";
|
|||||||
const {t} = useI18n()
|
const {t} = useI18n()
|
||||||
const {proxy} = getCurrentInstance()!;
|
const {proxy} = getCurrentInstance()!;
|
||||||
|
|
||||||
const {salary_values, salary_directions}
|
const {salary_values, salary_directions, labor_fee_values}
|
||||||
= proxy?.useDict( "salary_values", "salary_directions");
|
= proxy?.useDict( "salary_values", "salary_directions", "labor_fee_values");
|
||||||
const emit: any = defineEmits(['dialogOfClosedMethods'])
|
const emit: any = defineEmits(['dialogOfClosedMethods'])
|
||||||
const formRef = ref<InstanceType<typeof ElForm> | null>(null);
|
const formRef = ref<InstanceType<typeof ElForm> | null>(null);
|
||||||
|
interface SalaryValueItem {
|
||||||
|
label: string
|
||||||
|
value: string | number
|
||||||
|
}
|
||||||
|
|
||||||
|
const salaryValuesList = ref<SalaryValueItem[]>([])
|
||||||
|
|
||||||
const props: any = defineProps({
|
const props: any = defineProps({
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -185,35 +192,67 @@ function reset(): any {
|
|||||||
form.value = {
|
form.value = {
|
||||||
voucherType: 0,
|
voucherType: 0,
|
||||||
wordHead: '记'
|
wordHead: '记'
|
||||||
};
|
}
|
||||||
|
|
||||||
const summaryTemplate = typeTextMap[form.value.voucherType] || "";
|
// 先根据 voucherType 给 salaryValuesList 赋值
|
||||||
|
if (form.value.voucherType === 0 || form.value.voucherType === 1) {
|
||||||
|
salaryValuesList.value = salary_values.value
|
||||||
|
} else {
|
||||||
|
salaryValuesList.value = labor_fee_values.value
|
||||||
|
}
|
||||||
|
|
||||||
dataList.value = [{
|
// 取第一个值
|
||||||
|
const selectedValue = salaryValuesList.value.length > 0 ? salaryValuesList.value[0].value : null
|
||||||
|
|
||||||
|
// 设置 dataList
|
||||||
|
const summaryTemplate = typeTextMap[form.value.voucherType] || ""
|
||||||
|
|
||||||
|
dataList.value = [
|
||||||
|
{
|
||||||
id: null,
|
id: null,
|
||||||
summary: summaryTemplate,
|
summary: summaryTemplate,
|
||||||
direction: "1",
|
direction: "1",
|
||||||
subjectCode: props.deptOptions?.[0]?.code || null,
|
subjectCode: props.deptOptions?.[0]?.code || null,
|
||||||
selectedValue: salary_values.value[0].value,
|
selectedValue: selectedValue,
|
||||||
}]
|
}
|
||||||
|
]
|
||||||
|
|
||||||
formRef?.value?.resetFields();
|
formRef?.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function addRecord() {
|
|
||||||
|
|
||||||
|
function addRecord() {
|
||||||
const summaryTemplate = typeTextMap[form.value.voucherType] || "";
|
const summaryTemplate = typeTextMap[form.value.voucherType] || "";
|
||||||
|
|
||||||
|
// 根据 voucherType 先切换数据源
|
||||||
|
if (form.value.voucherType === 0 || form.value.voucherType === 1) {
|
||||||
|
salaryValuesList.value = salary_values.value;
|
||||||
|
} else {
|
||||||
|
salaryValuesList.value = labor_fee_values.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果 salaryValuesList 为空,安全处理(防止访问 undefined)
|
||||||
|
const selectedValue = salaryValuesList.value.length > 0 ? salaryValuesList.value[0].value : null;
|
||||||
|
|
||||||
|
// 新增一条记录
|
||||||
dataList.value.push({
|
dataList.value.push({
|
||||||
id: null,
|
id: null,
|
||||||
summary: summaryTemplate,
|
summary: summaryTemplate,
|
||||||
direction: "1",
|
direction: "1",
|
||||||
subjectCode: props.deptOptions?.[0]?.code || null,
|
subjectCode: props.deptOptions?.[0]?.code || null,
|
||||||
selectedValue: salary_values.value[0].value,
|
selectedValue: selectedValue,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleChangeType() {
|
||||||
|
// 根据 voucherType 先切换数据源
|
||||||
|
if (form.value.voucherType === 0 || form.value.voucherType === 1) {
|
||||||
|
salaryValuesList.value = salary_values.value;
|
||||||
|
} else {
|
||||||
|
salaryValuesList.value = labor_fee_values.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function dialogOfClosedMethods(val: any): any {
|
function dialogOfClosedMethods(val: any): any {
|
||||||
dialogStatus.value = false;
|
dialogStatus.value = false;
|
||||||
|
|||||||
@ -29,7 +29,8 @@ import lombok.Getter;
|
|||||||
@Getter
|
@Getter
|
||||||
public enum SalaryVoucherTemplateEnum {
|
public enum SalaryVoucherTemplateEnum {
|
||||||
COMPANY_COSTS("companyCosts", "公司成本"),
|
COMPANY_COSTS("companyCosts", "公司成本"),
|
||||||
SALARY_PAYABLE("salaryPayable", "实发工资"),
|
SALARY_PAYABLE("salaryPayable", "应发工资"),
|
||||||
|
ACTUAL_SALARY("actualSalary", "实发工资"),
|
||||||
PERSONAL_INCOME_TAX("personalIncomeTax", "个人所得税"),
|
PERSONAL_INCOME_TAX("personalIncomeTax", "个人所得税"),
|
||||||
PERSONAL_WITHHOLDING_SOCIAL_SECURITY("personalWithholdingOfSocialSecurity", "个人代扣社保"),
|
PERSONAL_WITHHOLDING_SOCIAL_SECURITY("personalWithholdingOfSocialSecurity", "个人代扣社保"),
|
||||||
PERSONAL_WITHHOLDING_PROVIDENT_FUND("personalWithholdingOfProvidentFund", "个人代扣公积金"),
|
PERSONAL_WITHHOLDING_PROVIDENT_FUND("personalWithholdingOfProvidentFund", "个人代扣公积金"),
|
||||||
|
|||||||
@ -19,8 +19,10 @@
|
|||||||
package com.jinbooks.persistence.service.impl;
|
package com.jinbooks.persistence.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.bean.copier.CopyOptions;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
|
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.jinbooks.entity.Message;
|
import com.jinbooks.entity.Message;
|
||||||
@ -29,6 +31,9 @@ import com.jinbooks.entity.book.dto.BookChangeDto;
|
|||||||
import com.jinbooks.entity.book.dto.BookPageDto;
|
import com.jinbooks.entity.book.dto.BookPageDto;
|
||||||
import com.jinbooks.entity.book.vo.BookVo;
|
import com.jinbooks.entity.book.vo.BookVo;
|
||||||
import com.jinbooks.entity.dto.ListIdsDto;
|
import com.jinbooks.entity.dto.ListIdsDto;
|
||||||
|
import com.jinbooks.entity.hr.EmployeeSalarySummary;
|
||||||
|
import com.jinbooks.entity.hr.EmployeeSalaryVoucherRule;
|
||||||
|
import com.jinbooks.entity.hr.EmployeeSalaryVoucherRuleTemplate;
|
||||||
import com.jinbooks.enums.BookBusinessExceptionEnum;
|
import com.jinbooks.enums.BookBusinessExceptionEnum;
|
||||||
import com.jinbooks.exception.BusinessException;
|
import com.jinbooks.exception.BusinessException;
|
||||||
import com.jinbooks.persistence.mapper.BookMapper;
|
import com.jinbooks.persistence.mapper.BookMapper;
|
||||||
@ -40,6 +45,7 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description:
|
* @description:
|
||||||
@ -79,6 +85,12 @@ public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements Bo
|
|||||||
@Autowired
|
@Autowired
|
||||||
StandardSubjectCashFlowService standardSubjectCashFlowService;
|
StandardSubjectCashFlowService standardSubjectCashFlowService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
EmployeeSalaryVoucherRuleTemplateService employeeSalaryVoucherRuleTemplateService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
EmployeeSalaryVoucherRuleService employeeSalaryVoucherRuleService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Message<Page<Book>> pageList(BookPageDto dto) {
|
public Message<Page<Book>> pageList(BookPageDto dto) {
|
||||||
Page<Book> page = bookMapper.pageList(dto.build(), dto);
|
Page<Book> page = bookMapper.pageList(dto.build(), dto);
|
||||||
@ -113,6 +125,9 @@ public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements Bo
|
|||||||
//新增默认科目和现金流量的关系
|
//新增默认科目和现金流量的关系
|
||||||
standardSubjectCashFlowService.saveTemplateRelationships(dto.getId());
|
standardSubjectCashFlowService.saveTemplateRelationships(dto.getId());
|
||||||
|
|
||||||
|
//新增默认工资凭证规则模板
|
||||||
|
setSalaryVoucherRule(dto.getId());
|
||||||
|
|
||||||
//新增账套
|
//新增账套
|
||||||
Book newBook = new Book();
|
Book newBook = new Book();
|
||||||
BeanUtil.copyProperties(dto, newBook);
|
BeanUtil.copyProperties(dto, newBook);
|
||||||
@ -204,4 +219,72 @@ public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements Bo
|
|||||||
return bookMapper.listBooks(userId);
|
return bookMapper.listBooks(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setSalaryVoucherRule(String bookId) {
|
||||||
|
// 1. 查询内置的模板数据(bookId为null的数据)
|
||||||
|
List<EmployeeSalaryVoucherRuleTemplate> builtInTemplates = employeeSalaryVoucherRuleTemplateService.list(
|
||||||
|
Wrappers.<EmployeeSalaryVoucherRuleTemplate>lambdaQuery()
|
||||||
|
.isNull(EmployeeSalaryVoucherRuleTemplate::getBookId)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (ObjectUtils.isEmpty(builtInTemplates)) {
|
||||||
|
return; // 如果没有内置模板数据,直接返回
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 获取内置模板的ID列表
|
||||||
|
List<String> builtInTemplateIds = builtInTemplates.stream()
|
||||||
|
.map(EmployeeSalaryVoucherRuleTemplate::getId)
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
// 3. 查询对应的内置规则数据
|
||||||
|
List<EmployeeSalaryVoucherRule> builtInRules = employeeSalaryVoucherRuleService.list(
|
||||||
|
Wrappers.<EmployeeSalaryVoucherRule>lambdaQuery()
|
||||||
|
.in(EmployeeSalaryVoucherRule::getTemplateId, builtInTemplateIds)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 4. 复制模板数据并设置新的bookId,同时建立映射关系
|
||||||
|
CopyOptions copyOptions = new CopyOptions();
|
||||||
|
copyOptions.setIgnoreProperties("id", "createdBy", "createdDate", "modifiedBy", "modifiedDate");
|
||||||
|
|
||||||
|
Map<String, String> templateIdMapping = new HashMap<>();
|
||||||
|
|
||||||
|
// 逐个处理模板数据,确保映射关系正确
|
||||||
|
for (EmployeeSalaryVoucherRuleTemplate builtInTemplate : builtInTemplates) {
|
||||||
|
String oldTemplateId = builtInTemplate.getId();
|
||||||
|
|
||||||
|
// 复制模板数据
|
||||||
|
EmployeeSalaryVoucherRuleTemplate newTemplate = BeanUtil.copyProperties(
|
||||||
|
builtInTemplate,
|
||||||
|
EmployeeSalaryVoucherRuleTemplate.class,
|
||||||
|
"id", "createdBy", "createdDate", "modifiedBy", "modifiedDate", "deleted"
|
||||||
|
);
|
||||||
|
newTemplate.setBookId(bookId);
|
||||||
|
|
||||||
|
// 保存单个模板以获取新生成的ID
|
||||||
|
employeeSalaryVoucherRuleTemplateService.save(newTemplate);
|
||||||
|
|
||||||
|
// 建立新旧ID映射关系
|
||||||
|
String newTemplateId = newTemplate.getId();
|
||||||
|
templateIdMapping.put(oldTemplateId, newTemplateId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 复制规则数据并设置新的templateId
|
||||||
|
if (ObjectUtils.isNotEmpty(builtInRules)) {
|
||||||
|
List<EmployeeSalaryVoucherRule> newRules = BeanUtil.copyToList(
|
||||||
|
builtInRules,
|
||||||
|
EmployeeSalaryVoucherRule.class,
|
||||||
|
copyOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
// 更新规则数据的templateId为新模板的ID
|
||||||
|
newRules.forEach(rule -> {
|
||||||
|
String oldTemplateId = rule.getTemplateId();
|
||||||
|
String newTemplateId = templateIdMapping.get(oldTemplateId);
|
||||||
|
rule.setTemplateId(newTemplateId);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 6. 批量保存新的规则数据
|
||||||
|
employeeSalaryVoucherRuleService.saveBatch(newRules);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -173,7 +173,8 @@ public class EmployeeSalarySummaryServiceImpl extends ServiceImpl<EmployeeSalary
|
|||||||
|
|
||||||
BigDecimal amount = switch (matchedEnum) {
|
BigDecimal amount = switch (matchedEnum) {
|
||||||
case COMPANY_COSTS -> summary.getBusinessExpenditureCosts();
|
case COMPANY_COSTS -> summary.getBusinessExpenditureCosts();
|
||||||
case SALARY_PAYABLE -> summary.getTotalAmount();
|
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_INCOME_TAX -> summary.getPersonalTax();
|
||||||
case PERSONAL_WITHHOLDING_SOCIAL_SECURITY -> summary.getTotalSocialInsurance();
|
case PERSONAL_WITHHOLDING_SOCIAL_SECURITY -> summary.getTotalSocialInsurance();
|
||||||
case PERSONAL_WITHHOLDING_PROVIDENT_FUND -> summary.getProvidentFund();
|
case PERSONAL_WITHHOLDING_PROVIDENT_FUND -> summary.getProvidentFund();
|
||||||
@ -267,6 +268,10 @@ public class EmployeeSalarySummaryServiceImpl extends ServiceImpl<EmployeeSalary
|
|||||||
wrapper.eq(BookSubject::getCode, rule.getSubjectCode());
|
wrapper.eq(BookSubject::getCode, rule.getSubjectCode());
|
||||||
BookSubject bookSubject = bookSubjectMapper.selectOne(wrapper);
|
BookSubject bookSubject = bookSubjectMapper.selectOne(wrapper);
|
||||||
|
|
||||||
|
if (Objects.isNull(bookSubject)) {
|
||||||
|
throw new BusinessException(50001, "查询不到该工资凭证规则设置的账套科目,请检查。");
|
||||||
|
}
|
||||||
|
|
||||||
VoucherItemChangeDto itemDto = new VoucherItemChangeDto();
|
VoucherItemChangeDto itemDto = new VoucherItemChangeDto();
|
||||||
itemDto.setSummary(rule.getSummary());
|
itemDto.setSummary(rule.getSummary());
|
||||||
itemDto.setSubjectId(bookSubject.getId());
|
itemDto.setSubjectId(bookSubject.getId());
|
||||||
|
|||||||
Reference in New Issue
Block a user