2019-01-02 14:48:09 +01:00
# include "fplib.h"
2018-07-06 16:30:37 +02:00
# include <prefix.h>
# include <config.h>
# include <utility.h>
# include <scanner.h>
# include <xvt.h>
# include <diction.h>
# include "text.h"
# include <isam.h>
2018-07-25 15:53:29 +02:00
# include <tabutil.h>
2018-07-31 16:01:13 +02:00
# include <dongle.h>
# include <execp.h>
2018-07-25 15:53:29 +02:00
# include "../fe/felib.h"
# include "../cg/cglib03.h"
2018-11-28 16:28:33 +01:00
# include "../ve/velib04.h"
2018-07-25 15:53:29 +02:00
# include <anagiu.h>
# include <comuni.h>
# include <cfven.h>
# include <nditte.h>
# include <unloc.h>
# include <causali.h>
# include "../cg/cfban.h"
2018-07-31 16:01:13 +02:00
# include "modaut.h"
2018-07-06 16:30:37 +02:00
void set_connection ( SSimple_query & s )
{
2018-10-08 11:45:08 +02:00
# ifdef DBG
2019-01-02 14:48:09 +01:00
TString ip = fp_settings ( ) . get_db_indirizzo ( ) ;
2018-10-10 10:09:57 +02:00
if ( ip . upper ( ) ! = " TESTCAMPO2012 " )
{
if ( s . sq_connect ( " TESTCAMPO2012@campo_fp " ,
" fp " ,
" fp " ,
TSDB_MSSQL ) ! = NOERR )
fatal_box ( " Impossibile connettersi al DB esterno " ) ;
}
else
{
# endif
2018-07-06 16:30:37 +02:00
if ( s . sq_connect (
2019-01-02 14:48:09 +01:00
fp_settings ( ) . get_db_str_con ( ) ,
fp_settings ( ) . get_db_user ( ) ,
fp_settings ( ) . get_db_password ( ) ,
2018-07-06 16:30:37 +02:00
TSDB_MSSQL ) ! = NOERR )
fatal_box ( " Impossibile connettersi al DB esterno " ) ;
2018-10-10 10:09:57 +02:00
# ifdef DBG
}
2018-10-08 11:45:08 +02:00
# endif
2018-07-06 16:30:37 +02:00
}
2018-10-08 11:45:08 +02:00
SSimple_query & fp_db ( )
2018-07-06 16:30:37 +02:00
{
static SSimple_query * db = nullptr ;
if ( db = = nullptr )
{
db = new SSimple_query ( ) ;
set_connection ( * db ) ;
// Non utilizzo l'autocommit, viene gestito manualmente
db - > sq_set_autocommit ( false ) ;
}
return * db ;
}
2018-07-31 16:01:13 +02:00
string getline ( ifstream & f )
{
string app ;
getline ( f , app ) ;
return app ;
}
2018-07-06 16:30:37 +02:00
bool check_tables ( )
{
/*
* Da questo programma in poi verr <EFBFBD> utilizzato un sistema diverso per la creazione e aggiornamento delle tabelle
* Verranno utilizzati dei file . sql aggiornati con il numero di patch , leggermente scomodo durante la creazione ma facile per i controlli successivamente
*/
SLIST files = xvt_fsys_list_files ( " .sql " , " sql/fp0/ " , false ) ;
TLocalisamfile tabmod ( LF_TABMOD ) ;
tabmod . put ( " MOD " , " FP " ) ;
tabmod . put ( " COD " , " SQL " ) ;
tabmod . put ( " CODTAB " , " VERSION " ) ;
TString version ;
if ( tabmod . read ( ) = = NOERR )
version = tabmod . get ( " S0 " ) ;
for ( SLIST_ELT file = xvt_slist_get_first ( files ) ; file ; file = xvt_slist_get_next ( files , file ) )
{
TString file_version = TFilename ( file - > str ) . name_only ( ) ;
file_version = file_version . mid ( 2 , 4 ) ;
if ( file_version < = version )
continue ;
ifstream f ( file - > str ) ;
if ( f . is_open ( ) )
{
string s ;
while ( ! f . eof ( ) )
{
2018-07-17 16:31:00 +02:00
static string r ;
r = getline ( f ) ;
if ( r [ 0 ] = = ' - ' & & r [ 1 ] = = ' - ' )
continue ;
s + = r ;
2018-10-04 18:10:17 +02:00
// Cerco un ;
2018-07-06 16:30:37 +02:00
const int limiter = s . find ( ' ; ' ) + 1 ;
if ( limiter > 0 )
{
string query = s . substr ( 0 , limiter ) ;
s . erase ( 0 , limiter ) ;
2018-10-08 11:45:08 +02:00
if ( ! fp_db ( ) . sq_set_exec ( query ) | | ! fp_db ( ) . sq_commit ( ) )
2018-07-06 16:30:37 +02:00
{
2018-10-08 11:45:08 +02:00
fatal_box ( " Impossibile eseguire/salvare la query: \n %s \n %s " , query . c_str ( ) , fp_db ( ) . sq_get_string_error ( ) ) ;
2018-07-06 16:30:37 +02:00
}
}
}
}
else
{
cantread_box ( file - > str ) ;
return false ;
}
// Salvo su tabmod
tabmod . zero ( ) ;
tabmod . put ( " MOD " , " FP " ) ;
tabmod . put ( " COD " , " SQL " ) ;
tabmod . put ( " CODTAB " , " VERSION " ) ;
tabmod . put ( " S0 " , file_version ) ;
if ( tabmod . rewrite_write ( ) ! = NOERR & & ! yesno_box ( " Attenzione! Errore di aggiornamento versione di Database in Campo, continuare? %s " , file_version ) )
{
return false ;
}
}
return true ;
}
2019-01-17 14:14:09 +01:00
TString & complete_num_fp ( const TCodice_numerazione & codnum , const int numdoc )
{
static const int len_num_doc = TRectype ( LF_DOC ) . length ( DOC_NDOC ) ;
TString & ret = get_tmp_string ( ) ;
const TString & prefisso = codnum . prefisso ( ) ;
const TString & postfisso = codnum . postfisso ( ) ;
static TString ndoc ; ndoc . cut ( 0 ) < < numdoc ;
if ( prefisso . full ( ) | | postfisso . full ( ) )
{
for ( ; ndoc . len ( ) < len_num_doc ; )
ndoc . add_front ( " 0 " ) ;
}
ret < < prefisso < < ndoc < < postfisso ;
return ret ;
}
2018-07-25 15:53:29 +02:00
/*
* HFATT : tipocf ( 1 ) + codcf ( 6 )
* BFATT : datadoc ( 8 ) + tipodoc_SDI ( 4 ) + numdoc ( 7 )
*/
// Crea la coppia di chiavi per il db PAF a partire da un documento vero e proprio
bool chiave_paf ( const TDocumento & doc , TString & hfatt , TString & bfatt )
{
hfatt . cut ( 0 ) ;
if ( doc . clifor ( ) . occasionale ( ) )
hfatt < < " O " < < doc . get ( " OCFPI " ) ;
else
hfatt < < doc . clifor ( ) . tipo ( ) < < doc . clifor ( ) . codice ( ) ;
CHECK ( hfatt . full ( ) , " Destinatario fattura P.A. non valido " ) ;
const TCodice_numerazione & codnum = doc . codice_numerazione ( ) ;
2019-01-10 14:11:28 +01:00
//20180101_TD01_123456712345671234567
2019-01-17 14:14:09 +01:00
bfatt . cut ( 0 ) < < doc . get_date ( DOC_DATADOC ) . date2ansi ( ) < < ' _ ' < < tipo_doc_sdi ( doc ) < < ' _ ' < < complete_num_fp ( codnum , doc . numero ( ) ) ;
2018-07-25 15:53:29 +02:00
return hfatt . full ( ) & & bfatt . full ( ) ;
}
// Crea la coppia di chiavi per il db PAF a partire da un semplice record di testata documento
bool chiave_paf ( const TRectype & doc , TString & hfatt , TString & bfatt )
{
TDocumento d ( doc ) ;
chiave_paf ( d , hfatt , bfatt ) ;
return hfatt . full ( ) ;
}
2019-01-02 14:48:09 +01:00
TString get_dest_sdi ( const char tipocf , const long codcf )
{
TString codsdi , pec ;
get_coddest ( tipocf , codcf , codsdi , pec ) ;
return pec . full ( ) ? pec : codsdi ;
}
2018-10-04 18:10:17 +02:00
bool get_coddest ( const char tipocf , const long codcf , TString & coddest , TString & pec )
{
TCli_for clifo ( tipocf , codcf ) ;
coddest = clifo . vendite ( ) . get ( " PADESTIN " ) ;
pec = clifo . get ( " PEC " ) ;
2019-01-14 14:41:52 +01:00
TAnagrafica anag ( LF_CLIFO , tipocf , codcf ) ;
2018-10-04 18:10:17 +02:00
if ( coddest . empty ( ) )
{
2019-01-14 14:41:52 +01:00
if ( pec . full ( ) | | fp_settings ( ) . get_esp_pri_empty ( ) )
2019-01-02 14:48:09 +01:00
coddest = " 0000000 " ;
2018-10-04 18:10:17 +02:00
// Controllo se <20> straniero
2019-01-14 14:41:52 +01:00
else if ( anag . estero ( ) & & anag . stato_partita_IVA ( ) ! = " IT " )
2018-10-04 18:10:17 +02:00
{
2019-01-14 14:41:52 +01:00
coddest = fp_settings ( ) . get_esp_est ( ) ? fp_settings ( ) . get_esp_est_cod ( ) : " " ;
2018-10-04 18:10:17 +02:00
}
}
2019-01-14 14:41:52 +01:00
else
pec = " " ;
2019-02-21 17:44:31 +01:00
2019-01-02 14:48:09 +01:00
return coddest . full ( ) ;
2018-10-04 18:10:17 +02:00
}
2018-10-08 10:42:28 +02:00
inline const TString & no_special ( char a )
{
TString & r = get_tmp_string ( ) . cut ( 0 ) ;
switch ( a )
{
case ' \' ' :
break ;
default :
r < < a ;
}
return r ;
}
2018-12-04 10:28:27 +01:00
const TString & tipo_doc_sdi ( const TDocumento & doc )
{
2019-02-21 12:25:58 +01:00
static TString tipo_doc_sdi ;
tipo_doc_sdi . cut ( 0 ) < < doc . get ( DOC_TIPODOCSDI ) ;
// Controlli da fare per clienti a cui si fotte la conversione e mi trovo dati sporchi nella colonna
if ( tipo_doc_sdi . len ( ) = = 4 & & tipo_doc_sdi . starts_with ( " TD " ) )
{
return tipo_doc_sdi ;
}
return doc . tipo ( ) . tipo_doc_sdi ( ) ;
2018-12-04 10:28:27 +01:00
}
2019-02-06 10:47:23 +01:00
bool is_fattura ( const TRectype & doc )
{
const TTipo_documento & td = cached_tipodoc ( doc . get ( DOC_TIPODOC ) ) ;
if ( ! td . is_fattura ( ) ) // Tengo per buone solo le fatture e le note di credito
return false ;
const TCodice_numerazione & cn = cached_numerazione ( doc . get ( DOC_CODNUM ) ) ;
return cn . tipo ( ) = = 2 & & ! cn . get_bool ( " B10 " ) ; // Controlla se fattura provvisioria esclusa da P.A.
}
TString & add_filter ( const TString & field , const TString & from , const TString & to )
{
TString & query = get_tmp_string ( ) ;
const TString qf = field . find ( ' . ' ) < 0 ? field : field . sub ( field . find ( ' . ' ) + 1 ) ;
if ( from . full ( ) & & to . full ( ) )
{
query < < " &&(BETWEEN( " < < field < < " , #DA " < < qf < < " , #A " < < qf < < " )) " ;
}
else if ( from . full ( ) )
{
query < < " &&( " < < field < < " >=#DA " < < qf < < " ) " ;
}
else if ( to . full ( ) )
{
query < < " &&( " < < field < < " <=#A " < < qf < < " ) " ;
}
return query ;
}
2018-07-25 15:53:29 +02:00
/***************************************************************************
* TPaf_record
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// Imposta il valore di un campo variant
void TPaf_record : : set ( const char * fld , const TVariant & var )
{
CHECK ( fld & & * fld , " Null field name " ) ;
if ( var . is_null ( ) )
{
_fields . remove ( fld ) ;
}
else
{
TVariant * obj = ( TVariant * ) _fields . objptr ( fld ) ;
if ( obj ! = NULL )
* obj = var ;
else
_fields . add ( fld , new TVariant ( var ) ) ;
}
}
// Imposta il valore di un campo intero
void TPaf_record : : set ( const char * fld , long val )
{
const TVariant var ( val ) ;
set ( fld , var ) ;
}
// Imposta il valore di un campo stringa
void TPaf_record : : set ( const char * fld , const char * val )
{
if ( val = = NULL )
set ( fld , NULL_VARIANT ) ;
else
{
const TVariant var ( val ) ;
set ( fld , var ) ;
}
}
// Imposta il valore di un campo stringa
void TPaf_record : : set ( const char * fld , const TString & val )
{
2018-10-15 12:58:46 +02:00
const TVariant var ( val ) ;
if ( ! var . is_string ( ) | | ( val . full ( ) ) )
2018-07-25 15:53:29 +02:00
set ( fld , var ) ;
}
// Imposta il valore di un campo numerico
void TPaf_record : : set ( const char * fld , const real & val )
{
const TVariant var ( val ) ;
set ( fld , var ) ;
}
// Imposta il valore di un campo data in formato ISO
void TPaf_record : : set ( const char * fld , const TDate & val )
{
if ( val . ok ( ) )
{
const TVariant var ( val ) ;
set ( fld , var ) ;
}
else
set ( fld , " " ) ;
}
// Imposta il valore di un campo booleano
void TPaf_record : : set ( const char * fld , bool var )
{
set ( fld , var ? " SI " : " NO " ) ;
}
const TString TPaf_record : : sq_get ( const char * fld ) const
{
2018-10-08 11:45:08 +02:00
return fp_db ( ) . sq_get ( fld ) ;
2018-07-25 15:53:29 +02:00
}
// Legge il valore di un campo variant
const TVariant & TPaf_record : : get ( const char * fld ) const
{
const TVariant * var = ( const TVariant * ) _fields . objptr ( fld ) ;
return var ? * var : NULL_VARIANT ;
}
// Converte un variant in una stringa valida per SQLite
const TString & TPaf_record : : var2str ( const TString & fldname , const TVariant & var ) const
{
2019-01-02 14:48:09 +01:00
const TFieldtypes vt = var . type ( ) ;
TString & tmp = get_tmp_string ( ) ;
if ( vt = = _realfld )
{
const TCurrency v ( var . as_real ( ) , " " , ZERO , fldname . find ( " PRZ " ) > 0 | | fldname . find ( " PREZZO " ) > 0 ) ;
tmp < < ' \' ' < < v . string ( ) < < ' \' ' ;
tmp . replace ( ' , ' , ' . ' ) ;
return tmp ;
}
if ( vt = = _datefld )
{
tmp < < ' \' ' < < var . as_date ( ) . string ( full , ' - ' , full , full , amg_date ) < < ' \' ' ;
return tmp ;
}
const TString & str = var . as_string ( ) ;
bool apici = vt = = _alfafld ;
if ( apici & & str [ 0 ] ! = ' 0 ' & & real : : is_natural ( str ) )
apici = false ;
// Parso i caratteri speciali
for ( int i = 0 ; i < str . len ( ) ; i + + )
{
tmp < < no_special ( str [ i ] ) ;
}
if ( apici )
{
2018-10-08 10:42:28 +02:00
// Aggiungo apici a inizio e fine riga
2018-07-25 15:53:29 +02:00
tmp . insert ( " ' " , 0 ) ;
tmp < < ' \' ' ;
2019-01-02 14:48:09 +01:00
}
return tmp ;
2018-07-25 15:53:29 +02:00
}
2018-10-10 10:09:57 +02:00
TString & TPaf_record : : remove_string ( bool id_riga )
2018-07-25 15:53:29 +02:00
{
2018-07-31 16:01:13 +02:00
TString & query = get_tmp_string ( ) . cut ( 0 ) ;
query < < " DELETE FROM " < < _table < < " WHERE " ;
int nkf = 0 ;
FOR_EACH_TOKEN ( _key , fld )
{
const TVariant & var = get ( fld ) ;
if ( ! var . is_null ( ) )
2018-07-25 15:53:29 +02:00
{
2018-10-10 10:09:57 +02:00
if ( ! id_riga & & TString ( fld ) . find ( " RIFNUMLINEA " ) > 0 )
continue ;
2018-07-31 16:01:13 +02:00
if ( nkf + + > 0 )
query < < " AND " ;
query < < fld < < ' = ' < < var2str ( fld , var ) ;
2018-07-25 15:53:29 +02:00
}
2018-07-31 16:01:13 +02:00
}
2018-10-08 17:40:11 +02:00
// Faccio un triccheballacche per mettere il progressivo non vuoto
TString prefix = _key . get ( 0 ) ;
prefix = prefix . sub ( 0 , prefix . find ( ' _ ' ) + 1 ) ;
query < < " AND " < < prefix < < " KEYPRGINVIO != '' " ;
CHECKS ( + + nkf > = 2 , " Can't remove partial key on table " , static_cast < const char * > ( _table ) ) ;
2018-07-31 16:01:13 +02:00
query < < ' ; ' ;
return query ;
}
// Elimina il record in base ai campi chiave
bool TPaf_record : : remove ( )
{
2018-10-08 11:45:08 +02:00
return fp_db ( ) . sq_set_exec ( remove_string ( ) ) ;
2018-07-25 15:53:29 +02:00
}
// Carica un record in base ai campi chiave
bool TPaf_record : : search ( )
{
CHECKS ( _fields . items ( ) > 0 , " Can't search with empty key on table " , static_cast < const char * > ( _table ) ) ;
TString256 query ;
2018-10-08 17:40:11 +02:00
query < < " SELECT TOP 1 * FROM " < < _table < < " WHERE " ;
2018-07-25 15:53:29 +02:00
FOR_EACH_TOKEN ( _key , fld )
{
const TVariant & var = get ( fld ) ;
if ( ! var . is_null ( ) )
query < < fld < < ' = ' < < var2str ( fld , var ) < < " AND " ;
}
query . rtrim ( 5 ) ;
2018-10-08 17:40:11 +02:00
query < < " ORDER BY " ;
FOR_EACH_TOKEN ( _key , fld )
{
const TVariant & var = get ( fld ) ;
if ( ! var . is_null ( ) )
query < < fld < < " , " ;
}
2018-10-15 12:58:46 +02:00
query . rtrim ( 2 ) < < " DESC; " ;
2018-07-25 15:53:29 +02:00
// return xvt_sql_execute(_db, query, paf_search_record, this) == 1;
// TODO: Valutare
2018-10-08 11:45:08 +02:00
return fp_db ( ) . sq_set_exec ( query ) ;
2018-07-25 15:53:29 +02:00
}
// Carica un record in base ad un massimo di 3 campi chiave
bool TPaf_record : : search ( const char * k1 , const char * k2 , const char * k3 )
{
_fields . destroy ( ) ;
set ( _key . get ( 0 ) , k1 ) ;
set ( _key . get ( 1 ) , k2 ) ;
if ( k3 & & * k3 )
set ( _key . get ( 2 ) , k3 ) ;
return search ( ) ;
}
2018-07-31 16:01:13 +02:00
TString & TPaf_record : : insert_string ( )
2018-07-25 15:53:29 +02:00
{
2018-07-31 16:01:13 +02:00
CHECKS ( _fields . items ( ) > = _key . items ( ) , " Can't insert empty record on table " , _table ) ;
2019-01-25 14:47:19 +01:00
static TString query , values ;
query . cut ( 0 ) ; values . cut ( 0 ) ;
2018-07-31 16:01:13 +02:00
query < < " INSERT INTO " < < _table < < " \n ( " ;
FOR_EACH_ASSOC_OBJECT ( _fields , obj , fld , itm )
{
const TVariant & var = get ( fld ) ;
if ( ! var . is_null ( ) )
2018-07-25 15:53:29 +02:00
{
2018-07-31 16:01:13 +02:00
query < < fld < < ' , ' ;
values < < var2str ( fld , var ) < < ' , ' ;
2018-07-25 15:53:29 +02:00
}
2018-07-31 16:01:13 +02:00
}
query . rtrim ( 1 ) ;
values . rtrim ( 1 ) ;
query < < " ) \n VALUES ( " < < values < < " ); " ;
return query ;
}
// Aggiunge un record al db
bool TPaf_record : : insert ( )
{
2019-02-04 10:45:27 +01:00
return fp_db ( ) . sq_set_exec ( insert_string ( ) , false ) ;
2018-07-25 15:53:29 +02:00
}
// Crea un record della tabella data ed imposta i nomi dei campi chiave
TPaf_record : : TPaf_record ( const char * table ) : _table ( table ) , _key ( 15 , ' , ' )
{
TString q ;
q < < " SELECT col.[name] FROM sys.columns AS col \
inner JOIN sys . index_columns AS idx on col . [ object_id ] = idx . [ object_id ] AND col . [ column_id ] = idx . [ column_id ] \
inner join sys . indexes as K on idx . [ index_id ] = K . [ index_id ] \
where K . [ name ] = ' " << table << " _KEY ' \
AND idx . [ object_id ] = object_id ( ' " << table << " ' ) \
ORDER BY index_column_id ASC " ;
2018-10-08 11:45:08 +02:00
for ( bool ok = fp_db ( ) . sq_set_exec ( q ) ; ok ; ok = fp_db ( ) . sq_next ( ) )
2018-07-25 15:53:29 +02:00
{
2018-10-08 11:45:08 +02:00
_key . add ( fp_db ( ) . sq_get ( " name " ) ) ;
2018-07-25 15:53:29 +02:00
}
CHECKS ( ! _key . empty_items ( ) , " Invalid primary key for table " , table ) ;
}
/***************************************************************************
* TAncestor
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
struct TAncestor : public TObject
2018-07-06 16:30:37 +02:00
{
2018-07-25 15:53:29 +02:00
TString20 _numdoc ;
TDate _datadoc ;
TAncestor ( const TRectype & rdoc ) ;
} ;
TAncestor : : TAncestor ( const TRectype & rdoc )
{
const int anno = rdoc . get_int ( RDOC_ANNO ) ;
const TString4 codnum = rdoc . get ( RDOC_CODNUM ) ;
const long ndoc = rdoc . get_long ( RDOC_NDOC ) ;
const TCodice_numerazione & num = cached_numerazione ( codnum ) ;
TToken_string kdoc ;
kdoc = rdoc . get ( RDOC_PROVV ) ;
kdoc . add ( anno ) ;
kdoc . add ( codnum ) ;
kdoc . add ( ndoc ) ;
const TRectype & doc = cache ( ) . get ( LF_DOC , kdoc ) ;
TString16 numdoc ;
num . complete_num ( ndoc , numdoc ) ;
_numdoc . format ( " %d/%s/%s " , anno , static_cast < const char * > ( codnum ) , static_cast < const char * > ( numdoc ) ) ;
_datadoc = doc . get_date ( DOC_DATADOC ) ;
}
/***************************************************************************
* TDoc_fp
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool TDoc_fp : : parse_sconto ( const TString & formula , TToken_string & sconti ) const
{
sconti . cut ( 0 ) ;
int start = 0 ;
for ( int i = 0 ; ; i + + )
{
const char c = formula [ i ] ;
if ( c = = ' + ' | | c = = ' - ' | | c < ' ' )
{
if ( i > 0 )
{
TString8 tok = formula . sub ( start , i ) ;
tok . replace ( ' , ' , ' . ' ) ;
const real perc = tok ;
if ( ! perc . is_zero ( ) )
sconti . add ( tok ) ;
}
if ( c < ' ' )
break ;
start = i ;
}
}
return sconti . full ( ) ;
}
bool TDoc_fp : : get_bnp_iban ( const TString & abi , const TString & cab , int nprog , TString & iban )
{
TTable bnp ( " BNP " ) ;
TString16 key ;
key < < abi < < cab ;
if ( nprog > 0 )
{
TString4 sprog ;
sprog . format ( " %02d " , nprog ) ;
key < < sprog ;
}
bnp . put ( " CODTAB " , key ) ;
int err = bnp . read ( _isgteq ) ;
if ( err = = NOERR & & ! bnp . get ( " CODTAB " ) . starts_with ( abi ) )
err = _iskeynotfound ;
if ( err = = NOERR )
iban = bnp . get ( " S3 " ) ;
return err = = NOERR ;
}
2019-02-21 17:44:31 +01:00
bool TDoc_fp : : get_bank ( TDocumento & doc , TString & iban , TString & abi , TString & cab , TString & istituto ) const
2018-07-25 15:53:29 +02:00
{
2019-02-21 17:44:31 +01:00
bool found = false ;
if ( doc . pagamento ( ) . tipo_rata ( 0 ) = = TTipo_pag : : _bonfico )
{
found = get_bank_presentazione ( doc , iban , abi , cab , istituto ) ;
}
else if ( doc . pagamento ( ) . tipo_rata ( 0 ) = = TTipo_pag : : _ric_ban | | doc . pagamento ( ) . tipo_rata ( 0 ) = = TTipo_pag : : _rid )
{
found = get_bank_appoggio ( doc , iban , abi , cab , istituto ) ;
}
return found ;
}
bool TDoc_fp : : get_bank_presentazione ( const TDocumento & doc , TString & iban , TString & abi , TString & cab , TString & istituto ) const
{
bool found = false ;
abi = doc . get ( DOC_CODABIP ) ;
cab = doc . get ( DOC_CODCABP ) ;
int prg = doc . get_int ( DOC_PROGBNP ) ;
found = abi . full ( ) & & cab . full ( ) ;
if ( found )
get_bnp_iban ( abi , cab , prg , iban ) ;
if ( ! found ) // Se non trovo banca su CFBAN la cerco su CFVEN
{
const TRectype & cfven = doc . clifor ( ) . vendite ( ) ;
abi = cfven . get ( CFV_CODABIPR ) ;
cab = cfven . get ( CFV_CODCABPR ) ;
2018-07-25 15:53:29 +02:00
found = abi . full ( ) & & cab . full ( ) ;
if ( found )
2019-02-21 17:44:31 +01:00
get_bnp_iban ( abi , cab , 0 , iban ) ;
}
if ( found )
istituto = cache ( ) . get ( " %BAN " , abi , " S0 " ) ;
return found ;
}
bool TDoc_fp : : get_bank_appoggio ( const TDocumento & doc , TString & iban , TString & abi , TString & cab ,
TString & istituto ) const
{
bool found = false ;
abi = doc . get ( DOC_CODABIA ) ;
cab = doc . get ( DOC_CODCABA ) ;
iban = doc . get ( DOC_IBAN ) ;
found = iban . full ( ) ;
if ( ! found ) // Se non trovo banca sul DOC la cerco su CFBAN
{
TToken_string key ;
key . add ( " C " ) ;
key . add ( doc . codcf ( ) ) ;
key . add ( " N " ) ;
key . add ( 1 ) ;
const TRectype & cfban = cache ( ) . get ( LF_CFBAN , key ) ;
if ( ! cfban . empty ( ) )
2018-07-25 15:53:29 +02:00
{
2019-02-21 17:44:31 +01:00
abi = cfban . get ( CFBAN_ABI ) ;
cab = cfban . get ( CFBAN_CAB ) ;
found = abi . full ( ) & & cab . full ( ) ;
iban = cfban . get ( CFBAN_IBAN ) ;
if ( found & & iban . blank ( ) )
get_bnp_iban ( abi , cab , - 1 , iban ) ;
2018-07-25 15:53:29 +02:00
}
2019-02-21 17:44:31 +01:00
}
if ( found )
istituto = cache ( ) . get ( " %BAN " , abi , " S0 " ) ;
return found ;
2018-07-25 15:53:29 +02:00
}
2019-02-21 17:44:31 +01:00
2019-01-25 14:47:19 +01:00
const TString & TDoc_fp : : descrizione ( const TRiga_documento & rdoc )
2018-07-25 15:53:29 +02:00
{
2019-01-25 14:47:19 +01:00
if ( rdoc . get_bool ( RDOC_DESCLUNGA ) )
{
TString & tmp = get_tmp_string ( ) ;
tmp < < rdoc . get ( RDOC_DESCR ) < < rdoc . get ( RDOC_DESCEST ) ;
tmp . replace ( ' \n ' , ' ' ) ;
tmp . strip_double_spaces ( ) ;
tmp . trim ( ) ;
2019-01-28 10:43:18 +01:00
if ( tmp . len ( ) > 900 )
2018-07-25 15:53:29 +02:00
{
2019-01-25 14:47:19 +01:00
TString err ;
2019-01-28 10:43:18 +01:00
err < < " Il documento " < < rdoc . doc ( ) . anno ( ) < < " " < < rdoc . doc ( ) . codice_numerazione ( ) . codice ( ) < < " " < < rdoc . doc ( ) . numero ( ) < < " ha la riga numero " < < rdoc . numero ( ) < < " pi<70> lunga di quanto supportato dal formato dell'agenzia delle entrate, verr<72> troncata a 900 caratteri " ;
2019-01-25 14:47:19 +01:00
log ( 1 , err ) ;
2018-07-25 15:53:29 +02:00
}
2019-01-28 10:43:18 +01:00
return tmp . left ( 900 ) ;
2019-01-25 14:47:19 +01:00
}
return rdoc . get ( RDOC_DESCR ) ;
2018-07-25 15:53:29 +02:00
}
const TRectype * TDoc_fp : : find_parent_row ( const TRectype & rdoc ) const
{
const long id = rdoc . get_long ( RDOC_DAIDRIGA ) ;
if ( id > 0L )
{
TToken_string key ;
key . add ( rdoc . get ( RDOC_DACODNUM ) ) ;
if ( key . full ( ) )
{
key . add ( rdoc . get ( RDOC_DAANNO ) ) ;
key . add ( rdoc . get ( RDOC_DAPROVV ) ) ;
key . add ( rdoc . 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 ;
}
int TDoc_fp : : find_ancestors ( const TRiga_documento & rdoc , TArray & ancestors ) const
{
if ( rdoc . is_articolo ( ) )
{
for ( const TRectype * prdoc = find_parent_row ( rdoc ) ; prdoc ! = NULL ; prdoc = find_parent_row ( * prdoc ) )
{
const TCodice_numerazione & cn = cached_numerazione ( prdoc - > get ( RDOC_CODNUM ) ) ;
const int td = cn . tipo ( ) ;
if ( td > 0 & & ancestors . objptr ( td ) = = NULL )
ancestors . add ( new TAncestor ( * prdoc ) , td ) ;
}
}
return ancestors . items ( ) ;
}
2018-07-31 16:01:13 +02:00
bool TDoc_fp : : insert ( TPaf_record & p )
{
bool ok ;
if ( _cache_insert )
{
_query . push_back ( p . insert_string ( ) ) ;
ok = true ;
}
else
{
ok = p . insert ( ) ;
2018-10-05 15:37:12 +02:00
if ( ! ok )
2018-10-08 10:42:28 +02:00
{
2018-10-08 11:45:08 +02:00
log ( 2 , fp_db ( ) . sq_get_string_error ( ) ) ;
2018-10-08 10:42:28 +02:00
log ( 2 , p . insert_string ( ) ) ;
}
2018-07-31 16:01:13 +02:00
}
return ok ;
}
bool TDoc_fp : : remove ( TPaf_record & p )
{
bool ok ;
if ( _cache_insert )
{
_query . push_back ( p . remove_string ( ) ) ;
ok = true ;
}
else
{
ok = p . remove ( ) ;
2018-10-05 15:37:12 +02:00
if ( ! ok )
2018-10-08 10:42:28 +02:00
{
2018-10-08 11:45:08 +02:00
log ( 2 , fp_db ( ) . sq_get_string_error ( ) ) ;
2018-10-08 10:42:28 +02:00
log ( 2 , p . remove_string ( ) ) ;
}
2018-07-31 16:01:13 +02:00
}
return ok ;
}
bool TDoc_fp : : save_paf ( )
{
bool ok = true ;
if ( _cache_insert )
{
string query ;
for ( auto i = _query . begin ( ) ; i ! = _query . end ( ) ; + + i )
query + = * i ;
2018-10-08 11:45:08 +02:00
ok = fp_db ( ) . sq_set_exec ( query ) ;
2018-10-05 15:37:12 +02:00
if ( ! ok )
2018-10-08 10:42:28 +02:00
{
2018-10-08 11:45:08 +02:00
log ( 2 , fp_db ( ) . sq_get_string_error ( ) ) ;
2018-10-08 10:42:28 +02:00
log ( 2 , query . c_str ( ) ) ;
}
2018-07-31 16:01:13 +02:00
}
return ok ;
}
2019-02-05 16:23:20 +01:00
2019-02-21 17:44:31 +01:00
bool TDoc_fp : : check_initial ( TDocumentoEsteso & doc )
{
bool ok = true ;
static TString msg ;
if ( _coddest . len ( ) ! = 6 & & _coddest . len ( ) ! = 7 )
{
log ( 1 , " Il codice destinatario ha una lunghezza non conforme. " ) ;
ok = false ;
}
if ( _rec_clifo . get ( CLI_PAIV ) . empty ( ) & & _rec_clifo . get ( CLI_COFI ) . empty ( ) )
{
log ( 1 , " Sia la partita IVA che il codice fiscale del cessionario committente sono vuoti, almeno uno dei due deve essere valorizzato. " ) ;
ok = false ;
}
TPagamento & pag = doc . pagamento ( ) ;
if ( pag . cond_pag_sdi ( ) . empty ( ) )
{
msg . cut ( 0 ) < < " Non <20> valorizzata la condizione di pagamento SDI (TP01, TP02, TP03) per la condizione di pagamento " < < pag . code ( ) ;
log ( 1 , msg ) ;
ok = false ;
}
for ( int nr = 0 ; nr < doc . scadenze ( ) . items ( ) ; nr + + )
{
const int rp = nr < pag . n_rate ( ) ? nr : 0 ;
static TString key_class ; key_class . cut ( 0 ) < < pag . tipo_rata ( rp ) < < pag . ulc_rata ( rp ) ;
if ( cache ( ) . get ( " %CLR " , key_class , " S12 " ) . empty ( ) )
{
msg . cut ( 0 ) < < " Non <20> valorizzata la tipologia di pagamento SDI (MPXX) per la condizione di pagamento " < < pag . code ( ) ;
log ( 1 , msg ) ;
ok = false ;
}
}
return ok ;
}
bool TDoc_fp : : check_row ( const TRiga_documento & rdoc )
{
bool ok = false ;
static TString msg ;
if ( rdoc . is_spese ( ) )
{
const TSpesa_prest & spesa = rdoc . spesa ( ) ;
if ( spesa . perc ( ) . is_zero ( ) )
{
msg . cut ( 0 ) < < " <EFBFBD> corretto che per la spesa " < < spesa . codice ( ) < < " la percentuale sia zero? " ;
log ( 1 , msg ) ;
}
}
const TCodiceIVA & codice_iva = rdoc . iva ( ) ;
if ( codice_iva . codice ( ) . full ( ) & & codice_iva . percentuale ( ) = = ZERO & & codice_iva . natura ( ) . empty ( ) )
{
msg . cut ( 0 ) < < " Impossibile avere la natura non valorizzata a fronte di una aliquota con percentuale zero. Codice IVA: " ; msg < < codice_iva . codice ( ) ;
log ( 1 , msg ) ;
ok = false ;
}
return ok ;
}
bool TDoc_fp : : check_riepilogo ( const TDocumentoEsteso & doc , const TRiepilogo_iva & riva )
{
bool ok = true ;
static TString msg ;
if ( * get_esigibilita_iva ( doc ) = = ' S ' & & riva . cod_iva ( ) . natura ( ) = = " N6 " )
{
msg . cut ( 0 ) < < " Impossibile avere un documento con scissione dei pagamenti e natura iva N6, codice: " < < riva . cod_iva ( ) . codice ( ) ;
log ( 1 , msg ) ;
ok = false ;
}
return ok ;
}
bool TDoc_fp : : initialize ( TDocumentoEsteso & doc )
2019-02-05 16:23:20 +01:00
{
// Azzero
_hfatt . cut ( 0 ) ;
_bfatt . cut ( 0 ) ;
// Preparo il record del cliente
_rec_clifo = cache ( ) . get ( LF_CLIFO , TString ( ) < < doc . tipocf ( ) < < " | " < < doc . codcf ( ) ) ;
// Valorizzo la gestione del cambio
_doc_cambio . _cod_val = doc . valuta ( ) ;
_doc_cambio . _is_valuta_estera = doc . valuta ( ) . full ( ) & & ! is_euro_value ( doc . valuta ( ) ) ;
_doc_cambio . _cambio = doc . cambio ( ) ;
// Paese del documento
_paese = " IT " ;
_has_bolla = false ;
if ( ! chiave_paf ( doc , _hfatt , _bfatt ) )
return false ;
// Preparo il log
log ( - 1 , _bfatt ) ;
# ifndef DBG
// Controllo se il documento <20> almeno in stato di stampa
if ( doc . stato ( ) < doc . tipo ( ) . stato_finale_stampa ( ) )
{
log ( 3 , " Il documento non <20> stato ancora stampato, verr<72> saltato " ) ;
return false ;
}
# endif
# ifndef DBG
_is_pa = doc . clifor ( ) . get_int ( " ALLEG " ) = = 7 ;
if ( ! get_coddest ( doc . clifor ( ) . tipo ( ) , doc . clifor ( ) . codice ( ) , _coddest , _pec ) )
2019-02-21 17:44:31 +01:00
{
log ( 1 , " Impossibile trovare il codice destinatario per la fattura " ) ;
2019-02-05 16:23:20 +01:00
return false ;
2019-02-21 17:44:31 +01:00
}
2019-02-05 16:23:20 +01:00
# else
_is_pa = true ;
_coddest = " WSUHKZ " ;
# endif
_enapec = _coddest = = " 0000000 " & & _pec . full ( ) ;
_privato = _coddest . len ( ) ! = 6 ;
_caus = TCausale ( doc . tipo ( ) . causale ( ) , doc . anno ( ) ) ;
2019-02-06 10:47:01 +01:00
// Preparo il codice iva di default
{
FOR_EACH_PHYSICAL_RDOC ( doc , r , rdoc )
{
_codivadefault = rdoc - > get ( RDOC_CODIVA ) ;
if ( _codivadefault . full ( ) )
break ;
}
}
2019-02-06 10:47:23 +01:00
// Azzero indici
_index_cassa_previdenziale = 1 ;
2019-02-21 17:44:31 +01:00
return check_initial ( doc ) | | fp_settings ( ) . get_check_not_block ( ) ;
2019-02-05 16:23:20 +01:00
}
2018-07-25 15:53:29 +02:00
const TRectype & TDoc_fp : : cco ( const TRectype & doc ) const
{
TString80 conkey ;
const TString & con = doc . get ( DOC_CONTRATTO ) ;
if ( con . full ( ) )
{
char tcon = doc . get_char ( DOC_MODPAG ) ;
if ( tcon < ' C ' ) tcon = ' C ' ;
2018-10-04 18:10:17 +02:00
conkey . format ( " %c%6ld%s " , tcon , doc . get_long ( DOC_CODCF ) , static_cast < const char * > ( con ) ) ;
2018-07-25 15:53:29 +02:00
}
return cache ( ) . get ( " &CON " , conkey ) ;
}
void TDoc_fp : : log ( int severity , const char * msg )
{
2018-10-04 18:10:17 +02:00
if ( _log = = nullptr )
{
_log = new TLog_report ;
2018-12-11 14:21:01 +01:00
// Tento l'eliminazione del file
std : : remove ( " fp_err.log " ) ;
2018-10-04 18:10:17 +02:00
}
if ( severity < 0 )
{
_logpaf = msg ;
}
else
{
2018-12-11 14:21:01 +01:00
static TString txt ;
txt . cut ( 0 ) ;
2018-10-04 18:10:17 +02:00
if ( _logpaf . full ( ) )
2018-07-25 15:53:29 +02:00
{
2018-10-04 18:10:17 +02:00
txt < < _logpaf < < " : " < < msg ;
2018-07-25 15:53:29 +02:00
}
2018-10-04 18:10:17 +02:00
else
2018-12-11 14:21:01 +01:00
txt < < msg ;
_log - > log ( severity , txt ) ;
// Scrivo anche su file
std : : filebuf fb ;
fb . open ( " fp_err.log " , std : : ios : : out | std : : ios : : app ) ;
std : : ostream os ( & fb ) ;
os < < txt < < std : : endl ;
fb . close ( ) ;
2018-10-04 18:10:17 +02:00
}
2018-07-25 15:53:29 +02:00
}
bool TDoc_fp : : show_log ( )
{
if ( _log )
{
_log - > preview ( ) ;
delete _log ;
_log = NULL ;
}
return true ;
}
2019-02-04 10:45:27 +01:00
2018-07-25 15:53:29 +02:00
const int TDoc_fp : : commit ( )
{
int r = 0 ;
if ( _to_commit )
{
2018-10-08 11:45:08 +02:00
if ( fp_db ( ) . sq_set_exec ( " UPDATE PAF0100F SET P1_GESTIONE = 'P' WHERE P1_GESTIONE = 'D' " ) & & fp_db ( ) . sq_commit ( ) )
2018-07-25 15:53:29 +02:00
{
r = 1 ;
}
else
{
r = - 1 ;
2018-10-08 11:45:08 +02:00
log ( 2 , fp_db ( ) . sq_get_string_error ( ) ) ;
2018-10-08 10:42:28 +02:00
log ( 2 , " UPDATE PAF0100F SET P1_GESTIONE = 'P' WHERE P1_GESTIONE = 'D' " ) ;
2018-07-25 15:53:29 +02:00
}
}
_to_commit = false ;
return r ;
}
2019-02-04 10:45:27 +01:00
2019-01-25 14:47:19 +01:00
const int TDoc_fp : : force_commit ( )
{
_to_commit = true ;
return commit ( ) ;
}
2019-02-04 10:45:27 +01:00
2018-07-25 15:53:29 +02:00
const char * TDoc_fp : : natura ( const TString & codiva ) const
{
return cache ( ) . get ( " %IVA " , codiva , " S12 " ) ;
}
2019-02-04 10:45:27 +01:00
2019-02-21 17:44:31 +01:00
const char * TDoc_fp : : get_esigibilita_iva ( const TDocumentoEsteso & doc )
{
// Esigibilit<69> IVA: Immediata, Differita, Split payment
const char * eiva = " I " ;
if ( doc . is_split_payment ( ) )
eiva = " S " ;
else if ( doc . get_bool ( DOC_LIQDIFF ) | | doc . get_bool ( DOC_IVAXCASSA ) )
eiva = " D " ;
return eiva ;
}
2019-02-06 10:47:01 +01:00
void TDoc_fp : : set_IVA ( TString codiva , TPaf_record & paf ) const
2018-07-25 15:53:29 +02:00
{
2019-02-06 10:47:01 +01:00
if ( codiva . empty ( ) )
codiva = _codivadefault ;
// <20> necessario il cast a real?
paf . set ( " PI_ALIQUOTAIVA " , static_cast < real > ( cache ( ) . get ( " %IVA " , codiva , " R0 " ) ) ) ;
paf . set ( " PI_NATURA " , natura ( codiva ) ) ;
2018-07-25 15:53:29 +02:00
}
2019-02-04 10:45:27 +01:00
2019-02-06 10:47:01 +01:00
void TDoc_fp : : set_IVA ( const TRiga_documento & rdoc , TPaf_record & paf ) const
2018-07-25 15:53:29 +02:00
{
set_IVA ( rdoc . get ( RDOC_CODIVA ) , paf ) ;
}
2019-02-05 16:23:20 +01:00
bool TDoc_fp : : add_row_art ( long & riga_art , const TString & codice_tipo , const TString & codice_valore , TPaf_record & paf )
2018-07-25 15:53:29 +02:00
{
paf . set ( " PY_KEYNLINAR " , + + riga_art ) ;
paf . set ( " PY_TIPOARTICOLO " , codice_tipo ) ;
paf . set ( " PY_VALOREARTICOLO " , codice_valore ) ;
2018-07-31 16:01:13 +02:00
const bool ok = insert ( paf ) ;
2018-07-25 15:53:29 +02:00
return ok ;
}
2018-07-31 16:01:13 +02:00
bool TDoc_fp : : add_row_alleg ( TFilename & file , long & nprogr , TPaf_record & paf )
{
static TString dest_path ;
static TString dest_usr_path ;
bool ok = false ;
dest_path . cut ( 0 ) < < _def_fld < < file . name ( ) ;
dest_usr_path . cut ( 0 ) < < _def_usr_fld < < file . name ( ) ;
if ( ! fcopy ( file , dest_usr_path ) )
{
return yesno_box ( " Errore critico nel copiare il file %s, si desidera continuare? " , file . name ( ) ) ;
}
// Provo a copiare il file
paf . set ( " PP_NUMEROLINEA " , + + nprogr ) ;
paf . set ( " PP_NOMEATTACHMENT " , file . name ( ) ) ;
paf . set ( " PP_ATTACHMENT " , dest_path ) ;
file . upper ( ) ; // serve estensione maiuscola
paf . set ( " PP_FMTATTACHMENT " , file . ext ( ) ) ;
ok = insert ( paf ) ;
return ok ;
}
2018-12-10 14:23:41 +01:00
const TString & TDoc_fp : : converti_prezzo ( const real & prezzo ) const
{
TString & ret = get_tmp_string ( ) ;
ret . cut ( 0 ) ;
2018-12-11 14:21:01 +01:00
if ( _doc_cambio . _is_valuta_estera )
2018-12-10 14:23:41 +01:00
{
2018-12-11 14:21:01 +01:00
TCurrency app ( prezzo , _doc_cambio . _cod_val , _doc_cambio . _cambio , true ) ;
app . change_to_euro_val ( ) ;
2018-12-22 11:38:31 +01:00
ret < < app . get_num ( ) . string ( 0 , 8 ) ;
2018-12-10 14:23:41 +01:00
}
else
ret < < prezzo ;
return ret ;
}
2019-01-02 14:48:09 +01:00
void TDoc_fp : : set_qta_prezzo ( TPaf_record & paf1800f , TRiga_documento * rdoc ) const
2018-12-14 12:10:42 +01:00
{
2019-01-02 14:48:09 +01:00
// Setto l'unit<69> di misura
paf1800f . set ( " PI_UNITAMISURA " , rdoc - > get ( RDOC_UMQTA ) ) ;
2019-02-15 11:38:50 +01:00
static TFP_righe_custom righe_custom ;
const TString field_qta = righe_custom . get_qta ( rdoc - > tipo ( ) . codice ( ) , rdoc - > doc ( ) . tipo ( ) . codice ( ) ) ;
const TString field_prezzo = righe_custom . get_prezzo ( rdoc - > tipo ( ) . codice ( ) , rdoc - > doc ( ) . tipo ( ) . codice ( ) ) ;
const TString field_imponibile = righe_custom . get_imponibile ( rdoc - > tipo ( ) . codice ( ) , rdoc - > doc ( ) . tipo ( ) . codice ( ) ) ;
const bool custom_prezzo = field_prezzo ! = RDOC_PREZZO ;
real qta = rdoc - > get_real ( field_qta ) ;
2019-01-18 21:30:23 +01:00
// Prendendo la stringa non ho problemi in scrittura della query, a volte accadono cose stupide
2019-02-15 11:38:50 +01:00
const TString & qta_string = rdoc - > get ( field_qta ) ;
2019-01-14 14:24:29 +01:00
real prezzo_unit ;
real prezzo_tot ;
2018-12-14 12:10:42 +01:00
if ( qta > = ZERO )
{
2019-01-14 14:24:29 +01:00
if ( qta = = ZERO )
qta = UNO ;
2019-01-18 21:30:23 +01:00
paf1800f . set ( " PI_QUANTITA " , qta_string ) ;
2019-02-15 11:38:50 +01:00
if ( custom_prezzo )
{
prezzo_unit = rdoc - > get_real ( field_prezzo ) ;
prezzo_tot = rdoc - > get_real ( field_imponibile ) ;
}
else
{
prezzo_unit = rdoc - > prezzo ( false , false , 8 ) ;
prezzo_tot = rdoc - > importo ( true , false ) ;
}
2018-12-14 12:10:42 +01:00
}
2019-01-14 14:24:29 +01:00
else if ( qta < ZERO )
2018-12-14 12:10:42 +01:00
{
2019-01-18 21:30:23 +01:00
// Metto la qualit<69> senza il segno
paf1800f . set ( " PI_QUANTITA " , qta_string . mid ( 1 ) ) ;
// E i prezzi in negativo, perch<63> l'importo non ha lo stesso segno del prezzo?
2019-02-15 11:38:50 +01:00
if ( custom_prezzo )
{
prezzo_unit = - abs ( rdoc - > get_real ( field_prezzo ) ) ;
prezzo_tot = - abs ( rdoc - > get_real ( field_imponibile ) ) ;
}
else
{
prezzo_unit = - abs ( rdoc - > prezzo ( false , false , 8 ) ) ;
prezzo_tot = - abs ( rdoc - > importo ( true , false ) ) ;
}
2018-12-14 12:10:42 +01:00
}
2019-01-14 14:24:29 +01:00
// Salvo tutto
paf1800f . set ( " PI_PREZZOUNIT " , converti_prezzo ( prezzo_unit ) ) ;
paf1800f . set ( " PI_PRZTOTALE " , converti_prezzo ( prezzo_tot ) ) ;
2018-12-14 12:10:42 +01:00
}
2019-02-05 16:23:20 +01:00
2019-02-06 10:47:23 +01:00
const real calc_ritenuta ( const TDocumento & doc )
2018-07-25 15:53:29 +02:00
{
2019-02-05 16:23:20 +01:00
real imponibile_prestazioni = ZERO ;
2018-11-28 16:28:33 +01:00
{
2019-02-05 16:23:20 +01:00
FOR_EACH_PHYSICAL_RDOC ( doc , r , rdoc )
{
if ( rdoc - > is_prestazione ( ) )
imponibile_prestazioni + = rdoc - > imponibile ( ) ;
}
2018-11-28 16:28:33 +01:00
}
2019-02-05 16:23:20 +01:00
real imponibile = imponibile_prestazioni ;
{
// Riciclo per sommare la % delle spese da sommare
FOR_EACH_PHYSICAL_RDOC ( doc , r , rdoc )
{
2019-02-06 10:47:23 +01:00
if ( rdoc - > is_spese ( ) & & rdoc - > spesa ( ) . spe_cal_rit ( ) )
2019-02-05 16:23:20 +01:00
imponibile + = imponibile * rdoc - > spesa ( ) . perc ( ) / CENTO ;
}
}
2019-02-06 10:47:23 +01:00
return imponibile ;
}
void TDoc_fp : : add_ritenuta ( const TDocumentoEsteso & doc , const TSpesa_prest & sp , TPaf_record & paf0700f ) const
{
// <DatiRitenuta>
paf0700f . set ( " P7_TIPORITENUTA " , _rec_clifo . get_char ( CLI_TIPOPERS ) = = ' F ' ? " RT01 " : " RT02 " ) ;
TString doc_imponibile = doc . imponibile ( ) . string ( ) ;
const real imponibile = calc_ritenuta ( doc ) ;
2019-02-05 16:23:20 +01:00
paf0700f . set ( " P7_IMPORTORIT " , converti_prezzo ( imponibile * sp . perc ( ) / CENTO ) ) ;
paf0700f . set ( " P7_ALIQUOTARIT " , sp . perc ( ) ) ;
static TString caus_la ; caus_la . cut ( 0 ) ;
caus_la < < sp . get ( " S14 " ) ;
if ( caus_la . empty ( ) )
{
2019-02-06 10:47:23 +01:00
caus_la < < sp . rec_caus_770 ( ) . get ( " S2 " ) ;
2019-02-05 16:23:20 +01:00
}
paf0700f . set ( " P7_CAUSPAGAM " , caus_la ) ;
// </DatiRitenuta>
}
2019-02-06 10:47:01 +01:00
bool TDoc_fp : : add_riepilogo_iva ( TPaf_record & paf2200f , const TCodiceIVA & cod_iva , const char * eiva , const real & imponibile ,
const real & imposta )
{
paf2200f . reset ( ) ;
paf2200f . set ( " PL_KEYHEADERFATT " , _hfatt ) ;
paf2200f . set ( " PL_KEYBODYFATT " , _bfatt ) ;
const real aliquota = cod_iva . percentuale ( ) ;
const TString & cod_aliquota = cod_iva . codice ( ) ;
TRiepilogo_agg & riepilogo_agg = _riepilogo_agg [ cod_aliquota ] ;
// Aliquota
paf2200f . set ( " PL_ALIQUOTAIVA " , aliquota ) ;
// Natura
if ( aliquota . is_zero ( ) )
paf2200f . set ( " PL_NATURA " , natura ( cod_aliquota ) ) ;
// Imponibile
paf2200f . set ( " PL_IMPONIBILE " , converti_prezzo ( imponibile + riepilogo_agg . imponibile ) ) ;
2019-02-06 10:47:23 +01:00
// Imposta
paf2200f . set ( " PL_IMPOSTA " , converti_prezzo ( imposta + riepilogo_agg . imposta ) ) ;
2019-02-06 10:47:01 +01:00
// Esigibilit<69> IVA
paf2200f . set ( " PL_ESIGIVA " , eiva ) ;
if ( * eiva = = ' S ' )
paf2200f . set ( " PL_RIFNORMATIVO " , " Scissione pagamenti art.17-ter DPR 633/72 " ) ;
else
paf2200f . set ( " PL_RIFNORMATIVO " , cod_iva . descrizione ( ) ) ;
paf2200f . set ( " PL_GESTIONE " , " D " ) ;
// Elimino l'oggetto
_riepilogo_agg . erase ( cod_aliquota ) ;
// Inserisco
return insert ( paf2200f ) ;
}
2019-02-06 10:47:23 +01:00
bool TDoc_fp : : add_cassa_previdenziale ( TRiga_documento & rdoc )
{
static TPaf_record paf0800f ( " PAF0800F " ) ;
paf0800f . reset ( ) ;
if ( _index_cassa_previdenziale = = 1 )
{
paf0800f . set ( " P8_KEYHEADERFATT " , _hfatt ) ;
paf0800f . set ( " P8_KEYBODYFATT " , _bfatt ) ;
remove ( paf0800f ) ;
}
// Chiavi
paf0800f . set ( " P8_KEYHEADERFATT " , _hfatt ) ;
paf0800f . set ( " P8_KEYBODYFATT " , _bfatt ) ;
paf0800f . set ( " P8_RIFNUMLINEA " , _index_cassa_previdenziale + + ) ;
// Resto
const TSpesa_prest & sp = rdoc . spesa ( ) ;
const real imponibile_ritenuta = calc_ritenuta ( rdoc . doc ( ) ) ;
const real importo_cassa = imponibile_ritenuta * sp . perc ( ) / CENTO ;
paf0800f . set ( " P8_TIPOCASSA " , sp . cassa_previdenziale ( ) ) ;
// Aliquota della cassa
paf0800f . set ( " P8_ALIQCASSA " , sp . perc ( ) ) ;
// Importo contributo cassa
paf0800f . set ( " P8_IMCONTRCASSA " , converti_prezzo ( importo_cassa ) ) ;
// Imponibile cassa
paf0800f . set ( " P8_IMPONCASSA " , converti_prezzo ( imponibile_ritenuta ) ) ;
// Aliquota applicata alla riga spesa
paf0800f . set ( " P8_ALIQIVA " , rdoc . iva ( ) . percentuale ( ) ) ;
if ( sp . sogg_a_rit ( ) )
paf0800f . set ( " P8_RITENUTA " , " SI " ) ;
paf0800f . set ( " P8_NATURA " , rdoc . iva ( ) . natura ( ) ) ;
// Inserisco il tutto nei dati riepilogo
TRiepilogo_agg & pop = _riepilogo_agg [ rdoc . iva ( ) . codice ( ) ] ;
pop . imponibile + = importo_cassa ;
pop . imposta + = importo_cassa * rdoc . iva ( ) . percentuale ( ) / CENTO ;
return insert ( paf0800f ) ;
}
2019-02-05 16:23:20 +01:00
const TFirm & TDoc_fp : : get_firm ( )
{
return prefix ( ) . firm ( ) ;
}
bool TDoc_fp : : export_paf0100f ( )
{
2018-07-25 15:53:29 +02:00
// <DatiTrassmissione>
TPaf_record paf0100f ( " PAF0100F " ) ;
2018-10-19 12:20:19 +02:00
paf0100f . set ( " P1_KEYHEADERFATT " , _hfatt ) ;
paf0100f . set ( " P1_KEYBODYFATT " , _bfatt ) ;
2018-07-31 16:01:13 +02:00
remove ( paf0100f ) ;
2019-02-05 16:23:20 +01:00
paf0100f . set ( " P1_TRASMITTPAESE " , _paese ) ;
2018-07-25 15:53:29 +02:00
paf0100f . set ( " P1_TRASMITTCOD " , _cofi ) ;
2019-02-05 16:23:20 +01:00
paf0100f . set ( " P1_FMTTRASMISS " , _privato ? " FPR12 " : " FPA12 " ) ; // SDI11 si usa dal 2015 per lo split payment (prima era SDI10)
paf0100f . set ( " P1_CODDEST " , _coddest ) ;
2018-07-25 15:53:29 +02:00
TString80 tel ;
2019-02-05 16:23:20 +01:00
tel < < get_firm ( ) . get ( NDT_PTEL ) < < get_firm ( ) . get ( NDT_TEL ) ;
2018-07-25 15:53:29 +02:00
paf0100f . set ( " P1_TELEFONO " , tel ) ;
2019-02-05 16:23:20 +01:00
paf0100f . set ( " P1_MAIL " , get_firm ( ) . get ( NDT_MAIL ) ) ;
2018-07-25 15:53:29 +02:00
paf0100f . set ( " P1_GESTIONE " , " D " ) ;
2019-02-21 17:44:31 +01:00
paf0100f . set ( " P1_ERRINT " , " " ) ;
2018-07-25 15:53:29 +02:00
// </DatiTrassmissione>
2019-02-05 16:23:20 +01:00
return insert ( paf0100f ) ;
}
bool TDoc_fp : : export_paf3200f ( )
{
if ( _enapec )
2018-07-25 15:53:29 +02:00
{
2019-02-05 16:23:20 +01:00
// <Datipec>
TPaf_record paf3200f ( " PAF3200F " ) ;
paf3200f . set ( " PU_KEYHEADERFATT " , _hfatt ) ;
paf3200f . set ( " PU_KEYBODYFATT " , _bfatt ) ;
remove ( paf3200f ) ;
paf3200f . set ( " PU_PEC " , _pec ) ;
// </Datipec>
return insert ( paf3200f ) ;
2018-07-25 15:53:29 +02:00
}
2019-02-05 16:23:20 +01:00
return true ;
}
bool TDoc_fp : : doc_to_paf ( TDocumentoEsteso & doc )
{
if ( ! initialize ( doc ) )
return false ;
bool ok = true ;
ok & = export_paf0100f ( ) ;
# ifndef DBG
ok & = export_paf3200f ( ) ;
2018-11-28 16:28:33 +01:00
# endif
2019-02-05 16:23:20 +01:00
2018-07-25 15:53:29 +02:00
// <CedentePrestatore>
TPaf_record paf0200f ( " PAF0200F " ) ;
2018-10-19 12:20:19 +02:00
paf0200f . set ( " P2_KEYHEADERFATT " , _hfatt ) ;
paf0200f . set ( " P2_KEYBODYFATT " , _bfatt ) ;
2018-07-31 16:01:13 +02:00
remove ( paf0200f ) ;
2018-07-25 15:53:29 +02:00
if ( _ditta . partita_IVA ( ) . full ( ) )
{
paf0200f . set ( " P2_FISCIVAPAESE " , _ditta . stato_partita_IVA ( ) ) ;
paf0200f . set ( " P2_FISCIVACOD " , _ditta . partita_IVA ( ) ) ;
}
paf0200f . set ( " P2_CODFISCALE " , _ditta . codice_fiscale ( ) ) ;
if ( _ditta . fisica ( ) )
{
paf0200f . set ( " P2_ANANOME " , _ditta . nome ( ) ) ;
paf0200f . set ( " P2_ANACOGNOME " , _ditta . cognome ( ) ) ;
}
else
{
paf0200f . set ( " P2_ANADENOMIN " , _ditta . ragione_sociale ( ) ) ;
}
paf0200f . set ( " P2_REGFISCALE " , doc . tipo ( ) . reg_fisc ( ) ) ;
// DatiSede
paf0200f . set ( " P2_SEDEIND " , _ditta . via_residenza ( ) ) ;
2019-01-25 09:56:13 +01:00
paf0200f . set ( " P2_SEDENRCIVICO " , _ditta . civico_residenza ( ) . left ( 8 ) ) ;
2018-07-25 15:53:29 +02:00
paf0200f . set ( " P2_SEDECAP " , _ditta . CAP_residenza ( ) ) ;
paf0200f . set ( " P2_SEDECOMUNE " , _ditta . comune_residenza ( ) ) ;
paf0200f . set ( " P2_SEDEPROV " , _ditta . provincia_residenza ( ) ) ;
2019-02-05 16:23:20 +01:00
paf0200f . set ( " P2_SEDENAZ " , _paese ) ;
2018-07-25 15:53:29 +02:00
paf0200f . set ( " P2_GESTIONE " , " D " ) ;
TAnagrafica cliente ( doc . clifor ( ) ) ;
TString rifamm = cco ( doc ) . get ( " S4 " ) ;
if ( rifamm . blank ( ) )
rifamm = doc . clifor ( ) . vendite ( ) . get ( CFV_PARIFAMM ) ;
paf0200f . set ( " P2_RIFAMMINISTR " , rifamm ) ;
paf0200f . set ( " P2_ISCRREASOCIOU " , _ditta . sociounico ( ) = = ' S ' ? " SU " : " SM " ) ;
TISAM_recordset unloc ( " USE UNLOC \n JOIN COMUNI INTO COM==COMCCIAA \n FROM CODDITTA=#DITTA \n TO CODDITTA=#DITTA " ) ;
2019-02-05 16:23:20 +01:00
unloc . set_var ( " #DITTA " , get_firm ( ) . get ( NDT_CODDITTA ) ) ;
2018-07-25 15:53:29 +02:00
if ( unloc . move_first ( ) )
{
const TString & numrea = unloc . get ( ULC_NUMCCIAA ) . as_string ( ) ;
if ( numrea . full ( ) )
{
paf0200f . set ( " P2_ISCRREANUM " , numrea ) ;
paf0200f . set ( " P2_ISCRREAUFF " , unloc . get ( " 13-> " COM_PROVCOM ) ) ;
}
}
if ( _ditta . giuridica ( ) )
{
TISAM_recordset anagiu ( " USE ANAGIU \n FROM CODANAGR=#CODICE \n TO CODANAGR=#CODICE " ) ;
2019-02-05 16:23:20 +01:00
anagiu . set_var ( " #CODICE " , get_firm ( ) . get ( NDT_CODANAGR ) ) ;
2018-07-25 15:53:29 +02:00
if ( anagiu . move_first ( ) )
{
paf0200f . set ( " P2_ISCRREACAP " , anagiu . get ( ANG_CAPSOC ) ) ;
const int ss = anagiu . get ( ANG_STATOSOC ) . as_int ( ) ;
paf0200f . set ( " P2_ISCRREASLIQUID " , ( ss = = 2 | | ss = = 3 ) ? " LS " : " LN " ) ;
}
}
else
paf0200f . set ( " P2_ISCRREASLIQUID " , " LN " ) ;
2018-07-31 16:01:13 +02:00
ok & = insert ( paf0200f ) ;
2018-07-25 15:53:29 +02:00
// </CedentePrestatore>
// <CessionarioCommittente>
TPaf_record paf0400f ( " PAF0400F " ) ;
2018-10-19 12:20:19 +02:00
paf0400f . set ( " P4_KEYHEADERFATT " , _hfatt ) ;
paf0400f . set ( " P4_KEYBODYFATT " , _bfatt ) ;
2018-07-31 16:01:13 +02:00
remove ( paf0400f ) ;
2018-11-28 16:28:33 +01:00
# ifndef DBG
2018-07-25 15:53:29 +02:00
if ( cliente . partita_IVA ( ) . full ( ) )
{
paf0400f . set ( " P4_FISCIVAPAESE " , cliente . stato_partita_IVA ( ) ) ;
paf0400f . set ( " P4_FISCIVACOD " , cliente . partita_IVA ( ) ) ;
}
paf0400f . set ( " P4_CODFISC " , cliente . codice_fiscale ( ) ) ;
2018-11-28 16:28:33 +01:00
# else
paf0400f . set ( " P4_FISCIVAPAESE " , " IT " ) ;
paf0400f . set ( " P4_FISCIVACOD " , " 00261170039 " ) ;
# endif
2019-01-30 13:08:34 +01:00
if ( cliente . fisica ( ) & & cliente . nome ( ) . full ( ) )
2018-07-25 15:53:29 +02:00
{
paf0400f . set ( " P4_ANANOME " , cliente . nome ( ) ) ;
paf0400f . set ( " P4_ANACOGNOME " , cliente . cognome ( ) ) ;
}
else
{
paf0400f . set ( " P4_ANADENOM " , cliente . ragione_sociale ( ) ) ;
}
// DatiSede
2018-10-15 12:58:46 +02:00
2019-01-18 21:30:23 +01:00
paf0400f . set ( " P4_SEDEIND " , cliente . via_residenza ( ) ) ;
2019-01-25 09:56:13 +01:00
paf0400f . set ( " P4_SEDENRCIVICO " , cliente . civico_residenza ( ) . left ( 8 ) ) ;
2019-01-18 21:30:23 +01:00
paf0400f . set ( " P4_SEDECOMUNE " , cliente . comune_residenza ( ) ) ;
paf0400f . set ( " P4_SEDENAZ " , cliente . stato_residenza_ISO ( ) ) ;
// I clienti esteri possono avere CAP alfanumerici, li tolgo
if ( cliente . stato_residenza_ISO ( ) ! = " IT " )
{
paf0400f . set ( " P4_SEDECAP " , " 00000 " ) ;
}
else
{
2018-10-15 12:58:46 +02:00
paf0400f . set ( " P4_SEDECAP " , cliente . CAP_residenza ( ) ) ;
2019-01-18 21:30:23 +01:00
paf0400f . set ( " P4_SEDEPROV " , cliente . provincia_residenza ( ) ) ;
}
2018-07-25 15:53:29 +02:00
paf0400f . set ( " P4_GESTIONE " , " D " ) ;
2018-07-31 16:01:13 +02:00
ok & = insert ( paf0400f ) ;
2018-07-25 15:53:29 +02:00
// </CessionarioCommittente>
// <DatiGenerali>
TPaf_record paf0700f ( " PAF0700F " ) ;
2018-10-19 12:20:19 +02:00
paf0700f . set ( " P7_KEYHEADERFATT " , _hfatt ) ;
paf0700f . set ( " P7_KEYBODYFATT " , _bfatt ) ;
2018-07-31 16:01:13 +02:00
remove ( paf0700f ) ;
2018-12-04 10:28:27 +01:00
paf0700f . set ( " P7_TIPODOC " , tipo_doc_sdi ( doc ) ) ;
2019-01-10 14:11:28 +01:00
paf0700f . set ( " P7_DIVISA " , " EUR " ) ; // Fisso su euro in quanto effettuiamo il cambio
2018-07-25 15:53:29 +02:00
paf0700f . set ( " P7_DATA " , doc . data ( ) ) ;
2019-01-17 14:14:09 +01:00
paf0700f . set ( " P7_NUMERO " , complete_num_fp ( doc . codice_numerazione ( ) , doc . numero ( ) ) ) ;
2018-07-25 15:53:29 +02:00
paf0700f . set ( " P7_GESTIONE " , " D " ) ;
// <DatiBollo>
2019-02-05 16:23:20 +01:00
const bool set_bollo = doc . get_bool ( " ADDBOLLI " ) ;
if ( ! set_bollo )
{
doc . put ( " ADDBOLLI " , true ) ;
}
{
real imponibile = doc . imponibile ( true ) ;
paf0700f . set ( " P7_IMPORTOBOLLO " , converti_prezzo ( doc . bolli ( imponibile , 8 ) ) ) ;
}
// Nel dubbio risetto
doc . put ( " ADDBOLLI " , set_bollo ) ;
2018-07-25 15:53:29 +02:00
// </DatiBollo>
2019-02-04 10:45:27 +01:00
2018-07-25 15:53:29 +02:00
// <DatiCassaPrevidenziale>
// Non la mettiamo!
// </DatiCassaPrevidenziale>
2019-02-04 10:45:27 +01:00
2018-07-25 15:53:29 +02:00
// Non inserisco pi<70> adesso il paf0700f ma lo faccio alla fine (per inserire le ritenute)
2019-02-04 10:45:27 +01:00
/*
* Lo sconto in testata <EFBFBD> stato disabilitato in quanto su Campo influenza solo le righe merci mentre dovrebbe modificare tutte le righe
2019-02-05 16:23:20 +01:00
*/
2018-07-25 15:53:29 +02:00
// <DatiGenerali>
TPaf_record paf2700f ( " PAF2700F " ) ;
2018-10-19 12:20:19 +02:00
paf2700f . set ( " PQ_KEYHEADERFATT " , _hfatt ) ;
paf2700f . set ( " PQ_KEYBODYFATT " , _bfatt ) ;
2018-07-31 16:01:13 +02:00
remove ( paf2700f ) ;
2018-12-10 14:23:41 +01:00
// Disabilitata la scrittura del totale del documento, questo causa problemi se <20> presente uno sconto in testata e l'addebito del bollo.
// Campo calcola prima il totale, poi lo sconta e ci applica il bollo mentre lo SDI sconta a bollo gi<67> applicato.
2019-02-04 10:45:27 +01:00
2019-01-30 13:08:34 +01:00
paf2700f . set ( " PQ_IMPTOTDOC " , doc . totale_doc ( ) ) ;
2018-07-25 15:53:29 +02:00
const TRectype & cont_conv_off = cco ( doc ) ;
TString causale = cont_conv_off . get ( " S1 " ) ;
if ( causale . full ( ) )
{
causale < < ' ' < < cont_conv_off . get ( " S2 " ) ;
causale < < ' ' < < cont_conv_off . get ( " S3 " ) ;
causale . strip_double_spaces ( ) ;
causale . cut ( 200 ) ;
}
else
causale = doc . tipo ( ) . descrizione ( ) ;
paf2700f . set ( " PQ_CAUSALE " , causale ) ;
// paf2700f.set("PQ_ART73", true);
paf2700f . set ( " PQ_GESTIONE " , " D " ) ;
2018-07-31 16:01:13 +02:00
ok & = insert ( paf2700f ) ;
2018-07-25 15:53:29 +02:00
// </DatiGenerali>
// Azzera DDT
TPaf_record paf1600f ( " PAF1600F " ) ;
2018-10-19 12:20:19 +02:00
paf1600f . set ( " PF_KEYHEADERFATT " , _hfatt ) ;
paf1600f . set ( " PF_KEYBODYFATT " , _bfatt ) ;
2018-07-31 16:01:13 +02:00
remove ( paf1600f ) ;
2018-07-25 15:53:29 +02:00
// Fuori dallo scope per dopo
const TString16 cup = doc . get ( DOC_CUP ) ;
const TString16 cig = doc . get ( DOC_CIG ) ;
const TString80 com = doc . get ( DOC_CODCMS ) ;
2018-10-08 11:45:08 +02:00
// SEMPRE
// Azzera contratti
TPaf_record paf1000f ( " PAF1000F " ) ;
2018-10-19 12:20:19 +02:00
paf1000f . set ( " P0_KEYHEADERFATT " , _hfatt ) ;
paf1000f . set ( " P0_KEYBODYFATT " , _bfatt ) ;
2018-10-08 11:45:08 +02:00
paf1000f . set ( " P0_RIFNUMLINEA " , 0L ) ;
remove ( paf1000f ) ;
// Azzera convenzioni
TPaf_record paf1100f ( " PAF1100F " ) ;
2018-10-19 12:20:19 +02:00
paf1100f . set ( " PA_KEYHEADERFATT " , _hfatt ) ;
paf1100f . set ( " PA_KEYBODYFATT " , _bfatt ) ;
2018-10-08 11:45:08 +02:00
paf1100f . set ( " PA_RIFNUMLINEA " , 0L ) ;
remove ( paf1100f ) ;
// Azzera ordini
TPaf_record paf1200f ( " PAF1200F " ) ;
2018-10-19 12:20:19 +02:00
paf1200f . set ( " PB_KEYHEADERFATT " , _hfatt ) ;
paf1200f . set ( " PB_KEYBODYFATT " , _bfatt ) ;
2018-10-08 11:45:08 +02:00
paf1200f . set ( " PB_RIFNUMLINEA " , 0L ) ;
remove ( paf1200f ) ;
TString80 con = doc . get ( DOC_CONTRATTO ) ;
if ( con . full ( ) | | cup . full ( ) | | cig . full ( ) )
2018-07-25 15:53:29 +02:00
{
2018-10-08 11:45:08 +02:00
char tcon = doc . get_char ( DOC_MODPAG ) ;
if ( tcon < ' C ' ) tcon = ' C ' ;
TDate datadoc ; // Data contratto non obbligatoria
if ( con . full ( ) )
{
datadoc = cco ( doc ) . get_date ( " D0 " ) ;
}
else
{
// IdDocumento obbligatorio
con = cig ;
if ( con . blank ( ) )
con = cup ;
2018-07-25 15:53:29 +02:00
}
2018-10-08 11:45:08 +02:00
if ( tcon = = ' O ' )
{
paf1000f . set ( " P0_RIFNUMLINEA " , 0L ) ;
paf1000f . set ( " P0_IDDOC " , con ) ;
paf1000f . set ( " P0_DATADOC " , datadoc ) ;
2019-02-07 09:13:55 +01:00
paf1000f . set ( " P0_COMMESSACONV " , com ) ;
2018-10-08 11:45:08 +02:00
paf1000f . set ( " P0_CODCUP " , cup ) ;
paf1000f . set ( " P0_CODCIG " , cig ) ;
paf1000f . set ( " P0_GESTIONE " , " D " ) ;
ok & = insert ( paf1000f ) ;
}
else if ( tcon = = ' C ' )
{
paf1100f . set ( " PA_RIFNUMLINEA " , 0L ) ;
paf1100f . set ( " PA_IDDOC " , con ) ;
paf1100f . set ( " PA_DATADOCU " , datadoc ) ;
paf1100f . set ( " PA_COMMCONVENZ " , com ) ;
paf1100f . set ( " PA_CODCUP " , cup ) ;
paf1100f . set ( " PA_CODCIG " , cig ) ;
2019-02-07 09:13:55 +01:00
paf1100f . set ( " PA_GESTIONE " , " D " ) ;
2018-10-08 11:45:08 +02:00
ok & = insert ( paf1100f ) ;
}
else
{
paf1200f . set ( " PB_RIFNUMLINEA " , 0L ) ;
paf1200f . set ( " PB_IDDOC " , con ) ;
paf1200f . set ( " PB_DATADOCO " , datadoc ) ;
2019-02-07 09:13:55 +01:00
paf1200f . set ( " PB_COMMESSACONV " , com ) ;
2018-10-08 11:45:08 +02:00
paf1200f . set ( " PB_CODCUP " , cup ) ;
paf1200f . set ( " PB_CODCIG " , cig ) ;
paf1200f . set ( " PB_GESTIONE " , " D " ) ;
ok & = insert ( paf1200f ) ;
}
2018-07-25 15:53:29 +02:00
}
2019-02-05 16:23:20 +01:00
if ( _is_pa & & cup . blank ( ) & & cig . blank ( ) )
2018-10-08 11:45:08 +02:00
log ( 1 , " CIG e CUP assenti " ) ;
2018-07-25 15:53:29 +02:00
// <DatiBeniServizi>
TPaf_record paf1800f ( " PAF1800F " ) ;
2018-10-19 12:20:19 +02:00
paf1800f . set ( " PI_KEYHEADERFATT " , _hfatt ) ;
paf1800f . set ( " PI_KEYBODYFATT " , _bfatt ) ;
2018-07-31 16:01:13 +02:00
remove ( paf1800f ) ; // Cancella tutte le righe documento
2018-07-25 15:53:29 +02:00
TPaf_record paf2000f ( " PAF2000F " ) ;
2018-10-19 12:20:19 +02:00
paf2000f . set ( " PJ_KEYHEADERFATT " , _hfatt ) ;
paf2000f . set ( " PJ_KEYBODYFATT " , _bfatt ) ;
2018-07-31 16:01:13 +02:00
remove ( paf2000f ) ; // Cancella tutti gli sconti di riga
2019-01-30 13:08:34 +01:00
TPaf_record paf2100f ( " PAF2100F " ) ;
paf2100f . set ( " PK_KEYHEADERFATT " , _hfatt ) ;
paf2100f . set ( " PK_KEYBODYFATT " , _bfatt ) ;
remove ( paf2000f ) ; // Cancella tutti i "altri dati gestionali"
2018-07-25 15:53:29 +02:00
TPaf_record paf1900f ( " PAF1900F " ) ;
2018-10-19 12:20:19 +02:00
paf1900f . set ( " PY_KEYHEADERFATT " , _hfatt ) ;
paf1900f . set ( " PY_KEYBODYFATT " , _bfatt ) ;
2018-07-31 16:01:13 +02:00
remove ( paf1900f ) ; // Cancella tutte le righe articoli del documento
2018-10-15 12:58:46 +02:00
TPaf_record paf3000f ( " PAF3000F " ) ;
2018-10-19 12:20:19 +02:00
paf3000f . set ( " PT_KEYHEADERFATT " , _hfatt ) ;
paf3000f . set ( " PT_KEYBODYFATT " , _bfatt ) ;
2018-10-15 12:58:46 +02:00
remove ( paf3000f ) ;
2019-02-06 10:47:23 +01:00
long riga = 1 ;
2019-02-06 10:47:01 +01:00
2018-07-25 15:53:29 +02:00
FOR_EACH_PHYSICAL_RDOC ( doc , r , rdoc )
{
2019-02-21 17:44:31 +01:00
// Controllo la riga
if ( check_row ( * rdoc ) & & ! fp_settings ( ) . get_check_not_block ( ) )
return false ;
2019-02-06 10:47:23 +01:00
bool skip_riga = false ;
2019-02-21 17:44:31 +01:00
paf1800f . reset ( ) ;
paf1800f . set ( " PI_KEYHEADERFATT " , _hfatt ) ;
paf1800f . set ( " PI_KEYBODYFATT " , _bfatt ) ;
paf1800f . set ( " PI_NUMEROLINEA " , riga ) ;
const TString & descrizione_riga = descrizione ( * rdoc ) ;
if ( descrizione_riga . empty ( ) )
continue ;
paf3000f . reset ( ) ;
paf3000f . set ( " PT_KEYHEADERFATT " , _hfatt ) ;
paf3000f . set ( " PT_KEYBODYFATT " , _bfatt ) ;
paf3000f . set ( " PT_RIFNUMLINEA " , riga ) ;
paf3000f . set ( " PT_COMMENTO " , descrizione_riga ) ;
// <CodiceArticolo>
if ( rdoc - > is_articolo ( ) )
2018-12-14 12:10:42 +01:00
{
2019-02-21 17:44:31 +01:00
TString codartmag = rdoc - > get ( RDOC_CODARTMAG ) ;
TString codart = rdoc - > get ( RDOC_CODART ) ;
long riga_art = 0 ;
if ( codart . full ( ) )
2018-07-25 15:53:29 +02:00
{
2019-02-21 17:44:31 +01:00
if ( codartmag . full ( ) )
{
paf1900f . reset ( ) ;
paf1900f . set ( " PY_KEYHEADERFATT " , _hfatt ) ;
paf1900f . set ( " PY_KEYBODYFATT " , _bfatt ) ;
paf1900f . set ( " PY_KEYNLINEA " , riga ) ;
ok & = add_row_art ( riga_art , " Codice articolo interno " , codartmag , paf1900f ) ;
}
// Se il codice articolo del magazzino <20> diverso quello <20> del cliente
if ( codart . full ( ) & & codart ! = codartmag )
{
paf1900f . reset ( ) ;
paf1900f . set ( " PY_KEYHEADERFATT " , _hfatt ) ;
paf1900f . set ( " PY_KEYBODYFATT " , _bfatt ) ;
paf1900f . set ( " PY_KEYNLINEA " , riga ) ;
ok & = add_row_art ( riga_art , " Codice articolo cliente " , codart , paf1900f ) ;
}
2018-07-25 15:53:29 +02:00
}
2018-12-14 12:10:42 +01:00
}
// </CodiceArticolo>
2018-12-10 14:23:41 +01:00
if ( rdoc - > is_descrizione ( ) )
{
paf1800f . set ( " PI_QUANTITA " , UNO ) ;
paf1800f . set ( " PI_PREZZOUNIT " , ZERO ) ;
paf1800f . set ( " PI_PRZTOTALE " , ZERO ) ;
2019-02-06 10:47:01 +01:00
set_IVA ( _codivadefault , paf1800f ) ;
2018-12-10 14:23:41 +01:00
}
else if ( rdoc - > is_merce ( ) )
{
2019-01-30 13:08:34 +01:00
if ( rdoc - > get ( RDOC_QTA ) . is_zero ( ) )
{
TString msg ;
msg . format ( " La riga merce %d ha quantit<69> nulla " , riga ) ;
log ( 1 , msg ) ;
}
set_qta_prezzo ( paf1800f , rdoc ) ;
if ( rdoc - > iva ( ) . codice ( ) . empty ( ) )
{
2019-02-06 10:47:01 +01:00
set_IVA ( _codivadefault , paf1800f ) ;
2019-01-30 13:08:34 +01:00
}
else
2018-12-10 14:23:41 +01:00
set_IVA ( * rdoc , paf1800f ) ;
2019-01-30 13:08:34 +01:00
/*
const TDate data = doc . get ( DOC_DATADOC ) ;
paf1800f . set ( " PI_DTINIZIOPER " , data ) ;
paf1800f . set ( " PI_DTFINEPER " , data ) ;
*/
/*
* Ogni riga si pu <EFBFBD> rifare a un DDT / Ordine diverso , per questo devo inserire i dati da qua e non in testata
*/
TArray ancestors ;
find_ancestors ( * rdoc , ancestors ) ;
for ( int i = ancestors . last ( ) ; i > 0 ; i = ancestors . pred ( i ) )
{
2019-02-05 16:23:20 +01:00
_has_bolla | = true ;
2019-01-30 13:08:34 +01:00
const TAncestor & a = ( const TAncestor & ) ancestors [ i ] ;
if ( i = = 1 )
2018-12-10 14:23:41 +01:00
{
2019-01-30 13:08:34 +01:00
// <DatiDDT>
paf1600f . reset ( ) ;
paf1600f . set ( " PF_KEYHEADERFATT " , _hfatt ) ;
paf1600f . set ( " PF_KEYBODYFATT " , _bfatt ) ;
paf1600f . set ( " PF_RIFNUMLINEA " , ( long ) r ) ;
paf1600f . set ( " PF_NUMDDDT " , a . _numdoc ) ;
paf1600f . set ( " PF_DATADDT " , a . _datadoc ) ;
paf1600f . set ( " PF_GESTIONE " , " D " ) ;
ok & = insert ( paf1600f ) ;
// </DatiDDT>
2018-12-10 14:23:41 +01:00
}
2019-01-30 13:08:34 +01:00
else if ( i = = 3 )
2018-12-10 14:23:41 +01:00
{
2019-01-30 13:08:34 +01:00
// <DatiOrdineAcquisto>
paf1000f . set ( " P0_KEYHEADERFATT " , _hfatt ) ;
paf1000f . set ( " P0_KEYBODYFATT " , _bfatt ) ;
paf1000f . set ( " P0_RIFNUMLINEA " , ( long ) r ) ;
paf1000f . set ( " P0_IDDOC " , a . _numdoc ) ;
paf1000f . set ( " P0_DATADOC " , a . _datadoc ) ;
2019-02-07 09:13:55 +01:00
paf1000f . set ( " P0_COMMESSACONV " , com ) ;
2019-01-30 13:08:34 +01:00
paf1000f . set ( " P0_CODCUP " , cup ) ;
paf1000f . set ( " P0_CODCIG " , cig ) ;
paf1000f . set ( " P0_GESTIONE " , " D " ) ;
ok & = insert ( paf1000f ) ;
// </DatiOrdineAcquisto>
2018-12-10 14:23:41 +01:00
}
2019-01-30 13:08:34 +01:00
}
2018-12-10 14:23:41 +01:00
}
else if ( rdoc - > is_spese ( ) )
{
2019-02-06 10:47:23 +01:00
const TSpesa_prest & sp = rdoc - > spesa ( ) ;
// Controllo se ha la cassa professionale lo metto in testata
if ( sp . cassa_previdenziale ( ) . full ( ) )
{
ok & = add_cassa_previdenziale ( * rdoc ) ;
skip_riga = true ;
}
// Altrimenti lo metto in riga
else
{
2018-12-10 14:23:41 +01:00
const real imp = rdoc - > importo ( true , false ) ;
real qta = UNO ;
2018-12-14 12:10:42 +01:00
bool qta_inverse = false ;
2018-12-10 14:23:41 +01:00
if ( sp . is_tipo ( ) )
{
2019-02-06 10:47:23 +01:00
paf1800f . set ( " PI_UNITAMISURA " , rdoc - > get ( RDOC_UMQTA ) ) ;
qta = rdoc - > get_real ( RDOC_QTA ) ;
if ( qta . is_zero ( ) )
{
TString msg ;
msg . format ( " La riga spese a quantit<69> %d ha quantit<69> nulla (campo %s) " , riga , static_cast < const char * > ( rdoc - > field_qta ( ) ) ) ;
log ( 1 , msg ) ;
qta = UNO ;
}
if ( qta < ZERO )
2018-12-14 12:10:42 +01:00
{
qta = - qta ;
qta_inverse = true ;
}
2019-02-06 10:47:23 +01:00
paf1800f . set ( " PI_QUANTITA " , qta ) ;
2018-12-10 14:23:41 +01:00
}
real prz = imp ;
if ( qta ! = UNO )
{
2019-02-06 10:47:23 +01:00
prz = rdoc - > prezzo ( true , false , 8 ) ;
if ( prz . is_zero ( ) & & ! imp . is_zero ( ) )
{
const TPrice price ( imp / qta ) ;
prz = price . get_value ( ) ;
}
2018-12-10 14:23:41 +01:00
}
2019-01-31 12:40:59 +01:00
paf1800f . set ( " PI_PREZZOUNIT " , converti_prezzo ( qta_inverse ? - abs ( prz ) : abs ( prz ) ) ) ;
2018-12-10 14:23:41 +01:00
paf1800f . set ( " PI_PRZTOTALE " , converti_prezzo ( imp ) ) ;
set_IVA ( * rdoc , paf1800f ) ;
2019-02-06 10:47:23 +01:00
2019-02-06 10:47:01 +01:00
// Controllo se <20> una ritenuta fiscale
2018-12-10 14:23:41 +01:00
if ( sp . tipo_ritenuta ( ) = = ' F ' )
{
2019-02-21 17:44:31 +01:00
paf1800f . set ( " PI_RITENUTA " , " SI " ) ;
2019-02-05 16:23:20 +01:00
add_ritenuta ( doc , rdoc - > spesa ( ) , paf0700f ) ;
2018-12-10 14:23:41 +01:00
}
2019-02-06 10:47:23 +01:00
}
2018-12-10 14:23:41 +01:00
}
else if ( rdoc - > is_prestazione ( ) )
{
real qta = rdoc - > get ( RDOC_QTA ) ;
if ( qta . is_zero ( ) ) qta = UNO ;
2018-12-14 12:10:42 +01:00
set_qta_prezzo ( paf1800f , rdoc ) ;
2019-01-14 12:45:24 +01:00
2018-12-10 14:23:41 +01:00
set_IVA ( * rdoc , paf1800f ) ;
}
2019-01-14 12:45:24 +01:00
else if ( rdoc - > is_sconto ( ) | | rdoc - > is_sconto_perc ( ) )
{
TString msg ;
msg < < " Il documento " < < doc . codice_numerazione ( ) . codice ( ) < < " " < < doc . tipo ( ) . codice ( ) < < " " < < doc . numero ( ) < < " presenta una o pi<70> righe di tipo sconto o sconto percentuale. \n " \
" Esportazione impossibile " ;
log ( 2 , msg ) ;
return false ;
}
2019-01-30 13:08:34 +01:00
else if ( rdoc - > is_omaggio ( ) )
2019-01-28 15:40:42 +01:00
{
if ( rdoc - > get ( RDOC_QTA ) . is_zero ( ) )
{
TString msg ;
msg . format ( " La riga omaggi %d ha quantit<69> nulla " , riga ) ;
log ( 1 , msg ) ;
}
2019-01-30 13:08:34 +01:00
paf1800f . set ( " PI_TIPOCESSPREST " , " AB " ) ;
2019-01-28 15:40:42 +01:00
set_qta_prezzo ( paf1800f , rdoc ) ;
set_IVA ( * rdoc , paf1800f ) ;
2019-01-30 13:08:34 +01:00
paf2100f . set ( " PK_KEYNLINEA " , static_cast < long > ( r ) ) ;
paf2100f . set ( " PK_KEYNLINAR " , 1L ) ;
paf2100f . set ( " PK_TIPODATO " , " AswTRiga " ) ;
if ( rdoc - > get_bool ( RDOC_ADDIVA ) )
2019-01-28 15:40:42 +01:00
{
2019-01-30 13:08:34 +01:00
paf2100f . set ( " PK_RIFDATO " , " Omaggio con rivalsa " ) ;
// Metto i dati come si trattasse di una riga normalissima
paf1800f . set ( " PI_UNITAMISURA " , rdoc - > get ( RDOC_UMQTA ) ) ;
2019-02-05 16:23:20 +01:00
paf1800f . set ( " PI_QUANTITA " , rdoc - > get_real ( RDOC_QTA ) . string ( 0 , 8 ) ) ;
paf1800f . set ( " PI_PREZZOUNIT " , converti_prezzo ( rdoc - > prezzo ( false , false , 8 ) ) ) ;
2019-01-30 13:08:34 +01:00
paf1800f . set ( " PI_PRZTOTALE " , converti_prezzo ( rdoc - > prezzo ( false , false ) * rdoc - > get_real ( RDOC_QTA ) ) ) ;
2019-02-06 10:47:01 +01:00
TRiepilogo_agg & riepilogo_agg = _riepilogo_agg [ rdoc - > iva ( ) . codice ( ) ] ;
riepilogo_agg . imponibile + = rdoc - > imponibile_omaggio ( 2 ) ;
// Non metto l'imposta, <20> gi<67> presente nei totali
//riepilogo_agg.imposta += rdoc->iva_omaggio(8, 2);
2019-01-28 15:40:42 +01:00
}
else
{
2019-01-30 13:08:34 +01:00
paf2100f . set ( " PK_RIFDATO " , " Omaggio senza rivalsa " ) ;
// Aggiungo uno sconto
paf2000f . set ( " PJ_KEYNLINEA " , static_cast < long > ( r ) ) ;
paf2000f . set ( " PJ_KEYNLINAR " , 1L ) ;
paf2000f . set ( " PJ_TIPOSCONTO " , " SC " ) ;
// Applico uno sconto del 100% portando l'importo a zero
paf2000f . set ( " PJ_PERCSCONTO " , CENTO ) ;
paf1800f . set ( " PI_PRZTOTALE " , ZERO ) ;
paf2000f . set ( " PJ_GESTIONE " , " D " ) ;
ok & = insert ( paf2000f ) ;
2019-01-28 15:40:42 +01:00
}
2019-01-30 13:08:34 +01:00
ok & = insert ( paf2100f ) ;
2019-01-28 15:40:42 +01:00
}
2018-12-10 14:23:41 +01:00
else
{
// Salto tutte le altre righe
continue ;
}
2019-01-30 13:08:34 +01:00
// <ScontoMaggiorazione>
2019-02-04 10:45:27 +01:00
TString80 sconto_expr = rdoc - > get ( RDOC_SCONTO ) ;
TToken_string sconti ;
2019-01-30 13:08:34 +01:00
if ( parse_sconto ( sconto_expr , sconti ) )
{
long nlin_sconto = 0 ;
FOR_EACH_TOKEN ( sconti , str )
{
const real perc = str ;
if ( ! perc . is_zero ( ) )
{
paf2000f . set ( " PJ_KEYNLINEA " , static_cast < long > ( r ) ) ;
paf2000f . set ( " PJ_KEYNLINAR " , + + nlin_sconto ) ;
if ( perc > ZERO )
{
paf2000f . set ( " PJ_TIPOSCONTO " , " SC " ) ;
paf2000f . set ( " PJ_PERCSCONTO " , perc ) ;
}
else
{
paf2000f . set ( " PJ_TIPOSCONTO " , " MG " ) ;
paf2000f . set ( " PJ_PERCSCONTO " , - perc ) ;
}
paf2000f . set ( " PJ_GESTIONE " , " D " ) ;
ok & = insert ( paf2000f ) ;
}
}
}
2019-02-04 10:45:27 +01:00
2019-01-30 13:08:34 +01:00
// </ScontoMaggiorazione>
2019-02-06 10:47:23 +01:00
if ( ! skip_riga )
{
paf1800f . set ( " PI_GESTIONE " , " D " ) ;
ok & = insert ( paf1800f ) & & insert ( paf3000f ) ;
riga + + ;
}
2018-07-25 15:53:29 +02:00
}
2018-10-15 12:58:46 +02:00
// Controllo plafond
// Riga esenzione?
2019-02-04 10:45:27 +01:00
if ( doc . is_fattura ( ) )
2018-10-15 12:58:46 +02:00
{
doc . set_riga_esenzione ( ) ;
if ( doc . ha_riga_esenzione ( ) )
{
const TRiga_documento & riga_es = doc . get_riga_esenzione ( ) ;
paf1800f . reset ( ) ;
2018-10-19 12:20:19 +02:00
paf1800f . set ( " PI_KEYHEADERFATT " , _hfatt ) ;
paf1800f . set ( " PI_KEYBODYFATT " , _bfatt ) ;
2018-10-15 12:58:46 +02:00
paf1800f . set ( " PI_NUMEROLINEA " , + + riga ) ;
paf3000f . reset ( ) ;
2018-10-19 12:20:19 +02:00
paf3000f . set ( " PT_KEYHEADERFATT " , _hfatt ) ;
paf3000f . set ( " PT_KEYBODYFATT " , _bfatt ) ;
2018-10-15 12:58:46 +02:00
paf3000f . set ( " PT_RIFNUMLINEA " , riga ) ;
paf3000f . set ( " PT_COMMENTO " , descrizione ( riga_es ) ) ;
paf1800f . set ( " PI_QUANTITA " , UNO ) ;
paf1800f . set ( " PI_PREZZOUNIT " , ZERO ) ;
paf1800f . set ( " PI_PRZTOTALE " , ZERO ) ;
2019-02-06 10:47:01 +01:00
set_IVA ( _codivadefault , paf1800f ) ;
2018-10-15 12:58:46 +02:00
ok & = insert ( paf1800f ) & & insert ( paf3000f ) ;
}
}
2018-10-10 10:09:57 +02:00
// Se il bollo va fatto pagare bisogna aggiungere una riga!
2018-10-19 12:20:19 +02:00
if ( doc . get_bool ( " ADDBOLLI " ) & & doc . get_real ( " BOLLI " ) > ZERO )
2018-10-10 10:09:57 +02:00
{
paf1800f . reset ( ) ;
2018-10-19 12:20:19 +02:00
paf1800f . set ( " PI_KEYHEADERFATT " , _hfatt ) ;
paf1800f . set ( " PI_KEYBODYFATT " , _bfatt ) ;
2018-10-10 10:09:57 +02:00
paf1800f . set ( " PI_NUMEROLINEA " , + + riga ) ;
2018-10-15 12:58:46 +02:00
paf3000f . reset ( ) ;
2018-10-19 12:20:19 +02:00
paf3000f . set ( " PT_KEYHEADERFATT " , _hfatt ) ;
paf3000f . set ( " PT_KEYBODYFATT " , _bfatt ) ;
2018-10-10 10:09:57 +02:00
paf3000f . set ( " PT_RIFNUMLINEA " , riga ) ;
2018-12-14 12:10:42 +01:00
paf3000f . set ( " PT_COMMENTO " , " Imposta di bollo assolta virtualmente ai sensi dell'art. 6 D.M. 17.6.2014 " ) ;
2018-10-15 12:58:46 +02:00
paf1800f . set ( " PI_QUANTITA " , UNO ) ;
2018-12-10 14:23:41 +01:00
paf1800f . set ( " PI_PREZZOUNIT " , converti_prezzo ( doc . get_real ( " BOLLI " ) ) ) ;
paf1800f . set ( " PI_PRZTOTALE " , converti_prezzo ( doc . get_real ( " BOLLI " ) ) ) ;
2018-10-10 10:09:57 +02:00
set_IVA ( doc . codiva_bolli ( ) , paf1800f ) ;
ok & = insert ( paf1800f ) & & insert ( paf3000f ) ;
}
2018-10-19 12:20:19 +02:00
// OMAGGI????
// Aggiungo le spese incasso
if ( doc . get_real ( " SPESINC " ) > ZERO )
{
paf1800f . reset ( ) ;
paf1800f . set ( " PI_KEYHEADERFATT " , _hfatt ) ;
paf1800f . set ( " PI_KEYBODYFATT " , _bfatt ) ;
paf1800f . set ( " PI_NUMEROLINEA " , + + riga ) ;
paf3000f . reset ( ) ;
paf3000f . set ( " PT_KEYHEADERFATT " , _hfatt ) ;
paf3000f . set ( " PT_KEYBODYFATT " , _bfatt ) ;
paf3000f . set ( " PT_RIFNUMLINEA " , riga ) ;
paf3000f . set ( " PT_COMMENTO " , " Spese incasso " ) ;
paf1800f . set ( " PI_QUANTITA " , UNO ) ;
real imponibile = doc . imponibile ( ) ;
2018-12-10 14:23:41 +01:00
paf1800f . set ( " PI_PREZZOUNIT " , converti_prezzo ( doc . spese_incasso ( imponibile , 6 , _netto ) ) ) ;
paf1800f . set ( " PI_PRZTOTALE " , converti_prezzo ( doc . spese_incasso ( imponibile , 6 , _netto ) ) ) ;
2018-10-19 12:20:19 +02:00
2019-02-05 16:23:20 +01:00
set_IVA ( doc . clifor ( ) . vendite ( ) . get ( " ASSFIS " ) , paf1800f ) ;
2018-10-19 12:20:19 +02:00
ok & = insert ( paf1800f ) & & insert ( paf3000f ) ;
}
2018-10-15 12:58:46 +02:00
// Conai assolto
if ( doc . clifor ( ) . vendite ( ) . get_bool ( " CONAIASS " ) )
{
paf1800f . reset ( ) ;
2018-10-19 12:20:19 +02:00
paf1800f . set ( " PI_KEYHEADERFATT " , _hfatt ) ;
paf1800f . set ( " PI_KEYBODYFATT " , _bfatt ) ;
2018-10-15 12:58:46 +02:00
paf1800f . set ( " PI_NUMEROLINEA " , + + riga ) ;
paf3000f . reset ( ) ;
2018-10-19 12:20:19 +02:00
paf3000f . set ( " PT_KEYHEADERFATT " , _hfatt ) ;
paf3000f . set ( " PT_KEYBODYFATT " , _bfatt ) ;
2018-10-15 12:58:46 +02:00
paf3000f . set ( " PT_RIFNUMLINEA " , riga ) ;
2019-01-02 16:06:29 +01:00
paf3000f . set ( " PT_COMMENTO " , _conai_str ) ;
2018-10-15 12:58:46 +02:00
paf1800f . set ( " PI_QUANTITA " , UNO ) ;
paf1800f . set ( " PI_PREZZOUNIT " , ZERO ) ;
paf1800f . set ( " PI_PRZTOTALE " , ZERO ) ;
2019-02-06 10:47:01 +01:00
set_IVA ( _codivadefault , paf1800f ) ;
2018-10-15 12:58:46 +02:00
ok & = insert ( paf1800f ) & & insert ( paf3000f ) ;
}
2019-02-04 10:45:27 +01:00
// Riga sconto di testata
// Se <20> presente uno sconto in testata devo sottrarlo come riga sconto o lo SDI urla
if ( doc . get ( DOC_SCONTOPERC ) . full ( ) )
{
TAssoc_array & tiva = doc . tabella_iva ( false ) ;
FOR_EACH_ASSOC_OBJECT ( tiva , obj , key , itm )
{
const TRiepilogo_iva & riva = * dynamic_cast < const TRiepilogo_iva * > ( itm ) ;
paf1800f . reset ( ) ;
paf1800f . set ( " PI_KEYHEADERFATT " , _hfatt ) ;
paf1800f . set ( " PI_KEYBODYFATT " , _bfatt ) ;
paf1800f . set ( " PI_NUMEROLINEA " , + + riga ) ;
paf3000f . reset ( ) ;
paf3000f . set ( " PT_KEYHEADERFATT " , _hfatt ) ;
paf3000f . set ( " PT_KEYBODYFATT " , _bfatt ) ;
paf3000f . set ( " PT_RIFNUMLINEA " , riga ) ;
paf1800f . set ( " PI_TIPOCESSPREST " , " AB " ) ;
TString msg = " Riga sconto merci in testata " ;
if ( riva . cod_iva ( ) . percentuale ( ) > ZERO )
msg < < riva . cod_iva ( ) . percentuale ( ) < < " % " ;
else
msg < < riva . cod_iva ( ) . codice ( ) ;
paf3000f . set ( " PT_COMMENTO " , msg ) ;
paf1800f . set ( " PI_QUANTITA " , UNO ) ;
paf1800f . set ( " PI_PREZZOUNIT " , - abs ( riva . sconto_perc ( ) ) ) ;
paf1800f . set ( " PI_PRZTOTALE " , - abs ( riva . sconto_perc ( ) ) ) ;
set_IVA ( riva . cod_iva ( ) . codice ( ) , paf1800f ) ;
ok & = insert ( paf1800f ) & & insert ( paf3000f ) ;
}
}
2018-07-25 15:53:29 +02:00
// </DatiBeniServizi>
2019-01-28 15:40:42 +01:00
// <DatiDDT>
// Metto qua i dati DDT per capire se la fattura <20> accompagnatoria o deriva da bolla
TPaf_record paf1700f ( " PAF1700F " ) ;
paf1700f . set ( " PG_KEYHEADERFATT " , _hfatt ) ;
paf1700f . set ( " PG_KEYBODYFATT " , _bfatt ) ;
remove ( paf1700f ) ; // Cancella la riga del vettore
2019-02-05 16:23:20 +01:00
if ( doc . get ( " CODVETT1 " ) . full ( ) & & ! _has_bolla )
2019-01-28 15:40:42 +01:00
{
TRectype vet = cache ( ) . get ( " %VET " , doc . get ( " CODVETT1 " ) ) ;
const TString4 statopiva = vet . get ( " S3 " ) . mid ( 49 , 2 ) ;
const TString piva = vet . get ( " S3 " ) . mid ( 20 , 28 ) ;
const TString codfisc = vet . get ( " S13 " ) . mid ( 28 , 16 ) ;
if ( piva . empty ( ) & & codfisc . empty ( ) )
{
TString msg = " Il vettore " ;
msg < < vet . get ( " S0 " ) . mid ( 0 , 50 ) < < " non ha n<> codice fiscale n<> partita IVA, la fattura " < < doc . anno ( ) < < " " < < doc . codice_numerazione ( ) . codice ( ) < < " " < < doc . numero ( ) < < " non pu<70> essere trasmessa " ;
log ( 3 , msg ) ;
return false ;
}
if ( piva . full ( ) )
{
paf1700f . set ( " PG_FISCIVAPAESE " , statopiva . full ( ) ? statopiva : " IT " ) ;
paf1700f . set ( " PG_FISCIVACODICE " , piva ) ;
}
paf1700f . set ( " PG_CODICEFISCALE " , codfisc ) ;
if ( vet . get_bool ( " B0 " ) )
{
paf1700f . set ( " PG_ANANOME " , vet . get ( " S0 " ) . mid ( 0 , 30 ) ) ;
paf1700f . set ( " PG_ANACOGNOME " , vet . get ( " S0 " ) . mid ( 30 , 20 ) ) ;
}
else
paf1700f . set ( " PG_ANADENOMINAZ " , vet . get ( " S0 " ) . mid ( 0 , 50 ) ) ;
paf1700f . set ( " PG_ANACODEORI " , vet . get ( " S2 " ) . mid ( 0 , 17 ) ) ;
ok & = insert ( paf1700f ) ;
}
// </DatiDDT>
2018-07-25 15:53:29 +02:00
// Salvo la testata
2018-07-31 16:01:13 +02:00
ok & = insert ( paf0700f ) ;
2019-01-30 13:08:34 +01:00
2018-07-25 15:53:29 +02:00
// <DatiRiepilogo>
TPaf_record paf2200f ( " PAF2200F " ) ;
2018-10-19 12:20:19 +02:00
paf2200f . set ( " PL_KEYHEADERFATT " , _hfatt ) ;
paf2200f . set ( " PL_KEYBODYFATT " , _bfatt ) ;
2018-07-31 16:01:13 +02:00
remove ( paf2200f ) ; // Cancella tutte le righe di riepilogo IVA
2019-02-21 17:44:31 +01:00
const char * eiva = get_esigibilita_iva ( doc ) ;
2018-07-25 15:53:29 +02:00
long num_riep = 0 ;
TAssoc_array & tiva = doc . tabella_iva ( false ) ;
FOR_EACH_ASSOC_OBJECT ( tiva , obj , key , itm )
{
2018-12-14 12:10:42 +01:00
const TRiepilogo_iva & riva = * dynamic_cast < const TRiepilogo_iva * > ( itm ) ;
2019-02-21 17:44:31 +01:00
if ( ! check_riepilogo ( doc , riva ) & & ! fp_settings ( ) . get_check_not_block ( ) )
return false ;
2019-02-06 10:47:01 +01:00
add_riepilogo_iva ( paf2200f , riva . cod_iva ( ) , eiva , riva . imponibile ( ) , riva . imposta ( ) ) ;
}
2019-01-30 13:08:34 +01:00
2019-02-06 10:47:01 +01:00
if ( ! _riepilogo_agg . empty ( ) )
{
for ( auto i = _riepilogo_agg . begin ( ) ; i ! = _riepilogo_agg . end ( ) ; + + i )
{
const TCodiceIVA cod_iva ( i - > first ) ;
add_riepilogo_iva ( paf2200f , cod_iva , eiva ) ;
}
2018-07-25 15:53:29 +02:00
}
2019-02-06 10:47:01 +01:00
2018-07-25 15:53:29 +02:00
// </DatiRiepilogo>
// <DatiPagamento>
TPaf_record paf2400f ( " PAF2400F " ) ;
2018-10-19 12:20:19 +02:00
paf2400f . set ( " PN_KEYHEADERFATT " , _hfatt ) ;
paf2400f . set ( " PN_KEYBODYFATT " , _bfatt ) ;
2018-07-31 16:01:13 +02:00
remove ( paf2400f ) ; // Cancella i dati pagamento
2018-07-25 15:53:29 +02:00
TPagamento & pag = doc . pagamento ( ) ;
2018-10-10 10:09:57 +02:00
2018-07-25 15:53:29 +02:00
doc . scadenze_recalc ( ) ; // Ricalcola array delle rate
TString_array & scad = doc . scadenze ( ) ;
const int nrate = scad . items ( ) ; // Conta rate generate
const char * rateazione = pag . cond_pag_sdi ( ) ; // A rate (TP01) o una soluzione(TP02)?
paf2400f . set ( " PN_RIGA " , ZERO ) ; // Al momento non gestiamo pi<70> tipologie di pagamento per documento
paf2400f . set ( " PN_CONDPAGAMENTO " , rateazione ) ;
paf2400f . set ( " PN_GESTIONE " , " D " ) ;
2018-07-31 16:01:13 +02:00
ok & = insert ( paf2400f ) ;
2018-07-25 15:53:29 +02:00
TPaf_record paf2500f ( " PAF2500F " ) ;
2018-10-19 12:20:19 +02:00
paf2500f . set ( " PO_KEYHEADERFATT " , _hfatt ) ;
paf2500f . set ( " PO_KEYBODYFATT " , _bfatt ) ;
2018-07-31 16:01:13 +02:00
remove ( paf2500f ) ; // Cancella tutte le rate
2018-12-14 12:10:42 +01:00
// Imposto i campi uguali per tutte le rate
2018-07-25 15:53:29 +02:00
paf2500f . set ( " PO_CONDPAGAMENTO " , rateazione ) ; // Condizione di pagamento PA
paf2500f . set ( " PO_CODICEPAGAM " , pag . code ( ) ) ; // Condizione di pagamento CAMPO
2018-11-28 16:28:33 +01:00
TRectype cod_pag = cache ( ) . get ( " CPG " , doc . pagamento ( ) . code ( ) ) ;
const int tipo_pag = cod_pag . get_int ( " S4 " ) ;
2018-07-25 15:53:29 +02:00
TString80 iban , istituto ;
TString8 abi , cab ;
if ( get_bank ( doc , iban , abi , cab , istituto ) )
{
2019-02-21 17:44:31 +01:00
paf2500f . set ( " PO_ISTFINANZ " , istituto ) ;
paf2500f . set ( " PO_IBAN " , iban ) ;
paf2500f . set ( " PO_ABI " , abi ) ;
paf2500f . set ( " PO_CAB " , cab ) ;
2018-07-25 15:53:29 +02:00
}
2018-11-28 16:28:33 +01:00
if ( tipo_pag = = 3 & & cab . blank ( ) ) // Ricevuta bancaria
2018-07-25 15:53:29 +02:00
log ( 2 , TR ( " Non sono presenti ABI, CAB, IBAN per il pagamento " ) ) ;
2018-11-28 16:28:33 +01:00
if ( ( tipo_pag = = 8 | | tipo_pag = = 9 ) & & iban . blank ( ) ) // R.I.D. o Bonifico
{
log ( 1 , TR ( " Non <20> presente il codice IBAN per il pagamento " ) ) ;
}
2018-07-25 15:53:29 +02:00
for ( int nr = 0 ; nr < nrate ; nr + + )
{
2019-02-21 17:44:31 +01:00
paf2500f . set ( " PO_RIGA " , long ( nr + 1 ) ) ; // Numero rata
const int rp = nr < pag . n_rate ( ) ? nr : 0 ;
static TString key_class ; key_class . cut ( 0 ) < < pag . tipo_rata ( rp ) < < pag . ulc_rata ( rp ) ;
paf2500f . set ( " PO_MODALITAPAGAM " , cache ( ) . get ( " %CLR " , key_class , " S12 " ) ) ; // Si assicura che il numero riga sia accettabile
TToken_string & riga_scadenze = scad . row ( nr ) ; // Data|Importo
paf2500f . set ( " PO_DATASCADENZA " , TDate ( riga_scadenze . get ( 0 ) ) ) ; // Data scadenza
paf2500f . set ( " PO_IMPORTO " , converti_prezzo ( real ( riga_scadenze . get ( ) ) ) ) ; // Importo rata
paf2500f . set ( " PO_GESTIONE " , " D " ) ;
ok & = insert ( paf2500f ) ;
2018-07-25 15:53:29 +02:00
}
2018-12-14 12:10:42 +01:00
// </DatiPagamento>
2018-07-31 16:01:13 +02:00
if ( _gestioneallegati )
2018-07-25 15:53:29 +02:00
{
2018-07-31 16:01:13 +02:00
TPaf_record paf2600f ( " PAF2600F " ) ;
2018-10-19 12:20:19 +02:00
paf2600f . set ( " PP_KEYHEADERFATT " , _hfatt ) ;
paf2600f . set ( " PP_KEYBODYFATT " , _bfatt ) ;
2018-07-31 16:01:13 +02:00
remove ( paf2600f ) ; // Cancella eventuali allegati
long nprogr = 0 ; // Numero di file allegati
// Se abilitato stampo il documento e lo allego
2018-08-01 14:30:43 +02:00
TFilename rep ;
2019-02-05 16:23:20 +01:00
if ( _allegafattura )
2018-07-25 15:53:29 +02:00
{
2019-02-05 16:23:20 +01:00
if ( ! dongle ( ) . active ( RSAUT ) )
{
log ( 1 , " Impossibile generare la fattura, il modulo RS non <20> abilitato! " ) ;
}
else if ( ! doc . tipo ( ) . main_print_profile ( rep , 2 ) )
2018-07-25 15:53:29 +02:00
{
2019-02-05 16:23:20 +01:00
log ( 1 , " Impossibile generare la fattura, non <20> disponibile un profilo di stampa per questo tipo documento! " ) ;
2018-08-01 14:30:43 +02:00
}
else
{
2019-02-22 15:35:45 +01:00
//ve1 -2 {CODNUM} {ANNO} {PROVV} {NDOC}(-{ANDOC}) {TIPO_ELABORAZIONE} {TIPO_STAMPA} {NUM_COPIE} {ARCHIVIAZIONE}
2019-02-05 16:23:20 +01:00
// Costruisco la chiamata
static TString commandline ;
commandline . cut ( 0 ) < < " ve1 -2 " < < doc . get ( DOC_CODNUM ) < < ' ' < < doc . get ( DOC_ANNO )
2019-02-22 15:35:45 +01:00
< < ' ' < < doc . get ( DOC_PROVV ) < < ' ' < < doc . get ( DOC_NDOC ) < < " X P 1 D " ; // X: stampa su disco, P: provvisorio, 1: 1 copia, D: disabilita archiviazione
2019-02-05 16:23:20 +01:00
TExternal_app interattivo ( commandline ) ;
if ( interattivo . run ( ) ! = NOERR )
2018-07-31 16:01:13 +02:00
{
2019-02-05 16:23:20 +01:00
TString msgerr = " Fallita generazione PDF documento " ;
msgerr < < doc . get ( DOC_CODNUM ) < < ' ' < < doc . get ( DOC_ANNO )
< < ' ' < < doc . get ( DOC_PROVV ) < < ' ' < < doc . get ( DOC_NDOC ) ;
error_box ( msgerr ) ;
}
else
{
TFilename pdf ; pdf . tempdir ( ) ;
pdf < < SLASH < < doc . get ( DOC_ANNO ) < < ' _ ' < < doc . get ( DOC_CODNUM ) < < ' _ ' < < doc . get ( DOC_NDOC ) < < " .pdf " ;
if ( ! pdf . exist ( ) & & ! yesno_box ( " Attenzione! Non <20> stato possibile creare il pdf, continuare? " ) )
{
return false ;
}
if ( ! add_row_alleg ( pdf , nprogr , paf2600f ) )
return false ;
2018-07-31 16:01:13 +02:00
}
}
2019-02-05 16:23:20 +01:00
TToken_string allegati ( doc . get ( " COLL_GOLEM " ) , ' \n ' ) ;
bool load_allegati = true ;
if ( allegati . full ( ) )
2018-07-31 16:01:13 +02:00
{
2019-02-05 16:23:20 +01:00
if ( _def_fld . empty ( ) )
{
TString msgerr ; msgerr < < " Errore: il documento " < < _bfatt < < " ha degli allegati ma nella configurazione non <20> stato impostato come trametterli \n Caricare il documento senza allegati? " ;
load_allegati = false ;
if ( ! yesno_box ( msgerr ) )
return false ;
}
else
2018-07-31 16:01:13 +02:00
{
2019-02-05 16:23:20 +01:00
TFilename fname ;
FOR_EACH_TOKEN ( allegati , row )
2018-07-25 15:53:29 +02:00
{
2019-02-05 16:23:20 +01:00
const TToken_string entry ( row ) ;
if ( entry . get ( 0 , fname ) & & fname . exist ( ) )
{
if ( ! add_row_alleg ( fname , nprogr , paf2600f ) )
return false ;
}
2018-07-25 15:53:29 +02:00
}
}
}
}
}
2018-12-14 12:10:42 +01:00
// Tabella di non invio XML
TPaf_record pafw300f ( " PAFW300F " ) ;
pafw300f . set ( " PW_KEYHEADERFATT " , _hfatt ) ;
pafw300f . set ( " PW_KEYBODYFATT " , _bfatt ) ;
remove ( pafw300f ) ;
pafw300f . set ( " PW_TIPODOC " , tipo_doc_sdi ( doc ) ) ;
pafw300f . set ( " PW_TIPONUM " , doc . codice_numerazione ( ) . codice ( ) ) ;
pafw300f . set ( " PW_NUMERO " , doc . numero ( ) ) ;
pafw300f . set ( " PW_DATA " , doc . data ( ) ) ;
2018-11-28 16:28:33 +01:00
if ( ! cached_tipodoc ( doc . get ( DOC_TIPODOC ) ) . invio_xml ( ) )
{
pafw300f . set ( " PW_CODSDI " , " ********** " ) ;
}
2018-12-14 12:10:42 +01:00
2019-02-05 16:23:20 +01:00
pafw300f . set ( " PW_CDEST " , _coddest ) ;
2019-01-15 11:28:21 +01:00
pafw300f . set ( " PW_RAGSOC " , cliente . ragione_sociale ( ) . left ( 35 ) ) ;
2018-12-14 12:10:42 +01:00
pafw300f . set ( " PW_PAESE " , cliente . stato_residenza_ISO ( ) ) ;
pafw300f . set ( " PW_CODICE " , cliente . codice_fiscale_estero ( ) ) ;
pafw300f . set ( " PW_CFISCA " , cliente . codice_fiscale ( ) ) ;
pafw300f . set ( " PW_DENOM " , cliente . ragione_sociale ( ) ) ;
2019-01-30 13:08:34 +01:00
if ( cliente . fisica ( ) & & cliente . nome ( ) . full ( ) )
2018-12-14 12:10:42 +01:00
{
pafw300f . set ( " PW_NOME " , cliente . nome ( ) ) ;
pafw300f . set ( " PW_COGN " , cliente . cognome ( ) ) ;
}
else
pafw300f . set ( " PW_RAGSOC " , cliente . ragione_sociale ( ) . left ( 35 ) ) ;
pafw300f . set ( " PW_IMPO " , converti_prezzo ( doc . totale_doc ( ) ) ) ;
ok & = insert ( pafw300f ) ;
2018-07-31 16:01:13 +02:00
return _to_commit = ( ok & & save_paf ( ) ) ;
2018-07-25 15:53:29 +02:00
}
bool TDoc_fp : : doc_to_paf ( const TRectype & rec )
{
TDocumentoEsteso doc ;
if ( doc . read ( rec ) = = NOERR )
{
2019-01-25 09:56:13 +01:00
if ( doc_to_paf ( doc ) )
return fp_db ( ) . sq_commit ( ) ;
fp_db ( ) . sq_rollback ( ) ;
2018-07-25 15:53:29 +02:00
}
return false ;
}
bool TDoc_fp : : doc_to_paf ( const TDoc_key & key )
{
2018-12-04 10:28:27 +01:00
return doc_to_paf ( key_to_doc ( key ) ) ;
2018-07-25 15:53:29 +02:00
}
bool TDoc_fp : : doc_to_paf ( const TFilename & ini )
{
TConfig cfg ( ini , " 33 " ) ;
const int anno = cfg . get_int ( DOC_ANNO ) ;
const long ndoc = cfg . get_long ( DOC_NDOC ) ;
const TFixed_string codnum ( cfg . get ( DOC_CODNUM ) ) ; // lascio sapientemente per ultima la get di una stringa
const TDoc_key key ( anno , codnum , ndoc ) ;
return doc_to_paf ( key ) ;
}
2019-01-30 13:08:34 +01:00
2018-12-04 10:28:27 +01:00
bool TDoc_fp : : doc_to_paf ( )
{
return _doc_rec ! = nullptr ? doc_to_paf ( * _doc_rec ) : false ;
}
2019-01-30 13:08:34 +01:00
2018-12-04 10:28:27 +01:00
TRectype & TDoc_fp : : key_to_doc ( const TDoc_key & key )
{
if ( _doc_rec ! = nullptr )
delete _doc_rec ;
_doc_rec = new TRectype ( LF_DOC ) ;
_doc_rec - > put ( DOC_PROVV , key . provv ( ) ) ;
_doc_rec - > put ( DOC_ANNO , key . anno ( ) ) ;
_doc_rec - > put ( DOC_CODNUM , key . codnum ( ) ) ;
_doc_rec - > put ( DOC_NDOC , key . ndoc ( ) ) ;
return * _doc_rec ;
}
2019-02-05 16:23:20 +01:00
TDoc_fp : : TDoc_fp ( ) : _doc_rec ( nullptr ) , _log ( nullptr ) , _cache_insert ( false ) , _rec_clifo ( LF_CLIFO )
2018-07-25 15:53:29 +02:00
{
_ditta . init ( LF_NDITTE , prefix ( ) . get_codditta ( ) ) ;
2019-01-02 14:48:09 +01:00
_cofi = fp_settings ( ) . get_cofi_tras ( ) ;
2018-07-25 15:53:29 +02:00
if ( _cofi . blank ( ) )
_cofi = _ditta . codice_fiscale ( ) ;
2018-10-08 11:45:08 +02:00
# ifdef DBG
_gestioneallegati = _allegafattura = false ;
2018-10-19 12:20:19 +02:00
# else
2019-01-02 14:48:09 +01:00
_gestioneallegati = fp_settings ( ) . get_gest_alleg ( ) ;
_allegafattura = fp_settings ( ) . get_allega_fat ( ) ;
2018-10-08 11:45:08 +02:00
# endif
2019-01-02 14:48:09 +01:00
_def_fld = fp_settings ( ) . get_fld_dest ( ) ;
2018-07-25 15:53:29 +02:00
if ( ! _def_fld . ends_with ( " \\ " ) )
{
_def_fld < < " \\ " ;
}
2019-01-02 14:48:09 +01:00
_def_usr_fld = fp_settings ( ) . get_fld_dest_usr ( ) ;
2018-07-25 15:53:29 +02:00
if ( _def_usr_fld . empty ( ) )
{
_def_usr_fld = _def_fld ;
}
else if ( ! _def_usr_fld . ends_with ( " \\ " ) )
{
_def_usr_fld < < " \\ " ;
}
2019-01-02 16:06:29 +01:00
// Mi preparo la stringa del CONAI
_conai_str = ini_get_string ( CONFIG_DITTA , " ve " , " DESCCONAIASS " ) ;
if ( _conai_str . empty ( ) )
_conai_str = " Contributo CONAI assolto ove dovuto " ;
2018-07-25 15:53:29 +02:00
}
TDoc_fp : : ~ TDoc_fp ( )
{
commit ( ) ;
2018-12-04 10:28:27 +01:00
if ( _doc_rec ! = nullptr )
delete _doc_rec ;
2018-07-25 15:53:29 +02:00
}