public void addCollection(MatchableCollection mc) { boolean notm = false; collections.add(mc); if (numRac > 0 && numUpl > 0) mc.setMatchable(); else notm = true; if (mc.isRacunTip()) ++numRac; else ++numUpl; if (notm && numRac > 0 && numUpl > 0) setMatchable(); }
public Object[] getMatchOptions(int row) { RowData rd = (RowData) rows.get(row); SaldoSlot ss = rd.mc.getOwner(); ArrayList ret = new ArrayList(); ret.add(MatchableCollection.none); for (int i = 0; i < ss.getCollectionCount(); i++) { MatchableCollection mc = ss.getCollection(i); if (rd.mc.isRacunTip() != mc.isRacunTip() && (mc.getMaxMatchStrength() <= 0 || mc.getMatch() == rd.mc)) ret.add(mc); } return ret.toArray(); }
public void fillData(final HashMap master) { // javax.swing.plaf.basic.BasicTableUI tui; rows.clear(); ArrayList keys = new ArrayList(master.keySet()); Collections.sort( keys, new Comparator() { public int compare(Object o1, Object o2) { SaldoGroup s1 = (SaldoGroup) master.get(o1); SaldoGroup s2 = (SaldoGroup) master.get(o2); if (s1.countMarkedCollections() != s2.countMarkedCollections()) return s2.countMarkedCollections() - s1.countMarkedCollections(); else if (s1.countTotalCollections() != s2.countTotalCollections()) return s1.countTotalCollections() - s2.countTotalCollections(); return Aus.getAnyNumber((String) o1) - Aus.getAnyNumber((String) o2); } }); for (Iterator it = keys.iterator(); it.hasNext(); ) { String key = (String) it.next(); String desc = analyzeKey(key); SaldoGroup salda = (SaldoGroup) master.get(key); rows.add(new RowData(desc, null)); rows.add(new RowData(desc, null)); for (Iterator s = salda.slotIterator(); s.hasNext(); ) { SaldoSlot ss = (SaldoSlot) s.next(); for (int c = 0; c < ss.getCollectionCount(); c++) { MatchableCollection mc = ss.getCollection(c); if ((mc.getMatch() != null || mc.getMaxMatchStrength() <= raOptimisticMatch.getFactor()) && mc.isRacunTip() == (ss.getNumRac() <= ss.getNumUpl())) rows.add(new RowData(desc, mc)); } } } rows.add(new RowData("", null)); this.fireTableDataChanged(); }
private boolean findAll(int maxDepth, Condition cond) { // nadji sve stavke koje zadovoljavaju uvjet, a nisu pokrivene. DataSet ds = Skstavke.getDataModule() .getTempSet( Aus.getKnjigCond() .and(cond) .and(Aus.getFreeYearCond()) .and(Condition.equal(raSaldaKonti.colPok(), "N"))); // ako je metoda pozvana iz raProcess sustava, iskoristi ga if (!raProcess.isRunning()) ds.open(); else { raProcess.setMessage("Dohvat nepokrivenih stavaka salda konti ...", true); raProcess.openScratchDataSet(ds); } // najprije prevrti cijeli dataset i prebaci sve stavke u MatchRow, // te ih napuni u LinkedList iz kojih cemo ih izbacivati kad i ako // pronadjemo kombinaciju u kojoj se moze pokriti. LinkedList stavke = new LinkedList(); for (ds.first(); ds.inBounds(); ds.next()) stavke.addLast(new MatchRow(ds)); // pocni raditi kombinacije. Najprije svaka stavka pojedinacno, // onda sve do 'maxDepth' stavki po kombinaciji. Prati i potrosnju // objekata da ne predje neku razumnu granicu. int slots = 0, collections = 0; master.clear(); for (int depth = 1; depth <= maxDepth; depth++) { if (raProcess.isRunning()) raProcess.setMessage("Provjera moguæeg pokrivanja stupnja " + depth + " ...", false); // prodji kroz sve preostale stavke i puni glavnu mapu, // koja se sastoji od po jedne mape salda na popis dokumenata za // svaku razlicitu kombinaciju cpar$konto$valuta$godina$uloga // koja postoji u nadjenim stavkama. Jebeno. for (Iterator st = stavke.iterator(); st.hasNext(); ) { MatchRow mr = (MatchRow) st.next(); if (raProcess.isRunning()) raProcess.checkClosing(); // probaj naci vec postojecu grupu salda za ovaj kljuc ili napravi novu SaldoGroup salda = (SaldoGroup) master.get(mr.getMasterKey()); if (salda == null) master.put(mr.getMasterKey(), salda = new SaldoGroup()); // Inicijaliziraj listu kombinacija koja ce se kasnije ubaciti u mapu salda. // Kombinacije se ne mogu odmah ubacivati u mapu jer se po njoj iterira, pa // bi to rezultiralo gadnim kolizijama. Ako je depth 1, onda se napravi // kombinacija od samo teukce stavke, inace se prolazi kroz cijelu mapu // salda i priprema dodavanje novih kombinacija duljine depth. ArrayList toAdd = new ArrayList(); if (depth == 1) toAdd.add(new MatchableCollection(mr)); else for (Iterator it = salda.slotIterator(); it.hasNext(); ) { SaldoSlot ss = (SaldoSlot) it.next(); if (raProcess.isRunning()) raProcess.checkClosing(); // prodji koz sve kombinacije u ovom slotu (koje imaju taj saldo) // i pripremi dodavanje po jedne nove kombinacije za svaku koja // ima depth-1 clanova, i koja je istog tipa kao nova stavka // (tip racuni ili uplate), te koja vec nije u toj kombinaciji. for (int i = 0; i < ss.getCollectionCount(); i++) { MatchableCollection mc = ss.getCollection(i); if (mc.checkAdd(mr, depth)) toAdd.add(mc.copyAndExtend(mr)); } } // i na kraju ubaci sve pripremljene kombinacije iz liste toAdd // u odgovarajuce slotove mape salda. slots -= salda.countSlots(); for (int i = 0; i < toAdd.size(); i++) { MatchableCollection mc = (MatchableCollection) toAdd.get(i); if (raProcess.isRunning()) raProcess.checkClosing(); // probaj naci postojeci saldo slot ili napravi novog ako ga nema, // te dodaj ovu kombinaciju u njega. SaldoSlot ss = (SaldoSlot) salda.getSlot(mc.getMatchSaldo()); if (ss == null) salda.addSlot(mc.getMatchSaldo(), ss = new SaldoSlot()); ss.addCollection(mc); mc.setOwner(ss); } slots += salda.countSlots(); collections += toAdd.size(); if (collections > 100000) break; } if (collections > 100000) break; // ako se stavka vec nalazi u nekoj kombinaciji koja se moze pokriti, // nema potrebe traziti daljnje kombinacije s njom, tj kombinacije s // vise clanova. Cilj je da se minimiziraju visestruka pokrivanja. for (Iterator st = stavke.iterator(); st.hasNext(); ) { MatchRow mr = (MatchRow) st.next(); if (mr.isMatchable()) st.remove(); } } // na kraju balade, u glavnoj mapi imamo mnostvo mapa (za svaki kljuc // cpar$konto$valuta$godina$uloga po jedna) u cijim slotovima se // potencijalno nalaze kombinacije stavaka koje se mogu medjusobno // pokriti. Sve te kombinacije bit ce ponudjene za pokrivanje, grupirane // po saldu. No najprije treba izbaciti iz mape sve one slotove kod kojih // nema bar po jedna kombinacija tipa uplate i jedna tipa racun. for (Iterator it = master.values().iterator(); it.hasNext(); ) { SaldoGroup salda = (SaldoGroup) it.next(); for (Iterator s = salda.slotIterator(); s.hasNext(); ) { SaldoSlot ss = (SaldoSlot) s.next(); if (!ss.isMatchable()) s.remove(); } if (salda.countSlots() == 0) it.remove(); } // medju preostalim mapama probaj naci najbolje matcheve. for (Iterator it = master.values().iterator(); it.hasNext(); ) { SaldoGroup salda = (SaldoGroup) it.next(); for (Iterator s = salda.slotIterator(); s.hasNext(); ) { SaldoSlot ss = (SaldoSlot) s.next(); for (int i = 0; i < ss.getCollectionCount(); i++) { MatchableCollection mi = ss.getCollection(i); mi.findRepresentations(); double now; for (int j = 0; j < ss.getCollectionCount(); j++) { MatchableCollection mj = ss.getCollection(j); if (mi.isRacunTip() != mj.isRacunTip() && (now = mi.getMatchFactor(mj)) > mi.getMatchedFactor() && now > mj.getMatchedFactor() && now > mi.getMaxMatchStrength() && now > mj.getMaxMatchStrength()) mi.setMatch(mj); } } } salda.findMarks(); } return master.size() > 0; }