|
32 | 32 | use Modules\Fatture\Fattura; |
33 | 33 | use Modules\Interventi\Intervento; |
34 | 34 | use Modules\Ordini\Ordine; |
| 35 | +use Util\Generator; |
35 | 36 |
|
36 | 37 | /** |
37 | 38 | * Esegue una somma precisa tra due interi/array. |
@@ -619,3 +620,154 @@ function cleanInvalidBankReferences($anagrafica) |
619 | 620 | $anagrafica->save(); |
620 | 621 | } |
621 | 622 | } |
| 623 | + |
| 624 | +/** |
| 625 | + * Calcola il prossimo numero progressivo per un documento. |
| 626 | + * |
| 627 | + * Funzione generica per il calcolo del numero progressivo utilizzata da vari moduli |
| 628 | + * (Contratti, Ordini, Interventi, DDT, Fatture, Preventivi, Anagrafiche). |
| 629 | + * |
| 630 | + * @param string $table Nome della tabella del database |
| 631 | + * @param string $field Nome del campo da calcolare (numero, numero_esterno, codice) |
| 632 | + * @param string $data Data del documento |
| 633 | + * @param int $id_segment ID del segmento |
| 634 | + * @param array $options Opzioni aggiuntive: |
| 635 | + * - 'data_field': nome del campo data (default 'data') |
| 636 | + * - 'direction': direzione del documento (entrata/uscita) |
| 637 | + * - 'skip_direction': direzione da saltare (ritorna stringa vuota) |
| 638 | + * - 'type_document': tipo di documento per condizioni extra |
| 639 | + * - 'type_document_field': campo del tipo documento (es. idtipoddt, idtipoordine) |
| 640 | + * - 'type_document_table': tabella del tipo documento |
| 641 | + * - 'conditions_extra': array di condizioni extra SQL |
| 642 | + * - 'use_setting': usa setting() invece di Generator::getMaschera() (default false) |
| 643 | + * - 'setting_key': chiave del setting per la maschera (se use_setting = true) |
| 644 | + * - 'date_pattern': pattern della data per Generator::generate() |
| 645 | + * - 'use_date_pattern': usa Generator::dateToPattern() per il pattern data |
| 646 | + * |
| 647 | + * @return string Il prossimo numero progressivo |
| 648 | + */ |
| 649 | +function getNextNumeroProgressivo($table, $field, $data, $id_segment, $options = []) |
| 650 | +{ |
| 651 | + // Opzioni di default |
| 652 | + $defaults = [ |
| 653 | + 'data_field' => 'data', |
| 654 | + 'direction' => null, |
| 655 | + 'skip_direction' => null, |
| 656 | + 'type_document' => null, |
| 657 | + 'type_document_field' => null, |
| 658 | + 'type_document_table' => null, |
| 659 | + 'conditions_extra' => [], |
| 660 | + 'use_setting' => false, |
| 661 | + 'setting_key' => null, |
| 662 | + 'date_pattern' => null, |
| 663 | + 'use_date_pattern' => false, |
| 664 | + ]; |
| 665 | + |
| 666 | + $options = array_merge($defaults, $options); |
| 667 | + |
| 668 | + // Se la direzione corrisponde a quella da saltare, ritorna stringa vuota |
| 669 | + if ($options['skip_direction'] && $options['direction'] == $options['skip_direction']) { |
| 670 | + return ''; |
| 671 | + } |
| 672 | + |
| 673 | + // Ottieni la maschera |
| 674 | + if ($options['use_setting']) { |
| 675 | + $maschera = setting($options['setting_key']); |
| 676 | + } else { |
| 677 | + $maschera = Generator::getMaschera($id_segment); |
| 678 | + } |
| 679 | + |
| 680 | + // Se la maschera è '#', ritorna '#' (per ordini di vendita) |
| 681 | + if ($maschera === '#') { |
| 682 | + return '#'; |
| 683 | + } |
| 684 | + |
| 685 | + // Calcola le condizioni in base alla maschera |
| 686 | + $has_month = str_contains($maschera, 'm'); |
| 687 | + $has_year = str_contains($maschera, 'YYYY') || str_contains($maschera, 'yy'); |
| 688 | + |
| 689 | + // Costruisci le condizioni |
| 690 | + $conditions = []; |
| 691 | + |
| 692 | + // Condizione per anno (solo se data è specificata) |
| 693 | + if ($has_year && $data !== null) { |
| 694 | + $data_timestamp = strtotime((string) $data); |
| 695 | + $conditions[] = 'YEAR('.$options['data_field'].') = '.prepare(date('Y', $data_timestamp)); |
| 696 | + } |
| 697 | + |
| 698 | + // Condizione per mese (solo se data è specificata) |
| 699 | + if ($has_month && $data !== null) { |
| 700 | + $data_timestamp = strtotime((string) $data); |
| 701 | + $conditions[] = 'MONTH('.$options['data_field'].') = '.prepare(date('m', $data_timestamp)); |
| 702 | + } |
| 703 | + |
| 704 | + // Condizione per segmento (se specificato) |
| 705 | + if (!empty($id_segment)) { |
| 706 | + $conditions[] = 'id_segment = '.prepare($id_segment); |
| 707 | + } |
| 708 | + |
| 709 | + // Condizione per direzione/tipo documento |
| 710 | + if ($options['direction'] && $options['type_document_field'] && $options['type_document_table']) { |
| 711 | + $conditions[] = $options['type_document_field'].' IN (SELECT `id` FROM `'.$options['type_document_table'].'` WHERE `dir` = '.prepare($options['direction']).')'; |
| 712 | + } |
| 713 | + |
| 714 | + // Aggiungi condizioni extra |
| 715 | + if (!empty($options['conditions_extra'])) { |
| 716 | + $conditions = array_merge($conditions, $options['conditions_extra']); |
| 717 | + } |
| 718 | + |
| 719 | + // Ottieni l'ultimo numero |
| 720 | + $ultimo = !empty($conditions) |
| 721 | + ? Generator::getPreviousFrom($maschera, $table, $field, $conditions, $data) |
| 722 | + : Generator::getPreviousFrom($maschera, $table, $field, null, $data); |
| 723 | + |
| 724 | + // Genera il nuovo numero |
| 725 | + $date_pattern = ($options['use_date_pattern'] && $data !== null) ? Generator::dateToPattern($data) : ($options['date_pattern'] ?? []); |
| 726 | + $numero = Generator::generate($maschera, $ultimo, 1, $date_pattern, $data); |
| 727 | + |
| 728 | + return $numero; |
| 729 | +} |
| 730 | + |
| 731 | +/** |
| 732 | + * Calcola il prossimo numero secondario progressivo per un documento. |
| 733 | + * |
| 734 | + * Funzione generica per il calcolo del numero secondario progressivo utilizzata da vari moduli |
| 735 | + * (Ordini, DDT, Fatture). Il numero secondario viene solitamente utilizzato per |
| 736 | + * i documenti di vendita (entrata). |
| 737 | + * |
| 738 | + * @param string $table Nome della tabella del database |
| 739 | + * @param string $field Nome del campo da calcolare (numero_esterno) |
| 740 | + * @param string $data Data del documento |
| 741 | + * @param int $id_segment ID del segmento |
| 742 | + * @param array $options Opzioni aggiuntive: |
| 743 | + * - 'data_field': nome del campo data (default 'data') |
| 744 | + * - 'direction': direzione del documento (entrata/uscita) |
| 745 | + * - 'skip_direction': direzione da saltare (ritorna stringa vuota, default 'uscita') |
| 746 | + * - 'type_document': tipo di documento per condizioni extra |
| 747 | + * - 'type_document_field': campo del tipo documento (es. idtipoddt, idtipoordine) |
| 748 | + * - 'type_document_table': tabella del tipo documento |
| 749 | + * - 'conditions_extra': array di condizioni extra SQL |
| 750 | + * - 'date_pattern': pattern della data per Generator::generate() |
| 751 | + * - 'use_date_pattern': usa Generator::dateToPattern() per il pattern data |
| 752 | + * |
| 753 | + * @return string Il prossimo numero secondario progressivo |
| 754 | + */ |
| 755 | +function getNextNumeroSecondarioProgressivo($table, $field, $data, $id_segment, $options = []) |
| 756 | +{ |
| 757 | + // Opzioni di default |
| 758 | + $defaults = [ |
| 759 | + 'data_field' => 'data', |
| 760 | + 'direction' => null, |
| 761 | + 'skip_direction' => 'uscita', |
| 762 | + 'type_document' => null, |
| 763 | + 'type_document_field' => null, |
| 764 | + 'type_document_table' => null, |
| 765 | + 'conditions_extra' => [], |
| 766 | + 'date_pattern' => null, |
| 767 | + 'use_date_pattern' => true, |
| 768 | + ]; |
| 769 | + |
| 770 | + $options = array_merge($defaults, $options); |
| 771 | + |
| 772 | + return getNextNumeroProgressivo($table, $field, $data, $id_segment, $options); |
| 773 | +} |
0 commit comments