diff --git a/cg/cg2100a.uml b/cg/cg2100a.uml index 813374657..f28f008af 100755 --- a/cg/cg2100a.uml +++ b/cg/cg2100a.uml @@ -56,7 +56,7 @@ BEGIN MESSAGE COPY,F_ANNOIVA,7,10 USE LF_MOV KEY 2 DISPLAY "Data\nRegistraz.@10" DATAREG - DISPLAY "Data\nCompetenza@10" DATAREG + DISPLAY "Data\nCompetenza@10" DATACOMP DISPLAY "Numero\nregistraz.@7" NUMREG DISPLAY "Causale" CODCAUS DISPLAY "Numero\nDocumento@10" NUMDOC @@ -93,8 +93,6 @@ BEGIN ADD RUN cg0 -4 CHECKTYPE NORMAL WARNING "Causale assente" - MESSAGE EMPTY SHOW,F_NUMREG|HIDE,F_CC_NUMREG - MESSAGE SHOW,F_CC_NUMREG|HIDE,F_NUMREG END STRING F_DESCRCAUS 50 @@ -129,21 +127,8 @@ BEGIN DISPLAY "Protoc." PROTIVA DISPLAY "Descrizione@50" DESCR OUTPUT F_NUMREG NUMREG - KEY 1 -END - -NUMBER F_CC_NUMREG 7 -BEGIN - PROMPT 3 10 "Numero operazione " - HELP "Numero del movimento di prima nota da modificare" - USE LF_MOV SELECT BETWEEN(CODCAUS,#F_CODCAUS,#F_CODCAUS) - INPUT NUMREG F_CC_NUMREG - COPY DISPLAY F_NUMREG - OUTPUT F_CC_NUMREG NUMREG - MESSAGE COPY F_NUMREG - FLAGS "H" - KEY 1 CHECKTYPE REQUIRED + KEY 1 END ENDPAGE diff --git a/cg/cg2100c.uml b/cg/cg2100c.uml index c49d7528d..15fe8e254 100755 --- a/cg/cg2100c.uml +++ b/cg/cg2100c.uml @@ -542,6 +542,12 @@ BEGIN FIELD RITSOC END +CURRENCY F_REVCHARGE 18 +BEGIN + PROMPT 1 17 "Reverse charge " + FIELD REVCHARGE +END + DATE F_DATA74TER BEGIN PROMPT 52 15 "Data 74/ter " @@ -552,18 +558,18 @@ END BOOLEAN F_IVAXCASSA BEGIN - PROMPT 1 17 "IVA per cassa" + PROMPT 1 18 "IVA per cassa" FIELD IVAXCASSA MODULE IC END BOOLEAN F_LIQDIFF BEGIN - PROMPT 25 17 "Liquidazione differita" + PROMPT 25 18 "Liquidazione differita" WARNING "Data di incasso per liquidazione differita" FIELD LIQDIFF MESSAGE FALSE CLEAR,F_DATAINC - MESSAGE TRUE ENABLE,F_DATAINC + MESSAGE TRUE ENABLE,F_DATAINC FLAGS "H" END @@ -590,7 +596,7 @@ END STRING F_VALUTAINTRA 3 BEGIN - PROMPT 1 18 "Cambio intracom. " + PROMPT 1 19 "Cambio intracom. " FIELD CODVALI FLAGS "UZ" GROUP 4 @@ -608,7 +614,7 @@ END NUMBER F_CAMBIOINTRA 15 6 BEGIN - PROMPT 25 18 "" + PROMPT 25 19 "" FIELD CAMBIOI FLAGS "U" GROUP 4 @@ -617,20 +623,20 @@ END DATE F_DATAINTRA BEGIN - PROMPT 43 18 "Data competenza intra " + PROMPT 43 19 "Data competenza intra " FIELD DATACOMPI END CURRENCY F_CORRISPETTIVO 18 BEGIN - PROMPT 1 19 "Corrispettivo " + PROMPT 1 20 "Corrispettivo " FIELD CORRLIRE GROUP 4 END CURRENCY F_CORRVALUTA 18 BEGIN - PROMPT 39 19 "Corrispet. valuta " + PROMPT 39 20 "Corrispet. valuta " FIELD CORRVALUTA GROUP 4 VALIDATE REQIF_FUNC 1 F_VALUTAINTRA @@ -639,7 +645,7 @@ END STRING NP_CONTSEP 6 BEGIN - PROMPT 1 20 "Cont. separata " + PROMPT 1 21 "Cont. separata " USE &NPENT INPUT CODTAB NP_CONTSEP DISPLAY "Codice@6" CODTAB @@ -652,7 +658,7 @@ END STRING NP_DESCONTSEP 50 BEGIN - PROMPT 25 20 "" + PROMPT 25 21 "" USE &NPENT KEY 2 INPUT S0 NP_DESCONTSEP DISPLAY "Descrizione@50" S0 diff --git a/cg/cg2102.cpp b/cg/cg2102.cpp index c6d3fe14d..90bca229a 100755 --- a/cg/cg2102.cpp +++ b/cg/cg2102.cpp @@ -31,7 +31,7 @@ char TPrimanota_application::row_type(const TToken_string& s) if (s.full()) { s.get(CG_ROWTYPE%DLG_USER-1, t); // Can't use cgs().cid2index() here! - if (t < 'A' || t > 'Z') + if (!((t >= 'A' && t <= 'Z')||((t >= '0' && t <= '9')))) // is not alphanumeric? t = ' '; } return t; @@ -72,42 +72,39 @@ const real& TPrimanota_application::cod2IVA(const TMask& m) // Certified 99% Non sono sicurissimo degli imponibili negativi real TPrimanota_application::scorpora(real& imponibile, const real& percent) { - real imposta; const int dec = TCurrency::get_firm_dec(); - if (dec == 0) // Gestione Lire - { - imposta = abs(imponibile) * percent / (percent + CENTO); - imposta.ceil(); - if (imponibile.sign() < 0) imposta = -imposta; - } - else - { // Gestione Euro - imposta = imponibile * percent / (percent + CENTO); - imposta.round(dec); - } + real imposta = imponibile * percent / (percent + CENTO); + imposta.round(dec); imponibile -= imposta; return imposta; } -// Calcola il totale del documento tenendo conto del segno della prima riga e di quella delle -// ritenute sociali sulla causale +// Calcola il totale del documento tenendo conto del segno della prima riga +// e di quella delle ritenute sociali sulla causale, ritenute fiscali e reverse charge real TPrimanota_application::totale_documento() { const TMask& m = curr_mask(); - real tot(m.get(F_TOTALE)); // Legge totale - const real ritfis(m.get(F_RITFIS)); + real tot = m.get(F_TOTALE); // Legge totale + const real ritfis = m.get(F_RITFIS); tot += ritfis; // Somma ritenute fiscali - const real ritsoc(m.get(F_RITSOC)); + const real ritsoc = m.get(F_RITSOC); + const real revcha = m.get(F_REVCHARGE); const bool swapt = test_swap(false); // Totale invertito ? const bool swaps = test_swap(true); // Ritenute sociali invertite ? if (swapt ^ swaps) // Somma ritenute sociali con segno + { tot -= ritsoc; + tot -= revcha; + } else + { tot += ritsoc; + tot += revcha; + } return tot; } @@ -129,7 +126,7 @@ bool TPrimanota_application::suspended_handler(TMask_field& f, KEY k) if (suspended) { sf = f.get(); - return f.error_box(TR("Il codice '%s' e' sospeso e non puo' essere utilizzato"), sf); + return f.error_box(TR("Il codice '%s' è sospeso e non puo' essere utilizzato"), sf); } } return true; @@ -141,11 +138,10 @@ bool TPrimanota_application::suspended_handler(TMask_field& f, KEY k) int TPrimanota_application::type2pos(char tipo) { - TString_array& cg = app().cgs().rows_array(); - for (int i = 0; i < cg.items(); i++) + TString_array& a = app().cgs().rows_array(); + FOR_EACH_ARRAY_ROW(a, i, s) { - const TToken_string& s = cg.row(i); - const char t = row_type(s); + const char t = row_type(*s); if (t == tipo) return i; } @@ -155,15 +151,13 @@ int TPrimanota_application::type2pos(char tipo) // Trova nelle righe contabili un conto nelle righe di tipo prescelto int TPrimanota_application::bill2pos(const TBill& conto, char tipo) { - TString_array& cg = app().cgs().rows_array(); - const int num_rows = cg.items(); - for (int i = 0; i < num_rows; i++) + TString_array& a = app().cgs().rows_array(); + FOR_EACH_ARRAY_ROW(a, i, s) { - TToken_string& s = cg.row(i); - const char t = row_type(s); + const char t = row_type(*s); if (t == tipo) { - const TBill c(s, 3, 0x0); + const TBill c(*s, 3, 0x0); if (c == conto) return i; } @@ -174,17 +168,15 @@ int TPrimanota_application::bill2pos(const TBill& conto, char tipo) // Trova nelle righe contabili un conto di contropartita per il conto dato int TPrimanota_application::bill2contr(const TBill& conto, char sezione) const { - TString_array& rows = cgs().rows_array(); - const int num_rows = rows.items(); - TBill c; // Conto corrente (Buona questa!) - for (int i = 0; i < num_rows; i++) + TString_array& a = app().cgs().rows_array(); + TBill c; // Conto corrente (Buona questa!) + FOR_EACH_ARRAY_ROW(a, i, r) { - TToken_string& r = rows.row(i); - const real dare(r.get(0)); + const real dare(r->get(0)); const char sez = dare.is_zero() ? 'A' : 'D'; if (sez == sezione) // Devo cercare sezione contraria continue; - c.get(r, 3, 0x0); + c.get(*r, 3, 0x0); if (conto == c) return i; } @@ -197,12 +189,11 @@ int TPrimanota_application::bill_used(const TBill& conto) const TString_array& rows = ivas().rows_array(); TBill c; // Conto corrente int users = 0; - for (int i = rows.items(); i >= 0 ; i--) + FOR_EACH_ARRAY_ROW(rows, i, row) { - TToken_string& row = rows.row(i); - if (!row.empty_items()) + if (!row->empty_items()) { - c.get(row, 6, 0x0); + c.get(*row, 6, 0x0); if (conto == c) users++; } @@ -276,16 +267,19 @@ bool TPrimanota_application::sub_cgs_imp(int n, const TImporto& imp) TImporto TPrimanota_application::real2imp(const real& r, char row_type) { - bool dare; - if (row_type == 'S') + bool dare = false; + + switch (row_type) { + case 'S': + case 'V': dare = causale().sezione_ritsoc() == 'D'; - } - else - { + break; + default: dare = causale().sezione_clifo() == 'D'; if (row_type != 'T' && row_type != 'F') dare = !dare; + break; } TImporto importo(dare ? 'D' : 'A', r); @@ -297,7 +291,7 @@ void TPrimanota_application::disable_cgs_cells(int n, char tipo) { TSheet_field& cg = cgs(); - int first = 0, last = 0; // Range di righe da disabilitare + int first = 0, last = 0; // Range di colonne da disabilitare switch(tipo) { case 'T': // Totale documento @@ -321,6 +315,8 @@ void TPrimanota_application::disable_cgs_cells(int n, char tipo) case 'P': // Abbuoni passivi case 'R': // Ritenute professionali case 'S': // Ritenute Sociali + case 'V': // Reverse charge + case '1': // Scissione pagamenti art, 17-ter DPR 633/72 last = 3; break; case 'K': // Riga cliente/fornitore per saldaconto @@ -410,15 +406,16 @@ int TPrimanota_application::set_cgs_row(int n, const TImporto& imp, } -HIDDEN int compare_rows(const TObject** o1, const TObject** o2) +HIDDEN int compare_rows(const TSortable& o1, const TSortable& o2, void* jolly) { // Totale, Rit.Fisc., Rit.Soc., da riga IVA, riga contabile, IVA detr., IVA non detr. - const char* const sort_order = "TFSI DNAPRC"; + const char* const sort_order = "TFSVI DN1APRC"; - const TToken_string* r1 = (const TToken_string*)*o1; - const TToken_string* r2 = (const TToken_string*)*o2; - const char c1 = app().row_type(*r1); - const char c2 = app().row_type(*r2); + const TToken_string& r1 = (const TToken_string&)o1; + const TToken_string& r2 = (const TToken_string&)o2; + const TPrimanota_application& a = *(TPrimanota_application*)jolly; + const char c1 = a.row_type(*r1); + const char c2 = a.row_type(*r2); return int(strchr(sort_order, c1) - strchr(sort_order, c2)); } @@ -466,7 +463,7 @@ void TPrimanota_application::cgs_pack() } } if (!pagamento && rowtypes_present) // Il pagamento e' gia' ordinato - rows.TArray::sort(compare_rows); // Pack and sort array + rows.TArray::sort(compare_rows, &app()); // Pack and sort array } @@ -1124,10 +1121,11 @@ bool TPrimanota_application::descr_handler(TMask_field& f, KEY k) if (first >= 0) { TSheet_field& cg = app().cgs(); - const TString80 old = cg.row(first).get(8); + const int pos = cg.cid2index(CG_DESCR); + const TFixed_string old = cg.row(first).get(pos); if (old.blank() || f.get().find(old) >= 0) { - cg.row(first).add(f.get(), 8); + cg.row(first).add(f.get(), pos); cg.force_update(first); } } @@ -1136,7 +1134,7 @@ bool TPrimanota_application::descr_handler(TMask_field& f, KEY k) if (k == K_ENTER && f.get().empty()) { if (f.mask().get(F_CODCAUS).empty()) - return f.error_box(TR("La descrizione del documento e' necessaria in assenza della causale")); + return f.error_box(TR("La descrizione del documento è necessaria in assenza della causale")); } return true; } @@ -1378,11 +1376,10 @@ real TPrimanota_application::calcola_imp() const TArray& rows = ivas().rows_array(); real imponibili, imposte; - for (int r = rows.items()-1; r >= 0; r--) + FOR_EACH_ARRAY_ROW(rows, r, row) if (!row->empty_items()) { - TToken_string& row = (TToken_string&)rows[r]; - imponibili += real(row.get(0)); - imposte += real(row.get(3)); + imponibili += real(row->get(0)); + imposte += real(row->get(3)); } TMask& m = curr_mask(); @@ -1392,7 +1389,7 @@ real TPrimanota_application::calcola_imp() const // Se e' attiva la terza pagina allora riporta i totali in testata if (is_fattura()) { - real tot(m.get(F_TOTALE)); tot -= imposte; + real tot = m.get(F_TOTALE); tot -= imposte; m.set(FS_IMPONIBILI, tot); m.set(FS_IMPOSTE, imposte); } @@ -1426,7 +1423,7 @@ int TPrimanota_application::get_importi_iva(const TToken_string& row, { real imptot; row.get(0, imptot); // Importo scritto nella riga iva TString4 zanicchi; row.get(1, zanicchi); // Codice IVA - TString4 codind; row.get(2, codind); // Codice indetraibilita' + TString4 codind; row.get(2, codind); // Codice indetraibilità real ivatot; row.get(3, ivatot); // Imposta scritta nella riga iva int annodoc = app()._msk[2]->get_date(F_DATADOC).year(); @@ -1647,8 +1644,34 @@ bool TPrimanota_application::iva_notify(TSheet_field& iva, int r, KEY k) oldposiva[d] = newposiva; } // for (int d = 0; d < 2; d++) - + TMask& m = a.curr_mask(); + + if (m.get_int(F_ANNOIVA) >= 2015 && a.clifo() == 'C') // Controllo split-payment + { + const int r_norm = type2pos('D'); + const int r_split = type2pos('1'); + const bool split_needed = r_norm >= 0 && a.is_split_payment(); + if (split_needed) + { + TImporto imp_split = a.get_cgs_imp(r_norm); imp_split.swap_section(); + if (r_split < 0) + { + TToken_string row_norm = a.cgs().row(r_norm); + TBill iva_split(row_norm, 3); + const char* desc = TR("IVA art. 17-ter D.P.R. 633/1972)"); + a.set_cgs_row(-1, imp_split, iva_split, desc, '1'); + } + else + a.set_cgs_imp(r_split, imp_split); + } + else + { + if (r_split >= 0) + a.reset_cgs_row(r_split); + } + } + if (r == 0) // Se cambio la prima riga ... { a.add_cgs_tot(m); // ... ricalcola conti e imponibili @@ -1676,9 +1699,14 @@ bool TPrimanota_application::iva_notify(TSheet_field& iva, int r, KEY k) imposta = m.get_real(F_IMPOSTE); imponibile = m.get_real(F_TOTALE) - imposta; } - imposta.round(pag.round(inv)); imponibile.round(pag.round(inv)); - real pimposta(pag.imposta(inv)); real pimponibile(pag.imponibile(inv)); - pimposta.round(pag.round(inv)); pimponibile.round(pag.round(inv)); + imposta.round(pag.round(inv)); + imponibile.round(pag.round(inv)); + + real pimposta(pag.imposta(inv)); + pimposta.round(pag.round(inv)); + + real pimponibile(pag.imponibile(inv)); + pimponibile.round(pag.round(inv)); if (pimposta != imposta || pimponibile != imponibile) a.set_scadenze(m); // Ricalcola rate @@ -1701,9 +1729,9 @@ bool TPrimanota_application::iva_handler(TMask_field& f, KEY k) const TCurrency tot(app().totale_documento()); if (imp != tot) { - const TString t(tot.string(true)); - const TString i(imp.string(true)); - return error_box(FR("La somma del totale documento e delle ritenute (%s) e' diverso dalla " + const TString t = tot.string(true); + const TString i = imp.string(true); + return error_box(FR("La somma del totale documento e delle ritenute (%s) è diverso dalla " "somma degli imponibili e delle imposte (%s)"), (const char*)t, (const char*)i); } @@ -1717,11 +1745,11 @@ bool TPrimanota_application::iva_handler(TMask_field& f, KEY k) { const TFixed_string codiva = row.get(1); if (codiva.blank()) - return error_box(FR("Il codice IVA della riga %d e' obbligatorio"), i+1); + return error_box(FR("Il codice IVA della riga %d è obbligatorio"), i+1); TBill c(row, 5, 0x1); if (!c.ok() || !c.find()) - return error_box(FR("Il conto della riga iva %d e' errato o incompleto"), i+1); + return error_box(FR("Il conto della riga iva %d è errato o incompleto"), i+1); } } } @@ -2166,6 +2194,10 @@ bool TPrimanota_application::caus_query_handler(TMask_field& f, KEY key) { const TString& cau = f.get(); const int ann = m.get_int(F_ANNOIVA); + + TEdit_field& numreg = m.efield(F_NUMREG); + TString16 filter; if (cau.full()) filter << MOV_CODCAUS << "==\"" << cau << '"'; + numreg.browse()->set_filter(filter); const TipoIVA i = app().cau2IVA(cau, ann); // Cerca causale e suo tipo if (i != iva_errata) @@ -2695,10 +2727,19 @@ void TPrimanota_application::add_cgs_tot(TMask& m) else { // Creazione/Aggiornamento riga totale - const real tot(m.get(F_TOTALE)); + real tot = m.get(F_TOTALE); + if (app().is_split_payment()) + { + calcola_imp(); // Ricalcola totale IVA + tot -= m.get_real(F_IMPOSTE); + } + TString80 descr; if (riga_totale >= 0) - descr = cgs().row(riga_totale).get(8); + { + const int idx_des = ss.cid2index(CG_DESCR); + descr = ss.row(riga_totale).get(idx_des); + } if (descr.blank()) descr = m.get(F_DESCR); TImporto imp = real2imp(tot, 'T'); @@ -2906,7 +2947,7 @@ bool TPrimanota_application::main_codiva_handler(TMask_field& f, KEY key) f.mask().set(F_RITFIS, imposta, true); } } - if (imp.is_zero()) // Se il totale documento non e' stato spezzato + if (imp.is_zero()) // Se il totale documento non è stato spezzato { TToken_string& row = a.ivas().row(0); iva_notify(a.ivas(), 0, K_SPACE); @@ -3153,23 +3194,21 @@ bool TPrimanota_application::totdocval_handler(TMask_field& f, KEY key) // Aggiunge o aggiorna la riga delle ritenute fiscali o sociali // Certified 99% -void TPrimanota_application::add_cgs_rit(bool fiscali) +void TPrimanota_application::add_cgs_ritenute(char tipo) { if (_as400) return; TMask& m = curr_mask(); - const real imp(m.get(fiscali ? F_RITFIS : F_RITSOC)); // Determina importo - - const char tipo = fiscali ? 'F' : 'S'; + const real imp = m.get(tipo=='F' ? F_RITFIS : (tipo=='S' ? F_RITSOC : F_REVCHARGE)); // Determina importo const int pos = type2pos(tipo); // Cerca la riga contabile if (pos < 0) // Se non c'e' ... { - if (!imp.is_zero()) // ... e l'importo e' valido - { // crea una nuova riga di ritenute - const int riga = fiscali ? RIGA_RITENUTE_FISCALI : RIGA_RITENUTE_SOCIALI; + if (!imp.is_zero()) // ... e l'importo e' valido crea una nuova riga di ritenute + { + const int riga = tipo=='F' ? RIGA_RITENUTE_FISCALI : (tipo== 'S' ? RIGA_RITENUTE_SOCIALI : RIGA_REVERSE_CHARGE); TBill conto; causale().bill(riga, conto); - const TString desc(causale().desc_agg(riga)); + const TString desc = causale().desc_agg(riga); set_cgs_row(-1, real2imp(imp, tipo), conto, desc, tipo); } } @@ -3221,7 +3260,7 @@ bool TPrimanota_application::protiva_handler(TMask_field& f, KEY key) bool TPrimanota_application::ritfis_handler(TMask_field& f, KEY key) { if (key == K_TAB && f.focusdirty()) - app().add_cgs_rit(true); + app().add_cgs_ritenute('F'); return true; } @@ -3231,10 +3270,20 @@ bool TPrimanota_application::ritfis_handler(TMask_field& f, KEY key) bool TPrimanota_application::ritsoc_handler(TMask_field& f, KEY key) { if (key == K_TAB && f.focusdirty()) - app().add_cgs_rit(false); + app().add_cgs_ritenute('S'); return true; } +// Handler of F_REVCHARGE +// Certified 100% +bool TPrimanota_application::revcharge_handler(TMask_field& f, KEY key) +{ + if (key == K_TAB && f.focusdirty()) + app().add_cgs_ritenute('V'); + return true; +} + + HIDDEN void inventa_cambio_intra(TMask& m) { const TString& codval = m.get(F_VALUTAINTRA); @@ -3455,14 +3504,15 @@ bool TPrimanota_application::solaiva_handler(TMask_field& f, KEY key) { TSheet_field& iva = a.ivas(); const int righe = iva.items(); - TProgind pi(righe, TR("Generazione righe contabilita'"), false, true); + TProgind pi(righe, TR("Generazione righe contabilità"), false, true); TSheet_field& cg = a.cgs(); cg.reset(); - a.add_cgs_tot(m); // Genera totale documento - if (m.get(F_RITFIS).not_empty()) a.add_cgs_rit(true); // Genera ritenute fiscali - if (m.get(F_RITSOC).not_empty()) a.add_cgs_rit(false); // Genera ritenute sociali + a.add_cgs_tot(m); // Genera totale documento + if (!m.efield(F_RITFIS).empty()) a.add_cgs_ritenute('F'); // Genera ritenute fiscali + if (!m.efield(F_RITSOC).empty()) a.add_cgs_ritenute('S'); // Genera ritenute sociali + if (!m.efield(F_REVCHARGE).empty()) a.add_cgs_ritenute('V'); // Genera reverse charge TToken_string oldrow(128); for (int i = 0; i < righe; i++) @@ -3535,12 +3585,12 @@ bool TPrimanota_application::quadratura_handler(TMask_field& f, KEY key) if (m.field(F_CLIENTE).shown()) { clifo.put(CLI_TIPOCF, "C"); - clifo.put(CLI_CODCF, m.get(F_CLIENTE));; + clifo.put(CLI_CODCF, m.get(F_CLIENTE)); } else { clifo.put(CLI_TIPOCF, "F"); - clifo.put(CLI_CODCF, m.get(F_FORNITORE));; + clifo.put(CLI_CODCF, m.get(F_FORNITORE)); } if (cliforel.read() == NOERR)