Example #1
0
 public MatchableCollection(MatchRow mr) {
   rows.add(mr);
   racTip = mr.isRacunSide();
   saldo = mr.isKob() ? mr.getPVSaldo().abs() : mr.getPVSaldo();
   matchFactor = 0;
   repr = tool = null;
   //    repr = getStringRepresentation();
   //    tool = getToolTipRepresentation();
 }
Example #2
0
  private String getToolTipRepresentation() {
    shared.clear();
    shared.append("<html><body><table border>");
    shared.append("<tr><th>OJ</th><th>Dokument</th><th>Datum</th><th>Saldo</th></tr>");

    for (int i = 0; i < rows.size(); i++) {
      MatchRow row = getRow(i);
      shared.append("<tr><td>").append(row.getCorg());
      shared.append("</td><td>").append(row.getVrdok());
      shared.append(' ').append(row.getBrojDok());
      if (row.isRacunTip() && row.getExtBroj().length() > 0)
        shared.append(" (").append(row.getExtBroj()).append(")");
      shared.append("</td><td>");
      shared.append(raDateUtil.getraDateUtil().dataFormatter(getRow(i).getDatum()));
      shared.append("</td><td>").append(getSF(getRow(i).getPVSaldo())).append("</td></tr>");
    }
    return shared.append("</table></body></html>").toString();
  }
Example #3
0
  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;
  }
Example #4
0
 public boolean checkAdd(MatchRow mr, int size) {
   return racTip == mr.isRacunSide() && rows.size() == size - 1 && mr.compareByKey(getRow(0)) > 0;
 }