#include #include #include #include #include "../cg/cg2103.h" #include "../db/dblib.h" #include "../pr/prlib.h" #include "../sv/svlib01.h" #include "veini.h" #include "velib.h" #include "sconti.h" #include "vepriv.h" #include "veuml.h" #include #include // calcola il prezzo per le spese void sppr_calc(const TRectype & rec, const TString & valuta_doc, const real & cambio, real & prezzo, exchange_type controeuro) { const TString4 sppr_valuta(rec.get("S4")); if (sppr_valuta != valuta_doc) { const bool prezzo_un = rec.get_char("S6") == 'Q'; if (prezzo_un) { TPrice val(prezzo, sppr_valuta); val.change_value(valuta_doc, cambio, controeuro); prezzo = val.get_num(); } else { TCurrency val(prezzo, sppr_valuta); val.change_value(valuta_doc, cambio, controeuro); prezzo = val.get_num(); } } } /////////////////////////////////////////////////////////// // Movimento di magazzino /////////////////////////////////////////////////////////// class TMov_mag_doc : public TMov_mag { TString_array _codmagc; protected: virtual const char * codmag_rauto(int r) const; public: void add_magc(const char* magc) { _codmagc.add(magc); } }; const char* TMov_mag_doc::codmag_rauto(int r) const { const TRecord_array& b = body(); if (r > b.rows()) // Can't check non-existent rows return NULL; const char tr = b[r].get_char(RMOVMAG_TIPORIGA); if (tr != 'D' && tr != 'A') // These are customer's added rows return NULL; int j = -1; // Indice per reperire il mag. collegato da _codmagc for (int i = r; i > 0; i--) // Scorre dalla riga r in su e conta quante righe D if (b[i].get_char(RMOVMAG_TIPORIGA) == 'D') j++; return j >= 0 && j < _codmagc.items() ? _codmagc.row(j) : NULL; } ///////////////////////////////////////////////////////////// // TRiepilogo IVA ///////////////////////////////////////////////////////////// TRiepilogo_iva& TRiepilogo_iva::copy(const TRiepilogo_iva& a) { (TRectype &) _codiva = (TRectype &) a._codiva; _imp = a._imp; _imp_orig = a._imp_orig; _imp_spese = a._imp_spese; _imp_spese_row = a._imp_spese_row; _iva = a._iva; _iva_spese = a._iva_spese; _sconto_perc = a._sconto_perc; _sconto_imp = a._sconto_imp; _iva_sconto = a._iva_sconto; _tipo = a._tipo; return *this; } TRiepilogo_iva::TRiepilogo_iva(const TCodiceIVA & codiva) : _codiva(codiva) { const TString& t =_codiva.tipo(); if (t == "VE") _tipo = 2; else if (t == "ES") _tipo = 4; else if (t == "NI") _tipo = 8; else if (t == "NS") _tipo = 16; else _tipo = 1; } /////////////////////////////////////////////////////////// // Agenti /////////////////////////////////////////////////////////// class TAgenti_cache : public TRecord_cache { protected: virtual TObject* rec2obj(const TRectype& rec) const { return new TAgente(rec);} public: const TAgente& agente(const char* chiave) { return (const TAgente &) get(chiave);} TAgenti_cache() : TRecord_cache(LF_AGENTI) {} virtual ~TAgenti_cache() { } }; HIDDEN TAgenti_cache * _agenti = NULL; /////////////////////////////////////////////////////////// // Documento per vendite /////////////////////////////////////////////////////////// long TDocumento::_firm = -1; TAssoc_array TDocumento::_tipi; TAssoc_array TDocumento::_numerazioni; TString4 TDocumento::_codiva_spese; TString4 TDocumento::_codiva_bolli; short TDocumento::_has_mag = 3; short TDocumento::_has_stat_ven = 3; short TDocumento::_has_provv = 3; TCodgiac_livelli * TDocumento::_livelli=NULL; // HIDDEN TStats_agg _st_agg; HIDDEN TAssoc_array _docs_to_agg; void TDocumento::init() { add_file(LF_RIGHEDOC, RDOC_NRIGA); set_memo_fld("G1"); _tipocf = new TRecfield(*this, DOC_TIPOCF); _codcf = new TRecfield(*this, DOC_CODCF); _cod_occas = new TRecfield(*this, DOC_OCFPI); _provv_agente = new TProvvigioni_agente; _sconto = _esenzione = NULL; _stato_originale = ' '; _dirty_deny = false; check_modules(); } TDocumento::TDocumento() : TMultiple_rectype(LF_DOC) { init(); } TDocumento::TDocumento(const TDocumento & d) : TMultiple_rectype(LF_DOC) { init(); copy(d); } TDocumento::TDocumento(char provv, int anno, const char* codnum, long numdoc) : TMultiple_rectype(LF_DOC) { init(); if (numdoc <= 0) { numdoc = 0; set_key(*this, provv, anno, codnum, numdoc); } else read(provv, anno, codnum, numdoc); } TDocumento::TDocumento(const TRectype& rec) : TMultiple_rectype(LF_DOC) { init(); read(rec); } TDocumento::~TDocumento() { delete _tipocf; delete _codcf; delete _cod_occas; if (_provv_agente != NULL) delete _provv_agente; if (_sconto != NULL) delete _sconto; if (_esenzione != NULL) delete _esenzione; } const TString& TDocumento::codiva_spese() const { ((TDocumento *)this)->test_firm(); return _codiva_spese;} const TString& TDocumento::codiva_bolli() const { ((TDocumento *)this)->test_firm(); return _codiva_bolli;} void TDocumento::check_modules() { if (_has_mag == 3) { _has_mag = dongle().active(MGAUT); _has_stat_ven = dongle().active(SVAUT); _has_provv = dongle().active(PRAUT); } } void TDocumento::set_variables(TExpression * e) const { const int items = e->numvar(); for (int i = 0; i < items; i++) { const TFieldref field(e->varname(i), LF_DOC); switch (field.file()) { case LF_CLIFO : e->setvar(i, clifor().get(field.name())); break; case LF_CFVEN : e->setvar(i, clifor().vendite().get(field.name())); break; default: e->setvar(i, get(field.name())); break; } } } void TDocumento::test_firm() { const long new_firm = prefix().get_codditta(); if (_firm != new_firm) { TConfig conf(CONFIG_DITTA, "ve"); _codiva_spese = conf.get("SPINCODIVA"); _codiva_bolli = conf.get("SPBOCODIVA"); _firm = new_firm; } } real TDocumento::spese_incasso(real & imp, int ndec, TTipo_importo t) const { static TArray spese_inc; static real maxadd, spadd; real imp_spese; const real percentuale = get(DOC_PERCSPINC); if (percentuale > ZERO) { if (ndec == AUTO_DECIMALS) ndec = decimals(); if (spese_inc.objptr(_rim_dir) == NULL) // Inizializzo le spese d'incasso se necessario { TConfig conf(CONFIG_STUDIO, "ve"); for (TTipo_pag p = _rim_dir; p < _nessun_pag; p = TTipo_pag((int)p + 1)) { const real r(conf.get("IMPSPINC", "ve", p)); spese_inc.add(r, p); } maxadd = (real)conf.get("MAXADD"); spadd = (real)conf.get("SPADD"); } // Calcola l'eventuale importo minimo per effetti (solitamente zero) const TRectype& cfven = clifor().vendite(); const real impmineff = cfven.get_real(CFV_IMPMINEFF); // Somma le spese di ogni singola rata const TPagamento& pag = ((TDocumento *)this)->pagamento(); const int nrate = pag.n_rate(); for (int i = 0; i < nrate; i++) { if (pag.importo_rata(i) >= impmineff) // Se la rata supera il minimo contrattuale { const TTipo_pag tp = (TTipo_pag)pag.tipo_rata(i); imp_spese += (const real&)spese_inc[tp]; } } if (imp_spese > ZERO && imp < maxadd) imp_spese += spadd; imp_spese = imp_spese * percentuale / CENTO; if (t == _lordo || t == _imposta) { TString4 codiva_es; iva_esente(codiva_es); const real iva_spese(TRiga_documento::iva(codiva_es.full() ? (const TString &)codiva_es : codiva_spese()).imposta(imp_spese, ndec)); if (t == _lordo) imp_spese += iva_spese; else if (t == _imposta) imp_spese = iva_spese; } const real cambio = get(DOC_CAMBIO); if (!cambio.is_zero()) { // Converte le spese nella valuta del documento const exchange_type ce = get_bool(DOC_CONTROEURO) ? _exchange_contro : _exchange_base; imp_spese = change_currency(imp_spese, "", ZERO, _exchange_undefined, get(DOC_CODVAL), cambio, ce, -1); } imp_spese.round(ndec); } return imp_spese; } void TDocumento::iva_esente(TString& codiva_es) const { codiva_es.cut(0); const int rows = physical_rows(); for (int r = 1; codiva_es.empty() && r <= rows; r++) { const TRiga_documento& riga = ((TDocumento*)this)->row(r); const TString4 str_codiva(riga.get(RDOC_CODIVA)); if (str_codiva.full()) { const TCodiceIVA codiva(str_codiva); const TString& tipoiva = codiva.tipo(); if (tipoiva.empty()) break; if (tipoiva == "NI") codiva_es = str_codiva; } } } real TDocumento::bolli(real & imp, int ndec, TTipo_importo t) const { real tot_bolli; static TArray sca_bolli; static TArray imp_bolli; static real bolli_es; static real impmin_bolli; static int nscagl; if (get_bool("ADDBOLLI")) { if (sca_bolli.objptr(0) == NULL) { TConfig conf(CONFIG_STUDIO, "ve"); bolli_es = (real) conf.get("BOLLIES", "ve"); impmin_bolli = (real) conf.get("IMPMINBOLLI", "ve"); for (nscagl = 0; nscagl < 7; nscagl++) { real s(conf.get("SPBOSCA", "ve", nscagl + 1)); real i(conf.get("SPBOIMP", "ve", nscagl + 1)); if (s == ZERO && i == ZERO) break; sca_bolli.add(s, nscagl); imp_bolli.add(i, nscagl); } } if (ndec == AUTO_DECIMALS) ndec = decimals(); TCurrency_documento imp_val(imp); imp_val.change_to_firm_val(); real importo = imp_val.get_num(); TPagamento & pag = ((TDocumento*)this)->pagamento(); const int nrate = pag.n_rate(); real old_bolli = -1.00; real iva_bolli; TCurrency_documento imp_orig_val(imposta()); imp_orig_val.change_to_firm_val(); const real imp_orig = imp_orig_val.get_num(); TCurrency_documento spese_val(spese()); spese_val.change_to_firm_val(); const real sp_orig = spese_val.get_num(); bool estero = FALSE; // Assumiamo per ora non estero TString4 codiva_es; iva_esente(codiva_es); for (int j = 0; j < 5 && tot_bolli+iva_bolli != old_bolli; j++) { old_bolli = tot_bolli + iva_bolli; const real imposte = imp_orig + iva_bolli; const real imp_spese = sp_orig + tot_bolli - iva_bolli; const real imponibile = importo - imposte - imp_spese; tot_bolli = ZERO; if (!tipo().nota_credito()) { real imponibile_esente; for (int r = physical_rows(); r > 0; r--) { const TRiga_documento& riga = ((TDocumento*)this)->row(r); const TCodiceIVA codiva(riga.get(RDOC_CODIVA)); if (codiva.tipo().not_empty()) imponibile_esente += riga.imponibile(); } if (imponibile_esente >= impmin_bolli) tot_bolli = bolli_es; } pag.set_total(imponibile, imposte, imp_spese); pag.set_rate_auto(); for (int i = 0; i < nrate; i++) { const TTipo_pag p = (TTipo_pag) pag.tipo_rata(i); real imp = pag.importo_rata(i); switch (p) { case _ric_ban: { int i; for (i = 0; i < nscagl - 1; i++) if ((real &) sca_bolli[i] >= imp) break; if (imp_bolli.items() > 0) tot_bolli += (real &) imp_bolli[i]; } break; case _tratta: case _tratta_acc: { if (j == 0) // Dobbiamo inizializzare la variabile 'estero' { TString16 key; key.format("%c|%ld", get_char(DOC_TIPOCF), get_long(DOC_CODCF)); const TRectype& clifo = cache().get(LF_CLIFO, key); const TString& stato_iva = clifo.get(CLI_STATOPAIV); estero = stato_iva.not_empty() && stato_iva != "IT"; if (!estero) { const TString& stato_cf = clifo.get(CLI_STATOCF); estero = (stato_cf.not_empty() && stato_cf != "IT") || clifo.get_char(CLI_COMCF) == 'Z'; } } real r(imp); const int ndec = decimals(); r.ceil(ndec == 0 ? -3 : 0); if (estero) r *= 0.009; else r *= 0.012; r.round(ndec == 0 ? -2 : ndec); tot_bolli += r; } break; case _cessione: case _paghero: case _let_cred: case _rim_dir: case _rid: case _bonfico: default: break; } } iva_bolli = TRiga_documento::iva(codiva_bolli()).imposta(tot_bolli, ndec); importo += (tot_bolli + iva_bolli - old_bolli); } if (t == _lordo) tot_bolli += iva_bolli; else if (t == _imposta) tot_bolli = iva_bolli; if (in_valuta()) { const real cambio = get_real("CAMBIO"); const exchange_type ce = get_bool(DOC_CONTROEURO) ? _exchange_contro : _exchange_base; tot_bolli = change_currency(tot_bolli, "", ZERO, _exchange_undefined, get(DOC_CODVAL), cambio, ce, -1); } tot_bolli.round(ndec); } return tot_bolli; } const TString & TDocumento::commessa_principale() const { if (codice_commessa().blank()) { const int row = physical_rows(); for (int i = 1; i <= rows(); i++) { const TRiga_documento &r = ((TRiga_documento &) ((TDocumento *)this)->row(i)); if (!r.codice_commessa().blank()) return r.codice_commessa(); } } return codice_commessa(); } bool TDocumento::modificabile() const { const char stato_attuale = stato(); if (stato_attuale <= ' ') return TRUE; const TString& stati_modifica = tipo().stati_iniziali_modifica(); return stati_modifica.blank() || stati_modifica.find(stato_attuale) >= 0; } bool TDocumento::cancellabile() const { const char stato_attuale = stato(); if (stato_attuale <= ' ') return TRUE; const TString& stati_cancellazione = tipo().stati_iniziali_cancellazione(); return stati_cancellazione.blank() || stati_cancellazione.find(stato_attuale) >= 0; } bool TDocumento::stampabile() const { const char stato_attuale = stato(); if (stato_attuale <= ' ') return TRUE; if (stato_attuale == tipo().stato_finale_stampa()) return FALSE; const TString& stati_stampa = tipo().stati_iniziali_stampa(); return stati_stampa.blank() || stati_stampa.find(stato_attuale) >= 0; } bool TDocumento::bloccato() const { const char stato_attuale = stato(); if (stato_attuale <= ' ') return false; char stato_bloccato = tipo().stato_bloccato(); if (stato_bloccato <= ' ') return false; return stato_attuale >= stato_bloccato; } bool TDocumento::chiuso() const { if (!tipo().is_scontrino()) return false; const char stato_attuale = stato(); if (stato_attuale <= ' ') return false; char stato_chiuso = tipo().stato_chiuso(); if (stato_chiuso <= ' ') return false; return stato_attuale >= stato_chiuso; } // Funzione statica utile a tutti gli utenti di LF_DOC e LF_RIGHEDOC void TDocumento::set_key(TRectype& rec, char provv, int anno, const char* codnum, long numdoc) { CHECK(provv == 'D' || provv == 'P', "Provvisorio o Definitivo?"); CHECKD(anno > 1900, "Anno non valido: ", anno); CHECK(codnum && *codnum, "Codice numerazione nullo"); CHECKD(numdoc >= 0, "Numero documento non valido ", numdoc); rec.put(DOC_PROVV, provv); rec.put(DOC_ANNO, anno); rec.put(DOC_CODNUM, codnum); rec.put(DOC_NDOC, numdoc); } // Funzione statica utile a tutti gli utenti di LF_DOC e LF_RIGHEDOC void TDocumento::copy_data(TRectype& dst, const TRectype& src) { const bool is_riga = dst.num() == LF_RIGHEDOC; // Memorizza tutti i campi chiave const char provv = dst.get_char(RDOC_PROVV); const int anno = dst.get_int(RDOC_ANNO); const TString4 codnum = dst.get(RDOC_CODNUM); const long numdoc = dst.get_long(RDOC_NDOC); const int nriga = is_riga ? dst.get_int(RDOC_NRIGA) : 0; const long idriga = is_riga ? dst.get_long(RDOC_IDRIGA) : 0; // Copia tutto il record dst = src; // Ripristina tutti i campi chiave set_key(dst, provv, anno, codnum, numdoc); dst.init_memo(RECORD_NON_FISICO); if (is_riga) { dst.put(RDOC_NRIGA, nriga); dst.put(RDOC_IDRIGA, idriga); dst.zero(RDOC_MOVMAG); const TString memo = src.get(RDOC_DESCEST); dst.put(RDOC_DESCEST, memo); } else { dst.zero(DOC_MOVMAG); dst.zero(DOC_NUMREG); dst.zero(DOC_NUMREGCA); } } // Funzione statica utile a tutti gli utenti di LF_RIGHEDOC void TDocumento::copy_data(TRiga_documento& dst, const TRiga_documento& src) { copy_data((TRectype&)dst, (const TRectype&)src); dst.put(RDOC_CODCMS, src.codice_commessa()); dst.put(RDOC_FASCMS, src.fase_commessa()); dst.put(RDOC_CODCOSTO, src.codice_costo()); } void TDocumento::copy_contents(const TDocumento& src, bool copy_header) { if (copy_header) copy_data(head(), src.head()); destroy_rows(); const int rows = src.physical_rows(); for (int i = 1; i <= rows ; i++) { const TRiga_documento& s = src[i]; TRiga_documento & r = new_row(s.tipo().codice()); copy_data(r, s); r.set_original_rdoc_key(s); } } TRiga_documento& TDocumento::insert_row(int row, const char *tipo) { TRiga_documento& r = (TRiga_documento&)TMultiple_rectype::insert_row(row); if (tipo && *tipo) r.set_tipo(tipo); return r; } TRiga_documento& TDocumento::new_row(const char *tipo) { TRiga_documento& r = (TRiga_documento&)TMultiple_rectype::new_row(); if (tipo && *tipo) r.set_tipo(tipo); return r; } int TDocumento::read(TBaseisamfile& f, word op, word lockop) { int err = TMultiple_rectype::read(f, op ,lockop); _cli_for.zero(); _occas.zero(); set_riga_sconto(); if (is_fattura()) set_riga_esenzione(); _stato_originale = stato(); if (err == NOERR && tipo_valido() && tipo().statistiche() && _has_stat_ven) { TString80 key(get(DOC_PROVV)); key << get(DOC_ANNO); key << get(DOC_CODNUM); key << get(DOC_NDOC); TObject* o = _docs_to_agg.objptr(key); const bool is_nota_credito = tipo().nota_credito(); if ( lockop >= _lock && o == NULL) { TStats_agg * st_agg = new TStats_agg; for (int i = physical_rows(); i > 0; i--) if (is_nota_credito) st_agg->add(row(i)); else st_agg->sub(row(i)); _docs_to_agg.add(key, st_agg, TRUE); } else if (lockop == _unlock && o != NULL) _docs_to_agg.remove(key); } if (err == NOERR && _has_provv) _old_agente = get(DOC_CODAG); else _old_agente.cut(0); return err; } int TDocumento::read(char provv, int anno, const char* codnum, long numdoc, word op, word lockop) { CHECK(numdoc > 0, "Numero documento nullo."); zero(); set_key(*this, provv, anno, codnum, numdoc); return read(op, lockop); } long TDocumento::renum_ndoc(long numdoc) { if (numdoc <= 0) { const char tn = tipo_numerazione(); const int an = anno(); const TString4 nu = numerazione(); numdoc = get_next_key(tn, an, nu); } put(DOC_NDOC, numdoc); // Aggiorna testata TMultiple_rectype::renum_key(); // Aggiorna righe ok return numdoc; } void TDocumento::set_riga_sconto() { const TString80 sconto(get(DOC_SCONTOPERC)); if (sconto.empty()) { if(_sconto != NULL) delete _sconto; _sconto = NULL; } else { if (_sconto == NULL) { static TString4 _tipo_riga_sc; if (_tipo_riga_sc.empty()) { TConfig conf(CONFIG_STUDIO, "ve"); _tipo_riga_sc = conf.get("TRSCONTI", "ve"); // Se non esiste il tipo riga lo cerca, lo setta di default ed avvisa if (_tipo_riga_sc.empty()) { _tipo_riga_sc = "08"; conf.set("TRSCONTI", _tipo_riga_sc); warning_box(FR("Il tipo riga sconti di testa non risultava impostato.\n L'applicazione usera' automaticamente il tipo %s"), (const char*) _tipo_riga_sc); } } _sconto = new TRiga_documento(this, _tipo_riga_sc); _sconto->put(RDOC_DESCR, TR("Sconto")); } _sconto->put(RDOC_SCONTO, sconto); } } void TDocumento::set_riga_esenzione() { TCli_for & c = clifor(); const TCodiceIVA codes(c.vendite().get(CFV_ASSFIS)); const TString16 v_esenzione(c.vendite().get(CFV_VSPROT)); const TString16 v_data_esenzione(c.vendite().get(CFV_VSDATAREG)); const TString16 n_registrazione(c.vendite().get(CFV_NSPROT)); const TString16 n_data_registrazione(c.vendite().get(CFV_NSDATAREG)); bool esente = codes.tipo().not_empty() && v_esenzione.not_empty() && v_data_esenzione.not_empty() && n_registrazione.not_empty() && n_data_registrazione.not_empty(); if (esente) { esente = false; const TString8 codiva = codes.codice(); for (int i = physical_rows(); !esente && i > 0; i--) esente = row(i).get(RDOC_CODIVA) == codiva; } if (!esente) { if(_esenzione != NULL) delete _esenzione; _esenzione = NULL; } else { static TString4 _tipo_riga_es; static TString80 _des_esenz; static real _bollo_es; if (_tipo_riga_es.empty()) { TConfig conf(CONFIG_STUDIO, "ve"); _tipo_riga_es = conf.get("TRESENZ", "ve"); _bollo_es = (real)conf.get("BOLLIES", "ve"); if (_tipo_riga_es.empty()) { _tipo_riga_es = "05"; conf.set("TRESENZ", _tipo_riga_es); warning_box("Il tipo riga esenzione non risultava impostato.\n L'applicazione usera' automaticamente il tipo %s", (const char*) _tipo_riga_es); } _des_esenz = conf.get("DESESENZ", "ve"); if (_des_esenz.not_empty()) _des_esenz.insert(" "); _des_esenz.insert("Fattura non imponibile"); } if (_esenzione == NULL) _esenzione = new TRiga_documento(this, _tipo_riga_es); TString d(256); d = _des_esenz; d << format(" come da vostra dichiarazione n. %s del %s da noi annotata al n. %s il %s.", (const char *) v_esenzione, (const char *) v_data_esenzione, (const char *) n_registrazione, (const char *) n_data_registrazione); _esenzione->put(RDOC_DESCR, d.left(50)); _esenzione->put(RDOC_DESCLUNGA, "X"); _esenzione->put(RDOC_DESCEST, d.mid(50)); } } void TDocumento::dirty_fields() { if (!_dirty_deny) { for (TDocumento_variable_field * f = (TDocumento_variable_field *) first_variable_field(); f != NULL; f = (TDocumento_variable_field *) succ_variable_field()) f->set_dirty(); dirty_tabella_iva(); if (loaded_rows(LF_RIGHEDOC)) // Se ho gia' caricato delle righe in memoria { TRecord_array& righe = body(LF_RIGHEDOC); for (int i = righe.last_row(); i > 0; i = righe.pred_row(i)) { TRiga_documento & r = (TRiga_documento &) righe[i]; r.dirty_fields(FALSE); } } _dirty_deny = true; } } int TDocumento::write_rewrite(TBaseisamfile & f, bool re) const { TDocumento& myself = *((TDocumento *)this); const bool new_doc = nuovo() || numero() <= 0; // E' nuovo di zecca! if (new_doc) { char stato_finale = tipo().stato_finale_inserimento(); if (stato() == '\0' && stato_finale > ' ') myself.stato(stato_finale); } else myself._stato_originale = stato(); const bool doc_bloccato = bloccato(); const char stato_doc(stato()); int err = NOERR; if (!doc_bloccato) { if (tipo().spese_aut() && !get_bool(DOC_SPESEUPD)) { char name[8] = "CODSP0"; TString_array spese; const TRectype & ven_rec = clifor().vendite(); for (int i = 1; i <= 4; i++) { name[5] = '0' + i; const TString& s = ven_rec.get(name); if (s.full()) spese.add(s); } myself.update_spese_aut(spese); } myself.update_conai(); myself.update_raee(); myself.set_row_ids(); const bool check_movmag = dongle().active(MGAUT) && tipo().mov_mag(); if (check_movmag) { const bool do_movmag = tipo().stato_with_mov_mag(stato_doc) && get(DOC_CAUSMAG).not_empty(); long num_movmag = get_long(DOC_MOVMAG); TMov_mag_doc mov; TLocalisamfile m(LF_MOVMAG); mov.zero(); if (do_movmag && num_movmag <= 0) { err = mov.write(m); if (err != NOERR) return err; num_movmag = mov.get_long(MOVMAG_NUMREG); myself.put(DOC_MOVMAG, num_movmag); } if (num_movmag > 0) { const bool scarica_residuo = tipo().scarica_residuo(); mov.put(MOVMAG_NUMREG, num_movmag); while (mov.read(m, _isequal, _testandlock) == _islocked) message_box("Movimento di magazzino n. %ld in uso da parte di un'altro utente", num_movmag); if (do_movmag) { TRecord_array & b = mov.body(); const int mag_rows = mov.rows(); int i; for (i = mag_rows; i > 0; i--) { TRectype & r = b[i]; if (r.get_char(RMOVMAG_TIPORIGA) == riga_dadocumento) { b.destroy_row(i); if (b.exist(i + 1) && b[i + 1].get_char(RMOVMAG_TIPORIGA) == riga_automatica) b.destroy_row(i + 1); } else if (r.get_bool(RMOVMAG_ESPLOSA)) b.destroy_row(i); } b.pack(); const TDate d(get(DOC_DATADOC)); TString4 codes; codes.format("%04d", mov.codice_esercizio(d)); mov.put(MOVMAG_ANNOES, codes); mov.put(MOVMAG_DATAREG, d); mov.put(MOVMAG_DATACOMP, d); mov.put(MOVMAG_DOCPROVV, get(DOC_PROVV)); mov.put(MOVMAG_ANNODOC, get(DOC_ANNO));; mov.put(MOVMAG_CODNUM, get(DOC_CODNUM)); long numdoc = get_long(DOC_NDOC); if (numdoc <= 0L) numdoc = myself.renum_ndoc(numdoc); mov.put(MOVMAG_NUMDOC, numdoc); const long ex_numdoc = get_long(DOC_NUMDOCRIF); if (ex_numdoc == 0) { mov.put(MOVMAG_EXNUMDOC, numdoc); mov.put(MOVMAG_EXDATADOC, d); } else { mov.put(MOVMAG_EXNUMDOC, ex_numdoc); const TDate ex_d(get("DATADOCRIF")); mov.put(MOVMAG_EXDATADOC, ex_d); } mov.put(MOVMAG_CATVEN, get("CATVEN")); mov.put(MOVMAG_CODLIST, get("CODLIST")); mov.put(MOVMAG_CODCONT, get("CODCONT")); mov.put(MOVMAG_CODCAMP, get("CODCAMP")); mov.put(MOVMAG_CODCAUS, get("CAUSMAG")); const TString4 codnum(numerazione()); mov.put(MOVMAG_DESCR, format("%s %s n. %ld del %s", (const char *) tipo().get("S1"),(const char *)codnum, numdoc, (const char *) d.string())); mov.put(MOVMAG_TIPOCF, get("TIPOCF")); mov.put(MOVMAG_CODCF, get("CODCF")); int j = 1; real cambio = ZERO; if (get(DOC_CODVAL).not_empty()) cambio = get_real(DOC_CAMBIO); if (cambio == ZERO) cambio = 1.0; const TString8 cod_caus(mov.get(MOVMAG_CODCAUS)); TCausale_magazzino caus(cod_caus); const bool esplodente = caus.esplodente(); const bool scarica_alt = caus.scarica_alternativi(); TString8 cod_caus_riga; TDistinta_tree dist; TCodice_articolo codart; for (i = 1; i <= physical_rows(); i++) { TRiga_documento & r = myself.row(i); const bool articolo = r.is_articolo(); bool valid_row = articolo; cod_caus_riga = r.get(RDOC_CAUSMAG); if (articolo) codart = r.get(RDOC_CODARTMAG); else { codart = r.get(RDOC_CODART); if (codart.full() && (cod_caus_riga.full() ? TCausale_magazzino(cod_caus_riga).esplodente() : esplodente)) valid_row = dist.set_root(codart); } if (valid_row) { long r_num = r.get_long(RDOC_MOVMAG); if (r_num == 0) { r_num = num_movmag; r.put(RDOC_MOVMAG, r_num); } const real qta = scarica_residuo ? r.qtaresidua(): r.quantita(); if (r_num == num_movmag && !qta.is_zero()) { TRectype & rm = mov.insert_row(j++); mov.add_magc(r.get(RDOC_CODMAGC)); rm.put(RMOVMAG_IMPIANTO, r.get(RDOC_IMPIANTO)); rm.put(RMOVMAG_LINEA, r.get(RDOC_LINEA)); rm.put(RMOVMAG_CODMAG, r.get(RDOC_CODMAG)); if (articolo && (cod_caus_riga.full() ? TCausale_magazzino(cod_caus_riga).scarica_alternativi() : scarica_alt)) { const TRectype art = cache().get(LF_ANAMAG, codart); const TString & alt = art.get(ANAMAG_CODARTALT); if (alt.full()) codart = alt; } rm.put(RMOVMAG_CODART, codart); rm.put(RMOVMAG_LIVGIAC, r.get(RDOC_LIVELLO)); rm.put(RMOVMAG_UM, r.get(RDOC_UMQTA)); rm.put(RMOVMAG_QUANT, qta); TCurrency_documento prezzo(r.prezzo(TRUE, FALSE), *this, TRUE); prezzo.change_to_firm_val(); rm.put(RMOVMAG_PREZZO, prezzo.get_num()); rm.put(RMOVMAG_CODCAUS, cod_caus_riga); rm.put(RMOVMAG_TIPORIGA, (char) riga_dadocumento); } } const TString & indetr = r.get(RDOC_TIPODET); if (indetr.full()) { const TRectype & det = cache().get("%DET", indetr); if (!det.empty() && !det.get_bool("FPC")) { TTable tab("%DET"); tab.curr() = det; tab.curr().put("FPC", "X"); tab.rewrite(); } } } mov.rewrite(m); } else { mov.remove(m); for (int i = physical_rows(); i > 0; i--) { TRiga_documento & r = myself.row(i); r.zero(RDOC_MOVMAG); } myself.zero(DOC_MOVMAG); } } } } { TLocalisamfile anamag(LF_ANAMAG); TLocalisamfile codalt(LF_CODCORR); codalt.setkey(2); bool docevaso = TRUE; const TDate datacons(get_date(DOC_DATACONS)); const TString80 codcms(get(DOC_CODCMS)); const TString80 fascms(get(DOC_FASCMS)); const TString80 codcos(get(DOC_CODCOSTO)); for (int i = physical_rows(); i > 0; i--) { TRiga_documento& r = myself.row(i); if ((r.is_merce() || r.is_omaggio()) && !r.is_checked()) { if (r.get(RDOC_CODARTMAG) == NULL_CODART) r.put(RDOC_CODARTMAG, ""); else { const TString & codart = r.get("CODART"); anamag.put("CODART", codart); if (anamag.read() == NOERR) r.put("CODARTMAG", codart); else { codalt.put("CODARTALT", codart); if (codalt.read() == NOERR) r.put("CODARTMAG", codalt.get("CODART")); } r.checked(); } } if (r.is_evadibile() && is_ordine()) { docevaso &= r.is_evasa(); const TDate dcons = r.get_date(RDOC_DATACONS); if (!dcons.ok()) r.put(RDOC_DATACONS, datacons); } if (r.get(RDOC_CODCMS).blank() && r.get(RDOC_FASCMS).blank() && r.get(RDOC_CODCOSTO).blank()) { r.put(RDOC_CODCMS, codcms); r.put(RDOC_FASCMS, fascms); r.put(RDOC_CODCOSTO, codcos); } } if (is_ordine()) ((TDocumento *)this)->put(DOC_DOCEVASO, docevaso); // Tutte le righe evase -> doc evaso } // Almeno una riga aperta -> doc aperto err = TMultiple_rectype::write_rewrite(f, re); if (!doc_bloccato && err == NOERR) { if (clifor().occasionale()) { if (get("OCFPI").not_empty()) { TLocalisamfile o(LF_OCCAS); TOccasionale & occ = occas(); err = occ.write(o); if (err == _isreinsert) err = occ.rewrite(o); } } if (_has_provv && tipo().provvigioni() && tipo().stato_provvigioni() <= stato()) { const TString16 agente = get(DOC_CODAG); if (agente != _old_agente) { if (_old_agente.not_empty()) { const int anno = get_int(DOC_ANNO); const TString16 codnum = get(DOC_CODNUM); const long numdoc = get_long(DOC_NDOC); TProvvigioni_agente provv; if (provv.read(_old_agente, anno, codnum, numdoc) == NOERR) provv.remove(); } myself._old_agente = agente; } if (agente.not_empty()) myself.write_provvigioni(); } if (tipo().statistiche() && _has_stat_ven) { TString80 key(get(DOC_PROVV)); key << get(DOC_ANNO); key << get(DOC_CODNUM); key << get(DOC_NDOC); TStats_agg * st_agg = (TStats_agg *) _docs_to_agg.objptr(key); const bool is_nota_credito = tipo().nota_credito(); if (st_agg == NULL) { st_agg = new TStats_agg; _docs_to_agg.add(key, st_agg, TRUE); } int i; for (i = physical_rows(); i > 0; i--) if (is_nota_credito) st_agg->sub(myself.row(i)); else st_agg->add(myself.row(i)); st_agg->update(); for (i = physical_rows(); i > 0; i--) if (is_nota_credito) st_agg->add(myself.row(i)); else st_agg->sub(myself.row(i)); } } return err; } // eliminare anche il mov di mag. ?????? int TDocumento::remove(TBaseisamfile& f) const { if (!cancellabile() && !yesno_box("Documento non cancellabile,\nContinuare ugualmente")) return NOERR; const bool check_movmag = dongle().active(MGAUT) && tipo().mov_mag(); const bool doc_bloccato = bloccato(); if (check_movmag) { const long num = get_long("MOVMAG"); if (num > 0) { TMov_mag_doc mov; TLocalisamfile m(LF_MOVMAG); mov.put(MOVMAG_NUMREG, num); while (mov.read(m, _isequal, _testandlock) == _islocked) message_box("Movimento di magazzino in uso da parte di un'altro utente"); if (doc_bloccato) { const int rows = mov.rows(); for (int i= 1; i <= rows; i++) mov.body()[i].zero(RMOVMAG_TIPORIGA); mov.rewrite(m); } else mov.remove(m); } } if (!doc_bloccato) { if (tipo().statistiche() && _has_stat_ven) { TString80 key(get(DOC_PROVV)); key << get(DOC_ANNO); key << get(DOC_CODNUM); key << get(DOC_NDOC); TStats_agg * st_agg = (TStats_agg *) _docs_to_agg.objptr(key); if (st_agg != NULL) { st_agg->update(); _docs_to_agg.remove(key); } } if (_has_provv && tipo().provvigioni()) { const TString8 agente(get(DOC_CODAG)); const int anno = TDocumento::anno(); const TString4 codnum(numerazione()); const long ndoc = numero(); // Legge le provvigioni per questo documento _provv_agente->read(agente, anno,codnum,ndoc); // Le rimuove _provv_agente->remove(); } } return TMultiple_rectype::remove(f); } int TDocumento::decimals(bool price) const { const TString4 codval(get(DOC_CODVAL)); const TExchange exc(codval); const int ndec = exc.decimals(price); return ndec; } void TDocumento::flush_rows() { remove_body(LF_RIGHEDOC); } TProvvigioni_agente& TDocumento::calc_provvigioni(const bool generata) { CHECK (_provv_agente, "Bad TProvvigione_agente object"); TString16 agente(get(DOC_CODAG)); const int anno = TDocumento::anno(); TString16 codnum(numerazione()); const long ndoc = numero(); TDate datadoc(data()); while (_provv_agente->read(agente, anno,codnum,ndoc) == _islocked) // Legge le provvigioni per questo documento if (!yesno_box("Dati agente %s in uso da un altro utente. Riprovare?", (const char*) agente)) return *_provv_agente; const TString16 codval(TDocumento::valuta()); const real change(cambio()); const real perc = _provv_agente->perc_fatt(); TCurrency_documento tot_doc(totale_doc(), *this); TCurrency_documento tot_netto(totale_netto(), *this); TCurrency_documento tot_provv(provvigione(), *this); TCurrency_documento provv_fat((tot_provv.get_num() / 100.0) * perc, *this); // Provvigione sul fatturato (rata 0) // const int ndec = decimals(); // provv_fat.round(ndec); TCurrency_documento provv_pag = tot_provv - provv_fat; // Provvigione sul pagato (da suddivere secondo il pagamento) const bool valuta = in_valuta(); // Calcolo rate per provvigioni e documento TPagamento& pag1 = pagamento(); // Per rate documento TPagamento* pag2 = new TPagamento(pag1.code(), datadoc.string()); // Per rate documento // Rilegge il pagamento, nel caso in cui venga chiamata la scrittura del documento // corrente dopo che è stata effettuata una contabilizzazione; la contabilizzazione // nel caso di anticipo aggiunge una rata in più if (pag1.n_rate() > pag2->n_rate()) pag1.read(); TCurrency_documento totspese(spese(), *this); TCurrency_documento totimposte(imposta(), *this); TCurrency_documento totimponibili(tot_doc - totimposte - totspese); TCurrency_documento anticipo(get_real(DOC_IMPPAGATO), *this); if (is_nota_credito()) // Se il documento e' una nota di credito, cambia segno { tot_doc = -tot_doc; tot_netto = -tot_netto; tot_provv = -tot_provv; provv_fat = -provv_fat; provv_pag = -provv_pag; totspese = -totspese; totimposte = -totimposte; totimponibili = -totimponibili; } // Considera l'anticipo, come in contabilizzazione ed in generazione effetti // // Un anticipo su di una nota di credito non dovrebbe comunque mai esistere, non ha senso. // Se esiste è un errore in inserimento da parte del cliente. if (anticipo.get_num() < abs(tot_doc.get_num())) { TGeneric_distrib d(anticipo.get_num(), decimals()); d.add(totimponibili.get_num()); d.add(totimposte.get_num()); d.add(totspese.get_num()); const TCurrency_documento pagtotimponibili(totimponibili.get_num() - d.get(), *this); const TCurrency_documento pagtotimposte(totimposte.get_num() - d.get(), *this); const TCurrency_documento pagtotspese(totspese.get_num() - d.get(), *this); TCurrency zero(ZERO); if (valuta) { //real val1 = totimponibili * change; TCurrency_documento val2(pagtotimposte); val2.change_to_firm_val(); TCurrency_documento val3(pagtotspese); val3.change_to_firm_val(); TCurrency_documento val1(tot_doc); val1.change_to_firm_val(); val1 -= val2 - val3; pag1.set_total_valuta(pagtotimponibili, pagtotimposte, pagtotspese, val1, val2, val3); TCurrency_documento provv_pag_base(provv_pag) ; provv_pag_base.change_to_firm_val(); pag2->set_total_valuta(provv_pag, zero, zero, provv_pag_base, zero, zero); } else { pag1.set_total(pagtotimponibili, pagtotimposte, pagtotspese); pag2->set_total(provv_pag, zero, zero); } pag1.set_rate_auto(); pag2->set_rate_auto(); } else { pag1.zap_rate(); pag2->zap_rate(); } const bool is_anticipo = anticipo.get_num() > ZERO; if (is_anticipo) { pag1.add_rata(); TDate first_scad(pag1.data_rata(0)); if (datadoc == first_scad) pag1.set_datarata(0, ++first_scad); for (int k=pag1.n_rate()-1; k>0; k--) pag1.rata(k) = pag1.rata(k-1); if (anticipo >= tot_doc) anticipo = tot_doc; TCurrency_documento anticipo_base(anticipo); anticipo_base.change_to_firm_val(); pag1.set_rata(0, valuta ? anticipo.get_num() : ZERO, anticipo_base.get_num(), datadoc, 1, "", FALSE); } // Crea le nuove rate provvigionali const bool isnew = _provv_agente->items() == 0; // Il documento non ha righe provvigionali TRate_doc& rd = _provv_agente->rate(anno, codnum, ndoc, isnew ? TRUE : FALSE); // A questo punto rd e' vuoto: settiamo i dati del documento: TToken_string t; t.add(anno); t.add(codnum);t.add(ndoc); t.add(datadoc.string()); t.add(tot_doc.string()); t.add(tot_provv.string());t.add(tot_netto.string()); t.add(codcf()); t.add(TDocumento::valuta());t.add(change.string()); t.add(get(DOC_DATACAMBIO)); rd.set(t); // Adesso si possono aggiungere le rate (per quelle gia' esistenti sostituisce solo alcuni valori) // - Rata 0 : importo rata = 0; importo provvigione = provvigione all'atto della fattura (percentuale sugli agenti) // data scadenza viene settata uguale alla data documento // la provvigione rimanente va suddivisa in rate a seconda del codice pagamento // Nel caso si ha un anticipo documento, l'importo della rata non sarà 0 ma eguale all'anticipo stesso // Se poi abbiamo il caso in cui l'anticipo paga completamente il documento // non avremo alcuna rata e tutto l'importo della provvigione del doc. andrà comunque // sulla rata 0, anche se la provvigione sul fatturato è 0 (% a 0) const int nrate = pag1.n_rate(); if (nrate == 1 && is_anticipo) // significa che l'anticipo paga tutto ora, quindi provv_fat vale tutta la provvigione del documento provv_fat = tot_provv; const bool first_rata_ok = provv_fat.get_num() != ZERO; // Impostazione prima rata solo se la provvigione sul fatturato è diversa da 0 if (first_rata_ok) { TRata& rt = rd.row(0,TRUE); rt.set_rata(0); rt.set_datascad(datadoc); rt.set_tipopag(1); rt.set_imprata(anticipo.get_num()); rt.set_impprovv(provv_fat.get_num()); if (generata) rt.set_generata(); } // Setta le rate rimanenti int i; for (i = 1; i <= nrate; i++) { if (i == nrate && is_anticipo) break; const int index = is_anticipo ? i : i - 1; TRata& rt = rd.row(first_rata_ok ? i : i - 1, TRUE); rt.set_rata(i); rt.set_datascad(pag1.data_rata(index)); rt.set_tipopag(pag1.tipo_rata(index)); rt.set_imprata(pag1.importo_rata(index,valuta ? TRUE : FALSE)); rt.set_impprovv(pag2->importo_rata(i-1,valuta ? TRUE : FALSE)); if (generata) rt.set_generata(); } // Rimuove eventuali righe in eccesso const int rd_items = rd.items(); // Rate precedenti for (i = first_rata_ok ? nrate+1 : nrate; i < rd_items; i++) rd.remove_rata(i); delete pag2; return *_provv_agente; } int TDocumento::write_provvigioni() { return calc_provvigioni().write(); } bool TDocumento::in_valuta() const { const TString& val = valuta(); return is_true_value(val); } TCodgiac_livelli & TDocumento::livelli() const { if (_livelli == NULL) _livelli = new TCodgiac_livelli(); return *_livelli; } TRiga_documento & TDocumento::row(int index) { TRecord_array & b = body(); const int nrows = b.rows(); TRiga_documento * r = NULL; if (index <= nrows) { r = &((TRiga_documento &) b.row(index, FALSE)); CHECKD(r, "Riga documento non esistente ", index); } else { CHECKD((index == nrows + 1 && (_sconto != NULL || _esenzione != NULL)) || (index == nrows + 2 && _sconto != NULL && _esenzione != NULL), "Riga documento non esistente ", index); if (index == nrows + 1) { r = _sconto != NULL ? _sconto : _esenzione; } if (index == nrows + 2) r = _esenzione; } return *r; } const TRiga_documento& TDocumento::physical_row(int index) const { TRecord_array & b = body(); return (TRiga_documento&)b.row(index, FALSE); } long TDocumento::get_next_key(char provv, int anno, const char* codnum) const { long n = 0; TLocalisamfile doc(LF_DOC); TRectype& curr = doc.curr(); set_key(curr, provv, anno, codnum, 9999999L); const int err = doc.read(_isgreat); if (err != _isemptyfile) { if (err == NOERR) doc.prev(); if (curr.get_char("PROVV") == provv && curr.get_int("ANNO") == anno && curr.get("CODNUM") == codnum) n = curr.get_long("NDOC"); } n++; return n; } const TTipo_documento& TDocumento::tipo(const char* tipodoc) { TTipo_documento* o = (TTipo_documento*)_tipi.objptr(tipodoc); if (o == NULL) { #ifdef DBG if (tipodoc == NULL || *tipodoc == '\0') NFCHECK("Tipo documento nullo"); #endif o = new TTipo_documento(tipodoc); _tipi.add(tipodoc, o); } return *o; } const TTipo_documento& TDocumento::tipo() const { TString4 tipodoc(get(DOC_TIPODOC)); #ifdef DBG if (tipodoc.blank()) // Test necessario per lavorare anche su dati rovinati { const TCodice_numerazione& codnum = codice_numerazione(); tipodoc = codnum.tipo_doc(0); yesnofatal_box("Tipo documento nullo su %d %s %ld\nforzato a %s", get_int(DOC_ANNO), (const char*)get(DOC_CODNUM), get_long(DOC_NDOC), (const char*)tipodoc); ((TDocumento*)this)->set_tipo(tipodoc); } #endif return tipo(tipodoc); } const TCodice_numerazione& TDocumento::codice_numerazione(const char* numerazione) { TCodice_numerazione* o = (TCodice_numerazione*)_numerazioni.objptr(numerazione); if (o == NULL) { o = new TCodice_numerazione(numerazione); _numerazioni.add(numerazione, o); } return *o; } const TCodice_numerazione& TDocumento::codice_numerazione() const { return codice_numerazione(numerazione()); } bool TDocumento::raggruppabile(const TDocumento& doc, TToken_string& campi) const { bool ok = raggruppabile() && doc.raggruppabile(); if (ok) { TString campo; for (const char* c = campi.get(0); c && ok; c = campi.get()) { if (strncmp(c, "CODABI", 6) == 0 || strncmp(c, "CODCAB", 6) == 0) { long cod = get_long(c); ok &= (cod == doc.get_long(c)); } else { campo = get(c); ok &= campo == doc.get(c); } } } return ok; } void TDocumento::set_fields(TAuto_variable_rectype & rec) { if (tipo_valido()) { TTipo_documento & tipo_doc = (TTipo_documento &) tipo(); const TString& tot_doc = tipo_doc.totale_doc(); for (const TFormula_documento* f = tipo_doc.first_formula(); f; f = tipo_doc.succ_formula()) { TExpr_documento * exp = f->expr(); if (exp != NULL) // Puo' succedere che sia NULL con dati incoerenti { if (tot_doc == f->name()) { TString16 tot_doc_netto(tot_doc); tot_doc_netto.insert("_"); const TFixed_string netto_def(exp->string()); TExpr_documento netto_exp(netto_def, _numexpr, this); add_field(new TDocumento_variable_field(tot_doc_netto, netto_exp)); if (netto_def == "IMPONIBILI()+IMPOSTE()") { TExpr_documento tot_exp("IMPONIBILI(1)+IMPOSTE(1)", _numexpr, this); add_field(new TDocumento_variable_field(tot_doc, tot_exp)); } else { TExpr_documento tot_exp(format("%s + _BOLLI(%s)", (const char *) tot_doc_netto, (const char *) tot_doc_netto), _numexpr, this); add_field(new TDocumento_variable_field(tot_doc, tot_exp)); } } else { exp->set_doc(this); add_field(new TDocumento_variable_field(f->name(), *exp)); } } } for (TVariable_field * src_field = rec.first_variable_field(); src_field != NULL; src_field = rec.succ_variable_field()) { const char * fieldname = src_field->name(); if (!exist(fieldname)) put(fieldname, rec.get(fieldname)); } } } real TDocumento::imponibile(bool spese, int ndec) const { real val; if (physical_rows() > 0) { TAssoc_array & table = ((TDocumento *)this)->tabella_iva(); for (TRiepilogo_iva * ri = (TRiepilogo_iva *) table.get(); ri != NULL; ri = (TRiepilogo_iva *) table.get()) val += ri->imponibile(spese); if (ndec == AUTO_DECIMALS) ndec = decimals(); val.round(ndec); } return val; } void TDocumento::calc_iva_fattura_commerciale() { // Calcolo iva per fatture commerciali: // 1) effettua la sommatoria di tutti i real per ogni elementi di _tabella_iva in un TRiepilogo_iva unico // 2) azzera _tabella_iva // 3) scorpora in % a seconda di cio' che e' indicato in configurazione, e mette i nuovi elementi in _tabella_iva // 4) per ogni nuovo elemento di _tabella_iva, ricalcola la relativa imposta. TAssoc_array & table = _tabella_iva; TRiepilogo_iva t; static TString_array tabella_ripartizione; const int ndec = decimals(); if (tabella_ripartizione.items() == 0) { TConfig cnf(CONFIG_STUDIO, "ve"); for (int k = 1; k <= MAX_IVA_SLICES; k++) { TToken_string* tt = new TToken_string(); tt->add(cnf.get("EXCLUDE_PERC", NULL, k)); tt->add(cnf.get("EXCLUDE_IVA", NULL, k)); tabella_ripartizione.add(tt); } } // 1) table.restart(); for (TRiepilogo_iva * ri = (TRiepilogo_iva *) table.get(); ri != NULL; ri = (TRiepilogo_iva *) table.get()) { t.imp() += ri->imp(); t.imp_spese() += ri->imp_spese(); t.imp_spese_row() += ri->imp_spese_row(); t.iva_spese() += ri->iva_spese(); t.iva_sconto() += ri->iva_sconto(); t.sconto_perc() += ri->sconto_perc(); t.sconto_imp() += ri->sconto_imp(); } // 2) table.destroy(); // 3) TArray tda; tda.add(new TDistrib(t.imp(), ndec)); tda.add(new TDistrib(t.imp_spese(), ndec)); tda.add(new TDistrib(t.imp_spese_row(), ndec)); tda.add(new TDistrib(t.iva_spese(), ndec)); tda.add(new TDistrib(t.iva_sconto(), ndec)); tda.add(new TDistrib(t.sconto_perc(), ndec)); tda.add(new TDistrib(t.sconto_imp(), ndec)); int k; for (k = 0; k < MAX_IVA_SLICES; k++) for (int j = 0; j < 7; j++) { const real p (tabella_ripartizione.row(k).get(0)); TDistrib& td = (TDistrib&) tda[j]; td.add(p); } // 4) for (k = 0; k < MAX_IVA_SLICES; k++) { TString16 cod(tabella_ripartizione.row(k).get(1)); cod.trim(); if (cod.empty()) continue; const TCodiceIVA civa(cod); TRiepilogo_iva * rp = (TRiepilogo_iva *) table.objptr(cod); if (rp == NULL) { rp = new TRiepilogo_iva(civa); table.add(cod, rp); } for (int j = 0; j < 7; j++) { TDistrib& td = (TDistrib&) tda[j]; const real rr = td.get(); switch (j) { case 0: rp->imp() = rr; rp->iva() = civa.imposta(rr, ndec); break; case 1: rp->imp_spese() = rr; break; case 2: rp->imp_spese_row() = rr; break; case 3: rp->iva_spese() = rr; break; case 4: rp->iva_sconto() = rr; break; case 5: rp->sconto_perc() = rr; break; case 6: rp->sconto_imp() = rr; break; default: break; } } } } void TDocumento::update_tabella_iva(bool solo_imponibili) { static bool __solo_imponibili = false; const int items = rows(); TAssoc_array & table = _tabella_iva; if (items == 0) { table.destroy(); return; } if (__solo_imponibili != solo_imponibili) { table.destroy(); __solo_imponibili = solo_imponibili; } if (table.items() > 0) { if (items == 0) table.destroy(); return; } const bool doc_al_lordo = tipo().calcolo_lordo(); TRiepilogo_iva * aliquota; const int ndec = decimals(); for (int j = items; j > 0; j--) { const TRiga_documento& r = row(j); if (!r.is_sconto() && !r.is_descrizione()) { const TCodiceIVA & iva = r.iva(); if (iva.ok()) { const TString & cod = iva.codice(); aliquota = (TRiepilogo_iva *) table.objptr(cod); if (aliquota == NULL) { aliquota = new TRiepilogo_iva(iva); table.add(cod, aliquota); } const real imponibile = doc_al_lordo ? r.importo(true, true, ndec) : r.imponibile(); aliquota->imp_orig() += imponibile; } } } if (solo_imponibili) return; real tot_doc; real tot_sconti; real tot_sconti_perc; TArray imponibili; const bool fatt_comm = tipo().fattura_commerciale(); TString4 codiva_es; iva_esente(codiva_es); for (int i = items; i > 0; i--) { const TRiga_documento& r = row(i); const real imponibile = doc_al_lordo ? r.importo(true, true, ndec) : r.imponibile(); tot_doc += imponibile; if (r.is_sconto()) { tot_sconti += imponibile; if (r.is_sconto_perc()) tot_sconti_perc += imponibile; } else if (!r.is_descrizione()) { const real imposta = doc_al_lordo ? ZERO :r.imposta(FALSE); // Aggiorna o aggiunge l'elemento se non esiste const TCodiceIVA & iva = r.iva(); if (iva.ok()) { const TString & cod = iva.codice(); aliquota = (TRiepilogo_iva *) table.objptr(cod); if (aliquota == NULL) { aliquota = new TRiepilogo_iva(iva); table.add(cod, aliquota); } aliquota->imp() += imponibile; if (r.is_spese() && iva.tipo().not_empty()) aliquota->imp_spese_row() += imponibile; aliquota->iva() += imposta; } tot_doc += imposta; } } if (table.items() == 0) return; if (tot_sconti != ZERO) { TGeneric_distrib d(tot_sconti, ndec); real tot_sconti_imp = tot_sconti - tot_sconti_perc; { FOR_EACH_ASSOC_OBJECT(table, obj, key, o) { TRiepilogo_iva * aliquota = (TRiepilogo_iva *) o; d.add(aliquota->imp() - aliquota->imp_spese_row()); } } FOR_EACH_ASSOC_OBJECT(table, obj, key, o) { TRiepilogo_iva * aliquota = (TRiepilogo_iva *) o; const TCodiceIVA & ci = aliquota->cod_iva(); const real i(d.get()); real & imponibile = aliquota->imp(); imponibile += i; TGeneric_distrib s(i, ndec); s.add(tot_sconti_imp); s.add(tot_sconti_perc); aliquota->sconto_imp() = s.get(); aliquota->sconto_perc() = s.get(); real & iva = aliquota->iva(); /* if (doc_al_lordo) { const real imposta(ci.imposta(i, ndec)); TGeneric_distrib iva(imposta, ndec); iva.add(tot_sconti_imp); iva.add(tot_sconti_perc); imponibile += imposta; aliquota->sconto_imp() += iva.get(); aliquota->sconto_perc() += iva.get(); tot_doc += imposta; } else */ if (!doc_al_lordo) { const real imposta(ci.imposta(i, ndec)); iva += imposta; aliquota->iva_sconto() = imposta; tot_doc += imposta; } } } if (fatt_comm) calc_iva_fattura_commerciale(); const real rit = ritenute(); real val = spese_incasso(real(tot_doc - rit), ALL_DECIMALS, doc_al_lordo ? _lordo : _netto); if (!val.is_zero()) { const TString& codiva = codiva_es.full() ? (const TString &) codiva_es : codiva_spese(); TRiepilogo_iva* ri = (TRiepilogo_iva*)table.objptr(codiva); if (ri == NULL && codiva.full()) { ri = new TRiepilogo_iva(TCodiceIVA(codiva)); table.add(codiva, ri); } if (ri != NULL) ri->imp_spese() += val; tot_doc += val; if (!doc_al_lordo) { val = spese_incasso(real(tot_doc - rit), ALL_DECIMALS, _imposta); if (ri != NULL) ri->iva_spese() += val; tot_doc += val; } } val = bolli(real(tot_doc - rit), ALL_DECIMALS, doc_al_lordo ? _lordo : _netto); if (val != ZERO) { const TString& codiva = codiva_bolli(); if (codiva.full()) { TRiepilogo_iva* ri = (TRiepilogo_iva*)table.objptr(codiva); if (ri == NULL) { ri = new TRiepilogo_iva(TCodiceIVA(codiva)); table.add(codiva, ri); } if (!doc_al_lordo) { real valiva = bolli(real(tot_doc - rit), ALL_DECIMALS, _imposta); ri->iva_spese() += valiva; tot_doc += valiva; } ri->imp_spese() += val; } tot_doc += val; } // SCORPORO if (doc_al_lordo) { FOR_EACH_ASSOC_OBJECT(table, obj, key, o) { TRiepilogo_iva * aliquota = (TRiepilogo_iva*) o; const TCodiceIVA& iva = aliquota->cod_iva(); aliquota->iva() = iva.scorpora(aliquota->imp(), ndec); aliquota->iva_spese() = iva.scorpora(aliquota->imp_spese(), ndec); iva.scorpora(aliquota->imp_spese_row(), ndec); aliquota->iva_sconto() = iva.scorpora(aliquota->sconto_imp(), ndec); aliquota->iva_sconto() += iva.scorpora(aliquota->sconto_perc(), ndec); } } } real TDocumento::imposta(bool spese, int ndec) const { real val = ZERO; if (physical_rows() > 0) { TAssoc_array & table = ((TDocumento *)this)->tabella_iva(); if (ndec == AUTO_DECIMALS) ndec = decimals(); for (TRiepilogo_iva * ri = (TRiepilogo_iva *) table.get(); ri != NULL; ri = (TRiepilogo_iva *) table.get()) { real iva = ri->imposta(spese); if (ndec == 0) { if (iva < ZERO) iva.floor(ndec); else iva.ceil(ndec); } else iva.round(ndec); val += iva; } } return val; } real TDocumento::totale_doc() const { /* A pag.1 c'e' scritto di non fare cosi' const TString16 field(tipo().totale_doc()); if (field.not_empty()) return get_real(field); else { real r = imponibile() + imposta(); const int ndec = decimals(); r += spese_incasso(r - ritenute()), ndec); r += bolli(real(r - ritenute()), ndec); return r; } */ // Cosi' e' piu' ordinato, strutturato e veloce real r; const TString& field = tipo().totale_doc(); if (field.blank()) { const int ndec = decimals(); const bool lordo = tipo().calcolo_lordo(); r = imponibile(lordo); if (!lordo) r += imposta(); r += spese_incasso(real(r - ritenute()), ndec); r += bolli(real(r - ritenute()), ndec); } else r = get_real(field); return r; } real TDocumento::totale_netto() const { const TString& field = tipo().totale_netto(); if (field.not_empty()) return get_real(field); else return imponibile() + imposta(); } real TDocumento::basesconto() const { const TString& field = tipo().basesconto(); if (field.not_empty()) return get_real(field); else return ZERO; } real TDocumento::spese() const { const TString& field = tipo().spese(); if (field.not_empty()) return get_real(field); else return ZERO; } real TDocumento::ritenute(const char tipo, bool lordo, int ndec) const { real val; for (int i = rows() ; i > 0; i--) { TRiga_documento &r = ((TRiga_documento &) ((TDocumento *)this)->row(i)); val += r.ritenuta(tipo, lordo, ndec); } return val; } TPagamento& TDocumento::pagamento() { const char tipocf = get_char(DOC_TIPOCF); const long codcf = get_long(DOC_CODCF); _pag.set_clifo(codcf, tipocf); TDate data_in = get_date(DOC_DATAINSC); if (data_in.empty()) data_in = get_date(DOC_DATADOC); const TString8 codpag(get(DOC_CODPAG)); if (codpag != _pag.code()) { _pag.set_code(codpag); _pag.read(); _pag.set_inizio(data_in); // Perche' rispetta rate TRUE? } else { if (data_in != _pag.get_datadoc()) _pag.set_inizio(data_in); // Perche' rispetta rate TRUE? } return _pag; } real TDocumento::provvigione(int ndec) const { TString16 field = agente().campoprovv(); if (field.empty()) field = tipo().totprovv(); real val; if (field.not_empty()) val = get_real(field); else { if (ndec == AUTO_DECIMALS) ndec = decimals(); for (int i = rows(); i > 0; i--) val += ((TRiga_documento &) ((TDocumento *)this)->row(i)).provvigione(ndec); } return val; } real TDocumento::valore(bool totale, int ndec) const { real val; for (int i=rows(); i>0; i--) { TRiga_documento &r = ((TRiga_documento &) ((TDocumento *)this)->row(i)); if (r.is_merce() || r.is_spese() || r.is_prestazione()) val += r.valore(totale, ndec); } return val; } void TDocumento::put_str(const char* fieldname, const char* val) { if (strcmp(fieldname, DOC_TIPODOC) == 0) { const TString16 v(val); if (TRectype::get(DOC_TIPODOC) != v) { TAuto_variable_rectype::put_str(fieldname, v); reset_fields(*this); set_fields(*this); } else dirty_fields(); } else if (strcmp(fieldname, DOC_CODCF) == 0) { const TString16 v(val); put(DOC_SPESEUPD, TRectype::get(DOC_CODCF) == v); TAuto_variable_rectype::put_str(fieldname, v); dirty_fields(); } else { TAuto_variable_rectype::put_str(fieldname, val); dirty_fields(); if (strcmp(fieldname, DOC_SCONTOPERC) == 0) set_riga_sconto(); } } const TString& TDocumento::get_str(const char* fieldname) const { if (_dirty_deny && variable_field(fieldname) != NULL) (bool&) _dirty_deny = false; return TMultiple_rectype::get_str(fieldname); } void TDocumento::zero(const char * fieldname) { if (strcmp(fieldname, DOC_TIPODOC) == 0) reset_fields(*this); TAuto_variable_rectype::zero(fieldname); dirty_fields(); } TCli_for & TDocumento::clifor() const { const char tipo = tipocf(); const long codice = codcf(); if (_cli_for.empty() || _cli_for.tipo() != tipo || _cli_for.codice() != codice) ((TDocumento *) this)->_cli_for.read(tipo, codice); return (TCli_for &)_cli_for; } TOccasionale& TDocumento::occas() const { const TString16 occ_code = cod_occas(); // Codice occasionale in testata if (occ_code != _occas.codice()) { /* Antidiluvian mode TLocalisamfile o(LF_OCCAS); ((TDocumento *) this)->_occas.zero(); ((TDocumento *) this)->_occas.put(OCC_CFPI, occ_code); TRectype oc(_occas); if (((TDocumento *) this)->_occas.read(o) != NOERR) ((TDocumento *) this)->_occas = oc; */ // Postdiluvian mode TRectype& o = (TRectype&)_occas; // Inganna const (una volta sola, non 4) o = cache().get(LF_OCCAS, occ_code); // Ricerca tramite cache if (o.empty()) // Occasionale cancellato per errore o.put(OCC_CFPI, occ_code); // Ripristina almeno il codice } return (TOccasionale&)_occas; } const TAgente & TDocumento::agente() const { if (_agenti == NULL) _agenti = new TAgenti_cache; return _agenti->agente(get(DOC_CODAG)); } TDocumento & TDocumento::copy(const TDocumento & d) { TMultiple_rectype::operator=((TMultiple_rectype &)d); reset_fields(*this); set_fields((TAuto_variable_rectype &) d); for (int i = physical_rows(); i > 0; i--) { TRiga_documento & r = row(i); r.set_doc(this); r.set_fields(r); } set_riga_sconto(); if (is_fattura()) set_riga_esenzione(); _occas = d.occas(); return *this; } TRectype & TDocumento::operator =(const TRectype & r) { return TMultiple_rectype::operator=(r); } TRectype & TDocumento::operator =(const char * r) { return TMultiple_rectype::operator=(r); } TRecord_array& TDocumento::body(int logicnum) const { const bool reset_data_cons = loaded_rows(logicnum) == 0; if (reset_data_cons) ((TDocumento*)this)->_dirty_deny = true; TRecord_array& r = TMultiple_rectype::body(logicnum); if (reset_data_cons) { const TDate datacons(get(DOC_DATACONS)); const TString80 codcms(get(DOC_CODCMS)); const TString80 fascms(get(DOC_FASCMS)); const TString80 codcos(get(DOC_CODCOSTO)); const bool order = is_ordine(); for (int i = r.last_row(); i > 0; i = r.pred_row(i)) { TRectype& rec = r[i]; TRecfield dcons(rec, RDOC_DATACONS); if (order && datacons == dcons) dcons = ""; TRecfield ccms(rec, RDOC_CODCMS); TRecfield fcms(rec, RDOC_FASCMS); TRecfield ccos(rec, RDOC_CODCOSTO); if (codcms == ccms && fascms == fcms && codcos == ccos) { ccms = ""; fcms = ""; ccos = ""; } } ((TDocumento*)this)->_dirty_deny = false; } return r; } void TDocumento::update_raee() { const TString & r_cod = tipo().raee_cod(); const TString & r_fld = tipo().raee_fld(); if (r_cod.full() && r_fld.full() && tipo().stati_iniziali_modifica().find(stato()) >= 0) { TSpesa_prest sp(r_cod); TString4 cod_iva_cli; TLocalisamfile cfven(LF_CFVEN); cfven.put("TIPOCF", get("TIPOCF")); cfven.put("CODCF", get("CODCF")); if (cfven.read() == NOERR) cod_iva_cli = cfven.get("ASSFIS"); int nrows = physical_rows(); int i; TArticolo art; for (i = nrows; i > 0; i--) { TRiga_documento & r = row(i); if (r.tipo().tipo() == RIGA_SPESEDOC && r.is_generata() && r.get("GENTIPO") == "R") destroy_row(i, true); } nrows = physical_rows(); for (i = nrows; i > 0; i--) { TRiga_documento & r = row(i); if (r.is_articolo()) { const TString & codart = r.get(RDOC_CODARTMAG); art.read(codart); real tax = art.get_real(r_fld); if (tax != ZERO) { const TCurrency_documento val(tax, *this, true); TString16 t(sp.tipo_riga()); TRiga_documento & r1 = insert_row(i + 1, t); copy_data(r1, r); r1.set_tipo(t); r1.put(RDOC_CODART, r_cod); TString d(sp.descrizione()); if (d.full()) d << " - "; d << r1.get(RDOC_DESCR); d << r1.get(RDOC_DESCEST); r1.put(RDOC_DESCR, d.left(50)); if (d.len() > 50) { r1.put(RDOC_DESCLUNGA, "X"); r1.put(RDOC_DESCEST, d.mid(50)); } else { r1.zero(RDOC_DESCLUNGA); r1.zero(RDOC_DESCEST); } const TString & um = sp.um(); if (um.full()) r1.put(RDOC_UMQTA, um); if (cod_iva_cli.blank()) { const TString & codiva = sp.cod_iva(); if (codiva.full()) r1.put(RDOC_CODIVA, codiva); } else r1.put(RDOC_CODIVA, cod_iva_cli); tax = val.get_num(); r1.put(RDOC_PREZZO, tax); if (tipo().calcolo_lordo()) { tax = r1.iva().lordo(tax, ALL_DECIMALS); r1.put(RDOC_PREZZOL, tax); } r1.generata(); r1.put("GENTIPO", "R"); } } } } } void TDocumento::update_spese_aut(TString_array & spese_aut, bool preserve_old, TSheet_field * sh) { const bool updated = get_bool(DOC_SPESEUPD); if (updated) return; const bool interactive = sh != NULL; if (tipo().spese_aut()) { const int nrows = physical_rows(); int i; for (i = nrows; i > 0; i--) { TRiga_documento & r = row(i); bool tipo_spese = r.get("GENTIPO").empty(); if (r.tipo().tipo() == RIGA_SPESEDOC && r.is_generata() && tipo_spese) { if (preserve_old) return; destroy_row(i, TRUE); if (interactive) sh->destroy(i - 1); } } TString4 cod_iva_cli; const int nspese = spese_aut.items(); if (nspese > 0) { TString16 key; key.format("%c|%ld", get_char(DOC_TIPOCF), get_long(DOC_CODCF)); const TString4 cod_iva_cli = cache().get(LF_CFVEN, key, "ASSFIS"); TSpesa_prest sp; for (i = 0; i < nspese; i++) { const TString& s = spese_aut.row(i); if (sp.read(s) != NOERR) message_box("Codice spesa %s assente", (const char *) s); else { const TString4 tipo(sp.tipo_riga()); TRiga_documento& riga = new_row(tipo); riga.put(RDOC_CODART, s); riga.generata(); riga.put(RDOC_DESCR, sp.descrizione()); if (cod_iva_cli.blank()) riga.put(RDOC_CODIVA, sp.cod_iva()); else riga.put(RDOC_CODIVA, cod_iva_cli); switch (sp.tipo()) { case 'Q': { real qta = sp.qta(); if (qta == ZERO) qta = UNO; riga.put("QTA", qta); } // Continua perche' e' quantita' e valore case 'V': { const real cambio = get_real(DOC_CAMBIO); const TString4 valuta = get(DOC_CODVAL); const exchange_type controeuro = get_bool(DOC_CONTROEURO) ? _exchange_contro : _exchange_base; real prezzo = sp.prezzo(); sppr_calc(sp, valuta, cambio, prezzo, controeuro); if (this->tipo().calcolo_lordo()) { prezzo = riga.iva().lordo(prezzo, ALL_DECIMALS); riga.put(RDOC_PREZZOL, prezzo); } riga.put(RDOC_PREZZO, prezzo); riga.put(RDOC_UMQTA, sp.um()); } break; case 'P': default: riga.put(RDOC_QTA, sp.perc()); break; } if (cod_iva_cli.empty()) riga.put(RDOC_CODIVA, sp.cod_iva()); else riga.put(RDOC_CODIVA, cod_iva_cli); riga.put(RDOC_CODCOSTO, sp.cdc()); riga.put(RDOC_CODCMS, sp.cms()); riga.put(RDOC_FASCMS, sp.fase()); if (interactive) { const int nrow = sh->insert(-1, FALSE); riga.autoload(*sh); sh->check_row(nrow); } } } } } put(DOC_SPESEUPD, true); } real TDocumento::calc_conai_qta(int type) { real qta; for (int i = physical_rows(); i > 0; i--) { const TRiga_documento& r = row(i); if (r.is_merce()) { const real row_qta = r.calc_conai_qta(type); qta += row_qta; } } return qta; } void TDocumento::update_conai() { if (tipo().add_conai() && tipo().stati_iniziali_modifica().find(stato()) >= 0) { const TRectype& cfven = clifor().vendite(); const bool cli_add_conai = cfven.get_bool("ADDCONAI"); const char* const conai_mat[6] = { "Acciaio", "Alluminio", "Carta", "Plastica", "Legno", "Vetro" }; const char * const __conai_cf_names[] = {"ESACC", "ESALL", "ESCAR", "ESPLA", "ESLEG", "ESVET"}; const TDate datadoc = get(DOC_DATADOC); const TDate dataes = cfven.get(CFV_DATAECONAI); bool esponi_esenti = false; TString_array conai_sp(6); // Codici spesa conai { const char* const conai_cod[6] = { "CODACC", "CODALL", "CODCAR", "CODPLA", "CODLEG", "CODVET" }; TConfig c(CONFIG_DITTA, "ve"); for (int i = 0; i < 6; i++) conai_sp.add(c.get(conai_cod[i])); esponi_esenti = c.get_bool("ESPONIESENTI"); } bool updated[6] = {false,false,false,false,false,false}; const int nrows = physical_rows(); int i; for (i = nrows; i > 0; i--) { TRiga_documento& r = row(i); const bool tipo_conai = r.get_char("GENTIPO") == 'C'; // Elimina righe generate if (tipo_conai) { const TString& cod = r.get(RDOC_CODART); const int pos = conai_sp.find(cod); if (pos >= 0) { if (cli_add_conai) { real perc_esenz = cfven.get_real(__conai_cf_names[pos]); real qta = calc_conai_qta(pos); if (dataes.ok() && datadoc > dataes) perc_esenz = ZERO; const bool cli_esente = (esponi_esenti) && (perc_esenz == CENTO); if (!cli_esente) qta = qta * (CENTO - perc_esenz) / CENTO; // More precise if (qta > ZERO) { r.put(RDOC_QTA, qta); if (cli_esente) r.zero(RDOC_PREZZO); } else destroy_row(i, true); } else destroy_row(i, true); updated[pos] = true; } } } // Genera nuove righe if (cli_add_conai) { const TString4 cod_iva_cli = cfven.get(CFV_ASSFIS); TSpesa_prest sp; for (i = 0; i < 6; i++) { if (!updated[i]) { real perc_esenz = cfven.get_real(__conai_cf_names[i]); real qta = calc_conai_qta(i); const bool cli_esente = (esponi_esenti) && (perc_esenz == CENTO); if (!cli_esente) qta = qta * (CENTO - perc_esenz) / CENTO; // More precise if (qta > ZERO) { const TString & s = conai_sp.row(i); if (sp.read(s) != NOERR) message_box("Il codice spesa CONAI %s specificato nei parametri ditta e' assente: '%s'", conai_mat[i], (const char*)s); else { const TString4 tipo = sp.tipo_riga(); TRiga_documento& riga = new_row(tipo); riga.put(RDOC_CODART, s); riga.generata(); riga.put("GENTIPO", "C"); riga.put(RDOC_DESCR, sp.descrizione()); riga.put(RDOC_QTA, qta); const real cambio = get_real(DOC_CAMBIO); const TString4 valuta = get(DOC_CODVAL); const bool controeuro = get_bool(DOC_CONTROEURO); real prezzo = cli_esente ? ZERO : sp.prezzo(); sppr_calc(sp, valuta, cambio, prezzo, controeuro ? _exchange_contro : _exchange_base); if (this->tipo().calcolo_lordo()) prezzo = riga.iva().lordo(prezzo, ALL_DECIMALS); riga.put(RDOC_PREZZO, prezzo); riga.put(RDOC_UMQTA, sp.um()); if (cod_iva_cli.empty()) riga.put(RDOC_CODIVA, sp.cod_iva()); else riga.put(RDOC_CODIVA, cod_iva_cli); } } } } } } } bool TDocumento::is_evaso() const { bool ok = is_ordine() || is_bolla() || is_generic(); for (int r = 1; ok && r <= physical_rows(); r++) { const TRiga_documento& riga = physical_row(r); if (riga.is_evadibile()) ok = riga.is_evasa(); } return ok; } bool TDocumento::is_nota_credito() const { bool swap = FALSE; // Controlla prima l'esistenza del flag nota-credito sul tipo documento; // se non e' settato controlla la causale if (tipo().nota_credito()) swap = TRUE; else { const TString16 codcaus(tipo().causale()); if (codcaus.not_empty()) { TLocalisamfile caus(LF_CAUSALI); TLocalisamfile rcaus(LF_RCAUSALI); TCausale c(codcaus, data().year()); const char sez = c.sezione_clifo(); swap = ((c.reg().iva() == iva_vendite) ^ (sez == 'D')); } } return swap; } TCurrency_documento::TCurrency_documento(const real& num, const TDocumento & doc, bool price) : TCurrency(ZERO, "", ZERO, _exchange_base, price) { const TString16 val(doc.get(DOC_CODVAL)); const bool controeuro = doc.get_bool(DOC_CONTROEURO); force_value(val, doc.get_real(DOC_CAMBIO), controeuro ? _exchange_contro : _exchange_base); set_num(num); } int TDocumento::set_row_ids() { const int phrw = physical_rows(); long maxid = 0L; int first_needed = 0, r; for (r = 1; r <= phrw; r++) { const TRiga_documento& row = physical_row(r); const long id = row.get_long(RDOC_IDRIGA); if (id > maxid) maxid = id; else { if (first_needed == 0) first_needed = r; } } if (first_needed > 0) { for (r = first_needed; r <= phrw; r++) { TRiga_documento& row = (TRiga_documento&)physical_row(r); const long id = row.get_long(RDOC_IDRIGA); if (id <= 0) row.put(RDOC_IDRIGA, ++maxid); } } return phrw; } const TRiga_documento* TDocumento::get_row_id(long id) const { for (int r = physical_rows(); r > 0; r--) { const TRiga_documento& row = physical_row(r); if (row.get_long(RDOC_IDRIGA) == id) return &row; } return NULL; } int TDocumento::tipo_riclassificato() const { int tipo_riclassificato = tipo().tipo(); if (tipo_riclassificato == TTipo_documento::_altro) { const TCodice_numerazione& num = codice_numerazione(); if (num.fattura_emettere_ricevere()) tipo_riclassificato = TTipo_documento::_bolla; else tipo_riclassificato = TTipo_documento::_fattura; } return tipo_riclassificato; }