diff --git a/ca/ca2100.cpp b/ca/ca2100.cpp index 509a1eb00..f510608f8 100755 --- a/ca/ca2100.cpp +++ b/ca/ca2100.cpp @@ -26,6 +26,8 @@ class TMovanal_msk : public TAutomask short _cdc_start; short _cdc_end; + TCache_ripartizioni _cache_rip; + protected: virtual bool on_field_event(TOperable_field& o, TField_event fe, long jolly); virtual bool can_be_closed() const; @@ -36,7 +38,8 @@ protected: // Lettura movimento contabile TToken_string& get_rip_row(const TRectype& rrip); - void split_cg_row(const TRectype& row, const TRecord_array& rrip); + void split_cg_row(const TRectype& row, const TAnal_ripartizioni_batch& rrip); + bool multi_split_cg_row(const TRectype& row, const TAnal_ripartizioni_batch& rrip); void load_cg_row(const TRectype& row); void load_cg_mov(); bool is_ripartible_movcg(); @@ -167,7 +170,7 @@ TToken_string& TMovanal_msk::get_rip_row(const TRectype& rrip) return row; } -void TMovanal_msk::split_cg_row(const TRectype& row, const TRecord_array& rrip) +void TMovanal_msk::split_cg_row(const TRectype& row, const TAnal_ripartizioni_batch& rrip) { // Importo totale da distribuire arrotondato ai decimali della valuta di conto TGeneric_distrib distrib(row.get_real(RMV_IMPORTO), TCurrency::get_firm_dec()); @@ -195,6 +198,79 @@ void TMovanal_msk::split_cg_row(const TRectype& row, const TRecord_array& rrip) } } +bool TMovanal_msk::multi_split_cg_row(const TRectype& row, const TAnal_ripartizioni_batch& rrip) +{ + bool splitted = true; + + //crea l'array con tutte le ripartizioni compatibili (sorelle) + + //1) crea lo sheet con codice e descrizione delle ripartizioni possibile + TArray_sheet lista_rips(-1, -1, 64, 16, TR("Scelta ripartizioni"), HR("Codice@8|Descrizione@50"), 0, 6); + //2) trova quante sono le ripartizioni possibili + const long nrips = rrip.find_sister_rips(lista_rips.rows_array()); + //3a) se le ripartizioni sono più di una mostra una maschera di scelta generata al volo con lo sheet dell'elenco.. + //..ripartizioni possibili e i dati della riga che propone il dilemma di scelta; la riga può essere contabile o.. + //..analitica in base al contesto in cui viene chiamata la multi_split_cg_row() + if (nrips > 1) + { + //campi comuni ai 2 casi + lista_rips.add_number(201, 0, "N.Riga ", 1, 0, 3, "D"); + lista_rips.add_string(202, 0, "Descriz. ", 1, 1, 50, "D"); + lista_rips.add_string(209, 0, "Importo ", 1, 3, 1, "D"); + lista_rips.add_currency(210, 0, "", 14, 3, 18, "D"); + + switch (row.num()) + { + case LF_RMOV: //metodo chiamato in fase di registrazione del movimento in CG + { + lista_rips.add_number(203, 0, "Gruppo ", 1, 2, 3, "D"); + lista_rips.add_number(204, 0, "Conto ", 16, 2, 3, "D"); + lista_rips.add_number(205, 0, "Sottoconto ", 30, 2, 6, "D"); + + lista_rips.set(201, row.get(RMV_NUMRIG)); + lista_rips.set(202, row.get(RMV_DESCR)); + lista_rips.set(203, row.get(RMV_GRUPPO)); + lista_rips.set(204, row.get(RMV_CONTO)); + lista_rips.set(205, row.get(RMV_SOTTOCONTO)); + lista_rips.set(209, row.get(RMV_SEZIONE)); + lista_rips.set(210, row.get(RMV_IMPORTO)); + } + break; + + case LF_RMOVANA: //metodo chiamato in fase di registrazione del movimento in CA + { + lista_rips.add_string(203, 0, "Conto ", 1, 2, 20, "D"); + lista_rips.add_string(204, 0, "Commessa ", 1, 4, 20, "D"); + lista_rips.add_string(205, 0, "C. Costo ", 1, 5, 20, "D"); + + lista_rips.set(201, row.get(RMOVANA_NUMRIG)); + lista_rips.set(202, row.get(RMOVANA_DESCR)); + lista_rips.set(203, row.get(RMOVANA_CODCONTO)); + lista_rips.set(204, row.get(RMOVANA_CODCMS)); + lista_rips.set(205, row.get(RMOVANA_CODCCOSTO)); + lista_rips.set(209, row.get(RMOVANA_SEZIONE)); + lista_rips.set(210, row.get(RMOVANA_IMPORTO)); + } + break; + default: + break; + } + + + splitted = lista_rips.run() == K_ENTER; + if (splitted) + { + TAnal_ripartizioni_batch selected_rip; + selected_rip.read('I', lista_rips.row().get(0)); + split_cg_row(row, selected_rip); + } + } + else + split_cg_row(row, rrip); + + return splitted; +} + bool TMovanal_msk::is_ripartible_movcg() { bool ok = true; @@ -210,25 +286,12 @@ bool TMovanal_msk::is_ripartible_movcg() const TBill zio(row); if (zio.is_analitico()) { - int i; - for (i = 3; i > 0; i--) - { - query = "USE RIP SELECT"; - query << " (GRUPPO=" << zio.gruppo() << ')'; // Il gruppo c'e' sempre - const int conto = i > 1 ? zio.conto() : 0; // Il conto c'e' per i = 2 o 3 - query << "&&(CONTO=" << conto << ')'; - if (conto > 0) - { - const long sotto = i > 2 ? zio.sottoconto() : 0; // Il sottoconto c'e' per i = 3 - query << "&&(SOTTOCONTO=" << sotto << ')'; - } - query << "\nFROM TIPO='I'\nTO TIPO='I'"; + //se il conto è valido per l'analitica cerca,nell'annoes indicato, delle ripartizioni pertinenti a tale conto + const int annoes = row.get_int(RMV_ANNOES); + const TAnal_ripartizioni_batch& rrip = _cache_rip.righe_interattive(zio, annoes); + const long rrip_items = rrip.rows(); - TISAM_recordset rs(query); - if (rs.items() > 0) // Ho trovato la ripartizione! - break; - } - if (i <= 0) // Non trovato la ripartizione + if (rrip_items <= 0) // Non trovato una ripartizione valida per il povero conto { ok = error_box(FR("Non esiste una ripartizione del conto %d.%d.%ld\n" "presente sulla riga %d del movimento %ld"), @@ -244,54 +307,44 @@ bool TMovanal_msk::is_ripartible_movcg() void TMovanal_msk::load_cg_row(const TRectype& row) { - // Cerco la ripartizione del sottoconto, se non la trovo uso quella del conto o del gruppo - TString query; - int i; - for (i = 3; i > 0; i--) + //se il conto è valido per l'analitica cerca,nell'annoes indicato, delle ripartizioni pertinenti a tale conto + const TBill zio(row); + if (zio.is_analitico()) { - query = "USE RIP SELECT"; - query << " (GRUPPO=" << row.get(RMV_GRUPPO) << ')'; // Il gruppo c'e' sempre - const int conto = i > 1 ? row.get_int(RMV_CONTO) : 0; // Il conto c'e' per i = 2 o 3 - query << "&&(CONTO=" << conto << ')'; - if (conto > 0) - { - const long sotto = i > 2 ? row.get_long(RMV_SOTTOCONTO) : 0; // Il sottoconto c'e' per i = 3 - query << "&&(SOTTOCONTO=" << sotto << ')'; - } - query << "\nFROM TIPO='I'\nTO TIPO='I'"; + const int annoes = row.get_int(RMV_ANNOES); + const TAnal_ripartizioni_batch& rrip = _cache_rip.righe_interattive(zio, annoes); + const long rrip_items = rrip.rows(); - TISAM_recordset rs(query); - if (rs.items() > 0) // Ho trovato la ripartizione: evviva! + bool splitted = rrip_items > 0; + if (splitted) { - TString16 codice = rs.get("CODICE").as_string(); - codice.insert("I|"); - TRecord_array rrip(codice, LF_RRIP); // Carico le righe di ripartizione - if (rrip.rows() > 0) - { + //se sa che ci sono varie ripartizioni interattive relative a questo conto deve trovarne la lista e cercare la.. + //..più adatta all'utonto + if (rrip.has_multirip()) + splitted = multi_split_cg_row(row, rrip); + else //se invece c'è una sola ripartizione possibile la applica e via! split_cg_row(row, rrip); - break; - } } - } - if (i == 0) // Non ho trovato nessuno schema di ripartizione valido - { - // Creo una riga nuova - TSheet_field& sheet = sfield(F_RIGHE); - TToken_string& riga = sheet.row(-1); - const TImporto imp(row.get_char(RMV_SEZIONE), row.get_real(RMV_IMPORTO)); - imp2row(imp, riga); // Ci copio l'importo - riga.add(row.get(RMV_DESCR), 2); // e la descrizione della riga contabile - - if (_use_pdc) + if (!splitted) // Non ho trovato nessuno schema di ripartizione valido { - TMask_field* f = sheet.sheet_mask().find_by_fieldname(RMOVANA_CODCONTO); - const int pos = sheet.cid2index(f->dlg()); - TString8 str; - str = row.get(RMV_GRUPPO); str.right_just(3, '0'); riga.add(str, pos-2); - str = row.get(RMV_CONTO); str.right_just(3, '0'); riga.add(str, pos-1); - str = row.get(RMV_SOTTOCONTO); str.right_just(6, '0'); riga.add(str, pos); - } - } + // Creo una riga nuova + TSheet_field& sheet = sfield(F_RIGHE); + TToken_string& riga = sheet.row(-1); + const TImporto imp(row.get_char(RMV_SEZIONE), row.get_real(RMV_IMPORTO)); + imp2row(imp, riga); // Ci copio l'importo + riga.add(row.get(RMV_DESCR), 2); // e la descrizione della riga contabile + + if (_use_pdc) + { + TMask_field* f = sheet.sheet_mask().find_by_fieldname(RMOVANA_CODCONTO); + const int pos = sheet.cid2index(f->dlg()); + TString8 str; + str = row.get(RMV_GRUPPO); str.right_just(3, '0'); riga.add(str, pos-2); + str = row.get(RMV_CONTO); str.right_just(3, '0'); riga.add(str, pos-1); + str = row.get(RMV_SOTTOCONTO); str.right_just(6, '0'); riga.add(str, pos); + } + } //else di rrip_items > 0... + } //if(zio.is_analitico(... } // A partire dal movimento contabile calcola il totale documento ed eventualmente prepara lo sheet diff --git a/ca/ca2100a.uml b/ca/ca2100a.uml index 08b500684..84aa4fb4e 100755 --- a/ca/ca2100a.uml +++ b/ca/ca2100a.uml @@ -301,17 +301,23 @@ TOOLBAR "topbar" 0 0 0 2 BUTTON DLG_OK 10 2 BEGIN - PROMPT -13 -1 "" + PROMPT -14 -1 "" +END + +BUTTON DLG_USER 10 2 +BEGIN + PROMPT -24 -1 "Ripartisce" + PICTURE TOOL_MULTISEL END BUTTON DLG_DELREC 10 2 BEGIN - PROMPT -23 -1 "" + PROMPT -34 -1 "" END BUTTON DLG_CANCEL 10 2 BEGIN - PROMPT -33 -1 "" + PROMPT -44 -1 "" END ENDPAGE @@ -462,30 +468,35 @@ BEGIN GROUP 1 END +TEXT DLG_NULL +BEGIN + PROMPT 1 20 "@bValori originali pre-ripartizione" +END + STRING S_CDC_ORI 20 BEGIN - PROMPT 1 20 "Cdc.Ori" + PROMPT 1 21 "Cdc " FLAGS "D" FIELD CODCCORI END STRING S_CMS_ORI 20 BEGIN - PROMPT 21 20 "Cms.Ori" + PROMPT 27 21 "Cms " FLAGS "D" FIELD CODCMSORI END STRING S_FAS_ORI 20 BEGIN - PROMPT 41 20 "Fase Ori" + PROMPT 53 21 "Fase " FLAGS "D" FIELD CODFASEORI END STRING S_CON_ORI 20 BEGIN - PROMPT 61 20 "Conto Ori." + PROMPT 1 22 "Conto " FLAGS "D" FIELD CODCONTORI END diff --git a/ca/calib01.cpp b/ca/calib01.cpp index 613902c1c..19fb4cfc0 100755 --- a/ca/calib01.cpp +++ b/ca/calib01.cpp @@ -1733,14 +1733,56 @@ int TAnal_ripartizioni_batch::read (const char tiporip, const int gr, const int } } + _multirip = false; if (err == NOERR) - err = read(tiporip, rip.get(RIP_CODICE)); //per chiave 3 sia tiporip=P che tiporip=B + { + err = read(tiporip, rip.get(RIP_CODICE)); //per chiave 3 sia tiporip=P che tiporip=I + const TString curr_key = rip.curr().build_key(3); + //cerca eventuali altre ripartizioni sorelle (con codice diverso ma stessi parametri) + if (rip.next() == NOERR) + { + const TString next_key = rip.curr().build_key(3); + _multirip = curr_key == next_key; + } + } return err; } -TAnal_ripartizioni_batch::TAnal_ripartizioni_batch() : TRecord_array (LF_RRIP, RRIP_NRIGA), _rip(LF_RIP) + +int TAnal_ripartizioni_batch::find_sister_rips(TString_array& lista_rips) const +{ + lista_rips.destroy(); + TToken_string key; + //ci sono più ripartizioni possibili... + if (has_multirip()) + { + //relazione e cursore su chiave 3 (TIPO+GRUPPO+CONTO+SOTTOCONTO+ANNOES+INDBIL+CLASSEMOV) sul file LF_RIP alla.. + //..ricerca di eventuali ripartizioni sorelle + TRelation rel_rip(LF_RIP); + TCursor cur_rip(&rel_rip, "", 3, &head(), &head()); + for (cur_rip = 0; cur_rip.pos() < cur_rip.items(); ++cur_rip) + { + key.cut(0); + key.add(cur_rip.curr().get(RIP_CODICE)); + key.add(cur_rip.curr().get(RIP_DESCRIZ)); + lista_rips.add(key); + } + } + else //c'è solo una ripartizione + { + key.add(head().get_long(RIP_CODICE)); + key.add(head().get(RIP_DESCRIZ)); + lista_rips.add(key); + } + + //restituisce il numero di ripartizioni trovate (nel TString_array c'è l'elenco) + return lista_rips.items(); +} + + +TAnal_ripartizioni_batch::TAnal_ripartizioni_batch() + : TRecord_array (LF_RRIP, RRIP_NRIGA), _rip(LF_RIP), _multirip(false) { - } /////////////////////////////////////////////////////////// @@ -1842,6 +1884,7 @@ void TCache_ripartizioni::set_esercizio(const int codes) } } + const TAnal_ripartizioni_batch& TCache_ripartizioni::righe(const char* costo, const char* commessa, const char* fase, const int annoes, const int indbil, const char tipomov) { @@ -1909,11 +1952,13 @@ const TAnal_ripartizioni_batch& TCache_ripartizioni::righe_interattive(const TBi return *(const TAnal_ripartizioni_batch*)objptr(parametro); } + TCache_ripartizioni::TCache_ripartizioni() { _codes = 0; } + /////////////////////////////////////////////////////////// // Metodi per la ricompattazione delle righe ripartite /////////////////////////////////////////////////////////// diff --git a/ca/calib01.h b/ca/calib01.h index f9ae09df0..e3236e69d 100755 --- a/ca/calib01.h +++ b/ca/calib01.h @@ -168,6 +168,8 @@ class TAnal_bill; class TAnal_ripartizioni_batch : public TRecord_array { TRectype _rip; + bool _multirip; + private: int read_rip_3(TLocalisamfile& rip, const char tiporip, const int gr, const int co, const long sot, const int annoes, const int indbil, const int classe_mov) const; @@ -177,10 +179,12 @@ public: const TRectype& head() const { return _rip; } int indbil() const; char tiporip() const; - int read (const char tiporip, const char* codice); - int read (const char* codcosto, const char* commessa, const char* fase, const int annoes, const int indbil, const int classe_mov); - int read (const char tiporip, const int gr, const int co, const long sot, const int annoes, const int indbil, const int classe_mov); - + int read(const char tiporip, const char* codice); + int read(const char* codcosto, const char* commessa, const char* fase, const int annoes, const int indbil, const int classe_mov); + int read(const char tiporip, const int gr, const int co, const long sot, const int annoes, const int indbil, const int classe_mov); + bool has_multirip() const { return _multirip; } + int find_sister_rips(TString_array& lista_rips) const; + TAnal_ripartizioni_batch(); }; @@ -208,7 +212,7 @@ public: //interattive per conversione e contabilizzazione (usate da cacnv e da contabilizzazione analitica docs) const TAnal_ripartizioni_batch& righe_interattive(const TBill& bill, const int annoes, const char tipomov = ' '); - TCache_ripartizioni(); + TCache_ripartizioni(); }; // metodi di implosione movimenti ripartiti!! Serve nel ribaltamento movimenti, stampa rendiconto...