From 3587bb603a6b3435a1b30d32ac8bd77a09678a97 Mon Sep 17 00:00:00 2001 From: luca Date: Tue, 21 Jul 2009 15:29:57 +0000 Subject: [PATCH] Patch level :10.0 peronalizzazione Files correlati : Ricompilazione Demo : [ ] Commento : prima stesura della personalizzazione HK; ancora non va! git-svn-id: svn://10.65.10.50/trunk@19125 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- ps/pg0068.cpp | 15 ++ ps/pg0068.h | 1 + ps/pg0068100.cpp | 543 ++++++++++++++++++++++++++++++++++++++++++++++ ps/pg0068100a.h | 8 + ps/pg0068100a.uml | 70 ++++++ 5 files changed, 637 insertions(+) create mode 100755 ps/pg0068.cpp create mode 100755 ps/pg0068.h create mode 100755 ps/pg0068100.cpp create mode 100755 ps/pg0068100a.h create mode 100755 ps/pg0068100a.uml diff --git a/ps/pg0068.cpp b/ps/pg0068.cpp new file mode 100755 index 000000000..b842adaa4 --- /dev/null +++ b/ps/pg0068.cpp @@ -0,0 +1,15 @@ +#include + +#include "pg0068.h" + +int main( int argc, char** argv ) +{ + const int r = (argc > 1) ? argv[1][1]-'0' : -1; + + switch (r) + { + case 0: pg0068100(argc, argv); break; // contabilizzazione Hair Kulture + default: break; + } + return 0; +} \ No newline at end of file diff --git a/ps/pg0068.h b/ps/pg0068.h new file mode 100755 index 000000000..37c3b616d --- /dev/null +++ b/ps/pg0068.h @@ -0,0 +1 @@ +int pg0068100(int, char**); diff --git a/ps/pg0068100.cpp b/ps/pg0068100.cpp new file mode 100755 index 000000000..ecf27fe0e --- /dev/null +++ b/ps/pg0068100.cpp @@ -0,0 +1,543 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../ca/movana.h" +#include "../ca/rmovana.h" +#include "../ve/velib04.h" +#include "../cg/cgsaldac.h" + +#include "pg0068100a.h" + + +/////////////////////////////////////////////// +// MASCHERA +/////////////////////////////////////////////// +class TEleabollazione_HK_mask : public TAutomask +{ + TArray_sheet* _num_sheet; // TArray_sheet contenente le selezioni sui codici numerazione + TString_array _tipi_doc; // Array di stringhe contenente i tipi documenti da elaborare + +protected: + virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); + // Costruisce lo sheet dei codici numerazione + void build_num_sheet(); + +public: + // Controlla se lo stato ed il tipo del documento sono validi e rispettano la selezione + bool doc_tipo_stato_ok(const TRectype& doc); + // Restituisce lo sheet con le numerazioni da elaborare + TArray_sheet& num_sheet() const { return *_num_sheet; } + // Constructor and Distructor + TEleabollazione_HK_mask(); + ~TEleabollazione_HK_mask(); +}; + +TEleabollazione_HK_mask::TEleabollazione_HK_mask() : TAutomask("ve6800a") +{ + _num_sheet = new TArray_sheet(-1, -1, -4, -4, "Codici numerazione", "@1|Cod. numerazione|Descrizione@50"); +} + +TEleabollazione_HK_mask::~TEleabollazione_HK_mask() +{ + delete _num_sheet; +} + +bool TEleabollazione_HK_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) +{ + switch (o.dlg()) + { + case F_CODICE_ELAB: + if (e == fe_modify || e == fe_init) + { + const bool full = !o.empty(); + if (full) + build_num_sheet(); + enable(DLG_USER, full); + enable(DLG_OK, full && _num_sheet->one_checked()); + } + break; + case DLG_USER: + if (e == fe_button && _num_sheet->run()) + { + // Hai selezionato qualcosa ? allora abilita il pulsante di conferma + enable(DLG_OK, _num_sheet->one_checked()); + } + break; + default: + break; + } + return true; +} + +void TEleabollazione_HK_mask::build_num_sheet() +{ + _num_sheet->destroy(); + _tipi_doc.destroy(); + + const TContabilizzazione_analitica contanal(get(F_CODICE_ELAB)); + if (!contanal.empty()) + { + TToken_string t; + TString4 tipo; + for (int i = 0; i < TElaborazione::_max_tipi_doc_elab; i++) + { + tipo = contanal.tipo_iniziale(i); + if (tipo.full()) + { + t = tipo; + t.add(contanal.stato_iniziale(i)); // Stato iniziale + _tipi_doc.add(t); // Aggiunge questo tipo documento alla lista + } + } + + TString s1,s2,s3; + TTable num("%NUM"); + for (num.first(); num.good(); num.next()) // scorre tutte le numerazioni possibili + { + TToken_string t,z; + t.add(" "); + t.add(num.get("CODTAB")); + t.add(num.get("S0")); + + s2 = num.get("S2"); // reperisce i tipi documento validi per questa numerazione + + for (int x = 0; x <= s2.len(); x += 4) + z.add(s2.mid(x,4)); + + bool found = false; + for (int i = _tipi_doc.last(); !found && i >= 0; i--) + found |= s2.find(_tipi_doc.row(i).get(0)) >= 0; + if (found) + _num_sheet->add(t); + } + + if (_num_sheet->items() == 1) + _num_sheet->check(0); + } +} + +bool TEleabollazione_HK_mask::doc_tipo_stato_ok(const TRectype& doc) +// Verifica che il tipo documento corrente esista tra i tipi previsti dalla elaborazione +// differita selezionata +{ + bool found = false; + const TString4 tipo = doc.get(DOC_TIPODOC); + const char stato = doc.get_char(DOC_STATO); + const int items = _tipi_doc.items(); + for (int i = 0; i < items && !found; i++) + { + TToken_string& t = _tipi_doc.row(i); + const TString4 tipox(t.get(0)); + const char statox = t.get(1)[0]; + if (tipo == tipox && stato == statox) + found = true; + } + return found; +} + + + + + + +class TContabilizzazione_analitica_costi : public TContabilizzazione_analitica +{ + TString4 _codcaus; + bool _costi; + +public: + virtual bool elabora(TDocumento& doc, long numreg_cg, TViswin* viswin, bool can_write, TAnal_mov& mov, + bool riclassifica_fdr_fde = true); + + TContabilizzazione_analitica_costi(const TString& codcaus, const char* cod = NULL, bool costi = true) + : TContabilizzazione_analitica(cod), _codcaus(codcaus), _costi(costi) {} + TContabilizzazione_analitica_costi(const TString& codcaus, const TRectype& rec, bool costi = true) + : TContabilizzazione_analitica(rec), _codcaus(codcaus), _costi(costi) {} + virtual ~TContabilizzazione_analitica_costi() {} + +}; + +bool TContabilizzazione_analitica_costi::elabora(TDocumento& doc, long numreg_cg, TViswin* viswin, bool can_write, + TAnal_mov& mov, bool riclassifica_fdr_fde) +{ + TDate datareg, datacomp, datadoc; + int annoes = 0; + TString descr, msg, codcaus; + bool dare = false; + TCausale caus(_codcaus); + + datadoc = doc.get(DOC_DATADOC); + datareg = datacomp = datadoc; + annoes = esercizi().date2esc(datareg); + doc.riferimento(descr); + if (descr.empty()) + descr = doc.tipo().descrizione(); + + const TString8 rif = doc.get(DOC_NUMDOCRIF); + codcaus = caus.codice(); + const bool use_rif = caus.iva() == iva_acquisti && rif.not_empty(); + if (use_rif) + { + descr << TR(" n. ") << rif; + descr << TR(" del ") << doc.get(DOC_DATADOCRIF); + } + else + { + descr << TR(" n. ") << doc.numero(); + descr << TR(" del ") << datadoc; + } + + + if (_costi) + dare = true; + else + dare = doc.get_char(DOC_TIPOCF) == 'F'; + + if (doc.is_nota_credito()) + dare = !dare; + + const char sezione = dare ? 'D' : 'A'; + const int decimals = TCurrency::get_firm_dec(); + + long numreg_ca = doc.get_long(DOC_NUMREGCA); + if (numreg_ca > 0) + { + const int err = mov.read(numreg_ca); + if (err == NOERR) + { + if (viswin != NULL) + { + msg.format("--- Il documento verrā ricontabilizzato nel movimento analitico %ld", numreg_ca); + viswin->add_line(msg); + } + mov.body().destroy_rows(); + } + else + mov.put(MOVANA_NUMREG, numreg_ca = 0); + } + mov.put(MOVANA_DATAREG, datareg); + mov.put(MOVANA_DATACOMP, datacomp); + mov.put(MOVANA_DATADOC, datadoc); + mov.put(MOVANA_ANNOES, annoes); + mov.put(MOVANA_DESCR, descr); + mov.put(MOVANA_NUMREGCG, numreg_cg); + mov.put(MOVANA_CODCAUS, caus.codice()); + mov.put(MOVANA_DPROVV, doc.get(DOC_PROVV)); // Documento originale + mov.put(MOVANA_DANNO, doc.get(DOC_ANNO)); + mov.put(MOVANA_DCODNUM, doc.get(DOC_CODNUM)); + mov.put(MOVANA_DNDOC, doc.get(DOC_NDOC)); + + + TImporto totdoc; // Totale movimento analitico + const TipoIVA tiva = caus.iva(); + TBill bill; caus.bill(RIGA_IVA_NON_DETRAIBILE, bill); + + // Scandisco le righe del documento, + int i; + for (i = 1; i <= doc.physical_rows(); i++) + { + const TRiga_documento& riga = doc[i]; + bool pareggio = false; + +// salto descrizioni, e omaggi + if (riga.is_descrizione() || riga.is_omaggio()) + continue; + + // salto valori nulli + const real qta = riga.get(RDOC_QTA); + const real costo = riga.articolo().get_real(ANAMAG_ULTCOS1); + real valore = _costi ? qta * costo : riga.provvigione(); + + /*real valore; + if (_costi) + valore = qta * costo; + else + valore = riga.provvigione();*/ + + if (valore.is_zero()) + continue; + + if (tiva != iva_vendite && !riga.is_sconto()) + { + const TString4 tipodet = riga.get(RDOC_TIPODET); + int td; + const real pind = indetraibile_al(tipodet, caus, datareg.year(), td); + + if (pind > ZERO) + { + const real imposta = riga.iva().imposta(valore); + const real ivaind = (imposta * pind) / CENTO; + if (bill.ok()) + { + if (bill.is_analitico()) + { + TString_array conti_ind; + const char tipomov = mov.get_char(MOVANA_TIPOMOV); + if (find_conti_iva_indetraibile(riga, bill, conti_ind, annoes, tipomov, pareggio)) //qui + { + TGeneric_distrib esso(ivaind, decimals); + + init_distrib(conti_ind, esso, pareggio); + FOR_EACH_ARRAY_ROW(conti_ind, j, row_ind) + { + TRectype& rmov = mov.new_row(); + rmov.put(RMOVANA_ANNOES, annoes); + rmov.put(RMOVANA_CODCONTO, row_ind->get(0)); + rmov.put(RMOVANA_CODCCOSTO,row_ind->get()); + rmov.put(RMOVANA_CODCMS, row_ind->get()); + rmov.put(RMOVANA_CODFASE, row_ind->get()); + rmov.put(RMOVANA_DESCR, riga.get(RDOC_DESCR)); + + const bool negative = pareggio && j > 0; + const bool totale = pareggio && j == 0; + TImporto imp(sezione, totale ? ivaind : real(esso.get())); + + if (negative) + imp.swap_section(); + imp.normalize(); + rmov.put(RMOVANA_SEZIONE, imp.sezione()); + rmov.put(RMOVANA_IMPORTO, imp.valore()); + totdoc += imp; + } + } + } + } + else + valore += ivaind; + } + } + + if (valore.is_zero()) + continue; + + TString_array conti; + const char tipomov = mov.get_char(MOVANA_TIPOMOV); + const bool ok = find_conti(riga, conti, annoes, riclassifica_fdr_fde, tipomov, pareggio); + if (!ok) + { + if (viswin != NULL) + { + TString msg; + msg.format(FR("*** Riga %d: Manca il conto analitico dell'articolo '%s'"), i, (const char*)riga.get(RDOC_CODART)); + viswin->add_line(msg); + } + //_error = conto_error; + can_write = false; + continue; + } + + TGeneric_distrib esso(valore, decimals); + + init_distrib(conti, esso, pareggio); + FOR_EACH_ARRAY_ROW(conti, i, row) + { + TRectype& rmov = mov.new_row(); + rmov.put(RMOVANA_ANNOES, annoes); + rmov.put(RMOVANA_CODCONTO, row->get(0)); + rmov.put(RMOVANA_CODCCOSTO,row->get()); + rmov.put(RMOVANA_CODCMS, row->get()); + rmov.put(RMOVANA_CODFASE, row->get()); + rmov.put(RMOVANA_DESCR, riga.get(RDOC_DESCR)); + + const bool negative = pareggio && i > 0; + const bool totale = pareggio && i == 0; + TImporto imp(sezione, totale ? valore : real(esso.get())); + + if (negative) + imp.swap_section(); + imp.normalize(); + rmov.put(RMOVANA_SEZIONE, imp.sezione()); + rmov.put(RMOVANA_IMPORTO, imp.valore()); + totdoc += imp; + } + } + + if (can_write && mov.rows() > 0) + { + totdoc.normalize(); + mov.put(MOVANA_SEZIONE, totdoc.sezione()); + mov.put(MOVANA_TOTDOC, totdoc.valore()); + + TLocalisamfile movana(LF_MOVANA); + if (numreg_ca > 0) + mov.rewrite(movana); + else + { + mov.write(movana); + numreg_ca = mov.get_long(MOVANA_NUMREG); + doc.put(DOC_NUMREGCA, numreg_ca); + } + if (viswin != NULL) + { + msg.format(FR("--- Movimento analitico $[r,w]%ld$[n,w] del %s"), numreg_ca, datacomp.string()); + viswin->add_line(msg); + } + } + + return can_write; +} + + +class TContabilizzazione_analitica_provvigioni : public TContabilizzazione_analitica_costi +{ +public: + TContabilizzazione_analitica_provvigioni(const TString& codcaus, const char* cod = NULL) + : TContabilizzazione_analitica_costi(codcaus, cod, false) {} + TContabilizzazione_analitica_provvigioni(const TString& codcaus, const TRectype& rec) + : TContabilizzazione_analitica_costi(codcaus, rec, false) {} + virtual ~TContabilizzazione_analitica_provvigioni() {} + +}; + +////////////////////////////////////////////// +// APPLICAZIONE +///////////////////////////////////////////// + +// TEleabollazione_HK +// Applicazione di contabilizzazione documenti +class TEleabollazione_HK_app : public TSkeleton_application +{ + TEleabollazione_HK_mask* _msk; + + virtual bool check_autorization() const {return false;} + virtual const char * extra_modules() const {return "ve";} + +protected: // TApplication + // Contabilizza i documenti + void contabilize(); + +public: + virtual bool create(); + virtual bool destroy(); + virtual void main_loop(); +}; + + +void TEleabollazione_HK_app::contabilize() +{ + //Prende i dati dalla maschera (date,sheet numerazioni) + const TDate data_ini = _msk->get_date(F_DATA_INI); + int year_from = data_ini.year(); + const TDate data_fine = _msk->get_date(F_DATA_FIN); + int year_to = data_fine.year(); + const TDate data_reg = _msk->get_date(F_DATA_REG); + TArray_sheet& num_sheet = _msk->num_sheet(); + const long items = num_sheet.items(); + + //Relazione su LF_DOC + TRelation doc_rel(LF_DOC); + TRectype da(LF_DOC); + TRectype a(LF_DOC); + + TString16 codnum; + TString msg, filt_expr; + TToken_string nums; + + // Compone la lista dei documenti da elaborare + for (long i = 0L; i < items; i++) // Scorre per tutte le numerazioni dello sheet + { + if (num_sheet.checked(i)) // Costruisce una espressione sul codice numerazione: "CODNUM="x0" || CODNUM="x1" || ..." + { + codnum = num_sheet.row(i).get(1); + filt_expr << "(CODNUM=\""; + filt_expr << codnum << "\")||"; + nums.add(codnum); + } + } + filt_expr.rtrim(2); + + da.put(DOC_DATADOC, data_ini); + da.put(DOC_PROVV, "D"); + da.put(DOC_ANNO, year_from); + a.put(DOC_DATADOC, data_fine); + a.put(DOC_PROVV, "D"); + a.put(DOC_ANNO, year_to); + + // Se ho una sola numerazione ottimizzo la setregion! + if (nums.items() == 1) + { + da.put(DOC_CODNUM, nums); + a.put(DOC_CODNUM, nums); + //filt_expr.cut(0); // Il filtro diventa inutile + } + + // Cursore complessivo con limiti di data (chiave 3). Viene sfruttata l'ottimizzazione + // sulla costruzione dei cursori nel caso i campi presenti nell'espressione siano campi + // chiave, nel nostro caso CODNUM soddisfa i requisiti. + TCursor doc_cur(&doc_rel, filt_expr, 3, &da, &a); + const TRecnotype cur_items = doc_cur.items(); + if (cur_items > 0) + { + TLista_documenti lista_in, lista_out; + + doc_cur.freeze(); + msg = "Selezione documenti dal "; + msg << data_ini.string() << " al "; + msg << data_fine.string(); + TProgind p(cur_items, msg, false, true); + const TRectype& cur_rec = doc_cur.curr(); + + // Scorre tutti i documenti che rientrano nell'intervallo selezionato + for (doc_cur = 0; doc_cur.pos() < cur_items; ++doc_cur) + { + p.addstatus(1); + // controlla che il tipo documento e lo stato siano coerenti con la ELD selezionata + if (nums.get_pos(cur_rec.get(DOC_CODNUM)) >= 0 && _msk->doc_tipo_stato_ok(cur_rec)) + { + TDocumento* doc = new TDocumento; + if (doc->read(doc_cur.curr()) == NOERR) // legge il documento + lista_in.add(doc); // Viene aggiunto alla lista dei documenti + else + delete doc; + } + } + //E finalmente fa l'agognata elaborazione!!!!! + TString16 elaborazione = _msk->get(F_CODICE_ELAB); + TContabilizzazione_analitica contanal(elaborazione); + contanal.elabora(lista_in, lista_out, data_reg); + + if (contanal.processed_docs() > 0L) + message_box(FR("Totale documenti contabilizzati: %ld"), contanal.processed_docs()); + } + else + warning_box(TR("Non vi sono documenti da contabilizzare per le numerazioni selezionate.")); + + xvtil_statbar_set(""); +} + + +bool TEleabollazione_HK_app::create() +{ + //se non ha le vendite č impossibile da utilizzare + if (!has_module(VEAUT) && !has_module(CAAUT)) + return error_box(TR("Modulo non autorizzato")); + + open_files(LF_TABCOM, LF_TAB, LF_DOC, LF_RIGHEDOC, LF_MOVANA, LF_RMOVANA, 0); + _msk = new TEleabollazione_HK_mask(); + return TSkeleton_application::create(); +} + +bool TEleabollazione_HK_app::destroy() +{ + if (_msk) delete _msk; + return TSkeleton_application::destroy(); +} + +void TEleabollazione_HK_app::main_loop() +{ + while (_msk->run() == K_ENTER) + contabilize(); +} + +int pg0068100 (int argc, char **argv) +{ + TEleabollazione_HK_app a; + a.run(argc,argv, TR("Contabilizzazione Hair Kulture")); + return true; +} diff --git a/ps/pg0068100a.h b/ps/pg0068100a.h new file mode 100755 index 000000000..e7b84764e --- /dev/null +++ b/ps/pg0068100a.h @@ -0,0 +1,8 @@ +// Include file per ve6800a.uml + +#define F_CODICE_ELAB 101 +#define F_DESC_ELAB 102 +#define F_DATA_INI 103 +#define F_DATA_FIN 104 +#define F_DATA_AUTO 105 +#define F_DATA_REG 106 diff --git a/ps/pg0068100a.uml b/ps/pg0068100a.uml new file mode 100755 index 000000000..9c2ec8ba1 --- /dev/null +++ b/ps/pg0068100a.uml @@ -0,0 +1,70 @@ +#include "pg0068100a.h" + +PAGE "Contabilizzazione HAIR KULTURE" -1 -1 78 8 + +STRING F_CODICE_ELAB 8 +BEGIN + PROMPT 1 1 "Codice " + FLAG "U" + USE %ELD SELECT I0 == 7 + INPUT CODTAB F_CODICE_ELAB + DISPLAY "Codice@8" CODTAB + DISPLAY "Descrizione@50" S0 + OUTPUT F_CODICE_ELAB CODTAB + OUTPUT F_DESC_ELAB S0 + CHECKTYPE REQUIRED + WARNING "E' necessario specificare il codice elaborazione" +END + +STRING F_DESC_ELAB 50 +BEGIN + PROMPT 20 1 "" + USE %ELD KEY 2 SELECT I0 == 7 + INPUT S0 F_DESC_ELAB + DISPLAY "Descrizione@50" S0 + DISPLAY "Codice@8" CODTAB + COPY OUTPUT F_CODICE_ELAB +END + +GROUPBOX DLG_NULL 26 4 +BEGIN + PROMPT 1 2 "Date intervallo documenti" +END + +DATE F_DATA_INI +BEGIN + PROMPT 2 3 "Inizio " + CHECKTYPE REQUIRED + WARNING "La data di inizio intervallo e' obbligatoria" +END + +DATE F_DATA_FIN +BEGIN + PROMPT 2 4 "Fine " + CHECKTYPE REQUIRED + WARNING "La data di fine intervallo deve essere successiva a quella di inizio" + VALIDATE DATE_CMP_FUNC >= F_DATA_INI +END + +DATE F_DATA_REG +BEGIN + PROMPT 2 6 "Data registrazione " + FLAGS "A" + CHECKTYPE REQUIRED +END + +ENDPAGE + +TOOLBAR "topbar" 0 0 0 2 + +BUTTON DLG_USER 10 2 +BEGIN + PROMPT -12 -1 "~Selezione" + PICTURE TOOL_MULTISEL +END + +#include + +ENDPAGE + +ENDMASK