diff --git a/ps/pi0002100.cpp b/ps/pi0002100.cpp index b92fc155c..7493b99be 100755 --- a/ps/pi0002100.cpp +++ b/ps/pi0002100.cpp @@ -4,12 +4,13 @@ #include #include #include -#include +#include +#include #include -#include #include "../cg/cgsaldac.h" +#include "../cg/cg2101.h" #include "pi0002.h" #include "pi0002100a.h" @@ -26,13 +27,19 @@ protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); bool on_sheet_event(TOperable_field& o, TField_event e, long jolly); + + TPartita& partita(TPartite_array& partite, int nrow); + TRiga_scadenze& rata(TPartite_array& partite, int nrow); + + bool update_mov(bool simulation); + public: - void update_scad(); + bool update_mov(); void update_sheet(); bool calc_residual(const TRiga_scadenze& scad, real& impres, bool& partially_unassigned, int& tipopag) const; bool fill_row(const TRiga_partite& rp, const TRiga_scadenze& rs, TToken_string& row, bool& partially_unassigned, bool force); - void update_total(); + void update_total(bool editing = false); TPF_mask(); virtual ~TPF_mask(); }; @@ -44,24 +51,25 @@ bool TPF_mask::on_sheet_event(TOperable_field& o, TField_event e, long jolly) { case F_PAGATO: if (e == fe_modify) - update_total(); + update_total(true); break; case F_IMPORTOANT: if (e == fe_modify) - update_total(); + update_total(true); break; case F_SHEET: switch(e) { - case se_query_del: - case se_query_add: - return false; - case se_notify_modify: - update_total(); - break; - default: - break; - } + case se_query_del: + case se_query_add: + return false; + case se_notify_modify: + update_total(); + break; + default: + break; + } + break; default: break; } @@ -74,19 +82,15 @@ bool TPF_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) switch (id) { case DLG_SAVEREC: - if (e == fe_button) + if (e == fe_button && check_fields()) { - update_scad(); + update_mov(); update_sheet(); - update_total(); } break; - case F_CLIFO: + case F_CLIENTE: if (e == fe_modify) - { update_sheet(); - update_total(); - } break; case F_SHEET: return on_sheet_event(o, e, jolly); @@ -99,43 +103,212 @@ bool TPF_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) return true; } -void TPF_mask::update_scad() +TPartita& TPF_mask::partita(TPartite_array& partite, int nrow) { - TSheet_field& s = sfield(F_SHEET); - const long items = s.items(); - int pospagato = s.cid2index(F_PAGATO); - int posanticip = s.cid2index(F_IMPORTOANT); - int posabi = s.cid2index(F_ABI); - int poscab = s.cid2index(F_CAB); - int posanno = s.cid2index(F_ANNO); - int posnumpart = s.cid2index(F_PARTITA); - int posnriga = s.cid2index(F_RIGA); - int posnrata = s.cid2index(F_RATA); - for (long pos = 0L; pos < items; pos++) - { - TToken_string row = s.row(pos); - TLocalisamfile scad(LF_SCADENZE); - scad.zero(); - scad.put(SCAD_TIPOCF, "C"); - scad.put(SCAD_GRUPPO, 0); - scad.put(SCAD_CONTO, 0); - scad.put(SCAD_SOTTOCONTO, get(F_CLIFO)); - scad.put(SCAD_ANNO, row.get(posanno)); - scad.put(SCAD_NUMPART, row.get(posnumpart)); - scad.put(SCAD_NRIGA, row.get(posnriga)); - scad.put(SCAD_NRATA, row.get(posnrata)); - if (scad.read() == NOERR) - { - const real importoant(row.get(posanticip)); - const real importopag(row.get(pospagato)); - scad.put(SCAD_IMPORTOANT, importoant-importopag); - scad.put(SCAD_CODABIPR, row.get(posabi)); - scad.put(SCAD_CODCABPR, row.get(poscab)); - scad.rewrite(); - } - } + TSheet_field& s = sfield(F_SHEET); + TToken_string& row = s.row(nrow); + const int posanno = s.cid2index(F_ANNO); + const int posnumpart = s.cid2index(F_PARTITA); + + const TBill bill(0, 0, get_long(F_CLIENTE), 'C'); + TPartita& game = partite.partita(bill, row.get_int(posanno), row.get(posnumpart)); + return game; } +TRiga_scadenze& TPF_mask::rata(TPartite_array& partite, int nrow) +{ + TSheet_field& s = sfield(F_SHEET); + const TToken_string& row = s.row(nrow); + const int posnriga = s.cid2index(F_RIGA); + const int posnrata = s.cid2index(F_RATA); + int nriga, nrata; + row.get(posnriga, nriga); + row.get(posnrata, nrata); + return partita(partite, nrow).rata(nriga, nrata); +} + +bool TPF_mask::update_mov(bool simulation) +{ + TLog_report log(main_app().title()); + + bool can_write = !simulation; + bool done = true; + + TSheet_field& s = sfield(F_SHEET); + const int pospagato = s.cid2index(F_PAGATO); + const int posanticip = s.cid2index(F_IMPORTOANT); + const int posabi = s.cid2index(F_ABI); + const int poscab = s.cid2index(F_CAB); + const int posanno = s.cid2index(F_ANNO); + const int posnumpart = s.cid2index(F_PARTITA); + const int posnriga = s.cid2index(F_RIGA); + const int posnrata = s.cid2index(F_RATA); + TToken_string key; + + const long cliente = get_long(F_CLIENTE); + key = "C"; key.add(cliente); + const TRectype& clifo = cache().get(LF_CLIFO, key); + + TBill conto_cliente; + key = get(F_CODCAUS); key.add(1); + const TRectype& rcaus1 = cache().get(LF_RCAUSALI, key); + const char sez1 = rcaus1.get_char(RCA_SEZIONE); + const char sez2 = sez1 == 'A' ? 'D' : 'A'; + + conto_cliente.get(rcaus1); + conto_cliente.codclifo() = cliente; + if (!conto_cliente.find()) + { + conto_cliente.get(clifo); + if (!conto_cliente.find()) + { + log.log(2, TR("Impossibile determinare il conto cliente: controllare la causalo e/o l'anagrafica")); + can_write = done = false; + } + } + + TPartite_array partite; + + FOR_EACH_SHEET_ROW(s, pos, row) + { + const TString8 abi = row->get(posabi); + const TString8 cab = row->get(poscab); + if (abi.blank() || cab.blank()) + continue; + + const real importopag(row->get(pospagato)); + const real importoant(row->get(posanticip)); + const real anticipo = importoant <= importopag ? ZERO : importoant-importopag; + + TRiga_scadenze& scad = rata(partite, pos); + TString msg; + msg << TR("Elaborazione Partita ") << scad.get_int(SCAD_ANNO) << '/' << scad.get_int(SCAD_NUMPART) + << TR(" Riga:") << scad.get(SCAD_NRIGA) << TR(" Rata:") << scad.get(SCAD_NRATA); + log.log(0, msg); + + scad.put(SCAD_IMPORTOANT, anticipo); + scad.put(SCAD_CODABIPR, row->get(posabi)); + scad.put(SCAD_CODCABPR, row->get(poscab)); + + if (importopag > ZERO) + { + TMovimentoPN mov; + TRectype& head = mov.curr(); + head.put(MOV_CODCAUS, get(F_CODCAUS)); + head.put(MOV_DATAREG, get(F_DATAMOV)); + head.put(MOV_TOTDOC, importopag); + + TBill conto_banca; + key = abi; key << cab; + const TRectype& bnp = cache().get("BNP", key); + conto_banca.set(bnp.get_int("I0"), bnp.get_int("I1"), bnp.get_long("I2")); + if (!conto_banca.find()) + { + log.log(2, TR("Impossibile determinare il conto della banca di presentazione")); + can_write = done = false; + } + + TRectype& riga1 = mov.cg(0); + riga1.put(RMV_SEZIONE, sez1); + riga1.put(RMV_IMPORTO, importopag); + riga1.put(RMV_ROWTYPE, 'K'); + conto_cliente.put(riga1, false); + conto_banca.put(riga1, true); + + TRectype& riga2 = mov.cg(1); + riga2.put(RMV_SEZIONE, sez2); + riga2.put(RMV_IMPORTO, importopag); + riga2.put(RMV_ROWTYPE, 'I'); + conto_banca.put(riga2, false); + conto_cliente.put(riga2, true); + + int err = NOERR; + if (can_write) + { + err = mov.write(true); + if (err == NOERR) + { + TString msg; + msg << TR("Generazione movimento di pagamento ") << head.get_long(MOV_NUMREG); + log.log(0, msg); + } + else + { + TString msg; + msg << TR("Impossibile creare il movimento di pagamento: errore ") << err; + log.log(2, msg); + can_write = done = false; + } + } + + if (err == NOERR) + { + TPartita& game = scad.partita(); + + TRiga_partite& rigap = game.new_row(); + const int nrigp = rigap.get_int(PART_NRIGA); + rigap.put(PART_NREG, head.get_long(MOV_NUMREG)); + rigap.put(PART_NUMRIG, mov.cg(0).get(RMV_NUMRIG)); + rigap.put(PART_SEZ, mov.cg(0).get(RMV_SEZIONE)); + rigap.put(PART_DATAREG, head.get(MOV_DATAREG)); + rigap.put(PART_DATADOC, head.get(MOV_DATADOC)); + rigap.put(PART_DATAPAG, head.get(MOV_DATAREG)); + rigap.put(PART_NUMDOC, head.get(MOV_NUMDOC)); + rigap.put(PART_DESCR, head.get(MOV_DESCR)); + rigap.put(PART_CODCAUS, head.get(MOV_CODCAUS)); + + TRectype pagsca = scad.new_row(nrigp); + pagsca.put(PAGSCA_IMPORTO, importopag); + pagsca.put(PAGSCA_CODABIPR, abi); + pagsca.put(PAGSCA_CODCABPR, cab); + conto_banca.put(pagsca, true); + if (scad.get_long(SCAD_CODCAB)>0) + { + pagsca.put(PAGSCA_CODABI, scad.get(SCAD_CODABI)); + pagsca.put(PAGSCA_CODCAB, scad.get(SCAD_CODCAB)); + } + else + { + pagsca.put(PAGSCA_CODABI, clifo.get(CLI_CODABI)); + pagsca.put(PAGSCA_CODCAB, clifo.get(CLI_CODCAB)); + } + game.modifica_pagamento(pagsca, TValuta(), true); + } + } + } + + if (can_write) + { + TString msg; + msg << TR("Aggiornamento di ") << partite.items() << TR(" partite"); + log.log(0, msg); + if (!partite.write(true)) + { + log.log(2, TR("Errore di aggiornamento del saldaconto")); + can_write = done = false; + } + } + + if (!done || !simulation) + log.preview(); + + return done; +} + +bool TPF_mask::update_mov() +{ + bool done = update_mov(true); // Simulation + if (done) + { + if (yesno_box(TR("Non sono stati rilevati errori formali:\nSi desidera proseguire con l'aggiornamento del saldaconto?"))) + done = update_mov(false); // Write on DB + } + else + error_box(TR("Sono stati rilevati errori formali che impediscono l'aggiornamento del saldaconto")); + return done; +} + + // Calcola il residuo di una rata tenendo conto anche degli eventuali // effetti non ancora contabilizzati bool TPF_mask::calc_residual(const TRiga_scadenze& scad, real& impres, @@ -189,7 +362,7 @@ bool TPF_mask::calc_residual(const TRiga_scadenze& scad, real& impres, return !impres.is_zero(); } -void TPF_mask::update_total() +void TPF_mask::update_total(bool editing) { const TSheet_field& s = sfield(F_SHEET); const int postop = s.cid2index(F_PAGATO); @@ -197,7 +370,7 @@ void TPF_mask::update_total() real tota, totp; FOR_EACH_SHEET_ROW_BACK(s, r, row) { - if (r == s.selected()) + if (editing && r == s.selected()) { const TMask& rm = s.sheet_row_mask(r); totp += rm.get_real(F_PAGATO); @@ -211,7 +384,7 @@ void TPF_mask::update_total() } set(F_TOTALEPAG, totp); set(F_TOTALEANT, tota); - enable(DLG_SAVEREC, !tota.is_zero()||!totp.is_zero()); + enable(DLG_SAVEREC, !tota.is_zero() || !totp.is_zero()); } bool TPF_mask::fill_row(const TRiga_partite& rp, const TRiga_scadenze& rs, TToken_string& row, bool& partially_unassigned, bool force) @@ -258,7 +431,7 @@ void TPF_mask::update_sheet() TRelation rel(LF_PARTITE); TRectype& filter = rel.curr(); filter.put(PART_TIPOCF, 'C'); - filter.put(PART_SOTTOCONTO, get(F_CLIFO)); + filter.put(PART_SOTTOCONTO, get(F_CLIENTE)); const char* filtro = "(CHIUSA!=\"X\")&&(TIPOMOV==1)"; TCursor partite(&rel, filtro, 1, &filter, &filter); @@ -322,6 +495,7 @@ void TPF_mask::update_sheet() xvtil_statbar_set(msg); } // if ci sono partite sheet.force_update(); + update_total(); } TPF_mask::TPF_mask() : TAutomask("pi0002100a") @@ -349,7 +523,7 @@ public: void TPresent_fatture::main_loop() { - open_files(LF_TABCOM, LF_TAB, LF_CLIFO, LF_CFVEN, LF_PARTITE, LF_SCADENZE, LF_PAGSCA, 0); + open_files(LF_TABCOM, LF_TAB, LF_CLIFO, LF_PARTITE, LF_SCADENZE, LF_PAGSCA, LF_CAUSALI, LF_RCAUSALI, 0); TPF_mask m; while (m.run() != K_QUIT) { diff --git a/ps/pi0002100a.h b/ps/pi0002100a.h index 6cd1ae7b8..4668743b1 100755 --- a/ps/pi0002100a.h +++ b/ps/pi0002100a.h @@ -1,8 +1,9 @@ -#define F_CLIFO 201 -#define F_RAGSOCCF 202 +#define F_CLIENTE 201 +#define F_RAGSOC 202 #define F_DATAMOV 203 #define F_TOTALEANT 204 #define F_TOTALEPAG 205 +#define F_CODCAUS 206 #define F_SHEET 300 diff --git a/ps/pi0002100a.uml b/ps/pi0002100a.uml index 8b2f31f90..244c93373 100755 --- a/ps/pi0002100a.uml +++ b/ps/pi0002100a.uml @@ -20,32 +20,32 @@ BEGIN PROMPT 1 0 "@bParametri" END -NUMBER F_CLIFO 6 +NUMBER F_CLIENTE 6 BEGIN PROMPT 2 1 "Cliente " USE LF_CLIFO SELECT LF_PARTITE->ANNO>0 JOIN LF_PARTITE INTO TIPOC=TIPOCF SOTTOCONTO=CODCF INPUT TIPOCF "C" SELECT - INPUT CODCF F_CLIFO + INPUT CODCF F_CLIENTE DISPLAY "Codice" CODCF DISPLAY "Ragione Sociale@50" RAGSOC DISPLAY "Partita IVA" PAIV - OUTPUT F_CLIFO CODCF - OUTPUT F_RAGSOCCF RAGSOC + OUTPUT F_CLIENTE CODCF + OUTPUT F_RAGSOC RAGSOC CHECKTYPE REQUIRED ADD RUN cg0 -1 END -STRING F_RAGSOCCF 50 +STRING F_RAGSOC 50 BEGIN PROMPT 22 1 "" USE LF_CLIFO KEY 2 INPUT TIPOCF "C" SELECT - INPUT RAGSOC F_RAGSOCCF + INPUT RAGSOC F_RAGSOC DISPLAY "Ragione Sociale@50" RAGSOC DISPLAY "Partita IVA" PAIV DISPLAY "Codice" CODCF - COPY OUTPUT F_CLIFO + COPY OUTPUT F_CLIENTE CHECKTYPE SEARCH ADD RUN cg0 -1 END @@ -53,6 +53,24 @@ END DATE F_DATAMOV BEGIN PROMPT 2 2 "Data movimento " + FLAGS "A" + CHECKTYPE REQUIRED +END + +STRING F_CODCAUS 3 +BEGIN + PROMPT 50 2 "Causale " + USE LF_CAUSALI SELECT (TIPOMOV>="3")&&(LF_RCAUSALI->TIPOCF=="C") + JOIN LF_RCAUSALI INTO CODCAUS=CODCAUS NRIGA=1 + INPUT CODCAUS F_CODCAUS + DISPLAY "Codice" CODCAUS + DISPLAY "Descrizione@50" DESCR + DISPLAY "Tipo Movimento" TIPOMOV + DISPLAY "Gruppo" LF_RCAUSALI->GRUPPO + DISPLAY "Conto" LF_RCAUSALI->CONTO + OUTPUT F_CODCAUS CODCAUS + CHECKTYPE REQUIRED + ADD RUN cg0 -4 END CURRENCY F_TOTALEANT @@ -121,6 +139,8 @@ BEGIN PROMPT 16 3 "CAB " COPY ALL F_ABI FLAGS "Z" + VALIDATE REQIF_FUNC 2 F_PAGATO F_IMPORTOANT + WARNING "La banca di presentazione e' obbligatoria in presenza di pagamento o anticipo" END CURRENCY F_IMPORTO 18