public static ArrayList<HashMap<String, String>> getFertDistribution(HashMap data, String num, String fecd, String feacd, String fedep, String[] offsets, String[] ptps) {
        int iNum;
        //Map expData;
        ArrayList<Map> eventData;
        String fen_tot;
        String[] fdates;
        //Event events;
        String pdate;
        ArrayList<HashMap<String, String>> results = new ArrayList<HashMap<String, String>>();

        try {
            iNum = Integer.parseInt(num);
            if (iNum < 1) {
                LOG.error("INPUT NUMBER OF FERTILIZER APPLICATIONS MUST BE A POSIIVE NUMBER");
                return results;
            }
        } catch (Exception e) {
            LOG.error("INPUT NUMBER OF FERTILIZER APPLICATIONS IS NOT A NUMBERIC STRING [" + num + "]");
            return results;
        }

        // Check if the two input array have "num" pairs of these data
        if (iNum != offsets.length || iNum != ptps.length) {
            if (iNum > offsets.length || !compare("100", round(sum(Arrays.copyOfRange(ptps, 0, iNum)), 0), CompareMode.EQUAL)) {
                LOG.error("THE REQUESTED NUMBER OF APPLICATION IS NOT MATCH WITH THE GIVEN OFFSET DATA");
                return results;
            }
        } // Check if the sum of PTPs is 100%
        else if (!compare("100", round(sum(ptps), 0), CompareMode.EQUAL)) {
            LOG.error("THE SUM OF PROPORTION OF TOTAL N ADDED (%) IS NOT EQUAL TO 100%");
            return results;
        }

        // Check if experiment data is available
        //ArrayList<Map> exps = getObjectOr(data, "experiments", new ArrayList());
        //if (exps.isEmpty()) {
        //    LOG.error("NO EXPERIMENT DATA.");
        //    return;
        //} else {
        //    expData = exps.get(0);
        //    if (expData.isEmpty()) {
        //        LOG.error("NO EXPERIMENT DATA.");
        //       return;
        //    } else {
        Map mgnData = getObjectOr(data, "management", new HashMap());
        eventData = getObjectOr(mgnData, "events", new ArrayList());
        //    }

        // Check FEN_TOT is avalaible
        try {
            fen_tot = getValueOr(data, "fen_tot", "");
        } catch (Exception e) {
            LOG.error("FEN_TOT IS INVALID");
            return results;
        }

        // Check planting date is avalaible
        // events = new Event(eventData, "planting");
        // if (events.isEventExist()) {
        //     pdate = getValueOr(events.getCurrentEvent(), "date", "");
        //     if (convertFromAgmipDateString(pdate) == null) {
        //         LOG.error("PLANTING DATE IS MISSING");
        //         return;
        //     }
        // } else {
        //     LOG.error("PLANTING EVENT IS MISSING");
        //     return;
        // }
        //HashMap<String, Object> dest = new HashMap<String, Object>();
        ArrayList<String> output = new ArrayList<String>();
        for (Map events : eventData) {
            if (getValueOr(events, "event", "").equals("planting")) {
                pdate = getValueOr(events, "date", "");
                //}

                // Check input days and ptps
                try {
                    fdates = new String[iNum];
                    for (int i = 0; i < iNum; i++) {
                        fdates[i] = dateOffset(pdate, offsets[i]);
                        if (fdates[i] == null) {
                            LOG.error("INVALID OFFSET NUMBER OF DAYS [" + offsets[i] + "]");
                            return results;
                        }
                    }
                } catch (Exception e) {
                    LOG.error("PAIR DATA IS IN VALID [" + e.getMessage() + "]");
                    return results;
                }

                //events.setEventType("fertilizer");
                for (int i = 0; i < iNum; i++) {
                    String feamn = round(product(fen_tot, ptps[i], "0.01"), 0);
                    if (feamn == null) {
                        LOG.error("Invalid value for FEN_TOT {} or PTP {}", fen_tot, ptps[i]);
                    }
                    output.add(String.format("%s|%s", fdates[i], feamn));
                }
                break;
            }
        }
        HashMap result = new HashMap();
        for (String addNew : output) {
            String[] tmp = addNew.split("[|]");
            AcePathfinderUtil.insertValue(result, "fedate", tmp[0]);
            AcePathfinderUtil.insertValue(result, "fecd", fecd);
            AcePathfinderUtil.insertValue(result, "feacd", feacd);
            AcePathfinderUtil.insertValue(result, "fedep", fedep);
            if (!tmp[1].equals("null")) {
                AcePathfinderUtil.insertValue(result, "feamn", tmp[1]);
            }
        }
        results = MapUtil.getBucket(result, "management").getDataList();

        return results;
    }
