#include "velib.h" #include "vepriv.h" #ifndef __APPLICAT_H #include #endif #ifndef __TABUTIL_H #include #endif #ifndef __VERIG_H #include "verig.h" #endif #ifndef __SCONTI_H #include "sconti.h" #endif /////////////////////////////////////////////////////////// // Tipo riga di un documento /////////////////////////////////////////////////////////// TAssoc_array TTipo_riga_documento::_formule_riga; TTipo_riga_documento::TTipo_riga_documento(const char* tiporig) : TRectype(LF_TABCOM), _mask(NULL) { settab("TRI"); _name = "verig"; _name << codice(); if (tiporig && *tiporig) read(tiporig); } TTipo_riga_documento::TTipo_riga_documento(const TRectype& rec) : TRectype(rec), _mask(NULL) { _name = "verig"; _name << codice(); read_formule(); } TTipo_riga_documento::~TTipo_riga_documento() { if (_mask) delete _mask; } int TTipo_riga_documento::read(const char* tiporig) { TTable t("%TRI"); put("CODTAB", tiporig); int err = TRectype::read(t); if (err == NOERR) read_formule(); else yesnofatal_box("Tipo riga documento errato: %s", tiporig); return err; } void TTipo_riga_documento::read_formule() { TFilename prof(profile_name()); prof.ext("ini"); TConfig profile(prof); _formule = profile.get("CAMPICALC", "MAIN"); _formule.add(profile.get("CALCOLI", "MAIN")); _imponibile = profile.get("IMPONIBILE", "MAIN"); if (_imponibile.empty()) { _imponibile = "IMPONIBILE"; if (_formule.find(_imponibile) < 0) _formule.add("IMPONIBILE=PREZZO()"); } if (_imponibile.not_empty() && _formule.find(_imponibile) < 0) { error_box("Campo imponibile (%s) sconosciuto nel tipo riga %s", (const char *) _imponibile, (const char *) codice()); _imponibile.cut(0); } } TFormula_documento * TTipo_riga_documento::succ_formula(bool restart) { if (restart) _formule.restart(); const TString formula(_formule.get()); if (formula.not_empty()) { char *expr = NULL; const int p = formula.find("="); if (p > 0) { expr = (char *) (const char *) formula + p; *expr = '\0'; expr++; } TFormula_documento * o = (TFormula_documento*)_formule_riga.objptr(formula); if (o == NULL) { o = new TFormula_documento(_riga, formula, expr); _formule_riga.add(formula, o); } return o; } else return NULL; } TVariable_mask * TTipo_riga_documento::mask() { if (mask_loaded()) return _mask; _mask = new TVariable_mask(mask_name()); TFilename proname(profile_name()); proname.ext( "ini" ); TConfig pro( proname ); int numhandler = pro.get_int( "NHANDLER", "HANDLERS" ); for( int i = 1; i <= numhandler; i ++ ) { TString chiave; chiave.format( "%d", i ); TToken_string riga = pro.get( chiave, "HANDLERS" ); row_set_handler( *_mask, riga.get_int( 0 ), riga.get_int( 1 ) ); } const int pos = _mask->id2pos(FR_CODART); if (pos >= 0) { const TMask_field & f = _mask->field(FR_CODART); if (f.is_edit()) { TBrowse * browse = ((TEdit_field &) f).browse(); const char tipo_r = tipo(); if (browse ) { const TCursor * cur = browse->cursor(); if (cur) { const int num = cur->file().num(); if (num == LF_ANAMAG) { _mask->set_handler( FR_CODART, codart_handler ); _mask->set_handler( FR_LIV1, liv_handler ); _mask->set_handler( FR_LIV2, liv_handler ); _mask->set_handler( FR_LIV3, liv_handler ); _mask->set_handler( FR_UMQTA, umart_handler ); _mask->set_handler( FR_CODARTMAG, codartmag_handler ); _mask->set_handler( FR_DESCR, descr_handler ); _mask->set_handler( FR_QTA, qta_handler ); } else if (tipo_r == RIGA_SPESEDOC || tipo_r == RIGA_PRESTAZIONI) _mask->set_handler( FR_CODART, sppr_handler ); } } } } const int posiva = _mask->id2pos(FR_CODIVA); if (posiva >= 0) _mask->set_handler( FR_CODIVA, iva_handler ); return _mask; } /////////////////////////////////////////////////////////// // Riga documento per vendite /////////////////////////////////////////////////////////// TAssoc_array TRiga_documento::_tipi; TAssoc_array TRiga_documento::_spese; TAssoc_array TRiga_documento::_ive; TRiga_documento::TRiga_documento(TDocumento* doc, const char * tipo) : TAuto_variable_rectype(LF_RIGHEDOC), _doc(doc), _iva_calc(FALSE) { if (tipo) set_tipo(tipo); } TRiga_documento::TRiga_documento(const TRiga_documento& rec, TDocumento* doc, const char * tipo) : TAuto_variable_rectype(rec), _doc(doc), _iva_calc(FALSE) { if (tipo) set_tipo(tipo); } const TTipo_riga_documento& TRiga_documento::tipo() const { const TString16 tiporig(get("TIPORIGA")); CHECK(tiporig.not_empty(), "Tipo riga documento nullo"); TTipo_riga_documento* o = (TTipo_riga_documento*)_tipi.objptr(tiporig); if (o == NULL) { if (_tipi.items() == 0) { TTable tri("%TRI"); // Tabella dei tipi riga for (tri.first(); !tri.eof(); tri.next()) { const TString16 codice = tri.get("CODTAB"); _tipi.add(codice, new TTipo_riga_documento(tri.curr())); } } o = (TTipo_riga_documento*)_tipi.objptr(tiporig); if (o == NULL) { o = new TTipo_riga_documento(tiporig); _tipi.add(tiporig, o); } } return *o; } const TSpesa_prest & TRiga_documento::spesa() const { const char tipor = tipo().tipo(); CHECK(tipor == RIGA_SPESEDOC || tipor == RIGA_PRESTAZIONI, "Tipo riga incompatibile con le spese"); static long firm = -1; long new_firm = main_app().get_firm(); if (firm != new_firm) { _spese.destroy(); firm = new_firm; } const TString16 codice(get("CODART")); TString16 index; index << tipor << codice; TSpesa_prest * s = (TSpesa_prest *) _spese.objptr(index); if (s == NULL) { s = new TSpesa_prest(codice, tipor); _spese.add(index, s); } return *s; } const TIVA & TRiga_documento::iva(const char *codice) { TIVA * v = (TIVA *) _ive.objptr(codice); if (v == NULL) { v = new TIVA(codice); _ive.add(codice, v); } return *v; } bool TRiga_documento::sola_descrizione() const { char t = tipo().tipo(); if (t <= ' ' && get("QTA").empty() && get("PREZZO").empty()) t = RIGA_DESCRIZIONI; return t == RIGA_DESCRIZIONI; } void TRiga_documento::forza_sola_descrizione() { // In realta' il test serve anche a caricare la lista dei tipi riga! if (!tipo_valido() || !is_descrizione()) { _tipi.restart(); for (const TObject* o = _tipi.get(); o; o = _tipi.get()) { const TTipo_riga_documento* trd = (const TTipo_riga_documento*)o; if (trd->tipo() == RIGA_DESCRIZIONI) { put("TIPORIGA", trd->codice()); break; } } zero("QTA"); zero("PREZZO"); } } TRectype & TRiga_documento::operator =(const TRectype & r) { TRectype::operator=(r); reset_fields(*this); set_fields(*this); return *this; } TRectype & TRiga_documento::operator =(const char * r) { TRectype::operator=(r); reset_fields(*this); set_fields(*this); return *this; } // Ritorna TRUE se le due righe del documento possono essere sommate bool TRiga_documento::raggruppabile(const TRiga_documento& r, TToken_string& campi) const { bool ok = TRUE; TString campo; for (const char* c = campi.get(0); c && ok; c = campi.get()) { campo = get(c); // Separare le due get! ok &= campo == r.get(c); } return ok; } TRiga_documento& TRiga_documento::operator +=(const TRiga_documento& r) { TToken_string campi("QTA|NCOLLI|QTAEVASA"); for (const char* c = campi.get(0); c && ok; c = campi.get()) { real num(r.get_real(c)); if (!num.is_zero()) { num += get_real(c); put(c, num); } } if (!get_bool("RIGAEVASA")) { const real qta = get_real("QTA"); const real qtaeva = get_real("QTAEVASA"); if (qtaeva >= qta) put("RIGAEVASA", "X"); } return *this; } void TRiga_documento::set_fields(TAuto_variable_rectype & rec) { if (get("TIPORIGA").not_empty()) { TTipo_riga_documento & tipo_riga = (TTipo_riga_documento &) tipo(); for (const TFormula_documento * f = tipo_riga.first_formula(); f; f = tipo_riga.succ_formula()) { TExpr_documento * exp = f->expr(); add_field(new TDocumento_variable_field(f->name(), exp)); if (exp) { exp->set_doc(_doc); exp->set_row(this); } } } } real TRiga_documento::prezzo(bool scontato, bool lordo, int ndec) const { real prezzo = get_real("PREZZO"); if (scontato) prezzo = prezzo_scontato(prezzo, get("SCONTO")); prezzo.round(ndec); if (lordo) prezzo = netto2lordo(prezzo, get("CODIVA"), ndec); prezzo.round(ndec); return prezzo; } real TRiga_documento::importo(bool scontato, bool lordo, int ndec) const { real importo; TTipo_calcolo c = _nessun_calcolo; const char tipor = tipo().tipo(); const real qta = get_real("QTA"); TString16 field_perc; TCond_vendita cv; switch (tipor) { case RIGA_MERCE: c = _qtaprezzo; break; case RIGA_PRESTAZIONI: case RIGA_SPESEDOC: { const TSpesa_prest & s = spesa(); switch (s.tipo()) { case 'Q': c = _qtaprezzo; break; case 'V': c = _valore; break; case 'P': c = _percentuale; field_perc = s.field_perc(); break; default: break; } } break; case RIGA_SCONTI: cv.set_sconto(get("SCONTO")); if (cv.get_sconto().not_empty()) c = _scontoperc; else c = _scontoimp; break; case RIGA_OMAGGI: if (_iva_calc && get_bool("ADDIVA")) c = _qtaprezzo; default: break; } switch (c) { case _qtaprezzo: importo = prezzo(scontato, lordo, ndec) * qta; break; case _valore: importo = prezzo(scontato, lordo, ndec); break; case _percentuale: importo = doc().get_real(field_perc) * get_real("PSPESA") / 100; break; case _scontoimp: importo = -prezzo(FALSE, lordo, ndec); break; case _scontoperc: importo = doc().basesconto() * (cv.sconto_val() - 1.0); break; default: break; } importo.round(ndec); return importo; } real TRiga_documento::iva(int ndec) const { ((TRiga_documento *) this)->_iva_calc = TRUE; real iva(::iva(imponibile(), iva(), ndec)); ((TRiga_documento *) this)->_iva_calc = FALSE; return iva; } real TRiga_documento::imponibile() const { const TString16 field(tipo().imponibile()); if (field.not_empty()) { if (is_omaggio() && _iva_calc) { TDocumento_variable_field * f = (TDocumento_variable_field *) variable_field(field); CHECKS(f, "Field UNKNOWN : ", field); f->set_dirty(TRUE); const real r = get_real(field); f->set_dirty(TRUE); return r; } else return get_real(field); } else return importo(TRUE, FALSE, doc().in_valuta() ? 3 : 0); } real TRiga_documento::imposta(bool round) const { return iva(round ? (doc().in_valuta() ? 3 : 0) : 20); } void TRiga_documento::dirty_fields(bool dirty_document) { for (TDocumento_variable_field * f = (TDocumento_variable_field *) first_variable_field(); f != NULL; f = (TDocumento_variable_field *) succ_variable_field()) f->set_dirty(); if (dirty_document) ((TDocumento &)doc()).dirty_fields(); } bool TRiga_documento::doc_dependent() const { if (tipo_valido()) { const char tipor = tipo().tipo(); if (tipor == RIGA_SPESEDOC) return spesa().tipo() == 'P'; else if (tipor == RIGA_SCONTI) return get("SCONTO").not_empty(); } return FALSE; } void TRiga_documento::put_str(const char* fieldname, const char* val) { TString v(val); if (strcmp(fieldname, "TIPORIGA") == 0 && TRectype::get("TIPORIGA") != v) { TAuto_variable_rectype::put_str(fieldname, v); reset_fields(*this); set_fields(*this); } else { TAuto_variable_rectype::put_str(fieldname, v); dirty_fields(); } } bool TRiga_documento::is_articolo() const { const char t = tipo().tipo(); return (t == RIGA_MERCE || t == RIGA_OMAGGI) && get("CODARTMAG").not_empty(); } void TRiga_documento::zero(const char * fieldname) { if (strcmp(fieldname, "TIPORIGA") == 0) reset_fields(*this); TAuto_variable_rectype::zero(fieldname); dirty_fields(); } void TRiga_documento::zero(char c) { reset_fields(*this); TAuto_variable_rectype::zero(c); } void TRiga_documento::autosave(TSheet_field & f) { const int num = numero() - 1; if (num >= 0 && num < f.items()) { TToken_string & row = f.row(num); put( "STATORIGA", row.get( f.cid2index(FR_STATORIGA) ) ); put( "TIPORIGA", row.get( f.cid2index(FR_TIPORIGA )) ); TString16 codmag(row.get(f.cid2index(FR_CODMAG))); codmag.left_just(3); codmag << row.get( f.cid2index(FR_CODDEP )); put( "CODMAG", codmag); put( "CODART", row.get( f.cid2index(FR_CODART )) ); TString liv(row.get(f.cid2index(FR_LIV1))); liv << row.get(f.cid2index(FR_LIV2)); liv << row.get(f.cid2index(FR_LIV3)); liv << row.get(f.cid2index(FR_LIV4)); put( "LIVELLO", liv); // da modificare TString s(row.get(f.cid2index(FR_DESCR))); int split_pos = s.find('\n'); const int descr_len = length("DESCR"); if (split_pos < 0 && s.len() > descr_len) split_pos = descr_len; if (split_pos > 0) { put( "DESCR", s.left(split_pos)); put("DESCLUNGA", "X"); put("DESCEST", s.mid(split_pos)); } else { put("DESCR", s); put("DESCLUNGA", ""); zero("DESCEST"); } put( "PREZZO", row.get( f.cid2index(FR_PREZZO )) ); put( "UMQTA", row.get( f.cid2index(FR_UMQTA )) ); TMask * m = ((TTipo_riga_documento &)tipo()).mask(); const int pos = m->id2pos(FR_QTA); if (pos >= 0 && m->fld(pos).field()->name() == "PSPESA") put( "PSPESA", row.get( f.cid2index(FR_QTA )) ); else put( "QTA", row.get( f.cid2index(FR_QTA )) ); put( "QTAEVASA", row.get( f.cid2index(FR_QTAEVASA )) ); put( "RIGAEVASA", row.get( f.cid2index(FR_RIGAEVASA )) ); put( "TARA", row.get( f.cid2index(FR_TARA )) ); put( "PNETTO", row.get( f.cid2index(FR_PNETTO )) ); put( "NCOLLI", row.get( f.cid2index(FR_NCOLLI )) ); put( "DAEVADERE", row.get( f.cid2index(FR_DAEVADERE )) ); put( "SCONTO", row.get( f.cid2index(FR_SCONTO )) ); put( "PERCPROV", row.get( f.cid2index(FR_PERCPROV )) ); put( "IMPFISSO", row.get( f.cid2index(FR_IMPFISSO )) ); put( "CODIVA", row.get( f.cid2index(FR_CODIVA )) ); put( "ADDIVA", row.get( f.cid2index(FR_ADDIVA )) ); put( "ASPBENI", row.get( f.cid2index(FR_ASPBENI )) ); put( "CAUSMAG", row.get( f.cid2index(FR_CAUS )) ); TString16 codmagc(row.get(f.cid2index(FR_CODMAGC))); codmagc.left_just(3); codmagc << row.get( f.cid2index(FR_CODDEPC )); put( "CODMAGC", codmagc); put( "CODARTMAG", row.get( f.cid2index(FR_CODARTMAG )) ); put( "CHECKED", row.get( f.cid2index(FR_CHECKED )) ); } } void TRiga_documento::autoload(TSheet_field & f) { const int num = numero() - 1; TToken_string & row = f.row(num); row.cut(0); row.add( get( "STATORIGA" ), f.cid2index(FR_STATORIGA )); row.add( get( "TIPORIGA" ), f.cid2index(FR_TIPORIGA )); const TString codmag(get("CODMAG")); row.add( codmag.left(3), f.cid2index(FR_CODMAG )); row.add( codmag.mid(3), f.cid2index(FR_CODDEP )); row.add( get( "CODART" ), f.cid2index(FR_CODART )); TString liv(get("LIVELLO")); int l = doc().liv_giac_len(1); if (l > 0) { row.add(liv.left(l), f.cid2index(FR_LIV1 )); liv.ltrim(l); } l = doc().liv_giac_len(2); if (l > 0) { row.add(liv.left(l), f.cid2index(FR_LIV2 )); liv.ltrim(l); } l = doc().liv_giac_len(3); if (l > 0) { row.add(liv.left(l), f.cid2index(FR_LIV3 )); liv.ltrim(l); } l = doc().liv_giac_len(4); if (l > 0) { row.add(liv.left(l), f.cid2index(FR_LIV4 )); liv.ltrim(l); } TString s(get("DESCR")); if (get_bool("DESCLUNGA")) s << get("DESCEST"); row.add(s, f.cid2index(FR_DESCR )); row.add( get( "UMQTA" ), f.cid2index(FR_UMQTA )); row.add( get( "PREZZO" ), f.cid2index(FR_PREZZO )); TMask * m = ((TTipo_riga_documento &)tipo()).mask(); const int pos = m->id2pos(FR_QTA); if (pos >= 0 && m->fld(pos).field()->name() == "PSPESA") row.add( get( "PSPESA" ), f.cid2index(FR_QTA )); else row.add( get( "QTA" ), f.cid2index(FR_QTA )); row.add( get( "QTAEVASA" ), f.cid2index(FR_QTAEVASA )); row.add( get( "RIGAEVASA" ), f.cid2index(FR_RIGAEVASA )); row.add( get( "TARA" ), f.cid2index(FR_TARA )); row.add( get( "PNETTO" ), f.cid2index(FR_PNETTO )); row.add( get( "NCOLLI" ), f.cid2index(FR_NCOLLI )); row.add( get( "DAEVADERE" ), f.cid2index(FR_DAEVADERE )); row.add( get( "SCONTO" ), f.cid2index(FR_SCONTO )); row.add( get( "PERCPROV" ), f.cid2index(FR_PERCPROV )); row.add( get( "IMPFISSO" ), f.cid2index(FR_IMPFISSO )); row.add( get( "CODIVA" ), f.cid2index(FR_CODIVA )); row.add( get( "ADDIVA" ), f.cid2index(FR_ADDIVA )); row.add( get( "ASPBENI" ), f.cid2index(FR_ASPBENI )); row.add( get( "CAUSMAG" ), f.cid2index(FR_CAUS )); const TString codmagc(get("CODMAGC")); row.add( codmagc.left(3), f.cid2index(FR_CODMAGC )); row.add( codmagc.mid(3), f.cid2index(FR_CODDEPC )); row.add( get( "CODARTMAG" ), f.cid2index(FR_CODARTMAG)); row.add( get( "CHECKED" ), f.cid2index(FR_CHECKED)); }