Compare commits

...

10 Commits

Author SHA1 Message Date
8cf3cc8014 会计科目菜单 2025-08-01 09:38:06 +08:00
7f469b3138 Subject PinyinCode 2025-07-31 18:06:50 +08:00
3bb38c2369 修改sql 2025-07-28 15:17:22 +08:00
7c873453b1 修改sql 2025-07-28 14:56:25 +08:00
f1be1e7b5d 修改sql 2025-07-24 17:09:28 +08:00
ce57bd4208 优化代码 2025-07-23 10:59:45 +08:00
51d53775ae 修复资产负债表金额统计异常 2025-07-06 10:37:29 +08:00
89ce78941e springBoot 3.4.7 2025-07-04 16:54:51 +08:00
214b89230c 科目余额表增加上月数据 2025-07-04 16:46:00 +08:00
b46bfe03c8 修复科目余额表统计问题 2025-07-04 16:06:13 +08:00
26 changed files with 443 additions and 485 deletions

View File

@ -14,7 +14,7 @@
"@element-plus/icons-vue": "2.3.1",
"@vueup/vue-quill": "1.2.0",
"@vueuse/core": "10.11.0",
"axios": "0.29.0",
"axios": "1.8.2",
"dayjs": "^1.11.13",
"decimal.js": "^10.5.0",
"echarts": "^5.6.0",

View File

@ -36,14 +36,14 @@
<svg-icon icon-class="setting"></svg-icon>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>
<svg-icon icon-class="border-left"></svg-icon>
<span style="margin-left: 5px">RTL</span>
</el-dropdown-item>
<el-dropdown-item>
</el-dropdown-item>
<el-dropdown-item>
<CleanSession class="right-menu-item hover-effect"/>

View File

@ -73,11 +73,6 @@
<el-tooltip content="编辑">
<el-button link icon="Edit" @click="handleUpdate(scope.row)"></el-button>
</el-tooltip>
<el-tooltip content="关联会计科目">
<el-button plain type="text" @click="showSubjects(scope.row)">
<svg-icon icon-class="menus-huijikemu" size="0.9em"></svg-icon>
</el-button>
</el-tooltip>
<el-tooltip content="移除">
<el-button link icon="Delete" type="danger" @click="handleDelete(scope.row)"></el-button>
</el-tooltip>
@ -99,8 +94,7 @@
:vat_types="books_vat_type"
:books_industry="books_industry"
@dialogOfClosedMethods="dialogOfClosedMethods"></edit-form>
<!--会计科目-->
<subjects-related :title="title" :form-id="id" :open="subjectOpen" @hatsDrawerClose="dialogOfClosedMethods"/>
</div>
</template>
@ -108,7 +102,6 @@
import {useI18n} from "vue-i18n";
import {getCurrentInstance, reactive, ref, toRefs} from "vue";
import editForm from "./edit.vue";
import subjectsRelated from "./subject-relate.vue";
import modal from "@/plugins/modal";
import DictTagNumber from "@/components/DIctTagNumber/index.vue";
import {listBooksSets, deleteBatch} from "@/api/system/book/book";

View File

