#include #include #include #include #include #include #include #include "../sc/scselect.h" #include "../ve/velib.h" #include #include "sv1.h" #include "sv1100a.h" class TSchede_mask : public TSelection_mask { void init_sheet(short id); void ini2sheet(short id); void sheet2ini(short id); protected: static bool date_handler(TMask_field& f, KEY k); static bool num_handler(TMask_field& f, KEY k); static bool save_handler(TMask_field& f, KEY k); static bool sheet_notify(TSheet_field& s, int row, KEY k); static bool fieldname_handler(TMask_field& f, KEY k); public: void mask2ini(); void ini2mask(); TSchede_mask(); virtual ~TSchede_mask() { } }; bool TSchede_mask::date_handler(TMask_field& f, KEY k) { bool ok = TRUE; if (f.to_check(k)) { TMask& m = f.mask(); const TDate fd(m.get(F_FROMDATE)); const TDate td(m.get(F_TODATE)); if (td.ok() && td < fd) ok = f.error_box("La data finale deve seguire quella iniziale"); } return ok; } bool TSchede_mask::num_handler(TMask_field& f, KEY k) { bool ok = TRUE; if (f.to_check(k)) { TMask& m = f.mask(); const TString& fn = m.get(F_FROMNUM); const TString& tn = m.get(F_TONUM); if (tn.not_empty() && tn < fn) ok = f.error_box("La numerazione finale deve seguire quella iniziale"); } return ok; } bool TSchede_mask::save_handler(TMask_field& f, KEY k) { if (k == K_SPACE) { TSchede_mask& m = (TSchede_mask&)f.mask(); m.mask2ini(); } return TRUE; } bool TSchede_mask::fieldname_handler(TMask_field& f, KEY k) { if (f.to_check(k)) { TSchede_mask& m = (TSchede_mask&)f.mask(); TEdit_field& head = m.efield(S_HEAD); if (head.empty()) { TParagraph_string para(m.get(S_DESCR), head.size()); head.set(para.get(0)); } } return TRUE; } bool TSchede_mask::sheet_notify(TSheet_field& s, int row, KEY k) { bool ok = TRUE; switch(k) { case K_INS: ok = s.items() < 8; break; default: break; } return ok; } void TSchede_mask::sheet2ini(short id) { TSheet_field& sheet = sfield(id); TString_array& arr = sheet.rows_array(); for (int r = arr.last(); r >= 0; r--) if (arr.row(r)[0] <= ' ') arr.destroy(r); arr.pack(); const char* field = id == F_SINTETICA ? "SynField" : "DetField"; const char* head = id == F_SINTETICA ? "SynHead" : "DetHead"; TConfig ini(CONFIG_STUDIO, "sv1100"); for (r = arr.last(); r >= 0; r--) { TToken_string& row = arr.row(r); ini.set(field, row.get(0), NULL, TRUE, r); ini.set(head, row.get(), NULL, TRUE, r); } ini.remove(field, arr.items()); ini.remove(head, arr.items()); } void TSchede_mask::ini2sheet(short id) { TSheet_field& sheet = sfield(id); const char* field = id == F_SINTETICA ? "SynField" : "DetField"; const char* head = id == F_SINTETICA ? "SynHead" : "DetHead"; TConfig ini(CONFIG_STUDIO, "sv1100"); for (int r = 0; ; r++) { TString16 str = ini.get(field, NULL, r); if (str.not_empty()) { TToken_string& row = sheet.row(r); row = str; row.add(ini.get(head, NULL, r)); sheet.check_row(r); } else break; } } void TSchede_mask::mask2ini() { sheet2ini(F_SINTETICA); sheet2ini(F_DETTAGLIATA); } void TSchede_mask::ini2mask() { ini2sheet(F_SINTETICA); ini2sheet(F_DETTAGLIATA); } void TSchede_mask::init_sheet(short id) { TSheet_field& sheet = sfield(id); sheet.set_notify(sheet_notify); TMask& sm = sheet.sheet_mask(); sm.set_handler(S_FIELD, fieldname_handler); } TSchede_mask::TSchede_mask() : TSelection_mask("sv1100a") { set_handler(F_TODATE, date_handler); set_handler(F_TONUM, num_handler); set_handler(DLG_SAVEREC, save_handler); init_sheet(F_SINTETICA); init_sheet(F_DETTAGLIATA); ini2mask(); } /////////////////////////////////////////////////////////// // TSchede_form /////////////////////////////////////////////////////////// class TSchede_form : public TForm { public: void init(const TSheet_field& sheet); TSchede_form(); virtual ~TSchede_form() { } }; TSchede_form::TSchede_form() : TForm("sv1100a") { } void TSchede_form::init(const TSheet_field& sheet) { TPrint_section& body = section('B', odd_page); TString_array& arr = sheet.rows_array(); TString80 str; bool on = TRUE; for (word r = 3; r < body.fields(); r++) { const int riga = r-3; if (on) { if (riga < arr.items()) { str = arr.row(riga).get(0); on = str.not_empty(); } else on = FALSE; } TForm_item& item = body.field(r); if (!item.is_section()) { item.show(on); if (on) { str = arr.row(riga).get(1); item.set_col_head(str); } } } const TPrint_section& head = section('H', odd_page); const TPrint_section& foot = section('F', odd_page); const int hh = head.height(); const int fh = foot.height(); const int fl = printer().formlen(); int rows[4]; // Righe orizzontali rows[0] = hh-2; // Terzultima riga della testata rows[1] = hh; // Ultima riga della testata rows[2] = fl-fh+1; // Prima riga del footer rows[3] = 0; genera_fincatura(odd_page, rows[0], rows[2], rows); genera_intestazioni(odd_page, hh-1); } /////////////////////////////////////////////////////////// // Main app /////////////////////////////////////////////////////////// class TStampa_schede : public TApplication { TArray _file; char _tipo; // ettagliata o intetica char _sort; // attura o rticolo char _prov; //

