2018-08-29 18:06:51 +02: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-08-29 18:06:51 +02:00
namespace Modules\Articoli ;
2020-09-22 20:28:37 +02:00
use Common\SimpleModelTrait ;
use Illuminate\Database\Eloquent\Model ;
2019-08-26 18:02:05 +02:00
use Illuminate\Database\Eloquent\SoftDeletes ;
2024-03-22 15:52:24 +01:00
use Models\Module ;
2021-08-31 15:46:14 +02:00
use Modules\AttributiCombinazioni\ValoreAttributo ;
use Modules\CombinazioniArticoli\Combinazione ;
2019-03-08 15:17:04 +01:00
use Modules\Interventi\Components\Articolo as ArticoloIntervento ;
2020-07-06 13:57:45 +02:00
use Modules\Iva\Aliquota ;
2021-07-27 18:11:54 +02:00
use Plugins\ListinoFornitori\DettaglioFornitore ;
2020-04-14 08:49:48 +02:00
use Traits\RecordTrait ;
2018-08-29 18:06:51 +02:00
class Articolo extends Model
{
2020-09-22 20:28:37 +02:00
use SimpleModelTrait ;
2019-08-26 11:10:59 +02:00
use SoftDeletes ;
2020-04-14 08:49:48 +02:00
use RecordTrait ;
2019-08-26 11:10:59 +02:00
2020-08-07 10:14:09 +02:00
protected $guarded = [
'qta' ,
];
2018-08-29 18:06:51 +02:00
protected $table = 'mg_articoli' ;
2024-03-19 15:50:41 +01:00
protected static $translated_fields = [
'name' ,
];
2024-03-19 18:18:11 +01:00
public static function build ( $codice = null , ? Categoria $categoria = null , ? Categoria $sottocategoria = null )
2019-10-18 16:40:15 +02:00
{
2020-09-22 20:28:37 +02:00
$model = new static ();
2019-10-18 16:40:15 +02:00
$model -> codice = $codice ;
$model -> abilita_serial = false ;
$model -> attivo = true ;
$model -> categoria () -> associate ( $categoria );
$model -> sottocategoria () -> associate ( $sottocategoria );
$model -> save ();
return $model ;
}
2018-08-29 18:06:51 +02:00
/**
2020-08-07 10:43:14 +02:00
* Funzione per registrare un movimento del magazzino in relazione all 'articolo corrente, modificando di conseguenza la quantità dell' articolo stesso .
2019-02-12 17:21:27 +01:00
*
2020-08-07 10:43:14 +02:00
* @ param string $descrizone
* @ param string $data
* @ param bool $manuale
* @ param array $array
2019-02-12 17:21:27 +01:00
*
* @ return bool
2018-08-29 18:06:51 +02:00
*/
2018-09-03 10:03:27 +02:00
public function movimenta ( $qta , $descrizone = null , $data = null , $manuale = false , $array = [])
2018-08-29 18:06:51 +02:00
{
2020-11-12 17:11:09 +01:00
$data = ( $data ? : date ( 'Y-m-d H:i:s' ));
2019-12-12 19:08:23 +01:00
$id = $this -> registra ( $qta , $descrizone , $data , $manuale , $array );
2018-08-29 18:06:51 +02:00
2020-12-22 16:01:02 +01:00
if ( empty ( $this -> servizio )) {
2018-08-29 18:06:51 +02:00
$this -> qta += $qta ;
$this -> save ();
}
2019-12-12 19:08:23 +01:00
return $id ;
2018-08-29 18:06:51 +02:00
}
/**
2020-08-07 10:43:14 +02:00
* Funzione per registrare un movimento del magazzino in relazione all 'articolo corrente, senza movimentare la quantità dell' articolo stesso .
2019-02-12 17:21:27 +01:00
*
2020-08-07 10:43:14 +02:00
* @ param string $descrizone
* @ param string $data
* @ param bool $manuale
* @ param array $array
2019-02-12 17:21:27 +01:00
*
* @ return bool
2018-08-29 18:06:51 +02:00
*/
public function registra ( $qta , $descrizone = null , $data = null , $manuale = false , $array = [])
{
if ( empty ( $qta )) {
return false ;
}
2023-01-11 11:03:56 +01:00
global $user ;
2018-08-29 18:06:51 +02:00
// Movimento il magazzino solo se l'articolo non è un servizio
2021-02-26 10:32:50 +01:00
if ( empty ( $this -> servizio )) {
2018-08-29 18:06:51 +02:00
// Registrazione della movimentazione
database () -> insert ( 'mg_movimenti' , array_merge ( $array , [
'idarticolo' => $this -> id ,
'qta' => $qta ,
'movimento' => $descrizone ,
'data' => $data ,
'manuale' => $manuale ,
2023-01-11 11:03:56 +01:00
'idutente' => $user -> id ,
2018-08-29 18:06:51 +02:00
]));
}
2019-12-12 19:08:23 +01:00
$id = database () -> lastInsertedID ();
2018-08-29 18:06:51 +02:00
2019-12-12 19:08:23 +01:00
return $id ;
2018-08-29 18:06:51 +02:00
}
2020-08-07 10:43:14 +02:00
/**
2024-01-30 09:16:17 +01:00
* Imposta il prezzo di vendita sulla base dell 'impostazione per l' utilizzo dei prezzi comprensivi di IVA .
2020-08-07 10:43:14 +02:00
*/
2020-07-06 13:57:45 +02:00
public function setPrezzoVendita ( $prezzo_vendita , $id_iva )
{
$this -> idiva_vendita = $id_iva ;
// Calcolo prezzo di vendita ivato e non ivato
$prezzi_ivati = setting ( 'Utilizza prezzi di vendita comprensivi di IVA' );
2021-12-21 10:49:21 +01:00
$id_iva = $id_iva ? : setting ( 'Iva predefinita' );
2020-07-06 13:57:45 +02:00
$percentuale_aliquota = floatval ( Aliquota :: find ( $id_iva ) -> percentuale );
if ( $prezzi_ivati ) {
$this -> prezzo_vendita_ivato = $prezzo_vendita ;
$this -> prezzo_vendita = $prezzo_vendita / ( 1 + $percentuale_aliquota / 100 );
} else {
$this -> prezzo_vendita = $prezzo_vendita ;
$this -> prezzo_vendita_ivato = $prezzo_vendita * ( 1 + $percentuale_aliquota / 100 );
}
}
2022-11-15 17:38:42 +01:00
/**
2024-01-30 09:16:17 +01:00
* Imposta il prezzo di vendita sulla base dell 'impostazione per l' utilizzo dei prezzi comprensivi di IVA .
2022-11-15 17:38:42 +01:00
*/
public function setMinimoVendita ( $prezzo_minimo , $id_iva )
{
// Calcolo prezzo minimo di vendita ivato e non ivato
$prezzi_ivati = setting ( 'Utilizza prezzi di vendita comprensivi di IVA' );
$id_iva = $id_iva ? : setting ( 'Iva predefinita' );
$percentuale_aliquota = floatval ( Aliquota :: find ( $id_iva ) -> percentuale );
if ( $prezzi_ivati ) {
$this -> minimo_vendita_ivato = $prezzo_minimo ;
$this -> minimo_vendita = $prezzo_minimo / ( 1 + $percentuale_aliquota / 100 );
} else {
$this -> minimo_vendita = $prezzo_minimo ;
$this -> minimo_vendita_ivato = $prezzo_minimo * ( 1 + $percentuale_aliquota / 100 );
}
}
2022-03-07 09:35:58 +01:00
/**
* Imposta il prezzo di acquisto e aggiorna il prezzo di vendita in base al coefficiente .
*/
public function setPrezzoAcquistoAttribute ( $value )
{
$this -> attributes [ 'prezzo_acquisto' ] = $value ;
2022-04-06 11:16:03 +02:00
if ( $this -> coefficiente != 0 ) {
2022-03-07 09:35:58 +01:00
$prezzo_vendita = $value * $this -> coefficiente ;
$prezzi_ivati = setting ( 'Utilizza prezzi di vendita comprensivi di IVA' );
$id_iva = $this -> idiva_vendita ? : setting ( 'Iva predefinita' );
$percentuale_aliquota = floatval ( Aliquota :: find ( $id_iva ) -> percentuale );
if ( $prezzi_ivati ) {
$prezzo_vendita = $prezzo_vendita * ( 1 + $percentuale_aliquota / 100 );
}
2023-08-04 14:54:28 +02:00
$this -> setPrezzoVendita ( round ( $prezzo_vendita , 2 ), $this -> idiva_vendita );
2022-03-07 09:35:58 +01:00
}
}
2021-08-31 15:46:14 +02:00
/**
* Verifica se l ' articolo corrente è una variante per una Combinazione .
*
* @ return bool
*/
public function isVariante ()
{
return ! empty ( $this -> id_combinazione );
}
2019-09-07 15:57:33 +02:00
// Attributi Eloquent
2019-07-12 12:40:13 +02:00
2020-04-14 08:49:48 +02:00
public function getImmagineUploadAttribute ()
{
if ( empty ( $this -> immagine )) {
return null ;
}
return $this -> uploads () -> where ( 'filename' , $this -> immagine ) -> first ();
}
2019-07-12 12:40:13 +02:00
public function getImageAttribute ()
{
if ( empty ( $this -> immagine )) {
return null ;
}
2024-03-28 16:38:03 +01:00
$module = Module :: find (( new Module ()) -> getByField ( 'name' , $this -> module , \Models\Locale :: getPredefined () -> id ));
2024-01-15 15:30:45 +01:00
$fileinfo = \Uploads :: fileInfo ( $this -> immagine );
2019-07-12 12:40:13 +02:00
2020-07-06 14:16:16 +02:00
$directory = '/' . $module -> upload_directory . '/' ;
$image = $directory . $this -> immagine ;
$image_thumbnail = $directory . $fileinfo [ 'filename' ] . '_thumb600.' . $fileinfo [ 'extension' ];
2019-07-12 12:40:13 +02:00
2020-09-23 17:53:19 +02:00
$url = file_exists ( base_dir () . $image_thumbnail ) ? base_path () . $image_thumbnail : base_path () . $image ;
2019-07-12 12:40:13 +02:00
return $url ;
}
/**
* Restituisce il nome del modulo a cui l ' oggetto è collegato .
*
* @ return string
*/
public function getModuleAttribute ()
{
return 'Articoli' ;
}
2019-09-07 15:57:33 +02:00
2021-08-31 15:46:14 +02:00
public function getNomeVarianteAttribute ()
{
2024-02-29 15:10:55 +01:00
$valori = database () -> fetchArray ( " SELECT
2024-02-29 17:42:08 +01:00
CONCAT ( `mg_attributi_lang` . `title` , ': ' , `mg_valori_attributi` . `nome` ) AS nome
2024-02-29 15:10:55 +01:00
FROM
`mg_articolo_attributo`
2021-08-31 15:46:14 +02:00
INNER JOIN `mg_valori_attributi` ON `mg_valori_attributi` . `id` = `mg_articolo_attributo` . `id_valore`
INNER JOIN `mg_attributi` ON `mg_attributi` . `id` = `mg_valori_attributi` . `id_attributo`
2024-03-22 15:52:24 +01:00
LEFT JOIN `mg_attributi_lang` ON ( `mg_attributi_lang` . `id_record` = `mg_attributi` . `id` AND `mg_attributi_lang` . `id_lang` = " .prepare( \ Models \ Locale::getDefault()->id).')
2021-08-31 15:46:14 +02:00
INNER JOIN `mg_articoli` ON `mg_articoli` . `id` = `mg_articolo_attributo` . `id_articolo`
INNER JOIN `mg_combinazioni` ON `mg_combinazioni` . `id` = `mg_articoli` . `id_combinazione`
INNER JOIN `mg_attributo_combinazione` ON `mg_attributo_combinazione` . `id_combinazione` = `mg_combinazioni` . `id` AND `mg_attributo_combinazione` . `id_attributo` = `mg_attributi` . `id`
2024-02-29 15:10:55 +01:00
WHERE
2024-03-22 15:52:24 +01:00
`mg_articoli` . `id` = '.prepare($this->id).'
2024-02-29 15:10:55 +01:00
ORDER BY
`mg_attributo_combinazione` . `order` ' );
2021-08-31 15:46:14 +02:00
return implode ( ', ' , array_column ( $valori , 'nome' ));
}
2019-09-07 15:57:33 +02:00
// Relazioni Eloquent
public function articoli ()
{
return $this -> hasMany ( ArticoloIntervento :: class , 'idarticolo' );
}
2019-09-26 18:12:32 +02:00
2021-08-31 15:46:14 +02:00
public function combinazione ()
{
return $this -> belongsTo ( Combinazione :: class , 'id_combinazione' );
}
public function attributi ()
{
return $this -> belongsToMany ( ValoreAttributo :: class , 'mg_articolo_attributo' , 'id_articolo' , 'id_valore' );
}
2020-03-03 10:33:32 +01:00
/**
* Restituisce i movimenti di magazzino dell ' articolo .
*
* @ return \Illuminate\Database\Eloquent\Relations\HasMany | \Illuminate\Database\Query\Builder
*/
public function movimenti ()
{
return $this -> hasMany ( Movimento :: class , 'idarticolo' );
}
2020-11-13 17:54:58 +01:00
/**
* Restituisce le giacenze per sede dell ' articolo .
*
2023-01-24 18:30:45 +01:00
* @ param $data Indica la data fino alla quale calcolare le giacenze totali . Di default tutte
*
2020-11-13 17:54:58 +01:00
* @ return array
*/
2023-01-24 18:30:45 +01:00
public function getGiacenze ( $data = null )
2020-11-13 17:54:58 +01:00
{
2023-01-24 18:30:45 +01:00
$movimenti = $this -> movimenti ()
2020-11-13 17:54:58 +01:00
-> select (
2021-02-05 13:27:18 +01:00
'idsede' ,
2020-11-13 17:54:58 +01:00
database () -> raw ( 'SUM(qta) AS qta' )
2023-01-24 18:30:45 +01:00
) -> groupBy ([ 'idsede' ]);
2023-08-04 14:54:28 +02:00
2023-01-24 18:30:45 +01:00
if ( ! empty ( $data )) {
$movimenti = $movimenti -> where ( 'data' , '<=' , \Carbon\Carbon :: parse ( $data ) -> format ( 'Y-m-d' ));
}
$movimenti = $movimenti -> get ()
2024-04-09 12:18:08 +02:00
-> mapToGroups ( fn ( $item , $key ) => [ $item -> idsede => ( float ) $item -> attributes [ 'qta' ]])
2020-11-13 17:54:58 +01:00
-> toArray ();
2023-08-04 14:54:28 +02:00
2023-01-24 18:30:45 +01:00
return $movimenti ;
2020-11-13 17:54:58 +01:00
}
2020-03-03 10:33:32 +01:00
/**
* Restituisce i movimenti di magazzino dell ' articolo raggruppati per documento relativo .
*
* @ return \Illuminate\Database\Eloquent\Relations\HasMany | \Illuminate\Database\Query\Builder
*/
2021-09-17 11:17:33 +02:00
public function movimentiComposti ( $mostra_vuoti = false )
2020-03-03 10:33:32 +01:00
{
2021-09-17 11:17:33 +02:00
$movimenti = $this -> movimenti ()
-> selectRaw ( '*, mg_movimenti.created_at AS data_movimento, SUM(mg_movimenti.qta) as qta_documento, IFNULL(mg_movimenti.reference_type, mg_movimenti.id) as tipo_gruppo' )
2023-01-11 11:03:56 +01:00
-> groupBy ([ 'tipo_gruppo' , 'mg_movimenti.reference_id' , 'mg_movimenti.idutente' ]);
2021-09-17 11:17:33 +02:00
2021-09-17 12:18:21 +02:00
if ( ! empty ( $mostra_vuoti )) {
2021-09-17 11:17:33 +02:00
return $movimenti ;
}
return $movimenti -> havingRaw ( 'mg_movimenti.reference_type IS NULL OR qta_documento != 0' );
2020-03-03 10:33:32 +01:00
}
2019-09-26 18:12:32 +02:00
public function categoria ()
{
return $this -> belongsTo ( Categoria :: class , 'id_categoria' );
}
public function sottocategoria ()
{
return $this -> belongsTo ( Categoria :: class , 'id_sottocategoria' );
}
2020-07-06 13:32:43 +02:00
public function dettaglioFornitori ()
{
2020-08-25 17:38:10 +02:00
return $this -> hasMany ( DettaglioFornitore :: class , 'id_articolo' );
2020-07-06 13:32:43 +02:00
}
public function dettaglioFornitore ( $id_fornitore )
{
return $this -> dettaglioFornitori ()
-> where ( 'id_fornitore' , $id_fornitore )
-> first ();
}
2024-02-29 15:10:55 +01:00
2024-03-22 15:52:24 +01:00
public static function getTranslatedFields ()
{
2024-03-19 15:50:41 +01:00
return self :: $translated_fields ;
}
2018-08-29 18:06:51 +02:00
}