#include #include #include #include #include #include #include #include #include #include #include #include "../cg/cgsaldac.h" #include "../ef/ef0301.h" #include "ef0.h" #include "ef0A00a.h" #include /////////////////////////////////////////////////////////// // Main Mask /////////////////////////////////////////////////////////// class TPE_mask : public TAutomask { protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); bool on_sheet_event(TOperable_field& o, TField_event e, long jolly); public: bool calc_residual(const TRiga_scadenze& scad, real& impres, real& imppag, char& accsal, int& rdist, int& reff) const; bool fill_rate(); void update_total(); TRectype& new_row_effetto(TDistinta& dist, char tipocf, long codcf, int& rigadist, int& rigaeff) const; void save_rate(); void print(); TPE_mask() : TAutomask("ef0A00a") { } virtual ~TPE_mask() { } }; // Calcola il residuo di una rata tenendo conto anche degli eventuali // effetti non ancora contabilizzati bool TPE_mask::calc_residual(const TRiga_scadenze& scad, real& impres, real& imppag, char& accsal, int& rdist, int& reff) const { TRelation rel(LF_REFFETTI); rel.add(LF_EFFETTI, "NPROGTR==NPROGTR"); TRectype& filter = rel.curr(); const char* field[] = { SCAD_ANNO, SCAD_NUMPART, SCAD_NRIGA, SCAD_NRATA, NULL }; for (int i = 0; field[i]; i++) filter.put(field[i], scad.get(field[i])); TCursor cur(&rel, "", 2, &filter, &filter); const char tipocf = scad.get_char(SCAD_TIPOCF); const long codcf = scad.get_long(SCAD_SOTTOCONTO); TString expr; expr << '(' << LF_EFFETTI << "->EFFCONT!=\"X\")&&"; expr << '(' << LF_EFFETTI << "->TIPOCF==\"" << tipocf << "\")&&"; expr << '(' << LF_EFFETTI << "->CODCF==\"" << codcf << "\")"; cur.setfilter(expr, TRUE); const long items = cur.items(); const bool valuta = scad.in_valuta(); impres = scad.residuo(TRUE).valore(); imppag = ZERO; accsal = 'A'; rdist = reff = 0; if (items > 0L) { cur.freeze(); const TRectype& riga = cur.curr(); const TRectype& effe = cur.curr(LF_EFFETTI); for (cur = 0L; cur.pos() < items; ++cur) { if (effe.get(EFF_TIPODIST) == get(F_TIPODIST) && effe.get(EFF_NDIST) == get(F_DIST)) { rdist = effe.get_int(EFF_NRIGADIST); reff = riga.get_int(REFF_NRIGATR); accsal = riga.get_char(REFF_ACCSAL); imppag += riga.get_real(valuta ? REFF_IMPORTOVAL : REFF_IMPORTO); } else { if (riga.get_char(REFF_ACCSAL) == 'S') { impres = ZERO; break; } impres -= riga.get_real(valuta ? REFF_IMPORTOVAL : REFF_IMPORTO); } } } return !impres.is_zero(); } void TPE_mask::update_total() { real tot, val; TSheet_field& s = sfield(F_SHEET); const int postot = s.cid2index(F_IMPORTO); FOR_EACH_SHEET_ROW_BACK(s, r, row) tot += real(row->get(postot)); set(F_TOTAL, tot); } bool TPE_mask::fill_rate() { const long ndist = get_long(F_DIST); const TDate dadata = get(F_DA_DATA); const TDate adata = get(F_A_DATA); const TString& codval = get(F_CODVAL); TSheet_field& sheet = sfield(F_SHEET); sheet.destroy(); TRelation rel(LF_PARTITE); TRectype filter(LF_PARTITE); filter.put(PART_TIPOCF, get(F_TIPOCF)); filter.put(PART_GRUPPO, 0); filter.put(PART_CONTO, 0); filter.put(PART_SOTTOCONTO, get(F_CLIFO)); TCursor partite(&rel, "", 1, &filter, &filter); TString filtro; filtro << "(CHIUSA!=\"X\")&&(CODVAL==\"" << codval << "\")"; partite.setfilter(filtro, TRUE); long items = partite.items(); if (items == 0) return FALSE; TRectype& partita = partite.curr(); TProgind pi(items, "Caricamento partite aperte", FALSE, TRUE); if (items > 900) items = 900; partite.freeze(); long last_cf = 0; int last_year = 0; TString16 last_game; TString last_ragsoc; for (partite = 0L; partite.pos() < items; ++partite) { pi.addstatus(1); const long cur_cf = partita.get_long(PART_SOTTOCONTO); const int cur_year = partita.get_int(PART_ANNO); const TString& cur_game = partita.get(PART_NUMPART); if (cur_cf == last_cf && cur_year == last_year && cur_game == last_game) continue; last_year = cur_year; last_game = cur_game; if (cur_cf != last_cf) { last_cf = cur_cf; TString16 cod; cod << get(F_TIPOCF) << '|' << last_cf; last_ragsoc = cache().get(LF_CLIFO, cod, CLI_RAGSOC); } const TPartita game(partita); const int last = game.last(); for (int riga = game.prima_fattura(); riga > 0 && riga <= last; riga++) { const TRiga_partite& rp = game.riga(riga); if (rp.is_fattura()) { for (int rata = 1; rata <= rp.rate(); rata++) { const TRiga_scadenze& rs = rp.rata(rata); if (!rs.chiusa()) { const TDate data = rs.get(SCAD_DATASCAD); if (data >= dadata && (!adata.ok() || data <= adata)) { real impres, imppag; char accsal; int rigadist, rigaeff; bool ok = calc_residual(rs, impres, imppag, accsal, rigadist, rigaeff); if (ok) { TToken_string& row = sheet.row(-1); row.add(imppag.string()); row.add(accsal); row.add(impres.string()); row.add(last_cf); row.add(last_ragsoc); row.add(game.anno()); row.add(game.numero()); row.add(riga); row.add(rata); row.add(data); row.add(rigadist); row.add(rigaeff); } } } } } } } sheet.force_update(); update_total(); const int righe = sheet.items(); const bool canedit = righe > 0; enable(-5, canedit); return canedit; } TRectype& TPE_mask::new_row_effetto(TDistinta& dist, char tipocf, long codcf, int& rigadist, int& rigaeff ) const { TString16 codice; codice << tipocf << '|' << codcf; const bool ragg = cache().get(LF_CFVEN, codice, CFV_RAGGEFF).not_empty(); TEffetto* neweff = NULL; if (ragg) { for (int i = 0; i < dist.items(); i++) { TEffetto& eff = dist[i]; if (eff.get_char(EFF_TIPOCF) == tipocf && eff.get_long(EFF_CODCF) == codcf) { neweff = &eff; rigadist = i+1; break; } } } if (neweff == NULL) { neweff = new TEffetto; dist.righe().add(neweff); rigadist = dist.items(); neweff->put(EFF_TIPOCF, tipocf); neweff->put(EFF_CODCF, codcf); neweff->put(EFF_TIPOCF, get(F_TIPOCF)); neweff->put(EFF_CODVAL, get(F_CODVAL)); neweff->put(EFF_CAMBIO, get(F_CAMBIO)); neweff->put(EFF_DATACAMBIO, get(F_DATADIST)); } rigaeff = neweff->rows_r()+1; return neweff->row_r(rigaeff, TRUE); } void TPE_mask::save_rate() { const TString& codval = get(F_CODVAL); const real cambio = get(F_CAMBIO); const char tipodist = get(F_TIPODIST)[0]; const long numdist = get_long(F_DIST); TDistinta distinta(tipodist, numdist, _lock); bool zeroes = FALSE; // Esistono righe effetto da cancellare TSheet_field& sheet = sfield(F_SHEET); FOR_EACH_SHEET_ROW(sheet, r, row) { real imp = row->get(sheet.cid2index(F_IMPORTO)); real impval; if (codval.not_empty() && !imp.is_zero()) { impval = imp; TCurrency c(impval, codval, cambio); c.change_to_firm_val(); imp = c.get_num(); } char accsal = row->get_char(sheet.cid2index(F_ACCSAL)); int rigadist = row->get_int(sheet.cid2index(F_RIGADIST)); int rigaeff = row->get_int(sheet.cid2index(F_RIGAEFF)); if (rigaeff > 0 || accsal == 'S' || imp > ZERO) { if (rigaeff <= 0) { char tipocf = get(F_TIPOCF)[0]; long codcf = row->get_long(sheet.cid2index(F_CODCF)); TRectype& reff = new_row_effetto(distinta, tipocf, codcf, rigadist, rigaeff); reff.put(REFF_ANNO, row->get(sheet.cid2index(F_ANNO))); reff.put(REFF_NUMPART, row->get(sheet.cid2index(F_PARTITA))); reff.put(REFF_NRIGA, row->get(sheet.cid2index(F_RIGA))); reff.put(REFF_NRATA, row->get(sheet.cid2index(F_RATA))); TToken_string key; key.add(get(F_TIPOCF)); key.add("0|0"); key.add(row->get(sheet.cid2index(F_CODCF))); key.add(row->get(sheet.cid2index(F_ANNO))); key.add(row->get(sheet.cid2index(F_PARTITA))); key.add(row->get(sheet.cid2index(F_RIGA))); key.add(row->get(sheet.cid2index(F_RATA))); const TRectype& scad = cache().get(LF_SCADENZE, key); TString16 abi = scad.get(SCAD_CODABI); TString16 cab = scad.get(SCAD_CODCAB); if (atol(cab) == 0L) { key = get(F_TIPOCF); key.add(row->get(sheet.cid2index(F_CODCF))); const TRectype& clifo = cache().get(LF_CLIFO, key); abi = clifo.get(CLI_CODABI); cab = clifo.get(CLI_CODCAB); } TEffetto& eff = distinta[rigadist-1]; eff.put(EFF_DATASCAD, scad.get(SCAD_DATASCAD)); eff.put(EFF_CODABI, abi); eff.put(EFF_CODCAB, cab); } TEffetto& eff = distinta[rigadist-1]; TRectype& reff = eff.row_r(rigaeff); real oldimp = reff.get(REFF_IMPORTO); real oldimpval = reff.get(REFF_IMPORTOVAL); reff.put(REFF_IMPORTO, imp); reff.put(REFF_IMPORTOVAL, impval); reff.put(REFF_ACCSAL, accsal); if (imp.is_zero() && accsal != 'S') { reff.put(REFF_ACCSAL, 'Z'); // Segna la riga come NULLA zeroes = TRUE; } } } // Ricalcola totali righe ed elimina le righe NULLE for (int rd = distinta.items()-1; rd >= 0; rd--) { TEffetto& eff = distinta[rd]; real totimp, totimpval; for (int i = eff.rows_r(); i > 0; i--) { const TRectype& reff = eff.row_r(i); if (reff.get_char(REFF_ACCSAL) == 'Z') eff.destroy_row_r(i, TRUE); else { totimp += reff.get_real(EFF_IMPORTO); totimpval += reff.get_real(EFF_IMPORTOVAL); } } if (eff.rows_r() == 0) distinta.righe().destroy(rd, TRUE); else { eff.put(EFF_IMPORTO, totimp); eff.put(EFF_IMPORTOVAL, totimpval); eff.put(EFF_TIPOPAG, get(F_TIPOPAG)); } } TToken_string dati_dist; dati_dist.add(tipodist); dati_dist.add(numdist); dati_dist.add(get(F_DATADIST)); dati_dist.add(get(F_ABI)); dati_dist.add(get(F_CAB)); distinta.write(FALSE, &dati_dist); } void TPE_mask::print() { TString16 cmd; cmd << "ef0 -4 " << get(F_TIPODIST) << ' ' << get(F_DIST); TExternal_app app(cmd); app.run(); } bool TPE_mask::on_sheet_event(TOperable_field& o, TField_event e, long jolly) { TMask& m = o.mask(); switch (o.dlg()) { case F_IMPORTO: if (e == fe_modify) { if (m.get_real(F_IMPORTO) >= m.get_real(F_RESIDUO)) m.set(F_ACCSAL, "S"); } break; case F_PAGA: if (e == fe_button) { TMask& m = o.mask(); if (m.get_real(F_IMPORTO).is_zero()) { m.set(F_IMPORTO, m.get(F_RESIDUO)); m.set(F_ACCSAL, "S"); } else { m.reset(F_IMPORTO); m.reset(F_ACCSAL); } } break; case F_SHEET: switch(e) { case se_query_add: { TOperable_field& baggio = (TOperable_field&)field(F_AGGIORNA); if (baggio.active()) on_field_event(baggio, fe_button, 0); } return FALSE; case se_notify_modify: update_total(); break; default: break; } default: break; } return TRUE; } bool TPE_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case DLG_NEWREC: { TLocalisamfile eff(LF_EFFETTI); eff.setkey(4); TRectype& curr = eff.curr(); curr.put(EFF_TIPODIST, get(F_TIPODIST)); curr.put(EFF_NDIST, 9999999L); const int err = eff.read(_isgreat); long n = 1L; if (err != _isemptyfile) { if (err == NOERR) eff.prev(); if (curr.get(EFF_TIPODIST) == get(F_TIPODIST)) n += curr.get_long(EFF_NDIST); } set(F_DIST, n); } break; case F_DIST: if (e == fe_modify) { TEdit_field& ef = (TEdit_field&)o; bool ok = ef.check(); if (ok) { const TCursor& cur = *ef.browse()->cursor(); ok = cur.ok(); if (ok) { const TRectype& rec = cur.curr(); if (rec.get_bool(EFF_EFFCONT)) return error_box("La distinta %s e' gia' stata contabilizzata,\n" "per cui non e' possibile modificarla", (const char*)ef.get()); } } enable(-3, !ok); } break; case F_AGGIORNA: if (e == fe_button) { if (!field(F_DIST).empty()) { const bool full = fill_rate(); if (full) { disable(-3); disable(-4); } } else return error_box("E' necessario specificare un numero di distinta"); } break; case F_CONTABILI: if (e == fe_button) { TString16 cmd; cmd << "ef0 -7 " << get(F_TIPODIST) << ' ' << get(F_DIST); TExternal_app app(cmd); app.run(); stop_run(K_ESC); } break; case DLG_DELREC: if (e == fe_button && yesno_box("Confermate l'eliminazione della distinta %ld", get_long(F_DIST))) { TSheet_field& sheet = sfield(F_SHEET); FOR_EACH_SHEET_ROW(sheet, r, row) row->add("", 0); save_rate(); } break; case DLG_SAVEREC: if (e == fe_button) { if (check_fields()) { save_rate(); fill_rate(); } } break; case DLG_PRINT: if (e == fe_button) { print(); return FALSE; } break; case F_SHEET: return on_sheet_event(o, e, jolly); default: if (jolly > 0) return on_sheet_event(o, e, jolly); break; } return TRUE; } /////////////////////////////////////////////////////////// // Main Program /////////////////////////////////////////////////////////// class TPagamento_effetti : public TSkeleton_application { TPE_mask* _mask; public: virtual void main_loop(); virtual void print(); }; void TPagamento_effetti::main_loop() { open_files(LF_TABCOM, LF_TAB, LF_CLIFO, LF_CFVEN, LF_PARTITE, LF_SCADENZE, LF_PAGSCA, LF_EFFETTI, LF_REFFETTI, LF_CESS, 0); enable_menu_item(M_FILE_PRINT); _mask = new TPE_mask; do { _mask->reset(F_DIST); _mask->enable(-3); _mask->enable(-4); _mask->disable(-5); _mask->sfield(F_SHEET).destroy(); _mask->reset(F_TOTAL); } while (_mask->run() != K_QUIT); delete _mask; _mask = NULL; } void TPagamento_effetti::print() { if (_mask) _mask->print(); } int ef0A00(int argc, char* argv[]) { TPagamento_effetti pe; pe.run(argc, argv, "Distinte Pagamento"); return 0; }