#include #include #include #include #include #include #include "celib.h" #include "ce2200a.h" #include "../cg/cglib01.h" #include "ammce.h" #include "catdi.h" #include "cespi.h" #include "salce.h" #include "movce.h" class TOpenesc_mask : public TAutomask { TDitta_cespiti& _dc; bool _has_cg; protected: virtual bool on_field_event(TOperable_field& o, TField_event e, long jolly); bool check_oldes(); public: TOpenesc_mask(); }; TOpenesc_mask::TOpenesc_mask() : TAutomask("ce2200a"), _dc(ditta_cespiti()) { _has_cg = main_app().has_module(CGAUT); field(F_NEWES).check_type(_has_cg ? CHECK_REQUIRED : CHECK_SEARCH); } // Controlla che siano stati stampati i bollati e chiuse le attivita bool TOpenesc_mask::check_oldes() { bool ok = true; const TString& oldes = get(F_OLDES); TRelation rel("CCB"); TRectype& ccb = rel.curr(); ccb.put("CODTAB", oldes); TCursor cur(&rel, "", 1, &ccb, &ccb); const long items = cur.items(); cur.freeze(); TString msg; int error = 0; for (cur = 0L; cur.pos() < items; ++cur) { const bool b1 = ccb.get_bool("B1"); const bool b2 = ccb.get_bool("B2"); if (!b1 || b2) { if (!b1) { msg << TR("Non è stato stampato il bollato dell'attività"); error |= 0x1; } else { msg << TR("E' già stata effettuata la chiusura dell'attività"); error |= 0x2; } const TString8 codatt = ccb.get("CODTAB").mid(4); msg << ' ' << oldes << ' ' << cache().get("%CAT", codatt, "S0") << ".\n"; } } if (error) { if (get_int(F_NEWES) >= _dc.esercizio_corrente()) { if (error & 0x1) { msg << TR("Verra' effettuata un'apertura provvisoria.") << '\n'; set(F_PROVVIS, true); } msg << TR("Si desidera proseguire ugualmente?"); ok = yesno_box(msg); } else ok = error_box(msg); } return ok; } bool TOpenesc_mask::on_field_event(TOperable_field& o, TField_event e, long jolly) { switch (o.dlg()) { case F_OLDES: if (e == fe_init) { TDate ies, fes; const int oes = _dc.esercizio_corrente(ies, fes); o.set(oes); set(F_OLDINIZIO, ies); set(F_OLDFINE, fes); } if (e == fe_init || e == fe_modify) { TEsercizi_contabili esc; const int oldes = get_int(F_OLDES); int nes = esc.next(oldes); if (nes < 0) nes = oldes+1; set(F_NEWES, nes, TRUE); if (esc.exist(nes)) { set(F_NEWINIZIO, esc[nes].inizio()); set(F_NEWFINE, esc[nes].fine()); disable(-2); } else { TDate inizio = get_date(F_OLDFINE); ++inizio; TDate fine = get_date(F_OLDFINE); fine.addyear(1); set(F_NEWINIZIO, inizio); set(F_NEWFINE, fine); enable(-2); } } if (e == fe_modify || e == fe_close) return check_oldes(); break; case F_NEWES: if (e == fe_close) { if (o.empty()) return error_box(TR("È necessario specificare il codice del nuovo esercizio")); } break; default: break; } return TRUE; } class TOpenesc : public TSkeleton_application { protected: virtual bool create(); virtual void main_loop(); void incr_riv(TRectype& rec, const char* riv, const char* anni) const; bool is_leap(int year) const; real calc_coeff(const TDate& ies, const TDate& fes) const; void incr_zero(TRectype& rec, const char* val, const char* valp) const; public: bool crea_esercizio(int oldes, int newes, const TDate& ies, const TDate& fes) const; void crea_attivita(int oldes, int newes, bool provvis) const; void crea_registro(int oldes, int newes) const; void crea_categorie(int oldes, int newes) const; void crea_saldi(int oldes, int newes) const; void crea_ammortamenti(int oldes, int newes) const; void test_alien(const TRectype& salce, const TDate& fines) const; }; bool TOpenesc::create() { open_files(LF_TABCOM, LF_TAB, LF_CESPI, LF_AMMCE, LF_SALCE, 0); return TSkeleton_application::create(); } bool TOpenesc::is_leap(int year) const { TDate d(28,2,year); ++d; return d.day() == 29; } real TOpenesc::calc_coeff(const TDate& ies, const TDate& fes) const { const real tot_es = fes - ies + 1; real max_es = 365; const int im = ies.month(); const int iy = ies.year(); const int fm = fes.month(); const int fy = fes.year(); if ((im < 3 && (fm >= 3 || fy > iy) && is_leap(iy)) || (fm >= 3 && (im < 3 || iy < fy) && is_leap(fy))) max_es += 1.0; real coeff = tot_es / max_es; coeff.round(9); return coeff; } bool TOpenesc::crea_esercizio(int oldes, int newes, const TDate& ies, const TDate& fes) const { // Crea l'esercizio contabile se necessario TTable esc("ESC"); TString4 key_new; key_new.format("%04d",newes); esc.put("CODTAB", key_new); if (esc.read() != NOERR) { if (!has_module(CGAUT)) { esc.zero(); esc.put("CODTAB", key_new); esc.put("D0", ies); esc.put("D1", fes); esc.write(); } else return error_box(TR("Attenzione: non esiste ancora l'esercizio contabile %04d"), newes); } // Crea l'esercizio cespiti se necessario TString4 key_old; key_old.format("%04d", oldes); const TRectype& oldrec = cache().get("CCE", key_old); TTable cce("CCE"); cce.put("CODTAB", key_new); const bool found = cce.read() == NOERR; if (!found) { cce.zero(); cce.put("CODTAB", key_new); } cce.put("S5", calc_coeff(ies, fes)); // Calcola coefficiente durata esercizio cce.put("S6", oldrec.get("S6")); // Copia tipo arrotondamento cce.put("I0", oldrec.get("I0")); // Copia tipo contabilità cce.put("I1", oldrec.get("I1")); // Copia tipo riproporzionamento cce.put("I2", oldrec.get("I2")); // Copia assoggettamento art.14 C.2 legge 449/97 cce.put("I3", fes - ies + 1); // Calcola durata esercizio cce.put("B0", oldrec.get("B0")); // Copia ditta relativa a professionista cce.put("B3", oldrec.get("B3")); // Copia ammortamento parti vendute cce.put("B4", oldrec.get("B4")); // Ragguaglio parti vendute cce.put("B5", oldrec.get("B5")); // Esposizione su libro cespiti if (found) cce.rewrite(); else cce.write(); return true; } void TOpenesc::crea_attivita(int oldes, int newes, bool provvis) const { TRelation rel("CCB"); TRectype& ccb = rel.curr(); ccb.put("CODTAB", oldes); TCursor cur(&rel, "", 1, &ccb, &ccb); const long items = cur.items(); cur.freeze(); for (cur = 0L; cur.pos() < items; ++cur) { if (!provvis) { ccb.put("B2", true); // Setta flag di chiusa rel.rewrite(); } // Crea nuova attività TString16 codtab = ccb.get("CODTAB"); TString4 str; str.format("%04d", newes); codtab.overwrite(str); const bool leasing = ccb.get_bool("B0"); const TString8 codreg = ccb.get("S6"); ccb.zero(); ccb.put("CODTAB", codtab); ccb.put("B0", leasing); ccb.put("S6", codreg); int err = rel.write(); if (err != NOERR) rel.rewrite(); } } void TOpenesc::crea_registro(int oldes, int newes) const { TEsercizi_contabili esc; const int old_year = esc[oldes].fine().year(); const int new_year = esc[newes].fine().year(); TRelation rel("REG"); TRectype& reg = rel.curr(); reg.put("CODTAB", old_year); TCursor cur(&rel, "I0=7", 1, ®, ®); const TRecnotype items = cur.items(); // Puo' succedere di averne più d'uno cur.freeze(); for (cur = 0; cur.pos() < items; ++cur) { TString16 codtab; codtab.format("%04d", new_year); codtab << reg.get("CODTAB").mid(4); reg.put("CODTAB", codtab); // reg.zero("I1"); // Pagine stampate rel.write(); } } void TOpenesc::crea_categorie(int oldes, int newes) const { TRelation rel(LF_CATDI); TRectype& cat = rel.curr(); cat.put(CATDI_CODES, oldes); TCursor cur(&rel, "", 1, &cat, &cat); const long items = cur.items(); cur.freeze(); for (cur = 0L; cur.pos() < items; ++cur) { cat.put(CATDI_CODES, newes); cat.zero(CATDI_DATE); cat.zero(CATDI_TPOP); int err = rel.write(); if (err != NOERR) rel.rewrite(); } } void TOpenesc::incr_riv(TRectype& rec, const char* riv, const char* anni) const { if (rec.get_real(riv) != ZERO) { const int new_anni = rec.get_int(anni) + 1; rec.put(anni, new_anni); } } static bool bad_alien(const TDate& dtalien, const TDate& fines) { if (!dtalien.ok() || dtalien == fines) return true; if (dtalien < fines && dtalien.is_end_month()) return true; return false; } static bool get_last_cespi(int logicnum, const char* filter, int key, const TString& idcespite, const char* field, TString& value) { bool ok = false; TRelation rel(logicnum); TRectype& rec = rel.curr(); rec.put("IDCESPITE", idcespite); TCursor cur(&rel, filter, key, &rec, &rec); const TRecnotype items = cur.items(); if (items > 0) { cur.freeze(); cur = items-1; value = rec.get(field); ok = value.full(); } return ok; } void TOpenesc::test_alien(const TRectype& salce, const TDate& fines) const { // Il cespite e' senza elementi e senza valore -> Dovrebbe risultare alienato if (null_fields(salce, SALCE_NUMELE, SALCE_CSTO, SALCE_RIV75, SALCE_RIV83, SALCE_RIV90, SALCE_RIV91, SALCE_RIVGF, SALCE_RIVGC)) { const TString16 idcespite = salce.get(SALCE_IDCESPITE); TLocalisamfile cespiti(LF_CESPI); cespiti.put(CESPI_IDCESPITE, idcespite); if (cespiti.read() == NOERR) { const TDate dtcomp = cespiti.get(CESPI_DTCOMP); const TDate dtalien = cespiti.get(CESPI_DTALIEN); // E' stato comprato tempo fa' ... ma ha una data di alienazione nulla o sospetta if (dtcomp <= fines && bad_alien(dtalien, fines)) { TDate alien2; if (!alien2.ok()) { // Cerca ultimo movimento di vendita/eliminazione TString16 value; if (get_last_cespi(LF_MOVCE, "SEGNO=\"-\"", 2, idcespite, MOVCE_DTMOV, value)) { const TDate dta(value); if (dta <= fines) alien2 = dta; } } if (!alien2.ok()) { // Cerca ultimo saldo non nullo TString4 value; if (get_last_cespi(LF_SALCE, "(TPSALDO=\"2\")&&(NUMELE!=\"0\")", 1, idcespite, SALCE_CODES, value)) { const int codes = atoi(value)+1; TEsercizi_contabili esc; TDate dti, dtf; esc.code2range(codes, dti, dtf); if (dtf <= fines) alien2 = dtf; } } if (!alien2.ok()) alien2 = fines; // Se ho trovato una data di alienazione diversa, allora la aggiorno if (!dtalien.ok() || alien2 < dtalien) { cespiti.put(CESPI_DTALIEN, alien2); cespiti.rewrite(); } } } } } void TOpenesc::crea_saldi(int oldes, int newes) const { TRelation rel(LF_SALCE); rel.add(LF_AMMCE, "CODES==CODES|IDCESPITE==IDCESPITE|TPSALDO==2|TPAMM==1"); TRectype& rec = rel.curr(); TString str; str << '(' << SALCE_CODES << "==" << oldes << ")&&(" << SALCE_TPSALDO << "==2)"; TCursor cur(&rel, str); const TRecnotype items = cur.items(); cur.freeze(); // Calcola data fine esercizio per eventuali alienazioni TEsercizi_contabili esc; const TDate fines = esc[oldes].fine(); TProgind pi(items, TR("Apertura saldi"), FALSE, TRUE); for (cur = 0; cur.pos() < items; ++cur) { pi.addstatus(1); rec.put(SALCE_CODES, newes); // Aggiorna anno di esercizio rec.put(SALCE_TPSALDO, 1); // Aggiorna tipo saldo ad "iniziale" incr_riv(rec, SALCE_RIV90, SALCE_ANNIPOST90); // Incrementa anni post 90 incr_riv(rec, SALCE_RIV91, SALCE_ANNIPOST91); // Incrementa anni post 91 rec.zero(SALCE_VSPMANU); // Azzera spese manutenzione rec.zero(SALCE_DTSTBOLL); // Azzera data stampa bollato // Incrementa gli anni di ammortamento const TRectype& ammce = rel.curr(LF_AMMCE); if (!null_fields(ammce, AMMCE_QNOR, AMMCE_QACC, AMMCE_QANT)) { const int anniamm = rec.get_int(SALCE_ANNIAMM); rec.put(SALCE_ANNIAMM, anniamm+1); } // Controlla se cespite alienato test_alien(rec, fines); const int err = rel.write(); if (err != NOERR) // Should never happen! rel.rewrite(); } } void TOpenesc::incr_zero(TRectype& rec, const char* val, const char* valp) const { real num = rec.get_real(val); num += rec.get_real(valp); rec.put(val, num); rec.zero(valp); } void TOpenesc::crea_ammortamenti(int oldes, int newes) const { TRelation rel(LF_AMMCE); rel.add(LF_AMMCE, "IDCESPITE==IDCESPITE|CODES==CODES|TPSALDO==1|TPAMM==TPAMM", 1, 0, 883); const TRectype& ammce1 = rel.curr(-883); TRectype& rec = rel.curr(); TString str; str << '(' << SALCE_CODES << "==" << oldes << ")&&(" << SALCE_TPSALDO << "==2)"; TCursor cur(&rel, str); const long items = cur.items(); cur.freeze(); TProgind pi(items, TR("Creazione ammortamenti"), FALSE, TRUE); for (cur = 0; cur.pos() < items; ++cur) { pi.addstatus(1); rec.put(AMMCE_CODES, newes); // Aggiorna anno di esercizio rec.put(AMMCE_TPSALDO, 1); // Aggiorna tipo saldo ad "iniziale" rec.zero(AMMCE_CSCEN); rec.zero(AMMCE_FZPER); rec.zero(AMMCE_FZQUO); // Le percentuali del nuovo esercizio devono essere uguali a quelle FINALI dell'esercizio precedente // Purtroppo sono sempre a zero per cui prendo quelle INIZIALI rec.put(AMMCE_PNOR, ammce1.get(AMMCE_PNOR)); rec.put(AMMCE_PACC, ammce1.get(AMMCE_PACC)); rec.put(AMMCE_PANT, ammce1.get(AMMCE_PANT)); incr_zero(rec, AMMCE_QNOR, AMMCE_QNORP); incr_zero(rec, AMMCE_QACC, AMMCE_QACCP); incr_zero(rec, AMMCE_QANT, AMMCE_QANTP); incr_zero(rec, AMMCE_QPERSE, AMMCE_QPERSEP); incr_zero(rec, AMMCE_FPRIVATO, AMMCE_FPRIVATOP); incr_zero(rec, AMMCE_QPPRIVATE, AMMCE_QPPRIVATEP); const int err = rel.write(); if (err != NOERR) // Should never happen! rel.rewrite(); } } void TOpenesc::main_loop() { TOpenesc_mask m; if (m.run() == K_ENTER) { const int oldes = m.get_int(F_OLDES); const int newes = m.get_int(F_NEWES); const TDate ies(m.get(F_NEWINIZIO)); const TDate fes(m.get(F_NEWFINE)); const bool provvis = m.get_bool(F_PROVVIS); if (crea_esercizio(oldes, newes, ies, fes)) { crea_attivita(oldes, newes, provvis); crea_registro(oldes, newes); crea_categorie(oldes, newes); crea_saldi(oldes, newes); crea_ammortamenti(oldes, newes); ditta_cespiti().set_attivita(newes, 0, NULL); } } } int ce2200(int argc, char* argv[]) { TOpenesc a; a.run(argc, argv, TR("Apertura esercizio cespiti")); return 0; }