任务列表

  • 【深瑞】费用模块跨年结转 task @测试中 🔼 📅 2026-01-04 ✅ 2026-01-04

需求描述

原始需求

一.费用账户新建及更新期初数

  1. 新建25年费用账户,25年的本级账户余额=26年的账户期初结转金额,25年12月31日凌晨再刷新一版数据

2. 新建25年费用-大区、25年费用-省区

个人账户:本级账户余额刷新到期初账户余额中

汇总账户:刷新个人账户上级汇总余额

3. 新建26年账户场景

二.费用额度发放替换为2026年费用账户

2512-26-01-01.png

需求增补(需求确认)

IT执行

执行方案概述

基础数据维护

  1. 费用-大区
  2. 费用-省区
  3. 费用账户 实现逻辑见代码块^7523d6

更新系统逻辑

  1. ERP销售合同
    1. 【深瑞&汇阳】ERP销售合同【统计日期】判断 工作流
      1. Recal_expense__c:【费用】【ERP销售合同】【差额处理】
      2. ContractSplit_UpdatePolicy__c:【费用】【ERP销售合同】更新核算方法
      3. CstmCtrl_2iPrW__c:【公共费】2025深瑞营销本部&大区公共费控制器
      4. CompleteShipmentGrant__c:【费用】【完全发货】费用发放
      5. IncompleteShipmentReduce__c:【费用】非【完全发货】费用扣减
      6. PaymentGrant__c:【费用】【回款比例更新】费用发放
  2. 合同费用额度
    1. ContractSplit_Margin__c:【费用】【合同政策&费用申请】3.差额处理
    2. ContractSplit_Return_Grant__c:【费用】合同政策确认后费用发放&营销公共费&大区公共费
    3. CstmCtrl_RHPsb__c:【合同费用】合同费用发放.控制器

重构部分逻辑

  1. CstmCtrl_FEx8a__c:【费用】费用账户匹配.控制器。
    1. 该控制器原逻辑为:根据ERP销售合同中销售代表去查询费用账户。
      • 这会导致拆分合同费用跨年后,重新匹配费用账户时,匹配到同一个账户。

    2. 重构后:增加旧费用账户参数,并修正调用代码

同步数据到财务共享

  1. 基础资料
    1. 大区:9 铁路专区 可删除
    2. 省区:39
  2. 费用账户
    1. 组织:1
    2. 大区:16
    3. 省区:78
    4. 个人:190

执行计划

  1. 2025-12-29 新建基础数据
  2. 2025-12-31 同步基础数据、更新最新一年基础数据

时间队列

  • 2025-12-26 17:24
    • 书写大区、省区复制逻辑
/**
 * @author 王亚新
 * @codeName 【IT】复制费用-大区
 * @description 生成新的大区
 * @createTime 2025-12-26
 * @bindingObjectLabel 费用-大区
 * @bindingObjectApiName object_G1rnx__c
 * @函数需求编号
 */
String id = context.data._id as String //id
String recordType = context.data.record_type as String //业务类型
String areaName = context.data.name as String //编码  --
List dataOwner = context.data.owner as List //负责人
String bigArea = context.data.field_248Cd__c as String //大区
List ownerList = context.data.field_6GINq__c as List //个人(财务共享)
String areaCode = context.data.field_w2aCs__c as String //大区编码  --
String orgName = context.data.field_IH27f__c as String //组织
String isSync = "0" //是否需要同步  默认为否
areaName = areaName.replace("2025", "")
areaCode = areaCode.replace("2025", "")
Map masterData = [
  "name": areaName,
  "owner": dataOwner,
  "field_248Cd__c": bigArea,
  "field_6GINq__c": ownerList,
  "field_w2aCs__c": areaCode,
  "field_IH27f__c": orgName,
  "field_need_sync__c": isSync,
  "record_type":recordType
]
def ret = Fx.object.create("object_G1rnx__c", masterData, null, CreateAttribute.builder().build()).result() as Map
String dataId = ret["data"]["_id"] as String 
def updateRet = Fx.object.update("object_G1rnx__c", id, ["transfer_storage__c": dataId], UpdateAttribute.builder().triggerWorkflow(true).build())
/**
 * @author 王亚新
 * @codeName 【IT】复制费用-省区
 * @description init
 * @createTime 2025-12-26
 * @bindingObjectLabel 费用-省区
 * @bindingObjectApiName object_M8s68__c
 */
