2018-12-29 14:24:27 +01:00
< ? php
2020-09-07 15:04:06 +02:00
/*
* OpenSTAManager : il software gestionale open source per l ' assistenza tecnica e la fatturazione
2021-01-20 15:08:51 +01:00
* Copyright ( C ) DevCode s . r . l .
2020-09-07 15:04:06 +02:00
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < https :// www . gnu . org / licenses />.
*/
2018-12-29 14:24:27 +01:00
namespace Modules\DDT ;
2020-09-23 18:36:33 +02:00
use Common\Components\Component ;
2018-12-29 14:24:27 +01:00
use Common\Document ;
use Modules\Anagrafiche\Anagrafica ;
2021-03-25 16:20:22 +01:00
use Modules\Fatture\Fattura ;
2024-02-08 13:10:46 +01:00
use Modules\Pagamenti\Pagamento ;
2018-12-29 14:24:27 +01:00
use Traits\RecordTrait ;
2020-03-03 10:33:32 +01:00
use Traits\ReferenceTrait ;
2018-12-29 14:24:27 +01:00
use Util\Generator ;
class DDT extends Document
{
2020-03-03 10:33:32 +01:00
use ReferenceTrait ;
2018-12-29 14:24:27 +01:00
use RecordTrait ;
protected $table = 'dt_ddt' ;
2020-07-08 08:45:55 +02:00
protected $casts = [
'bollo' => 'float' ,
'peso' => 'float' ,
'volume' => 'float' ,
2021-04-06 15:10:55 +02:00
'sconto_finale' => 'float' ,
'sconto_finale_percentuale' => 'float' ,
2020-07-08 08:45:55 +02:00
];
2020-03-09 13:57:13 +01:00
protected $with = [
'tipo' ,
];
2018-12-29 14:24:27 +01:00
/**
* Crea un nuovo ddt .
*
2020-02-11 11:43:59 +01:00
* @ param string $data
2018-12-29 14:24:27 +01:00
*
* @ return self
*/
2022-11-28 09:27:25 +01:00
public static function build ( Anagrafica $anagrafica , Tipo $tipo_documento , $data , $id_segment = null )
2018-12-29 14:24:27 +01:00
{
2020-09-22 20:28:37 +02:00
$model = new static ();
2024-01-15 15:30:45 +01:00
$user = \Auth :: user ();
2019-06-25 18:51:37 +02:00
2024-03-27 15:34:01 +01:00
$stato_documento = ( new Stato ()) -> getByField ( 'name' , 'Bozza' , \Models\Locale :: where ( 'predefined' , true ) -> first () -> id );
2018-12-29 14:24:27 +01:00
$direzione = $tipo_documento -> dir ;
2022-11-28 09:27:25 +01:00
$id_segment = $id_segment ? : getSegmentPredefined ( $model -> getModule () -> id );
2018-12-29 14:24:27 +01:00
if ( $direzione == 'entrata' ) {
$conto = 'vendite' ;
} else {
$conto = 'acquisti' ;
}
// Tipo di pagamento e banca predefinite dall'anagrafica
2024-02-08 13:10:46 +01:00
$id_pagamento = Pagamento :: find ( $anagrafica [ 'idpagamento_' . $conto ]) -> id_record ;
2018-12-29 14:24:27 +01:00
// Se il ddt è un ddt cliente e non è stato associato un pagamento predefinito al cliente leggo il pagamento dalle impostazioni
if ( $direzione == 'entrata' && empty ( $id_pagamento )) {
$id_pagamento = setting ( 'Tipo di pagamento predefinito' );
}
$model -> anagrafica () -> associate ( $anagrafica );
$model -> tipo () -> associate ( $tipo_documento );
$model -> stato () -> associate ( $stato_documento );
2022-11-28 09:27:25 +01:00
$model -> id_segment = $id_segment ;
2023-04-27 15:37:15 +02:00
$model -> idagente = $anagrafica -> idagente ;
2023-08-04 14:54:28 +02:00
2018-12-29 14:24:27 +01:00
// Salvataggio delle informazioni
$model -> data = $data ;
if ( ! empty ( $id_pagamento )) {
$model -> idpagamento = $id_pagamento ;
}
2023-02-16 17:42:10 +01:00
$model -> numero = static :: getNextNumero ( $data , $direzione , $id_segment );
2022-11-28 09:27:25 +01:00
$model -> numero_esterno = static :: getNextNumeroSecondario ( $data , $direzione , $id_segment );
2018-12-29 14:24:27 +01:00
2019-06-25 18:51:37 +02:00
// Imposto, come sede aziendale, la prima sede disponibile come utente
if ( $direzione == 'entrata' ) {
2019-06-29 11:01:26 +02:00
$model -> idsede_partenza = $user -> sedi [ 0 ];
2019-06-25 18:51:37 +02:00
} else {
2019-06-29 11:01:26 +02:00
$model -> idsede_destinazione = $user -> sedi [ 0 ];
2019-06-25 18:51:37 +02:00
}
2018-12-29 14:24:27 +01:00
$model -> save ();
return $model ;
}
/**
* Restituisce il nome del modulo a cui l ' oggetto è collegato .
*
* @ return string
*/
public function getModuleAttribute ()
{
2019-03-29 12:46:17 +01:00
return $this -> direzione == 'entrata' ? 'Ddt di vendita' : 'DDT di acquisto' ;
2018-12-29 14:24:27 +01:00
}
2019-03-29 12:46:17 +01:00
public function getDirezioneAttribute ()
2018-12-29 14:24:27 +01:00
{
2019-03-29 12:46:17 +01:00
return $this -> tipo -> dir ;
2018-12-29 14:24:27 +01:00
}
2020-07-14 13:30:25 +02:00
public function isImportabile ()
{
$database = database ();
2024-03-08 13:10:32 +01:00
$stati = Stato :: where ( 'is_fatturabile' , 1 ) -> get ();
2021-03-29 10:07:45 +02:00
foreach ( $stati as $stato ) {
2024-03-20 11:13:28 +01:00
$stati_importabili [] = $stato -> getTranslation ( 'name' );
2021-03-26 09:42:43 +01:00
}
2024-03-20 16:15:37 +01:00
$causale = $database -> fetchOne ( 'SELECT * FROM `dt_causalet` LEFT JOIN `dt_causalet_lang` ON (`dt_causalet`.`id` = `dt_causalet_lang`.`id_record` AND `dt_causalet_lang`.`id_lang` =' . prepare ( \Models\Locale :: getDefault () -> id ) . ') WHERE `dt_causalet`.`id` = ' . prepare ( $this -> idcausalet ));
2020-07-14 13:30:25 +02:00
2024-03-20 11:13:28 +01:00
return $causale [ 'is_importabile' ] && in_array ( $this -> stato -> getTranslation ( 'name' ), $stati_importabili );
2020-07-14 13:30:25 +02:00
}
2021-01-14 16:03:13 +01:00
public function getReversedAttribute ()
{
$database = database ();
2024-03-20 16:15:37 +01:00
$causale = $database -> fetchOne ( 'SELECT * FROM `dt_causalet` LEFT JOIN `dt_causalet_lang` ON (`dt_causalet`.`id` = `dt_causalet_lang`.`id_record` AND `dt_causalet_lang`.`id_lang` =' . prepare ( \Models\Locale :: getDefault () -> id ) . ') WHERE `dt_causalet`.`id` = ' . prepare ( $this -> idcausalet ));
2021-01-14 16:03:13 +01:00
return $causale [ 'reversed' ];
}
2020-07-08 08:45:55 +02:00
/**
* Restituisce il peso calcolato sulla base degli articoli del documento .
*
* @ return float
*/
public function getPesoCalcolatoAttribute ()
{
$righe = $this -> getRighe ();
$peso_lordo = $righe -> sum ( function ( $item ) {
return $item -> isArticolo () ? $item -> articolo -> peso_lordo * $item -> qta : 0 ;
});
return $peso_lordo ;
}
/**
* Restituisce il volume calcolato sulla base degli articoli del documento .
*
* @ return float
*/
public function getVolumeCalcolatoAttribute ()
{
$righe = $this -> getRighe ();
$volume = $righe -> sum ( function ( $item ) {
return $item -> isArticolo () ? $item -> articolo -> volume * $item -> qta : 0 ;
});
return $volume ;
}
2018-12-29 14:24:27 +01:00
public function anagrafica ()
{
return $this -> belongsTo ( Anagrafica :: class , 'idanagrafica' );
}
public function tipo ()
{
return $this -> belongsTo ( Tipo :: class , 'idtipoddt' );
}
public function stato ()
{
return $this -> belongsTo ( Stato :: class , 'idstatoddt' );
}
public function articoli ()
{
return $this -> hasMany ( Components\Articolo :: class , 'idddt' );
}
public function righe ()
{
return $this -> hasMany ( Components\Riga :: class , 'idddt' );
}
2019-04-04 17:12:32 +02:00
public function sconti ()
{
return $this -> hasMany ( Components\Sconto :: class , 'idddt' );
}
2018-12-29 14:24:27 +01:00
public function descrizioni ()
{
return $this -> hasMany ( Components\Descrizione :: class , 'idddt' );
}
2019-07-22 18:35:13 +02:00
/**
* Effettua un controllo sui campi del documento .
2020-07-14 13:30:25 +02:00
* Viene richiamato dalle modifiche alle righe del documento .
2019-07-22 18:35:13 +02:00
*/
2020-09-23 18:36:33 +02:00
public function triggerEvasione ( Component $trigger )
2019-07-22 18:35:13 +02:00
{
2019-09-13 10:07:54 +02:00
parent :: triggerEvasione ( $trigger );
2019-07-22 18:35:13 +02:00
if ( setting ( 'Cambia automaticamente stato ddt fatturati' )) {
$righe = $this -> getRighe ();
$qta = $righe -> sum ( 'qta' );
2021-03-25 16:20:22 +01:00
$qta_evasa = $righe -> sum ( 'qta_evasa' );
2019-07-22 18:35:13 +02:00
$parziale = $qta != $qta_evasa ;
2021-03-25 16:20:22 +01:00
$fattura = Fattura :: find ( $trigger -> iddocumento );
2021-03-29 10:07:45 +02:00
if ( ! empty ( $fattura )) {
2021-03-25 16:20:22 +01:00
$righe_fatturate = $fattura -> getRighe () -> where ( 'idddt' , '=' , $this -> id );
$qta_fatturate = $righe_fatturate -> sum ( 'qta' );
$parziale_fatturato = $qta != $qta_fatturate ;
}
2021-03-29 10:07:45 +02:00
2019-07-22 18:35:13 +02:00
// Impostazione del nuovo stato
if ( $qta_evasa == 0 ) {
$descrizione = 'Bozza' ;
2021-03-29 10:07:45 +02:00
} elseif ( empty ( $qta_fatturate )) {
2021-03-25 16:20:22 +01:00
$descrizione = $parziale ? 'Parzialmente evaso' : 'Evaso' ;
2021-03-29 10:07:45 +02:00
} else {
2021-03-25 16:20:22 +01:00
$descrizione = $parziale_fatturato ? 'Parzialmente fatturato' : 'Fatturato' ;
2019-07-22 18:35:13 +02:00
}
2024-03-20 11:13:28 +01:00
$stato = ( new Stato ()) -> getByField ( 'name' , $descrizione );
2019-07-22 18:35:13 +02:00
$this -> stato () -> associate ( $stato );
$this -> save ();
}
}
2018-12-29 14:24:27 +01:00
// Metodi statici
/**
* Calcola il nuovo numero di ddt .
*
* @ param string $data
* @ param string $direzione
*
* @ return string
*/
2023-02-16 17:42:10 +01:00
public static function getNextNumero ( $data , $direzione , $id_segment )
2018-12-29 14:24:27 +01:00
{
2023-02-16 17:42:10 +01:00
if ( $direzione == 'entrata' ) {
return '' ;
}
$maschera = Generator :: getMaschera ( $id_segment );
2018-12-29 14:24:27 +01:00
2019-01-10 20:10:47 +01:00
$ultimo = Generator :: getPreviousFrom ( $maschera , 'dt_ddt' , 'numero' , [
'YEAR(data) = ' . prepare ( date ( 'Y' , strtotime ( $data ))),
'idtipoddt IN (SELECT id FROM dt_tipiddt WHERE dir = ' . prepare ( $direzione ) . ')' ,
2018-12-29 14:24:27 +01:00
]);
2023-02-16 17:42:10 +01:00
$numero = Generator :: generate ( $maschera , $ultimo , 1 , Generator :: dateToPattern ( $data ));
2018-12-29 14:24:27 +01:00
2019-01-10 20:10:47 +01:00
return $numero ;
2018-12-29 14:24:27 +01:00
}
/**
* Calcola il nuovo numero secondario di ddt .
*
* @ param string $data
* @ param string $direzione
*
* @ return string
*/
2022-11-28 09:27:25 +01:00
public static function getNextNumeroSecondario ( $data , $direzione , $id_segment )
2018-12-29 14:24:27 +01:00
{
if ( $direzione == 'uscita' ) {
return '' ;
}
2022-11-28 09:27:25 +01:00
$maschera = Generator :: getMaschera ( $id_segment );
2018-12-29 14:24:27 +01:00
2019-01-10 20:10:47 +01:00
$ultimo = Generator :: getPreviousFrom ( $maschera , 'dt_ddt' , 'numero_esterno' , [
'YEAR(data) = ' . prepare ( date ( 'Y' , strtotime ( $data ))),
'idtipoddt IN (SELECT id FROM dt_tipiddt WHERE dir = ' . prepare ( $direzione ) . ')' ,
2018-12-29 14:24:27 +01:00
]);
2019-01-10 20:10:47 +01:00
$numero = Generator :: generate ( $maschera , $ultimo , 1 , Generator :: dateToPattern ( $data ));
2018-12-29 14:24:27 +01:00
2019-01-10 20:10:47 +01:00
return $numero ;
2018-12-29 14:24:27 +01:00
}
2020-03-03 10:33:32 +01:00
// Opzioni di riferimento
public function getReferenceName ()
{
2024-03-20 11:13:28 +01:00
return $this -> tipo -> getTranslation ( 'name' );
2020-03-03 10:33:32 +01:00
}
public function getReferenceNumber ()
{
return $this -> numero_esterno ? : $this -> numero ;
}
public function getReferenceDate ()
{
return $this -> data ;
}
2020-10-15 17:00:43 +02:00
public function getReferenceRagioneSociale ()
{
return $this -> anagrafica -> ragione_sociale ;
}
2018-12-29 14:24:27 +01:00
}