rovvisori o efinitivi TDate _fromdate, _todate; // Date limite TString _fromnum, _tonum; // Numerazioni limite TArray _totali; // Totali complessivi TArray _totriga; // Totali di riga long _progressivo; // Numero progressivo di record per file di stampa TString _lastkey; // Ultima chiave del file di stampa temporaneo TSchede_mask* _mask; // Mask di stampa TSchede_form* _form; // Form di stampa protected: virtual bool menu(MENU_TAG mt); virtual bool create(); virtual bool destroy(); protected: void put_real(TRectype& tab, int index, real val, bool importo, const TDocumento& doc); void fill_key(TRectype& tab, const TDocumento& doc); void fill_key(TRectype& tab, const TRiga_documento& rdoc); public: void open_files(int logicnum, ...); bool fill_doc(TRectype& tab, const TDocumento& doc); bool fill_rdoc(TRectype& tab, const TRiga_documento& rdoc); void update_totriga(const TRectype& tab); void fill_totriga(TRectype& tab); void fill_tot(TRectype& tab); bool write_tab(TLocalisamfile& tab) const; bool write_totali_per_articolo(TLocalisamfile& tab); bool stampa_sintetica() const { return _tipo == 'S'; } bool stampa_dettagliata() const { return _tipo == 'D'; } bool stampa_per_articolo() const { return _sort == 'A'; } bool stampa_per_documento() const { return _sort == 'D'; } bool stampa_clifo(TCursor& cur, const TString& ragsoc); }; void TStampa_schede::put_real(TRectype& tab, int index, real val, bool importo, const TDocumento& doc) { char erre[4]; sprintf(erre, "R%d", index); if (importo && doc.in_valuta()) { val *= doc.cambio(); val.round(0); } tab.put(erre, val); real* r = (real*)_totali.objptr(index); if (r == NULL) _totali.add(val, index); else *r += val; } void TStampa_schede::fill_key(TRectype& tab, const TDocumento& doc) { tab.zero(); tab.put("COD", "PRN"); const TCli_for& clifo = doc.clifor(); tab.put("S8", clifo.tipo()); tab.put("I8", clifo.codice()); TString16 str; TString80 key; key = doc.data().string(ANSI); str = doc.numerazione(); str.left_just(4); key << str; str.format("%4d", doc.numero()); key << str; tab.put("S0", key); tab.put("CODTAB", ++_progressivo); } void TStampa_schede::fill_key(TRectype& tab, const TRiga_documento& rdoc) { fill_key(tab, rdoc.doc()); _lastkey = tab.get("S0"); _lastkey.left_just(20); if (stampa_per_articolo()) { TString80 str = rdoc.get(RDOC_CODART); str.left_just(20); _lastkey.insert(str, 0); } TString16 numero; numero.format("%4d", rdoc.numero()); _lastkey << numero; tab.put("S0", _lastkey); } bool TStampa_schede::fill_doc(TRectype& tab, const TDocumento& doc) { if (stampa_dettagliata()) return FALSE; fill_key(tab, doc); TString descr(80); const TTipo_documento& tipo = doc.tipo(); const TCodice_numerazione& num = doc.codice_numerazione(); descr << tipo.descrizione() << ' '; descr << num.prefisso(); descr << doc.numero(); descr << num.postfisso(); descr << " del " << doc.data(); tab.put("S1", descr); put_real(tab, 0, doc.totale_netto(), TRUE, doc); put_real(tab, 1, doc.totale_doc(), TRUE, doc); TSheet_field& sheet = _mask->sfield(F_SINTETICA); TString_array& arr = sheet.rows_array(); TString16 src; for (int r = 0; r < arr.items(); r++) { TToken_string& row = arr.row(r); src = row.get(0); if (src.blank()) break; const bool importo = row.get(3)[0] > ' '; real val = doc.get(src); put_real(tab, r+2, val, importo, doc); } return TRUE; } bool TStampa_schede::fill_rdoc(TRectype& tab, const TRiga_documento& rdoc) { if (stampa_sintetica()) return FALSE; switch(rdoc.tipo().tipo()) { case RIGA_MERCE : break; case RIGA_OMAGGI : break; case RIGA_PRESTAZIONI: break; default : return FALSE; } const TDocumento& doc = rdoc.doc(); fill_key(tab, rdoc); TString descr(80); descr << rdoc.get(RDOC_CODART) << ' '; descr << rdoc.get(RDOC_DESCR); tab.put("S1", descr); put_real(tab, 0, rdoc.importo(TRUE, FALSE, 0), TRUE, doc); put_real(tab, 1, rdoc.importo(TRUE, TRUE, 0), TRUE, doc); TSheet_field& sheet = _mask->sfield(F_DETTAGLIATA); TString_array& arr = sheet.rows_array(); TString16 src; for (int r = 0; r < arr.items(); r++) { TToken_string& row = arr.row(r); src = row.get(0); if (src.blank()) break; const bool importo = row.get(3)[0] > ' '; real val = rdoc.get(src); put_real(tab, r+2, val, importo, doc); } return TRUE; } void TStampa_schede::update_totriga(const TRectype& tab) { char erre[4]; for (int r = _totali.last(); r >= 0; r--) { sprintf(erre, "R%d", r); const real val(tab.get(erre)); real* tot = (real*)_totriga.objptr(r); if (tot == NULL) _totriga.add(val, r); else *tot += val; } } void TStampa_schede::fill_totriga(TRectype& tab) { tab.zero(); tab.put("COD", "PRN"); tab.put("CODTAB", ++_progressivo); _lastkey.overwrite("9999", _lastkey.len()-4); tab.put("S0", _lastkey); tab.put("S1", stampa_per_articolo() ? "Totale articolo" : "Totale documento"); tab.put("B8", TRUE); // Riga totale for (int r = _totriga.last(); r >= 0; r--) { char erre[4]; sprintf(erre, "R%d", r); tab.put(erre, (real&)_totriga[r]); } } void TStampa_schede::fill_tot(TRectype& tab) { tab.zero(); tab.put("COD", "PRN"); tab.put("CODTAB", ++_progressivo); tab.put("S0", "zzzzzzzzzzzzzzzzzzzz"); tab.put("S1", "Totale"); tab.put("B8", TRUE); // Riga totale for (int r = _totali.last(); r >= 0; r--) { char erre[4]; sprintf(erre, "R%d", r); tab.put(erre, (real&)_totali[r]); } } bool TStampa_schede::write_tab(TLocalisamfile& tab) const { int err = tab.write(); if (err != NOERR) error_box("Errore %d durante la scrittura sul file temporaneo", err); return err == NOERR; } bool TStampa_schede::write_totali_per_articolo(TLocalisamfile& tab) { bool ok = TRUE; TRectype& curtab = tab.curr(); const TRecfield key(curtab, "S0"); _lastkey.cut(0); _totriga.destroy(); for (int err = tab.first(); err == NOERR && ok; err = tab.next()) { if (_lastkey.not_empty() && _lastkey.compare((const char*)key, 20) != 0) { const TRecnotype pos = tab.recno(); fill_totriga(curtab); ok = write_tab(tab); tab.readat(pos); _totriga.destroy(); } _lastkey = (const char*)key; update_totriga(curtab); } if (ok && _lastkey.not_empty()) { fill_totriga(curtab); ok = write_tab(tab); } return ok; } bool TStampa_schede::stampa_clifo(TCursor& cur, const TString& ragsoc) { const long items = cur.items(); TString header(160); header = "Preparazione file temporaneo di stampa ..."; if (ragsoc.not_empty()) header << '\n' << ragsoc; TProgind pi(items, header, TRUE, TRUE, 60); cur.file().set_curr(new TDocumento); TDocumento& doc = (TDocumento&)cur.file().curr(); TIsamtempfile* tab = new TIsamtempfile(LF_TAB, "svschede", TRUE); tab->set_autodel(TRUE); tab->setkey(2); _form->relation()->replace(tab); TRectype& curtab = tab->curr(); _totali.destroy(); _progressivo = 0; bool can_print = TRUE; for (cur = 0; cur.pos() < items && can_print; ++cur) { pi.addstatus(1); if (pi.iscancelled()) { can_print = FALSE; break; } if (stampa_sintetica()) { if (fill_doc(curtab, doc)) can_print = write_tab(*tab); } else { _totriga.destroy(); for (int r = doc.physical_rows(); r > 0 && can_print; r--) { const TRiga_documento& rdoc = doc[r]; if (fill_rdoc(curtab, rdoc)) { can_print = write_tab(*tab); if (stampa_per_documento()) update_totriga(curtab); } } if (can_print && _totriga.items() > 0) { fill_totriga(curtab); can_print = write_tab(*tab); } } } if (can_print && stampa_per_articolo()) can_print = write_totali_per_articolo(*tab); if (can_print) { fill_tot(curtab); can_print = write_tab(*tab); } pi.close_modal(); if (can_print && tab->items() > 0) { _form->print(); } _form->relation()->replace(new TLocalisamfile(LF_TAB)); return can_print; } bool TStampa_schede::menu(MENU_TAG mt) { TSchede_mask& m = *_mask; while (m.run() != K_QUIT) { _tipo = m.get(F_TIPO)[0]; _sort = m.get(F_ORDINE)[0]; _prov = m.get(F_PROVVIS)[0]; _fromdate = m.get_date(F_FROMDATE); _todate = m.get_date(F_TODATE); _fromnum = m.get(F_FROMNUM); _tonum = m.get(F_TONUM); _form->init(m.sfield(stampa_dettagliata() ? F_DETTAGLIATA : F_SINTETICA)); TString filter(80); if (_fromdate.ok()) { if (filter.not_empty()) filter << "&&"; filter << "(ANSI(" << DOC_DATADOC << ")>=\"" << _fromdate.string(ANSI) << "\")"; } if (_todate.ok()) { if (filter.not_empty()) filter << "&&"; filter << "(ANSI(" << DOC_DATADOC << ")<=\"" << _todate.string(ANSI) << "\")"; } if (_fromnum.not_empty()) { if (filter.not_empty()) filter << "&&"; filter << '(' << DOC_CODNUM << ">=\"" << _fromnum << "\")"; } if (_tonum.not_empty()) { if (filter.not_empty()) filter << "&&"; filter << '(' << DOC_CODNUM << "<=\"" << _tonum << "\")"; } const TCursor_sheet& clifosheet = m.cur_sheet(); TCursor& clifocur = *clifosheet.cursor(); const long clifos = clifocur.items(); const bool all = clifosheet.checked() == 0; TRelation rel(LF_DOC); TRectype rec(LF_DOC); TString ragsoc(80); bool cancel = FALSE; if (all) { TString msg; msg.format("Attenzione: e' stata selezionata la stampa di tutti i %s!\n" "Si desidera continuare ugualmente?", m.get_who() == 'C' ? "clienti" : "fornitori"); cancel = !yesno_box(msg); } for (clifocur = 0; clifocur.pos() < clifos && !cancel; ++clifocur) { if (all || clifosheet.checked(clifocur.pos())) { const long codcf = clifocur.file().get_long(CLI_CODCF); ragsoc = m.get_who() == 'C' ? "Cliente" : "Fornitore"; ragsoc << ' ' << codcf << " - " << clifocur.file().get(CLI_RAGSOC); rec.put(DOC_TIPOCF, m.get_who()); rec.put(DOC_CODCF, codcf); rec.put(DOC_PROVV, _prov); // Uso la chiave 2: TIPOCF+CODCF+PROVV+ANNO+DATADOC+CODNUM+NDOC TCursor cur(&rel, filter, 2, &rec, &rec); if (cur.items() > 0) { cur.freeze(); cancel = !stampa_clifo(cur, ragsoc); cur.freeze(FALSE); } } } } return FALSE; } void TStampa_schede::open_files(int logicnum, ...) { va_list marker; va_start(marker, logicnum); while (logicnum > 0) { CHECKD(_file.objptr(logicnum) == NULL, "File gia' aperto: ", logicnum); _file.add(new TLocalisamfile(logicnum), logicnum); logicnum = va_arg(marker, int); } } bool TStampa_schede::create() { open_files(LF_TABCOM, 0); // File comuni open_files(LF_TAB, LF_CLIFO, LF_OCCAS, 0); // File ditta open_files(LF_CFVEN, LF_DOC, LF_RIGHEDOC, 0); // File vendite _mask = new TSchede_mask; _form = new TSchede_form; dispatch_e_menu(BAR_ITEM(1)); return TRUE; } bool TStampa_schede::destroy() { delete _form; delete _mask; _file.destroy(); return TRUE; } int sv1100(int argc, char* argv[]) { TStampa_schede app; app.run(argc, argv, "Stampa schede"); return 0; }