Aggiunta importazione FE

This commit is contained in:
Thomas Zilio 2018-09-24 18:10:16 +02:00
parent 50c9083473
commit e91064eb38
25 changed files with 838 additions and 294 deletions

View File

@ -64,8 +64,10 @@
"Modules\\Fatture\\Custom\\": "modules/fatture/custom/src", "Modules\\Fatture\\Custom\\": "modules/fatture/custom/src",
"Modules\\Interventi\\": "modules/interventi/src", "Modules\\Interventi\\": "modules/interventi/src",
"Modules\\Interventi\\Custom\\": "modules/interventi/custom/src", "Modules\\Interventi\\Custom\\": "modules/interventi/custom/src",
"Plugins\\Fatturazione\\": "plugins/fatturazione/src", "Plugins\\ExportPA\\": "plugins/exportPA/src",
"Plugins\\Fatturazione\\Custom\\": "plugins/fatturazione/custom/src" "Plugins\\ExportPA\\Custom\\": "plugins/exportPA/custom/src",
"Plugins\\ImportPA\\": "plugins/importPA/src",
"Plugins\\ImportPA\\Custom\\": "plugins/importPA/custom/src"
}, },
"files": [ "files": [
"lib/functions.php", "lib/functions.php",

View File

@ -2,6 +2,8 @@
include_once __DIR__.'/../../core.php'; include_once __DIR__.'/../../core.php';
use Modules\Anagrafiche\Anagrafica;
$id_azienda = $dbo->fetchArray("SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE descrizione='Azienda'")[0]['idtipoanagrafica']; $id_azienda = $dbo->fetchArray("SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE descrizione='Azienda'")[0]['idtipoanagrafica'];
$id_cliente = $dbo->fetchArray("SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE descrizione='Cliente'")[0]['idtipoanagrafica']; $id_cliente = $dbo->fetchArray("SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE descrizione='Cliente'")[0]['idtipoanagrafica'];
$id_fornitore = $dbo->fetchArray("SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE descrizione='Fornitore'")[0]['idtipoanagrafica']; $id_fornitore = $dbo->fetchArray("SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE descrizione='Fornitore'")[0]['idtipoanagrafica'];
@ -9,73 +11,80 @@ $id_tecnico = $dbo->fetchArray("SELECT idtipoanagrafica FROM an_tipianagrafiche
switch (post('op')) { switch (post('op')) {
case 'update': case 'update':
$partita_iva = trim(strtoupper(post('piva'))); $anagrafica = Anagrafica::find($id_record);
$codice_fiscale = trim(strtoupper(post('codice_fiscale')));
// Leggo tutti i valori passati dal POST e li salvo in un array // Informazioni sull'anagrafica
$dbo->update('an_anagrafiche', [ $anagrafica->codice = post('codice');
'ragione_sociale' => post('ragione_sociale'), $anagrafica->ragione_sociale = post('ragione_sociale');
'tipo' => post('tipo'), $anagrafica->tipo = post('tipo');
'piva' => $partita_iva, $anagrafica->data_nascita = post('data_nascita');
'codice_fiscale' => $codice_fiscale, $anagrafica->luogo_nascita = post('luogo_nascita');
'data_nascita' => post('data_nascita'), $anagrafica->sesso = post('sesso');
'luogo_nascita' => post('luogo_nascita'), $anagrafica->capitale_sociale = post('capitale_sociale');
'sesso' => post('sesso'), $anagrafica->pec = post('pec');
'capitale_sociale' => post('capitale_sociale'), $anagrafica->idsede_fatturazione = post('idsede_fatturazione');
'indirizzo' => post('indirizzo'), $anagrafica->note = post('note');
'indirizzo2' => post('indirizzo2'), $anagrafica->codiceri = post('codiceri');
'citta' => post('citta'), $anagrafica->codicerea = post('codicerea');
'cap' => post('cap'), $anagrafica->appoggiobancario = post('appoggiobancario');
'provincia' => post('provincia'), $anagrafica->filiale = post('filiale');
'km' => post('km'), $anagrafica->codiceiban = post('codiceiban');
'id_nazione' => !empty(post('id_nazione')) ? post('id_nazione') : null, $anagrafica->bic = post('bic');
'telefono' => post('telefono'), $anagrafica->diciturafissafattura = post('diciturafissafattura');
'cellulare' => post('cellulare'), $anagrafica->idpagamento_acquisti = post('idpagamento_acquisti');
'fax' => post('fax'), $anagrafica->idpagamento_vendite = post('idpagamento_vendite');
'email' => post('email'), $anagrafica->idlistino_acquisti = post('idlistino_acquisti');
'pec' => post('pec'), $anagrafica->idlistino_vendite = post('idlistino_vendite');
'idsede_fatturazione' => post('idsede_fatturazione'), $anagrafica->idiva_acquisti = post('idiva_acquisti');
'note' => post('note'), $anagrafica->idiva_vendite = post('idiva_vendite');
'codiceri' => post('codiceri'), $anagrafica->idbanca_acquisti = post('idbanca_acquisti');
'codicerea' => post('codicerea'), $anagrafica->idbanca_vendite = post('idbanca_vendite');
'appoggiobancario' => post('appoggiobancario'), $anagrafica->settore = post('settore');
'filiale' => post('filiale'), $anagrafica->marche = post('marche');
'codiceiban' => post('codiceiban'), $anagrafica->dipendenti = post('dipendenti');
'bic' => post('bic'), $anagrafica->macchine = post('macchine');
'diciturafissafattura' => post('diciturafissafattura'), $anagrafica->idagente = post('idagente');
'idpagamento_acquisti' => post('idpagamento_acquisti'), $anagrafica->idrelazione = post('idrelazione');
'idpagamento_vendite' => post('idpagamento_vendite'), $anagrafica->sitoweb = post('sitoweb');
'idlistino_acquisti' => post('idlistino_acquisti'), $anagrafica->nome_cognome = post('nome_cognome');
'idlistino_vendite' => post('idlistino_vendite'), $anagrafica->iscrizione_tribunale = post('iscrizione_tribunale');
'idiva_acquisti' => post('idiva_acquisti'), $anagrafica->cciaa = post('cciaa');
'idiva_vendite' => post('idiva_vendite'), $anagrafica->cciaa_citta = post('cciaa_citta');
'idbanca_acquisti' => post('idbanca_acquisti'), $anagrafica->n_alboartigiani = post('n_alboartigiani');
'idbanca_vendite' => post('idbanca_vendite'), $anagrafica->foro_competenza = post('foro_competenza');
'settore' => post('settore'), $anagrafica->colore = post('colore');
'marche' => post('marche'), $anagrafica->idtipointervento_default = post('idtipointervento_default');
'dipendenti' => post('dipendenti'),
'macchine' => post('macchine'), $anagrafica->save();
'idagente' => post('idagente'),
'idrelazione' => post('idrelazione'), $anagrafica->updateTipologie((array)post('idtipoanagrafica'));
'sitoweb' => post('sitoweb'),
'idzona' => post('idzona'), // Informazioni sulla sede
'nome_cognome' => post('nome_cognome'), $sede = $anagrafica->sedeLegale();
'iscrizione_tribunale' => post('iscrizione_tribunale'), $sede->partita_iva = post('piva');
'cciaa' => post('cciaa'), $sede->codice_fiscale = post('codice_fiscale');
'cciaa_citta' => post('cciaa_citta'), $sede->indirizzo = post('indirizzo');
'n_alboartigiani' => post('n_alboartigiani'), $sede->indirizzo2 = post('indirizzo2');
'foro_competenza' => post('foro_competenza'), $sede->citta = post('citta');
'colore' => post('colore'), $sede->cap = post('cap');
'idtipointervento_default' => post('idtipointervento_default'), $sede->provincia = post('provincia');
'gaddress' => post('gaddress'), $sede->km = post('km');
'lat' => post('lat'), $sede->id_nazione = post('id_nazione') ?: null;
'lng' => post('lng'), $sede->gaddress = post('gaddress');
], ['idanagrafica' => $id_record]); $sede->lat = post('lat');
$sede->lng = post('lng');
$sede->telefono = post('telefono');
$sede->cellulare = post('cellulare');
$sede->fax = post('fax');
$sede->idzona = post('idzona');
$sede->email = post('email');
$sede->save();
flash()->info(str_replace('_NAME_', '"'.post('ragione_sociale').'"', "Informazioni per l'anagrafica _NAME_ salvate correttamente!")); flash()->info(str_replace('_NAME_', '"'.post('ragione_sociale').'"', "Informazioni per l'anagrafica _NAME_ salvate correttamente!"));
// Validazione della Partita IVA // Validazione della Partita IVA
$check_vat_number = Validate::isValidVatNumber(strtoupper($partita_iva)); $partita_iva = $anagrafica->partita_iva ;
$check_vat_number = Validate::isValidVatNumber($partita_iva);
if (empty($check_vat_number)) { if (empty($check_vat_number)) {
flash()->error(tr('Attenzione: la partita IVA _IVA_ sembra non essere valida', [ flash()->error(tr('Attenzione: la partita IVA _IVA_ sembra non essere valida', [
'_IVA_' => $partita_iva, '_IVA_' => $partita_iva,
@ -83,13 +92,8 @@ switch (post('op')) {
} }
// Aggiorno il codice anagrafica se non è già presente, altrimenti lo ignoro // Aggiorno il codice anagrafica se non è già presente, altrimenti lo ignoro
$esiste = $dbo->fetchNum('SELECT idanagrafica FROM an_anagrafiche WHERE codice='.prepare(post('codice')).' AND NOT idanagrafica='.prepare($id_record)); if ($anagrafica->codice!= post('codice')) {
// Verifica dell'esistenza codice anagrafica
if ($esiste) {
flash()->error(tr("Il codice anagrafica inserito esiste già! Inserirne un'altro...")); flash()->error(tr("Il codice anagrafica inserito esiste già! Inserirne un'altro..."));
} else {
$dbo->query('UPDATE an_anagrafiche SET codice='.prepare(post('codice')).' WHERE idanagrafica='.prepare($id_record));
} }
// Aggiorno gli agenti collegati // Aggiorno gli agenti collegati
@ -100,56 +104,17 @@ switch (post('op')) {
$dbo->query('DELETE FROM an_anagrafiche_agenti WHERE idanagrafica='.prepare($id_record).' AND idagente='.prepare(post('idagente'))); $dbo->query('DELETE FROM an_anagrafiche_agenti WHERE idanagrafica='.prepare($id_record).' AND idagente='.prepare(post('idagente')));
} }
// Aggiorno le tipologie di anagrafica
$idtipoanagrafica = (array) post('idtipoanagrafica');
if (in_array($id_azienda, $tipi_anagrafica)) {
$idtipoanagrafica[] = $id_azienda;
}
$dbo->sync('an_tipianagrafiche_anagrafiche', ['idanagrafica' => $id_record], ['idtipoanagrafica' => $idtipoanagrafica]);
// Verifico se esiste già l'associazione dell'anagrafica a conti del partitario
$rs = $dbo->fetchArray('SELECT idconto_cliente, idconto_fornitore FROM an_anagrafiche WHERE idanagrafica='.prepare($id_record));
$idconto_cliente = $rs[0]['idconto_cliente'];
$idconto_fornitore = $rs[0]['idconto_fornitore'];
// Creo il relativo conto nel partitario se non esiste
if (empty($idconto_cliente) && in_array($id_cliente, $idtipoanagrafica)) {
// Calcolo prossimo numero cliente
$rs = $dbo->fetchArray("SELECT MAX(CAST(co_pianodeiconti3.numero AS UNSIGNED)) AS max_numero FROM co_pianodeiconti3 INNER JOIN co_pianodeiconti2 ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id WHERE co_pianodeiconti2.descrizione='Crediti clienti e crediti diversi'");
$new_numero = $rs[0]['max_numero'] + 1;
$new_numero = str_pad($new_numero, 6, '0', STR_PAD_LEFT);
$dbo->query('INSERT INTO co_pianodeiconti3(numero, descrizione, idpianodeiconti2, can_delete, can_edit) VALUES('.prepare($new_numero).', '.prepare(post('ragione_sociale')).", (SELECT id FROM co_pianodeiconti2 WHERE descrizione='Crediti clienti e crediti diversi'), 1, 1)");
$idconto = $dbo->lastInsertedID();
// Collegamento conto
$dbo->query('UPDATE an_anagrafiche SET idconto_cliente='.prepare($idconto).' WHERE idanagrafica='.prepare($id_record));
}
if (empty($idconto_fornitore) && in_array($id_fornitore, $idtipoanagrafica)) {
// Calcolo prossimo numero cliente
$rs = $dbo->fetchArray("SELECT MAX(CAST(co_pianodeiconti3.numero AS UNSIGNED)) AS max_numero FROM co_pianodeiconti3 INNER JOIN co_pianodeiconti2 ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id WHERE co_pianodeiconti2.descrizione='Debiti fornitori e debiti diversi'");
$new_numero = $rs[0]['max_numero'] + 1;
$new_numero = str_pad($new_numero, 6, '0', STR_PAD_LEFT);
$dbo->query('INSERT INTO co_pianodeiconti3(numero, descrizione, idpianodeiconti2, can_delete, can_edit) VALUES('.prepare($new_numero).', '.prepare(post('ragione_sociale')).", (SELECT id FROM co_pianodeiconti2 WHERE descrizione='Debiti fornitori e debiti diversi'), 1, 1)");
$idconto = $dbo->lastInsertedID();
// Collegamento conto
$dbo->query('UPDATE an_anagrafiche SET idconto_fornitore='.prepare($idconto).' WHERE idanagrafica='.prepare($id_record));
}
break; break;
case 'add': case 'add':
$idtipoanagrafica = post('idtipoanagrafica'); $idtipoanagrafica = post('idtipoanagrafica');
$ragione_sociale = post('ragione_sociale'); $ragione_sociale = post('ragione_sociale');
// Inserimento anagrafica base $anagrafica = Anagrafica::create([
// Leggo l'ultimo codice anagrafica per calcolare il successivo 'ragione_sociale' => $ragione_sociale,
$rs = $dbo->fetchArray('SELECT codice FROM an_anagrafiche ORDER BY CAST(codice AS SIGNED) DESC LIMIT 0, 1'); 'tipologie' => $idtipoanagrafica,
$codice = Util\Generator::generate(setting('Formato codice anagrafica'), $rs[0]['codice']); ]);
$id_record = $anagrafica->id;
// Se ad aggiungere un cliente è un agente, lo imposto come agente di quel cliente // Se ad aggiungere un cliente è un agente, lo imposto come agente di quel cliente
// Lettura tipologia dell'utente loggato // Lettura tipologia dell'utente loggato
@ -166,95 +131,32 @@ switch (post('op')) {
$idagente = ($agente_is_logged && in_array($id_cliente, $idtipoanagrafica)) ? $user['idanagrafica'] : 0; $idagente = ($agente_is_logged && in_array($id_cliente, $idtipoanagrafica)) ? $user['idanagrafica'] : 0;
$partita_iva = trim(strtoupper(post('piva'))); $anagrafica->partita_iva = post('piva');
$codice_fiscale = trim(strtoupper(post('codice_fiscale'))); $anagrafica->codice_fiscale = post('codice_fiscale');
$anagrafica->indirizzo = post('indirizzo');
$anagrafica->citta = post('citta');
$anagrafica->cap = post('cap');
$anagrafica->provincia = post('provincia');
$anagrafica->telefono = post('telefono');
$anagrafica->cellulare = post('cellulare');
$anagrafica->email = post('email');
$anagrafica->idrelazione = post('idrelazione');
$anagrafica->idagente = $idagente;
// Inserisco l'anagrafica $anagrafica->save();
$dbo->insert('an_anagrafiche', [
'ragione_sociale' => $ragione_sociale,
'codice' => $codice,
'piva' => $partita_iva,
'codice_fiscale' => $codice_fiscale,
'indirizzo' => post('indirizzo'),
'citta' => post('citta'),
'cap' => post('cap'),
'provincia' => post('provincia'),
'telefono' => post('telefono'),
'cellulare' => post('cellulare'),
'email' => post('email'),
'idrelazione' => post('idrelazione'),
'idagente' => $idagente,
]);
$new_id = $dbo->lastInsertedID(); if ($anagrafica->isAzienda()) {
flash()->info(tr('Anagrafica Azienda impostata come predefinita').'. '.tr('Per ulteriori informazionioni, visitare "Strumenti -> Impostazioni -> Generali"'));
// Inserisco il rapporto dell'anagrafica (cliente, tecnico, ecc)
$dbo->sync('an_tipianagrafiche_anagrafiche', ['idanagrafica' => $new_id], ['idtipoanagrafica' => (array) $idtipoanagrafica]);
if (in_array($id_azienda, $idtipoanagrafica)) {
Settings::setValue('Azienda predefinita', $new_id);
flash()->info(tr('Anagrafica Azienda impostata come predefinita. Per ulteriori informazionioni, visitare "Strumenti -> Impostazioni -> Generali"'));
} }
//se sto inserendo un tecnico, mi copio già le tariffe per le varie attività
if (in_array($id_tecnico, $idtipoanagrafica)) {
//per ogni tipo di attività
$rs_tipiintervento = $dbo->fetchArray('SELECT * FROM in_tipiintervento');
for ($i = 0; $i < count($rs_tipiintervento); ++$i) {
if ($dbo->query('INSERT INTO in_tariffe( idtecnico, idtipointervento, costo_ore, costo_km, costo_dirittochiamata, costo_ore_tecnico, costo_km_tecnico, costo_dirittochiamata_tecnico ) VALUES( '.prepare($new_id).', '.prepare($rs_tipiintervento[$i]['idtipointervento']).', (SELECT costo_orario FROM in_tipiintervento WHERE idtipointervento='.prepare($rs_tipiintervento[$i]['idtipointervento']).'), (SELECT costo_km FROM in_tipiintervento WHERE idtipointervento='.prepare($rs_tipiintervento[$i]['idtipointervento']).'), (SELECT costo_diritto_chiamata FROM in_tipiintervento WHERE idtipointervento='.prepare($rs_tipiintervento[$i]['idtipointervento']).'), (SELECT costo_orario_tecnico FROM in_tipiintervento WHERE idtipointervento='.prepare($rs_tipiintervento[$i]['idtipointervento']).'), (SELECT costo_km_tecnico FROM in_tipiintervento WHERE idtipointervento='.prepare($rs_tipiintervento[$i]['idtipointervento']).'), (SELECT costo_diritto_chiamata_tecnico FROM in_tipiintervento WHERE idtipointervento='.prepare($rs_tipiintervento[$i]['idtipointervento']).') )')) {
//flash()->info(tr('Informazioni salvate correttamente!'));
} else {
flash()->error(tr("Errore durante l'importazione tariffe!"));
}
}
}
// Creo il relativo conto nel partitario (cliente)
if (in_array($id_cliente, $idtipoanagrafica)) {
// Calcolo prossimo numero cliente
$rs = $dbo->fetchArray("SELECT MAX(CAST(co_pianodeiconti3.numero AS UNSIGNED)) AS max_numero FROM co_pianodeiconti3 INNER JOIN co_pianodeiconti2 ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id WHERE co_pianodeiconti2.descrizione='Crediti clienti e crediti diversi'");
$new_numero = $rs[0]['max_numero'] + 1;
$new_numero = str_pad($new_numero, 6, '0', STR_PAD_LEFT);
// Creazione conto
$dbo->query('INSERT INTO co_pianodeiconti3(numero, descrizione, idpianodeiconti2, can_delete, can_edit) VALUES('.prepare($new_numero).', '.prepare($ragione_sociale).", (SELECT id FROM co_pianodeiconti2 WHERE descrizione='Crediti clienti e crediti diversi'), 1, 1)");
$idconto = $dbo->lastInsertedID();
// Collegamento conto
$dbo->query('UPDATE an_anagrafiche SET idconto_cliente='.prepare($idconto).' WHERE idanagrafica='.prepare($new_id));
}
// Creo il relativo conto nel partitario (fornitore)
if (in_array($id_fornitore, $idtipoanagrafica)) {
// Calcolo prossimo numero cliente
$rs = $dbo->fetchArray("SELECT MAX(CAST(co_pianodeiconti3.numero AS UNSIGNED)) AS max_numero FROM co_pianodeiconti3 INNER JOIN co_pianodeiconti2 ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id WHERE co_pianodeiconti2.descrizione='Debiti fornitori e debiti diversi'");
$new_numero = $rs[0]['max_numero'] + 1;
$new_numero = str_pad($new_numero, 6, '0', STR_PAD_LEFT);
// Creazione conto
$dbo->query('INSERT INTO co_pianodeiconti3(numero, descrizione, idpianodeiconti2, can_delete, can_edit) VALUES('.prepare($new_numero).', '.prepare($ragione_sociale).", (SELECT id FROM co_pianodeiconti2 WHERE descrizione='Debiti fornitori e debiti diversi'), 1, 1)");
$idconto = $dbo->lastInsertedID();
// Collegamento conto
$dbo->query('UPDATE an_anagrafiche SET idconto_fornitore='.prepare($idconto).' WHERE idanagrafica='.prepare($new_id));
}
$id_record = $new_id;
// Lettura tipologia della nuova anagrafica // Lettura tipologia della nuova anagrafica
if (!empty($idtipoanagrafica)) { $descrizioni_tipi = $anagrafica->tipi()->get()->pluck('descrizione')->toArray();
$rs = $dbo->fetchArray('SELECT descrizione FROM an_tipianagrafiche WHERE idtipoanagrafica IN ('.implode(',', $idtipoanagrafica).')'); if (isAjaxRequest() && in_array(post('tipoanagrafica'), $descrizioni_tipi)) {
$tipoanagrafica_dst = implode(', ', array_column($rs, 'descrizione'));
}
if (isAjaxRequest() && str_contains($tipoanagrafica_dst, post('tipoanagrafica'))) {
echo json_encode(['id' => $id_record, 'text' => $ragione_sociale]); echo json_encode(['id' => $id_record, 'text' => $ragione_sociale]);
} }
flash()->info(tr('Aggiunta nuova anagrafica di tipo _TYPE_', [ flash()->info(tr('Aggiunta nuova anagrafica di tipo _TYPE_', [
'_TYPE_' => '"'.$tipoanagrafica_dst.'"', '_TYPE_' => '"'.implode(', ', $descrizioni_tipi).'"',
])); ]));
break; break;

View File

@ -48,17 +48,17 @@ if (!$cliente) {
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-4">
{[ "type": "text", "label": "<?php echo tr('Partita IVA'); ?>", "maxlength": 13, "name": "piva", "class": "text-center alphanumeric-mask", "value": "$piva$" ]}
</div>
<div class="col-md-4">
{[ "type": "text", "label": "<?php echo tr('Codice fiscale'); ?>", "maxlength": 16, "name": "codice_fiscale", "class": "text-center alphanumeric-mask", "value": "$codice_fiscale$" ]}
</div>
<div class="col-md-4"> <div class="col-md-4">
{[ "type": "text", "label": "<?php echo tr('Codice anagrafica'); ?>", "name": "codice", "required": 1, "class": "text-center", "value": "$codice$" ]} {[ "type": "text", "label": "<?php echo tr('Codice anagrafica'); ?>", "name": "codice", "required": 1, "class": "text-center", "value": "$codice$" ]}
</div> </div>
<div class="col-md-4">
{[ "type": "text", "label": "<?php echo tr('PEC'); ?>", "name": "pec", "class": "email-mask", "placeholder":"pec@dominio.ext", "value": "$pec$", "icon-before": "<i class='fa fa-envelope-o'></i>" ]}
</div>
<div class="col-md-4">
{[ "type": "text", "label": "<?php echo tr('Sito web'); ?>", "name": "sitoweb", "placeholder":"www.dominio.ext", "value": "$sitoweb$", "icon-before": "<i class='fa fa-globe'></i>" ]}
</div>
</div> </div>
<div class="row"> <div class="row">
@ -74,6 +74,24 @@ if (!$cliente) {
{[ "type": "select", "label": "<?php echo tr('Sesso'); ?>", "name": "sesso", "values": "list=\"\": \"Non specificato\", \"M\": \"<?php echo tr('Uomo'); ?>\", \"F\": \"<?php echo tr('Donna'); ?>\"", "value": "$sesso$" ]} {[ "type": "select", "label": "<?php echo tr('Sesso'); ?>", "name": "sesso", "values": "list=\"\": \"Non specificato\", \"M\": \"<?php echo tr('Uomo'); ?>\", \"F\": \"<?php echo tr('Donna'); ?>\"", "value": "$sesso$" ]}
</div> </div>
</div> </div>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-building"></i> <?php echo tr('Sede legale'); ?></h3>
</div>
<div class="panel-body">
<div class="row">
<div class="col-md-6">
{[ "type": "text", "label": "<?php echo tr('Partita IVA'); ?>", "maxlength": 13, "name": "piva", "class": "text-center alphanumeric-mask", "value": "$piva$" ]}
</div>
<div class="col-md-6">
{[ "type": "text", "label": "<?php echo tr('Codice fiscale'); ?>", "maxlength": 16, "name": "codice_fiscale", "class": "text-center alphanumeric-mask", "value": "$codice_fiscale$" ]}
</div>
</div>
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4">
@ -85,7 +103,7 @@ if (!$cliente) {
</div> </div>
<div class="col-md-4"> <div class="col-md-4">
{[ "type": "select", "label": "<?php echo tr('Zona'); ?>", "name": "idzona", "values": "query=SELECT id, CONCAT_WS( ' - ', nome, descrizione) AS descrizione FROM an_zone ORDER BY descrizione ASC", "value": "$idzona$", "placeholder": "<?php echo tr('Nessuna zona'); ?>", "icon-after": "add|<?php echo Modules::get('Zone')['id']; ?>" ]} {[ "type": "text", "label": "<?php echo tr('Città'); ?>", "name": "citta", "class": "text-center", "value": "$citta$" ]}
</div> </div>
</div> </div>
@ -94,12 +112,12 @@ if (!$cliente) {
{[ "type": "select", "label": "<?php echo tr('Nazione'); ?>", "name": "id_nazione", "values": "query=SELECT id AS id, nome AS descrizione FROM an_nazioni ORDER BY nome ASC", "value": "$id_nazione$" ]} {[ "type": "select", "label": "<?php echo tr('Nazione'); ?>", "name": "id_nazione", "values": "query=SELECT id AS id, nome AS descrizione FROM an_nazioni ORDER BY nome ASC", "value": "$id_nazione$" ]}
</div> </div>
<div class="col-md-2"> <div class="col-md-4">
{[ "type": "text", "label": "<?php echo tr('C.A.P.'); ?>", "name": "cap", "maxlength": 5, "class": "text-center", "value": "$cap$" ]} {[ "type": "select", "label": "<?php echo tr('Zona'); ?>", "name": "idzona", "values": "query=SELECT id, CONCAT_WS( ' - ', nome, descrizione) AS descrizione FROM an_zone ORDER BY descrizione ASC", "value": "$idzona$", "placeholder": "<?php echo tr('Nessuna zona'); ?>", "icon-after": "add|<?php echo Modules::get('Zone')['id']; ?>" ]}
</div> </div>
<div class="col-md-4"> <div class="col-md-2">
{[ "type": "text", "label": "<?php echo tr('Città'); ?>", "name": "citta", "class": "text-center", "value": "$citta$" ]} {[ "type": "text", "label": "<?php echo tr('C.A.P.'); ?>", "name": "cap", "maxlength": 5, "class": "text-center", "value": "$cap$" ]}
</div> </div>
<div class="col-md-2"> <div class="col-md-2">
@ -110,46 +128,23 @@ if (!$cliente) {
{[ "type": "number", "label": "<?php echo tr('Distanza'); ?>", "name": "km", "decimals":"1", "class": "text-center", "value": "$km$", "icon-after": "Km" ]} {[ "type": "number", "label": "<?php echo tr('Distanza'); ?>", "name": "km", "decimals":"1", "class": "text-center", "value": "$km$", "icon-after": "Km" ]}
</div> </div>
</div> </div>
</div>
</div>
<!-- CONTATTI -->
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title"><?php echo tr('Contatti'); ?></h3>
</div>
<div class="panel-body">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-3">
{[ "type": "text", "label": "<?php echo tr('Telefono'); ?>", "name": "telefono", "class": "text-center", "value": "$telefono$", "icon-before": "<i class='fa fa-phone'></i>" ]} {[ "type": "text", "label": "<?php echo tr('Telefono'); ?>", "name": "telefono", "class": "text-center", "value": "$telefono$", "icon-before": "<i class='fa fa-phone'></i>" ]}
</div> </div>
<div class="col-md-4"> <div class="col-md-3">
{[ "type": "text", "label": "<?php echo tr('Fax'); ?>", "name": "fax", "class": "text-center", "value": "$fax$", "icon-before": "<i class='fa fa-fax'></i>" ]} {[ "type": "text", "label": "<?php echo tr('Fax'); ?>", "name": "fax", "class": "text-center", "value": "$fax$", "icon-before": "<i class='fa fa-fax'></i>" ]}
</div> </div>
<div class="col-md-4"> <div class="col-md-3">
{[ "type": "text", "label": "<?php echo tr('Cellulare'); ?>", "name": "cellulare", "class": "text-center", "value": "$cellulare$", "icon-before": "<i class='fa fa-mobile'></i>" ]} {[ "type": "text", "label": "<?php echo tr('Cellulare'); ?>", "name": "cellulare", "class": "text-center", "value": "$cellulare$", "icon-before": "<i class='fa fa-mobile'></i>" ]}
</div> </div>
</div>
<div class="row"> <div class="col-md-3">
<div class="col-md-4">
{[ "type": "text", "label": "<?php echo tr('Email'); ?>", "name": "email", "class": "email-mask", "placeholder":"casella@dominio.ext", "value": "$email$", "icon-before": "<i class='fa fa-envelope'></i>" ]} {[ "type": "text", "label": "<?php echo tr('Email'); ?>", "name": "email", "class": "email-mask", "placeholder":"casella@dominio.ext", "value": "$email$", "icon-before": "<i class='fa fa-envelope'></i>" ]}
</div> </div>
<div class="col-md-4">
{[ "type": "text", "label": "<?php echo tr('PEC'); ?>", "name": "pec", "class": "email-mask", "placeholder":"pec@dominio.ext", "value": "$pec$", "icon-before": "<i class='fa fa-envelope-o'></i>" ]}
</div>
<div class="col-md-4">
{[ "type": "text", "label": "<?php echo tr('Sito web'); ?>", "name": "sitoweb", "placeholder":"www.dominio.ext", "value": "$sitoweb$", "icon-before": "<i class='fa fa-globe'></i>" ]}
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -4,14 +4,204 @@ namespace Modules\Anagrafiche;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Modules\Fatture\Fattura; use Modules\Fatture\Fattura;
use Util\Generator;
use Settings;
class Anagrafica extends Model class Anagrafica extends Model
{ {
protected $table = 'an_anagrafiche'; protected $table = 'an_anagrafiche';
protected $primaryKey = 'idanagrafica'; protected $primaryKey = 'idanagrafica';
/** @var array Opzioni abilitate per la creazione */
protected $fillable = [
'ragione_sociale',
];
protected $appends = [
'id',
'partita_iva',
];
protected $hidden = [
'idanagrafica',
'piva',
];
/**
* Crea una nuova fattura.
*
* @param int $id_anagrafica
* @param string $data
* @param int $id_segment
*/
public static function create(array $attributes = [])
{
$model = static::query()->create($attributes);
// Completamento informazioni
$model->updateTipologie((array)$attributes['tipologie']);
$ultimo = database()->fetchOne('SELECT codice FROM an_anagrafiche ORDER BY CAST(codice AS SIGNED) DESC LIMIT 1');
$codice = Generator::generate(setting('Formato codice anagrafica'), $ultimo['codice']);
$model->codice = $codice;
$model->save();
return $model;
}
public static function fixAzienda(Anagrafica $anagrafica)
{
Settings::setValue('Azienda predefinita', $anagrafica->id);
}
public static function fixCliente(Anagrafica $anagrafica)
{
$database = database();
// Creo il relativo conto nel partitario se non esiste
if (empty($anagrafica->idconto_cliente)) {
// Calcolo prossimo numero cliente
$rs = $database->fetchArray("SELECT MAX(CAST(co_pianodeiconti3.numero AS UNSIGNED)) AS max_numero FROM co_pianodeiconti3 INNER JOIN co_pianodeiconti2 ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id WHERE co_pianodeiconti2.descrizione='Crediti clienti e crediti diversi'");
$new_numero = $rs[0]['max_numero'] + 1;
$new_numero = str_pad($new_numero, 6, '0', STR_PAD_LEFT);
$database->query('INSERT INTO co_pianodeiconti3(numero, descrizione, idpianodeiconti2, can_delete, can_edit) VALUES('.prepare($new_numero).', '.prepare(post('ragione_sociale')).", (SELECT id FROM co_pianodeiconti2 WHERE descrizione='Crediti clienti e crediti diversi'), 1, 1)");
$idconto = $database->lastInsertedID();
// Collegamento conto
$anagrafica->idconto_cliente = $idconto;
$anagrafica->save();
}
}
public static function fixFornitore(Anagrafica $anagrafica)
{
$database = database();
// Creo il relativo conto nel partitario se non esiste
if (empty($anagrafica->idconto_fornitore)) {
// Calcolo prossimo numero cliente
$rs = $database->fetchArray("SELECT MAX(CAST(co_pianodeiconti3.numero AS UNSIGNED)) AS max_numero FROM co_pianodeiconti3 INNER JOIN co_pianodeiconti2 ON co_pianodeiconti3.idpianodeiconti2=co_pianodeiconti2.id WHERE co_pianodeiconti2.descrizione='Debiti fornitori e debiti diversi'");
$new_numero = $rs[0]['max_numero'] + 1;
$new_numero = str_pad($new_numero, 6, '0', STR_PAD_LEFT);
$database->query('INSERT INTO co_pianodeiconti3(numero, descrizione, idpianodeiconti2, can_delete, can_edit) VALUES('.prepare($new_numero).', '.prepare(post('ragione_sociale')).", (SELECT id FROM co_pianodeiconti2 WHERE descrizione='Debiti fornitori e debiti diversi'), 1, 1)");
$idconto = $database->lastInsertedID();
// Collegamento conto
$anagrafica->idconto_fornitore = $idconto;
$anagrafica->save();
}
}
public static function fixTecnico(Anagrafica $anagrafica)
{
// Copio già le tariffe per le varie attività
if (in_array($id_tecnico, $idtipoanagrafica)) {
$result = $database->query('INSERT INTO in_tariffe(idtecnico, idtipointervento, costo_ore, costo_km, costo_dirittochiamata, costo_ore_tecnico, costo_km_tecnico, costo_dirittochiamata_tecnico) SELECT '.prepare($model->id).', idtipointervento, costo_orario, costo_km, costo_diritto_chiamata, costo_orario_tecnico, costo_km_tecnico, costo_diritto_chiamata_tecnico FROM in_tipiintervento');
if (!$result) {
flash()->error(tr("Errore durante l'importazione tariffe!"));
}
}
}
/**
* Aggiorna la tipologia dell'anagrafica.
*
* @param array $tipologie
* @return void
*/
public function updateTipologie(array $tipologie)
{
if ($this->isAzienda()) {
$tipologie[] = Tipo::where('descrizione', 'Azienda')->first()->id;
}
$previous = $this->tipi()->get();
$this->tipi()->sync($tipologie);
$actual = $this->tipi()->get();
$diff = $actual->diff($previous);
foreach ($diff as $tipo) {
$method = 'fix'.$tipo->descrizione;
if (method_exists($this, $method)) {
self::$method($this);
}
}
}
/**
* Controlla se l'anagrafica è di tipo 'Azienda'.
*
* @return bool
*/
public function isAzienda()
{
return $this->tipi()->get()->search(function ($item, $key) {
return $item->descrizione == 'Azienda';
}) !== false ;
}
/**
* Restituisce l'identificativo.
*
* @return int
*/
public function getIdAttribute()
{
return $this->idanagrafica;
}
public function setCodiceAttribute($value)
{
if (self::where([
['codice', $value],
[$this->primaryKey, '<>', $this->id]
])->count() == 0) {
$this->attributes['codice'] = $value;
}
}
public function getPartitaIvaAttribute()
{
return $this->piva;
}
public function setPartitaIvaAttribute($value)
{
$this->attributes['piva'] = trim(strtoupper($value));
}
public function setCodiceFiscaleAttribute($value)
{
$this->attributes['codice_fiscale'] = trim(strtoupper($value));
}
public function tipi()
{
return $this->belongsToMany(Tipo::class, 'an_tipianagrafiche_anagrafiche', 'idanagrafica', 'idtipoanagrafica');
}
public function fatture() public function fatture()
{ {
return $this->hasMany(Fattura::class, 'idanagrafica'); return $this->hasMany(Fattura::class, 'idanagrafica');
} }
public function nazione()
{
return $this->belongsTo(Nazione::class, 'id_nazione');
}
/**
* Restituisce la sede legale collegata.
*
* @return self
*/
public function sedeLegale()
{
return $this;
}
} }

View File

@ -0,0 +1,15 @@
<?php
namespace Modules\Anagrafiche;
use Illuminate\Database\Eloquent\Model;
class Nazione extends Model
{
protected $table = 'an_nazioni';
public function anagrafiche()
{
return $this->hasMany(Anagrafica::class, 'id_nazione');
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace Modules\Anagrafiche;
use Illuminate\Database\Eloquent\Model;
class Tipo extends Model
{
protected $table = 'an_tipianagrafiche';
protected $primaryKey = 'idtipoanagrafica';
protected $appends = [
'id',
];
protected $hidden = [
'idtipoanagrafica',
];
/**
* Restituisce l'identificativo.
*
* @return int
*/
public function getIdAttribute()
{
return $this->idtipoanagrafica;
}
public function anagrafiche()
{
return $this->hasMany(Anagrafica::class, 'an_tipianagrafiche_anagrafiche', 'idtipoanagrafica', 'idanagrafica');
}
}

View File

@ -29,7 +29,7 @@ switch (post('op')) {
'idanagrafica' => $idanagrafica, 'idanagrafica' => $idanagrafica,
'data' => $data, 'data' => $data,
'id_segment' => $id_segment, 'id_segment' => $id_segment,
'idtipodocumento' => $idtipodocumento, 'tipo' => $idtipodocumento,
]); ]);
$id_record = $fattura->id; $id_record = $fattura->id;

View File

@ -35,6 +35,7 @@ $id_anagrafica = !empty(get('idanagrafica')) ? get('idanagrafica') : $user['idan
<div class="col-md-6"> <div class="col-md-6">
{[ "type": "select", "label": "<?php echo tr('Tipo fattura'); ?>", "name": "idtipodocumento", "required": 1, "values": "query=SELECT id, descrizione FROM co_tipidocumento WHERE dir='<?php echo $dir; ?>'" ]} {[ "type": "select", "label": "<?php echo tr('Tipo fattura'); ?>", "name": "idtipodocumento", "required": 1, "values": "query=SELECT id, descrizione FROM co_tipidocumento WHERE dir='<?php echo $dir; ?>'" ]}
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
{[ "type": "select", "label": "<?php echo tr('Sezionale'); ?>", "name": "id_segment", "required": 1, "values": "query=SELECT id, name AS descrizione FROM zz_segments WHERE id_module='<?php echo $id_module; ?>' ORDER BY name", "value": "<?php echo $_SESSION['module_'.$id_module]['id_segment']; ?>" ]} {[ "type": "select", "label": "<?php echo tr('Sezionale'); ?>", "name": "id_segment", "required": 1, "values": "query=SELECT id, name AS descrizione FROM zz_segments WHERE id_module='<?php echo $id_module; ?>' ORDER BY name", "value": "<?php echo $_SESSION['module_'.$id_module]['id_segment']; ?>" ]}
</div> </div>

View File

@ -251,7 +251,7 @@ if ($tipodoc == 'Fattura accompagnatoria di vendita') {
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
{[ "type": "select", "label": "'.tr('Vettore').'", "name": "idvettore", "values": "query=SELECT DISTINCT an_anagrafiche.idanagrafica AS id, an_anagrafiche.ragione_sociale AS descrizione FROM an_anagrafiche INNER JOIN an_tipianagrafiche_anagrafiche ON an_anagrafiche.idanagrafica=an_tipianagrafiche_anagrafiche.idanagrafica WHERE an_tipianagrafiche_anagrafiche.idtipoanagrafica=(SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE descrizione=\'Vettore\') ORDER BY descrizione ASC", "value": "$idvettore$" ]} {[ "type": "select", "label": "'.tr('Vettore').'", "name": "idvettore", "values": "query=SELECT DISTINCT an_anagrafiche.idanagrafica AS id, an_anagrafiche.ragione_sociale AS descrizione FROM an_anagrafiche INNER JOIN an_tipianagrafiche_anagrafiche ON an_anagrafiche.idanagrafica=an_tipianagrafiche_anagrafiche.idanagrafica WHERE an_tipianagrafiche_anagrafiche.idtipoanagrafica=(SELECT idtipoanagrafica FROM an_tipianagrafiche WHERE descrizione=\'Vettore\') ORDER BY descrizione ASC", "value": "$idvettore$", "required": 1 ]}
</div> </div>
</div> </div>
</div> </div>

View File

@ -31,7 +31,7 @@ class Fattura extends Model
{ {
$model = static::query()->create($attributes); $model = static::query()->create($attributes);
$tipo_documento = Tipo::find($attributes['idtipodocumento']); $tipo_documento = Tipo::find($attributes['tipo']);
$stato_documento = Stato::where('descrizione', 'Bozza')->first(); $stato_documento = Stato::where('descrizione', 'Bozza')->first();
$direzione = $tipo_documento->dir; $direzione = $tipo_documento->dir;
@ -40,7 +40,7 @@ class Fattura extends Model
$id_anagrafica = $attributes['idanagrafica']; $id_anagrafica = $attributes['idanagrafica'];
$id_segment = $attributes['id_segment']; $id_segment = $attributes['id_segment'];
$dbo = database(); $database = database();
// Calcolo dei numeri fattura // Calcolo dei numeri fattura
$numero = static::getNumero($data, $direzione, $id_segment); $numero = static::getNumero($data, $direzione, $id_segment);
@ -55,7 +55,7 @@ class Fattura extends Model
} }
// Tipo di pagamento e banca predefinite dall'anagrafica // Tipo di pagamento e banca predefinite dall'anagrafica
$pagamento = $dbo->fetchOne('SELECT id, (SELECT idbanca_'.$conto.' FROM an_anagrafiche WHERE idanagrafica = ?) AS idbanca FROM co_pagamenti WHERE id = (SELECT idpagamento_'.$conto.' AS pagamento FROM an_anagrafiche WHERE idanagrafica = ?)', [ $pagamento = $database->fetchOne('SELECT id, (SELECT idbanca_'.$conto.' FROM an_anagrafiche WHERE idanagrafica = ?) AS idbanca FROM co_pagamenti WHERE id = (SELECT idpagamento_'.$conto.' AS pagamento FROM an_anagrafiche WHERE idanagrafica = ?)', [
$id_anagrafica, $id_anagrafica,
$id_anagrafica, $id_anagrafica,
]); ]);
@ -69,12 +69,12 @@ class Fattura extends Model
// Se non è impostata la banca dell'anagrafica, uso quella del pagamento. // Se non è impostata la banca dell'anagrafica, uso quella del pagamento.
if (empty($id_banca)) { if (empty($id_banca)) {
$id_banca = $dbo->fetchOne('SELECT id FROM co_banche WHERE id_pianodeiconti3 = (SELECT idconto_'.$conto.' FROM co_pagamenti WHERE id = :id_pagamento)', [ $id_banca = $database->fetchOne('SELECT id FROM co_banche WHERE id_pianodeiconti3 = (SELECT idconto_'.$conto.' FROM co_pagamenti WHERE id = :id_pagamento)', [
':id_pagamento' => $id_pagamento, ':id_pagamento' => $id_pagamento,
])['id']; ])['id'];
} }
$id_sede = $dbo->selectOne('an_anagrafiche', 'idsede_fatturazione', ['idanagrafica' => $id_anagrafica])['idsede_fatturazione']; $id_sede = $database->selectOne('an_anagrafiche', 'idsede_fatturazione', ['idanagrafica' => $id_anagrafica])['idsede_fatturazione'];
// Salvataggio delle informazioni // Salvataggio delle informazioni
$model->numero = $numero; $model->numero = $numero;
@ -104,11 +104,11 @@ class Fattura extends Model
*/ */
public static function getNumero($data, $direzione, $id_segment) public static function getNumero($data, $direzione, $id_segment)
{ {
$dbo = database(); $database = database();
$maschera = $direzione == 'uscita' ? static::getMaschera($id_segment) : '#'; $maschera = $direzione == 'uscita' ? static::getMaschera($id_segment) : '#';
$ultima_fattura = $dbo->fetchOne('SELECT numero_esterno FROM co_documenti WHERE YEAR(data) = :year AND id_segment = :id_segment '.static::getMascheraOrder($maschera), [ $ultima_fattura = $database->fetchOne('SELECT numero_esterno FROM co_documenti WHERE YEAR(data) = :year AND id_segment = :id_segment '.static::getMascheraOrder($maschera), [
':year' => date('Y', strtotime($data)), ':year' => date('Y', strtotime($data)),
':id_segment' => $id_segment, ':id_segment' => $id_segment,
]); ]);
@ -133,12 +133,12 @@ class Fattura extends Model
return ''; return '';
} }
$dbo = database(); $database = database();
// Recupero maschera per questo segmento // Recupero maschera per questo segmento
$maschera = static::getMaschera($id_segment); $maschera = static::getMaschera($id_segment);
$ultima_fattura = $dbo->fetchOne('SELECT numero_esterno FROM co_documenti WHERE YEAR(data) = :year AND id_segment = :id_segment '.static::getMascheraOrder($maschera), [ $ultima_fattura = $database->fetchOne('SELECT numero_esterno FROM co_documenti WHERE YEAR(data) = :year AND id_segment = :id_segment '.static::getMascheraOrder($maschera), [
':year' => date('Y', strtotime($data)), ':year' => date('Y', strtotime($data)),
':id_segment' => $id_segment, ':id_segment' => $id_segment,
]); ]);
@ -157,9 +157,9 @@ class Fattura extends Model
*/ */
protected static function getMaschera($id_segment) protected static function getMaschera($id_segment)
{ {
$dbo = database(); $database = database();
$maschera = $dbo->fetchOne('SELECT pattern FROM zz_segments WHERE id = :id_segment', [ $maschera = $database->fetchOne('SELECT pattern FROM zz_segments WHERE id = :id_segment', [
':id_segment' => $id_segment, ':id_segment' => $id_segment,
])['pattern']; ])['pattern'];

View File

@ -18,7 +18,7 @@ if (!empty($fattura_pa)) {
} }
// Campi obbligatori per l'anagrafica Azienda // Campi obbligatori per l'anagrafica Azienda
$azienda = Plugins\Fatturazione\FatturaElettronica::getAzienda(); $azienda = Plugins\ExportPA\FatturaElettronica::getAzienda();
$fields = [ $fields = [
'piva' => 'Partita IVA', 'piva' => 'Partita IVA',
// 'codice_fiscale' => 'Codice Fiscale', // 'codice_fiscale' => 'Codice Fiscale',

View File

@ -1,7 +1,7 @@
<?php <?php
try { try {
$fattura_pa = new Plugins\Fatturazione\FatturaElettronica($id_record); $fattura_pa = new Plugins\ExportPA\FatturaElettronica($id_record);
} catch (UnexpectedValueException $e) { } catch (UnexpectedValueException $e) {
} }

View File

@ -1,6 +1,6 @@
<?php <?php
namespace Plugins\Fatturazione; namespace Plugins\ExportPA;
use FluidXml\FluidXml; use FluidXml\FluidXml;
use Respect\Validation\Validator as v; use Respect\Validation\Validator as v;
@ -362,7 +362,7 @@ class FatturaElettronica
$result = [ $result = [
'DatiGeneraliDocumento' => static::getDatiGeneraliDocumento($fattura), 'DatiGeneraliDocumento' => static::getDatiGeneraliDocumento($fattura),
// TODO: DatiOrdineAcquisto, DatiContratto, DatiConvenzione, DatiRicezione, DatiFattureCollegate, DatiSAL, DatiDDT, DatiTrasporto, FatturaPrincipale // TODO: DatiOrdineAcquisto, DatiContratto, DatiConvenzione, DatiRicezione, DatiFattureCollegate, DatiSAL, DatiDDT, FatturaPrincipale
]; ];
if ($documento['tipo'] == 'Fattura accompagnatoria di vendita') { if ($documento['tipo'] == 'Fattura accompagnatoria di vendita') {

View File

@ -0,0 +1,42 @@
<?php
include_once __DIR__.'/../../core.php';
switch (filter('op')) {
case 'save':
$id = Uploads::getFakeID();
$filename = $upload = Uploads::upload($_FILES['blob'], [
'name' => tr('Fattura Elettronica'),
'category' => tr('Fattura Elettronica'),
'id_module' => $id_module,
'id_record' => $id,
]);
echo json_encode([
'id' => $id,
'filename' => $filename,
'id_segment' => post('id_segment'),
]);
break;
case 'generate':
$id = post('id');
$filename = post('filename');
$directory = Uploads::getDirectory($id_module);
$xml = file_get_contents(DOCROOT.'/'.$directory.'/'.$filename);
$fattura_pa = new Plugins\ImportPA\FatturaElettronica($xml);
$id_record = $fattura_pa->saveFattura(post('id_segment'), post('articoli'));
$fattura_pa->saveRighe(post('articoli'));
$fattura_pa->saveAllegati($directory);
Uploads::updateFake($id, $id_record);
redirect(ROOTDIR.'/editor.php?id_module='.$id_module.'&id_record='.$id_record);
break;
}

68
plugins/importPA/edit.php Normal file
View File

@ -0,0 +1,68 @@
<?php
include_once __DIR__.'/../../core.php';
echo '
<script>
function upload() {
if ($("#blob").val()) {
swal({
title: "'.tr('Avviare la procedura?').'",
type: "warning",
showCancelButton: true,
confirmButtonText: "'.tr('Sì').'"
}).then(function (result) {
$("#upload").ajaxSubmit({
url: globals.rootdir + "/actions.php",
data: {
op: "save",
id_module: "'.$id_module.'",
id_plugin: "'.$id_plugin.'",
},
type: "post",
success: function(data){
data = JSON.parse(data);
launch_modal("'.tr('Righe fattura').'", globals.rootdir + "/plugins/importPA/rows.php?id_module=" + globals.id_module + "&id_plugin=" + '.$id_plugin.' + "&id=" + data.id + "&filename=" + data.filename + "&id_segment" + data.id_segment)
},
error: function(data) {
alert("'.tr('Errore').': " + data);
}
});
})
} else {
swal({
title: "'.tr('Selezionare un file!').'",
type: "error",
})
}
}
</script>
<div class="box box-success">
<div class="box-header with-border">
<h3 class="box-title">
'.tr('Carica un XML').'</span>
</h3>
</div>
<div class="box-body" id="upload">
<div class="row">
<div class="col-md-9">
<label><input type="file" name="blob" id="blob"></label>
</div>
<div class="col-md-3">
{[ "type": "select", "label": "'.tr('Sezionale').'", "name": "id_segment", "required": 1, "values": "query=SELECT id, name AS descrizione FROM zz_segments WHERE id_module='.$id_module.' ORDER BY name", "value": "'.$_SESSION['module_'.$id_module]['id_segment'].'" ]}
</div>
</div>
<div class="row">
<div class="col-md-12 text-center">
<button type="button" class="btn btn-primary btn-lg" onclick="upload()">
<i class="fa fa-upload"></i> '.tr('Carica').'...
</button>
</div>
</div>
</div>
</div>';

65
plugins/importPA/rows.php Normal file
View File

@ -0,0 +1,65 @@
<?php
include_once __DIR__.'/../../core.php';
$directory = Uploads::getDirectory($id_module);
$xml = file_get_contents(DOCROOT.'/'.$directory.'/'.get('filename'));
$fattura_pa = new Plugins\ImportPA\FatturaElettronica($xml);
$righe = $fattura_pa->getRighe();
echo '
<form action="'.$rootdir.'/actions.php" method="post">
<input type="hidden" name="id_module" value="'.$id_module.'">
<input type="hidden" name="id_plugin" value="'.$id_plugin.'">
<input type="hidden" name="filename" value="'.get('filename').'">
<input type="hidden" name="id_segment" value="'.get('id_segment').'">
<input type="hidden" name="id" value="'.get('id').'">
<input type="hidden" name="backto" value="record-edit">
<input type="hidden" name="op" value="generate">';
if (!empty($righe)) {
echo '
<table class="table table-hover table-striped">
<tr>
<th width="10%">'.tr('Riga').'</th>
<th width="40%">'.tr('Descrizione').'</th>
<th width="15%">'.tr('Quantità').'</th>
<th width="15%">'.tr('Prezzo unitario').'</th>
<th width="20%">'.tr('Articolo associato').'</th>
</tr>';
foreach ($righe as $key => $riga) {
echo '
<tr>
<td>'.$key.'</td>
<td>'.$riga['Descrizione'].'</td>
<td>'.$riga['Quantita'].' '.$riga['UnitaMisura'].'</td>
<td>'.$riga['PrezzoUnitario'].'</td>
<td>
{[ "type": "select", "name": "articoli['.$key.']", "ajax-source": "articoli" ]}
</td>
</tr>';
}
echo '
</table>';
} else {
echo '
<p>Non ci sono righe nella fattura.</p>';
}
echo '
<div class="row">
<div class="col-md-12 text-right">
<button type="submit" class="btn btn-primary">
<i class="fa fa-arrow-right"></i> '.tr('Continua').'...
</button>
</div>
</div>
</form>';
echo '
<script src="'.$rootdir.'/lib/init.js"></script>';

View File

@ -0,0 +1,215 @@
<?php
namespace Plugins\ImportPA;
use Modules\Fatture\Fattura;
use Modules\Fatture\Stato as StatoFattura;
use Modules\Fatture\Tipo as TipoFattura;
use Modules\Anagrafiche\Anagrafica;
use Modules\Anagrafiche\Tipo as TipoAnagrafica;
use Modules\Anagrafiche\Nazione;
use Uploads;
use Modules;
/**
* Classe per la gestione della fatturazione elettronica in XML.
*
* @since 2.4.2
*/
class FatturaElettronica
{
/** @var array XML della fattura */
protected $xml = null;
/** @var Fattura Fattura collegata */
protected $fattura = null;
public function __construct($content)
{
$xml = simplexml_load_string($content, "SimpleXMLElement", LIBXML_NOCDATA);
$json = json_encode($xml);
$array = json_decode($json, true);
$this->xml = $array;
}
public function getFattura()
{
return $this->fattura;
}
public function getHeader()
{
return $this->xml['FatturaElettronicaHeader'];
}
public function getBody()
{
return $this->xml['FatturaElettronicaBody'];
}
public static function createAnagrafica($xml, $type = 'Fornitore')
{
$database = database();
$where = [];
$partita_iva = $xml['DatiAnagrafici']['IdFiscaleIVA']['IdCodice'];
if (!empty($partita_iva)) {
$where[] = '`piva` = '.prepare($partita_iva);
}
$codice_fiscale = $xml['DatiAnagrafici']['CodiceFiscale'];
if (!empty($codice_fiscale)) {
$where[] = '`codice_fiscale` = '.prepare($codice_fiscale);
}
$id_anagrafica = $database->fetchOne('SELECT `an_anagrafiche`.`idanagrafica` FROM `an_anagrafiche`
INNER JOIN `an_tipianagrafiche_anagrafiche` ON `an_anagrafiche`.`idanagrafica` = `an_tipianagrafiche_anagrafiche`.`idanagrafica`
INNER JOIN `an_tipianagrafiche` ON `an_tipianagrafiche`.`idtipoanagrafica` = `an_tipianagrafiche_anagrafiche`.`idtipoanagrafica`
WHERE `an_tipianagrafiche`.`descrizione` = '.prepare($type).' AND ('.implode(' OR ', $where).')')['idanagrafica'];
if (!empty($id_anagrafica)) {
return $id_anagrafica;
}
$ragione_sociale = $xml['DatiAnagrafici']['Anagrafica']['Denominazione'] ?: $xml['DatiAnagrafici']['Anagrafica']['Nome'].' '.$xml['DatiAnagrafici']['Anagrafica']['Cognome'];
$anagrafica = Anagrafica::create([
'ragione_sociale' => $ragione_sociale,
'tipologie' => [
TipoAnagrafica::where('descrizione', 'Fornitore')->first()->id
],
]);
// Informazioni sull'anagrafica
$REA = $xml['IscrizioneREA'];
if (!empty($REA)) {
$anagrafica->codicerea = $REA['Ufficio'].'-'.$REA['NumeroREA'];
if (!empty($REA['CapitaleSociale'])) {
$anagrafica->capitale_sociale = $REA['CapitaleSociale'];
}
}
$anagrafica->save();
// Informazioni sulla sede
$info = $xml['Sede'];
$sede = $anagrafica->sedeLegale();
if (!empty($partita_iva)) {
$sede->partita_iva = $partita_iva;
}
if (!empty($codice_fiscale)) {
$sede->codice_fiscale = $codice_fiscale;
}
$sede->indirizzo = $info['Indirizzo'];
$sede->cap = $info['CAP'];
$sede->citta = $info['Comune'];
$sede->indirizzo = $info['Indirizzo'];
$sede->nazione()->associate(Nazione::where('iso2', $info['Nazione'])->first());
if (!empty($info['Provincia'])) {
$sede->provincia = $info['Provincia'];
}
$contatti = $xml['Contatti'];
if (!empty($contatti)) {
if (!empty($contatti['Telefono'])) {
$sede->telefono = $contatti['Telefono'];
}
if (!empty($contatti['Fax'])) {
$sede->fax = $contatti['Fax'];
}
if (!empty($contatti['email'])) {
$sede->email = $contatti['email'];
}
}
$sede->save();
return $anagrafica->id;
}
public function saveRighe($articoli)
{
$righe = $this->getRighe();
}
public function getRighe()
{
return $this->getBody()['DatiBeniServizi']['DettaglioLinee'];
}
public static function existsFattura($id_anagrafica, $data, $numero, $id_tipo)
{
return database()->fetchOne('SELECT `id` FROM `co_documenti` WHERE idanagrafica = '.prepare($id_anagrafica) .' AND idtipodocumento = '.prepare($id_tipo).' AND data = '.prepare($data).' AND numero = '.prepare($numero));
}
public function saveAllegati($directory)
{
$allegati = $this->getBody()['Allegati'];
if (!isset($allegati[0])) {
$allegati = [$allegati];
}
foreach ($allegati as $allegato) {
$content = base64_decode($allegato['Attachment']);
$filename = $directory.'/'.$allegato['NomeAttachment'].'.'.strtolower($allegato['FormatoAttachment']);
file_put_contents($filename, $content);
Uploads::register([
'original' => $allegato['NomeAttachment'],
'category' => tr('Fattura elettronica'),
'id_module' => Modules::get('Fatture di acquisto')['id'],
'id_record' => $this->fattura->id,
]);
}
}
/**
* Registra la fattura elettronica come fattura del gestionale.
*
* @param int $id_segment
* @return int
*/
public function saveFattura($id_segment)
{
$id_anagrafica = static::createAnagrafica($this->getHeader()['CedentePrestatore']);
$dati_generali = $this->getBody()['DatiGenerali']['DatiGeneraliDocumento'];
$data = $dati_generali['Data'];
$numero = $dati_generali['Numero'];
$tipo = empty($this->getBody()['DatiGenerali']['DatiTrasporto']) ? TipoFattura::where('descrizione', 'Fattura immediata di acquisto') : TipoFattura::where('descrizione', 'Fattura accompagnatoria di acquisto');
$id_tipo = $tipo->first()->id;
$result = self::existsFattura($id_anagrafica, $data, $numero, $id_tipo);
// Fattura già inserita
if (!empty($result)) {
$this->fattura = Fattura::find($result['id']);
return $result['id'];
}
$fattura = Fattura::create([
'idanagrafica' => $id_anagrafica,
'data' => $data,
'id_segment' => $id_segment,
'tipo' => $id_tipo,
]);
$fattura->numero = $numero;
$stato_documento = StatoFattura::where('descrizione', 'Emessa')->first();
$fattura->stato()->associate($stato_documento);
$fattura->save();
$this->fattura = $fattura;
return $fattura->id;
}
}

View File

@ -238,6 +238,9 @@ class Backup
// Rimozione del database // Rimozione del database
$tables = include DOCROOT.'/update/tables.php'; $tables = include DOCROOT.'/update/tables.php';
// Ripristino del database
$database_file = $extraction_dir.'/database.sql';
if (file_exists($database_file)) {
$database->query('SET foreign_key_checks = 0'); $database->query('SET foreign_key_checks = 0');
foreach ($tables as $tables) { foreach ($tables as $tables) {
$database->query('DROP TABLE `'.$tables.'`'); $database->query('DROP TABLE `'.$tables.'`');
@ -245,8 +248,9 @@ class Backup
$database->query('DROP TABLE `updates`'); $database->query('DROP TABLE `updates`');
// Ripristino del database // Ripristino del database
$database->multiQuery($extraction_dir.'/database.sql'); $database->multiQuery($database_file);
$database->query('SET foreign_key_checks = 1'); $database->query('SET foreign_key_checks = 1');
}
// Salva il file di configurazione // Salva il file di configurazione
$config = file_get_contents(DOCROOT.'/config.inc.php'); $config = file_get_contents(DOCROOT.'/config.inc.php');

View File

@ -272,7 +272,7 @@ class Uploads
*/ */
public static function updateFake($fake_id, $id_record) public static function updateFake($fake_id, $id_record)
{ {
$database->update('zz_files', [ database()->update('zz_files', [
'id_record' => $id_record, 'id_record' => $id_record,
], [ ], [
'id_record' => $fake_id, 'id_record' => $fake_id,

View File

@ -10,7 +10,7 @@ class FatturaTest extends \Codeception\Test\Unit
'idanagrafica' => 1, 'idanagrafica' => 1,
'data' => $data, 'data' => $data,
'id_segment' => 1, 'id_segment' => 1,
'idtipodocumento' => 2, 'tipo' => 2,
]); ]);
$this->assertEquals($fattura->idanagrafica, 1); $this->assertEquals($fattura->idanagrafica, 1);

View File

@ -648,6 +648,12 @@ foreach ($movimenti as $movimento) {
$dbo->query("UPDATE mg_movimenti SET data = created_at WHERE data = '0000-00-00'"); $dbo->query("UPDATE mg_movimenti SET data = created_at WHERE data = '0000-00-00'");
// Fix Partite IVA
foreach ($it as $key => $value) {
$dbo->query("UPDATE `an_anagrafiche` SET `piva` = SUBSTRING(`piva`, 2) WHERE `piva` LIKE '".$key."%'");
}
// File e cartelle deprecate // File e cartelle deprecate
$files = [ $files = [
'docs', 'docs',

View File

@ -370,7 +370,9 @@ INSERT INTO `zz_settings` (`idimpostazione`, `nome`, `valore`, `tipo`, `editable
ALTER TABLE `an_anagrafiche` ADD `codice_destinatario` varchar(7); ALTER TABLE `an_anagrafiche` ADD `codice_destinatario` varchar(7);
-- Plugin Fatturazione Elettronica -- Plugin Fatturazione Elettronica
INSERT INTO `zz_plugins` (`id`, `name`, `title`, `idmodule_from`, `idmodule_to`, `position`, `directory`, `options`) VALUES (NULL, 'Fatturazione Elettronica', 'Fatturazione Elettronica', (SELECT `id` FROM `zz_modules` WHERE `name`='Fatture di vendita'), (SELECT `id` FROM `zz_modules` WHERE `name`='Fatture di vendita'), 'tab', 'fatturazione', 'custom'); INSERT INTO `zz_plugins` (`id`, `name`, `title`, `idmodule_from`, `idmodule_to`, `position`, `directory`, `options`) VALUES
(NULL, 'Fatturazione Elettronica', 'Fatturazione Elettronica', (SELECT `id` FROM `zz_modules` WHERE `name`='Fatture di vendita'), (SELECT `id` FROM `zz_modules` WHERE `name`='Fatture di vendita'), 'tab', 'exportPA', 'custom'),
(NULL, 'Fatturazione Elettronica', 'Fatturazione Elettronica', (SELECT `id` FROM `zz_modules` WHERE `name`='Fatture di vendita'), (SELECT `id` FROM `zz_modules` WHERE `name`='Fatture di acquisto'), 'tab_main', 'importPA', 'custom');
--INSERT INTO `zz_emails` (`id`, `id_module`, `id_smtp`, `name`, `icon`, `subject`, `reply_to`, `cc`, `bcc`, `body`, `read_notify`, `main`) VALUES (NULL, (SELECT `id` FROM `zz_modules` WHERE `name` = 'Fatture di vendita'), 1, 'Fattura Elettronica', 'fa fa-file', 'Invio fattura numero {numero} del {data}', '', 'sdi01@pec.fatturapa.it', '', '<p>Gentile Cliente,</p>\r\n<p>inviamo in allegato la fattura numero {numero} del {data}.</p>\r\n<p>&nbsp;</p>\r\n<p>Distinti saluti</p>\r\n', '0', '0'); --INSERT INTO `zz_emails` (`id`, `id_module`, `id_smtp`, `name`, `icon`, `subject`, `reply_to`, `cc`, `bcc`, `body`, `read_notify`, `main`) VALUES (NULL, (SELECT `id` FROM `zz_modules` WHERE `name` = 'Fatture di vendita'), 1, 'Fattura Elettronica', 'fa fa-file', 'Invio fattura numero {numero} del {data}', '', 'sdi01@pec.fatturapa.it', '', '<p>Gentile Cliente,</p>\r\n<p>inviamo in allegato la fattura numero {numero} del {data}.</p>\r\n<p>&nbsp;</p>\r\n<p>Distinti saluti</p>\r\n', '0', '0');
--INSERT INTO `zz_email_print` (`id`, `id_email`, `id_print`) VALUES (NULL, (SELECT `id` FROM `zz_emails` WHERE `name` = 'Fattura Elettronica' AND `id_module` = (SELECT `id` FROM `zz_modules` WHERE `name` = 'Fatture di vendita')), (SELECT `id` FROM `zz_prints` WHERE `name` = 'Fattura di vendita')); --INSERT INTO `zz_email_print` (`id`, `id_email`, `id_print`) VALUES (NULL, (SELECT `id` FROM `zz_emails` WHERE `name` = 'Fattura Elettronica' AND `id_module` = (SELECT `id` FROM `zz_modules` WHERE `name` = 'Fatture di vendita')), (SELECT `id` FROM `zz_prints` WHERE `name` = 'Fattura di vendita'));
@ -477,3 +479,6 @@ INSERT INTO `zz_email_print` (`id`, `id_email`, `id_print`) VALUES
UPDATE `zz_emails` SET `main` = 1 WHERE `name` = 'Rapportino intervento' AND `id_module` = (SELECT `id` FROM `zz_modules` WHERE `name` = 'Interventi'); UPDATE `zz_emails` SET `main` = 1 WHERE `name` = 'Rapportino intervento' AND `id_module` = (SELECT `id` FROM `zz_modules` WHERE `name` = 'Interventi');
UPDATE `in_statiintervento` SET `id_email` = (SELECT `id` FROM `zz_emails` WHERE `name` = 'Stato intervento' AND `id_module` = (SELECT `id` FROM `zz_modules` WHERE `name` = 'Interventi')); UPDATE `in_statiintervento` SET `id_email` = (SELECT `id` FROM `zz_emails` WHERE `name` = 'Stato intervento' AND `id_module` = (SELECT `id` FROM `zz_modules` WHERE `name` = 'Interventi'));
-- Correzione partite ive e codici fiscali
UPDATE `an_anagrafiche` SET `piva` = REPLACE(`piva`, ' ', ''), `codice_fiscale` = REPLACE(`codice_fiscale`, ' ', '');