#include "sconti.h" #include "vepriv.h" #include "../ca/commesse.h" #include #include /////////////////////////////////////////////////////////// // Tipo riga di un documento /////////////////////////////////////////////////////////// TAssoc_array TTipo_riga_documento::_formule_riga; TTipo_riga_documento::TTipo_riga_documento(const char* tiporig) : TRectype(LF_TABCOM) { settab("TRI"); if (tiporig && *tiporig) read(tiporig); } TTipo_riga_documento::TTipo_riga_documento(const TRectype& rec) : TRectype(rec) { read_formule(); } int TTipo_riga_documento::read(const char* tiporig) { *this = cache().get("%TRI", tiporig); if (empty()) yesnofatal_box("Tipo riga documento errato: %s", tiporig); else read_formule(); return NOERR; } void TTipo_riga_documento::add_formula_if_needed(TConfig& profile, TString& variable, const char* varname, const char* formula) { variable = profile.get(varname, "MAIN"); if (variable.empty()) variable = varname; const TRectype& frr = cache().get("%FRR", variable); if (frr.empty()) _formule_riga.add(variable, new TFormula_documento(_riga, variable, formula), TRUE); if (_formule.find(variable) < 0) _formule.add(variable); } const TString& TTipo_riga_documento::mask_name(TString& name) const { name = "verig"; name << codice(); return name; } const TFilename& TTipo_riga_documento::profile_name(TFilename& name) const { mask_name(name); name.ext(".ini"); name.custom_path(); return name; } void TTipo_riga_documento::read_formule() { TFilename prof; profile_name(prof); TConfig profile(prof, "MAIN"); _search_nums = profile.get("SEARCHNUMS"); _search_years = profile.get_int("SEARCHYEARS"); _max_rows_art = profile.get_int("MAXROWSART"); _search_active_docs = profile.get("SEARCHACTDOCS"); _fields_to_update = profile.get("FIELDSTOUPDATE"); _field_list = profile.get("FIELDLIST"); _header = profile.get("HEADER"); _order = profile.get("ORDER"); _select_clifo = profile.get_bool("SELCLIFO", NULL, -1, true); _no_desc = profile.get_bool("NODESC"); _formule = profile.get("CAMPICALC"); _extended_desc_search = ini_get_bool(CONFIG_DITTA, "Main", "CUSTOM_SEARCH_" TOSTRING(LF_ANAMAG), false, 2); const TString& calcoli = profile.get("CALCOLI"); if (calcoli == "*") { TISAM_recordset frr("USE %FRR"); for (bool ok = frr.move_first(); ok; ok = frr.move_next()) { const TString& formula = frr.get("CODTAB").as_string(); if (_formule.find(formula) < 0) _formule.add(formula); } } else _formule.add(calcoli); _field_provv = profile.get("PROVV"); _field_provv1 = profile.get("PROVV1"); _field_qta = profile.get("QTA"); // Non dare un default: ingannerebbe il tipo documento _field_qtaevasa = profile.get("QTAEVASA"); // Non dare un default: ingannerebbe il tipo documento _field_qta_mag = profile.get("QTA_MAG"); if(_field_qta_mag.blank()) _field_qta_mag = _field_qta; _field_qtaevasa_mag = profile.get("QTAEVASA_MAG"); if(_field_qtaevasa_mag.blank()) _field_qtaevasa_mag = _field_qtaevasa; _field_imposta = profile.get("IMPOSTA"); _incrp = profile.get_int("VARP+"); _decrp = profile.get_int("VARP-"); for (int i = 0; i < 4; i++) { const TToken_string str(profile.get("LIVGEN", NULL, i)); if (str.full()) _genconf.add(str, i); } add_formula_if_needed(profile, _imponibile, "IMPONIBILE", "IMPORTO(1)"); add_formula_if_needed(profile, _quant, "QUANT", "QUANT()"); add_formula_if_needed(profile, _quantevasa, "QUANTEVASA", "QUANTEVASA()"); add_formula_if_needed(profile, _qtares, "QTARES", "QTARES()"); } 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; } /////////////////////////////////////////////////////////// // Riga documento per vendite /////////////////////////////////////////////////////////// long TRiga_documento::_firm = -1; TAssoc_array TRiga_documento::_tipi; TAssoc_array TRiga_documento::_spese; TAssoc_array TRiga_documento::_ive; // 0=ignora IVA; 1=consedera iva solo se c'e' addebito; 2=considera sempre IVA int TRiga_documento::_iva_calc_mode = 0; bool TRiga_documento::_rit_calc = false; TRiga_documento::TRiga_documento(TDocumento* doc, const char * tipo) : TAuto_variable_rectype(LF_RIGHEDOC), _doc(doc) { set_memo_fld("RG1"); if (tipo) set_tipo(tipo); } TRiga_documento::TRiga_documento(const TRiga_documento & row) : TAuto_variable_rectype(LF_RIGHEDOC), _doc(NULL) { set_memo_fld("RG1"); copy(row); } /* Maialata inguardabile: guai a chi la riporta! TRiga_documento::TRiga_documento(const TRiga_documento& rec, TDocumento* doc, const char * tipo) : TAuto_variable_rectype(rec), _doc(doc) { set_memo_fld("RG1"); if (tipo) set_tipo(tipo); }*/ const TTipo_riga_documento& TRiga_documento::tipo(const char * tiporiga) { CHECK(tiporiga && *tiporiga, "Tipo riga documento nullo"); TTipo_riga_documento* o = (TTipo_riga_documento*)_tipi.objptr(tiporiga); if (o == NULL) { if (_tipi.items() == 0) { TISAM_recordset tri("USE %TRI"); for (bool ok = tri.move_first(); ok; ok = tri.move_next()) { const TString& codice = tri.get("CODTAB").as_string(); if (codice.full() && codice.len() <= 2) _tipi.add(codice, new TTipo_riga_documento(tri.cursor()->curr())); } } o = (TTipo_riga_documento*)_tipi.objptr(tiporiga); if (o == NULL) { o = new TTipo_riga_documento(tiporiga); _tipi.add(tiporiga, o); } } return *o; } const TTipo_riga_documento& TRiga_documento::tipo() const { const TString4 tiporiga = get(RDOC_TIPORIGA); CHECK(tiporiga.full(), "Tipo riga documento nullo"); return TRiga_documento::tipo(tiporiga); } const TSpesa_prest & TRiga_documento::spesa() const { const char tipor = tipo().tipo(); CHECK(tipor == RIGA_SPESEDOC || tipor == RIGA_PRESTAZIONI || tipor == RIGA_RISORSE || tipor == RIGA_ATTREZZATURE, "Tipo riga incompatibile con le spese"); test_firm(); const TString80 codice(get(RDOC_CODART)); TString80 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 TCodiceIVA & TRiga_documento::iva(const char *codice) { TCodiceIVA * v = (TCodiceIVA *)_ive.objptr(codice); if (v == NULL) { v = new TCodiceIVA(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()) { TString4 cod; _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) { const TString& c = trd->codice(); if (cod.empty() || c < cod) cod = c; } } put(RDOC_TIPORIGA, cod); zero(RDOC_QTA); zero(RDOC_PREZZO); } } TRiga_documento & TRiga_documento::copy(const TRiga_documento& r) { if (_doc == NULL) _doc = r._doc; TAuto_variable_rectype::operator=(r); reset_fields(*this); set_fields((TAuto_variable_rectype&)r); return *this; } void TRiga_documento::set_variables(TExpression * e) const { const int items = e->numvar(); for (int i = 0; i < items; i++) { const TFieldref field(e->varname(i), LF_RIGHEDOC); switch (field.file()) { case LF_ANAMAG : e->setvar(i, articolo().get(field.name())); break; case LF_DOC : e->setvar(i, doc().get(field.name())); break; case LF_CLIFO : e->setvar(i, doc().clifor().get(field.name())); break; case LF_CFVEN : e->setvar(i, doc().clifor().vendite().get(field.name())); break; default: e->setvar(i, get(field.name())); break; } } } void TRiga_documento::test_firm() { const long new_firm = prefix().get_codditta(); if (_firm != new_firm) { _spese.destroy(); _firm = new_firm; } } TRectype & TRiga_documento::operator =(const TRectype & r) { TAuto_variable_rectype::operator=(r); reset_fields(*this); set_fields(*this); return *this; } TRectype & TRiga_documento::operator =(const char * r) { TAuto_variable_rectype::operator=(r); reset_fields(*this); set_fields(*this); return *this; } bool TRiga_documento::cost2revenue() { bool done = false; if (is_attrezzatura() || is_risorsa()) { const TSpesa_prest& s = spesa(); const TString80 codice(s.revenue()); done = codice.full(); if (done) { TString4 tipo = s.tipo(); if (tipo.blank()) tipo = "06"; put(RDOC_TIPORIGA, tipo); put(RDOC_CODART, codice); zero(RDOC_CODARTMAG); put(RDOC_CHECKED, true); put(RDOC_DESCR, s.descrizione()); put(RDOC_UMQTA, s.um()); put(RDOC_PREZZO, s.prezzo()); if (get(RDOC_CODIVA).blank()) put(RDOC_CODIVA, s.cod_iva()); } } return done; } // Ritorna TRUE se le due righe del documento possono essere sommate bool TRiga_documento::raggruppabile(const TRiga_documento& r, TToken_string& campi) const { // Controlla che i nomi dei campi quantita' siano coerenti bool ok = (tipo().codice() == r.tipo().codice()) || (field_qta() == r.field_qta() && field_qtaevasa() == r.field_qtaevasa()); if (ok) { TString campo1, campo2; FOR_EACH_TOKEN(campi, c) { campo1 = get(c); if (campo1.empty() && doc().exist(c)) // Succede con COMMESSA, FASE, CODCOSTO campo1 = doc().get(c); campo2 = r.get(c); if (campo2.empty() && r.doc().exist(c)) // Succede con COMMESSA, FASE, CODCOSTO campo2 = r.doc().get(c); ok = campo1 == campo2; if (!ok) break; } } return ok; } TRiga_documento& TRiga_documento::operator +=(const TRiga_documento& r) { // New age mode const char* const campi[5] = { RDOC_NCOLLI, RDOC_TARA, RDOC_PNETTO, field_qta(), field_qtaevasa() }; for (int i = 0; i < 5; i++) add(campi[i], r.get_real(campi[i])); if (!get_bool(RDOC_RIGAEVASA)) { if (qtaresidua().is_zero()) // same as is_evasa() put(RDOC_RIGAEVASA, "X"); } return *this; } void TRiga_documento::set_fields(TAuto_variable_rectype & rec) { if (get(RDOC_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(); if (exp) { exp->set_doc(_doc); exp->set_row(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 (src_field->expression() == NULL) put(fieldname, rec.get(fieldname)); } } } real TRiga_documento::prezzo(bool scontato, bool lordo, int ndec) const { real prezzo; if (ndec == AUTO_DECIMALS) ndec = doc().decimals(TRUE); if (doc().tipo().calcolo_lordo()) { prezzo = get_real(RDOC_PREZZOL); if (prezzo.is_zero()) { prezzo = get_real(RDOC_PREZZO); if (scontato) prezzo = prezzo_scontato(prezzo, get(RDOC_SCONTO)); if (lordo) prezzo = iva().lordo(prezzo, ndec); } else { if (scontato) prezzo = prezzo_scontato(prezzo, get(RDOC_SCONTO)); if (!lordo) iva().scorpora(prezzo, ndec); } } else { prezzo = get_real(RDOC_PREZZO); if (scontato) prezzo = prezzo_scontato(prezzo, get(RDOC_SCONTO)); if (lordo) prezzo = iva().lordo(prezzo, ndec); } prezzo.round(ndec); return prezzo; } real TRiga_documento::importo(bool scontato, bool lordo, int ndec) const { if (ndec == AUTO_DECIMALS) ndec = doc().decimals(); real importo; bool doc_al_lordo = doc().tipo().calcolo_lordo(); TTipo_calcolo c = _nessun_calcolo; const char tipor = tipo().tipo(); const real qta = get_real(RDOC_QTA); real valore, perc; switch (tipor) { case RIGA_MERCE: case RIGA_RISORSE: case RIGA_ATTREZZATURE: c = _qtaprezzo; break; case RIGA_PRESTAZIONI: case RIGA_SPESEDOC: { const TSpesa_prest & s = spesa(); const bool to_calc = _rit_calc || s.tipo_ritenuta() == '\0'; if (to_calc) { switch (s.tipo()) { case 'Q': c = _qtaprezzo; break; case 'P': { const TString16 field_perc(s.field_perc()); c = _percentuale; valore = doc().get_real(field_perc); if (doc_al_lordo) valore = iva().lordo(valore, ALL_DECIMALS, doc().valuta()); } break; case 'V': default: c = _valore; break; } } } break; case RIGA_SCONTI: c = _scontopi; break; case RIGA_OMAGGI: if (_iva_calc_mode > 1 || (_iva_calc_mode == 1 && get_bool("ADDIVA"))) c = _qtaprezzo; default: break; } switch (c) { case _qtaprezzo: importo = prezzo(scontato, lordo, ALL_DECIMALS) * qta; break; case _valore: importo = prezzo(scontato, lordo, ndec); break; case _percentuale: importo = valore * qta / CENTO; break; case _scontopi: { TCond_vendita cv(NULL, NULL); cv.set_sconto(get("SCONTO")); if (cv.get_sconto().full()) { importo = doc().basesconto(); importo *= (cv.sconto_val() - UNO); doc_al_lordo = false; } else importo = -prezzo(false, lordo, ALL_DECIMALS); TGeneric_distrib d(importo, ALL_DECIMALS); TRiepilogo_iva * aliquota; if (doc_al_lordo) { if (!lordo) { TAssoc_array & table = ((TDocumento &) doc()).tabella_iva(true); importo = ZERO; table.restart(); for (aliquota = (TRiepilogo_iva *) table.get(); aliquota != NULL; aliquota = (TRiepilogo_iva *) table.get()) d.add(aliquota->imp_orig()); table.restart(); for (aliquota = (TRiepilogo_iva *) table.get(); aliquota != NULL; aliquota = (TRiepilogo_iva *) table.get()) { const TCodiceIVA & iva = aliquota->cod_iva(); real slice = d.get(); iva.scorpora(slice, ALL_DECIMALS, ((TDocumento &) doc()).valuta()); importo += slice; } } } else { if (lordo) { TAssoc_array & table = ((TDocumento &) doc()).tabella_iva(true); importo = ZERO; table.restart(); for (aliquota = (TRiepilogo_iva *) table.get(); aliquota != NULL; aliquota = (TRiepilogo_iva *) table.get()) d.add(aliquota->imp_orig()); table.restart(); for (aliquota = (TRiepilogo_iva *) table.get(); aliquota != NULL; aliquota = (TRiepilogo_iva *) table.get()) { const TCodiceIVA & iva = aliquota->cod_iva(); importo += iva.lordo(d.get(), ALL_DECIMALS, ((TDocumento &) doc()).valuta()); } } } } break; default: break; } importo.round(ndec); // arrotondamento finale return importo; } real TRiga_documento::iva(int ndec) const { real zanicchi; if (!is_sconto()) { if (is_omaggio()) zanicchi = iva_omaggio(ndec); else { if (ndec == AUTO_DECIMALS) ndec = doc().decimals(); const TString& field = tipo().imposta(); if (field.not_empty()) { zanicchi = get_real(field); zanicchi.round(ndec); } else { zanicchi = iva().imposta(imponibile(), ndec); } } } return zanicchi; } real TRiga_documento::iva_omaggio(int ndec, int tipo_iva_calc) const { if (ndec == AUTO_DECIMALS) ndec = doc().decimals(); const real zanicchi = iva().imposta(imponibile_omaggio(tipo_iva_calc), ndec); return zanicchi; } real TRiga_documento::imponibile_omaggio(int tipo_iva_calc) const { _iva_calc_mode = tipo_iva_calc; const real imp = imponibile(); _iva_calc_mode = 0; return imp; } real TRiga_documento::imponibile(bool lordo) const { const TString& field = tipo().imponibile(); if (field.full()) { real r; if (is_omaggio() && _iva_calc_mode > 0) { TDocumento_variable_field * f = (TDocumento_variable_field *) variable_field(field); CHECKS(f, "Field UNKNOWN : ", (const char *) field); f->set_dirty(TRUE); r = get_real(field); f->set_dirty(TRUE); } else r = get_real(field); if (lordo) { if (doc().tipo().calcolo_lordo()) r = importo(true, lordo, doc().decimals()); else r = iva().lordo(r, doc().decimals(TRUE)); } return r; } return importo(true, lordo, doc().decimals()); } real TRiga_documento::imposta(bool round) const { return iva(round ? doc().decimals() : 20); } real TRiga_documento::provvigione(bool first, int ndec) const { real val; if (ndec == AUTO_DECIMALS) ndec = doc().decimals(); const TString & field = first ? tipo().provv() : tipo().provv1(); if (field.not_empty()) val = get_real(field); else { const char tipo_riga = tipo().tipo(); val = importo(TRUE, FALSE, ndec); if (tipo_riga == RIGA_MERCE || tipo_riga == RIGA_SPESEDOC || tipo_riga == RIGA_PRESTAZIONI) { real netto_testa; TString80 s; if (scontoexpr2perc(doc().get(DOC_SCONTOPERC), FALSE, s, netto_testa) && netto_testa != ZERO) val *= netto_testa; } val *= get_real(first ? RDOC_PERCPROV : RDOC_PERCPROV1) / CENTO; } val.round(ndec); return val; } real TRiga_documento::ritenuta(const char tipor, bool lordo, int ndec) const { real val; if (tipo().tipo() == RIGA_SPESEDOC) { const char tipo_rit = spesa().tipo_ritenuta(); if ((tipor != '\0' && tipo_rit == tipor) || (tipor == '\0' && tipo_rit != '\0')) { _rit_calc = true; val = importo(true, lordo, ndec); _rit_calc = false; } } return val; } const TString& TRiga_documento::field_qta() const { const TString& rowtype_field = tipo().field_qta(); if (rowtype_field.not_empty()) return rowtype_field; const TString& doctype_field = doc().tipo().field_qta(); return doctype_field; } const TString& TRiga_documento::field_qtaevasa() const { const TString& rowtype_field = tipo().field_qtaevasa(); if (rowtype_field.not_empty()) return rowtype_field; const TString& doctype_field = doc().tipo().field_qtaevasa(); return doctype_field; } real TRiga_documento::quantita() const { return get_real(field_qta()); } real TRiga_documento::qtaevasa() const { return get_real(field_qtaevasa()); } real TRiga_documento::qtaresidua() const { if (!get_bool(RDOC_RIGAEVASA)) { const real val = quantita() - qtaevasa(); if (val > ZERO) return val; } return ZERO; } const TString& TRiga_documento::field_qta_mag() const { const TString& rowtype_field = tipo().field_qta_mag(); if (rowtype_field.not_empty()) return rowtype_field; const TString& doctype_field = doc().tipo().field_qta_mag(); return doctype_field; } const TString& TRiga_documento::field_qtaevasa_mag() const { const TString& rowtype_field = tipo().field_qtaevasa_mag(); if (rowtype_field.not_empty()) return rowtype_field; const TString& doctype_field = doc().tipo().field_qtaevasa_mag(); return doctype_field; } real TRiga_documento::quantita_mag() const { return get_real(field_qta_mag()); } real TRiga_documento::qtaevasa_mag() const { return get_real(field_qtaevasa_mag()); } real TRiga_documento::qtaresidua_mag() const { if (!get_bool(RDOC_RIGAEVASA)) { real val = quantita_mag() - qtaevasa_mag(); if (val > ZERO) return val; } return ZERO; } // Converte un codice categoria o sottocategoria (avente la categoria come prefisso) // nell'identificatore interno della classe CONAI nel range [0,5] TCONAI_class conai_str2class(const char* code) { TCONAI_class ct = CONAI_NONE; if (code && *code) { switch(code[0]) { case 'A': ct = code[1] == 'C' ? CONAI_ACC : CONAI_ALL; break; case 'C': ct = CONAI_CAR; break; case 'L': ct = CONAI_LEG; break; case 'P': ct = CONAI_PLA; break; case 'V': ct = CONAI_VET; break; default: break; } } return ct; } const char* conai_material(TCONAI_class cc) { CHECK_CONAI(cc); const char* const mat[CONAI_CLASSES] = { "Acciaio", "Alluminio", "Carta", "Plastica", "Legno", "Vetro" }; return cc >= CONAI_FIRST && cc < CONAI_CLASSES ? mat[cc] : ""; } // Controlla attivazione di una categoria CONAI bool conai_configured_class(TCONAI_class cc) { CHECK_CONAI(cc); static bool* __con_conf = NULL; if (__con_conf == NULL) { __con_conf = new bool[CONAI_CLASSES]; const char* const __conai_suffixes[CONAI_CLASSES] = { "ACC", "ALL", "CAR", "PLA", "LEG", "VET" }; TConfig c(CONFIG_DITTA, "ve"); TString8 name_conf, name_cods; FOR_EACH_CONAI_CLASS(i) { name_conf.cut(0) << "CONF" << __conai_suffixes[i]; bool yes = c.get_bool(name_conf); if (!yes) { name_cods.cut(0) << "COD" << __conai_suffixes[i]; yes = c.get(name_cods).full(); if (yes) c.set(name_conf, yes); } __con_conf[i] = yes; } } return cc>=CONAI_FIRST && cc<=CONAI_LAST && __con_conf[cc]; } // Campi virtuali per peso CONAI su RDOC e ANAMAG in Kg const char* conai_peso_name(TCONAI_class type, int logicnum) { if (conai_configured_class(type)) // Garantisce anche che type < CONAI_CLASSES { const char* const __conai_peso_rdoc[CONAI_CLASSES] = { "CONPUACC", "CONPUALL", "CONPUCAR", "CONPUPLA", "CONPULEG", "CONPUVET" }; const char* const __conai_peso_anmg[CONAI_CLASSES] = {ANAMAG_CONACC, ANAMAG_CONALL, ANAMAG_CONCAR, ANAMAG_CONPLA, ANAMAG_CONLEG, ANAMAG_CONVET}; switch (logicnum) { case LF_ANAMAG : return __conai_peso_anmg[type]; case LF_RIGHEDOC: return __conai_peso_rdoc[type]; default : break; } } return ""; } // Campi virtuali per sottocategoria CONAI su RDOC e ANAMAG const char* conai_sottocat_name(TCONAI_class type, int logicnum) { if (conai_configured_class(type)) // Garantisce anche che type < CONAI_CLASSES { const char* const __conai_scat_rdoc[CONAI_CLASSES] = { "CONSCACC", "CONSCALL", "CONSCCAR", "CONSCPLA", "CONSCLEG", "CONSCVET" }; const char* const __conai_scat_anmg[CONAI_CLASSES] = { ANAMAG_CONAISC"[1,4]", ANAMAG_CONAISC"[5,8]", ANAMAG_CONAISC"[9,12]", ANAMAG_CONAISC"[13,16]", ANAMAG_CONAISC"[17,20]", ANAMAG_CONAISC"[21,24]" }; switch (logicnum) { case LF_ANAMAG : return __conai_scat_anmg[type]; case LF_RIGHEDOC: return __conai_scat_rdoc[type]; default : break; } } return ""; } const char* conai_esenzione_name(TCONAI_class cc, int logicnum) { if (conai_configured_class(cc)) // Garantisce anche che type < CONAI_CLASSES { const char* const __conai_ese_cfven[CONAI_CLASSES] = { CFV_ESACC, CFV_ESALL, CFV_ESCAR, CFV_ESPLA, CFV_ESLEG, CFV_ESVET }; switch (logicnum) { case LF_RIGHEDOC: case LF_CFVEN : return __conai_ese_cfven[cc]; default : break; } } return ""; } // Calcola il peso in Kg di una componente (carta, palstica, ecc.) dell'imballo della riga corrente real TRiga_documento::calc_conai_qta(TCONAI_class type) const { real kg; if (is_merce() || is_omaggio()) { const char* weight_name = conai_peso_name(type, LF_RIGHEDOC); if (weight_name && *weight_name) // Se la categoria conai e' gestita { const real peso = get_real(weight_name); // Peso unitario imballo real qta = quantita(); // Quantita' merce if (peso > ZERO && !qta.is_zero()) // Verifica se ha un peso valido { const TString4 um = get(RDOC_UMQTA); TArticolo& art = articolo(); qta = art.convert_to_um(qta, NULL, um); // Converte la quantita nell'unita' base kg = qta * peso; // Calcola peso dell'imballo kg.round(5); /* TString s = kg.string(); s.trim(); */ } } } return kg; } bool TRiga_documento::is_evasa() const { return qtaresidua().is_zero(); } real TRiga_documento::valore(bool totale, bool lordo, int ndec) const { real val; const TString& f_qta = field_qta(); const bool qta_is_price = f_qta == RDOC_PREZZO; if (totale) { val = get_real(qta_is_price ? RDOC_QTA : f_qta); val *= prezzo(true, lordo, ALL_DECIMALS); } else { val = qtaresidua(); if (!qta_is_price) val *= prezzo(true, lordo, ALL_DECIMALS); } if (ndec == AUTO_DECIMALS) ndec = doc().decimals(); val.round(ndec); return val; } const TString & TRiga_documento::codice_costo() const { const TString& cod_cos = get(RDOC_CODCOSTO); return cod_cos.empty() ? doc().get(DOC_CODCOSTO) : cod_cos; } const TString & TRiga_documento::codice_commessa() const { const TString& cod_cms = get(RDOC_CODCMS); return cod_cms.empty() ? doc().get(DOC_CODCMS) : cod_cms; } const TString & TRiga_documento::fase_commessa() const { const TString & fas_cms = get(RDOC_FASCMS); return fas_cms.empty() ? doc().get(DOC_FASCMS) : fas_cms; } 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(RDOC_SCONTO).not_empty(); } return FALSE; } void TRiga_documento::put_str(const char* fieldname, const char* val) { if (strcmp(fieldname, RDOC_TIPORIGA) == 0) { const TString4 v(val); if (TRectype::get(RDOC_TIPORIGA) != v) { TAuto_variable_rectype::put_str(fieldname, v); reset_fields(*this); set_fields(*this); } else dirty_fields(); } else { TAuto_variable_rectype::put_str(fieldname, val); dirty_fields(); } } bool TRiga_documento::is_articolo() const { const char t = tipo().tipo(); return (t == RIGA_MERCE || t == RIGA_OMAGGI) && get(RDOC_CODARTMAG).full(); } void TRiga_documento::zero(const char * fieldname) { if (strcmp(fieldname, RDOC_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::cms2tipodet() { if (doc().modificabile()) { TString4 cms_tipodet; const TString4 tipodet = get(RDOC_TIPODET); TString codcms = codice_commessa(); if (codcms.full() && get(RDOC_CODIVA).full()) { const TRectype& rec_cms = cache().get(LF_COMMESSE, codcms); const TString& regiva = rec_cms.get(COMMESSE_REGIVA); if (regiva.full()) cms_tipodet = (regiva == "PR") ? rec_cms.get(COMMESSE_INDETR) : "9"; if (cms_tipodet != tipodet) if (cms_tipodet == "9" || tipodet.blank()) put( RDOC_TIPODET, cms_tipodet ); } } } void TRiga_documento::set_descr(const char* descr) { const int descr_len = length(RDOC_DESCR); TString s = descr; s.rtrim(); int split_pos = s.find('\n'); if (split_pos < 0 && s.len() > descr_len) split_pos = descr_len; if (split_pos > descr_len) split_pos = descr_len; if (split_pos > 0) { put(RDOC_DESCR, s.left(split_pos)); const TString& dest = s.mid(split_pos); put(RDOC_DESCLUNGA, "X"); put(RDOC_DESCEST, dest); } else { put(RDOC_DESCR, s); zero(RDOC_DESCLUNGA); zero(RDOC_DESCEST); } } void TRiga_documento::autosave(TSheet_field& f) { const int num = numero() - 1; if (num >= 0 && num < f.items()) { TMask& m = f.sheet_row_mask(num); TToken_string & row = f.row(num); put( RDOC_TIPORIGA, row.get( f.cid2index(FR_TIPORIGA )) ); TString8 codmag(row.get(f.cid2index(FR_CODMAG))); codmag.left_just(3); codmag << row.get( f.cid2index(FR_CODDEP )); put( RDOC_CODMAG, codmag); put( RDOC_CODART, row.get( f.cid2index(FR_CODART )) ); TString80 liv; for (int l = 0; l<4 ; l++) doc().livelli().pack_grpcode(liv,row.get(f.cid2index(FR_LIV1+l)),l+1); put( RDOC_LIVELLO, liv); // da modificare set_descr(row.get(f.cid2index(FR_DESCR))); const int prezzo_id = f.cid2index(FR_PREZZO); real prezzo(row.get(prezzo_id)); const TString4 codiva(row.get(f.cid2index(FR_CODIVA))); if (doc().tipo().calcolo_lordo()) { put(RDOC_PREZZOL, prezzo); iva(codiva).scorpora(prezzo, doc().decimals(true)); } put( RDOC_PREZZO, prezzo); put( RDOC_UMQTA, row.get( f.cid2index(FR_UMQTA )) ); put( RDOC_QTA, row.get( f.cid2index(FR_QTA )) ); put( RDOC_QTAEVASA, row.get( f.cid2index(FR_QTAEVASA )) ); put( RDOC_RIGAEVASA, row.get( f.cid2index(FR_RIGAEVASA )) ); put( RDOC_TARA, row.get( f.cid2index(FR_TARA )) ); put( RDOC_PNETTO, row.get( f.cid2index(FR_PNETTO )) ); put( RDOC_NCOLLI, row.get( f.cid2index(FR_NCOLLI )) ); put( RDOC_DAEVADERE, row.get( f.cid2index(FR_DAEVADERE )) ); put( RDOC_SCONTO, row.get( f.cid2index(FR_SCONTO )) ); put( RDOC_PERCPROV, row.get( f.cid2index(FR_PERCPROV )) ); put( RDOC_IMPFISUN, row.get( f.cid2index(FR_IMPFISUN )) ); put( RDOC_IMPFISSO, row.get( f.cid2index(FR_IMPFISSO )) ); put( RDOC_CODIVA, codiva); put( RDOC_ADDIVA, row.get( f.cid2index(FR_ADDIVA )) ); put( RDOC_ASPBENI, row.get( f.cid2index(FR_ASPBENI )) ); put( RDOC_CAUSMAG, row.get( f.cid2index(FR_CAUS )) ); TString8 codmagc(row.get(f.cid2index(FR_CODMAGC))); codmagc.left_just(3); codmagc << row.get( f.cid2index(FR_CODDEPC )); put( RDOC_CODMAGC, codmagc); put( RDOC_DATACONS, row.get( f.cid2index(FR_DATACONS )) ); put( RDOC_CODARTMAG, row.get( f.cid2index(FR_CODARTMAG )) ); put( RDOC_CHECKED, row.get( f.cid2index(FR_CHECKED )) ); put( RDOC_QTAGG1, row.get( f.cid2index(FR_QTAGG1 )) ); put( RDOC_QTAGG2, row.get( f.cid2index(FR_QTAGG2 )) ); put( RDOC_QTAGG3, row.get( f.cid2index(FR_QTAGG3 )) ); put( RDOC_QTAGG4, row.get( f.cid2index(FR_QTAGG4 )) ); put( RDOC_QTAGG5, row.get( f.cid2index(FR_QTAGG5 )) ); put( RDOC_IMPIANTO, row.get( f.cid2index(FR_IMPIANTO )) ); put( RDOC_LINEA, row.get( f.cid2index(FR_LINEA )) ); put( RDOC_CODAGG1, row.get( f.cid2index(FR_CODAGG1)) ); put( RDOC_CODAGG2, row.get( f.cid2index(FR_CODAGG2)) ); put( RDOC_RIDPREZZO, row.get( f.cid2index(FR_RIDPREZZO)) ); put( RDOC_PERCPROV1, row.get( f.cid2index(FR_PERCPROV1 )) ); for (short cdcid = FR_CDC1; cdcid <= FR_CDC12; cdcid++) { const int pos = m.id2pos(cdcid); if (pos < 0) break; const TMask_field& fld = m.fld(pos); const TFieldref* fldref = fld.field(); if (fldref == NULL) break; const char* value = row.get(f.cid2index(cdcid)); //il valore va preso dalla riga NON dalla maschera!!!!! fldref->write(value, *this); } if (m.id2pos(FR_TIPODET) >= 0 && m.field(FR_TIPODET).active()) //solo se attivo il campo di indetraibilita'... { TString4 tipodet = row.get( f.cid2index(FR_TIPODET)); put(RDOC_TIPODET, tipodet); cms2tipodet(); tipodet = get(RDOC_TIPODET); row.add(tipodet, f.cid2index(FR_TIPODET)); m.set(FR_TIPODET, tipodet); } //if(m.field(... // Salvo i campi con un FIELD manuale for (short id = FR_JOLLY1; id <= FR_JOLLY10; id++) { const int pos = m.id2pos(id); if (pos > 0) { const char* val = row.get(f.cid2index(id)); if (val != NULL) { const TFieldref* fld = m.fld(pos).field(); if (fld != NULL) fld->write(val, *this); } else break; } } for (short id = FR_SCAACC; id <= FR_PUNVET; id++) { const int pos = m.id2pos(id); if (pos > 0) { const TFieldref* fld = m.fld(pos).field(); if (fld != NULL) { const char* val = row.get(f.cid2index(id)); if (val != NULL) fld->write(val, *this); else fld->write(EMPTY_STRING, *this); } } } } } void TRiga_documento::autoload(TSheet_field & f) { const int num = numero() - 1; TToken_string & row = f.row(num); row.cut(0); row.add( get( RDOC_TIPORIGA ), f.cid2index(FR_TIPORIGA )); const TString8 codmag(get(RDOC_CODMAG)); row.add( codmag.left(3), f.cid2index(FR_CODMAG )); row.add( codmag.mid(3), f.cid2index(FR_CODDEP )); row.add( get( RDOC_CODART ), f.cid2index(FR_CODART )); TString16 liv(get(RDOC_LIVELLO)); for (int l = 0; l<4 ; l++) row.add(doc().livelli().unpack_grpcode(liv,l+1), f.cid2index(FR_LIV1+l )); TString s = get(RDOC_DESCR); if (get_bool(RDOC_DESCLUNGA)) s << get(RDOC_DESCEST); row.add(s, f.cid2index(FR_DESCR )); row.add( get( RDOC_UMQTA ), f.cid2index(FR_UMQTA )); const TString4 codiva(get(RDOC_CODIVA)); real prezzo = get_real(RDOC_PREZZO); if (doc().tipo().calcolo_lordo()) { const real prezzol = get_real(RDOC_PREZZOL); if (prezzol != ZERO) prezzo = prezzol; else prezzo = iva(codiva).lordo(prezzo, ALL_DECIMALS); } row.add(prezzo.string(), f.cid2index(FR_PREZZO )); row.add( get( RDOC_QTA ), f.cid2index(FR_QTA )); row.add( get( RDOC_QTAEVASA ), f.cid2index(FR_QTAEVASA )); row.add( get( RDOC_RIGAEVASA ), f.cid2index(FR_RIGAEVASA )); row.add( get( RDOC_TARA ), f.cid2index(FR_TARA )); row.add( get( RDOC_PNETTO ), f.cid2index(FR_PNETTO )); row.add( get( RDOC_NCOLLI ), f.cid2index(FR_NCOLLI )); row.add( get( RDOC_DAEVADERE ), f.cid2index(FR_DAEVADERE )); row.add( get( RDOC_SCONTO ), f.cid2index(FR_SCONTO )); row.add( get( RDOC_PERCPROV ), f.cid2index(FR_PERCPROV )); row.add( get( RDOC_IMPFISUN ), f.cid2index(FR_IMPFISUN )); row.add( get( RDOC_IMPFISSO ), f.cid2index(FR_IMPFISSO )); row.add( codiva, f.cid2index(FR_CODIVA )); row.add( get( RDOC_ADDIVA ), f.cid2index(FR_ADDIVA )); row.add( get( RDOC_ASPBENI ), f.cid2index(FR_ASPBENI )); row.add( get( RDOC_CAUSMAG ), f.cid2index(FR_CAUS )); const TString8 codmagc(get("CODMAGC")); row.add( codmagc.left(3), f.cid2index(FR_CODMAGC )); row.add( codmagc.mid(3), f.cid2index(FR_CODDEPC )); row.add( get( RDOC_DATACONS ), f.cid2index(FR_DATACONS )); row.add( get( RDOC_CODARTMAG ), f.cid2index(FR_CODARTMAG)); row.add( get( RDOC_CHECKED ), f.cid2index(FR_CHECKED)); row.add( get( RDOC_QTAGG1), f.cid2index(FR_QTAGG1)); row.add( get( RDOC_QTAGG2), f.cid2index(FR_QTAGG2)); row.add( get( RDOC_QTAGG3), f.cid2index(FR_QTAGG3)); row.add( get( RDOC_QTAGG4) , f.cid2index(FR_QTAGG4)); row.add( get( RDOC_QTAGG5) , f.cid2index(FR_QTAGG5)); row.add( get( RDOC_IMPIANTO) , f.cid2index(FR_IMPIANTO)); row.add( get( RDOC_LINEA) , f.cid2index(FR_LINEA)); row.add( get( RDOC_CODAGG1) , f.cid2index(FR_CODAGG1)); row.add( get( RDOC_CODAGG2) , f.cid2index(FR_CODAGG2)); row.add( get( RDOC_RIDPREZZO) , f.cid2index(FR_RIDPREZZO)); row.add( get( RDOC_PERCPROV1 ), f.cid2index(FR_PERCPROV1 )); const TMask& m = f.sheet_row_mask(num); for (short cdcid = FR_CDC1; cdcid <= FR_CDC12; cdcid++) { const int pos = m.id2pos(cdcid); if (pos < 0) break; TMask_field& fld = m.fld(pos); const TFieldref* fldref = fld.field(); if (fldref == NULL) break; const TString& val = fldref->read(*this); row.add(val, f.cid2index(cdcid)); } row.add( get( RDOC_TIPODET) , f.cid2index(FR_TIPODET)); // Leggo i campi con un FIELD manuale for (short id = FR_JOLLY1; id <= FR_JOLLY10; id++) { const int pos = m.id2pos(id); if (pos > 0) { const TFieldref* fld = m.fld(pos).field(); if (fld != NULL) { const int idx = f.cid2index(id); row.add(fld->read(*this), idx); } } } for (short id = FR_SCAACC; id <= FR_PUNVET; id++) { const int pos = m.id2pos(id); if (pos > 0) { const TFieldref* fld = m.fld(pos).field(); if (fld != NULL) { const int idx = f.cid2index(id); row.add(fld->read(*this), idx); } } } row.pack(); } TArticolo& TRiga_documento::articolo() const { return cached_article(get(RDOC_CODARTMAG)); } TArticolo_giacenza& TRiga_documento::articolo_giacenza() const { return cached_article_balances(get(RDOC_CODARTMAG)); } const TToken_string & TRiga_documento::get_original_rdoc_key() const { TToken_string & key = get_tmp_string(32); key.add(get(RDOC_DACODNUM)); key.add(get(RDOC_DAANNO)); key.add(get(RDOC_DAPROVV)); key.add(get(RDOC_DANDOC)); key.add(get(RDOC_DAIDRIGA)); return key; } const TToken_string & TRiga_documento::get_rdoc_key() const { TToken_string& key = get_tmp_string(32); key.add(get(RDOC_CODNUM)); key.add(get(RDOC_ANNO)); key.add(get(RDOC_PROVV)); key.add(get(RDOC_NDOC)); key.add(get(RDOC_IDRIGA)); return key; } void TRiga_documento::set_original_rdoc_key(const TRectype& orig, int depth) { CHECK(orig.num() == LF_RIGHEDOC, "Bad document row"); switch (depth) { case 0: put(RDOC_DACODNUM, orig.get(RDOC_CODNUM)); put(RDOC_DAANNO, orig.get(RDOC_ANNO)); put(RDOC_DAPROVV, orig.get(RDOC_PROVV)); put(RDOC_DANDOC, orig.get(RDOC_NDOC)); put(RDOC_DAIDRIGA, orig.get(RDOC_IDRIGA)); break; case 1: put(RDOC_DACODNUM, orig.get(RDOC_DACODNUM)); put(RDOC_DAANNO, orig.get(RDOC_DAANNO)); put(RDOC_DAPROVV, orig.get(RDOC_DAPROVV)); put(RDOC_DANDOC, orig.get(RDOC_DANDOC)); put(RDOC_DAIDRIGA, orig.get(RDOC_DAIDRIGA)); break; default: CHECK(0, "Sorry, too deep!"); break; } } void TRiga_documento::reset_original_rdoc_key() { zero(RDOC_DACODNUM); zero(RDOC_DAANNO); zero(RDOC_DAPROVV); zero(RDOC_DANDOC); zero(RDOC_DAIDRIGA); } const TRectype* TRiga_documento::find_original_rdoc() const { const long id = get_long(RDOC_DAIDRIGA); if (id > 0L) { TToken_string key; key.add(get(RDOC_DACODNUM)); key.add(get(RDOC_DAANNO)); key.add(get(RDOC_DAPROVV)); key.add(get(RDOC_DANDOC)); for (int r = 0; ; r++) { if (r == 0) key.add(id, 4); else key.add(r, 4); const TRectype& rec = cache().get(LF_RIGHEDOC, key); if (r > 0 && rec.empty()) break; if (rec.get_long(RDOC_IDRIGA) == id) return &rec; } } return NULL; } const TRectype* TRiga_documento::find_original_doc() const { const long id = get_long(RDOC_DANDOC); if (id > 0L) { TToken_string key; key.add(get(RDOC_DAPROVV)); key.add(get(RDOC_DAANNO)); key.add(get(RDOC_DACODNUM)); key.add(get(RDOC_DANDOC)); const TRectype& rec = cache().get(LF_DOC, key); if (!rec.empty()) return &rec; } return NULL; } void TTipo_riga_documento::set_defaults(TSheet_field& s, int row) const { if (_defaults.items() == 0) // Carica lo string_array con i defaults { TFilename pn; profile_name(pn); TConfig prof(pn, "DEFAULT"); for(int i = 0; ; i++) { TToken_string s(prof.get("Default", NULL, i)); if (s.empty()) break; const int field = s.get_int(); ((TTipo_riga_documento*)this)->_defaults.add(s.get(), field); } } // Setta i campi della maschera TToken_string& r = s.row(row - 1); FOR_EACH_ARRAY_ROW(_defaults, i, tt) r.add(*tt, s.cid2index(i)); } bool TRiga_documento::edit(int logicnum, const char* alternate_key_fields, const char* hint) const { const char* app = NULL; const TString& module = doc().tipo().module(); if (module.compare("CO", -1, true) == 0) app = "co0 -6"; else if (module.compare("LV", -1, true) == 0) app = "lv3 -0"; else if (module.compare("PE", -1, true) == 0) app = "pe0 -3"; return TRectype::edit(logicnum, alternate_key_fields, app); }