|
|
@@ -170,9 +170,13 @@ class FatturazioneGeneraService
|
|
170
|
170
|
'segnalazione.ordineLavoro.righe',
|
|
171
|
171
|
'segnalazione.acquistoServizio',
|
|
172
|
172
|
])
|
|
|
173
|
+ ->where(function ($q) {
|
|
|
174
|
+ $q->whereNull('non_fatturare')->orWhere('non_fatturare', false);
|
|
|
175
|
+ })
|
|
173
|
176
|
->where(function ($q) {
|
|
174
|
177
|
$q->where('tempo_minuti', '>', 0)
|
|
175
|
|
- ->orWhere('costo', '>', 0);
|
|
|
178
|
+ ->orWhere('costo', '>', 0)
|
|
|
179
|
+ ->orWhere('costo_uscita', true);
|
|
176
|
180
|
})
|
|
177
|
181
|
->where(function ($q) use ($from, $to) {
|
|
178
|
182
|
$q->whereBetween('tempo_data', [$from, $to])
|
|
|
@@ -379,7 +383,7 @@ class FatturazioneGeneraService
|
|
379
|
383
|
$data = $this->dataAnnotazione($annotazione);
|
|
380
|
384
|
|
|
381
|
385
|
if ($segnalazione->acquisto_servizio_id) {
|
|
382
|
|
- return [
|
|
|
386
|
+ return $this->conCostoUscita([
|
|
383
|
387
|
'copertura' => 'acquisto',
|
|
384
|
388
|
'minuti_coperti' => $minuti,
|
|
385
|
389
|
'minuti_fatturare' => 0,
|
|
|
@@ -388,7 +392,7 @@ class FatturazioneGeneraService
|
|
388
|
392
|
'importo_spesa' => 0.0,
|
|
389
|
393
|
'tariffa_mancante' => false,
|
|
390
|
394
|
'note' => 'Già pagato (acquisto servizio)',
|
|
391
|
|
- ];
|
|
|
395
|
+ ], $annotazione, $segnalazione);
|
|
392
|
396
|
}
|
|
393
|
397
|
|
|
394
|
398
|
$fatturaSpesa = $costo > 0 ? round($costo, 2) : 0.0;
|
|
|
@@ -415,7 +419,7 @@ class FatturazioneGeneraService
|
|
415
|
419
|
? 'contratto_misto'
|
|
416
|
420
|
: ($extra > 0 ? 'contratto_extra' : 'contratto');
|
|
417
|
421
|
|
|
418
|
|
- return [
|
|
|
422
|
+ return $this->conCostoUscita([
|
|
419
|
423
|
'copertura' => $copertura,
|
|
420
|
424
|
'minuti_coperti' => $coperti,
|
|
421
|
425
|
'minuti_fatturare' => $extra,
|
|
|
@@ -424,7 +428,7 @@ class FatturazioneGeneraService
|
|
424
|
428
|
'importo_spesa' => $fatturaSpesa,
|
|
425
|
429
|
'tariffa_mancante' => $mancante,
|
|
426
|
430
|
'note' => $this->noteContratto($contratto, $coperti, $extra, $pools[$poolKey]['ore_totali']),
|
|
427
|
|
- ];
|
|
|
431
|
+ ], $annotazione, $segnalazione);
|
|
428
|
432
|
}
|
|
429
|
433
|
|
|
430
|
434
|
if ($segnalazione->ordine_lavoro_id && $segnalazione->ordineLavoro) {
|
|
|
@@ -451,7 +455,7 @@ class FatturazioneGeneraService
|
|
451
|
455
|
? 'ordine_misto'
|
|
452
|
456
|
: ($extra > 0 ? 'ordine_extra' : 'ordine');
|
|
453
|
457
|
|
|
454
|
|
- return [
|
|
|
458
|
+ return $this->conCostoUscita([
|
|
455
|
459
|
'copertura' => $copertura,
|
|
456
|
460
|
'minuti_coperti' => $coperti,
|
|
457
|
461
|
'minuti_fatturare' => $extra,
|
|
|
@@ -462,12 +466,12 @@ class FatturazioneGeneraService
|
|
462
|
466
|
'note' => $forfait
|
|
463
|
467
|
? 'Incluso in ordine (a corpo)'
|
|
464
|
468
|
: $this->noteOrdine($ordine, $coperti, $extra),
|
|
465
|
|
- ];
|
|
|
469
|
+ ], $annotazione, $segnalazione);
|
|
466
|
470
|
}
|
|
467
|
471
|
|
|
468
|
472
|
$mancante = $minuti > 0 && $tariffaDefault <= 0;
|
|
469
|
473
|
|
|
470
|
|
- return [
|
|
|
474
|
+ return $this->conCostoUscita([
|
|
471
|
475
|
'copertura' => 'libero',
|
|
472
|
476
|
'minuti_coperti' => 0,
|
|
473
|
477
|
'minuti_fatturare' => $minuti,
|
|
|
@@ -476,12 +480,23 @@ class FatturazioneGeneraService
|
|
476
|
480
|
'importo_spesa' => $fatturaSpesa,
|
|
477
|
481
|
'tariffa_mancante' => $mancante,
|
|
478
|
482
|
'note' => 'Senza contratto né ordine',
|
|
479
|
|
- ];
|
|
|
483
|
+ ], $annotazione, $segnalazione);
|
|
|
484
|
+ }
|
|
|
485
|
+
|
|
|
486
|
+ protected function conCostoUscita(array $allocazione, Annotazione $annotazione, $segnalazione): array
|
|
|
487
|
+ {
|
|
|
488
|
+ $allocazione['importo_uscita'] = 0.0;
|
|
|
489
|
+ if (! $segnalazione->acquisto_servizio_id && $annotazione->costo_uscita) {
|
|
|
490
|
+ $allocazione['importo_uscita'] = round(Config::costoUscitaDefault(), 2);
|
|
|
491
|
+ }
|
|
|
492
|
+
|
|
|
493
|
+ return $allocazione;
|
|
480
|
494
|
}
|
|
481
|
495
|
|
|
482
|
496
|
protected function accumulaTempo(array &$cliente, $segnalazione, Annotazione $annotazione, array $allocazione): void
|
|
483
|
497
|
{
|
|
484
|
498
|
$sid = (int) $segnalazione->id;
|
|
|
499
|
+ $importoUscita = (float) ($allocazione['importo_uscita'] ?? 0);
|
|
485
|
500
|
if (! isset($cliente['segnalazioni'][$sid])) {
|
|
486
|
501
|
$cliente['segnalazioni'][$sid] = [
|
|
487
|
502
|
'id' => $sid,
|
|
|
@@ -498,6 +513,7 @@ class FatturazioneGeneraService
|
|
498
|
513
|
'minuti_fatturare' => 0,
|
|
499
|
514
|
'importo_tempo' => 0.0,
|
|
500
|
515
|
'importo_spesa' => 0.0,
|
|
|
516
|
+ 'importo_uscita' => 0.0,
|
|
501
|
517
|
'importo' => 0.0,
|
|
502
|
518
|
'tariffa' => $allocazione['tariffa'],
|
|
503
|
519
|
'tariffa_mancante' => false,
|
|
|
@@ -511,7 +527,8 @@ class FatturazioneGeneraService
|
|
511
|
527
|
$row['minuti_fatturare'] += $allocazione['minuti_fatturare'];
|
|
512
|
528
|
$row['importo_tempo'] = round($row['importo_tempo'] + $allocazione['importo_tempo'], 2);
|
|
513
|
529
|
$row['importo_spesa'] = round($row['importo_spesa'] + $allocazione['importo_spesa'], 2);
|
|
514
|
|
- $row['importo'] = round($row['importo_tempo'] + $row['importo_spesa'], 2);
|
|
|
530
|
+ $row['importo_uscita'] = round($row['importo_uscita'] + $importoUscita, 2);
|
|
|
531
|
+ $row['importo'] = round($row['importo_tempo'] + $row['importo_spesa'] + $row['importo_uscita'], 2);
|
|
515
|
532
|
$row['tariffa_mancante'] = $row['tariffa_mancante'] || $allocazione['tariffa_mancante'];
|
|
516
|
533
|
if ($allocazione['tariffa'] !== null) {
|
|
517
|
534
|
$row['tariffa'] = $allocazione['tariffa'];
|
|
|
@@ -560,18 +577,39 @@ class FatturazioneGeneraService
|
|
560
|
577
|
'nota' => null,
|
|
561
|
578
|
];
|
|
562
|
579
|
}
|
|
|
580
|
+ if ($importoUscita > 0) {
|
|
|
581
|
+ $cliente['voci'][] = [
|
|
|
582
|
+ 'tipo' => FatturaRiga::TIPO_USCITA,
|
|
|
583
|
+ 'descrizione' => 'Costo d\'uscita '.$segnalazione->getNumeroLabel().' — '.$segnalazione->titolo,
|
|
|
584
|
+ 'quantita' => 1,
|
|
|
585
|
+ 'unita_misura' => 'forfait',
|
|
|
586
|
+ 'prezzo_unitario' => $importoUscita,
|
|
|
587
|
+ 'importo' => $importoUscita,
|
|
|
588
|
+ 'minuti' => null,
|
|
|
589
|
+ 'annotazione_id' => $annotazione->id,
|
|
|
590
|
+ 'segnalazione_id' => $segnalazione->id,
|
|
|
591
|
+ 'contratto_servizio_id' => $segnalazione->contratto_servizio_id,
|
|
|
592
|
+ 'contratto_servizio_riga_id' => null,
|
|
|
593
|
+ 'ordine_lavoro_id' => $segnalazione->ordine_lavoro_id,
|
|
|
594
|
+ 'prodotto_id' => null,
|
|
|
595
|
+ 'periodo_da' => null,
|
|
|
596
|
+ 'periodo_a' => null,
|
|
|
597
|
+ 'nota' => 'Costo d\'uscita',
|
|
|
598
|
+ ];
|
|
|
599
|
+ }
|
|
563
|
600
|
|
|
564
|
601
|
$cliente['minuti_totali'] += (int) $annotazione->tempo_minuti;
|
|
565
|
602
|
$cliente['minuti_coperti'] += $allocazione['minuti_coperti'];
|
|
566
|
603
|
$cliente['minuti_fatturare'] += $allocazione['minuti_fatturare'];
|
|
567
|
604
|
$cliente['importo_tempi'] = round($cliente['importo_tempi'] + $allocazione['importo_tempo'], 2);
|
|
568
|
|
- $cliente['importo_spese'] = round($cliente['importo_spese'] + $allocazione['importo_spesa'], 2);
|
|
|
605
|
+ $cliente['importo_spese'] = round($cliente['importo_spese'] + $allocazione['importo_spesa'] + $importoUscita, 2);
|
|
569
|
606
|
$cliente['totale'] = round($cliente['importo_tempi'] + $cliente['importo_spese'] + $cliente['importo_rinnovi'], 2);
|
|
570
|
607
|
$cliente['ha_tariffa_mancante'] = $cliente['ha_tariffa_mancante'] || $allocazione['tariffa_mancante'];
|
|
571
|
608
|
}
|
|
572
|
609
|
|
|
573
|
610
|
protected function accumulaRinnovi(array &$clienti, Carbon $from, Carbon $to, ?int $privatiAziendaId): void
|
|
574
|
611
|
{
|
|
|
612
|
+ $rinnoviDa = Config::rinnoviDa();
|
|
575
|
613
|
$contratti = ContrattoServizio::query()
|
|
576
|
614
|
->with(['user.azienda', 'righe.prodotto'])
|
|
577
|
615
|
->where('attivo', true)
|
|
|
@@ -595,6 +633,9 @@ class FatturazioneGeneraService
|
|
595
|
633
|
|
|
596
|
634
|
foreach ($contratto->righe as $riga) {
|
|
597
|
635
|
foreach ($this->dateOccorrenzeRigaNelPeriodo($contratto, $riga, $from, $to) as $occurrence) {
|
|
|
636
|
+ if ($occurrence->copy()->startOfDay()->lt($rinnoviDa)) {
|
|
|
637
|
+ continue;
|
|
|
638
|
+ }
|
|
598
|
639
|
$periodoKey = (string) ($riga->periodo ?: $contratto->periodo ?: 'una_tantum');
|
|
599
|
640
|
[$pDa, $pA] = $this->finestraCiclo($periodoKey, $occurrence);
|
|
600
|
641
|
if ($this->canoneGiaFatturato($contratto->id, $riga->id, $pDa, $pA)) {
|
|
|
@@ -618,6 +659,9 @@ class FatturazioneGeneraService
|
|
618
|
659
|
]);
|
|
619
|
660
|
$fake->setRelation('contrattoServizio', $contratto);
|
|
620
|
661
|
foreach ($this->dateOccorrenzeRigaNelPeriodo($contratto, $fake, $from, $to) as $occurrence) {
|
|
|
662
|
+ if ($occurrence->copy()->startOfDay()->lt($rinnoviDa)) {
|
|
|
663
|
+ continue;
|
|
|
664
|
+ }
|
|
621
|
665
|
[$pDa, $pA] = $this->finestraCiclo($periodo, $occurrence);
|
|
622
|
666
|
if ($this->canoneGiaFatturato($contratto->id, null, $pDa, $pA)) {
|
|
623
|
667
|
continue;
|
|
|
@@ -669,9 +713,6 @@ class FatturazioneGeneraService
|
|
669
|
713
|
}
|
|
670
|
714
|
}
|
|
671
|
715
|
|
|
672
|
|
- /**
|
|
673
|
|
- * @return Carbon[]
|
|
674
|
|
- */
|
|
675
|
716
|
protected function dateOccorrenzeRigaNelPeriodo(ContrattoServizio $contratto, ContrattoServizioRiga $riga, Carbon $from, Carbon $to): array
|
|
676
|
717
|
{
|
|
677
|
718
|
if ($riga->isAConsumo()) {
|
|
|
@@ -773,7 +814,12 @@ class FatturazioneGeneraService
|
|
773
|
814
|
{
|
|
774
|
815
|
$query = Annotazione::query()
|
|
775
|
816
|
->where('tempo_minuti', '>', 0)
|
|
776
|
|
- ->whereHas('segnalazione', fn ($q) => $q->where('contratto_servizio_id', $contrattoId));
|
|
|
817
|
+ ->where(function ($q) {
|
|
|
818
|
+ $q->whereNull('non_fatturare')->orWhere('non_fatturare', false);
|
|
|
819
|
+ })
|
|
|
820
|
+ ->whereHas('segnalazione', function ($q) use ($contrattoId) {
|
|
|
821
|
+ $q->where('contratto_servizio_id', $contrattoId);
|
|
|
822
|
+ });
|
|
777
|
823
|
|
|
778
|
824
|
$this->applicaLimiteTemporale($query, $windowFrom, $billingFrom->copy()->subSecond());
|
|
779
|
825
|
|
|
|
@@ -784,7 +830,12 @@ class FatturazioneGeneraService
|
|
784
|
830
|
{
|
|
785
|
831
|
$query = Annotazione::query()
|
|
786
|
832
|
->where('tempo_minuti', '>', 0)
|
|
787
|
|
- ->whereHas('segnalazione', fn ($q) => $q->where('ordine_lavoro_id', $ordineId));
|
|
|
833
|
+ ->where(function ($q) {
|
|
|
834
|
+ $q->whereNull('non_fatturare')->orWhere('non_fatturare', false);
|
|
|
835
|
+ })
|
|
|
836
|
+ ->whereHas('segnalazione', function ($q) use ($ordineId) {
|
|
|
837
|
+ $q->where('ordine_lavoro_id', $ordineId);
|
|
|
838
|
+ });
|
|
788
|
839
|
|
|
789
|
840
|
$this->applicaLimiteTemporale($query, null, $billingFrom->copy()->subSecond());
|
|
790
|
841
|
|
|
|
@@ -1003,13 +1054,15 @@ class FatturazioneGeneraService
|
|
1003
|
1054
|
$labelRiga = $riga ? $riga->label : 'Canone contratto';
|
|
1004
|
1055
|
$periodoLabel = $riga ? $riga->periodo_label : $contratto->periodo_label;
|
|
1005
|
1056
|
$descrizione = $contratto->label.' — '.$labelRiga.' ('.$pDa->format('d/m/Y').' – '.$pA->format('d/m/Y').')';
|
|
1006
|
|
-
|
|
1007
|
1057
|
$cliente['rinnovi'][] = [
|
|
1008
|
1058
|
'tipo' => 'canone',
|
|
1009
|
1059
|
'contratto_id' => $contratto->id,
|
|
1010
|
1060
|
'contratto' => $contratto->label,
|
|
|
1061
|
+ 'contratto_servizio_riga_id' => $riga?->id,
|
|
1011
|
1062
|
'riga' => $labelRiga,
|
|
1012
|
1063
|
'periodo' => $periodoLabel,
|
|
|
1064
|
+ 'periodo_da' => $pDa->toDateString(),
|
|
|
1065
|
+ 'periodo_a' => $pA->toDateString(),
|
|
1013
|
1066
|
'occorrenze' => 1,
|
|
1014
|
1067
|
'importo' => $importo,
|
|
1015
|
1068
|
'scadenza' => null,
|