#include #include #include // Serve per DLG_NEWREC #ifndef __EXTRA__ #include "cg2102.h" // Applicazione di prima nota #include "cg2100.h" // Campi maschere prima nota #endif #include "cg2100p.h" // Campi maschere partite e pagamenti #include // Archivio clienti/fornitori #include // Archivio movimenti di prima nota #include // Archivio pagamenti #include // Archivio partite #include // Archivio scadenze /////////////////////////////////////////////////////////// // Maschera pagamenti /////////////////////////////////////////////////////////// class TPay_mask : public TMask { real _da_pagare, _pagabile; TValuta _valuta; protected: static bool importo_handler(TMask_field& f, KEY k); public: void set_pag(const TRectype& oldpag, const TRiga_scadenze& scad, const TImporto& importo); void get_pag(TRectype& oldpag) const; const TValuta& valuta() const { return _valuta; } TPay_mask(); virtual ~TPay_mask() {} }; TPay_mask::TPay_mask() : TMask("cg2100s") { } void TPay_mask::set_pag(const TRectype& oldpag, const TRiga_scadenze& scad, const TImporto& importo) { TRelation rel(LF_PAGSCA); // Working relation rel.curr() = oldpag; autoload(&rel); // Load current record on mask const TPartita& p = scad.partita(); const int nrigp = oldpag.get_int(PAGSCA_NRIGP); const TRiga_partite& sum = p.riga(nrigp); const TRiga_partite& fatt = scad.riga(); set(S_NUMDOC, fatt.get(PART_NUMDOC)); // Numero documento set(S_DATADOC, fatt.get(PART_DATADOC)); // Data documento set(S_NUMPROT, fatt.get(PART_PROTIVA)); // Protocollo IVA set(S_DESCR, sum.get(PART_DESCR)); // Descrizione documento set(S_DATA_SCAD, scad.get(SCAD_DATASCAD)); // Data della scadenza set(S_SEZIONE_SCAD, scad.riga().sezione()); // Sezione della rata set(S_IMPORTO_SCAD, scad.get(SCAD_IMPORTO)); // Importo della rata set(S_IMPORTOVAL_SCAD, scad.get(SCAD_IMPORTOVAL)); // Importo in valuta const bool in_valuta = scad.in_valuta(); _da_pagare = scad.residuo(in_valuta).valore(); // Calcola residuo in valuta TReal_field& res = (TReal_field&)field(S_RESIDUORATA); res.set_decimals(in_valuta ? 2 : 0); res.set(_da_pagare.string()); set_handler(in_valuta ? S_IMPORTOVAL : S_IMPORTO, importo_handler); // Ricorda l'importo da pagare _da_pagare += oldpag.get_real(in_valuta ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO); // Attiva campi relativi alla valuta show(-3, in_valuta); const long numreg = sum.get_long(PART_NREG); const int numrig = sum.get_int(PART_NUMRIG); _valuta.get(sum); TReal_field& resp = (TReal_field&)field(S_RESIDUOPAG); resp.set_decimals(in_valuta ? 2 : 0); TImporto r(importo); r -= app().partite().importo_speso(numreg, numrig); if (in_valuta) _pagabile = _valuta.lit2val(r.valore()); else _pagabile = r.valore(); resp.set(_pagabile.string()); _pagabile += oldpag.get_real(in_valuta ? PAGSCA_IMPORTOVAL : PAGSCA_IMPORTO); // Il flag di saldo/acconto e' attivo solo se non ci sono acconti bool sa = oldpag.get_int(PAGSCA_NRIGA) != TPartita::UNASSIGNED; if (sa) { const TDate datasca(fatt.get(PART_DATADOC)); const TDate datapag(sum.get(PART_DATADOC)); sa = datapag >= datasca; } else { hide(S_RESIDUORATA); } enable(S_SALDOACC, sa); #ifdef __EXTRA__ hide(S_RESIDUOPAG); const bool disabilita = TRUE; #else const bool disabilita = app().causale().tipomov() == 2; #endif if (disabilita) send_key(K_CTRL + K_SHIFT + 'c', -2); // Disabilita contropartita e ritenute } void TPay_mask::get_pag(TRectype& newpag) const { TRelation rel(LF_PAGSCA); // Working relation rel.curr() = newpag; autosave(&rel); // Load current record from mask newpag = rel.curr(); } bool TPay_mask::importo_handler(TMask_field& f, KEY k) { TPay_mask& m = (TPay_mask&)f.mask(); if (k == K_F8) { const real& imp = fnc_min(m._da_pagare, m._pagabile); f.set(imp.string()); k = K_TAB; } if (k == K_TAB && f.focusdirty()) { const real i(f.get()); if (i >= m._da_pagare && m.field(S_SALDOACC).active()) m.set(S_SALDOACC, "S"); const real residuo(m._da_pagare - i); m.set(S_RESIDUORATA, residuo.string()); const real residuopag(m._pagabile - i); m.set(S_RESIDUOPAG, residuopag.string()); if (f.dlg() == S_IMPORTOVAL) { const real lit = m.valuta().val2lit(i); m.set(S_IMPORTO, lit.string()); } } return TRUE; } /////////////////////////////////////////////////////////// // Maschera partite /////////////////////////////////////////////////////////// class TGame_mask : public TMask { const TBill _conto; // Conto fisso del cliente/fornitore long _numreg; // Numero movimento contabile int _numrig; // Riga contabile corrente (prima = 1!) TImporto _importo; // Importo riga contabile int _riga_partite; // Riga corrente delle partite bool _changed; int _tipomov; // Dati per la creazione di un nuovo movimento char _sezione; TDate _datadoc; TString _codpag, _descr, _numdoc; protected: static bool annopart_handler(TMask_field& f, KEY k); static bool numpart_handler(TMask_field& f, KEY k); static bool partite_notify(TSheet_field& partite, int r, KEY k); static bool scadenze_notify(TSheet_field& partite, int r, KEY k); static bool show_all_handler(TMask_field& f, KEY k); static bool edit_scadenza_handler(TMask_field& f, KEY k); static bool nuovo_handler(TMask_field& f, KEY k); static bool cambio_handler(TMask_field& f, KEY k); static void add_importo(TToken_string& s, const TImporto& i, bool val = FALSE, int pos = -1); TImporto get_importo(TToken_string& s, int pos) const; void fill_partite(int anno = 0, const char* numero = ""); real aggiorna_residuo(); int update_partita(const TPartita& game, int prow); void update_saldo_clifo(); int nuova_riga(TPartita& partita) const; int nuovo_pagamento(TPartita& partita, int nriga, int rata) const; bool edit_pagamento(TPartita& p, int nriga, int nrata, int nrigp) const; bool same_number(const char* s1, const char* s2) const; #ifdef __EXTRA__ bool edit_fattura(TPartita& p, int nriga); void prima_nota(const long nreg); #endif bool cerca_valuta(TValuta& val) const; void aggiorna_valuta(const TValuta& val); public: TSheet_field& partite() const { return (TSheet_field&)field(P_PARTITE); } TSheet_field& scadenze() const { return (TSheet_field&)field(P_SCADENZE); } const TBill& conto() const { return _conto; } bool changed() const { return _changed; } TGame_mask(const TBill& bill, long numreg, int riga); virtual ~TGame_mask() {} }; TGame_mask::TGame_mask(const TBill& bill, long numreg, int riga) : TMask("cg2100p"), _conto(bill), _numreg(numreg), _numrig(riga), _changed(FALSE) { const char tipocf[2] = { _conto.tipo(), '\0' }; set(P_TIPOC, tipocf); set(P_GRUPPO, _conto.gruppo()); set(P_CONTO, _conto.conto()); set(P_SOTTOCONTO, _conto.sottoconto()); set(P_DESCR, ((TBill&)_conto).descrizione()); TValuta val; #ifndef __EXTRA__ TMask& cm = app().curr_mask(); val.get(cm, S_VALUTA, S_DATACAMBIO, S_CAMBIO); #endif cerca_valuta(val); val.set(*this, P_VALUTA, P_DATACAMBIO, P_CAMBIO); enable(-3, val.in_valuta()); set_handler(P_ANNO, annopart_handler); set_handler(P_NUMERO, numpart_handler); set_handler(P_SHOWALL, show_all_handler); set_handler(P_NUOVO, nuovo_handler); set_handler(P_CAMBIO, cambio_handler); partite().set_notify(partite_notify); scadenze().set_notify(scadenze_notify); scadenze().sheet_mask().set_handler(100, edit_scadenza_handler); } /////////////////////////////////////////////////////////// // Handlers dei campi e della maschera principale /////////////////////////////////////////////////////////// bool TGame_mask::annopart_handler(TMask_field& f, KEY k) { if (k == K_TAB && f.focusdirty() && f.get().not_empty()) { TMask_field& n = f.mask().field(P_NUMERO); n.set_dirty(); numpart_handler(n, k); } return TRUE; } bool TGame_mask::numpart_handler(TMask_field& f, KEY k) { if (k == K_TAB && f.dirty()) { const TGame_mask& m = (const TGame_mask&)f.mask(); const int anno = m.get_int(P_ANNO); const TString16 num = f.get(); if (anno > 0 && num.not_empty()) { TSheet_field& sheet = m.partite(); for (int i = 0; i < sheet.items(); i++) { TToken_string& row = sheet.row(i); if (anno == row.get_int(0)) // Se corrisponde l'anno e ... { TString16 n = row.get(); n.trim(); if (num == n) // corrisponde il numero partita ... { sheet.select(i); // ... seleziona la partita partite_notify(sheet, i, K_TAB); // ed esplodi le sue righe break; } } } if (i >= sheet.items()) f.warning_box("Partita inesistente"); } } return TRUE; } bool TGame_mask::show_all_handler(TMask_field& f, KEY k) { if (k == K_SPACE) { TGame_mask& gm = (TGame_mask&)f.mask(); gm.fill_partite(); } return TRUE; } bool TGame_mask::cambio_handler(TMask_field& f, KEY k) { if (k == K_TAB && f.focusdirty() && yesno_box("Aggiornare gli importi dei pagamenti?")) { TGame_mask& gm = (TGame_mask&)f.mask(); TValuta val; val.get(gm, P_VALUTA, P_DATACAMBIO, P_CAMBIO); gm.aggiorna_valuta(val); } return TRUE; } /////////////////////////////////////////////////////////// // Metodi dei campi e della maschera principale /////////////////////////////////////////////////////////// // Aggiorna il campo con il residuo da spendere sui pagamenti real TGame_mask::aggiorna_residuo() { #ifdef __EXTRA__ return ZERO; #else _importo = app().get_cgs_imp(_numrig-1); // Importo sulla riga contabile TImporto residuo(_importo); residuo -= app().partite().importo_speso(_numreg, _numrig); // Sottraggo importi spesi set(P_RESIDUO, residuo.valore()); return residuo.valore(); #endif } // Scandisce tutte le partite per cercare la prima del movimento corrente e la sua valuta bool TGame_mask::cerca_valuta(TValuta& val) const { bool found = FALSE; TPartite_array& pa = app().partite(); for (const TPartita* game = pa.first(); game; game = pa.next()) { const int r = game->mov2rig(_numreg, _numrig); if (r > 0) { const TRiga_partite& row = game->riga(r); val.get(row); found = TRUE; break; } } return found; } void TGame_mask::aggiorna_valuta(const TValuta& val) { int annorif = 0; TString16 numrif; TPartite_array& pa = app().partite(); for (TPartita* game = pa.first(); game; game = pa.next()) { for (int r = game->last(); r > 0; r = game->pred(r)) { const TRiga_partite& riga = game->riga(r); for (int s = riga.rate(); s > 0; s--) { const TRiga_scadenze& scad = riga.rata(s); for (int p = scad.last(); p > 0; p = scad.pred(p)) { TRiga_partite& sum = game->riga(p); if (sum.get_long(PART_NREG) == _numreg && sum.get_int(PART_NUMRIG) == _numrig) { if (annorif == 0) { annorif = sum.get_int(PART_ANNO); numrif = sum.get(PART_NUMPART); } TRectype pag(scad.row(p)); real imp(pag.get(PAGSCA_IMPORTOVAL)); val.val2lit(imp); pag.put(PAGSCA_IMPORTO, imp); // Converte in lire l'importo in valuta #ifdef __EXTRA__ game->modifica_pagamento(pag); #else app().notify_edit_pagamento(*game, pag, val); #endif } } } } } #ifndef __EXTRA__ if (annorif != 0) { const bool proponi = app().causale().tipomov() == 2; if (proponi) { const TMask& cm = app().curr_mask(); const int anno = cm.get_int(F_ANNORIF); if (anno != 0) { annorif = anno; numrif = cm.get(F_NUMRIF); } } } #endif fill_partite(annorif, numrif); } bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k) { TGame_mask& gm = (TGame_mask&)partite.mask(); if (k == K_TAB) { gm._riga_partite = r; TString_array& scadenze = gm.scadenze().rows_array(); scadenze.destroy(); TToken_string& row = partite.row(r); const int anno = row.get_int(0); // Anno partita const TString16 num = row.get(); // Numero partita gm.set(P_ANNO, anno); // Aggiorna campi di ricerca gm.set(P_NUMERO, num); if (anno > 0) { const TBill& zio = gm.conto(); // Conto cliente/fornitore TPartita* game = app().partite().exist(zio, anno, num); // Cerca la partita tra quelle editate const bool should_delete_game = (game == NULL); // Ricorda di fare delete if (should_delete_game) // Se non c'era ... game = new TPartita(zio, anno, num); // ... creane una temporanea TImporto tot_lit, tot_val; TToken_string riga_fattura; const int lastrow = game->last(); for (int ri = game->first(); ri <= lastrow; ri = game->succ(ri)) { const TRiga_partite& riga = game->riga(ri); const bool in_valuta = riga.in_valuta(); if (riga.rate() > 0) // Se ci sono rate stampa la riga con la fattura { riga_fattura.add(ri); riga_fattura.add(""); riga_fattura.add(""); riga_fattura.add(riga.get(PART_DATADOC)); riga_fattura.add(riga.get(PART_DESCR)); add_importo(riga_fattura, TImporto(riga.sezione(), riga.get_real(SCAD_IMPORTO))); if (in_valuta) add_importo(riga_fattura, TImporto(riga.sezione(), riga.get_real(SCAD_IMPORTOVAL)), TRUE); else riga_fattura.add(""); riga_fattura.add(riga.get(PART_NREG)); riga_fattura.add(riga.get(PART_DATAREG)); riga_fattura.add(riga.get(PART_NUMDOC)); riga_fattura.add(riga.get(PART_PROTIVA)); scadenze.add(riga_fattura); } for (int ra = 1; ra <= riga.rate(); ra++) { const TRiga_scadenze& scad = riga.rata(ra); TToken_string& row = scadenze.row(scadenze.add(riga_fattura)); row.add(ra, 1); row.add(scad.get(SCAD_DATASCAD), 2); add_importo(row, TImporto(riga.sezione(), scad.get_real(SCAD_IMPORTO)), FALSE, 5); if (in_valuta) add_importo(row, TImporto(riga.sezione(), scad.get_real(SCAD_IMPORTOVAL)), TRUE, 6); const int lastp = scad.last(); for (int pa = scad.first(); pa <= lastp; pa = scad.succ(pa)) { const TRectype& pag = scad.row(pa); const TRiga_partite& sum = game->riga(pa); const char sez = sum.sezione(); TToken_string& row = scadenze.row(scadenze.add("")); row.add(ri); row.add(ra); row.add(scad.get(SCAD_DATASCAD)); row.add(sum.get(PART_DATADOC)); row.add(sum.get(PART_DESCR)); add_importo(row, TImporto(sez, pag.get_real(PAGSCA_IMPORTO))); if (in_valuta) add_importo(row, TImporto(sez, pag.get_real(PAGSCA_IMPORTOVAL)), 2); else row.add(""); row.add(sum.get(PART_NREG)); row.add(sum.get(PART_DATAREG)); row.add(sum.get(PART_NUMDOC)); row.add(""); row.add(pa); } TImporto abb(scad.importo_pagato(TRUE, 0x2)); if (!abb.is_zero()) { TToken_string& rabb = scadenze.row(scadenze.add("")); rabb.add("Abbuoni rata ", 4); rabb << ra; if (in_valuta) { add_importo(rabb, scad.importo_pagato(FALSE, 0x2)); add_importo(rabb, abb); } else { add_importo(rabb, abb, TRUE); rabb.add(""); } } if (in_valuta) { TImporto diff(scad.importo_pagato(FALSE, 0x4)); if (!diff.is_zero()) { TToken_string& rdiff = scadenze.row(scadenze.add("")); rdiff.add("Differ. cambio rata ", 4); rdiff << ra; add_importo(rdiff, diff.normalize()); } } TToken_string& rsal = scadenze.row(scadenze.add("")); rsal.add("Saldo rata ", 4); rsal << ra; if (!scad.chiusa()) { TImporto sl(scad.residuo(FALSE, 0x7)); sl.normalize(); add_importo(rsal, sl); tot_lit += sl; if (in_valuta) { sl = scad.residuo(TRUE, 0x3); sl.normalize(); add_importo(rsal, sl, TRUE); tot_val += sl; } } } TRecord_array& unas = game->unassigned(); const int lastp = unas.last_row(); for (int pa = unas.first_row(); pa <= lastp; pa = unas.succ_row(pa)) { const TRectype& pag = unas.row(pa); const TRiga_partite& sum = game->riga(pa); TImporto imp(sum.sezione(), ZERO); TToken_string& row = scadenze.row(scadenze.add("")); row.add(pag.get(PAGSCA_NRIGA)); row.add(pag.get(PAGSCA_NRATA)); row.add(""); row.add(sum.get(PART_DATADOC)); row.add(sum.get(PART_DESCR)); TImporto i(sum.sezione(), pag.get_real(PAGSCA_IMPORTO)); i.normalize(); tot_lit += i; add_importo(row, i); if (in_valuta) { i = TImporto(sum.sezione(), pag.get_real(PAGSCA_IMPORTOVAL)); tot_val += i; i.normalize(); add_importo(row, i, TRUE); } else row.add(""); row.add(sum.get(PART_NREG)); row.add(sum.get(PART_DATAREG)); row.add(sum.get(PART_NUMDOC)); row.add(""); row.add(pa); } } if (lastrow > 0) { TToken_string& sp = scadenze.row(scadenze.add("")); sp.add("Saldo ", 4); sp << anno << ' ' << num; add_importo(sp, tot_lit.normalize()); add_importo(sp, tot_val.normalize(), TRUE); } if (should_delete_game) delete game; } gm.scadenze().force_update(); } if (k == K_INS) { gm.send_key(K_CTRL + 'N', 0, &partite); // Simula la pressione del tasto nuovo return FALSE; // Rifiuta l'aggiunta di una riga } return TRUE; } bool TGame_mask::scadenze_notify(TSheet_field& scadenze, int r, KEY k) { if (k == K_INS) { TGame_mask& gm = (TGame_mask&)scadenze.mask(); gm.send_key(K_CTRL + 'N', 0, &scadenze); // Simula la pressione del tasto nuovo return FALSE; // Rifiuta l'aggiunta di una riga } return TRUE; } int TGame_mask::nuova_riga(TPartita& partita) const { TRiga_partite& part = partita.new_row(); // Creazione nuova riga vuota const int nriga = part.get_int(PART_NRIGA); // Copia dati movimento corrente part.put(PART_NREG, _numreg); // Numero operazione part.put(PART_NUMRIG, _numrig); // Riga su cui ho cliccato // Forza il gruppo/conto cliente corretto part.put(PART_GRUPPOCL, conto().gruppo()); part.put(PART_CONTOCL, conto().conto()); // Setta il cambio corrente const real cambio(get(P_CAMBIO)); part.put(PART_CAMBIO, cambio); part.put(PART_CODVAL, get(P_VALUTA)); part.put(PART_DATACAM, get(P_DATACAMBIO)); #ifdef __EXTRA__ part.put(PART_TIPOMOV, _tipomov); part.put(PART_DESCR, _descr); part.put(PART_NUMDOC, _numdoc); part.put(PART_DATADOC, _datadoc); part.put(PART_DATAREG, TDate(TODAY)); part.put(PART_SEZ, _sezione); part.put(PART_SEZABB, _sezione); part.put(PART_SEZDIFCAM,_sezione); if (_tipomov == 1) { part.put(PART_IMPORTO, _importo.valore()); if (!cambio.is_zero()) { real impval = _importo.valore(); impval /= cambio; impval.round(2); part.put(PART_IMPORTOVAL, impval); } } #else TMask& cm = app().curr_mask(); const TCausale& causale = app().causale(); const int tipomov = causale.tipomov(); part.put(PART_TIPOMOV, tipomov); part.put(PART_DESCR, cm.get(F_DESCR)); part.put(PART_NUMDOC, cm.get(F_NUMDOC)); part.put(PART_DATADOC, cm.get(F_DATADOC)); part.put(PART_DATAREG, cm.get(F_DATAREG)); // Copia dati causale corrente part.put(PART_CODCAUS, causale.codice()); if (causale.iva() != nessuna_iva) { part.put(PART_REG, cm.get(F_CODREG)); part.put(PART_PROTIVA, cm.get(F_PROTIVA)); } const char tipoc = conto().tipo(); // Complesso algoritmo per calcolare la sezione di una nuova riga partita char sezione = causale.sezione(1); // Usa la sezione della causale if (sezione <= ' ') // Se non c'e' la sezione bell'e' ch'e' pronta { if (tipomov == 1 || tipomov == 5) // calcola in base al tipo movimento e sezione = (tipoc == 'C') ? 'D' : 'A'; // al tipo cliente/fornitore else sezione = (tipoc == 'C') ? 'A' : 'D'; } if (tipoc > ' ') // Se il tipo e' C o F { TBill bill; causale.bill(1, bill); // Legge primo conto causale if (bill.tipo() != tipoc) sezione = (sezione == 'D') ? 'A' : 'D'; // scambia segno } // Memorizza solo la sezione (importi nulli) part.put(PART_SEZ, sezione); part.put(PART_SEZABB, sezione); part.put(PART_SEZDIFCAM, sezione); #endif return nriga; } int TGame_mask::nuovo_pagamento(TPartita& partita, int nriga, int rata) const { const TBill& conto = partita.conto(); // Legge conto principale int nrigp = partita.mov2rig(_numreg, _numrig); // Cerca riga partita relativa alla riga rmov if (nrigp <= 0) // Devo creare una nuova riga di partita nrigp = nuova_riga(partita); TRectype& pagamento = partita.pagamento(nriga, rata, nrigp); // Crea nuovo pagamento int caus = 2; // Calcola riga causale per la contropartita in base al tipo pagamento if (rata != TPartita::UNASSIGNED) { const TRiga_scadenze& scad = partita.rata(nriga, rata); const int tp = scad.get_int(SCAD_TIPOPAG); switch (tp) { case 2: // Tratta case 7: // Tratta accettata caus = 3; break; case 3: // Ricevuta bancaria caus = 4; break; case 4: // Cessione caus = 5; break; case 5: // Paghero' caus = 6; break; case 6: // Fattura di credito caus = 7; break; case 1: // Rimessa case 8: // Rapporti interbancari diretti case 9: // Bonifico default: caus = 2; break; } pagamento.put(PAGSCA_TIPOPAG, tp); pagamento.put(PAGSCA_CODABIPR, scad.get(SCAD_CODABIPR)); pagamento.put(PAGSCA_CODCABPR, scad.get(SCAD_CODCABPR)); pagamento.put(PAGSCA_CODABI, scad.get(SCAD_CODABI)); pagamento.put(PAGSCA_CODCAB, scad.get(SCAD_CODCAB)); pagamento.put(PAGSCA_CODAG, scad.get(SCAD_CODAG)); pagamento.put(PAGSCA_DATAPAG, _datadoc); } #ifndef __EXTRA__ const TCausale& causale = app().causale(); TBill contro; causale.bill(caus, contro); // Legge conto contropartita if (caus != 2 && contro.empty()) // Se non specificato ... causale.bill(caus = 2, contro); // ... prende il primo contro.put(pagamento, TRUE); // Scrive conto contropartita #endif return nrigp; } bool TGame_mask::edit_scadenza_handler(TMask_field& f, KEY k) { if (k == K_SPACE) { TMask& m = f.mask(); const int nriga = m.get_int(101); if (nriga == 0) return FALSE; // Ho cliccato su di un saldo (per sbaglio!) TGame_mask& gm = (TGame_mask&)(m.get_sheet()->mask()); TMask_field& cambio = gm.field(P_CAMBIO); if (cambio.active() && cambio.get().empty()) return f.error_box("E' necessario specificare un cambio"); const TBill& bill = gm.conto(); const int anno = gm.get_int(P_ANNO); const TString16 numero = gm.get(P_NUMERO); TPartita& game = app().partite().partita(bill, anno, numero); long nreg = m.get_long(108); // Numero registrazione const int nrata = m.get_int(102); // Rata selezionata (puo' essere 0) int nrigp = m.get_int(112); // Pagamento selezionato (puo' essere 0) if (nrata != 0 && nrigp == 0) { #ifdef __EXTRA__ gm._tipomov = 3; gm._descr = ""; gm._numdoc = ""; gm._datadoc = TDate(TODAY); gm._sezione = game.riga(nriga).sezione() == 'D' ? 'A' : 'D'; #endif nrigp = gm.nuovo_pagamento(game, nriga, nrata); nreg = gm._numreg; } if (nrigp > 0) // Si vuole editare un pagamento { if (nreg == gm._numreg) { const bool dirty = gm.edit_pagamento(game, nriga, nrata, nrigp); if (dirty) { gm.update_partita(game, gm._riga_partite); partite_notify(gm.partite(), gm._riga_partite, K_TAB); gm._changed = TRUE; if (!game.esiste(nriga, nrata, nrigp)) m.stop_run(K_ESC); } } else { #ifdef __EXTRA__ gm.prima_nota(nreg); #else return f.error_box("Modificare il movimento %ld", nreg); #endif } } else { // Si vogliono editare le rate #ifdef __EXTRA__ if (nreg > 0) gm.prima_nota(nreg); else gm.edit_fattura(game, nriga); #else if (nreg != gm._numreg || nrata == 0) { if (nreg == 0) f.error_box("Utilizzare la gestione extra-contabile"); else f.error_box("Modificare il movimento %ld", nreg); return FALSE; } #endif } } return TRUE; } bool TGame_mask::nuovo_handler(TMask_field& f, KEY k) { if (k == K_SPACE) { TGame_mask& gm = (TGame_mask&)f.mask(); int anno; TString numero; // Graffa tattica per distruggere la maschera new_game alla fine del blocco { TMask new_game("cg2100n"); new_game.first_focus(P_NUMERO); #ifndef __EXTRA__ const TMask& cm = app().curr_mask(); new_game.disable(-1); gm._tipomov = app().causale().tipomov(); new_game.set(P_NUOVO, gm._tipomov); new_game.set(P_SEZIONE, gm._importo.sezione()); new_game.set(P_RESIDUO, gm._importo.valore()); new_game.set(P_DATADOC, cm.get(F_DATADOC)); new_game.set(P_NUMDOC, cm.get(F_NUMDOC)); new_game.set(P_DESCR, cm.get(F_DESCR)); if (gm._tipomov < 3) new_game.set(P_CODPAG,cm.get(F_CODPAG)); if (gm._tipomov == 2) { new_game.set(P_ANNO, cm.get(F_ANNORIF)); new_game.set(P_NUMERO, cm.get(F_NUMRIF)); } #endif k = new_game.run(); anno = new_game.get_int(P_ANNO); numero = new_game.get(P_NUMERO); gm._tipomov = new_game.get_int(P_NUOVO); gm._codpag = new_game.get(P_CODPAG); gm._sezione = new_game.get(P_SEZIONE)[0]; gm._importo.set(gm._sezione, real(new_game.get(P_RESIDUO))); gm._numdoc = new_game.get(P_NUMDOC); gm._datadoc = new_game.get(P_DATADOC); gm._descr = new_game.get(P_DESCR); } if (k == K_ENTER) { TPartita& game = app().partite().partita(gm.conto(), anno, numero); if (game.ok()) return error_box("La partita %d %s esiste gia'.", anno, (const char*)numero); if (gm._tipomov > 1) { const int nriga = TPartita::UNASSIGNED; const int nrata = TPartita::UNASSIGNED; const int nrigp = gm.nuovo_pagamento(game, nriga, nrata); gm.edit_pagamento(game, nriga, nrata, nrigp); } #ifdef __EXTRA__ else { gm.edit_fattura(game, 0); } #endif if (game.ok()) { gm.fill_partite(anno, numero); // Aggiorna sheet partite gm._changed = TRUE; } else app().partite().destroy(gm.conto(), anno, numero); } } return TRUE; } /////////////////////////////////////////////////////////// // Metodi della maschera delle partite /////////////////////////////////////////////////////////// void TGame_mask::add_importo(TToken_string& s, const TImporto& i, bool valuta, int pos) { if (i.is_zero()) s.add("", pos); else { TString80 v; v << i.valore().string(valuta ? 2 : 0) << ' ' << i.sezione(); s.add(v, pos); } } TImporto TGame_mask::get_importo(TToken_string& s, int pos) const { const TFixed_string imp(s.get(pos)); const real i(imp); const char sez = imp.right(1)[0]; return TImporto(sez, i); } int TGame_mask::update_partita(const TPartita& game, int prow) { TImporto saldo, doc, pag, imp; game.calcola_saldo(saldo, doc, pag, imp); TSheet_field& games = partite(); int riga_fatt = game.prima_fattura(); if (riga_fatt <= 0) riga_fatt = game.first(); // E' un anticipo TToken_string &r = games.row(prow); // Stringa di lavoro per lo sheet if (game.esiste(riga_fatt)) // Esiste veramente { const TRiga_partite& riga = game.riga(riga_fatt); r.cut(0); r.add(riga.get(PART_ANNO)); r.add(riga.get(PART_NUMPART)); r.add(riga.get(PART_DATADOC)); r.add(riga.get(PART_NUMDOC)); add_importo(r, saldo); add_importo(r, doc); add_importo(r, pag); add_importo(r, imp); r.add(riga.get(PART_DESCR)); } else { r.add("", 4); r.add("", 5); r.add("", 6); r.add("", 7); } if (prow >= 0) { games.force_update(prow); update_saldo_clifo(); games.force_update(games.items()-1); aggiorna_residuo(); } else prow = partite().items()-1; if (prow == 0) { const char all = game.allineamento_richiesto(); field(P_NUMERO).set_justify(all == 'R'); } return prow; } void TGame_mask::update_saldo_clifo() { TString_array& s = partite().rows_array(); TImporto sal, doc, pag, imp; for (int i = 0; i < s.items(); i++) { TToken_string& r = s.row(i); if (r.get_int(0) > 0) { sal += get_importo(r, 4); doc += get_importo(r, -1); pag += get_importo(r, -1); imp += get_importo(r, -1); } else break; } TToken_string& r = s.row(s.add("", i)); r.add(""); r.add(""); r.add(TDate(TODAY).string()); r.add(""); add_importo(r, sal.normalize()); add_importo(r, doc.normalize()); add_importo(r, pag.normalize()); add_importo(r, imp.normalize()); r.add("Saldo "); if (get(P_TIPOC)[0] == 'C') r << "cliente"; else r << "fornitore"; r << conto().sottoconto(); } bool TGame_mask::same_number(const char* s1, const char* s2) const { TString t1(s1); t1.trim(); TString t2(s2); t2.trim(); return t1 == t2; } void TGame_mask::fill_partite(int annorif, const char* numrif) { const bool all = get(P_SHOWALL).not_empty(); int first_game = -1; TString_array& a = partite().rows_array(); a.destroy(); app().begin_wait(); for (TPartita* gioco = app().partite().first(); gioco != NULL; gioco = app().partite().next()) { const int added = update_partita(*gioco, -1); // Memorizza posizione di inserimento if (first_game < 0 && gioco->anno() == annorif && same_number(gioco->numero(), numrif)) first_game = added; } TLocalisamfile partita(LF_PARTITE); partita.zero(); if (conto().tipo() > ' ') // Ignora gruppo e conto dei clifo { partita.put(PART_TIPOCF, conto().tipo()); partita.put(PART_SOTTOCONTO, conto().codclifo()); } else conto().put(partita.curr()); // Scrive completamente i conti normali const TRectype filter(partita.curr()); // Record campione for (int err = partita.read(_isgteq); err == NOERR && partita.curr() == filter; err = partita.read(_isgreat)) { const int anno = partita.get_int(PART_ANNO); const TString16 num(partita.get(PART_NUMPART)); if (!app().partite().exist(conto(), anno, num)) { TPartita game(conto(), anno, num); int added = -1; if (all || !game.chiusa()) added = update_partita(game, -1); if (first_game < 0 && added >= 0 && anno == annorif && same_number(num, numrif)) first_game = added; } partita.put(PART_NRIGA, 9999); // Forza lettura partita successiva nella prossima read } update_saldo_clifo(); partite().force_update(); aggiorna_residuo(); if (a.items() > 0) { if (first_game < 0) first_game = 0; partite_notify(partite(), first_game, K_TAB); } else { scadenze().destroy(); // scadenze().force_update(); } app().end_wait(); } bool TGame_mask::edit_pagamento(TPartita& p, int nriga, int nrata, int nrigp) const { TRectype oldpag = p.pagamento(nriga, nrata, nrigp); TRiga_partite& somma = p.riga(nrigp); TPay_mask m; if (nriga == TPartita::UNASSIGNED) { nriga = p.primo_pagamento(); TRiga_partite& riga = p.riga(nriga); TRiga_scadenze& scaden = riga.new_row(); m.set_pag(oldpag, scaden, _importo); riga.destroy_rows(); } else { const TRiga_scadenze& scaden = p.rata(nriga, nrata); m.set_pag(oldpag, scaden, _importo); } m.set(S_DESCAGG, somma.get(PART_DESCR)); const KEY key = m.run(); if (key == K_ENTER || key == K_DEL) { if (key == K_DEL) { m.reset(S_SALDOACC); // Non puo' essere un saldo m.reset(S_IMPORTO); // Azzera importo ... m.reset(S_IMPORTOVAL); // .. anche in valuta m.reset(S_RITENUTE); // Azzera ritenute } else { somma.put(PART_DESCR, m.get(S_DESCAGG)); // Aggiorna descrizione (comune ai pagamenti) } TRectype newpag(oldpag); m.get_pag(newpag); const TValuta val; // Non cambiare valuta! #ifdef __EXTRA__ p.modifica_pagamento(newpag); #else app().notify_edit_pagamento(p, newpag, val); #endif } return key != K_ESC; } #ifndef __EXTRA__ /////////////////////////////////////////////////////////// // Edit delle partite /////////////////////////////////////////////////////////// bool TPrimanota_application::edit_partite(const TMask& m, int riga) { const TImporto imp = get_cgs_imp(riga); if (imp.is_zero()) // Esci se 'importo e' nullo return FALSE; const char tipo = m.get(103)[0]; const int gruppo = m.get_int(104); const int conto = m.get_int(105); const long sottoconto = m.get_int(106); const TBill b(gruppo, conto, sottoconto, tipo); // Legge il conto della riga selezionata if (!b.ok()) return FALSE; // Esci se il conto della riga cliente non e' valido curr_mask().autosave(get_relation()); // Aggiorna i dati della testata sulle partite const TRectype& mov = get_relation()->curr(); partite().update_reg(mov); // Esecuzione maschera di selezione partite TGame_mask mask(b, mov.get_long(MOV_NUMREG), riga+1); mask.run(); const bool changed = mask.changed(); if (changed) { cgs().force_update(); // Aggiornamento righe contabili calcola_saldo(); } return changed; } #endif