#include // Serve per DLG_NEWREC #include "cg2102.h" // Applicazione di prima nota #include "cg2100.h" // Campi maschere prima nota #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 partite /////////////////////////////////////////////////////////// class TGame_mask : public TMask { const TBill _conto; // Conto fisso del cliente/fornitore int _riga_partite; // Riga corrente delle partite 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 show_all_handler(TMask_field& f, KEY k); static bool scambio_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); void add_importo(TToken_string& s, const TImporto& i) const; TImporto get_importo(TToken_string& s, int pos) const; void fill_partite(bool all) const; real aggiorna_residuo(); void update_partita(const TPartita& game, int prow) const; void update_saldo_clifo() const; 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; } TGame_mask(const TBill& bill); virtual ~TGame_mask() {} }; TGame_mask::TGame_mask(const TBill& bill) : TMask("cg2100p"), _conto(bill) { 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()); set_handler(P_ANNO, annopart_handler); set_handler(P_NUMERO, numpart_handler); set_handler(P_SHOWALL, show_all_handler); set_handler(P_SCAMBIO, scambio_handler); set_handler(P_NUOVO, nuovo_handler); partite().set_notify(partite_notify); scadenze().sheet_mask().set_handler(100, edit_scadenza_handler); aggiorna_residuo(); } /////////////////////////////////////////////////////////// // 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 ... if (num == row.get()) // 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) { const TGame_mask& gm = (const TGame_mask&)f.mask(); const bool all = f.get().not_empty(); gm.fill_partite(all); } return TRUE; } bool TGame_mask::scambio_handler(TMask_field& f, KEY k) { if (k == K_SPACE) { const TGame_mask& gm = (const TGame_mask&)f.mask(); const TSheet_field& sheet = gm.scadenze(); sheet.swap_columns(103, 110); // Scambia colonne sheet.swap_columns(104, 111); } return TRUE; } real TGame_mask::aggiorna_residuo() { const TMask& cm = app().curr_mask(); const long cur_reg = cm.get_long(F_NUMREG); const int rmov = app().cgs().selected(); TImporto residuo(app().get_cgs_imp(rmov)); residuo -= app().partite().importo_speso(cur_reg, rmov+1, TRUE); set(P_RESIDUO, residuo.valore().string()); return residuo.valore(); } bool TGame_mask::partite_notify(TSheet_field& partite, int r, KEY k) { if (k == K_TAB) { TGame_mask& gm = (TGame_mask&)partite.mask(); gm._riga_partite = r; TString_array& scadenze = gm.scadenze().rows_array(); scadenze.destroy(); const TBill& zio = gm.conto(); // Conto cliente/fornitore 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); 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 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(); for (int ra = 1; ra <= riga.rate(); ra++) { const TRiga_scadenze& scad = riga.rata(ra); TToken_string& row = scadenze.row(scadenze.add("")); row.add(ri); row.add(ra); row.add(riga.get(PART_DATADOC)); row.add(riga.get(PART_NREG)); row.add(riga.get(PART_DATAREG)); row.add(scad.get(SCAD_DATASCAD)); row.add(scad.get(SCAD_IMPORTO)); row.add(in_valuta ? scad.get_real(SCAD_IMPORTOVAL).string(0, 2) : ""); row.add(riga.get(PART_DESCR)); row.add(riga.get(PART_NUMDOC)); row.add(riga.get(PART_PROTIVA)); const int lastp = scad.last(); for (int pa = scad.first(); pa <= lastp; pa = scad.succ(pa)) { const TRiga_partite& rigp = game->riga(pa); const TRectype& pag = scad.row(pa); TToken_string& row = scadenze.row(scadenze.add("")); row.add(ri); row.add(ra); row.add(rigp.get(PART_DATADOC)); row.add(rigp.get(PART_NREG)); row.add(rigp.get(PART_DATAREG)); row.add(scad.get(SCAD_DATASCAD)); row.add(pag.get_real(PAGSCA_IMPORTO).string()); row.add(in_valuta ? pag.get_real(PAGSCA_IMPORTOVAL).string(0, 2) : ""); row.add(rigp.get(PART_DESCR)); row.add(rigp.get(PART_NUMDOC)); row.add(""); row.add(pa); } TToken_string& sal = scadenze.row(scadenze.add("")); sal.add(ri); sal.add(ra); if (scad.pagata()) { sal.add("", 6); sal.add(""); } else { sal.add(scad.residuo(FALSE).string(), 6); sal.add(in_valuta ? scad.residuo(TRUE).string(0, 2) : ""); } sal.add("Saldo della rata "); sal << ra; } 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& rigp = game->riga(pa); TToken_string& row = scadenze.row(scadenze.add("")); row.add(pag.get(PAGSCA_NRIGA)); row.add(pag.get(PAGSCA_NRATA)); row.add(rigp.get(PART_DATADOC)); row.add(rigp.get(PART_NREG)); row.add(rigp.get(PART_DATAREG)); row.add(""); row.add(pag.get_real(PAGSCA_IMPORTO).string()); row.add(in_valuta ? pag.get_real(PAGSCA_IMPORTOVAL).string(0, 2) : ""); row.add(rigp.get(PART_DESCR)); row.add(rigp.get(PART_NUMDOC)); row.add(""); row.add(pa); } } gm.scadenze().force_update(); if (should_delete_game) delete game; } return TRUE; } bool TGame_mask::edit_scadenza_handler(TMask_field& f, KEY k) { if (k == K_SPACE) { TMask& m = f.mask(); TGame_mask& gm = (TGame_mask&)(m.get_sheet()->mask()); const TBill& bill = gm.conto(); const int anno = gm.get_int(P_ANNO); const TString16 numero = gm.get(P_NUMERO); const int nriga = m.get_int(101); const int nrata = m.get_int(102); const int rmov = app().cgs().selected()+1; CHECK(nriga && nrata, "La riga della scadenza sembra vuota, ma tutti sanno che e' una balla!"); TPartita& game = app().partite().partita(bill, anno, numero); int nrigp = m.get_int(112); if (nrigp == 0) { if (game.rata_pagata(nriga, nrata)) return f.error_box("La rata %d e' gia' stata pagata", nrata); nrigp = app().nuovo_pagamento(game, nriga, nrata, rmov); } else { const TMask& cm = app().curr_mask(); const long cur_reg = cm.get_long(F_NUMREG); const long nreg = m.get_long(104); if (cur_reg != nreg) return f.error_box("Il movimento corrente e' il %ld", cur_reg); const int paga = game.rata_pagata(nriga, nrata); if (paga != 0 && paga != nrigp) return f.error_box("Pagamento non modificabile"); } const bool dirty = app().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.aggiorna_residuo(); } } return TRUE; } bool TGame_mask::nuovo_handler(TMask_field& f, KEY k) { if (k == K_SPACE) { TMask new_game("Nuova partita", 1, 24, 5); new_game.add_number(P_ANNO, 0, "Anno ", 1, 1, 4, "A"); new_game.add_string(P_NUMERO, 0, "Partita ", 1, 2, 7); new_game.add_button(DLG_OK, 0, "", -12, 3, 8, 2); new_game.add_button(DLG_CANCEL, 0, "", -22, 3, 8, 2); if (new_game.run() == K_ENTER) { TGame_mask& gm = (TGame_mask&)f.mask(); const int anno = new_game.get_int(P_ANNO); const TString16 numero(new_game.get(P_NUMERO)); 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); const int nriga = TPartita::UNASSIGNED; const int nrata = TPartita::UNASSIGNED; const int nrigp = app().nuovo_pagamento(game, nriga, nrata, app().cgs().selected()+1); app().edit_pagamento(game, nriga, nrata, nrigp); if (game.ok()) { game.write(); gm.send_key(K_SPACE, P_SHOWALL); // Aggiorna sheet partite gm.set(P_ANNO, anno); gm.set(P_NUMERO, numero, TRUE); // Selezione nuova partita } 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) const { if (i.is_zero()) s.add(""); else { s.add(i.valore().string()); s << ' ' << i.sezione(); } } 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); } void TGame_mask::update_partita(const TPartita& game, int prow) const { TImporto saldo, doc, pag, imp; game.calcola_saldo(saldo, doc, pag, imp); int riga_fatt = game.prima_fattura(); if (riga_fatt <= 0) riga_fatt = game.first(); // E' un anticipo const TRiga_partite& riga = game.riga(riga_fatt); TToken_string &r = partite().row(prow); // Stringa di lavoro per lo sheet 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)); if (prow >= 0) { TSheet_field& games = partite(); games.force_update(prow); update_saldo_clifo(); games.force_update(games.items()-1); } } void TGame_mask::update_saldo_clifo() const { 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); add_importo(r, doc); add_importo(r, pag); add_importo(r, imp); r.add("Saldo "); if (get(P_TIPOC)[0] == 'C') r << "cliente"; else r << "fornitore"; } void TGame_mask::fill_partite(bool all) const { TString_array& a = partite().rows_array(); a.destroy(); app().begin_wait(); 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().sottoconto()); } else conto().put(partita.curr()); // Scrive completamente i conti normali const long nreg = app().curr_mask().get_long(F_NUMREG); 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)); TPartita* game = NULL; bool should_delete_game = FALSE; if (app().partite().exist(conto(), anno, num)) game = &app().partite().partita(conto(), anno, num); else { game = new TPartita(conto(), anno, num); should_delete_game = TRUE; } if (all || (!game->chiusa() || game->mov2rig(nreg, 0) > 0)) update_partita(*game, -1); if (should_delete_game) delete game; partita.put(PART_NRIGA, 9999); // Forza lettura partita successiva nella prossima read } update_saldo_clifo(); partite().force_update(); if (a.items() > 0) partite_notify(partite(), 0, K_TAB); else { scadenze().destroy(); scadenze().force_update(); } app().end_wait(); } /////////////////////////////////////////////////////////// // Paymask /////////////////////////////////////////////////////////// class TPay_mask : public TMask { bool _in_valuta; real _da_pagare; protected: static bool importo_handler(TMask_field& f, KEY k); public: void set_pag(const TRectype& oldpag, const TRiga_scadenze& scad); void get_pag(TRectype& oldpag) const; TPay_mask(); virtual ~TPay_mask() {} }; TPay_mask::TPay_mask() : TMask("cg2100s") { } void TPay_mask::set_pag(const TRectype& oldpag, const TRiga_scadenze& scad) { TRelation rel(LF_PAGSCA); // Working relation rel.lfile().curr() = oldpag; autoload(&rel); // Load current record on mask const TRiga_partite& parbas = scad.riga(); set(S_NUMDOC, parbas.get(PART_NUMDOC)); // Numero documento set(S_DATADOC, parbas.get(PART_DATADOC)); // Data documento set(S_NUMPROT, parbas.get(PART_PROTIVA)); // Protocollo IVA set(S_DESCR, parbas.get(PART_DESCR)); // Descrizione documento set(S_DATASCAD, 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 _in_valuta = scad.in_valuta(); _da_pagare = scad.residuo(_in_valuta); // Calcola residuo in valuta TReal_field& res = (TReal_field&)field(S_RESIDUO); res.set_decimals(_in_valuta ? 2 : 0); res.set(_da_pagare.string()); if (!_da_pagare.is_zero()) 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); show(S_IMPORTOVAL_SCAD, _in_valuta); show(S_IMPORTOVAL, _in_valuta); } void TPay_mask::get_pag(TRectype& newpag) const { TRelation rel(LF_PAGSCA); // Working relation rel.lfile().curr() = newpag; autosave(&rel); // Load current record from mask newpag = rel.lfile().curr(); } bool TPay_mask::importo_handler(TMask_field& f, KEY k) { TPay_mask& m = (TPay_mask&)f.mask(); if (k == K_F8) { f.set(m._da_pagare.string()); k = K_TAB; } if (k == K_TAB && f.focusdirty()) { const real i(f.get()); if (i >= m._da_pagare) m.set(S_SALDOACC, "S"); const real residuo(m._da_pagare - i); m.set(S_RESIDUO, residuo.string()); } return TRUE; } /////////////////////////////////////////////////////////// // Metodi di prima nota /////////////////////////////////////////////////////////// bool TPrimanota_application::showpartite_handler(TMask_field& f, KEY k) { bool ok = TRUE; TMask& m = f.mask(); if (m.get(116) == "K") { TSheet_field& s = *m.get_sheet(); const int riga = s.selected(); if (k == K_SPACE) { const bool dirty = app().edit_partite(riga); if (dirty) { if (m.field(103).enabled()) app().disable_cgs_cells(riga, 'K'); k = K_ENTER; } } if (k == K_ENTER) { const long curreg = app().curr_mask().get_long(F_NUMREG); const TImporto importo(app().get_cgs_imp(riga)); const TImporto speso(app().partite().importo_speso(curreg, riga+1, TRUE)); if (importo != speso) { ok = yesno_box("L'importo della riga %d dovrebbe essere %c %s\n" "Si desidera correggerlo?", riga+1, speso.sezione(), speso.valore().string(".")); if (ok) app().set_cgs_imp(riga, speso); } } } return ok; } bool TPrimanota_application::edit_partite(int riga) { TToken_string& cgr = cgs().row(riga); const TBill b(cgr, 2, 0x3); // Legge il conto della riga selezionata if (row_type(cgr) != 'K' || !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); TGame_mask mask(b); // Esecuzione maschera di selezione partite mask.run(); cgs().force_update(); // Aggiornamento righe contabili return TRUE; } int TPrimanota_application::nuovo_pagamento(TPartita& partita, int nriga, int rata, int rmov) { CHECKD(!partita.rata_pagata(nriga, rata), "Rata pagata ", rata); TBill conto; partita.conto(conto); // Legge conto principale const long numreg = curr_mask().get_long(F_NUMREG); int nrigp = partita.mov2rig(numreg, rmov); // Cerca riga partita relativa alla riga rmov if (nrigp <= 0) // Devo creare una nuova riga di partita { TRiga_partite& part = partita.nuova_riga(); // Creazione nuova riga vuota nrigp = part.get_int(PART_NRIGA); // Copia dati movimento corrente part.put(PART_NREG, numreg); // Numero operazione part.put(PART_NUMRIG, rmov); // Riga su cui ho cliccato part.put(PART_DATAREG, curr_mask().get(F_DATAREG)); part.put(PART_DATADOC, curr_mask().get(F_DATADOC)); part.put(PART_NUMDOC, curr_mask().get(F_NUMDOC)); part.put(PART_DESCR, curr_mask().get(F_DESCR)); part.put(PART_CODVAL, curr_mask().get(S_VALUTA)); part.put(PART_CAMBIO, curr_mask().get(S_CAMBIO)); part.put(PART_DATACAM, curr_mask().get(S_DATACAMBIO)); // Copia dati causale corrente const int tipomov = causale().tipomov(); part.put(PART_TIPOMOV, tipomov); part.put(PART_CODCAUS, causale().codice()); if (causale().iva() != nessuna_iva) { part.put(PART_REG, curr_mask().get(F_CODREG)); part.put(PART_PROTIVA, curr_mask().get(F_PROTIVA)); } // 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 = (conto.tipo() == 'C') ? 'D' : 'A'; // al tipo cliente/fornitore else sezione = (conto.tipo() == 'C') ? 'A' : 'D'; } if (conto.tipo() > ' ') // Se il tipo e' C o F { TBill bill; causale().bill(1, bill); // Legge primo conto causale if (bill.tipo() != conto.tipo()) sezione = (sezione == 'D') ? 'A' : 'D'; // scambia segno } part.put(PART_SEZ, sezione); // Memorizza solo la sezione (importi nulli) part.put(PART_SEZABB, sezione); part.put(PART_SEZDIFCAM, sezione); } 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); switch (scad.get_int(SCAD_TIPOPAG)) { 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_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)); } TBill contro; causale().bill(caus, contro); // Legge conto contropartita if (contro.empty()) // Se non specificato ... causale().bill(caus = 1, contro); // ... prende il primo contro.put(pagamento, TRUE); // Scrive conto contropartita /* TBG Da regalare a Ferdinando if (conto.tipo() > ' ') // Se cliente o fornitore cerca sua banca { TRelation cliforel(LF_CLIFO); cliforel.add(LF_CFVEN, "TIPOCF=TIPOCF|CODCF=CODCF"); TRectype& clifo = cliforel.lfile().curr(); clifo.put(CLI_TIPOCF, conto.tipo()); clifo.put(CLI_CODCF, conto.codclifo()); const int err = cliforel.read(); CHECK(err == NOERR, "Chiss'e' fregato il clifo"); pagamento.put(PAGSCA_CODABI, clifo.get(CLI_CODABI)); pagamento.put(PAGSCA_CODCAB, clifo.get(CLI_CODCAB)); pagamento.put(PAGSCA_CODAG, cliforel.lfile(LF_CFVEN).get(CLI_CODAG)); } */ return nrigp; } bool TPrimanota_application::notify_edit_pagamento(TPartita& p, TRectype& new_pag, int deleting) { if (deleting != 0) { const int nriga = new_pag.get_int(PAGSCA_NRIGA); // Riga fattura const int nrata = new_pag.get_int(PAGSCA_NRATA); // Numero rata const int nrigp = new_pag.get_int(PAGSCA_NRIGP); // Riga pagamento const TRectype& old_pag = p.pagamento(nriga, nrata, nrigp); const TRiga_partite& somma = p.riga(nrigp); const char sez = somma.sezione(); // Sezione importo e ritenute const char controsez = sez == 'A' ? 'D' : 'A'; // Sezione contropartita // Aggiornamento contopartita const TImporto old_importo(controsez, old_pag.get_real(PAGSCA_IMPORTO)); TBill old_conto; old_conto.get(old_pag, TRUE); const TImporto new_importo(controsez, new_pag.get_real(PAGSCA_IMPORTO)); TBill new_conto; new_conto.get(new_pag, TRUE); if (old_importo != new_importo || old_conto != new_conto) { const int old_riga = bill2pos(old_conto, 'I'); if (old_riga >= 0) { const bool empty = sub_cgs_imp(old_riga, old_importo); if (empty && (new_importo.is_zero() || new_conto != old_conto)) reset_cgs_row(old_riga); } // Importo della contropartita if (!new_importo.is_zero()) { const int new_riga = bill2pos(new_conto, 'I'); if (new_riga < 0) set_cgs_row(new_riga, new_importo, new_conto, "", 'I'); else add_cgs_imp(new_riga, new_importo); } } // Aggiornamento ritenute const real old_ritenute(old_pag.get(PAGSCA_RITENUTE)); const real new_ritenute(new_pag.get(PAGSCA_RITENUTE)); if (old_ritenute != new_ritenute) { const TImporto grow_ritenute(controsez, new_ritenute-old_ritenute); const riga = type2pos('F'); if (riga < 0) { TBill conto_rit; causale().bill(11, conto_rit); set_cgs_row(riga, grow_ritenute, conto_rit, "", 'F'); } else { const bool empty = add_cgs_imp(riga, grow_ritenute); if (empty) reset_cgs_row(riga); } } } // if (deleting != 0) char old_ap, new_ap; TImporto old_abbuono, new_abbuono, old_diffcam, new_diffcam; const bool empty = p.modifica_pagamento(new_pag, old_ap, old_abbuono, old_diffcam, new_ap, new_abbuono, new_diffcam); if (deleting != 0) { const int riga_contabile = app().cgs().selected(); // Se c'e' differenza negli abbuoni if (old_abbuono != new_abbuono || old_ap != new_ap) { if (old_ap != ' ') // Se c'era un abbuono ... { const int riga_abb = type2pos(old_ap); CHECK(riga_abb >= 0, "Chiss'e' fregato gli abbuoni?"); const bool empty = sub_cgs_imp(riga_abb, old_abbuono); if (empty && new_ap != old_ap) reset_cgs_row(riga_abb); if (deleting != riga_contabile) { // Sottrae l'abbuono con la sezione invertita dalla riga contabile add_cgs_imp(riga_contabile, old_abbuono); } } if (new_ap != ' ') // Se ci sono abbuoni { const riga_abb = type2pos(new_ap); if (riga_abb < 0) { TBill conto_abb; causale().bill(new_ap == 'A' ? 9 : 8, conto_abb); app().set_cgs_row(riga_abb, new_abbuono, conto_abb, "", new_ap); } else add_cgs_imp(riga_abb, new_abbuono); if (deleting != riga_contabile) { // Aggiunge l'abbuono con la sezione invertita sub_cgs_imp(riga_contabile, new_abbuono); } } } // Se c'e' variazione nella differenza cambi if (old_diffcam != new_diffcam) { const int riga_diffcam = type2pos('C'); TImporto grow_diffcam(new_diffcam); grow_diffcam -= old_diffcam; if (riga_diffcam < 0) { TBill conto_diffcam; causale().bill(12, conto_diffcam); set_cgs_row(riga_diffcam, grow_diffcam, conto_diffcam, "", 'C'); } else { const bool empty = add_cgs_imp(riga_diffcam, grow_diffcam); if (empty) reset_cgs_row(riga_diffcam); } if (deleting != riga_contabile) { // Aggiunge la differenza con la sezione invertita sub_cgs_imp(riga_contabile, grow_diffcam); } } } // if (deleting != 0) return empty; } bool TPrimanota_application::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; // Dati della scadenza che ha generato la partita if (nriga != TPartita::UNASSIGNED) { const TRiga_scadenze& scaden = p.rata(nriga, nrata); m.set_pag(oldpag, scaden); } else { nriga = p.primo_pagamento(); TRiga_partite& riga = p.riga(nriga); TRiga_scadenze& scaden = riga.new_row(); m.set_pag(oldpag, scaden); riga.destroy_rows(); } 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_IMPORTO); m.reset(S_IMPORTOVAL); m.reset(S_RITENUTE); } else { somma.put(PART_DESCR, m.get(S_DESCAGG)); // Aggiorna descrizione (comune ai pagamenti) } TRectype new_pag(oldpag); m.get_pag(new_pag); notify_edit_pagamento(p, new_pag); } return key != K_ESC; } // Scorre tutte le righe della partita ed azzera i pagamenti relativi a alla riga contabile // cancellata e decrementa i numeri riga superiori a numrig bool TPrimanota_application::notify_cgline_deletion(TPartita& partita, long nreg, int numrig) { bool found = FALSE; for (int p = partita.last(); p > 0; p = partita.pred(p)) { TRiga_partite& part = partita.riga(p); if (part.get_int(PART_TIPOMOV) == 1) { for (int r = part.rate(); r > 0; r--) { const TRiga_scadenze& scad = part.rata(r); for (int s = scad.last(); s > 0; s = scad.pred(s)) { const TRiga_partite& sum = partita.riga(s); if (sum.get_long(PART_NREG) == nreg && (numrig <= 0 || sum.get_int(PART_NUMRIG) == numrig)) { TRectype pag(scad.row(s)); pag.zero(PAGSCA_IMPORTO); pag.zero(PAGSCA_IMPORTOVAL); pag.zero(PAGSCA_RITENUTE); notify_edit_pagamento(partita, pag, numrig); found = TRUE; } } } } else { if (numrig > 0 && part.get_long(PART_NREG) == nreg && part.get_int(PART_NUMRIG) > numrig) part.put(PART_NUMRIG, numrig-1); } } return found; } bool TPrimanota_application::notify_cgline_deletion(int numrig) { bool found = FALSE; const long nreg = curr_mask().get_long(F_NUMREG); partite().add_numreg(nreg); // Carica tutte le partite interessate for (TPartita* game = _partite.first(); game; game = _partite.next()) found |= notify_cgline_deletion(*game, nreg, numrig); return found; } bool TPrimanota_application::remove_unassigned() { bool found = FALSE; const long nreg = curr_mask().get_long(F_NUMREG); for (TPartita* game = partite().first(); game; game = partite().next()) { if (game->prima_fattura() > 0) { TRecord_array& unas = game->unassigned(); for (int u = unas.last_row(); u > 0; u = unas.pred_row(u)) { const TRectype& pag = unas.row(u); const int nrigp = pag.get_int(PAGSCA_NRIGP); TRiga_partite& sum = game->riga(nrigp); if (sum.get_long(PART_NREG) == nreg) { const int rmov = sum.get_int(PART_NUMRIG)-1; const TImporto imp(sum.sezione(), pag.get_real(PAGSCA_IMPORTO)); add_cgs_imp(rmov, imp); TRectype zero(pag); zero.zero(); sum.update(pag, zero, PART_IMPORTO); sum.update(pag, zero, PART_IMPORTOVAL); sum.update(pag, zero, PART_RITENUTE); unas.destroy_row(u); found = TRUE; } } } } return found; }