144 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| namespace App\Models;
 | |
| 
 | |
| use App\Utils\TransporteUtils;
 | |
| 
 | |
| use Illuminate\Database\Eloquent\Relations\HasMany;
 | |
| use Illuminate\Database\Eloquent\Relations\BelongsTo;
 | |
| use Illuminate\Database\Eloquent\Model;
 | |
| use Illuminate\Support\Facades\DB;
 | |
| use League\Csv\CannotInsertRecord;
 | |
| use League\Csv\Writer;
 | |
| 
 | |
| class Barrio extends Model
 | |
| {
 | |
|     /**
 | |
|      * The attributes that are mass assignable.
 | |
|      *
 | |
|      * @var array<int, string>
 | |
|      */
 | |
|     protected $fillable = [
 | |
|         'nombre',
 | |
|     ];
 | |
| 
 | |
|     /**
 | |
|      * La región a la que pertenece el barrio.
 | |
|      */
 | |
|     public function region(): BelongsTo
 | |
|     {
 | |
|         return $this->belongsTo(Region::class);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Los pedidos que pertenecen al barrio.
 | |
|      */
 | |
|     public function pedidos(): HasMany
 | |
|     {
 | |
|         return $this->hasMany(Pedido::class);
 | |
|     }
 | |
| 
 | |
|     public function crearPedido(string $nombre) : Pedido {
 | |
|         return $this->pedidos()->create(['nombre' => $nombre]);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Devuelve una query, para obtener el resultado agregarle ->get().
 | |
|      * La query devuelve objetos con todos los atributos de un producto, seguidos
 | |
|      * de la cantidad de ese producto pedida entre todos los pedidos del barrio y
 | |
|      * el costo total de dicha cantidad.
 | |
|      */
 | |
|     public function productosPedidos() {
 | |
|         return DB::table('productos')
 | |
|             ->join('pedido_producto', 'productos.id', '=', 'pedido_producto.producto_id')
 | |
|             ->join('pedidos', 'pedidos.id', '=', 'pedido_producto.pedido_id')
 | |
|             ->where(['pedidos.barrio_id' => $this->id, 'pedidos.pagado' => true])
 | |
|             ->select('productos.*',
 | |
|                      DB::raw('SUM(pedido_producto.cantidad) as cantidad'),
 | |
|                      DB::raw('SUM(pedido_producto.cantidad * productos.precio) as total'))
 | |
|             ->groupBy('productos.id');
 | |
|     }
 | |
| 
 | |
|     public function totalARecaudar() : float {
 | |
|         return $this->pedidos()->where(['pagado' => true])->get()->sum(
 | |
|             fn($p) => $p->totalATransferir()
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     public function totalATransferir() : float {
 | |
|         return $this->totalProductosConTransporte() + $this->totalBonosDeTransporte();
 | |
|     }
 | |
| 
 | |
|     public function totalBonosDeTransporte() : int {
 | |
|         return TransporteUtils::calcularTotal($this->totalProductosConTransporte());
 | |
|     }
 | |
| 
 | |
|     public function totalProductosConTransporte(): float
 | |
|     {
 | |
|         return $this->totalProductosIf(fn($p) => $p->pagaTransporte());
 | |
|     }
 | |
| 
 | |
|     private function totalProductosIf($predicado) : float {
 | |
|         return $this->productosPedidos()->where($predicado)->get()->sum(
 | |
|             fn($producto) => $producto->total
 | |
|         );
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Los productos que pertenecen al barrio.
 | |
|      */
 | |
|     public function productos(): HasMany
 | |
|     {
 | |
|         return $this->hasMany(Producto::class);
 | |
|     }
 | |
| 
 | |
|     public function exportarPedidoACsv() {
 | |
|         if ($this->productosPedidos()->get()->isNotEmpty()) {
 | |
|             $columnaProductos = $this->armarColumnaTotales();
 | |
| 
 | |
|             try {
 | |
|                 $writer = Writer::createFromPath(resource_path('csv/exports/'.$this->nombre.'.csv'), 'w');
 | |
|                 $writer->setDelimiter("|");
 | |
|                 $writer->setEnclosure("'");
 | |
|                 $writer->insertAll($columnaProductos);
 | |
|                 return true;
 | |
|             } catch (CannotInsertRecord $e) {
 | |
|                 var_export($e->getRecords());
 | |
|                 return false;
 | |
|             }
 | |
|         }
 | |
|         return false;
 | |
|     }
 | |
| 
 | |
|     private function armarColumnaTotales() : array {
 | |
|         $columnaProductos = [];
 | |
|         $filasVaciasAgregadas = false;
 | |
|         $productos = $this->productosPedidos()->where(['barrial' => false])->get();
 | |
| 
 | |
|         foreach (Categoria::orderBy('id')->get() as $categoria) {
 | |
|             if ($categoria->productos()->where(['barrial' => false])->count() == 0)
 | |
|                 continue;
 | |
| 
 | |
|             $columnaProductos[] = ['nombre' => $categoria->nombre, 'cantidad' => null];
 | |
| 
 | |
|             if ($categoria->nombre == 'TRANSPORTE, BONOS Y FINANCIAMIENTO SORORO')
 | |
|                 $columnaProductos[] = ['nombre' => 'Bono de Transporte', 'cantidad' => TransporteUtils::cantidad($this->totalProductosConTransporte())];
 | |
|             if ($categoria->nombre == 'PRODUCTOS DE GESTIÓN MENSTRUAL')
 | |
|                 $columnaProductos[] = ['nombre' => '¿Cuántas copas quieren y pueden comprar en el grupo?', 'cantidad' => null];
 | |
| 
 | |
|             foreach ($categoria->productos()->orderBy('id')->get() as $producto) {
 | |
|                 if ($producto->precio == 0 && !$filasVaciasAgregadas) {
 | |
|                     $columnaProductos[] = ['nombre' => '¿Cuántas copas quieren adquirir a través del financiamiento sororo?', 'cantidad' => null];
 | |
|                     $filasVaciasAgregadas = true;
 | |
|                 }
 | |
|                 $columnaProductos[] = ['nombre' => $producto->nombre, 'cantidad' => $this->cantidadPedida($producto->id, $productos)];
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return $columnaProductos;
 | |
|     }
 | |
| 
 | |
|     private function cantidadPedida($productoId, $productos) {
 | |
|         return $productos->find($productoId)->cantidad ?? 0;
 | |
|     }
 | |
| }
 |