String id = context.data._id as String 
String recordType = context.data.record_type as String //业务类型
String areaName = context.data.name as String //编码  --
List dataOwner = context.data.owner as List //负责人
String bigArea = context.data.field_fr76b__c as String //大区
List ownerList = context.data.field_afxqp__c as List //个人(财务共享)
String areaCode = context.data.field_NJFFk__c as String //省区编码  --
String orgName = context.data.field_QGm2E__c as String //组织
String privance = context.data.field_OErKl__c as String //销售省份
areaName = areaName.replace("2025", "")
areaCode = areaCode.replace("2025", "")
String isSync = "0"
def findArea = Fx.object.findById("object_G1rnx__c", //对象apiName
            bigArea, //数据id
            FQLAttribute.builder()
                    .columns(["_id", "name","transfer_storage__c"]) //需要返回的字段
                    .build(),
            SelectAttribute.builder()
                    .needCalculate(false) //是否实时处理计算字段,默认true
                    .needQuote(false) //是否实时处理引用字段,默认true
                    .calculateCount(false) //是否实时处理统计字段,默认true
                    .build()).result() as Map //complete result : (Boolean error,Map data,String errorMessage)
bigArea = findArea["transfer_storage__c"] as String
Map masterData = [
  "name": areaName, //编码
  "owner": dataOwner, //负责人
  "field_NJFFk__c": areaCode, //省区编码
  "field_fr76b__c": bigArea, //大区
  "field_afxqp__c": ownerList, //个人(财务共享)
  "field_QGm2E__c": orgName, //组织
  "field_OErKl__c": privance, //销售省份
  "record_type":recordType,
  "is_synchronized__c":isSync
]
def ret = Fx.object.create("object_M8s68__c", masterData, null, CreateAttribute.builder().build()).result() as Map
String dataId = ret["data"]["_id"] as String 
def updateRet = Fx.object.update("object_M8s68__c", id, ["transfer_storage__c": dataId], UpdateAttribute.builder().triggerWorkflow(true).build())
/**  
 * @decription 账户复制应遵循一定顺序:组织 >> 大区汇总 >> 大区公共 >> 省区汇总 >> 省区公共 >> 普通账户  
 */  
Map map = context.data as Map  
String id = map["_id"] as String  //数据id  
//收集必须字段  
String name = map["name"] as String  //账户编码  
String beforeName = name as String  //账户编码  
String accountName = map["field_A8a5g__c"] as String  //账户名称  
List saleOwner = map["field_yrCyI__c"] as List  //销售代表  
String organization = map["field_l1b1v__c"] as String //组织  
String regionId = map["field_0opVt__c"] as String ?: "none" //大区  
String provinceId = map["field_cZ4Qe__c"] as String ?: "none" //省区  
List regionList = map["field_LR1l6__c"] as List //区域负责人  
String isTotal = map["field_Q2t6y__c"] as String //是否汇总账户  
String isPublic = map["field_0KgPb__c"] as String //是否公共费池  
Date beginDate = "2026-01-01"//生效日期  
Date endDate = "2026-12-31"//失效日期  
String isSync = "0"  //是否同步默认为否  
String parentAccount = map["field_aBs7b__c"] as String ?: "none"//当前数据上级账户id  
List dataOwner = map["owner"] as List //负责人  
String recordType = map["record_type"] as String //业务类型  
String groupTag = map["group_identifier__c"] as String //分组标识  
//二次处理  
name = name.replace("25", "26")  
if (accountName) {  
    accountName = accountName.replace("25", "26")//账户名称中24替换为25  
}  
beginDate = Date.of("2026-01-01")  
endDate = Date.of("2026-12-31")  
isSync = "0"  
//获取大区  
def findArea = Fx.object.findById("object_G1rnx__c", //大区  
        regionId, //数据id  
        FQLAttribute.builder()  
                .columns(["_id", "name", "transfer_storage__c"]) //需要返回的字段  
                .build(),  
        SelectAttribute.builder()  
                .build()).result() as Map //complete result : (Boolean error,Map data,String errorMessage)  
if (findArea) {  
    regionId = findArea["transfer_storage__c"] as String  
}else{  
    regionId = ""  
}  
//获取省区  
def findProvince = Fx.object.findById("object_M8s68__c", //省区  
        provinceId, //数据id  
        FQLAttribute.builder()  
                .columns(["_id", "name", "transfer_storage__c"]) //需要返回的字段  
                .build(),  
        SelectAttribute.builder()  
                .build()).result() as Map //complete result : (Boolean error,Map data,String errorMessage)  
