入库、出库 费用登记费用科目列表查询修改
This commit is contained in:
+98
-1
@@ -337,6 +337,99 @@ public class ContractManageApplicationService {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 单据类型「仓库进出仓单」编码(与 BMS / WMS 推送一致) */
|
||||||
|
public static final String DOCUMENT_TYPE_CODE_WAREHOUSE_IN_OUT_ORDER = "WMS_ckjccd";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按结算主体取仓储合同结算设置中,单据类型包含指定类型的费用科目编码(按明细行顺序,可重复,调用方去重)。
|
||||||
|
* 科目编码优先取二级 {@code second_subject_code},为空则取一级 {@code first_subject_code}。
|
||||||
|
* settlementCustomersCode 为空时与同模块合同逻辑一致:使用通用仓储合同(commonContractFlag=1)。
|
||||||
|
*/
|
||||||
|
public List<String> listSecondSubjectCodesBySettlementAndDocumentType(String settlementCustomersCode,
|
||||||
|
Long organizationId,
|
||||||
|
Long topOrganizationId,
|
||||||
|
String documentTypeCode) {
|
||||||
|
if (StringUtils.isEmpty(documentTypeCode)) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
ContractManagePO contractManagePO = getInfoByCustomerAndOrganizationId(settlementCustomersCode, 1, topOrganizationId, organizationId);
|
||||||
|
if (contractManagePO == null || contractManagePO.getContractManageId() == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
List<ContractManageDetailPO> detailPOS = contractManageDetailDomainService.queryListByManageId(contractManagePO.getContractManageId());
|
||||||
|
if (detailPOS == null || detailPOS.isEmpty()) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
List<String> codes = new ArrayList<>();
|
||||||
|
for (ContractManageDetailPO detail : detailPOS) {
|
||||||
|
if (detail == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String subjectCode = resolveContractDetailExpenseSubjectCode(detail);
|
||||||
|
if (StringUtils.isEmpty(subjectCode)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!matchesContractDetailWarehouseInOut(detail, documentTypeCode)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
codes.add(subjectCode);
|
||||||
|
}
|
||||||
|
return codes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 合同结算行的费用科目编码:有二级科目用二级,否则用一级。
|
||||||
|
*/
|
||||||
|
private static String resolveContractDetailExpenseSubjectCode(ContractManageDetailPO detail) {
|
||||||
|
if (detail == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!StringUtils.isEmpty(detail.getSecondSubjectCode())) {
|
||||||
|
return detail.getSecondSubjectCode().trim();
|
||||||
|
}
|
||||||
|
if (!StringUtils.isEmpty(detail.getFirstSubjectCode())) {
|
||||||
|
return detail.getFirstSubjectCode().trim();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否属于「仓库进出仓单」类结算行:优先按单据类型编码精确匹配(含逗号分隔多编码),
|
||||||
|
* 避免因 BMS 主数据编码与 WMS 计费推送编码(如 WMS_ckjccd)不一致导致筛掉全部行;
|
||||||
|
* 兼容按单据类型名称包含「仓库进出仓」判定(合同保存时会拼接中文名称)。
|
||||||
|
*/
|
||||||
|
private static boolean matchesContractDetailWarehouseInOut(ContractManageDetailPO detail, String documentTypeCode) {
|
||||||
|
if (detail == null || StringUtils.isEmpty(documentTypeCode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (contractDetailContainsDocumentType(detail.getDocumentTypeCode(), documentTypeCode)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String typeNames = detail.getDocumentType();
|
||||||
|
if (StringUtils.isEmpty(typeNames)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Stream.of(typeNames.split(","))
|
||||||
|
.map(String::trim)
|
||||||
|
.filter(s -> !StringUtils.isEmpty(s))
|
||||||
|
.anyMatch(n -> n.contains("仓库进出仓"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean contractDetailContainsDocumentType(String detailDocumentTypeCodes, String documentTypeCode) {
|
||||||
|
if (StringUtils.isEmpty(detailDocumentTypeCodes)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return Stream.of(detailDocumentTypeCodes.split(","))
|
||||||
|
.map(String::trim)
|
||||||
|
.filter(s -> !StringUtils.isEmpty(s))
|
||||||
|
.anyMatch(code -> code.equalsIgnoreCase(documentTypeCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按单据类型取合同结算行上的计费单价(计费策略展开的 isFee 项)。
|
||||||
|
* <p>多条结算明细共用同一计费策略(accounting_strategy_id 相同)时,只展开一次策略参数,
|
||||||
|
* 避免前端出现重复的单价列。</p>
|
||||||
|
*/
|
||||||
public List<SubjectAndPriceReturn> getPrice(String documentTypeCode, String settlementCustomersCode,Long organizationId,Long topOrganizationId) {
|
public List<SubjectAndPriceReturn> getPrice(String documentTypeCode, String settlementCustomersCode,Long organizationId,Long topOrganizationId) {
|
||||||
List<SubjectAndPriceReturn> result = new ArrayList<>();
|
List<SubjectAndPriceReturn> result = new ArrayList<>();
|
||||||
ContractManagePO contractManagePO = getInfoByCustomerAndOrganizationId(settlementCustomersCode, 1, topOrganizationId, organizationId);
|
ContractManagePO contractManagePO = getInfoByCustomerAndOrganizationId(settlementCustomersCode, 1, topOrganizationId, organizationId);
|
||||||
@@ -346,11 +439,15 @@ public class ContractManageApplicationService {
|
|||||||
List<ContractManageDetailPO> contractManageDetailPOList = contractManagePO.getContractManageDetailPOList();
|
List<ContractManageDetailPO> contractManageDetailPOList = contractManagePO.getContractManageDetailPOList();
|
||||||
if (contractManageDetailPOList != null && contractManageDetailPOList.size() > 0) {
|
if (contractManageDetailPOList != null && contractManageDetailPOList.size() > 0) {
|
||||||
List<ContractManageDetailPO> contractManageDetailPOs = contractManageDetailPOList.stream()
|
List<ContractManageDetailPO> contractManageDetailPOs = contractManageDetailPOList.stream()
|
||||||
.filter(item -> item.getDocumentTypeCode().equals(documentTypeCode))
|
.filter(item -> contractDetailContainsDocumentType(item.getDocumentTypeCode(), documentTypeCode))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
if (contractManageDetailPOs != null && contractManageDetailPOs.size() > 0) {
|
if (contractManageDetailPOs != null && contractManageDetailPOs.size() > 0) {
|
||||||
|
Set<Long> expandedAccountingStrategyIds = new HashSet<>();
|
||||||
for (ContractManageDetailPO contractManageDetailPO : contractManageDetailPOs) {
|
for (ContractManageDetailPO contractManageDetailPO : contractManageDetailPOs) {
|
||||||
Long accountingStrategyId = contractManageDetailPO.getAccountingStrategyId();
|
Long accountingStrategyId = contractManageDetailPO.getAccountingStrategyId();
|
||||||
|
if (accountingStrategyId == null || !expandedAccountingStrategyIds.add(accountingStrategyId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
List<BillingParamsPO> billingParams = contractManageDetailMapper.getBillingParams(accountingStrategyId);
|
List<BillingParamsPO> billingParams = contractManageDetailMapper.getBillingParams(accountingStrategyId);
|
||||||
if (billingParams != null && billingParams.size() > 0) {
|
if (billingParams != null && billingParams.size() > 0) {
|
||||||
//if (billingParams != null && billingParams.size() > 0) {
|
//if (billingParams != null && billingParams.size() > 0) {
|
||||||
|
|||||||
+36
@@ -9,6 +9,7 @@ import com.mhd.basic.domain.expenseAccount.repository.po.QueryExpenseAccountPO;
|
|||||||
import com.mhd.basic.domain.expenseAccount.repository.todo.ExpenseAccountDO;
|
import com.mhd.basic.domain.expenseAccount.repository.todo.ExpenseAccountDO;
|
||||||
import com.mhd.basic.domain.expenseAccount.repository.todo.ExpenseAccountDoMap;
|
import com.mhd.basic.domain.expenseAccount.repository.todo.ExpenseAccountDoMap;
|
||||||
import com.mhd.basic.domain.expenseAccount.repository.todo.SearchExpenseAccountDO;
|
import com.mhd.basic.domain.expenseAccount.repository.todo.SearchExpenseAccountDO;
|
||||||
|
import com.mhd.basic.application.service.contractManage.ContractManageApplicationService;
|
||||||
import com.mhd.basic.domain.expenseAccount.service.ExpenseAccountDomainService;
|
import com.mhd.basic.domain.expenseAccount.service.ExpenseAccountDomainService;
|
||||||
import com.mhd.basic.infrastructure.feign.vo.SysDictDataVo;
|
import com.mhd.basic.infrastructure.feign.vo.SysDictDataVo;
|
||||||
import com.mhd.basic.interfaces.dto.expenseAccount.ExpenseAccountDTO;
|
import com.mhd.basic.interfaces.dto.expenseAccount.ExpenseAccountDTO;
|
||||||
@@ -27,6 +28,7 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -45,8 +47,42 @@ public class ExpenseAccountApplicationService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ExpenseAccountDomainService expenseAccountDomainService;
|
private ExpenseAccountDomainService expenseAccountDomainService;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
private ContractManageApplicationService contractManageApplicationService;
|
||||||
|
@Autowired
|
||||||
private SystemServiceFeign systemServiceFeign;
|
private SystemServiceFeign systemServiceFeign;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 入库/出库费用登记等场景:按仓储合同「仓库进出仓单」结算行取科目(二级编码优先,否则一级),再关联费用科目主数据。
|
||||||
|
* <p>科目范围以合同结算设置为准,不按费用科目主数据的 in_order_display/out_order_display 再筛,避免合同有 7 条主数据未勾「入库显示」却只剩几条的情况。</p>
|
||||||
|
* settlementCustomersCode 不传或为空时使用通用仓储合同。
|
||||||
|
*/
|
||||||
|
public List<ExpenseAccountPO> queryListFromContractWarehouseInOutSettlement(ExpenseAccountDO expenseAccountDO, String settlementCustomersCode) {
|
||||||
|
Long topOrgIdForExpense = expenseAccountDO.getTopOrganizationId();
|
||||||
|
if (topOrgIdForExpense == null) {
|
||||||
|
LoginUser lu = SecurityUtils.getLoginUser();
|
||||||
|
if (lu != null && lu.getUserPo() != null && lu.getUserPo().getTopOrganizationId() != null) {
|
||||||
|
topOrgIdForExpense = lu.getUserPo().getTopOrganizationId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<String> orderedCodes = contractManageApplicationService.listSecondSubjectCodesBySettlementAndDocumentType(
|
||||||
|
settlementCustomersCode,
|
||||||
|
expenseAccountDO.getOrganizationId(),
|
||||||
|
topOrgIdForExpense,
|
||||||
|
ContractManageApplicationService.DOCUMENT_TYPE_CODE_WAREHOUSE_IN_OUT_ORDER);
|
||||||
|
log.info("按合同取费用科目编码:topOrgIdForExpense={}, 命中结算行科目数={}", topOrgIdForExpense,
|
||||||
|
orderedCodes != null ? orderedCodes.size() : 0);
|
||||||
|
List<ExpenseAccountPO> result = new ArrayList<>();
|
||||||
|
for (String code : orderedCodes) {
|
||||||
|
if (StringUtils.isEmpty(code)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ExpenseAccountPO po = expenseAccountDomainService.getInfoByCode2(code.trim(), topOrgIdForExpense);
|
||||||
|
if (po != null && po.getExpenseAccountId() != null) {
|
||||||
|
result.add(po);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询费用科目列表
|
* 分页查询费用科目列表
|
||||||
|
|||||||
+6
@@ -175,4 +175,10 @@ public class ExpenseAccountDO extends BaseVOEntity{
|
|||||||
|
|
||||||
@ApiModelProperty("nc科目编码")
|
@ApiModelProperty("nc科目编码")
|
||||||
private String ncSubjectCode;
|
private String ncSubjectCode;
|
||||||
|
|
||||||
|
/** 查询参数:是否按仓储合同结算设置拉取科目 */
|
||||||
|
private Boolean contractSettlementQuery;
|
||||||
|
|
||||||
|
/** 查询参数:结算主体编码(货主编码等) */
|
||||||
|
private String settlementCustomersCode;
|
||||||
}
|
}
|
||||||
+9
@@ -160,4 +160,13 @@ public class ExpenseAccountDTO extends BaseVOEntity{
|
|||||||
|
|
||||||
@ApiModelProperty("nc科目编码")
|
@ApiModelProperty("nc科目编码")
|
||||||
private String ncSubjectCode;
|
private String ncSubjectCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为 true 时从仓储合同「结算设置」取费用科目(入库/出库费用登记等)
|
||||||
|
*/
|
||||||
|
@ApiModelProperty("是否按合同结算设置查询费用科目(入库/出库费用登记,出库建议配合 outOrderDisplay=1)")
|
||||||
|
private Boolean contractSettlementQuery;
|
||||||
|
|
||||||
|
@ApiModelProperty("结算主体编码(通常为货主编码);不传则按通用仓储合同的结算设置取科目")
|
||||||
|
private String settlementCustomersCode;
|
||||||
}
|
}
|
||||||
+16
@@ -50,6 +50,12 @@ public class ExpenseAccountApi extends BaseController{
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询费用科目列表
|
* 分页查询费用科目列表
|
||||||
|
*
|
||||||
|
* <p>入库/出库费用登记等场景传 {@code contractSettlementQuery=true}(与单据类型「仓库进出仓单」合同结算行一致),
|
||||||
|
* 科目来源、结算主体为空走通用合同等逻辑<strong>入库与出库相同</strong>。
|
||||||
|
* 该路径<strong>仅以合同结算行</strong>为准拉取费用科目主数据,<strong>不会</strong>再按 {@code inOrderDisplay}/{@code outOrderDisplay} 二次过滤,
|
||||||
|
* 以免合同配置了多条但主数据未勾选「入库/出库显示」导致条数被裁掉;
|
||||||
|
* 若在其它场景需要按展示位收窄列表,请勿传 {@code contractSettlementQuery=true},走默认 {@code queryList} 分页查询即可。</p>
|
||||||
*/
|
*/
|
||||||
@ApiOperation("查询费用科目列表")
|
@ApiOperation("查询费用科目列表")
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
@@ -62,6 +68,16 @@ public class ExpenseAccountApi extends BaseController{
|
|||||||
expenseAccountDTO = new ExpenseAccountDTO();
|
expenseAccountDTO = new ExpenseAccountDTO();
|
||||||
logger.info("expenseAccountDTO 为 null,创建新对象");
|
logger.info("expenseAccountDTO 为 null,创建新对象");
|
||||||
}
|
}
|
||||||
|
if (Boolean.TRUE.equals(expenseAccountDTO.getContractSettlementQuery())) {
|
||||||
|
ExpenseAccountDO contractQueryDO = new ExpenseAccountDO();
|
||||||
|
BeanUtils.copyProperties(expenseAccountDTO, contractQueryDO);
|
||||||
|
logger.info("按合同结算设置查询费用科目,settlementCustomersCode={}", expenseAccountDTO.getSettlementCustomersCode());
|
||||||
|
List<ExpenseAccountPO> contractList =
|
||||||
|
expenseAccountApplicationService.queryListFromContractWarehouseInOutSettlement(
|
||||||
|
contractQueryDO, expenseAccountDTO.getSettlementCustomersCode());
|
||||||
|
logger.info("按合同结算设置查询完成,条数:{}", contractList != null ? contractList.size() : 0);
|
||||||
|
return getDataTable(contractList != null ? contractList : new ArrayList<>());
|
||||||
|
}
|
||||||
ExpenseAccountDO expenseAccountDO = new ExpenseAccountDO();
|
ExpenseAccountDO expenseAccountDO = new ExpenseAccountDO();
|
||||||
BeanUtils.copyProperties(expenseAccountDTO, expenseAccountDO);
|
BeanUtils.copyProperties(expenseAccountDTO, expenseAccountDO);
|
||||||
logger.info("转换后的 ExpenseAccountDO:{}", expenseAccountDO);
|
logger.info("转换后的 ExpenseAccountDO:{}", expenseAccountDO);
|
||||||
|
|||||||
Reference in New Issue
Block a user