/// <summary> /// 新增一条新的数据 /// /// (新增一行新的主数据, 服务类负责把这行新的主数据, 拆分为多行子数据.) /// /// 处理结果, 将存储在 主数据的 SubDataList 属性中. /// </summary> /// <param name="mainData"></param> public void InsertNewMainData(MainData mainData) { // 参数有效性检查. if (mainData == null) { throw new ArgumentNullException("主数据不能为空!"); } if (mainData.MainInitValue < 0) { throw new ArgumentException("主数据金额不能为负数!"); } // 首先, 初始化 主数据的 子数据列表. mainData.InitSubDataList(); // 获取初始的 主数据的 金额. decimal remainValue = mainData.MainInitValue; // 拆分处理. while (remainValue > 0) { // 构造一个子数据. SubData subData = new SubData(); // 子数据的初始值,为 当前余额, 与 单位最大数值 中, 较小对一个. subData.SubInitValue = Math.Min(remainValue, this.MaxSubValue); // 余额 = 初始值. subData.SubBalanceValue = subData.SubInitValue; // 加入列表. mainData.SubDataList.Add(subData); // 余额递减. remainValue -= this.MaxSubValue; } }
/// <summary> /// 更新一行主数据. /// /// (处理前,要求主数据的 SubDataList 属性非空且有效) /// /// 处理的主要逻辑, 将修改 主数据的 SubDataList 属性中的相关数值. /// </summary> /// <param name="mainData">主数据</param> /// <param name="changeValue">变化值,增加或减少的数量</param> public bool UpdateMainData(MainData mainData, decimal changeValue) { // 参数有效性检查. if (mainData == null) { throw new ArgumentNullException("主数据不能为空!"); } if (mainData.SubDataList == null) { throw new ArgumentException("主数据未加载子数据列表!"); } // 中间计算金额. decimal remainValue = changeValue; if (remainValue > 0) { // 金额大于0, 是给子数据增加数值. // 从后向前遍历. for (int i = mainData.SubDataList.Count - 1; i >= 0; i--) { // 获取子数据. ISubData subData = mainData.SubDataList[i]; // 如果未使用过,那么尝试上一行. if (subData.SubFinishValue == 0) { continue; } // 准备发生变化的数值 = 剩余总金额 与 当前子数据可容纳金额 中,较小的一个. decimal changeVal = Math.Min(remainValue, subData.SubFinishValue); // 剩余金额递减. remainValue -= changeVal; // 子数据余额递增. subData.SubBalanceValue = subData.SubBalanceValue + changeVal; if( remainValue ==0) { break; } } } else { // 金额小于0, 是给子数据减少数值. // 从前向后遍历. for (int i = 0; i < mainData.SubDataList.Count; i++) { // 获取子数据. ISubData subData = mainData.SubDataList[i]; // 准备发生变化的数值 = 需要减少的金额绝对值 与 当前子数据可余额 中,较小的一个. decimal changeVal = Math.Min(Math.Abs(remainValue), subData.SubBalanceValue ); // 减少金额变化. remainValue += changeVal; // 子数据余额递减. subData.SubBalanceValue = subData.SubBalanceValue - changeVal; if( remainValue ==0) { break; } } } // 如果变化金额最后为0, 表示处理成功! return remainValue == 0; }
public void Test1500() { // 拆分单位 = 1500 没单位. DefaultMainSubDataManager manager = new DefaultMainSubDataManager() { MaxSubValue = 1500 }; // 初始金额= 8K. MainData mainData = new MainData() { MainInitValue = 8000 }; // 拆分. manager.InsertNewMainData(mainData); // 拆分后子数据列表不为 NULL Assert.IsNotNull(mainData.SubDataList); // 子数据列表长度应为 6个 其中, 前5个是满的 1500, 最后一个是 500 Assert.AreEqual(6, mainData.SubDataList.Count); for (int i = 0; i < 5; i++) { Assert.AreEqual(1500, mainData.SubDataList[i].SubInitValue); Assert.AreEqual(1500, mainData.SubDataList[i].SubBalanceValue); } Assert.AreEqual(500, mainData.SubDataList[5].SubInitValue); Assert.AreEqual(500, mainData.SubDataList[5].SubBalanceValue); // 测试消耗一次. bool updateResult = manager.UpdateMainData(mainData, -500); // 成功. Assert.IsTrue(updateResult); // 首行消耗 500, 其它保持不变. Assert.AreEqual(1000, mainData.SubDataList[0].SubBalanceValue); for (int i = 1; i < 5; i++) { Assert.AreEqual(1500, mainData.SubDataList[i].SubBalanceValue); } Assert.AreEqual(500, mainData.SubDataList[5].SubBalanceValue); updateResult = manager.UpdateMainData(mainData, -3000); // 成功. Assert.IsTrue(updateResult); // 前2行余额0, 第3行消耗 500, 其它保持不变. for (int i = 0; i < 2; i++) { Assert.AreEqual(0, mainData.SubDataList[i].SubBalanceValue); } Assert.AreEqual(1000, mainData.SubDataList[2].SubBalanceValue); for (int i = 3; i < 5; i++) { Assert.AreEqual(1500, mainData.SubDataList[i].SubBalanceValue); } Assert.AreEqual(500, mainData.SubDataList[5].SubBalanceValue); updateResult = manager.UpdateMainData(mainData, -1500); // 成功. Assert.IsTrue(updateResult); // 前3行余额0, 第4行消耗 500, 其它保持不变. for (int i = 0; i < 3; i++) { Assert.AreEqual(0, mainData.SubDataList[i].SubBalanceValue); } Assert.AreEqual(1000, mainData.SubDataList[3].SubBalanceValue); for (int i = 4; i < 5; i++) { Assert.AreEqual(1500, mainData.SubDataList[i].SubBalanceValue); } Assert.AreEqual(500, mainData.SubDataList[5].SubBalanceValue); updateResult = manager.UpdateMainData(mainData, 3000); // 成功. Assert.IsTrue(updateResult); // 前1行余额0, 第2行消耗 500, 其它保持不变. for (int i = 0; i < 1; i++) { Assert.AreEqual(0, mainData.SubDataList[i].SubBalanceValue); } Assert.AreEqual(1000, mainData.SubDataList[1].SubBalanceValue); for (int i = 2; i < 5; i++) { Assert.AreEqual(1500, mainData.SubDataList[i].SubBalanceValue); } Assert.AreEqual(500, mainData.SubDataList[5].SubBalanceValue); }