if (findProvince) {  
    provinceId = findProvince["transfer_storage__c"] as String  
}else{  
    provinceId = ""  
}  
def findParent = Fx.object.findById("object_tlU1k__c", //对象apiName  
        parentAccount, //数据id  
        FQLAttribute.builder()  
                .columns(["_id", "name", "transfer_storage__c"]) //需要返回的字段  
                .build(),  
        SelectAttribute.builder()  
                .build()).result() as Map //complete result : (Boolean error,Map data,String errorMessage)  
if(findParent){  
    parentAccount = findParent["transfer_storage__c"] as String  
}else{  
    parentAccount = ""  
}  
  
//创建主表数据  
Map masterData = [  
        "name"                : name, //账户编码  
        "field_A8a5g__c"      : accountName, //账户名称  
        "field_LR1l6__c"      : regionList, //区域负责人  
        "field_0opVt__c"      : regionId, //大区  
        "field_l1b1v__c"      : organization, //组织  
        "field_Q2t6y__c"      : isTotal, //是否汇总账户  
        "field_0KgPb__c"      : isPublic, //是否公共费池  
        "field_28Wa2__c"      : beginDate, //生效日期  
        "field_242ks__c"      : endDate, //失效日期  
        "field_sync_or_not__c": isSync, //是否同步  
        "owner"               : dataOwner, //负责人  
        "record_type"         : recordType, //业务类型  
        "field_aBs7b__c"      : parentAccount,//上级账户  
        "transfer_storage__c" : beforeName, //中转寄存  
        "field_cZ4Qe__c"      : provinceId, //省区  
        "field_yrCyI__c"      : saleOwner, //销售代表  
        "group_identifier__c" : groupTag //组标识符  
]  
//创建费用账户  
def (Boolean error_create, Map data_create, String errorMessage_create) = Fx.object.create("object_tlU1k__c", masterData, null, CreateAttribute.builder().build())  
if (error_create) {  
    log.error("获取对象异常" + errorMessage_create)  
} else {  
    Map item_1 = data_create["data"] as Map  
    String dataId = item_1["_id"] as String  
    log.info("创建成功:" + dataId)  
    def (Boolean error_update, Map data_update, String errorMessage_update) = Fx.object.update("object_tlU1k__c", id, ["transfer_storage__c": dataId], UpdateAttribute.builder().triggerWorkflow(false).build())  
}
/**  
 * @author 王亚新  
 * @description 本年账户余额结转到次年账户期初结转金额  
 */  
//符合条件的数据id  
List ids = context.objectIds as List  
def (boolean error, List dataList, String errorMessage) = Fx.object.findByIds("object_tlU1k__c", ids, FQLAttribute.builder().columns(["_id", "name", "transfer_storage__c", "field_7172F__c"]).build(), SelectAttribute.builder()  
        .needCalculate(true) //是否实时处理计算字段,默认true  
        .needQuote(true) //是否实时处理引用字段,默认true  
        .calculateCount(true) //是否实时处理统计字段,默认true)  
        .build())  
dataList.each { item ->  
    Map map = item as Map  
    //处理业务逻辑  
    String target_id = map["transfer_storage__c"] as String //中转寄存即目标数据ID  
    BigDecimal now_amount = map["field_7172F__c"] as BigDecimal ?: 0.000 //本级账户余额
    BigDecimal target_amount = now_amount as BigDecimal //账户期初结转金额  
    if (target_id) {  
        //当前时间  
        DateTime now_date = DateTime.now() as DateTime  
        Map updateData = ["field_m8K7O__c": target_amount, "scheduled_task_modified_ti__c": now_date]  
        def (Boolean error_result, Map data_result, String errorMessage_result) = Fx.object.update("object_tlU1k__c", target_id, updateData, UpdateAttribute.builder().triggerWorkflow(true).build())  
        if (error_result) {  
            log.error("获取对象异常" + errorMessage_result)  
        } else {  
            // dosomething,将示例逻辑细化至业务数据层  
            def map_result = data_result as Map  
            def name_result = map_result['name'] as String  
            def amount_result = map_result['field_m8K7O__c']  
            log.info(name_result + "。<余额,期初金额>:${target_amount} : ${amount_result}")  
        }  
    } else {  
        log.info("中转寄存数据为空:" + map["name"])  
    }  
}