public static ArrayList < HashMap < String , String > > getFertDistribution ( HashMap data , String num , String fecd , String feacd , String fedep , String [ ] offsets , String [ ] ptps ) { int iNum ; ArrayList < Map > eventData ; String fen_tot ; String [ ] fdates ; String pdate ; ArrayList < HashMap < String , String > > results = new ArrayList < HashMap < String , String > > ( ) ; try { iNum = Integer . parseInt ( num ) ; if ( iNum < 1 ) { LOG . error ( "INPUT NUMBER OF FERTILIZER APPLICATIONS MUST BE A POSIIVE NUMBER" ) ; return results ; } } catch ( Exception e ) { LOG . error ( "INPUT NUMBER OF FERTILIZER APPLICATIONS IS NOT A NUMBERIC STRING [" + num + "]" ) ; return results ; } if ( iNum != offsets . length || iNum != ptps . length ) { if ( iNum > offsets . length || ! compare ( "100" , round ( sum ( Arrays . copyOfRange ( ptps , 0 , iNum ) ) , 0 ) , CompareMode . EQUAL ) ) { LOG . error ( "THE REQUESTED NUMBER OF APPLICATION IS NOT MATCH WITH THE GIVEN OFFSET DATA" ) ; return results ; } } else if ( ! compare ( "100" , round ( sum ( ptps ) , 0 ) , CompareMode . EQUAL ) ) { LOG . error ( "THE SUM OF PROPORTION OF TOTAL N ADDED (%) IS NOT EQUAL TO 100%" ) ; return results ; } Map mgnData = getObjectOr ( data , "management" , new HashMap ( ) ) ; eventData = getObjectOr ( mgnData , "events" , new ArrayList ( ) ) ; try { fen_tot = getValueOr ( data , "fen_tot" , "" ) ; } catch ( Exception e ) { LOG . error ( "FEN_TOT IS INVALID" ) ; return results ; } ArrayList < String > output = new ArrayList < String > ( ) ; for ( Map events : eventData ) { if ( getValueOr ( events , "event" , "" ) . equals ( "planting" ) ) { pdate = getValueOr ( events , "date" , "" ) ; try { fdates = new String [ iNum ] ; for ( int i = 0 ; i < iNum ; i ++ ) { fdates [ i ] = dateOffset ( pdate , offsets [ i ] ) ; if ( fdates [ i ] == null ) { LOG . error ( "INVALID OFFSET NUMBER OF DAYS [" + offsets [ i ] + "]" ) ; return results ; } } } catch ( Exception e ) { LOG . error ( "PAIR DATA IS IN VALID [" + e . getMessage ( ) + "]" ) ; return results ; } for ( int i = 0 ; i < iNum ; i ++ ) { String feamn = round ( product ( fen_tot , ptps [ i ] , "0.01" ) , 0 ) ; if ( feamn == null ) { LOG . error ( "Invalid value for FEN_TOT {} or PTP {}" , fen_tot , ptps [ i ] ) ; } output . add ( String . format ( "%s|%s" , fdates [ i ] , feamn ) ) ; } break ; } } HashMap result = new HashMap ( ) ; for ( String addNew : output ) { String [ ] tmp = addNew . split ( "[|]" ) ; AcePathfinderUtil . insertValue ( result , "fedate" , tmp [ 0 ] ) ; AcePathfinderUtil . insertValue ( result , "fecd" , fecd ) ; AcePathfinderUtil . insertValue ( result , "feacd" , feacd ) ; AcePathfinderUtil . insertValue ( result , "fedep" , fedep ) ; if ( ! tmp [ 1 ] . equals ( "null" ) ) { AcePathfinderUtil . insertValue ( result , "feamn" , tmp [ 1 ] ) ; } } results = MapUtil . getBucket ( result , "management" ) . getDataList ( ) ; return results ; }
Often the total amount of fertilizer in a growing season has been
recorded, but no details of application dates, types of fertilizer,etc.
This function allows a user to specify rules for fertilizer application
in a region. As a result, "N" fertilizer events are added to the JSON
object.

@param num Number of fertilizer applications
@param fecd The code for type of fertilizer added
@param feacd The code for fertilizer application method
@param fedep The depth at which fertilizer is applied (cm)
@param offsets The array of date as offset from planting date (days)
(must be paired with ptps)
@param ptps The array of proportion of total N added (%) (must be paired
with offsets, the sum must be 100%)
@param data The experiment data holder

@return An {@code ArrayList} of generated {@code fertilizer event} based
on each planting date