記錄一次主單明細(xì)分包解決思路

項(xiàng)目背景:建行收到財(cái)政發(fā)來的公務(wù)卡墊款xml報(bào)文存庫,報(bào)文格式分主單和明細(xì),主單不包含收款賬號(hào),明細(xì)單包含收款賬號(hào),即一個(gè)主單包含多個(gè)明細(xì)(明細(xì)確定不超過500,但具體多少,未知)!建行公務(wù)卡支付需按照明細(xì)支付,支付完成以后,需按主單生成清算單到人行做清算,也是主單+明細(xì)的情況,但是明細(xì)單有一個(gè)要求,不能超過500,超過500必須分包,而且必須保證一個(gè)主單的明細(xì)單必須在一個(gè)清算單中,不能存在一個(gè)主單對應(yīng)的明細(xì)單在兩個(gè)清算單中,而且必須保證清算單最少(不能10個(gè)公務(wù)卡,生成10張清算單)。

解決思路草稿.png

比如說主單A包含450條明細(xì)單,主單B包含300條明細(xì)單,主單C包含200條明細(xì)單,那么這種情況就只能生成3張清算單,如果主單D包含10條明細(xì)單,那么也只能生成3張清算單,雖然人行清算也是按照明細(xì)單做清算,但是為了三方對賬方便(主要還是財(cái)政),建行規(guī)則必須按照這種業(yè)務(wù)邏輯生成!

所以依據(jù)草稿(解決思路),理了一下業(yè)務(wù)邏輯:

1、取出Map<明細(xì)條數(shù),公務(wù)卡主單憑證號(hào)>
2、求Map明細(xì)條數(shù)的Sum
3、明細(xì)合計(jì)<499,則生成一個(gè)清算單,>499考慮遞歸,最終合計(jì)小于499為出口

模擬業(yè)務(wù)邏輯,代碼如下:

package xf;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class Person {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("79", "主單憑證號(hào)1"); // 1111
        map.put("68", "主單憑證號(hào)2");
        map.put("57", "主單憑證號(hào)3");
        map.put("46", "主單憑證號(hào)4");
        map.put("35", "主單憑證號(hào)5");
        map.put("24", "主單憑證號(hào)6");
        map.put("12", "主單憑證號(hào)7"); // 1111
        map.put("1", "主單憑證號(hào)8"); // 1111

        int count = SumList(map);
        System.out.println("合計(jì)條數(shù)========" + count);

        if (count < 100) {
            System.out.println("就一筆清算單");
        }
        if (count > 100) {
            System.out.println("清算明細(xì)單超過100======================================");
            
            List<String> strArr = new ArrayList<String>();
            strArr = returnVoucher(map); //第一次取出不超過100的主單憑證號(hào) AA         
            
            Map<String, String> remMap = new HashMap<String, String>(); 
            remMap = returnRemoveMap(map, strArr); //第一次剔除AA
            
            // 統(tǒng)計(jì)remMap明細(xì)條數(shù)
            int sum = SumList(remMap);
            
            boolean turn = true;
            int n = 0;
            int m = 0;
            
            while (turn) {
                if (sum < 100) {
                    // 直接生成最后一筆清算
                    System.err.println("我是最后一筆清算 我是出口 遞歸函數(shù)出口!");
                    strArr = returnVoucher(remMap); //剩下的
                    for (String str : strArr) {
                        System.err.println("最后剩下的憑證號(hào)==" + str);
                    }
                    turn = false;
                    break; // 出口
                }
                if (sum > 100) {
                    // 循環(huán)
                    n++;
                    m++;
                    System.err.println("生成第" + n + "筆清算!"); //此時(shí)的strArr剛好是第一次取出來的
                    remMap = returnRemoveMap(remMap, strArr); // 在剔除
                    System.out.println("第" + m + "次剔除!");
                        
                    sum = SumList(remMap); // 判斷條數(shù)
                    System.out.println("統(tǒng)計(jì)明細(xì)條數(shù)===" + sum);
                    
                    strArr = returnVoucher(remMap);
                }
            }
        }
    }

    // 取出明細(xì)合計(jì)小于499的任意主單
    public static List<String> returnVoucher(Map<String, String> map) {
        List<String> strArr = new ArrayList<String>();
        int sum = 0;

        Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, String> entry = it.next();
            sum = sum + Integer.valueOf(entry.getKey()); // key是明細(xì)條數(shù)
            if (sum < 100) {
                strArr.add(entry.getValue());
                // System.out.println("key= " + entry.getKey() + " and value= "
                // + entry.getValue());
            } else {
                break;
            }
        }

        return strArr;
    }

    // 剔除list 返回剩余Map
    public static Map<String, String> returnRemoveMap(Map<String, String> map, List<String> listStr) {

        Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, String> entry = it.next();
            for (String str : listStr) {
                if (str.equals(entry.getValue())) {
                    // map.remove(entry.getKey()); //map移除元素必須用迭代器
                    it.remove();
                }
            }
        }

        return map;
    }
 
//統(tǒng)計(jì)明細(xì)條數(shù)的sum
    public static Integer SumList(Map<String, String> remMap) {
        int sum = 0;

        Iterator<Map.Entry<String, String>> it = remMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, String> entry = it.next();
            sum = sum + Integer.valueOf(entry.getKey()); // key是明細(xì)條數(shù)
        }
        return sum;
    }
}
模擬Console.png

main函數(shù)匯總的map,模擬數(shù)據(jù)庫中取出的Map,該業(yè)務(wù)邏輯需要注意的是,并非合計(jì)數(shù)除以500的結(jié)果+1就是最少清算單條數(shù),這個(gè)就是該業(yè)務(wù)最大難點(diǎn),比方說:
主單A包含450條明細(xì)單
主單B包含300條明細(xì)單
主單C包含200條明細(xì)單
主單D包含100條明細(xì)單
主單E包含350條明細(xì)單
雖然明細(xì)合計(jì)為1400,但是必須生成4張清算單,這是必須要注意到的地方!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容