@ -1,10 +1,6 @@
<template>
<el-drawer v-model="dialogStatus" :close-on-click-modal="false" size="80%"
@close="dialogOfClosedMethods(false)">
<template #header>
<h4>{{ title }}</h4>
</template>
<template #default>
<div class="app-container">
<el-card class="common-card query-box">
<div class="queryForm">
<el-form :model="queryParams" ref="queryRef" :inline="true"
@submit.native.prevent>
@ -47,6 +43,8 @@
</el-form-item>
</el-form>
</div>
</el-card>
<el-card class="common-card">
<div class="button-top">
<el-button
@click="handleAdd"
@ -127,6 +125,7 @@
</template>
</el-table-column>
</el-table>
</el-card>
<!-- <pagination-->
<!-- v-show="total > 0"-->
<!-- :total="total"-->
@ -240,13 +239,7 @@
</div>
</template>
</el-drawer>
</template>
<template #footer>
<div style="flex: auto">
<el-button @click="dialogOfClosedMethods(false)">{{ t('org.cancel') }}</el-button>
</div>
</template>
</el-drawer>
</div>
</template>
<script setup lang="ts">
import modal from "@/plugins/modal";
@ -267,10 +260,13 @@ import {
reorgDisplayName
} from "@/api/system/book/book-subject";
import {handleTree} from "@/utils/Jinbooks";
import bookStore from "@/store/modules/bookStore";
import Template from "@/views/hr/salary-voucher-rules/template.vue";
const {t} = useI18n()
const currBookStore = bookStore()
const {proxy} = getCurrentInstance()!;
const {subjects_category, subjects_auxiliary}
@ -287,22 +283,6 @@ const emit: any = defineEmits(['hatsDrawerClose'])
const formRef = ref<InstanceType<typeof ElForm> | null>(null);
const props: any = defineProps({
title: {
type: String,
default: ""
},
open: {
type: Boolean,
default: false
},
formId: {
type: String,
default: undefined
},
}
)
const data: any = reactive({
queryParams: {
pageSize: 100000,
@ -345,21 +325,7 @@ const defaultProps: any = ref({
disabled: disabledFilter
})
// open
watch(
() => props.open,
(val: any) => {
if (val && props.formId) {
dialogStatus.value = props.open;
queryParams.value.bookId = props.formId;
getList();
getSetTree();
} else {
reset();
}
},
{immediate: true}
);
queryParams.value.bookId = currBookStore.bookId;
function dialogOfClosedMethods(val: any): any {
dialogStatus.value = false;
@ -391,7 +357,7 @@ function handleAdd(): any {
form.value = {
direction: "1",
status: 1,
bookId: props.formId,
bookId: currBookStore.bookId,
auxiliary: [],
isCash: 0
};
@ -400,7 +366,7 @@ function handleAdd(): any {
}
function getOneSetSubject() {
getSetSubject({id: id.value, bookId: props.formId}).then((res: any) => {
getSetSubject({id: id.value, bookId: currBookStore.bookId}).then((res: any) => {
try {
res.data.auxiliary = res.data.auxiliary ? JSON.parse(res.data.auxiliary) : [];
res.data.auxiliary.forEach((t: any) => {
@ -415,13 +381,13 @@ function getOneSetSubject() {
}
form.value = res.data;
form.value.bookId = props.formId;
form.value.bookId = currBookStore.bookId;
})
}
function onDelete(row: any): any {
modal.confirm("是否确认删除名称为\"" + row.name + "\"的会计科目?").then(function () {
return deleteBatch({listIds: [row.id], bookId: props.formId});
return deleteBatch({listIds: [row.id], bookId: currBookStore.bookId});
}).then((res: any) => {
if (res.code === 0) {
getList();
@ -436,7 +402,7 @@ function onDelete(row: any): any {
/** 多选删除操作*/
function handleRemove(): any {
modal.confirm("是否确认删除这些数据?").then(function () {
return deleteBatch({listIds: ids.value, bookId: props.formId});
return deleteBatch({listIds: ids.value, bookId: currBookStore.bookId});
}).then((res: any) => {
if (res.code === 0) {
handleQuery();
@ -497,17 +463,17 @@ interface TreeNode {
}
function getSetTree() {
getTree({bookId: props.formId}).then((response: { data: TreeNode[] }) => {
getTree({bookId: currBookStore.bookId}).then((response: { data: TreeNode[] }) => {
deptOptions.value = response.data;
form.value.parentId = undefined;
});
}
function disabledFilter(data: any, node: any): any {
if (!props.formId) {
if (!currBookStore.bookId) {
return false;
}
return new RegExp(`/${props.formId}(/|$)`).test(data.idPath)
return new RegExp(`/${currBookStore.bookId}(/|$)`).test(data.idPath)
}
function handleUpdate(row: any): any {
@ -533,10 +499,10 @@ function submitForm(): any {
formRef?.value?.validate((valid: any) => {
if (valid) {
const operation: any = id.value ? updateSubject : saveSubject;
const successMessage: any = props.formId
const successMessage: any = currBookStore.bookId
? t('org.success.update')
: t('org.success.add');
const formData = {...form.value, bookId: props.formId}
const formData = {...form.value, bookId: currBookStore.bookId}
formData.auxiliary = formData.auxiliary && formData.auxiliary instanceof Array
? JSON.stringify(formData.auxiliary) : '[]';
operation(formData).then((res: any) => handleResponse(res, successMessage));
@ -568,6 +534,10 @@ function handle_subjects_category_dicts(item: any) {
}
}
getList();
getSetTree();
</script>
<style lang="scss" scoped>

View File

@ -17,17 +17,17 @@
show-word-limit
placeholder="请输入规则描述"
></el-input>
</el-form-item>
<el-form-item prop="status" :label="$t('jbx.text.status.status')">
<el-switch
:width="44"
v-model="form.status"
:active-value="1"
:inactive-value="0"
active-icon-class="el-icon-close"
inactive-icon-class="el-icon-check">
</el-switch>
</el-form-item>
</el-form-item><el-form-item prop="status" :label="$t('jbx.text.status.status')">
<el-switch
:width="44"
v-model="form.status"
:active-value="1"
:inactive-value="0"
active-icon-class="el-icon-close"
inactive-icon-class="el-icon-check">
</el-switch>
</el-form-item>
</el-form>
<!-- 公式构建区 -->

View File

@ -293,7 +293,7 @@ function submit() {
saveSelectItem(dataDto).then((response: any) => {
if (response.code === 0) {
modal.msgSuccess("新增成功");
modal.msgSuccess("操作成功");
} else {
modal.msgError(response.message);
}

View File

@ -42,9 +42,13 @@
<el-radio-group v-if="queryParams.periodType === 'quarter'" style="margin-left: 10px"
v-model="queryParams.reportQuarter" @change="handleQuery">
<el-radio-button label="第一季度" value="Q1"></el-radio-button>
<el-radio-button label="第二季度" value="Q2"></el-radio-button>
<el-radio-button label="第季度" value="Q3"></el-radio-button>
<el-radio-button label="第四季度" value="Q4"></el-radio-button>
<el-radio-button v-if="currBookStore.termCurrent >= (new Date().getFullYear() + '-04')"
label="第季度"
value="Q2"></el-radio-button>
<el-radio-button v-if="currBookStore.termCurrent >= (new Date().getFullYear() + '-07')"
label="第三季度" value="Q3"></el-radio-button>
<el-radio-button v-if="currBookStore.termCurrent >= (new Date().getFullYear() + '-10')"
label="第四季度" value="Q4"></el-radio-button>
</el-radio-group>
<el-radio-group v-if="queryParams.periodType === 'halfYear'" style="margin-left: 10px"
v-model="queryParams.reportQuarter" @change="handleQuery">
@ -94,7 +98,7 @@
<template #default="scope">
<span :style="{'text-indent': scope.row.level + 'em',
display: 'inline-block', 'margin-right': '30px', fontWeight: scope.row.level === 1 ? 'bold' : ''}">
{{scope.row.symbol === '-' ? '减:' : ''}}{{ scope.row.itemName }}
{{ scope.row.symbol === '-' ? '减:' : '' }}{{ scope.row.itemName }}
</span>
</template>
</el-table-column>
@ -123,12 +127,12 @@
<template #default="scope">
<span :style="{'text-indent': scope.row.liabilityLevel + 'em',
display: 'inline-block', 'margin-right': '30px', fontWeight: scope.row.liabilityLevel === 1 ? 'bold' : ''}">
{{scope.row.liabilitySymbol === '-' ? '减:' : ''}}{{ scope.row.liabilityItemName }}
{{ scope.row.liabilitySymbol === '-' ? '减:' : '' }}{{ scope.row.liabilityItemName }}
</span>
</template>
</el-table-column>
<el-table-column label="行次" align="center" width="100" prop="liabilitySortIndex"/>
<el-table-column label="期末余额" align="right" header-align="center" width="140"
<el-table-column label="期末余额" align="right" header-align="center" width="140"
prop="liabilityCurrentBalance">
<template #default="scope">
{{ formatAmount(scope.row.liabilityCurrentBalance, '') }}
@ -164,30 +168,30 @@
<template #default>
<el-form :model="form" :rules="rules" ref="balanceSheetRef" label-width="68px"
inline-message>
<!-- <el-form-item v-if="!form.id" label="级别" prop="level">-->
<!-- <el-radio-group :disabled="!form.parentId" v-model="form.level">-->
<!-- <el-radio-button label="本级" :value="level"/>-->
<!-- <el-radio-button label="下级" :value="level + 1"/>-->
<!-- </el-radio-group>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="类型" prop="assetOrLiability">-->
<!-- <el-radio-group disabled v-model="form.assetOrLiability">-->
<!-- <el-radio-button label="资产" value="asset"/>-->
<!-- <el-radio-button label="负债" value="liability"/>-->
<!-- </el-radio-group>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="编码" prop="itemCode">-->
<!-- <el-input disabled style="width: 300px" v-model="form.itemCode" placeholder="请输入编码"/>-->
<!-- </el-form-item>-->
<!-- <el-form-item v-if="!form.id" label="级别" prop="level">-->
<!-- <el-radio-group :disabled="!form.parentId" v-model="form.level">-->
<!-- <el-radio-button label="本级" :value="level"/>-->
<!-- <el-radio-button label="下级" :value="level + 1"/>-->
<!-- </el-radio-group>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="类型" prop="assetOrLiability">-->
<!-- <el-radio-group disabled v-model="form.assetOrLiability">-->
<!-- <el-radio-button label="资产" value="asset"/>-->
<!-- <el-radio-button label="负债" value="liability"/>-->
<!-- </el-radio-group>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="编码" prop="itemCode">-->
<!-- <el-input disabled style="width: 300px" v-model="form.itemCode" placeholder="请输入编码"/>-->
<!-- </el-form-item>-->
<el-form-item label="编码" prop="itemCode">
<el-input style="width: 300px" v-model="form.itemCode" placeholder="请输入编码" disabled/>
</el-form-item>
<el-form-item label="名称" prop="itemName">
<el-input style="width: 300px" v-model="form.itemName" placeholder="请输入名称"/>
</el-form-item>
<!-- <el-form-item label="行号" prop="sortIndex">-->
<!-- <el-input-number disabled :min="1" v-model="form.sortIndex" placeholder="请输入行号"/>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="行号" prop="sortIndex">-->
<!-- <el-input-number disabled :min="1" v-model="form.sortIndex" placeholder="请输入行号"/>-->
<!-- </el-form-item>-->
<el-form-item v-if="form.level === 2" label="计算" prop="symbol">
<el-radio-group v-model="form.symbol">
<el-radio-button label="加" value="+"/>

View File

@ -7,9 +7,9 @@
<el-switch v-model="queryParams.showAux" @change="handleQuery"/>
</el-form-item>
<!-- <el-form-item label="显示所有科目" prop="showAll">-->
<!-- <el-switch v-model="queryParams.showAll" @change="handleQuery"/>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="显示所有科目" prop="showAll">-->
<!-- <el-switch v-model="queryParams.showAll" @change="handleQuery"/>-->
<!-- </el-form-item>-->
<el-form-item label="" prop="defaultExpandAll">
<el-checkbox @change="defaultExpandAll" :model-value="showTreeAll" label="展开所有层级"/>
@ -97,7 +97,7 @@
</div>
</template>
</el-table-column>
<el-table-column label="期初余额" align="center">
<el-table-column :label="queryParams.periodType === 'year'? '年初余额' : '期初余额'" align="center">
<el-table-column prop="openingBalanceDebit" align="center" label="借方">
<template #default="scope">
{{ formatAmount(scope.row.openingBalanceDebit, '') }}
@ -139,14 +139,14 @@
<el-table-column prop="closingBalanceDebit" align="center" label="借方">
<template #default="scope">
<div :style="{backgroundColor: scope.row.closingBalanceDebit >= 0 ? '' : 'bisque'}">
{{ formatAmount(scope.row.closingBalanceDebit, '') }}
{{ formatAmount(scope.row.closingBalanceDebit, '') }}
</div>
</template>
</el-table-column>
<el-table-column prop="closingBalanceCredit" align="center" label="贷方">
<template #default="scope">
<div :style="{backgroundColor: scope.row.closingBalanceCredit >= 0 ? '' : 'bisque'}">
{{ formatAmount(scope.row.closingBalanceCredit, '') }}
<div :style="{backgroundColor: scope.row.closingBalanceCredit >= 0 ? '' : 'bisque'}">
{{ formatAmount(scope.row.closingBalanceCredit, '') }}
</div>
</template>
</el-table-column>

View File

@ -13,10 +13,10 @@ jibToAuthPassword =docker registry credential
#jars version
#spring
springVersion =6.2.7
springBootVersion =3.4.6
springSecurityVersion =6.5.0
springDataVersion =3.5.0
springVersion =6.2.8
springBootVersion =3.4.7
springSecurityVersion =6.5.1
springDataVersion =3.5.1
springretryVersion =2.0.9
#spring plugin
springplugincoreVersion =3.0.0

View File

@ -168,6 +168,42 @@ public class StatementSubjectBalance extends BaseEntity implements Serializable
@Schema(name = "closingBalanceCredit", description = "期末余额(贷方)")
private BigDecimal closingBalanceCredit;
/**
* 上月末余额
*/
@Schema(name = "prevbalance", description = "上月余额")
@TableField(fill = FieldFill.INSERT)
private BigDecimal prevBalance;
/**
* 上月期末余额(借方)
*/
@Schema(name = "prevClosingBalanceDebit", description = "上月期末余额(借方)")
@TableField(fill = FieldFill.INSERT)
private BigDecimal prevClosingBalanceDebit;
/**
* 上月期末余额(贷方)
*/
@Schema(name = "prevClosingBalanceCredit", description = "上月期末余额(贷方)")
@TableField(fill = FieldFill.INSERT)
private BigDecimal prevClosingBalanceCredit;
/**
* 上月本年累计发生额(借方)
*/
@Schema(name = "prevYearToDateDebit", description = "上月本年累计发生额(借方)")
@TableField(fill = FieldFill.INSERT)
private BigDecimal prevYearToDateDebit;
/**
* 上月本年累计发生额(贷方)
*/
@Schema(name = "prevYearToDateCredit", description = "上月本年累计发生额(贷方)")
@TableField(fill = FieldFill.INSERT)
private BigDecimal prevYearToDateCredit;
/**
* 是否辅助核算项:n-否;y-是
*/

View File

@ -1,188 +0,0 @@
/*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.jinbooks.entity.statement;
import com.baomidou.mybatisplus.annotation.*;
import com.jinbooks.entity.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 科目余额期初数据 jbx_statement_subject_balance_opening
*
* @author wuyan
* {@code @date} 2025-02-03
*/
@EqualsAndHashCode(callSuper = true)
@Data
@TableName("jbx_statement_subject_balance_opening")
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class StatementSubjectBalanceOpening extends BaseEntity implements Serializable {
/**
*
*/
private static final long serialVersionUID = -3640591095573870104L;
/**
* 主键
*/
@TableId(type = IdType.ASSIGN_ID)
private String id;
/**
* 账套ID
*/
@Schema(name = "bookId", description = "所属账套")
private String bookId;
@Schema(name = "yearPeriod", description = "期间")
private String yearPeriod;
/**
* 报表周期month、quarter、year
*/
@Schema(name = "periodType", description = "报表周期(如:月、季、年)")
private String periodType;
/**
* 排序序号
*/
@Schema(name = "sortIndex", description = "排序序号")
private Integer sortIndex;
/**
* 原始数据id
*/
@Schema(name = "sourceId", description = "原始数据id")
private String sourceId;
/**
* 父级科目id
*/
@Schema(name = "parentId", description = "父级科目id")
private String parentId;
/**
* 科目编码
*/
@Schema(name = "subjectCode", description = "科目编码")
private String subjectCode;
/**
* 科目名称
*/
@Schema(name = "subjectName", description = "科目名称")
private String subjectName;
/**
* 借贷方向
*/
@Schema(name = "direction", description = "借贷方向")
String direction;
/**
* 余额
*/
@Schema(name = "balance", description = "余额")
private BigDecimal balance;
/**
* 期初余额(借方)
*/
@Schema(name = "openingBalanceDebit", description = "期初余额(借方)")
private BigDecimal openingBalanceDebit;
/**
* 期初余额(贷方)
*/
@Schema(name = "openingBalanceCredit", description = "期初余额(贷方)")
private BigDecimal openingBalanceCredit;
/**
* 年初余额(借方)
*/
@Schema(name = "openingYearBalanceDebit", description = "年初余额(借方)")
private BigDecimal openingYearBalanceDebit;
/**
* 年初余额(贷方)
*/
@Schema(name = "openingYearBalanceCredit", description = "年初余额(贷方)")
private BigDecimal openingYearBalanceCredit;
/**
* 本期发生额(借方)
*/
@Schema(name = "currentPeriodDebit", description = "本期发生额(借方)")
private BigDecimal currentPeriodDebit;
/**
* 本期发生额(贷方)
*/
@Schema(name = "currentPeriodCredit", description = "本期发生额(贷方)")
private BigDecimal currentPeriodCredit;
/**
* 本年累计发生额(借方)
*/
@Schema(name = "yearToDateDebit", description = "本年累计发生额(借方)")
private BigDecimal yearToDateDebit;
/**
* 本年累计发生额(贷方)
*/
@Schema(name = "yearToDateCredit", description = "本年累计发生额(贷方)")
private BigDecimal yearToDateCredit;
/**
* 期末余额(借方)
*/
@Schema(name = "closingBalanceDebit", description = "期末余额(借方)")
private BigDecimal closingBalanceDebit;
/**
* 期末余额(贷方)
*/
@Schema(name = "closingBalanceCredit", description = "期末余额(贷方)")
private BigDecimal closingBalanceCredit;
/**
* 是否辅助核算项:n-否;y-是
*/
private String isAuxiliary;
/**
* 当前期是否使用n-否;y-是
*/
private String isVoucher;
/**
* 删除标记,默认为 'n' (未删除),如果为 'y' 表示已删除
*/
@TableField(fill = FieldFill.INSERT)
@TableLogic(value = "n", delval = "y")
private String deleted;
}

View File

@ -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.statement.dto;
@ -26,8 +26,11 @@ import com.jinbooks.util.DateUtils;
import lombok.*;
import org.apache.commons.lang3.StringUtils;
import java.io.Serial;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
@ -45,12 +48,13 @@ import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
public class StatementParamsDto extends PageQuery {
/**
*
*/
@Serial
private static final long serialVersionUID = -3371902023167307161L;
/**
*
*/
private static final long serialVersionUID = -3371902023167307161L;
/**
* 账套ID
*/
private String bookId;
@ -102,7 +106,7 @@ public class StatementParamsDto extends PageQuery {
* 显示所有科目
*/
private Boolean showAll;
/**
* 科目编码过滤
*/
@ -123,13 +127,28 @@ public class StatementParamsDto extends PageQuery {
this.year = Integer.parseInt(reportDate.substring(0, 4));
this.month = null;
this.quarter = null;
// 设置全年起始和结束日期
this.dateRange = new String[]{this.year + "-01",this.year + "-12"};
//年初日期
this.dateRangeStart = year + "-01-01";
//年终日期
this.dateRangeEnd = year + "-12-31";
this.reportDate = this.year + "-12";
// 年初日期固定
this.dateRangeStart = this.year + "-01-01";
// 当前系统日期
LocalDate now = LocalDate.now();
int currentYear = now.getYear();
if (this.year == currentYear) {
// 当前是本年度,终止为本月最后一天
int currentMonth = now.getMonthValue();
LocalDate lastDayOfCurrentMonth = now.with(TemporalAdjusters.lastDayOfMonth());
// 设置 dateRange 为 01 到当前月
this.dateRange = new String[]{
String.format("%d-01", this.year),
String.format("%d-%02d", this.year, currentMonth)
};
this.dateRangeEnd = lastDayOfCurrentMonth.toString();
this.reportDate = String.format("%d-%02d", this.year, currentMonth);
} else {
// 非本年度,默认整年
this.dateRange = new String[]{this.year + "-01", this.year + "-12"};
this.dateRangeEnd = this.year + "-12-31";
this.reportDate = this.year + "-12";
}
} else if (StatementPeriodTypeEnum.MONTH.getValue().equals(this.periodType)) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
var date = java.time.YearMonth.parse(reportDate, formatter);
@ -161,8 +180,8 @@ public class StatementParamsDto extends PageQuery {
this.month = null;
if (this.quarter == 1) {
//报告年月
this.reportDate = this.year + "-03";
//报告年月
this.reportDate = this.year + "-03";
//季初日期
this.dateRangeStart = this.year + "-01-01";
//季末日期
@ -170,8 +189,8 @@ public class StatementParamsDto extends PageQuery {
//月份范围
this.dateRange = new String[]{this.year + "-01", this.year + "-03"};
} else if (this.quarter == 2) {
//报告年月
this.reportDate = this.year + "-06";
//报告年月
this.reportDate = this.year + "-06";
//季初日期
this.dateRangeStart = this.year + "-04-01";
//季末日期
@ -179,8 +198,8 @@ public class StatementParamsDto extends PageQuery {
//月份范围
this.dateRange = new String[]{this.year + "-04", this.year + "-06"};
} else if (this.quarter == 3) {
//报告年月
this.reportDate = this.year + "-09";
//报告年月
this.reportDate = this.year + "-09";
//季初日期
this.dateRangeStart = this.year + "-07-01";
//季末日期
@ -188,8 +207,8 @@ public class StatementParamsDto extends PageQuery {
//月份范围
this.dateRange = new String[]{this.year + "-07", this.year + "-09"};
} else if (this.quarter == 4) {
//报告年月
this.reportDate = this.year + "-12";
//报告年月
this.reportDate = this.year + "-12";
//季初日期
this.dateRangeStart = this.year + "-10-01";
//季末日期
@ -200,17 +219,17 @@ public class StatementParamsDto extends PageQuery {
this.year = Integer.parseInt(reportDate.substring(0, 4));
this.half = parseHalfYear(reportDate.substring(5, 7));
if (this.half == 1) {
//报告年月
this.reportDate = this.year + "-06";
//起始-终结日期
//报告年月
this.reportDate = this.year + "-06";
//起始-终结日期
this.dateRangeStart = this.year + "-01-01";
this.dateRangeEnd = this.year + "-06-30";
//月份范围
this.dateRange = new String[]{this.year + "-01", this.year + "-06"};
} else if (this.half == 2) {
//报告年月
this.reportDate = this.year + "-12";
//起始-终结日期
//报告年月
this.reportDate = this.year + "-12";
//起始-终结日期
this.dateRangeStart = this.year + "-07-01";
this.dateRangeEnd = this.year + "-12-31";
//月份范围
@ -248,13 +267,20 @@ public class StatementParamsDto extends PageQuery {
* 获取时间范围中的所有月份
*/
public List<String> getAllMonths() {
return getAllMonths(null);
}
public List<String> getAllMonths(String currentMonth) {
List<String> months = new ArrayList<>();
if (dateRange == null || dateRange.length != 2) {
throw new IllegalArgumentException("dateRange must contain exactly two elements: start and end.");
}
YearMonth start = YearMonth.parse(dateRange[0]);
YearMonth end = YearMonth.parse(dateRange[1]);
YearMonth end = currentMonth == null ? YearMonth.parse(dateRange[1])
: currentMonth.compareTo(dateRange[1]) > 0
? YearMonth.parse(dateRange[1])
: YearMonth.parse(currentMonth);
if (start.isAfter(end)) {
throw new IllegalArgumentException("Start date must be before or equal to end date.");
@ -269,6 +295,7 @@ public class StatementParamsDto extends PageQuery {
return months;
}
/**
* 判断是否是季报所在月份
*
@ -278,9 +305,10 @@ public class StatementParamsDto extends PageQuery {
this.parse();
return isQuarterReportMonth(this.dateRange[1]);
}
/**
* 判断是否季末
*
* @param yyyy_MM 2025-03 2025-06 2025-09 2025-12
* @return boolean
*/
@ -300,9 +328,10 @@ public class StatementParamsDto extends PageQuery {
this.parse();
return isYearReportMonth(this.dateRange[1]);
}
/**
* 判断是否12月
*
* @param yyyy_MM 2025-12
* @return boolean
*/

View File

@ -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,16 +14,23 @@
* limitations under the License.
*
*/
package com.jinbooks.persistence.mapper;
import com.jinbooks.entity.statement.StatementSubjectBalance;
import com.jinbooks.entity.statement.dto.StatementParamsDto;
import com.jinbooks.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface StatementSubjectBalanceMapper extends BaseMapperPlus<StatementSubjectBalanceMapper, StatementSubjectBalance, StatementSubjectBalance> {
List<StatementSubjectBalance> groupCodeSubjectBalance(@Param("dto") StatementParamsDto dto,
@Param("allMonths") List<String> allMonths,
@Param("minPeriod") String minPeriod,
@Param("maxPeriod") String maxPeriod);
}

View File

@ -1,27 +0,0 @@
/*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.jinbooks.persistence.mapper;
import com.jinbooks.entity.statement.StatementSubjectBalanceOpening;
import com.jinbooks.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface StatementSubjectBalanceOpeningMapper extends BaseMapperPlus<StatementSubjectBalanceOpeningMapper, StatementSubjectBalanceOpening, StatementSubjectBalanceOpening> {
}

View File

@ -60,7 +60,7 @@ public interface StatementBalanceSheetService {
void updateRuleBalance(StatementSubjectBalance subjectBalance, StatementRules statementRules);
void refreshItemsBalance(List<StatementBalanceSheetItem> items,
String bookId, String yearPeriod);
String bookId, String yearPeriod, int updateParams);
StatementBalanceSheetItemListVo insertSubtotals(List<StatementBalanceSheetItem> items);

View File

@ -267,7 +267,16 @@ public class BookInitBalanceServiceImpl extends ServiceImpl<BookInitBalanceMappe
balance.setClosingBalanceCredit(balance.getOpeningBalanceCredit()
.subtract(balance.getOpeningBalanceDebit()));
}
//上月期末余额
balance.setPrevBalance(balance.getBalance());
//上月期末借贷余额
balance.setPrevClosingBalanceDebit(balance.getPrevClosingBalanceDebit());
balance.setPrevClosingBalanceCredit(balance.getPrevClosingBalanceCredit());
//上月期末年度累计
balance.setPrevYearToDateDebit(balance.getYearToDateDebit());
balance.setPrevYearToDateCredit(balance.getYearToDateCredit());
updateBalances.add(balance);
}
statementSubjectBalanceMapper.insertOrUpdateBatch(updateBalances);

View File

@ -569,6 +569,7 @@ public class BookSubjectServiceImpl extends ServiceImpl<BookSubjectMapper, BookS
if (subject.getCode().length() == 4) {
subject.setIdPath("/"+subject.getId());
subject.setDisplayName(subject.getName());
subject.setPinyinCode(StrUtils.getPinYinShort(subject.getName()));
subject.setPinyinDisplayCode(subject.getPinyinCode());
}
}
@ -581,9 +582,11 @@ public class BookSubjectServiceImpl extends ServiceImpl<BookSubjectMapper, BookS
subject.setParentId(parentSubject.getId());
subject.setIdPath(parentSubject.getIdPath()+"/"+subject.getId());
subject.setDisplayName(parentSubject.getDisplayName() + "_" + subject.getName());
subject.setPinyinCode(StrUtils.getPinYinShort(subject.getName()));
subject.setPinyinDisplayCode(parentSubject.getPinyinDisplayCode() + "_" + subject.getPinyinCode());
} else {
subject.setDisplayName(subject.getName());
subject.setPinyinCode(StrUtils.getPinYinShort(subject.getName()));
subject.setPinyinDisplayCode(subject.getPinyinCode());
}
}
@ -597,9 +600,11 @@ public class BookSubjectServiceImpl extends ServiceImpl<BookSubjectMapper, BookS
subject.setParentId(parentSubject.getId());
subject.setIdPath(parentSubject.getIdPath()+"/"+subject.getId());
subject.setDisplayName(parentSubject.getDisplayName() + "_" + subject.getName());
subject.setPinyinCode(StrUtils.getPinYinShort(subject.getName()));
subject.setPinyinDisplayCode(parentSubject.getPinyinDisplayCode() + "_" + subject.getPinyinCode());
} else {
subject.setDisplayName(subject.getName());
subject.setPinyinCode(StrUtils.getPinYinShort(subject.getName()));
subject.setPinyinDisplayCode(subject.getPinyinCode());
}
}
@ -613,9 +618,11 @@ public class BookSubjectServiceImpl extends ServiceImpl<BookSubjectMapper, BookS
subject.setParentId(parentSubject.getId());
subject.setIdPath(parentSubject.getIdPath()+"/"+subject.getId());
subject.setDisplayName(parentSubject.getDisplayName() + "_" + subject.getName());
subject.setPinyinCode(StrUtils.getPinYinShort(subject.getName()));
subject.setPinyinDisplayCode(parentSubject.getPinyinDisplayCode() + "_" + subject.getPinyinCode());
} else {
subject.setDisplayName(subject.getName());
subject.setPinyinCode(StrUtils.getPinYinShort(subject.getName()));
subject.setPinyinDisplayCode(subject.getPinyinCode());
}
}

View File

@ -148,6 +148,7 @@ public class StandardSubjectServiceImpl extends ServiceImpl<StandardSubjectMappe
for(StandardSubject subject : subjectList) {
if(subject.getCode().length() == 4) {
subject.setDisplayName(subject.getName());
subject.setPinyinCode(StrUtils.getPinYinShort(subject.getName()));
subject.setPinyinDisplayCode(subject.getPinyinCode());
}
}
@ -159,9 +160,11 @@ public class StandardSubjectServiceImpl extends ServiceImpl<StandardSubjectMappe
if(parentSubject != null) {
subject.setParentId(parentSubject.getId());
subject.setDisplayName(parentSubject.getDisplayName()+"_"+subject.getName());
subject.setPinyinCode(StrUtils.getPinYinShort(subject.getName()));
subject.setPinyinDisplayCode(parentSubject.getPinyinDisplayCode()+"_"+ subject.getPinyinCode());
}else {
subject.setDisplayName(subject.getName());
subject.setPinyinCode(StrUtils.getPinYinShort(subject.getName()));
subject.setPinyinDisplayCode(subject.getPinyinCode());
}
}
@ -174,9 +177,11 @@ public class StandardSubjectServiceImpl extends ServiceImpl<StandardSubjectMappe
if(parentSubject != null) {
subject.setParentId(parentSubject.getId());
subject.setDisplayName(parentSubject.getDisplayName()+"_"+subject.getName());
subject.setPinyinCode(StrUtils.getPinYinShort(subject.getName()));
subject.setPinyinDisplayCode(parentSubject.getPinyinDisplayCode()+"_"+ subject.getPinyinCode());
}else {
subject.setDisplayName(subject.getName());
subject.setPinyinCode(StrUtils.getPinYinShort(subject.getName()));
subject.setPinyinDisplayCode(subject.getPinyinCode());
}
}
@ -189,9 +194,11 @@ public class StandardSubjectServiceImpl extends ServiceImpl<StandardSubjectMappe
if(parentSubject != null) {
subject.setParentId(parentSubject.getId());
subject.setDisplayName(parentSubject.getDisplayName()+"_"+subject.getName());
subject.setPinyinCode(StrUtils.getPinYinShort(subject.getName()));
subject.setPinyinDisplayCode(parentSubject.getPinyinDisplayCode()+"_"+ subject.getPinyinCode());
}else {
subject.setDisplayName(subject.getName());
subject.setPinyinCode(StrUtils.getPinYinShort(subject.getName()));
subject.setPinyinDisplayCode(subject.getPinyinCode());
}
}

View File

@ -105,7 +105,7 @@ public class StatementBalanceSheetConfigServiceImpl implements StatementBalanceS
lqw.eq(StatementBalanceSheetItem::getBookId, bookId);
lqw.eq(StatementBalanceSheetItem::getBalanceSheetId, ConstsSysConfig.SYS_CONFIG_TEMPLATE_ID);
List<StatementBalanceSheetItem> balanceSheets = statementBalanceSheetItemMapper.selectList(lqw);
statementBalanceSheetService.refreshItemsBalance(balanceSheets, bookId, configSysService.getCurrentTerm(bookId));
statementBalanceSheetService.refreshItemsBalance(balanceSheets, bookId, configSysService.getCurrentTerm(bookId), 3);
StatementBalanceSheetItemListVo itemListVo = statementBalanceSheetService.insertSubtotals(balanceSheets);
itemListVo.getAssets().sort(Comparator.comparing(StatementBalanceSheetItem::getItemCode));
itemListVo.getLiability().sort(Comparator.comparing(StatementBalanceSheetItem::getItemCode));

View File

@ -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.persistence.service.impl;
@ -91,7 +91,7 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
StatementBalanceSheet balanceSheet = balanceSheetMapper.selectOne(lqw);
String currentTerm = configSysService.getCurrentTerm(dto.getBookId());
List<String> allMonths = dto.getAllMonths();
List<String> allMonths = dto.getAllMonths(currentTerm);
List<StatementBalanceSheetItem> items;
// 查询范围包含了当前期,或者没数据,则实时统计
boolean isNull = balanceSheet == null;
@ -126,12 +126,15 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
//balanceSheetMapper.insert(balanceSheet);
}
// 遍历月份,统计总金额
for (String month : allMonths) {
refreshItemsBalance(items, dto.getBookId(), month);
// 统计总金额,因为是期末和年初,则只需要统计第一个月和最后一个月的数
if (allMonths.size() == 1) {
refreshItemsBalance(items, dto.getBookId(), allMonths.get(0), 3);
} else {
refreshItemsBalance(items, dto.getBookId(), allMonths.get(0), 1);
refreshItemsBalance(items, dto.getBookId(), allMonths.get(allMonths.size() - 1), 2);
}
}
}else {// 拉取历史数据
} else {// 拉取历史数据
// 查询条目
LambdaQueryWrapper<StatementBalanceSheetItem> itemLqw = Wrappers.lambdaQuery();
itemLqw.eq(StatementBalanceSheetItem::getBookId, dto.getBookId());
@ -363,17 +366,18 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
return true;
}
/**
* 刷新信息项对应的余额数据
*
* @param items 信息项组
* @param bookId 所属账簿
* @param yearPeriod 账期
* @param items 信息项组
* @param bookId 所属账簿
* @param yearPeriod 账期
* @param updateParams 需要更新的金额项1年初2期末3同时
*/
@Override
public void refreshItemsBalance(List<StatementBalanceSheetItem> items,
String bookId, String yearPeriod) {
String bookId, String yearPeriod, int updateParams) {
// 方便更新参数
Map<String, StatementBalanceSheetItem> mapSheet = items.stream()
.collect(Collectors.toMap(StatementBalanceSheetItem::getItemCode, item -> item));
@ -383,7 +387,9 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
lqwRule.in(StatementRules::getItemCode, itemCodes);
lqwRule.eq(StatementRules::getBookId, bookId);
lqwRule.eq(StatementRules::getType, StatementTypeEnum.balance_sheet.name());
// 相关的所有规则
List<StatementRules> rules = rulesMapper.selectList(lqwRule);
// 所有规则下的绑定科目编号
List<String> subjectCodes = rules.stream().map(StatementRules::getSubjectCode).toList();
if (CollectionUtils.isNotEmpty(subjectCodes)) {
// 查询科目余额
@ -400,11 +406,19 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
updateRuleBalance(subjectBalance, statementRules);
StatementBalanceSheetItem balanceSheet = mapSheet.get(statementRules.getItemCode());
if (StatementSymbolEnum.PLUS.getValue().equals(statementRules.getSymbol())) {
balanceSheet.setInitialBalance(balanceSheet.getInitialBalance().add(statementRules.getOpeningYearBalance()));
balanceSheet.setCurrentBalance(balanceSheet.getCurrentBalance().add(statementRules.getClosingBalance()));
if (updateParams == 1 || updateParams == 3) {
balanceSheet.setInitialBalance(balanceSheet.getInitialBalance().add(statementRules.getOpeningYearBalance()));
}
if (updateParams == 2 || updateParams == 3) {
balanceSheet.setCurrentBalance(balanceSheet.getCurrentBalance().add(statementRules.getClosingBalance()));
}
} else {
balanceSheet.setInitialBalance(balanceSheet.getInitialBalance().subtract(statementRules.getOpeningYearBalance()));
balanceSheet.setCurrentBalance(balanceSheet.getCurrentBalance().subtract(statementRules.getClosingBalance()));
if (updateParams == 1 || updateParams == 3) {
balanceSheet.setInitialBalance(balanceSheet.getInitialBalance().subtract(statementRules.getOpeningYearBalance()));
}
if (updateParams == 2 || updateParams == 3) {
balanceSheet.setCurrentBalance(balanceSheet.getCurrentBalance().subtract(statementRules.getClosingBalance()));
}
}
}
}
@ -545,7 +559,7 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
initialSum = initialSum.add(
child.getInitialBalance() != null ? child.getInitialBalance() : BigDecimal.ZERO
);
} else if (StatementSymbolEnum.MINUS.getValue().equals(child.getSymbol())){
} else if (StatementSymbolEnum.MINUS.getValue().equals(child.getSymbol())) {
currentSum = currentSum.subtract(
child.getCurrentBalance() != null ? child.getCurrentBalance() : BigDecimal.ZERO
);
@ -562,14 +576,21 @@ public class StatementBalanceSheetServiceImpl implements StatementBalanceSheetSe
@Override
public void updateRuleBalance(StatementSubjectBalance subjectBalance, StatementRules statementRules) {
if (subjectBalance != null) {
statementRules.setOpeningYearBalance(subjectBalance.getOpeningYearBalanceDebit()
.subtract(subjectBalance.getOpeningYearBalanceCredit()));
statementRules.setClosingBalance(subjectBalance.getBalance());
} else {
if (statementRules != null && statementRules.getOpeningYearBalance() == null) {
statementRules.setOpeningYearBalance(BigDecimal.ZERO);
}
if (statementRules != null && statementRules.getClosingBalance() == null) {
statementRules.setClosingBalance(BigDecimal.ZERO);
}
if (subjectBalance != null && statementRules != null) {
statementRules.setOpeningYearBalance(
statementRules.getOpeningYearBalance().add(
subjectBalance.getOpeningYearBalanceDebit()
.subtract(subjectBalance.getOpeningYearBalanceCredit()))
);
statementRules.setClosingBalance(statementRules.getClosingBalance().add(subjectBalance.getBalance()));
}
}
}

View File

@ -360,52 +360,59 @@ public class StatementReportServiceImpl implements StatementReportService {
@Override
public Message<List<StatementSubjectBalance>> subjectBalance(StatementParamsDto dto) {
dto.parse();
List<String> allMonths = dto.getAllMonths();
LambdaQueryWrapper<StatementSubjectBalance> lqw = Wrappers.lambdaQuery();
lqw.in(StatementSubjectBalance::getYearPeriod, allMonths);
lqw.eq(StatementSubjectBalance::getBookId, dto.getBookId());
lqw.eq(!dto.getShowAll(), StatementSubjectBalance::getIsVoucher, YesNoEnum.y.name());
List<StatementSubjectBalance> res = subjectBalanceMapper.selectList(lqw);
String currentTerm = configSysService.selectConfigByKey(dto.getBookId(), ConstsSysConfig.SYS_PAYMENT_TERM_CURRENT);
List<String> allMonths = dto.getAllMonths(currentTerm);
// 拉取父级数据
List<String> subjectIds = new ArrayList<>(res.stream().map(StatementSubjectBalance::getSourceId).toList());
List<String> parentIds = res.stream().filter(item -> item.getIsAuxiliary().equals(YesNoEnum.y.name()))
.map(StatementSubjectBalance::getParentId).toList();
subjectIds.addAll(parentIds);
if (!subjectIds.isEmpty()) {
LambdaQueryWrapper<BookSubject> lqwSubject = Wrappers.lambdaQuery();
lqwSubject.eq(BookSubject::getBookId, dto.getBookId());
List<BookSubject> bookSubjects = bookSubjectMapper.selectList(lqwSubject);
// 找出所有父级
List<String> subjectPaths = new ArrayList<>();
bookSubjects.forEach(bookSubject -> {
for (String subjectId : subjectIds) {
if (bookSubject.getIdPath().contains(subjectId)) {
subjectPaths.addAll(List.of(bookSubject.getIdPath().split("/")));
}
}
});
// 创建父级
List<StatementSubjectBalance> balanceList = bookSubjects.stream()
.filter(bookSubject -> subjectPaths.contains(bookSubject.getId()))
.map(subject -> subjectBalanceService.create(subject, dto.getReportDate()))
.toList();
// 合并
Set<String> existingSourceIds = res.stream().map(StatementSubjectBalance::getSourceId).collect(Collectors.toSet());
for (StatementSubjectBalance item : balanceList) {
if (!existingSourceIds.contains(item.getSourceId())) {
res.add(item);
}
}
List<StatementSubjectBalance> res = null;
if (allMonths.size() > 1) {
res = subjectBalanceMapper.groupCodeSubjectBalance(dto, allMonths,allMonths.get(0), allMonths.get(allMonths.size() - 1));
} else {
LambdaQueryWrapper<StatementSubjectBalance> lqw = Wrappers.lambdaQuery();
lqw.in(StatementSubjectBalance::getYearPeriod, allMonths);
lqw.eq(StatementSubjectBalance::getBookId, dto.getBookId());
lqw.eq(!dto.getShowAll(), StatementSubjectBalance::getIsVoucher, YesNoEnum.y.name());
res = subjectBalanceMapper.selectList(lqw);
}
// // 拉取父级数据
// List<String> subjectIds = new ArrayList<>(res.stream().map(StatementSubjectBalance::getSourceId).toList());
// List<String> parentIds = res.stream().filter(item -> item.getIsAuxiliary().equals(YesNoEnum.y.name()))
// .map(StatementSubjectBalance::getParentId).toList();
// subjectIds.addAll(parentIds);
// if (!subjectIds.isEmpty()) {
// LambdaQueryWrapper<BookSubject> lqwSubject = Wrappers.lambdaQuery();
// lqwSubject.eq(BookSubject::getBookId, dto.getBookId());
// List<BookSubject> bookSubjects = bookSubjectMapper.selectList(lqwSubject);
// // 找出所有父级
// Set<String> subjectPaths = new HashSet<>();
// bookSubjects.forEach(bookSubject -> {
// for (String subjectId : subjectIds) {
// if (bookSubject.getIdPath().contains(subjectId)) {
// subjectPaths.addAll(List.of(bookSubject.getIdPath().split("/")));
// }
// }
// });
// // 创建父级
// List<StatementSubjectBalance> balanceList = bookSubjects.stream()
// .filter(bookSubject -> subjectPaths.contains(bookSubject.getId()))
// .map(subject -> subjectBalanceService.create(subject, dto.getReportDate()))
// .toList();
// // 合并
// Set<String> existingSourceIds = res.stream().map(StatementSubjectBalance::getSourceId).collect(Collectors.toSet());
// for (StatementSubjectBalance item : balanceList) {
// if (!existingSourceIds.contains(item.getSourceId())) {
// res.add(item);
// }
// }
// }
// counterBalance(res);
// 按照科目编号升序排列
res.sort(Comparator.comparing(StatementSubjectBalance::getSubjectCode));
if (!dto.getShowAux()) {
res = res.stream().filter(item -> item.getIsAuxiliary().equals(YesNoEnum.n.name())).toList();
}
// if (!dto.getShowAux()) {
// res = res.stream().filter(item -> item.getIsAuxiliary().equals(YesNoEnum.n.name())).toList();
// }
return new Message<>(res);
}

View File

@ -31,7 +31,6 @@ import com.jinbooks.entity.base.AssistAcc;
import com.jinbooks.entity.book.BookSubject;
import com.jinbooks.entity.book.Settlement;
import com.jinbooks.entity.statement.StatementSubjectBalance;
import com.jinbooks.entity.statement.StatementSubjectBalanceOpening;
import com.jinbooks.entity.voucher.VoucherAuxiliary;
import com.jinbooks.entity.voucher.VoucherItem;
import com.jinbooks.enums.StatementPeriodTypeEnum;
@ -41,12 +40,10 @@ import com.jinbooks.enums.YesNoEnum;
import com.jinbooks.persistence.mapper.AssistAccMapper;
import com.jinbooks.persistence.mapper.BookSubjectMapper;
import com.jinbooks.persistence.mapper.StatementSubjectBalanceMapper;
import com.jinbooks.persistence.mapper.StatementSubjectBalanceOpeningMapper;
import com.jinbooks.persistence.mapper.VoucherItemMapper;
import com.jinbooks.persistence.service.ConfigSysService;
import com.jinbooks.persistence.service.StatementSubjectBalanceService;
import cn.hutool.core.bean.BeanUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -70,7 +67,6 @@ public class StatementSubjectBalanceServiceImpl implements StatementSubjectBalan
private final AssistAccMapper assistAccMapper;
private final IdentifierGenerator identifierGenerator;
private final VoucherItemMapper voucherItemMapper;
private final StatementSubjectBalanceOpeningMapper statementSubjectBalanceOpeningMapper;
@Override
public StatementSubjectBalance getSubjectBalance(String bookId, String subjectCode) {
@ -454,19 +450,21 @@ public class StatementSubjectBalanceServiceImpl implements StatementSubjectBalan
statementSubjectBalance.setYearToDateDebit(BigDecimal.ZERO);
statementSubjectBalance.setYearToDateCredit(BigDecimal.ZERO);
}
//上月期末余额
statementSubjectBalance.setPrevBalance(statementSubjectBalance.getBalance());
//上月期末借贷余额
statementSubjectBalance.setPrevClosingBalanceDebit(statementSubjectBalance.getPrevClosingBalanceDebit());
statementSubjectBalance.setPrevClosingBalanceCredit(statementSubjectBalance.getPrevClosingBalanceCredit());
//上月期末年度累计
statementSubjectBalance.setPrevYearToDateDebit(statementSubjectBalance.getYearToDateDebit());
statementSubjectBalance.setPrevYearToDateCredit(statementSubjectBalance.getYearToDateCredit());
//状态
statementSubjectBalance.setIsVoucher(YesNoEnum.n.name());
String currentId = identifierGenerator.nextId(statementSubjectBalance).toString();
statementSubjectBalance.setId(currentId);
}
subjectBalanceMapper.insertBatch(subjectBalanceList);
List<StatementSubjectBalanceOpening> subjectBalanceOpeningList = new ArrayList<>();
for( StatementSubjectBalance statementSubjectBalance: subjectBalanceList) {
StatementSubjectBalanceOpening statementSubjectBalanceOpening = new StatementSubjectBalanceOpening();
BeanUtil.copyProperties(statementSubjectBalance, statementSubjectBalanceOpening);
subjectBalanceOpeningList.add(statementSubjectBalanceOpening);
}
statementSubjectBalanceOpeningMapper.insertBatch(subjectBalanceOpeningList);
return true;
}

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jinbooks.persistence.mapper.StatementSubjectBalanceMapper">
<select id="groupCodeSubjectBalance" resultType="com.jinbooks.entity.statement.StatementSubjectBalance">
SELECT
sb.subject_code,
sb.subject_name,
sb.source_id,
sb.parent_id,
sb.is_auxiliary,
-- 年初余额只取1月
SUM(CASE WHEN sb.year_period = #{minPeriod} THEN sb.opening_balance_debit ELSE 0 END) AS
opening_balance_debit,
SUM(CASE WHEN sb.year_period = #{minPeriod} THEN sb.opening_balance_credit ELSE 0 END) AS
opening_balance_credit,
-- 本期发生额
SUM(CASE WHEN sb.year_period = #{maxPeriod} THEN sb.current_period_debit ELSE 0 END) AS current_period_debit,
SUM(CASE WHEN sb.year_period = #{maxPeriod} THEN sb.current_period_credit ELSE 0 END) AS current_period_credit,
-- 本年累计发生额取最后一个月的累计值需外部传入最终月份如2025-08
SUM(CASE WHEN sb.year_period = #{maxPeriod} THEN sb.year_to_date_debit ELSE 0 END) AS year_to_date_debit,
SUM(CASE WHEN sb.year_period = #{maxPeriod} THEN sb.year_to_date_credit ELSE 0 END) AS year_to_date_credit,
-- 期末余额(取最后一个月)
SUM(CASE WHEN sb.year_period = #{maxPeriod} THEN sb.closing_balance_debit ELSE 0 END) AS
closing_balance_debit,
SUM(CASE WHEN sb.year_period = #{maxPeriod} THEN sb.closing_balance_credit ELSE 0 END) AS
closing_balance_credit
FROM jbx_statement_subject_balance sb
WHERE sb.deleted = 'n'
AND sb.book_id = #{dto.bookId}
<if test="dto.showAll == false">
AND sb.is_voucher = 'y'
</if>
<if test="allMonths != null and allMonths.size() > 0">
AND sb.year_period IN
<foreach collection="allMonths" item="month" open="(" separator="," close=")">
#{month}
</foreach>
</if>
GROUP BY
sb.subject_code,
sb.subject_name,
sb.source_id,
sb.parent_id,
sb.is_auxiliary
ORDER BY sb.subject_code ASC
</select>
</mapper>

View File

@ -40,9 +40,9 @@ spring.datasource.type =com.alibaba.druid.pool.DruidDat
#spring.datasource.url=jdbc:highgo://192.168.56.107:5866/highgo?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
#mysql
spring.datasource.driver-class-name =com.mysql.cj.jdbc.Driver
spring.datasource.url =jdbc:mysql://${DATABASE_HOST:localhost}:${DATABASE_PORT:3306}/${DATABASE_NAME:jinbooks}?allowPublicKeyRetrieval=true&autoReconnect=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username =${DATABASE_USER:root}
spring.datasource.password =${DATABASE_PWD:jinbooks}
spring.datasource.url =jdbc:mysql://${DATABASE_HOST:192.168.31.233}:${DATABASE_PORT:3306}/${DATABASE_NAME:jinbooks}?allowPublicKeyRetrieval=true&autoReconnect=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username =${DATABASE_USER:jinbooks}
spring.datasource.password =${DATABASE_PWD:Jinbooks321!}
#mybatis
mybatis-plus.dialect =mysql

View File

@ -1,16 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO" monitorInterval="300">
<Configuration status="WARN" monitorInterval="300">
<Appenders>
<Console name="consolePrint" target="SYSTEM_OUT">
<PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss.SSS} %highlight{%level} [%t] %logger{36}:%L - %msg%n"/>
<!-- 控制台输出 -->
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout
pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{%-5level} [%t] %style{%logger{36}}{cyan}:%L - %msg%n"
disableAnsi="false" noConsoleNoAnsi="false"/>
</Console>
<!-- 输出到文件按天或者超过128MB分割 -->
<RollingFile name="RollingFile" fileName="logs/jinbooks.log"
<!-- 滚动日志输出:每天生成 + 超过128MB滚动最多保留15个文件 -->
<RollingFile name="RollingFileAppender"
fileName="logs/jinbooks.log"
filePattern="logs/$${date:yyyyMMdd}/jinbooks-%d{yyyy-MM-dd}-%i.log.gz">
<!-- 需要记录的级别 -->
<!-- <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> -->
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5level [%t] (%logger{36}:%L) - %msg%n"/>
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%t] (%logger{36}:%L) - %msg%n"/>
<Policies>
<OnStartupTriggeringPolicy/>
<TimeBasedTriggeringPolicy/>
@ -21,40 +24,50 @@
</Appenders>
<Loggers>
<!-- 设置 MyBatis 和 MyBatis-Plus 的日志级别 -->
<!-- MyBatis 相关调试日志 -->
<Logger name="com.baomidou.mybatisplus" level="DEBUG" additivity="false">
<AppenderRef ref="consolePrint"/>
<AppenderRef ref="RollingFile"/>
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="RollingFileAppender"/>
</Logger>
<Logger name="org.apache.ibatis" level="DEBUG" additivity="false">
<AppenderRef ref="consolePrint"/>
<AppenderRef ref="RollingFile"/>
</Logger>
<!-- 更详细的 SQL 执行日志 -->
<Logger name="org.apache.ibatis.executor.statement" level="TRACE" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="RollingFileAppender"/>
</Logger>
<Logger name="org.apache.ibatis.transaction.jdbc" level="TRACE" additivity="false">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
<!-- SQL 执行器详细日志 -->
<Logger name="org.apache.ibatis.executor.statement" level="INFO" additivity="false">
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="RollingFileAppender"/>
</Logger>
<Logger name="org.apache.ibatis.transaction.jdbc" level="INFO" additivity="false">
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="RollingFileAppender"/>
</Logger>
<Logger level="TRACE" name="com.jinbooks.persistence.mapper" ></Logger>
<Logger level="OFF" name="org.hibernate.validator.internal.util.Version"></Logger>
<!-- 项目 DAO 层日志 -->
<Logger name="com.jinbooks.persistence.mapper" level="TRACE" additivity="false">
<AppenderRef ref="RollingFileAppender"/>
</Logger>
<Logger level="INFO" name="org.apache.logging"></Logger>
<Logger level="INFO" name="org.springframework"></Logger>
<Logger level="DEBUG" name="com.jinbooks"></Logger>
<Logger level="ERROR" name="com.alibaba.nacos"></Logger>
<Logger level="ERROR" name="org.reflections.Reflections"></Logger>
<Logger level="ERROR" name="RocketmqRemoting"></Logger>
<Logger level="OFF" name="org.quartz"></Logger>
<!-- 关闭不需要的日志输出 -->
<Logger name="org.hibernate.validator.internal.util.Version" level="OFF"/>
<Logger name="org.quartz" level="OFF"/>
<!-- 常见框架日志配置 -->
<Logger name="org.springframework" level="INFO"/>
<Logger name="org.apache.logging" level="INFO"/>
<Logger name="com.alibaba.nacos" level="ERROR"/>
<Logger name="org.reflections.Reflections" level="ERROR"/>
<Logger name="RocketmqRemoting" level="ERROR"/>
<!-- 项目主包日志 -->
<Logger name="com.jinbooks" level="DEBUG"/>
<!-- 根日志配置 -->
<Root level="INFO">
<AppenderRef ref="consolePrint"/>
<AppenderRef ref="RollingFile"/>
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="RollingFileAppender"/>
</Root>
</Loggers>
</Configuration>

View File

@ -1,19 +1,37 @@
ALTER TABLE `jinbooks`.`jbx_employee_salary_temp`
ALTER TABLE `jinbooks`.`jbx_employee_salary_temp`
ADD COLUMN `pay_amount` DECIMAL(10,5) NULL DEFAULT '0.00000' COMMENT '应发工资=工资+应增-应扣' AFTER `personal_tax`;
ALTER TABLE `jinbooks`.`jbx_employee_salary`
ALTER TABLE `jinbooks`.`jbx_employee_salary`
ADD COLUMN `pay_amount` DECIMAL(10,5) NULL DEFAULT '0.00000' COMMENT '应发工资=工资+应增-应扣' AFTER `personal_tax`;
ALTER TABLE `jinbooks`.`jbx_employee_salary_summary`
ALTER TABLE `jinbooks`.`jbx_employee_salary_summary`
ADD COLUMN `pay_amount` DECIMAL(10,5) NULL DEFAULT '0.00000' COMMENT '应发工资=工资+应增-应扣' AFTER `personal_tax`;
ALTER TABLE `jinbooks`.`jbx_employee_salary_summary`
ALTER TABLE `jinbooks`.`jbx_employee_salary_summary`
DROP COLUMN `salary_voucher_id`,
DROP COLUMN `accrual_voucher_id`;
DROP TABLE `jinbooks`.`jbx_employee_salary_voucher_rule_template`, `jinbooks`.`jbx_employee_salary_voucher_rule`;
ALTER TABLE `jinbooks`.`jbx_voucher_template`
ALTER TABLE `jinbooks`.`jbx_voucher_template`
ADD COLUMN `voucher_date` SMALLINT NULL DEFAULT 0 COMMENT '默认凭证日期为月份的第几天0为月末' AFTER `voucher_type`;
-- 上月数据
ALTER TABLE `jinbooks`.`jbx_statement_subject_balance`
ADD COLUMN `prev_balance` DECIMAL(18,2) NOT NULL DEFAULT '0.00' COMMENT '上月末余额' AFTER `closing_balance_credit`,
ADD COLUMN `prev_closing_balance_debit` DECIMAL(18,2) NOT NULL DEFAULT '0.00' COMMENT '上月期末余额(借方)' AFTER `prev_balance`,
ADD COLUMN `prev_closing_balance_credit` DECIMAL(18,2) NOT NULL DEFAULT '0.00' COMMENT '上月期末余额(贷方)' AFTER `prev_closing_balance_debit`,
ADD COLUMN `prev_year_to_date_debit` DECIMAL(18,2) NOT NULL DEFAULT '0.00' COMMENT '上月本年累计发生额(借方)' AFTER `prev_closing_balance_credit`,
ADD COLUMN `prev_year_to_date_credit` DECIMAL(18,2) NOT NULL DEFAULT '0.00' COMMENT '上月本年累计发生额(贷方)' AFTER `prev_year_to_date_debit`;
ALTER TABLE `jinbooks`.`jbx_employee_salary`
ADD COLUMN `accrual_voucher_id` varchar(45) DEFAULT NULL COMMENT '收票凭证编码',
ADD COLUMN `salary_voucher_id` varchar(45) DEFAULT NULL COMMENT '发放凭证编码';
ALTER TABLE `jinbooks`.`jbx_voucher_item`
MODIFY COLUMN `subject_balance` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '科目余额';