diff --git a/sc/sc0300.cpp b/sc/sc0300.cpp index a72e09f55..fd20aaff6 100644 --- a/sc/sc0300.cpp +++ b/sc/sc0300.cpp @@ -8,6 +8,7 @@ #include #include +#include #include class TPareggio_tree : public TObject_tree @@ -16,18 +17,30 @@ class TPareggio_tree : public TObject_tree protected: virtual TFieldtypes get_var(const TString& name, TVariant& var) const; - virtual bool marked() const { return rand() % 2 != 0; } - const TPartita& partita(const TRectype& rec) const; public: - bool init(const TBill& bill, const TString& valuta, bool nc, int stato); // Stato- 1=aperte; 2=chiuse; 0 o 3 = tutte + bool init(const TBill& bill, const TString& valuta, bool nc, int stato); // Stato: 1=aperte; 2=chiuse; 0 o 3 = tutte + TPartita& partita(const TRectype& rec) const; + const TRectype* node2rec(const TString& id); }; -const TPartita& TPareggio_tree::partita(const TRectype& rec) const +TPartita& TPareggio_tree::partita(const TRectype& rec) const { return ((TPartite_array&)_games).partita(rec); } +const TRectype* TPareggio_tree::node2rec(const TString& id) +{ + const TRectype* rec = NULL; + if (id.blank() || goto_node(id)) + { + const TObject* obj = curr_node(); + if (obj->is_kind_of(CLASS_RECTYPE)) + rec = (const TRectype*)obj; + } + return rec; +} + TFieldtypes TPareggio_tree::get_var(const TString& name, TVariant& var) const { TFieldtypes ft = _nullfld; @@ -107,7 +120,6 @@ TFieldtypes TPareggio_tree::get_var(const TString& name, TVariant& var) const return ft; } - bool TPareggio_tree::init(const TBill& bill, const TString& valuta, bool nc, int stato) { goto_root(); @@ -212,7 +224,7 @@ bool TPareggio_tree::init(const TBill& bill, const TString& valuta, bool nc, int } else { - TPartita game(rec); + TPartita& game = partita(rec); const TRiga_partite& riga = game.riga(rec.get_int(PART_NRIGA)); for (int rata = 1; rata <= riga.rate(); rata++) { @@ -244,6 +256,32 @@ bool TPareggio_tree::init(const TBill& bill, const TString& valuta, bool nc, int return goto_root(); } +/////////////////////////////////////////////////////////// +// TScad_mask +/////////////////////////////////////////////////////////// + +class TScad_mask : public TAutomask +{ +protected: + virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); + +public: + TScad_mask() : TAutomask("sc0300b") {} +}; + +bool TScad_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) +{ + switch (o.dlg()) + { + case F_TUTTE: + if (e == se_query_add || e == se_query_del) + return false; + break; + default: break; + } + return true; +} + /////////////////////////////////////////////////////////// // TPareggio_mask /////////////////////////////////////////////////////////// @@ -256,10 +294,161 @@ class TPareggio_mask : public TAutomask protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); + const TString& causale_nc_reg(const TString& reg) const; + bool converti(const TRectype& rec); + bool abbuona_rata(const real& imp, const TRectype& nota, TRiga_scadenze& scad); + bool elabora(const TRectype& nota, const TPointer_array& fatture); + public: TPareggio_mask(); }; +// Cerca una causale di nota di credito sul registro reg +const TString& TPareggio_mask::causale_nc_reg(const TString& reg) const +{ + if (reg.full()) + { + const TString& codcaus = get(get(F_TIPO) == "C" ? F_CODCAUS_C : F_CODCAUS_F); + const TString& cr = cache().get(LF_CAUSALI, codcaus, CAU_REG); + if (cr == reg) + return codcaus; // Siamo fortunati: va bene la causale standard + + TISAM_recordset recset("USE CAUS SELECT (REG=#CODREG)&&(TIPOMOV=2)"); + recset.set_var("#CODREG", reg); + if (recset.move_first()) + return recset.get(CAU_CODCAUS).as_string(); + } + return EMPTY_STRING; +} + +bool TPareggio_mask::converti(const TRectype& rec) +{ + CHECK(rec.num() == LF_PARTITE, "Solo partite, grazie!"); + const long numreg = rec.get_long(PART_NREG); + const TString4 codreg = rec.get(PART_REG); + const TString4 codcau = causale_nc_reg(codreg); + if (codcau.blank()) + return error_box(FR("E' necessario creare una causale di note di credito sul registro %s"), (const char*)codreg); + + TString msg; + msg << TR("Si desidera trasformare la fattura in nota di credito con causale ") + << codcau << '\n' << cache().get(LF_CAUSALI, codcau, CAU_DESCR); + if (!yesno_box(msg)) + return false; + + int err = NOERR; + if (numreg > 0) + { + TLocalisamfile mov(LF_MOV); + mov.curr().put(MOV_NUMREG, numreg); + err = mov.read(_isequal, _lock); + if (err == NOERR) + { + mov.put(MOV_CODCAUS, codcau); + mov.put(MOV_TIPOMOV, tm_nota_credito); + err = mov.rewrite(); + } + if (err != NOERR) + return error_box(FR("Impossibile modificare il movimento %ld: errore %d"), numreg, err); + } + + if (err == NOERR) + { + TPartita& game = _nc.partita(rec); + const int nriga = game.prima_fattura(numreg); + if (nriga > 0) + { + TRiga_partite& fatt = game.riga(nriga); + fatt.put(PART_CODCAUS, codcau); + fatt.put(PART_TIPOMOV, tm_nota_credito); + TRectype& pag = game.unassigned().row(nriga, true); + pag.put(PAGSCA_IMPORTO, fatt.get(PART_IMPORTO)); + err = game.rewrite() ? NOERR : _islocked; + } + else + err = _iskeynotfound; + } + if (err != NOERR) + return error_box(FR("Impossibile modificare la partita associata la movimento %ld: errore %d"), numreg, err); + + return true; +} + +bool TPareggio_mask::abbuona_rata(const real& imp, const TRectype& nota, TRiga_scadenze& scad) +{ + const TValuta valuta(scad.riga()); + const char* imp_field = valuta.in_valuta() ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO; + + TPartita& old_nc = _nc.partita(nota); + TPartita& ft = scad.partita(); + + TRiga_partite& new_nc = ft.new_row(); + new_nc.put(PART_SEZ, scad.riga().get_char(PART_SEZ) == 'D' ? 'A' : 'D'); + new_nc.put(PART_NREG, nota.get(PART_NREG)); + new_nc.put(PART_CODCAUS, nota.get(PART_CODCAUS)); + new_nc.put(PART_REG, nota.get(PART_REG)); + new_nc.put(PART_NUMDOC, nota.get(PART_NUMDOC)); + new_nc.put(PART_DATADOC, nota.get(PART_DATADOC)); + + TRectype new_pag = scad.new_row(new_nc.get_int(PART_NRIGA)); + new_pag.put(imp_field, imp); + ft.modifica_pagamento(new_pag, valuta, true); + + TRectype unass = old_nc.unassigned().row(nota.get_int(PART_NRIGA)); + if (new_nc.get(PART_SEZ) == nota.get(PART_SEZ)) + unass.add(imp_field, -imp); + else + unass.add(imp_field, imp); + old_nc.modifica_pagamento(unass, valuta, true); + + return true; +} + +bool TPareggio_mask::elabora(const TRectype& nota, const TPointer_array& scadenze) +{ + CHECK(nota.num() == LF_PARTITE, "Solo partite, grazie!"); + const tipo_movimento tm = (tipo_movimento)nota.get_int(PART_TIPOMOV); + if (tm == tm_fattura && !converti(nota)) + return false; + + TScad_mask ass; + const TString& codval = get(F_CODVAL); + ass.set(F_CODVAL, codval); + TSheet_field& sheet = ass.sfield(F_TUTTE); + + real residuo_nc = abs(nota.get_real(is_true_value(codval) ? PART_IMPORTOVAL : PART_IMPORTO)); + TString_array rate; + FOR_EACH_ARRAY_ITEM(scadenze, i, s) + { + const TRiga_scadenze& scad = *(TRiga_scadenze*)s; + TToken_string& row = sheet.row(-1); + const real residuo_scad = scad.residuo(true).valore(); + real imp = residuo_nc; + if (imp > residuo_scad) + imp = residuo_scad; + row.add(imp.string()); + residuo_nc -= imp; + row.add(residuo_scad.string()); + row.add(scad.importo(true).valore().string()); + row.add(scad.get(SCAD_DATASCAD)); + } + + if (ass.run() == K_ENTER) + { + FOR_EACH_SHEET_ROW(sheet, r, row) + { + const real imp = row->get(0); + if (imp > ZERO) + { + TRiga_scadenze& scad = (TRiga_scadenze&)scadenze[r]; + abbuona_rata(imp, nota, scad); + } + } + } + + return true; +} + bool TPareggio_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) @@ -269,7 +458,7 @@ bool TPareggio_mask::on_field_event(TOperable_field& o, TField_event e, long jol case F_FORNITORE: case F_CODVAL: case F_TUTTE: - if (e == fe_modify) + if (e == fe_modify && !o.empty()) { TWait_cursor hourglass; const short id = efield(F_FORNITORE).active() ? F_FORNITORE : @@ -284,6 +473,17 @@ bool TPareggio_mask::on_field_event(TOperable_field& o, TField_event e, long jol tfield(F_FT_TREE).set_tree(&_ft); _numreg = 0; disable(DLG_LINK); + disable(DLG_RECALC); + } + break; + case F_CODCAUS_C: + case F_CODCAUS_F: + if (e == fe_init) + { + TEdit_field& e = (TEdit_field&)o; + TCursor& cur = *e.browse()->cursor(); + cur = 0L; + e.set(cur.curr().get(CAU_CODCAUS)); } break; case F_NC_TREE: @@ -297,16 +497,66 @@ bool TPareggio_mask::on_field_event(TOperable_field& o, TField_event e, long jol else _numreg = 0L; enable(DLG_LINK, _numreg > 0); + + bool can_conv = false; + if (_numreg > 0 && o.dlg() == F_NC_TREE) + { + TLocalisamfile mov(LF_MOV); + mov.put(MOV_NUMREG, _numreg); + can_conv = mov.read() == NOERR && mov.get_int(MOV_TIPOMOV) == tm_fattura; + } + enable(DLG_RECALC, can_conv); } break; case DLG_LINK: if (_numreg > 0) { - TRectype mov(LF_MOV); mov.put(MOV_NUMREG, _numreg); + TRectype mov(LF_MOV); + mov.put(MOV_NUMREG, _numreg); if (mov.edit()) send_key(K_SPACE, F_TUTTE, &o); } break; + case DLG_RECALC: + if (e == fe_button) + { + TTree_field& nc = tfield(F_NC_TREE); + TPareggio_tree* nct = (TPareggio_tree*)nc.tree(); + const TRectype* nota = nct->node2rec(EMPTY_STRING); + if (nota != NULL && converti(*nota)) + send_key(K_SPACE, F_TUTTE, &o); + } + break; + case DLG_ELABORA: + if (e == fe_button) + { + TTree_field& nc = tfield(F_NC_TREE); + TTree_field& ft = tfield(F_FT_TREE); + + TPareggio_tree* nct = (TPareggio_tree*)nc.tree(); + const TRectype* nota = nct->node2rec(EMPTY_STRING); + if (nota == NULL) + return error_box(TR("Selezionare una nota di credito nel pannello di sinistra")); + + TPointer_array fatture; + TString_array a; + if (ft.selection(a) > 0) + { + TPareggio_tree* ftt = (TPareggio_tree*)ft.tree(); + FOR_EACH_ARRAY_ROW(a, r, riga) + { + const TRectype* rec = ftt->node2rec(*riga); + if (rec) + fatture.add((TRectype*)rec); + } + } + + if (fatture.items() > 0) + elabora(*nota, fatture); + else + return error_box(TR("Selezionare almeno una fattura nel pannello di destra")); + } + break; default: break; } return true; diff --git a/sc/sc0300a.h b/sc/sc0300a.h index f0214908c..0fe8c2a52 100644 --- a/sc/sc0300a.h +++ b/sc/sc0300a.h @@ -1,4 +1,6 @@ #include "sc0200b.h" -#define F_NC_TREE 121 -#define F_FT_TREE 122 \ No newline at end of file +#define F_CODCAUS_C 119 +#define F_CODCAUS_F 120 +#define F_NC_TREE 121 +#define F_FT_TREE 122 diff --git a/sc/sc0300a.uml b/sc/sc0300a.uml index 666f67899..aeb0b1d1b 100644 --- a/sc/sc0300a.uml +++ b/sc/sc0300a.uml @@ -2,15 +2,21 @@ TOOLBAR "" 0 0 0 2 -BUTTON DLG_EDIT 2 2 +BUTTON DLG_ELABORA 2 2 BEGIN - PROMPT 1 1 "Modifica" - PICTURE TOOL_EDIT + PROMPT 1 1 "Elabora" + PICTURE TOOL_ELABORA +END + +BUTTON DLG_RECALC 2 2 +BEGIN + PROMPT 2 1 "Converti" + PICTURE TOOL_CONVERT END BUTTON DLG_LINK 2 2 BEGIN - PROMPT 2 1 "Collega" + PROMPT 3 1 "Collega" PICTURE TOOL_LINK END @@ -157,7 +163,7 @@ END STRING F_CODVAL 3 BEGIN - PROMPT 61 3 "Valuta " + PROMPT 43 2 "Valuta " USE %VAL INPUT CODTAB F_CODVAL DISPLAY "Codice" CODTAB @@ -167,6 +173,36 @@ BEGIN CHECKTYPE NORMAL END +STRING F_CODCAUS_C 4 +BEGIN + PROMPT 43 3 "Causale " + USE LF_CAUSALI SELECT (TIPOMOV=2)&&(LF_RCAUSALI->TIPOCF="C") + JOIN LF_RCAUSALI INTO CODCAUS==CODCAUS + INPUT CODCAUS F_CODCAUS_C + DISPLAY "Codice" CODCAUS + DISPLAY "Descrizione@50" DESCR + DISPLAY "Tipo" TIPODOC + OUTPUT F_CODCAUS_C CODCAUS + FLAGS "GU" + CHECKTYPE REQUIRED + ADD RUN CG0 -4 + GROUP 2 +END + +STRING F_CODCAUS_F 4 +BEGIN + PROMPT 43 3 "Causale " + USE LF_CAUSALI SELECT (TIPOMOV=2)&&(LF_RCAUSALI->TIPOCF="F") + JOIN LF_RCAUSALI INTO CODCAUS==CODCAUS + INPUT CODCAUS F_CODCAUS_F + COPY DISPLAY F_CODCAUS_C + OUTPUT F_CODCAUS_F CODCAUS + FLAGS "GU" + CHECKTYPE REQUIRED + ADD RUN CG0 -4 + GROUP 3 +END + TLIST F_NC_TREE 35 -1 BEGIN PROMPT 0 5 "" diff --git a/sc/sc0300b.uml b/sc/sc0300b.uml new file mode 100644 index 000000000..6122352ba --- /dev/null +++ b/sc/sc0300b.uml @@ -0,0 +1,83 @@ +#include "sc0300a.h" + +PAGE "Assegnamento" -1 -1 75 12 + +STRING F_CODVAL 3 +BEGIN + PROMPT 1 0 "" + FLAGS "H" +END + +SPREADSHEET F_TUTTE +BEGIN + PROMPT 0 1 "" + ITEM "Importo\nnota credito@15R" + ITEM "Residuo\nrata@15R" + ITEM "Importo\nrata@15R" + ITEM "Scadenza\nrata@10" +END + +ENDPAGE + +TOOLBAR "" -2 0 0 2 + +BUTTON DLG_OK 2 2 +BEGIN + PROMPT 1 1 "" +END + +BUTTON DLG_CANCEL 2 2 +BEGIN + PROMPT 2 1 "" +END + +ENDPAGE + +ENDMASK + +PAGE "Riga 1" -1 -1 40 5 + +CURRENCY 101 15 +BEGIN + PROMPT 1 1 "Importo nota credito " + DRIVENBY -F_CODVAL +END + +CURRENCY 102 15 +BEGIN + PROMPT 1 2 "Residuo rata " + FLAGS "D" + DRIVENBY -F_CODVAL +END + +CURRENCY 103 15 +BEGIN + PROMPT 1 3 "Importo rata " + FLAGS "D" + DRIVENBY -F_CODVAL +END + +DATE 104 +BEGIN + PROMPT 1 4 "Data scadenza " + FLAGS "D" +END + +ENDPAGE + +TOOLBAR "" -2 0 0 2 + +BUTTON DLG_OK 2 2 +BEGIN + PROMPT 1 1 "" +END + +BUTTON DLG_CANCEL 2 2 +BEGIN + PROMPT 2 1 "" +END + +ENDPAGE + +ENDMASK +