.
*/
use Carbon\Carbon;
use Models\Module;
use Models\Plugin;
use Modules\Anagrafiche\Anagrafica;
use Modules\DDT\Stato as StatoDDT;
use Modules\Fatture\Fattura;
use Modules\Fatture\Gestori\Bollo;
use Modules\Fatture\Stato as StatoFattura;
use Modules\Interventi\Intervento;
use Modules\Iva\Aliquota;
use Modules\Ordini\Stato as StatoOrdine;
use Plugins\ExportFE\Interaction;
include_once __DIR__.'/../../core.php';
$anagrafica_azienda = Anagrafica::find(setting('Azienda predefinita'));
$id_stato_bozza = (new StatoFattura())->getByField('name', 'Bozza', Models\Locale::getPredefined()->id);
$id_stato_emessa = (new StatoFattura())->getByField('name', 'Emessa', Models\Locale::getPredefined()->id);
$id_stato_pagato = (new StatoFattura())->getByField('name', 'Pagato', Models\Locale::getPredefined()->id);
$id_stato_parz_pagato = (new StatoFattura())->getByField('name', 'Parzialmente pagato', Models\Locale::getPredefined()->id);
$id_stato_non_valida = (new StatoFattura())->getByField('name', 'Non valida', Models\Locale::getPredefined()->id);
$id_stato_annullata = (new StatoFattura())->getByField('name', 'Annullata', Models\Locale::getPredefined()->id);
$block_edit = !empty($note_accredito) || in_array($fattura->stato->id, [$id_stato_parz_pagato, $id_stato_pagato, $id_stato_emessa]) || !$abilita_genera;
if ($dir == 'entrata') {
$conto = 'vendite';
} else {
$conto = 'acquisti';
}
// Informazioni sulla dichiarazione d'intento, visibili solo finché la fattura è in bozza
if ($dir == 'entrata' && !empty($fattura->dichiarazione)) {
$diff = $fattura->dichiarazione->massimale - $fattura->dichiarazione->totale;
$diff_in_days = Carbon::parse($fattura->dichiarazione->data_fine)->diffAsCarbonInterval($fattura->data);
$id_iva = setting("Iva per lettere d'intento");
$iva = Aliquota::find($id_iva);
if (!empty($iva)) {
if ($diff == 0) {
echo '
'.tr("La dichiarazione d'intento _PROTOCOLLO_ ha raggiunto il massimale previsto di _MONEY_.", [
'_MONEY_' => moneyFormat(abs($fattura->dichiarazione->massimale)),
'_PROTOCOLLO_' => $fattura->dichiarazione->numero_protocollo,
]).'.
';
} elseif ($diff < 0) {
echo '
'.tr("La dichiarazione d'intento _PROTOCOLLO_ ha superato il massimale previsto di _MONEY_.", [
'_MONEY_' => moneyFormat(abs($diff)),
'_PROTOCOLLO_' => $fattura->dichiarazione->numero_protocollo,
]).'.
';
} elseif ($diff_in_days < 0) {
echo '
'.tr("La dichiarazione d'intento _PROTOCOLLO_ ha come data fine validità _SCADENZA_ mentre la fattura ha data _DATA_", [
'_SCADENZA_' => dateFormat($fattura->dichiarazione->data_fine),
'_DATA_' => dateFormat($fattura->data),
'_PROTOCOLLO_' => $fattura->dichiarazione->numero_protocollo,
]).'.
';
}
} else {
// TODO link ad impostazioni con nuova ricerca rapida
echo '
'.tr("Attenzione nessuna aliq. IVA definita per la dichiarazione d'intento. _SETTING_", [
'_SETTING_' => Modules::link('Impostazioni', null, tr('Selezionala dalle impostazioni'), true, null, true, null, "&search=Iva per lettere d'intento"),
]).'
';
}
}
// Autofattura
if (!empty($fattura_acquisto_originale)) {
echo '
'.tr("Questa è un'autofattura generata da una fattura di acquisto").':
'.Modules::link('Fatture di acquisto', $fattura_acquisto_originale->id, tr('Fattura num. _NUM_ del _DATE_', [
'_NUM_' => $fattura_acquisto_originale->numero_esterno,
'_DATE_' => dateFormat($fattura_acquisto_originale->data),
])).'
';
}
if ($abilita_autofattura) {
echo '
'.tr("Per questa fattura è prevista la generazione di un'autofattura tramite Crea » Autofattura").'.
'.tr('Questa autofattura è già stata importata come fattura di acquisto').':
'.Modules::link('Fatture di acquisto', $autofattura_collegata->id, tr('Fattura num. _NUM_ del _DATE_', [
'_NUM_' => $autofattura_collegata->numero_esterno,
'_DATE_' => dateFormat($autofattura_collegata->data),
])).'
';
}
// Note di credito collegate
if (!empty($note_accredito)) {
echo '
'.tr('Note di credito collegate').':';
foreach ($note_accredito as $nota) {
$text = tr('Rif. fattura _NUM_ del _DATE_', [
'_NUM_' => $nota['numero'],
'_DATE_' => Translator::dateToLocale($nota['data']),
]);
echo '
'.Modules::link($dir == 'entrata' ? 'Fatture di vendita' : 'Fatture di acquisto', $nota['id'], $text, $text);
}
echo '
';
}
// Fattura originale della Nota di credito
if (!empty($fattura->ref_documento) && $fattura->isNota()) {
$nota = Fattura::find($fattura->ref_documento);
echo '
'.tr('Questa è una _TIPO_ generata dalla seguente fattura', [
'_TIPO_' => $fattura->tipo->getTranslation('name'),
]).':
'.Modules::link($module->getTranslation('name'), $fattura->ref_documento, tr('Fattura num. _NUM_ del _DATE_', [
'_NUM_' => $nota->numero_esterno,
'_DATE_' => dateFormat($nota->data),
])).'
';
}
// Ricordo che si sta emettendo una fattura conto terzi
if ($dir == 'entrata' && $fattura->stato->id == $id_stato_bozza) {
if ($fattura->is_fattura_conto_terzi) {
echo '
'.tr("Questa è una fattura per conto di terzi. Nell'XML della Fattura Elettronica sarà indicato il fornitore _FORNITORE_ come cessionario e il cliente come cedente/prestatore", ['_FORNITORE_' => '"'.stripslashes($database->fetchOne('SELECT ragione_sociale FROM an_anagrafiche WHERE idanagrafica = '.prepare(setting('Azienda predefinita')))['ragione_sociale']).'"']).'.
';
}
}
// Verifica aggiuntive sulla sequenzialità dei numeri
if ($dir == 'entrata') {
// Calcolo il numero previsto solo se la data della fattura è maggiore o uguale all'impostazione "Data inizio verifica contatore fattura di vendita" oppure l'impostazione non è valorizzata.
if (!empty(setting('Data inizio verifica contatore fattura di vendita'))) {
$dateFormat = 'd/m/Y';
$carbonDate = Carbon::createFromFormat($dateFormat, setting('Data inizio verifica contatore fattura di vendita'));
$data_inizio_verifica_contatore = (($carbonDate !== false) ? $carbonDate->format('Y-m-d') : null);
}
if (strtotime($fattura->data) >= strtotime($data_inizio_verifica_contatore) || empty($data_inizio_verifica_contatore)) {
$numero_previsto = verifica_numero_fattura($fattura);
}
if (!empty($numero_previsto)) {
echo '
'.tr("E' assente una fattura di vendita di numero _NUM_ in data precedente o corrispondente a _DATE_: si potrebbero verificare dei problemi con la numerazione corrente delle fatture", [
'_DATE_' => dateFormat($fattura->data),
'_NUM_' => '"'.$numero_previsto.'"',
]).'.
'.tr('Questa fattura è stata scartata e sono trascorsi i termini di reinvio, è necessario invalidare il documento.').'
';
}
// Verifica la data dell'intervento rispetto alla data della fattura
$fatturazione_futura = false;
$data_fattura = new Carbon($fattura->data);
$interventi_collegati = $fattura->getDocumentiCollegati()[Intervento::class];
if (!empty($interventi_collegati)) {
foreach ($interventi_collegati as $intervento) {
$fine_intervento = $intervento->fine;
$fine_intervento = new Carbon($fine_intervento);
if ($fine_intervento->diffInDays($data_fattura, false) < 0) {
$fatturazione_futura = true;
break;
}
}
if ($fatturazione_futura) {
echo '
'.tr("Stai fatturando un'attività futura rispetto alla data di fatturazione.").'
';
}
}
}
$righe = $fattura->getRighe();
$righe_vuote = false;
foreach ($righe as $riga) {
if ($riga->qta == 0) {
$righe_vuote = true;
}
}
if ($righe_vuote) {
echo '
'.tr('Nel documento sono presenti delle righe con quantità a 0.').'
';
}
if ($fattura->stato->id == $id_stato_bozza) {
echo '
'.tr("La fattura è collegata ad una dichiarazione d'intento con diponibilità residura pari a _MONEY_.", ['_MONEY_' => moneyFormat($diff)]).' '.tr('Per collegare una riga alla dichiarazione è sufficiente specificare come IVA
_IVA_
', ['_IVA_' => $descrizione_iva_accettata]).'
';
}
}
echo '
'.tr('Righe').'
';
if (!$block_edit) {
if (empty($record['ref_documento'])) {
if ($dir == 'entrata') {
$where = '';
// Lettura interventi non collegati a preventivi, ordini e contratti
if (!setting('Permetti fatturazione delle attività collegate a contratti')) {
$where = ' AND in_interventi.id_contratto IS NULL';
}
if (!setting('Permetti fatturazione delle attività collegate a ordini')) {
$where .= ' AND in_interventi.id_ordine IS NULL';
}
if (!setting('Permetti fatturazione delle attività collegate a preventivi')) {
$where .= ' AND in_interventi.id_preventivo IS NULL';
}
// Lettura interventi non rifiutati, non fatturati
$int_query = 'SELECT COUNT(*) AS tot FROM `in_interventi` INNER JOIN `in_statiintervento` ON `in_interventi`.`idstatointervento`=`in_statiintervento`.`id` WHERE `idanagrafica`='.prepare($record['idanagrafica']).' AND `in_statiintervento`.`is_fatturabile`=1 AND `in_interventi`.`id` NOT IN (SELECT `idintervento` FROM `co_righe_documenti` WHERE `idintervento` IS NOT NULL) '.$where;
$interventi = $dbo->fetchArray($int_query)[0]['tot'];
// Se non trovo niente provo a vedere se ce ne sono per clienti terzi
if (empty($interventi)) {
// Lettura interventi non rifiutati, non fatturati
$int_query = 'SELECT COUNT(*) AS tot FROM `in_interventi` INNER JOIN `in_statiintervento` ON `in_interventi`.`idstatointervento`=`in_statiintervento`.`id` WHERE `idclientefinale`='.prepare($record['idanagrafica']).' AND `in_statiintervento`.`is_fatturabile`=1 AND `in_interventi`.`id` NOT IN (SELECT `idintervento` FROM `co_righe_documenti` WHERE `idintervento` IS NOT NULL) '.$where;
$interventi = $dbo->fetchArray($int_query)[0]['tot'];
}
// Lettura preventivi accettati, in attesa di conferma o in lavorazione
$prev_query = 'SELECT
COUNT(*) AS tot
FROM
`co_preventivi`
LEFT JOIN `co_righe_preventivi` ON `co_preventivi`.id = `co_righe_preventivi`.idpreventivo
INNER JOIN `co_statipreventivi` ON `co_statipreventivi`.id = `co_preventivi`.idstato
WHERE
`idanagrafica`='.prepare($record['idanagrafica']).' AND `co_statipreventivi`.`is_fatturabile` = 1 AND `default_revision` = 1 AND (`co_righe_preventivi`.`qta` - `co_righe_preventivi`.`qta_evasa`) > 0';
$preventivi = $dbo->fetchArray($prev_query)[0]['tot'];
// Lettura contratti accettati, in attesa di conferma o in lavorazione
$contr_query = 'SELECT COUNT(*) AS tot FROM `co_contratti` WHERE `idanagrafica`='.prepare($record['idanagrafica']).' AND `idstato` IN (SELECT `id` FROM `co_staticontratti` WHERE `is_fatturabile` = 1) AND `co_contratti`.`id` IN (SELECT `idcontratto` FROM `co_righe_contratti` WHERE `co_righe_contratti`.`idcontratto` = `co_contratti`.`id` AND (`qta` - `qta_evasa`) > 0)';
$contratti = $dbo->fetchArray($contr_query)[0]['tot'];
}
$id_stato_evaso = (new StatoDDT())->getByField('name', 'Evaso', Models\Locale::getPredefined()->id);
$id_stato_parz_evaso = (new StatoDDT())->getByField('name', 'Parziale evaso', Models\Locale::getPredefined()->id);
$id_stato_parz_fatt = (new StatoDDT())->getByField('name', 'Parziale fatturato', Models\Locale::getPredefined()->id);
// Lettura ddt (entrata o uscita)
$ddt_query = 'SELECT
COUNT(*) AS tot
FROM
`dt_ddt`
INNER JOIN `dt_causalet` ON `dt_causalet`.`id` = `dt_ddt`.`idcausalet`
INNER JOIN `dt_statiddt` ON `dt_statiddt`.`id` = `dt_ddt`.`idstatoddt`
LEFT JOIN `dt_statiddt_lang` ON (`dt_statiddt`.`id` = `dt_statiddt_lang`.`id_record` AND `dt_statiddt_lang`.`id_lang` = '.prepare(Models\Locale::getDefault()->id).')
LEFT JOIN `dt_tipiddt` ON `dt_tipiddt`.`id` = `dt_ddt`.`idtipoddt`
INNER JOIN `dt_righe_ddt` ON `dt_righe_ddt`.`idddt` = `dt_ddt`.`id`
WHERE
`idanagrafica`='.prepare($record['idanagrafica']).'
AND `dt_statiddt`.`id` IN ('.prepare($id_stato_evaso).','.prepare($id_stato_parz_evaso).','.prepare($id_stato_parz_fatt).')
AND `dt_tipiddt`.`dir` = '.prepare($dir).'
AND `dt_causalet`.`is_importabile` = 1
AND (`dt_righe_ddt`.`qta` - `dt_righe_ddt`.`qta_evasa`) > 0';
$ddt = $dbo->fetchArray($ddt_query)[0]['tot'];
// Lettura ordini (cliente o fornitore)
$id_stato_accettato = (new StatoOrdine())->getByField('name', 'Accettato', Models\Locale::getPredefined()->id);
$id_stato_evaso = (new StatoOrdine())->getByField('name', 'Evaso', Models\Locale::getPredefined()->id);
$id_stato_parz_evaso = (new StatoOrdine())->getByField('name', 'Parzialmente evaso', Models\Locale::getPredefined()->id);
$id_stato_parz_fatt = (new StatoOrdine())->getByField('name', 'Parzialmente fatturato', Models\Locale::getPredefined()->id);
$ordini_query = 'SELECT
COUNT(*) AS tot
FROM
`or_ordini`
INNER JOIN `or_righe_ordini` ON `or_ordini`.`id` = `or_righe_ordini`.`idordine`
INNER JOIN `or_statiordine` ON `or_statiordine`.`id` = `or_ordini`.`idstatoordine`
LEFT JOIN `or_statiordine_lang` ON (`or_statiordine`.`id` = `or_statiordine_lang`.`id_record` AND `or_statiordine_lang`.`id_lang` = '.prepare(Models\Locale::getDefault()->id).')
INNER JOIN `or_tipiordine` ON `or_tipiordine`.`id` = `or_ordini`.`idtipoordine`
WHERE
idanagrafica='.prepare($record['idanagrafica']).'
AND `or_statiordine`.`id` IN ('.prepare($id_stato_accettato).','.prepare($id_stato_evaso).','.prepare($id_stato_parz_evaso).','.prepare($id_stato_parz_fatt).')
AND `dir`='.prepare($dir).'
AND (`or_righe_ordini`.`qta` - `or_righe_ordini`.`qta_evasa`) > 0';
$ordini = $dbo->fetchArray($ordini_query)[0]['tot'];
}
// Form di inserimento riga documento
echo '
';
}
?>