From 07bcd60df87e86026180065165fe0194f29abf30 Mon Sep 17 00:00:00 2001 From: guy Date: Thu, 8 Aug 1996 09:24:17 +0000 Subject: [PATCH] Cominciata nuova stesura del programma di fatturazione bolle e corrette le tabelle usate. git-svn-id: svn://10.65.10.50/trunk@3339 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- ve/batbeld.h | 8 +- ve/batbeld.uml | 110 +++-- ve/batbnum.uml | 116 +----- ve/ve6200.cpp | 1060 ++---------------------------------------------- ve/ve6300.cpp | 424 ------------------- ve/velib01.cpp | 201 +++++++++ ve/velib01.h | 82 ++++ 7 files changed, 411 insertions(+), 1590 deletions(-) create mode 100755 ve/velib01.cpp create mode 100755 ve/velib01.h diff --git a/ve/batbeld.h b/ve/batbeld.h index 1e5f036d1..455d7e0b7 100755 --- a/ve/batbeld.h +++ b/ve/batbeld.h @@ -2,7 +2,8 @@ #define F_CODICE 101 #define F_DESCR 102 #define F_TIPO 103 -#define F_CODNUM 104 +#define F_CODNUM_I 104 +#define F_CODNUM_F 105 #define F_TIPODOC_I_1 111 #define F_STATO_I_DOC_I_1 121 #define F_STATO_F_DOC_I 131 @@ -16,3 +17,8 @@ #define F_STATO_I_DOC_I_5 125 #define F_TIPODOC_F 140 #define F_STATO_F_DOC_F 141 +#define F_DOC1 151 +#define F_DOC2 152 +#define F_DOC3 153 +#define F_DOC4 154 +#define F_DOC5 155 diff --git a/ve/batbeld.uml b/ve/batbeld.uml index 5cdaadc00..a9d45e854 100755 --- a/ve/batbeld.uml +++ b/ve/batbeld.uml @@ -26,7 +26,6 @@ BEGIN OUTPUT F_DESCR S0 KEY 1 HELP "Codice dell'elaborazione differita da eseguire" - MESSAGE ENABLE, F_PROGRAMMA END STRING F_DESCR 50 @@ -53,27 +52,78 @@ BEGIN ITEM "TC|Trasferimento a contabilita'" END -GROUPBOX DLG_NULL 78 5 +GROUPBOX DLG_NULL 78 6 BEGIN PROMPT 1 6 "@bDocumento originale" END +STRING F_CODNUM_I 4 +BEGIN + PROMPT 2 7 "Codice numerazione " + FLAGS "U" + FIELD S5 + USE NUM + INPUT CODTAB F_CODNUM_I + DISPLAY "Codice" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_CODNUM_I CODTAB + OUTPUT F_DOC1 S2[1,4] + OUTPUT F_DOC2 S2[5,8] + OUTPUT F_DOC3 S2[9,12] + OUTPUT F_DOC4 S2[13,16] + OUTPUT F_DOC5 S2[17,20] + CHECKTYPE NORMAL + WARNING "Numerazione errata" +END + +STRING F_DOC1 4 +BEGIN + PROMPT 30 7 "" + FLAGS "D" +END + +STRING F_DOC2 4 +BEGIN + PROMPT 36 7 "" + FLAGS "D" +END + +STRING F_DOC3 4 +BEGIN + PROMPT 42 7 "" + FLAGS "D" +END + +STRING F_DOC4 4 +BEGIN + PROMPT 48 7 "" + FLAGS "D" +END + +STRING F_DOC5 4 +BEGIN + PROMPT 54 7 "" + FLAGS "D" +END + STRING F_TIPODOC_I_1 4 BEGIN - PROMPT 2 7 "Tipo documento " + PROMPT 2 8 "Tipo documento " + FLAGS "U" FIELD S2[1,4] - CHECKTYPE REQUIRED - WARNING "E' necessario specificare un valore" USE %TIP INPUT CODTAB F_TIPODOC_I_1 DISPLAY "Codice" CODTAB DISPLAY "Tipo documento@50" S0 OUTPUT F_TIPODOC_I_1 CODTAB + CHECKTYPE REQUIRED + STR_EXPR {(#F_CODNUM_I=="")||(#THIS_FIELD==#F_DOC1)||(#THIS_FIELD==#F_DOC2)||(#THIS_FIELD==#F_DOC3)||(#THIS_FIELD==#F_DOC4)||(#THIS_FIELD==#F_DOC5)} + WARNING "E' necessario specificare un valore valido e previsto dalla numerazione" END STRING F_STATO_I_DOC_I_1 1 BEGIN - PROMPT 2 8 "Stato iniziale " + PROMPT 2 9 "Stato iniziale " FLAGS "U" FIELD S7[1,1] CHECKTYPE REQUIRED @@ -82,7 +132,7 @@ END STRING F_STATO_F_DOC_I 1 BEGIN - PROMPT 2 9 "Stato finale " + PROMPT 2 10 "Stato finale " FLAGS "U" FIELD S4 CHECKTYPE REQUIRED @@ -91,19 +141,21 @@ END STRING F_TIPODOC_I_2 4 BEGIN - PROMPT 30 7 "" + PROMPT 30 8 "" + FLAGS "U" FIELD S2[5,8] - WARNING "E' necessario specificare un valore" COPY USE F_TIPODOC_I_1 INPUT CODTAB F_TIPODOC_I_2 COPY DISPLAY F_TIPODOC_I_1 OUTPUT F_TIPODOC_I_2 CODTAB CHECKTYPE NORMAL + STR_EXPR {(#F_CODNUM_I=="")||(#THIS_FIELD==#F_DOC1)||(#THIS_FIELD==#F_DOC2)||(#THIS_FIELD==#F_DOC3)||(#THIS_FIELD==#F_DOC4)||(#THIS_FIELD==#F_DOC5)} + WARNING "E' necessario specificare un valore valido e previsto dalla numerazione" END STRING F_STATO_I_DOC_I_2 1 BEGIN - PROMPT 30 8 "" + PROMPT 30 9 "" FLAGS "U" FIELD S7[2,2] WARNING "E' necessario specificare un valore" @@ -112,19 +164,21 @@ END STRING F_TIPODOC_I_3 4 BEGIN - PROMPT 39 7 "" + PROMPT 39 8 "" + FLAGS "U" FIELD S2[9,12] - WARNING "E' necessario specificare un valore" COPY USE F_TIPODOC_I_1 INPUT CODTAB F_TIPODOC_I_3 COPY DISPLAY F_TIPODOC_I_1 OUTPUT F_TIPODOC_I_3 CODTAB CHECKTYPE NORMAL + STR_EXPR {(#F_CODNUM_I=="")||(#THIS_FIELD==#F_DOC1)||(#THIS_FIELD==#F_DOC2)||(#THIS_FIELD==#F_DOC3)||(#THIS_FIELD==#F_DOC4)||(#THIS_FIELD==#F_DOC5)} + WARNING "E' necessario specificare un valore valido e previsto dalla numerazione" END STRING F_STATO_I_DOC_I_3 1 BEGIN - PROMPT 39 8 "" + PROMPT 39 9 "" FLAGS "U" FIELD S7[3,3] WARNING "E' necessario specificare un valore" @@ -133,19 +187,21 @@ END STRING F_TIPODOC_I_4 4 BEGIN - PROMPT 48 7 "" + PROMPT 48 8 "" + FLAGS "U" FIELD S2[13,15] - WARNING "E' necessario specificare un valore" COPY USE F_TIPODOC_I_1 INPUT CODTAB F_TIPODOC_I_4 COPY DISPLAY F_TIPODOC_I_1 OUTPUT F_TIPODOC_I_4 CODTAB CHECKTYPE NORMAL + STR_EXPR {(#F_CODNUM_I=="")||(#THIS_FIELD==#F_DOC1)||(#THIS_FIELD==#F_DOC2)||(#THIS_FIELD==#F_DOC3)||(#THIS_FIELD==#F_DOC4)||(#THIS_FIELD==#F_DOC5)} + WARNING "E' necessario specificare un valore valido e previsto dalla numerazione" END STRING F_STATO_I_DOC_I_4 1 BEGIN - PROMPT 48 8 "" + PROMPT 48 9 "" FLAGS "U" FIELD S7[4,4] WARNING "E' necessario specificare un valore" @@ -154,19 +210,21 @@ END STRING F_TIPODOC_I_5 4 BEGIN - PROMPT 57 7 "" + PROMPT 57 8 "" + FLAGS "U" FIELD S2[16,19] - WARNING "E' necessario specificare un valore" COPY USE F_TIPODOC_I_1 INPUT CODTAB F_TIPODOC_I_4 COPY DISPLAY F_TIPODOC_I_1 OUTPUT F_TIPODOC_I_4 CODTAB CHECKTYPE NORMAL + STR_EXPR {(#F_CODNUM_I=="")||(#THIS_FIELD==#F_DOC1)||(#THIS_FIELD==#F_DOC2)||(#THIS_FIELD==#F_DOC3)||(#THIS_FIELD==#F_DOC4)||(#THIS_FIELD==#F_DOC5)} + WARNING "E' necessario specificare un valore valido e previsto dalla numerazione" END STRING F_STATO_I_DOC_I_5 1 BEGIN - PROMPT 57 8 "" + PROMPT 57 9 "" FLAGS "U" FIELD S7[5,5] WARNING "E' necessario specificare un valore" @@ -175,12 +233,12 @@ END GROUPBOX DLG_NULL 78 5 BEGIN - PROMPT 1 11 "@bDocumento finale" + PROMPT 1 12 "@bDocumento finale" END STRING F_TIPODOC_F 4 BEGIN - PROMPT 2 12 "Tipo documento " + PROMPT 2 13 "Tipo documento " FIELD S8 CHECKTYPE REQUIRED WARNING "E' necessario specificare un valore" @@ -192,22 +250,22 @@ END STRING F_STATO_F_DOC_F 1 BEGIN - PROMPT 2 13 "Stato finale " + PROMPT 2 14 "Stato finale " FLAGS "U" FIELD S9 CHECKTYPE REQUIRED WARNING "E' necessario specificare uno stato finale" END -STRING F_CODNUM 4 +STRING F_CODNUM_F 4 BEGIN - PROMPT 2 14 "Codice numerazione " + PROMPT 2 15 "Codice numerazione " FIELD S5 USE NUM - INPUT CODTAB F_CODNUM + INPUT CODTAB F_CODNUM_F DISPLAY "Codice" CODTAB DISPLAY "Descrizione@50" S0 - OUTPUT F_CODNUM CODTAB + OUTPUT F_CODNUM_F CODTAB CHECKTYPE REQUIRED WARNING "E' necessario specificare un codice di numerazione" END diff --git a/ve/batbnum.uml b/ve/batbnum.uml index 23f5d3a7f..f521ccdda 100755 --- a/ve/batbnum.uml +++ b/ve/batbnum.uml @@ -77,7 +77,7 @@ PAGE "Numerazione documenti" -1 -1 60 14 ENDPAGE -PAGE "Numerazioni documenti pag.2" -1 -1 60 14 +PAGE "Tipi documento validi" -1 -1 60 14 GROUPBOX DLG_NULL 64 15 BEGIN @@ -112,7 +112,7 @@ PAGE "Numerazioni documenti pag.2" -1 -1 60 14 STRING F_TIPODOC2 4 BEGIN - PROMPT 2 5 "" + PROMPT 2 6 "" USE %TIP INPUT CODTAB F_TIPODOC2 DISPLAY "Codice" CODTAB @@ -126,13 +126,13 @@ PAGE "Numerazioni documenti pag.2" -1 -1 60 14 STRING F_DESDOC2 40 BEGIN - PROMPT 12 5 "" + PROMPT 12 6 "" FLAG "D" END STRING F_TIPODOC3 4 BEGIN - PROMPT 2 6 "" + PROMPT 2 8 "" USE %TIP INPUT CODTAB F_TIPODOC3 DISPLAY "Codice" CODTAB @@ -146,13 +146,13 @@ PAGE "Numerazioni documenti pag.2" -1 -1 60 14 STRING F_DESDOC3 40 BEGIN - PROMPT 12 6 "" + PROMPT 12 8 "" FLAG "D" END STRING F_TIPODOC4 4 BEGIN - PROMPT 2 7 "" + PROMPT 2 10 "" USE %TIP INPUT CODTAB F_TIPODOC4 DISPLAY "Codice" CODTAB @@ -166,13 +166,13 @@ PAGE "Numerazioni documenti pag.2" -1 -1 60 14 STRING F_DESDOC4 40 BEGIN - PROMPT 12 7 "" + PROMPT 12 10 "" FLAG "D" END STRING F_TIPODOC5 4 BEGIN - PROMPT 2 8 "" + PROMPT 2 12 "" USE %TIP INPUT CODTAB F_TIPODOC5 DISPLAY "Codice" CODTAB @@ -185,109 +185,9 @@ PAGE "Numerazioni documenti pag.2" -1 -1 60 14 END STRING F_DESDOC5 40 - BEGIN - PROMPT 12 8 "" - FLAG "D" - END - - STRING F_TIPODOC6 4 - BEGIN - PROMPT 2 9 "" - USE %TIP - INPUT CODTAB F_TIPODOC6 - DISPLAY "Codice" CODTAB - DISPLAY "Descrizione@50" S0 - OUTPUT F_TIPODOC6 CODTAB - OUTPUT F_DESDOC6 S0 - HELP "Tipo di documento 6" - FIELD S2[21,24] - CHECKTYPE NORMAL - END - - STRING F_DESDOC6 40 - BEGIN - PROMPT 12 9 "" - FLAG "D" - END - - STRING F_TIPODOC7 4 - BEGIN - PROMPT 2 10 "" - USE %TIP - INPUT CODTAB F_TIPODOC7 - DISPLAY "Codice" CODTAB - DISPLAY "Descrizione@50" S0 - OUTPUT F_TIPODOC7 CODTAB - OUTPUT F_DESDOC7 S0 - HELP "Tipo di documento 7" - FIELD S2[25,28] - CHECKTYPE NORMAL - END - - STRING F_DESDOC7 40 - BEGIN - PROMPT 12 10 "" - FLAG "D" - END - - STRING F_TIPODOC8 4 - BEGIN - PROMPT 2 11 "" - USE %TIP - INPUT CODTAB F_TIPODOC8 - DISPLAY "Codice" CODTAB - DISPLAY "Descrizione@50" S0 - OUTPUT F_TIPODOC8 CODTAB - OUTPUT F_DESDOC8 S0 - HELP "Tipo di documento 8" - FIELD S2[29,32] - CHECKTYPE NORMAL - END - - STRING F_DESDOC8 40 - BEGIN - PROMPT 12 11 "" - FLAG "D" - END - - STRING F_TIPODOC9 4 - BEGIN - PROMPT 2 12 "" - USE %TIP - INPUT CODTAB F_TIPODOC9 - DISPLAY "Codice" CODTAB - DISPLAY "Descrizione@50" S0 - OUTPUT F_TIPODOC9 CODTAB - OUTPUT F_DESDOC9 S0 - HELP "Tipo di documento 9" - FIELD S2[32,36] - CHECKTYPE NORMAL - END - - STRING F_DESDOC9 40 BEGIN PROMPT 12 12 "" FLAG "D" END - STRING F_TIPODOC10 4 - BEGIN - PROMPT 2 13 "" - USE %TIP - INPUT CODTAB F_TIPODOC10 - DISPLAY "Codice" CODTAB - DISPLAY "Descrizione@50" S0 - OUTPUT F_TIPODOC10 CODTAB - OUTPUT F_DESDOC10 S0 - HELP "Tipo di documento 10" - FIELD S2[37,40] - CHECKTYPE NORMAL - END - - STRING F_DESDOC10 40 - BEGIN - PROMPT 12 13 "" - FLAG "D" - END - ENDMASK diff --git a/ve/ve6200.cpp b/ve/ve6200.cpp index 2fe3a7929..06e9e1fe7 100755 --- a/ve/ve6200.cpp +++ b/ve/ve6200.cpp @@ -1,1051 +1,49 @@ -// ve6200.cpp: modulo per la generazione dei documenti in modo BATCH. - -#include -#include +#include #include #include -#include -#include -#include + +#include "velib01.h" #include "ve6000.h" -#include "ve6retv.h" // valori di ritorno dalle varie funzioni -#include "ve6gen.h" // dichiarazione della classe base -#define TOKEN_QTA 5 -#define TOKEN_QTAEVASA 7 -#define TOKEN_QTA_DA_EVADERE 9 -#define CAMPO_DAEVADERE 101 +class TFatturazione_bolle : public TApplication +{ +protected: // TApplication + virtual bool create(); + virtual bool menu(MENU_TAG mt); -// è stata derivata la classe TSheet, perchè in alcuni documenti (es. Ordini) -// l'utente (tramite Ve6 -3, applicazione derivata dalla presente) -// può specificare di evadere una sola parte della quantità di merci indicate -// nella riga, così è stato necessario chiedere all'utente la quantità da evadere -// e riportarla nell'ultima colonna dello sheet: prima non era possibile, in quanto -// tale quantità non era un campo del record del file righedoc +public: + TFatturazione_bolle() { } + virtual ~TFatturazione_bolle() { } +}; -/***********************************/ -/**** Classe TInterattivo_sheet ****/ -/***********************************/ - -// funzione quasi uguale a quella del TSheet - -void TInterattivo_sheet::get_row(long first, TToken_string& l) +bool TFatturazione_bolle::create() { - *cursor() = (TRecnotype)first; - - const int last = fields_array().last(); - for (int i = 0; i <= last; i++) - { - const TRecfield* rf = (TRecfield*)fields_array().objptr(i); - const char* s = rf ? (const char*)*rf : ""; - l.add(s); - } - -// stabilisce per default che la quantità da evadere è quella non ancora evasa - const long qta = l.get_long(TOKEN_QTA); - const long qtaevasa = l.get_long(TOKEN_QTAEVASA); - const real qtadaevadere = qta - qtaevasa; - l.add(qtadaevadere.string(11,3), TOKEN_QTA_DA_EVADERE); -} - -// quando l'utente fa doppio click o preme selezione, la on_key riceve un K_ENTER -// e qui apro una mascherina in cui chiedo la qta da evadere, CONFERMA o ANNULLA -bool TInterattivo_sheet::on_key (KEY k) -{ -/* -// K_ENTER e' E_MOUSE_DBL, mentre K_SPACE e' E_MOUSE_DOWN - if (k==K_ENTER) - { -// maschera per l'inserimento del valore - TMask m("Modifica", 1, 33, 7); - m.add_number (CAMPO_DAEVADERE, 0, "Quantità da evadere", 1, 3, 11); - m.add_button (DLG_OK, 0, "", 1, 4); - m.add_button (DLG_CANCEL, 0, "", 1, 5); - if (m.run()==K_ENTER) - { -// aggiorna il campo "quantita' evasa della riga selezionata - // TOKEN_QTAEVASA = posizione del campo QTAEVASA nel file ve0300b.dat, - // file gestito da Matteo e coincidente con i campi di righedoc, - // da lui utilizzato per lo spreadsheet delle righe nel suo Motore - long n = selected(); - TToken_string temp = row(n); // riga selezionata - real qtaev (temp.get(TOKEN_QTAEVASA)); // valore di qtaevasa - real qtaspec (m.get(CAMPO_DAEVADERE)); // quantita' da evadere specificata - qtaev += real (qtaspec); // aggiorna il campo - real qtatot (temp.get(TOKEN_QTA)); // quantità totale della merce della riga -// controlla che qta_evasa + qta_da_evadere < qta_totale - if (qtaev>qtatot) error_box("Qtà da evadere superiore alla Qta non ancora evasa"); - else { -// se corretto, setta la riga dello sheet - temp.add (qtaspec.string(), TOKEN_QTA_DA_EVADERE); // aggiunge il campo aggiornato nella stessa posizione - set_row (temp, (byte)n); // aggiorna lo sheet - } - check(n, TRUE); - } - return FALSE; - } -*/ - return TCursor_sheet::on_key(k); -} - -/******************************/ -/*** Classe TBatch_crea_doc ***/ -/******************************/ - -// L'applicazione TBatch_crea_doc crea n documenti finali partendo da m doc. iniziali, -// individuati tramite una maschera attivata prima dell'elaborazione, ve6000a.uml, che chiede: -// Data elaborazione (del documento da creare) -// Da Codice cli/for a Codice cli/for (doc. originale) -// Da Data documento a Data documento (doc. originale) -// Da Codice agente a Codice agente (doc. originale) -// Da Codice zona a Codice zona (doc. originale) -// Ordinamento della sequenza dei documenti creati per ognuna delle voci precedenti -// Raggruppa più documenti sorgente in un solo doc. destinazione quando possibile -// Raggruppa articoli : quando possibile raggruppa più righe dello stesso articolo, -// accumulandone le quantità -// Stampa immediata (non gestito) - -inline TBatch_crea_doc& app() { return (TBatch_crea_doc&) main_app(); } // per accedere ai data members della TElaborazioni dalla filterfunct() - -bool TBatch_crea_doc::create() -{ -// BATCH --> non interattivo; questo serve perché le routines di TBatch_crea_doc -// sono usate anche da TInterattivo_crea_doc, classe figlia di " - _interattivo = FALSE; - _crea_doc = TRUE; - - dispatch_e_menu(BAR_ITEM(1)); // chiama il metodo menu + dispatch_e_menu(MENU_ITEM(1)); return TRUE; } -bool TBatch_crea_doc::destroy() +bool TFatturazione_bolle::menu(MENU_TAG) { - return TRUE; -} - -bool TBatch_crea_doc::menu(MENU_TAG) -{ - int err; -// contengono i limiti Da - a per l'individuazione dei documenti originali - TRectype first(LF_DOC), last(LF_DOC); - if (errore_fatale (run_mask(first, last))) // richiede e setta i parametri, tramite maschera - return FALSE; - - switch (_ordinamento) // in base all'ordinamento, lancia la procedura con diversi parametri - { - case CLIFO : - // crea documenti ordinando per cli./for. - err = per_cliente(first, last, "TIPOCF|CODCF"); - break; - case AGENTE: - // crea documenti ordinando per agente - err = per_cliente(first, last, "TIPOCF|CODAG"); - break; - case ZONA: - // crea documenti ordinando per zona - err = per_cliente(first, last, "TIPOCF|ZONA"); - break; - case DATA: - // crea documenti ordinando per data - err = per_cliente(first, last, "TIPOCF|DATADOC"); - break; - default: - break; + TMask m("ve6000"); + while (m.run() == K_ENTER) + { + const long dc = m.get_long(F_CODICE_CLIFO_DA); + const long ac = m.get_long(F_CODICE_CLIFO_A); + const long da = m.get_long(F_CODICE_AGENTE_DA); + const long aa = m.get_long(F_CODICE_AGENTE_A); + const long dz = m.get_long(F_CODICE_ZONA_DA); + const long az = m.get_long(F_CODICE_ZONA_A); + + TLista_clienti clienti; + clienti.leggi(dc, ac, da, aa, dz, az); } - if (errore_fatale(err)) - fatal_box ("A fatal error has occured!"); return FALSE; } -// run_mask(): -// imposta i records first e last con gli estremi Da - a -// per individuare i documenti originali da elaborare -int TBatch_crea_doc::run_mask(TRectype& first, TRectype& last) -{ -// int err; - first.zero(); - last.zero(); - TMask *_msk = new TMask ("ve6000"); - -// --- parte di Marcello, già disabilitata: a cosa serviva ? - // Imposta il flag di autorizzazione agente -/* TTable t("%TIP"); - t.zero(); - t.put ("CODTAB", _tipo_doc_org); // tipo del documento originale - if (err = t.read (_isgteq)) // si posiziona sul record relativo al documento del tipo specificato - { - error_box ("TElaborazioni::run_mask() : errore di lettura %d da tab(TIP)", err); - return READ_ERROR; - } - if (t.get ("CODTAB") != _tipo_doc_org) // verifica che il tipo di documento trovato sia quello richiesto - { - error_box ("TElaborazioni::run_mask() : non esiste il tipo documento %s in tab(TIP)", (const char *)_tipo_doc_org); - return DOC_TYPE_NOT_FOUND; - } - TFilename profilo(t.get ("S4")); // nome del profilo documento (nome del .ini associato al tipo documento originale) - profilo.ext("ini"); - TConfig profilo_doc(profilo); // file di configurazione (ini) del documento -*/ - TConfig p(CONFIG_DITTA); -// gestione agente abilitata <==> abilitata in profilo documento e nel .ini della ditta -// int agente = (profilo_doc.get_int ("CODAG", "PROFILO") && p.get_int("AGENTE", "VE")); - int agente = (p.get_int("AGENTE", "VE")); - - /* se il flag per la gestione agenti è != 0, allora visualizza i campi agente ed - adotta la stessa convenzione usata per CODICE CLIENTE e ZONA per gestire l'eventualita' che - l'utente non specifichi nulla. - Se è disabilitata, allora lascia vuoti i campi CODICE AGENTE DA e CODICE AGENTE A, in modo - da eliminare una condizione durante il filtraggio dei records. - */ - -// nasconde i campi se la gestione agenti è disabilitata - if (!agente) - { - _msk->show (F_CODICE_AGENTE_DA, FALSE); - _msk->show (F_CODICE_AGENTE_A, FALSE); - } - - if (_msk->run() == K_ESC) // runna la maschera: se premuto esc, esci - { - delete _msk; - return ESC_PRESSED; - } - - _ordinamento = _msk->get_int (F_ORDINAMENTO_EMISSIONE); // ordinamento (RadioButton) - _raggruppa = _msk->get_bool (F_RAGGRUPPA); // raggruppa più doc. originali ? - _per_articolo = _msk->get_bool (F_RAGGR_ARTICOLI); // raggruppa linee con lo stesso articolo - _datadoc = _msk->get(F_DATA_ELAB); // Data documenti finali - _anno = _datadoc.year(); // anno è una componente della chiave - - TString temps; // temporanea per rilevare i valori dei campi della maschera - TLocalisamfile f(LF_DOC); - - // i due seguenti campi non sono discriminanti, in quanto due documenti diversi - // (es.: BollaC e Fattura Acc.) sono raggruppabili nella stessa fattura - // e lo stato in cui devono essere dipende solo dal .ini di quel tipo di documento originale - -// first.put ("TIPODOC", _tipo_doc_org); // tipo documento (da tab. ELD) -// last.put ("TIPODOC", _tipo_doc_org); -// first.put ("STATO", _stato_i_doc_i); // stato documento originale -// last.put ("STATO", _stato_i_doc_i); - - temps = _msk->get(F_CODICE_CLIFO_DA); - if (temps.not_empty()) - first.put ("CODCF", temps); // codice cliente (v. filterfunct) - temps = _msk->get(F_CODICE_CLIFO_A); - if (temps.not_empty()) - last.put ("CODCF", temps); // codice cliente (v. filterfunct) - -// data - first.put ("DATADOC", _msk->get(F_DATA_DOCUMENTO_DA)); // nessun controllo perché data doc. da e data doc. a sono checktype required - last.put ("DATADOC", _msk->get(F_DATA_DOCUMENTO_A)); - -// codice zona - temps = _msk->get (F_CODICE_ZONA_DA); // mette in temps il valore del campo codice zona da - if (temps.not_empty()) // se è stato inserito un valore... - first.put("ZONA", temps); // mettilo nel campo zona - temps = _msk->get (F_CODICE_ZONA_A); - if (temps.not_empty()) - last.put ("ZONA", temps); - -// codice agente: imposta i campi solo se ne è abilitata la gestione -// se agente è disabilitato, i campi agente rimangono vuoti - if (agente) - { - temps = _msk->get (F_CODICE_AGENTE_DA); - if (temps.not_empty()) - first.put("CODAG", temps); - temps = _msk->get (F_CODICE_AGENTE_A); - if (temps.not_empty()) - last.put ("CODAG", temps); - } - - delete _msk; - - return 0; -} - -// crea fatture ordinate tramite la elab_princ() -// first e last sono 2 rectype che contengono i dati da a per filtrare i documenti originali -// campo_ordinamento è una stringa contenente la chiave di ordinamento (per cliente o per altro) -// da specificare nel TCursor usato per individuare i documenti originali - -int TBatch_crea_doc::per_cliente(TRectype& first, TRectype& last, const char* campo_ordinamento) -{ - TRelation rel (LF_DOC); // relazione sul file dei documenti -// filtro per il TCursor: -// DATADOC è obbligatoria, ma TIPOCF non dovrebbe essere per forza "C" - TString filter("(ANSI(DATADOC)>=\""); // include nel filtro i tests sui campo obbligatori - filter << first.get_date("DATADOC").string(ANSI) << "\")&&(ANSI(DATADOC)<=\""; - filter << last.get_date("DATADOC").string(ANSI) << "\")&&(TIPOCF==\"C\")"; - -// se per i campi opzionali sono stati specificati dei valori, include i tests nel filtro: -// CODICE AGENTE - if (!first.get("CODAG").empty()) - filter << "&&(CODAG>=\"" << first.get("CODAG") << "\")"; - if (!last.get("CODAG").empty()) - filter << "&&(CODAG<=\"" << last.get("CODAG") << "\")"; - -// CODICE ZONA - if (!first.get("ZONA").empty()) - filter << "&&(ZONA>=\"" << first.get("ZONA") << "\")"; - if (!last.get("ZONA").empty()) - filter << "&&(ZONA<=\"" << last.get("ZONA") << "\")"; - -// setta i limiti dei codici CLIENTI/FORNITORI per la funzione filterfunct del TCursor - _first_codcf = first.get_long ("CODCF"); - _last_codcf = last.get_long ("CODCF"); - -#ifdef _TDD_IN_FILTER -// filtro costruito in base a tutti i tipi di doc. che hanno un record ELABORAZIONE DIFFERITA (ELD) -// che li trasforma in _tipo_doc_des - TString tdfilter(1024); - tdfilter = td_ELD_to_filter(_tipo_doc_des); -// se non è vuoto, lo aggiunge al filtro già creato - if (!tdfilter.empty()) - filter << "&&(" << tdfilter << ")"; -#endif -// crea, tramite un TCursor, un elenco dei documenti sorgente che rispondono alle caratteristiche - TSorted_cursor curs(&rel, campo_ordinamento, filter, _chiave, &first, &last); -// la filterfunct limita i documenti a quelli con un codice CLI/FO fra _first_codcf e _last_codcf -// (cioé quelli indicati nella maschera richiesta in precedenza) - curs.set_filterfunction(filterfunct); - - return elab_princ(curs); -} - -// esegue tutta l'elaborazione in modo BATCH, sui documenti individuati nel TCursor curs -int TBatch_crea_doc::elab_princ(TSorted_cursor &curs) -{ - int err; // errori ritornati dalle funzioni - long n; // numero della fattura nella numerazione corrente - bool no_select = TRUE; // TRUE se non sono stati selezionati documenti dallo sheet - bool no_elab = TRUE; // TRUE se non ha ancora elaborato nessun documento - TLocalisamfile f(LF_DOC); // per gestire la testata dei documenti - TLocalisamfile rdoc(LF_RIGHEDOC); // per gestire le righe dei documenti - int current = 0; // chiave corrente - TRectype pilota (LF_DOC); // record per il documento pilota - TTable t("NUM"); // tabella numerazioni documenti - TRectype tempr(LF_DOC); // record del documento originale che si sta elaborando - TRectype temprdoc (LF_RIGHEDOC); // record per le righe dei documenti originali - int nrdoc; // numero di righe scritte nel doc finale - bool altri; // TRUE se ci sono altri documenti da includere nello stesso doc. finale - - if (curs.items() == 0) // se non ha individuato doc. originali, indica errore - { - error_box ("Nessun documento da elaborare."); - return NO_ORG_DOCS; - } - curs.freeze(); // non perdere tempo a riaggiornarti -// curs=0; // comincia dal primo documento della lista - -// _processed è un array di flag che indica se il documento relativo a ciascun flag -// sia da processare (FALSE) o da ignorare/già processato (TRUE). - -// le prossime sono righe fossili, rimaste da quanto BATCH e INTERATTIVO erano ancora assieme -//********************* -// Inizio righe fossili -//********************* - - TString80 Titolo("documenti elaborabili che possono diventare"); - Titolo << _tipo_doc_des; - TCursor_sheet docs_sheet(&curs, - " |NDOC|TIPODOC|DATADOC|TIPOCF|CODCF|OCFPI", - Titolo, - "@1|Numero@7|Tipo@4|Data@10|C/F|Cod. cliente|CF o P.IVA@16"); - - docs_sheet.enable_check(); - if (_interattivo) - { - if (docs_sheet.run()==K_ESC) return ESC_PRESSED; - for (int i=0; i interattivo = TRUE: nel BATCH, _crea_doc = TRUE, sempre - if (!_crea_doc) doc_destinazione.read(r); // se non deve crearlo, legge le righe gia' presenti -// doc_destinazione.set_key(&r); - -// legge tutti i doc_originali che vanno nel doc_destinazione - do - { -/* TRecord_array doc_originale (LF_RIGHEDOC, "NRIGA"); // array per leggere le righe del doc. org. da elaborare - // carica il documento corrente da rdoc: - // imposta i campi della chiave - temprdoc.zero(); - temprdoc.put ("CODNUM", tempr.get("CODNUM")); // tempr = record del documento originale da inserire - temprdoc.put ("ANNO", tempr.get ("ANNO")); - temprdoc.put ("PROVV", tempr.get("PROVV")); - temprdoc.put ("NDOC", tempr.get("NDOC")); - // lascia il campo "NRDOC" come campo per il conteggio - // legge le righe del documento originale, distruggendo quelle precedentemente memorizzate - // legge solo i records che corrispondono alla chiave (temprdoc) - int err = doc_originale.read(temprdoc); - CHECK (err==NOERR, "read da rdoc fallita"); - */ - // appende il documento originale al documento di destinazione -// per ogni doc_originale legge i dati (per il primo non e' necessario) - get_info(tempr); -// legge dal .ini del doc_originale tempr. il flag che dice se le righe di tempr -// possono essere evase parzialmente o devono essere evase per intero: controllo fossile, -// dal momento che in modo BATCH i documenti vengono evasi completamente - bool raggr_parz = get_raggr_parz(tempr,err); -// legge il metodo (es. B01F01) di elaborazione (trasformazione) delle righe - TString met = metodo(tempr); -// elabora le righe, scrivendole nel doc_destinazione tramite l'omonimo TRecord_array - elab_righe(met,raggr_parz,tempr,doc_destinazione,temprdoc); - - _processed.set(curs.pos()); // indica che il documento e' stato processato - -// aggiorna lo stato del documento originale e lo scrive - curs.file(LF_DOC).put ("STATO", _stato_f_doc_i); - curs.file(LF_DOC).setkey(1); - if (err = curs.file(LF_DOC).rewrite()) - { - error_box ("ve6200: Errore fatale: %d scrivendo sul file DOC", err); - return RECORD_WRITE_ERROR; - } - curs.file(LF_DOC).setkey(2); - curs.unlock(); // unlocka il record del documento processato - -// cerca il prossimo doc_originale da inserire. Se non ce ne sono piu', termina la generazione del doc_destinazione -// se ce ne sono ancora, mette nel TRectype tempr il record del prossimo doc_originale da aggiungere - - if (_raggruppa) // se deve raggruppare piu' doc_originali in uno solo, ne cerca altri - altri = search(pilota, tempr, curs); - else // altrimenti passa al prossimo doc_destinazione - altri = FALSE; - } - while (altri); // fine del ciclo che raggruppa i doc_originali in un solo doc_destinazione - -// controlla se deve raggruppare le righe per codice articolo: -// se vi sono piu' righe con lo stesso codice articolo e altre caratteristiche in comune, -// le riunisce in una sola riga - - if (_per_articolo && (doc_destinazione.rows() > 1)) // se deve raggr. e ci sono almeno 2 righe - raggruppa_righe (doc_destinazione); - -// salva le righe del doc_destinazione creato - if (err = doc_destinazione.write()) - { - error_box ("Errore nella scrittura del doc. destinazione. err = %d", err); - return RECORD_WRITE_ERROR; - } - - no_elab = FALSE; // ha elaborato almeno un documento - -// cerca il prossimo documeto pilota per il prossimo doc_destinazione - }; // finche' i doc_originali non finiscono - if (no_elab) // se non ha elaborato (trovato)doc_originali da elaborare, indica errore - { - error_box ("Nessun documento elaborato."); - return NO_ORG_DOCS; - } - return 0; -}//*** fino a qua ***// - -int TBatch_crea_doc::get_info(TRectype &doc) -{ - int err; - // informazioni dalla tabella elaborazioni differite - TRectype reld(LF_TAB); // reld e' un record di tipo tabella - leggi_da_ELD(reld,doc.get("TIPODOC")); - - // Imposta i dati relativi all'elaborazione differita corrente - _tipo_doc_org = reld.get ("S6"); // tipo documento originale - _tipo_doc_des = reld.get ("S8"); // tipo documento destinazione - TConfig doc_config (getini(doc,err), "RAGGRUPPA"); // prende il .ini di doc - _stati_validi_doc_i = doc_config.get ("STATIVALIDI"); // stato iniziale del documento originale - _stato_f_doc_i = doc_config.get ("STATOFINALE"); // stato finale (dopo l'elaborazione) del documento originale -// ha qualche senso che _stato_f_doc_f e _codnum siano indicati nel record ELD di ciascun documento iniziale ? - if (!_interattivo) - { - _stato_f_doc_f = reld.get ("S9"); // stato finale (dopo l'elaborazione) del documento finale - _codnum = reld.get ("S5"); // codice numerazione per il documento finale - } - // il flag di sospensione imposta da controllare va preso dal registro a cui - // la numerazione del documento e' collegata - _sosp_imposta = getflag(doc, SOSPENSIONE_IMPOSTA); // T/F sospensione imposta - _cod_sconto = getflag(doc, CODICE_SCONTO); // T/F codice sconto - _stesso_anno = stesso_anno_fiscale(doc); // T/F per STESSOANNOFISCALE in [RAGGR.] del .ini di reld - - return 0; -} - -bool TBatch_crea_doc::stesso_anno_fiscale(TRectype& rec) -{ - bool stesso = FALSE; -// bool stesso = _stesso_anno_fiscale; - int err; -// if (!stesso) -// { - TString name(getini(rec, err)); - if (!err){ - TConfig config (name, "RAGGRUPPA"); // prende il .ini di rec - stesso = (config.get("STESSOANNOFISCALE")[0] == '1'); // trova se si possono evadere parzialmente le righe - } -// } - return stesso; -} - -// ritorna la stringa metodo di trasf. dal record ELD per rec->_tipo_destinazione -TString TBatch_crea_doc::metodo(TRectype &rec) -{ - TString metodo; - TString _tipo_pilota = rec.get("TIPODOC"); - TRectype reld(LF_TAB); // = rec solo per inizializzarlo - leggi_da_ELD(reld,_tipo_pilota); - metodo = reld.get("S1"); - return metodo; -} - -// trova il .ini di rec e lo restituisce -TString TBatch_crea_doc::getini(TRectype& rec, int &err) -{ -// aggiustare con una new ad un TConfig - TTable teld("%TIP"); // nella tabella %TIP - teld.zero(); - teld.put ("CODTAB", rec.get("TIPODOC")); // tipo del documento pilota - err = teld.read (_isgteq); // legge il record - if (err) - { - error_box("Non riesco a leggere nella tabella %s il tipo documento %s",teld.name(),(const char *)rec.get("TIPODOC")); - return err; - } - TRectype& rtip = teld.curr(); // e lo mette in dest - TFilename inifile (rtip.get("S4")); // il nome del .ini e' nel campo S4 - inifile.ext("ini"); - return (TString)inifile; -} - -// prende i dati della sezione [RAGGRUPPA] -bool TBatch_crea_doc::get_raggr_parz(TRectype& rec, int &err) -{ - bool raggr_parz = FALSE; - err = FALSE; - TString name(getini(rec, err)); - // if (err) return err; - // _stati_validi = config.get("STATIVALIDI"); // trova gli stati validi - if (!err) { - TConfig config (name,"RAGGRUPPA"); // prende il .ini di rec - raggr_parz = (config.get("RAGGRPARZ")[0] == '1'); // trova se si possono evadere parzialmente le righe - } - return raggr_parz; -} - -// controlla che il documento rec sia in uno degli stati validi indicati nella sezione [RAGGRUPPA] del suo .ini -int TBatch_crea_doc::statovalido(TRectype& rec) -{ - int err; -// TConfig config (getini(rec, err), "RAGGRUPPA"); // prende il .ini di rec -// if (err) return err; -// TString80 _stati_validi; -// _stati_validi = config.get("STATIVALIDI"); // trova gli stati validi - err = _stati_validi_doc_i.find((rec.get("STATO"))[0]); // cerca lo stato (-1 e' non trovato) - if (err == -1) err = STATO_NON_VALIDO; - else err = STATO_VALIDO; - return err; -} - -// ritorna TRUE se esiste una ELD che passa dal tipo documento di pilota a _tipo_doc_des -int TBatch_crea_doc::esiste_ELD(TSorted_cursor &curs,int i,bool set_proc) -{ -//************* -// bisognerebbe affidarsi ad un decoder -//************* - curs = i; - TRectype &pilota = curs.curr(); // imposta il primo documento da verificare : pilota - TString _tipo_pilota = pilota.get("TIPODOC"); - TRectype dummy(LF_TAB); // = pilota solo per inizializzarlo - int err = leggi_da_ELD(dummy,_tipo_pilota); - if (err == ELAB_NOT_FOUND) - if (set_proc==SET_PROCESSED) _processed.set(curs.pos()); - else error_box ("TElaborazioni::per_cliente() : non esiste il tipo di elaborazione %s -> %s in tab(ELD)", (const char *)_tipo_pilota, (const char *)_tipo_doc_des); - return err; -} -// ritorna ELAB_FOUND se esiste una ELD che passa dal tipo documento di pilota a _tipo_dest -// (o _tipo_doc_dest, se _tipo_dest non viene specificato) e riempie eventualmente dest con la prima ELD -int TBatch_crea_doc::leggi_da_ELD(TRectype &dest,TString _tipo_pilota,TString _tipo_dest) -{ - TRelation rel("ELD"); - TString80 filter; - filter << "((S6==\"" << _tipo_pilota << "\")"; - if (!_tipo_dest.empty()) filter << "&&(S8==\"" << _tipo_doc_des << "\")"; - else if (!_tipo_doc_des.empty()) filter << "&&(S8==\"" << _tipo_doc_des << "\")"; - filter << ")"; - TCursor curs(&rel, filter); - if (curs.items() == 0) return ELAB_NOT_FOUND; - curs = 0; - dest = curs.curr(); - return ELAB_FOUND; -/* - int err; - TTable teld("ELD"); - teld.zero(); - teld.put ("S6", _tipo_pilota); // tipo del documento pilota - teld.put ("S8", _tipo_doc_des); // tipo del documento finale - err = teld.read (_isgteq); // legge il record - dest = teld.curr(); // e lo mette in dest - if (err) // guarda se si è verificato un errore - { - error_box ("TElaborazioni::per_cliente() : errore di lettura %d da tab(ELD)", err); - return READ_ERROR; - } - - if ((teld.get ("S6") != _tipo_pilota)||(teld.get ("S8") != _tipo_doc_des)) // verifica che il tipo di documento trovato sia quello richiesto - { -// error_box ("TElaborazioni::per_cliente() : non esiste il tipo di elaborazione %s -> %s in tab(ELD)", (const char *)_tipo_pilota, (const char *)_tipo_doc_des); -// se non esiste una ELD, setta processed (set_proc permettendo), -// in modo da ignorare questo documento nei controlli successivi - return ELAB_NOT_FOUND; - } - - teld.read (_isequal, _unlock); // unlocka il record in ogni caso - return ELAB_FOUND; -*/ -} - -const char *TBatch_crea_doc::td_ELD_to_filter(TString &_tipo_doc_des) -{ - bool first = TRUE; - TString td_filter(1024); - TRelation rel("ELD"); - TString80 filter; - if (_tipo_doc_des.empty()) return ""; - filter << "(S8==\"" << _tipo_doc_des << "\")"; - TCursor curs(&rel, filter); - if (curs.items() == 0) return ""; - for (int i=0; i=temp) return FALSE; // se sono stati tutti processati --> termina - return TRUE; // altrimenti continua a processare -} - -// elabora le righe di doc_originale in doc_destinazione, sul TRectype temprdoc, col metodo metodo -bool TBatch_crea_doc::elab_righe(TString metodo,bool raggr_parz,TRectype &tempr,TRecord_array &doc_destinazione,TRectype &temprdoc) -{ - bool tutte_le_righe_elab = TRUE; -// switch (metodo) -// { -// case "B01F01": - TRecord_array righe_tmp (LF_RIGHEDOC, "NRIGA"); // array contenente le righe della fattura - TRelation rel(LF_RIGHEDOC); -// rel.lfile().zero(); - TString80 ndoc_filter = "("; - ndoc_filter << "(CODNUM==\"" << tempr.get("CODNUM") << "\")&&"; - ndoc_filter << "(ANNO==\"" << tempr.get("ANNO") << "\")&&"; - ndoc_filter << "(PROVV==\"" << tempr.get("PROVV") << "\")&&"; - ndoc_filter << "(NDOC==\"" << tempr.get("NDOC") << "\")"; - ndoc_filter << ")"; - TSorted_cursor curs_righe(&rel, "NRIGA", ndoc_filter); - curs_righe.read(); // legge le righe del documento originale corrente - - // qui sostituisci le costanti stringa per testata e fields col tuo frammento di - // codice che interpreta l'apposita sezione del profilo documento. - TTable t("%TIP"); - t.zero(); - t.put ("CODTAB", tempr.get("TIPODOC")); - t.read (_isgteq); - TString _descr_tipodocorg (t.get("S4")); - TInterattivo_sheet righe_sheet(&curs_righe,"|NRIGA|CODART|DESCR|PREZZO|QTA|UMQTA|QTAEVASA|UMQTA|QTA", - _descr_tipodocorg << " - righe", - "@1|N.riga|Codice articolo@20|Descrizione@50|Prezzo@18|Quantità@11|um|Q.tà evasa@11|um|Q.tà da evadere"); - righe_sheet.add_button(DLG_OK, "Conferma", K_YES); -/* if (_raggruppa_intero) - { - righe_sheet.enable(); // seleziona tutte le righe - righe_sheet.disable_check(); // impedisce di toglierne alcune - } -*/ - KEY key=0; - int _rdoc = 1; - bool batch = !((raggr_parz)&&(_interattivo)); - if (!batch) - key = righe_sheet.run(); - if (batch||(key==K_YES)) - for (int i=0; i search() ha gia' settato la ricerca sull'anno - if (!(pil.get("ANNO") == pil2.get("ANNO"))) - if (stesso_anno_fiscale(pil2)) return FALSE; -*/ -// _stesso_anno si riferisce solo a pil2, dato che lo STESSOANNOFISCALE che conta e' quello -// dei doc originali e l'_anno e' quello di oggi (TODAY) - if ((_stesso_anno) && (pil2.get("ANNO")!=_anno)) return FALSE; - TRectype dest(LF_TAB); // reld e' un record di tipo tabella - leggi_da_ELD(dest,pil2.get("TIPODOC")); -// if (!(_stato_f_doc_f == dest.get("S9"))) return FALSE; - if (!(_codnum == dest.get("S5"))) return FALSE; - return TRUE; -} - -// filterfunction per il campo numerico CODCF (la TExpression::eval() sbaglia perche' considera tutti i dati come stringhe) -bool TBatch_crea_doc::filterfunct(const TRelation* r) -{ - TRectype& temp = r->curr(); // per accedere al record corrente senza dover sempre chiamare la funzione curr() della relazione - bool result = TRUE; - long l; - long firstcodcf, lastcodcf; // per non chiamare sempre app() - -#ifndef _TDD_IN_FILTER - if (!_tipo_doc_dest.empty()) - { - TRectype dummy(LF_TAB); // = pilota solo per inizializzarlo - result = result && ((leggi_da_ELD(dummy,_temp.get("TIPODOC"),_tipo_doc_des) == ELAB_FOUND); - } -#endif - - l = temp.get_long("CODCF"); - if ((firstcodcf = app()._first_codcf) > 0) - result = result && (l >= firstcodcf); - - if ((lastcodcf = app()._last_codcf) > 0) - result = result && (l <= lastcodcf); - return result; -} - - - -/* Raggruppa tutte le righe del documento doc che hanno uguali i seguenti campi: - - codice articolo (deve essere non blank) - - unita' di misura - - prezzo - - IVA -*/ -void TBatch_crea_doc::raggruppa_righe (TRecord_array& doc) -{ - TRectype pilota (LF_RIGHEDOC); // record corrente di raggruppamento - TRectype tempr (LF_RIGHEDOC); // prossimo record da raggruppare - TBit_array processed; // array per indicare quali righe sono gia' state processate - TBit_array tocopy(doc.rows()); // array che indica quali righe debbono essere copiate in doc2 - - tocopy.set(); // indica che tutte le righe sono da copiare - // si posiziona sul primo record che ha il codice articolo non vuoto - int i; - // salta le righe senza codice articolo (con CODART vuoto) - for (i=1; i<=doc.rows() && doc.row(i).get("CODART").empty() ; i++); - if (i>doc.rows()) - { - message_box ("Tutti gli articoli sono privi di codice. Nessuna riga raggruppata."); - return; - } - - TRectype confronto(LF_RIGHEDOC); // record per il confronto dei campi significativi - int current; // posizione dell'ultimo record valido trovato (per non ripetere sempre la ricerca dall'inizio) - do - { - current = i; - pilota = doc.row(i); - confronto.zero(); // imposta i campi significativi per il raggruppamento delle righe - confronto.put ("CODART", pilota.get ("CODART")); - confronto.put ("CODIVA", pilota.get ("CODIVA")); - confronto.put ("PREZZO", pilota.get ("PREZZO")); - confronto.put ("UMQTA", pilota.get ("UMQTA")); - processed.set(i); // la riga trovata e' processata (e' la riga pilota) - int prox; // numero della prossima riga da raggruppare - while (prox_riga (prox, doc, processed, confronto)) - { - const real qta = pilota.get_real("QTA") + doc.row(prox).get_real("QTA"); - pilota.put("QTA", qta); // aggiorna il contenuto della riga pilota - doc.row(current, FALSE) = pilota; - processed.set(prox); // indica che la riga e' stata processata - tocopy.reset(prox); // indica che la riga non e' da copiare, perche' inglobata nella riga pilota - } - // cerca la prossima riga pilota - bool skip = TRUE; - for (i=current+1; i<=doc.rows() && skip; i++) - skip = doc.row(i).get("CODART").empty() || processed[i]; - i--; - } - while (i<=doc.rows()); // finche' ci sono righe da elaborare - // necessario usare questa var. nel ciclo for seguente perche'doc.rows viene valutata ad ogni ciclo, - // e diminuisce di una unita' ogni volta che viene cancellata una riga. Cio' provocherebbe la mancata cancellazione - // delle ultime righe della fattura. - int drows = doc.rows(); - for (i=1; i<=drows; i++) // cancella le righe raggruppate - if (!tocopy[i]) - doc.destroy_row (i, FALSE); -} - -bool TBatch_crea_doc::prox_riga (int& prox, TRecord_array& doc, TBit_array& processed, TRectype& confronto) -{ - bool found = FALSE; - - for (int i=1; !found && i<=doc.rows(); i++) - if (!processed[i] && !doc.row(i).get("CODART").empty()) - found = (doc.row(i) == confronto); - prox = i-1; - return found; -} - int ve6200 (int argc, char **argv) { - TBatch_crea_doc a; - a.run (argc, argv, "Fatturazione"); + TFatturazione_bolle a; + a.run (argc, argv, "Fatturazione Bolle"); return TRUE; } diff --git a/ve/ve6300.cpp b/ve/ve6300.cpp index 66483fc41..f19796db9 100755 --- a/ve/ve6300.cpp +++ b/ve/ve6300.cpp @@ -1,430 +1,6 @@ // ve6300.cpp. Composizione interattiva dei documenti. -#include -#include -#include -#include -#include -#include -#include - -#include "ve6retv.h" -#include "ve6300.h" -#include "ve6gen.h" - -class TInterattivo_crea_doc : public TBatch_crea_doc -{ -private: - virtual bool menu (MENU_TAG); - virtual bool create (); - virtual bool destroy(); - -// int set_vars(); // setta le variabili della classe - int componi_doc_finale(); // corpo del programma - static bool tipo_doc_handler (TMask_field&, KEY); // handler per il campo tipo doc. destinaz. della maschera -// static bool filterfunct(const TRelation*); // funzione per filtrare i documenti originali - - int _rdoc; // numero di righe nel documento finale -public: - TInterattivo_crea_doc(void) {} - ~TInterattivo_crea_doc() {} -}; - -inline TInterattivo_crea_doc& app() { return (TInterattivo_crea_doc&) main_app(); } - -bool TInterattivo_crea_doc::create() -{ - _interattivo = TRUE; - - const int cargc = argc(); - const char **vargv = argv(); - - if (cargc >= 2) - { - if (cargc < 5) - return error_box ("Numero di parametri insufficiente: chiave incompleta!"); - - if (cargc >= 5) - { - _codnum = vargv[2]; - _anno = vargv[3]; - _provv = vargv[4]; - _ndoc = vargv[5]; - _crea_doc = (cargc == 7); - } - - if (cargc > 7) - message_box ("Sono presenti piu' di 6 argomenti sulla linea di comando: possibile errore"); - } - - dispatch_e_menu(BAR_ITEM(1)); - return TRUE; -} - -bool TInterattivo_crea_doc::destroy() -{ - return TRUE; -} - -bool TInterattivo_crea_doc::menu(MENU_TAG) -{ -// if (errore_fatale (set_vars())) return FALSE; - if (errore_fatale (componi_doc_finale())) - return FALSE; - return TRUE; -} - -/* -TInterattivo_crea_doc::set_vars() -{ - TMask m("ve6300.uml"); - - m.set_handler (F_TIPODOCDES, tipo_doc_handler); - if (m.run()==K_ESC) return ESC_PRESSED; - _datadoc = m.get(F_DATADOC); // data da assegnare al documento da creare - _first_codcf = _last_codcf = m.get_long(F_CODCF); // codice cliente - _tipo_doc_des = m.get(F_TIPODOCDES); // tipo del documento da creare - _codnum = m.get(F_CODNUM); // codice numerazione per il documento da creare - _anno << _datadoc.year(); // anno fiscale del documento da creare - _provv = m.get(F_PROVV); // indica se il la numerazione _codnum e' provvisoria o definitiva - - // cerca il record di ELD che corrisponde a _tipo_doc_des -// TRelation rel("ELD"); -// TString16 filter ("S8==\""); -// filter << _tipo_doc_des << '"'; -// TCursor curs(&rel, filter); -// if (curs.items()==0) -// { -// fatal_box (TString("Nessuna elaborazione genera documenti del tipo ") << _tipo_doc_des); -// return NO_ELABS; -// } -// else if (curs.items()>1) -// warning_box ("Trovate %d elaborazioni per la generazione dei documenti di tipo %s", curs.items(), (const char*)_tipo_doc_des); -// -// return 0; -} -*/ - -// handler per il tipo documento di destinazione -bool TInterattivo_crea_doc::tipo_doc_handler (TMask_field& field, KEY key) -{ - if (key == K_TAB) - { - if (field.to_check(key)) - { - TFixed_string tdd(field.get(),4); // tipo del documento destinazione selezionato - tdd.trim(); - TTable t("%TIP"); - t.zero(); - t.put ("CODTAB", tdd); // cerca tipo del documento destinazione - t.read (_isgteq); -/* if (err = t.read (_isgteq)) // si posiziona sul record relativo al documento del tipo specificato - { - error_box ("TElaborazioni::run_mask() : errore di lettura %d da tab(TIP)", err); - return READ_ERROR; - } -*/ - if (t.get ("CODTAB") != tdd) // verifica che il tipo di documento trovato sia quello richiesto - { - error_box ("TElaborazioni::run_mask() : non esiste il tipo documento %s in tab(TIP)", (const char *)tdd); - return DOC_TYPE_NOT_FOUND; - } - TFilename profilo(t.get ("S4")); // nome del profilo documento (nome del .ini associato al tipo documento originale) - profilo.ext("ini"); - TConfig profilo_doc(profilo); // file di configurazione (ini) del documento - TString tipocf = (profilo_doc.get("TIPOCF", "MAIN")); - tipocf.cut(1); - field.mask().set(F_TIPOCF, tipocf); - } - } - - TMask& mask = field.mask(); - TFixed_string s(mask.get(F_TIPIDOC), 40); - if (key==K_ENTER || key==K_TAB) - return (s.find(field.get()) % 4) == 0; // per evitare che trovi "0010" in "00010002" - return TRUE; -} - -int TInterattivo_crea_doc::componi_doc_finale() -{ - int err; // errori ritornati dalle funzioni -// long n; // numero della fattura nella numerazione corrente - bool no_select = TRUE; // TRUE se non sono stati selezionati documenti dallo sheet - bool no_elab = TRUE; // TRUE se non ha ancora elaborato nessun documento - TLocalisamfile f(LF_DOC); // per gestire la testata dei documenti - TLocalisamfile rdoc(LF_RIGHEDOC); // per gestire le righe dei documenti - int current = 0; // chiave corrente - TRectype pilota (LF_DOC); // record per il documento pilota - TTable t("NUM"); // tabella numerazioni - TRectype tempr(LF_DOC); // record del documento originale che si sta elaborando - TRectype temprdoc (LF_RIGHEDOC); // record per trovare le righe dei documenti originale -// int nrdoc; // numero di righe scritte nella fattura - // bool end = FALSE; // true non ci sono piu' documenti originali da elaborare - bool altri; // TRUE se ci sono altri documenti da includere nella fattura -// se _crea_doc, il documento destinazione (testata) deve essere inizializzato -// con i valori del primo documento originale selezionato - bool primo_pilota = _crea_doc; - - f.put ("CODNUM", _codnum); // la fattura va numerata in base alla codnum specificata in ELD - f.put ("ANNO", _anno); // imposta l'anno del documento - f.put ("PROVV", _provv); // imposta provv./def. del documento - f.put ("NDOC", _ndoc); // imposta il numero del documento - - err = f.read(_isgteq); // cerca il documento - if (err) // guarda se si è verificato un errore - { - error_box ("Errore di lettura %d in doc, cercando il documento", err); - return READ_ERROR; - } -/* else if (_crea_doc) f.curr() = pilota; // tutti i campi della fattura sono uguali al documento pilota, tranne alcuni (impostati più sotto) - else { -// confronta f.curr() e pilota (se pilota ha dei campi diversi, segnalalo e chiedi conferma - } -*/ -// } - _first_codcf = _last_codcf = f.get_long("CODCF"); // valori del campo CODCF dei records first e last, per potervi accedere dalla filterfunct() - _tipo_doc_des = f.get ("TIPODOC"); // imposta il tipo di documento - _stato_f_doc_f = f.get ("STATO"); // stato della fattura appena creata - - TRelation rel (LF_DOC); - TString tdfilter(1024); - tdfilter =""; // non so se e' necessaria -#ifdef _TDD_IN_FILTER - // filtro costruito in base a tutti i tipi di doc. che hanno un ELD che li trasforma in _tipo_doc_des - tdfilter = td_ELD_to_filter(_tipo_doc_des); -#endif - - TSorted_cursor curs (&rel, "NDOC", tdfilter); // lista i documenti ordinati per numero - curs.set_filterfunction (filterfunct); - -// non dovrebbe servire : _raggruppa = TRUE; - _per_articolo = TRUE; - - // Cursore per selezionare le testate dei documenti - if (curs.items() == 0) // se non ci sono bolle allo stato richiesto, indica errore - { - error_box ("Nessun documento da elaborare."); - return NO_ORG_DOCS; - } - curs.freeze(); // non perdere tempo a riaggiornarti -// curs=0; // comincia dal primo documento della lista - -// scandaglia tutto curs e setta _processed tutti i doc. originali che non sono selezionati - TString80 Titolo("Documenti elaborabili che possono diventare "); - Titolo << _tipo_doc_des; - TCursor_sheet docs_sheet(&curs, - " |NDOC|TIPODOC|DATADOC|TIPOCF|CODCF|OCFPI", - Titolo, - "@1|Numero@7|Tipo@4|Data@10|C/F|Cod. cliente|CF o P.IVA@16"); - - docs_sheet.enable_check(); - if (docs_sheet.run()==K_ESC) return ESC_PRESSED; - for (int i=0; i 1)) // se deve raggr. e ci sono almeno 2 righe - raggruppa_righe (doc_destinazione); - - // salva la fattura creata - if (err = doc_destinazione.write()) - { - error_box ("Errore nella scrittura del doc. destinazione. err = %d", err); - return RECORD_WRITE_ERROR; - } - - no_elab = FALSE; // ha elaborato almeno un documento - - // cerca il prossimo documeto pilota - }; // finche' i documenti non finiscono - if (no_elab) // se non ci sono bolle allo stato richiesto, indica errore - { - error_box ("Nessun documento elaborato."); - return NO_ORG_DOCS; - } - return 0; -} - int ve6300 (int argc, char** argv) { - TInterattivo_crea_doc a; - a.run (argc, argv, "Composizione documenti"); return 0; } - -/* -TPerson p ("MATTEO LIGABUE"); -p.send_message( - "DISCLAIMER: se leggerai questo pseudocodice e lo troverai childish, sappi che dopo la prima - stesura non l'ho piu' modificato, quindi questa e' l'idea che inizialmente avevo del programma - di composizione interattiva."); -p.bye(); - -- il prg per ora fa: - -a) runna una maschera in cui chiede: - a1) il codice di numerazione del doc da comporre (+PROVV) - a2) il tipo di documento da comporre - a3) la data (AUTOMAGIC) - a4) TIPOCF/CODCF del doc da comporre (e degli originali da selezionare) - a5) tipo di documento originale (da TOGLIERE !!!) - -b) runna un TCursor_Sheet con i documenti individuati da scegliere ed elaborare - -c) runna un TInterattivo_sheet (TCursor_Sheet) con le singole righe da elaborare (selezionabili) - -d) se la relativa tabella ELD permette l'evasione di parti di riga, - a1) mostrare il TCursor_sheet o TSpreadsheet (TSheet_field con maschera ve6301.uml) - a2) che possa trattare l'evasione parziale (TCursor_sheet -> con un campo number staccato dallo sheet) - a3) oppure il TSpreadsheet (TSheet_field) con tutte le colonne disabilitate, tranne la QTA_DA_EVADERE - -il programma deve ancora: - -a) passare la trasformazione al ve6200, che nella sua parte centrale (elaborazione del singolo doc.) - deve avere la eventuale selezione (da richiedersi in base ad un flag che ve6200 e ve6300 devono - settare rispettivamente a FALSE e TRUE, alla propria entrata) delle singole righe.... - aggiornare la qtaevase dei singoli sorgenti... - lo stato del documento varia solo con la completa evasione delle righe !!! - -... da continuare ... - -- controllare lo stato dei documenti originali - --*chiama una funzione che runna la maschera e copia i nomi dei campi in variabili private --*chiama una funzione che trova il record di ELD relativo al documento destinazione specificato - e setta le rimanenti variabili private --*chiama una funzione che trova i documenti (testate) validi. Usare un TSorted_cursor od un - TRecord_array - - componi la testata del documento originale con le variabili private (non metterci NDOC) - while l'utente non preme il button "Salva" per salvare il documento composto - se l'utente vuole inserire un documento dalla lista allora - mostra la lista - per ogni documento selezionato - se il flag "raggruppa unito" e' true, allora // caso doc. orig = BOLLE - fagli vedere le righe - attendi che prema un button - se preme ok aggiungi le righe al documento finale - end se ru=TRUE - altrimenti // caso doc. orig = ORDINI - fagli vedere le righe - attendi che selezioni le righe (possibilita' di selezionarle tutte) -// - usare un TBit_array per indicare se una riga va evasa tutta oppure se ne e' stata specificata una parte - settare a TRUE tutto il TBit_array; ?????????? - se doubleclicka una riga - chiedigli la quantita' da evadere (puo' essere inferiore alla quantita' ordinata su quella riga) - scrivi nel documento originale la quantita' evasa - setta il TBit_array per indicare che nella bolla deve essere scritta la quantita' evasa - end se dblclk riga -// - ...preferisco usare un TArray delle quantita' evase - - end altrimenti (ru=FALSE) - end per ogni documento selezionato - end se seleziona dei documenti - altrimenti // vuole aggiungere delle righe - leggi i campi della riga (settando automaticamente codnum, ecc.) - metti la riga letta nel documento finale - end altrimenti (inserimento righe) - end - - scrivi NDOC nella testata del documento - scrivi la testata del documento - salva il documento destinazione -end -*/ diff --git a/ve/velib01.cpp b/ve/velib01.cpp new file mode 100755 index 000000000..e413d2d91 --- /dev/null +++ b/ve/velib01.cpp @@ -0,0 +1,201 @@ +#include + +#include "velib01.h" + +/////////////////////////////////////////////////////////// +// Documento per vendite +/////////////////////////////////////////////////////////// + +TDocumento_vendita::TDocumento_vendita() + : _head(LF_DOC), _rows(LF_RIGHEDOC, "NRIGA") +{ +} + +TDocumento_vendita::TDocumento_vendita(const char* codnum, int anno, char provv, long numdoc) + : _head(LF_DOC), _rows(LF_RIGHEDOC, "NRIGA") +{ + read(codnum, anno, provv, numdoc); +} + +int TDocumento_vendita::read(const TRectype& rec) +{ + _head = rec; // Inizializza i campi chiave in ogni caso + + TLocalisamfile doc(LF_DOC); + int err = _head.read(doc); + if (err == NOERR) + { + TRectype* key = new TRectype(LF_RIGHEDOC); + key->put("CODNUM", doc.get("CODNUM")); + key->put("ANNO", doc.get("ANNO")); + key->put("PROVV", doc.get("PROVV")); + key->put("NUMDOC", doc.get("NUMDOC")); + err = _rows.read(key); + } + + return err; +} + +int TDocumento_vendita::read(const char* codnum, int anno, char provv, long numdoc) +{ + CHECK(codnum && *codnum && anno > 0 && (provv == 'D' || provv == 'P') && numdoc > 0, + "Codice documento non valido"); + + _head.zero(); + _head.put("CODNUM", codnum); + _head.put("ANNO", anno); + _head.put("PROVV", provv); + _head.put("NUMDOC", numdoc); + + return read(_head); +} + +int TDocumento_vendita::write(bool re) const +{ + TLocalisamfile doc(LF_DOC); + int err = re ? _head.rewrite(doc) : _head.write(doc); + if (err != NOERR) + err = re ? _head.write(doc) : _head.rewrite(doc); + if (err == NOERR) + err = _rows.write(re); + return err; +} + +int TDocumento_vendita::remove() const +{ + TLocalisamfile doc(LF_DOC); + int err = _head.remove(doc); + if (err == NOERR) + err = _rows.remove(); + return err; +} + +/////////////////////////////////////////////////////////// +// Cliente per vendite +/////////////////////////////////////////////////////////// + +void TLista_clienti::TCliente::init(const TRectype& rec) +{ + CHECK(rec.num() == LF_CFVEN, "E' necessario un cliente per vendite"); + _codice = rec.get_long(CLI_CODCF); + _agente = rec.get_long(CLI_CODAG); + _zona = rec.get_long(CLI_CODZONA); +} + +bool TLista_clienti::TCliente::read(long cod) +{ + TRelation clifo(LF_CLIFO); + clifo.add(LF_CFVEN, "TIPOCF=TIPOCF|CODCF=CODCF"); + + clifo.curr().put(CLI_TIPOCF, "C"); + clifo.curr().put(CLI_CODCF, cod); + if (clifo.read() == NOERR) + init(clifo.curr(LF_CFVEN)); + else + zero(); + + return ok(); +} + +TLista_clienti::TCliente::TCliente(const TRectype& rec) +{ + if (rec.num() == LF_CFVEN) + init(rec); + else + { + _codice = rec.get_long(CLI_CODCF); + read(_codice); + } +} + +int TLista_clienti::leggi(long dc, long ac, long da, long aa, long dz, long az) +{ + TRelation clifo(LF_CLIFO); + clifo.add(LF_CFVEN, "TIPOCF=TIPOCF|CODCF=CODCF"); + + TRectype start(LF_CLIFO), stop(LF_CLIFO); + + start.put(CLI_TIPOCF, 'C'); + stop.put(CLI_TIPOCF, 'C'); + + if (dc > 0) + start.put(CLI_CODCF, dc); + + if (ac > 0) + stop.put(CLI_CODCF, ac); + + TString filter(32); + if (da > 0) + filter << '(' << LF_CFVEN << "->" << CLI_CODAG << ">=" << da << ')'; + if (aa > 0) + { + if (filter.not_empty()) filter << "&&"; + filter << '(' << LF_CFVEN << "->" << CLI_CODAG << "<=" << aa << ')'; + } + if (dz > 0) + { + if (filter.not_empty()) filter << "&&"; + filter << '(' << LF_CFVEN << "->" << CLI_CODZONA << ">=" << dz << ')'; + } + if (az > 0) + { + if (filter.not_empty()) filter << "&&"; + filter << '(' << LF_CFVEN << "->" << CLI_CODZONA << "<=" << az << ')'; + } + + TCursor cur(&clifo, filter, 1, &start, &stop); + for (cur = 0; cur.ok(); ++cur) + { + TCliente* c = new TCliente(cur.curr(LF_CFVEN)); + _clienti.add(c); + } + + if (dc > 0 || ac > 0) ordina_per_codice(); else + if (da > 0 || aa > 0) ordina_per_agente(); else + if (dz > 0 || az > 0) ordina_per_zona(); + + return _clienti.items(); +} + +int TLista_clienti::sort_by_code(const TObject** o1, const TObject** o2) +{ + TLista_clienti::TCliente* c1 = (TLista_clienti::TCliente*)*o1; + TLista_clienti::TCliente* c2 = (TLista_clienti::TCliente*)*o2; + const long d = c1->codice() - c2->codice(); + return d == 0L ? 0 : (d > 0 ? +1 : -1); +} + +int TLista_clienti::sort_by_agent(const TObject** o1, const TObject** o2) +{ + TLista_clienti::TCliente* c1 = (TLista_clienti::TCliente*)*o1; + TLista_clienti::TCliente* c2 = (TLista_clienti::TCliente*)*o2; + const long d = c1->agente() - c2->agente(); + return d == 0L ? 0 : (d > 0 ? +1 : -1); +} + +int TLista_clienti::sort_by_zone(const TObject** o1, const TObject** o2) +{ + TLista_clienti::TCliente* c1 = (TLista_clienti::TCliente*)*o1; + TLista_clienti::TCliente* c2 = (TLista_clienti::TCliente*)*o2; + const long d = c1->zona() - c2->zona(); + return d == 0L ? 0 : (d > 0 ? +1 : -1); +} + +int TLista_clienti::ordina_per_codice() +{ + _clienti.sort(sort_by_code); + return _clienti.items(); +} + +int TLista_clienti::ordina_per_agente() +{ + _clienti.sort(sort_by_agent); + return _clienti.items(); +} + +int TLista_clienti::ordina_per_zona() +{ + _clienti.sort(sort_by_zone); + return _clienti.items(); +} + diff --git a/ve/velib01.h b/ve/velib01.h new file mode 100755 index 000000000..68f87b52a --- /dev/null +++ b/ve/velib01.h @@ -0,0 +1,82 @@ +#ifndef __VELIB01_H +#define __VELIB01_H + +#ifndef __RELATION_H +#include +#endif + +class TDocumento_vendita : public TObject +{ + TRectype _head; // Record di testata + TRecord_array _rows; // Array di TRectype per le righe documenti di vendita. + +public: + int rows() const { return _rows.rows(); } + + const TRectype& head() const { return _head; } // Ritorna la testata del documento + const TRectype& operator[](int index) const { return _rows.row(index); } // Ritorna la riga n-esima del documento + TRectype& operator[](int index) { return _rows.row(index, FALSE); } + TRectype& add_row() { return _rows.row(-1, TRUE); } + bool destroy_row(int n) { return _rows.destroy_row(n); } + + int read(const char* codnum, int anno, char provv, long numdoc); + int read(const TRectype& rec); + int write(bool re = FALSE) const; + int rewrite() const { return write(TRUE); } + int remove() const; + + TDocumento_vendita (); + TDocumento_vendita(const char* codnum, int anno, char provv, long numdoc); + virtual ~TDocumento_vendita() { } +}; + +class TLista_clienti : public TObject +{ + class TCliente : public TObject + { + long _codice; + long _agente; + long _zona; + + protected: + void zero() { _codice = _agente = _zona = 0L; } + void init(const TRectype& rec); + bool read(long cod); + + public: // TObject + virtual bool ok() const { return _codice > 0; } + + public: + long codice() const { return _codice; } + long agente() const { return _agente; } + long zona() const { return _zona; } + + TCliente() { zero(); } + TCliente(long cod) { read(cod); } + TCliente(const TRectype& rec); + virtual ~TCliente() { } + }; + + TArray _clienti; + +protected: + const TCliente& cliente(int n) const { return (TCliente&)_clienti[n]; } + + static int sort_by_code(const TObject** o1, const TObject** o2); + static int sort_by_agent(const TObject** o1, const TObject** o2); + static int sort_by_zone(const TObject** o1, const TObject** o2); + +public: + int ordina_per_codice(); + int ordina_per_agente(); + int ordina_per_zona(); + + int leggi(long dc, long ac, long da = 0, long aa = 0, long dz = 0, long az = 0); + + long operator[] (int n) const { return cliente(n).codice(); } + + TLista_clienti() { } + virtual ~TLista_clienti() { } +}; + +#endif