builder(); $builder->select([ 'pedidos.id as pedido_id', 'pedidos_linea.id as linea_id', 'pedidos_linea.cantidad as cantidad_linea', 'presupuestos.id as presupuesto_id', ]); $builder->join('pedidos_linea', 'pedidos_linea.pedido_id = pedidos.id', 'left'); $builder->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id', 'left'); $builder->join('envios_lineas', 'envios_lineas.pedido_id = pedidos_linea.pedido_id', 'left'); $builder->groupStart() ->where('pedidos.id', $search) ->whereIn('pedidos.estado', ['finalizado']) ->orWhere("REPLACE(presupuestos.isbn, '-', '')", $searchClean) ->groupEnd(); $builder->groupBy('pedidos_linea.id'); $builder->having('IFNULL(SUM(envios_lineas.unidades_envio), 0) < cantidad_linea', null, false); $result = $builder->get()->getResult(); if (empty($result)) { $response = [ 'status' => false, 'message' => lang('Logistica.errors.notFound'), ]; return $response; } $PresupuestoDireccionesModel = model('App\Models\Presupuestos\PresupuestoDireccionesModel'); $numDirecciones = $PresupuestoDireccionesModel->where('presupuesto_id', $result[0]->presupuesto_id) ->countAllResults(); if ($numDirecciones == 0) { $response = [ 'status' => false, 'message' => lang('Logistica.errors.noAddresses'), ]; return $response; } else if ($numDirecciones > 1) { $multienvio = true; } $response = [ 'status' => true, 'data' => $result[0], ]; $response_envio = LogisticaService::generateEnvio($result[0]->pedido_id, $multienvio); if ($response_envio['status'] == false) { $response = [ 'status' => false, 'message' => $response_envio['message'], ]; return $response; } else { $response['data']->id_envio = $response_envio['data']['id_envio']; $response['data']->multienvio = $response_envio['data']['multienvio']; } return $response; } public static function findLineaEnvioPorEnvio(int $envio_id) { $db = \Config\Database::connect(); $subCliente = $db->table('envios') ->select('cliente_id') ->where('id', $envio_id) ->getCompiledSelect(); $builder = $db->table('envios e_main'); $builder->select(" CONCAT('[', p.id, '] - ', pr.titulo) AS name, pl.id AS id, pl.cantidad, ( SELECT IFNULL(SUM(el.unidades_envio), 0) FROM envios_lineas el JOIN envios e ON e.id = el.envio_id WHERE el.pedido_id = p.id AND e.direccion = e_main.direccion AND pr.cliente_id = ($subCliente) ) AS unidades_enviadas, ( pl.cantidad - ( SELECT IFNULL(SUM(el2.unidades_envio), 0) FROM envios_lineas el2 JOIN envios e2 ON e2.id = el2.envio_id WHERE el2.pedido_id = p.id AND e2.direccion = e_main.direccion AND pr.cliente_id = ($subCliente) ) ) AS unidades_pendientes "); $builder->join('pedidos_linea pl', '1=1'); // para incluir líneas sin envío aún $builder->join('pedidos p', 'p.id = pl.pedido_id'); $builder->join('presupuestos pr', 'pr.id = pl.presupuesto_id'); $builder->where('e_main.id', $envio_id); $builder->where('p.estado', 'finalizado'); $builder->where("pr.cliente_id = ($subCliente)", null, false); $builder->having('unidades_pendientes >', 0); $builder->orderBy('name', 'ASC'); return $builder; } public static function addLineaEnvio($envio_id = null, $pedido_id = null, $direccion = null) { $modelPedido = model('App\Models\Pedidos\PedidoModel'); $builder = $modelPedido->builder(); $builder->select(" pedidos.id as pedido_id, pedidos_linea.id as linea_id, pedidos_linea.cantidad as total_unidades, ( SELECT IFNULL(SUM(el.unidades_envio), 0) FROM envios_lineas el JOIN envios e ON e.id = el.envio_id WHERE el.pedido_id = pedidos.id AND e.finalizado = 1 AND TRIM(e.direccion) = '" . addslashes(trim($direccion)) . "' ) as unidades_enviadas, pedidos_linea.cantidad - IFNULL(SUM(envios_lineas.unidades_envio), 0) as unidades_envio, presupuestos.id as presupuesto_id "); $builder->join('pedidos_linea', 'pedidos_linea.pedido_id = pedidos.id', 'left'); $builder->join('presupuestos', 'presupuestos.id = pedidos_linea.presupuesto_id', 'left'); $builder->join('envios_lineas', 'envios_lineas.pedido_id = pedidos_linea.pedido_id', 'left'); $builder->groupBy('pedidos_linea.id'); $builder->having('IFNULL(SUM(envios_lineas.unidades_envio), 0) < pedidos_linea.cantidad', null, false); $builder->where('pedidos.estado', 'finalizado'); $builder->where('pedidos.id', $pedido_id); $result = $builder->get()->getResultObject(); if (empty($result)) { return [ 'status' => false, 'message' => lang('Logistica.errors.notFound'), ]; } else { $EnvioLineasModel = model('App\Models\Logistica\EnvioLineaModel'); $EnvioLineasModel->save([ 'envio_id' => $envio_id, 'pedido_id' => $result[0]->pedido_id, 'unidades_envio' => $result[0]->unidades_envio, 'unidades_total' => $result[0]->total_unidades, 'cajas' => null, 'unidades_cajas' => 1, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s'), 'created_by' => auth()->user()->id, 'updated_by' => auth()->user()->id, 'presupuesto_id' => $result[0]->presupuesto_id, ]); } return [ 'status' => true, 'data' => [ 'unidades_envio' => $result[0]->unidades_envio, 'unidades_enviadas' => $result[0]->unidades_enviadas, 'total_unidades' => $result[0]->total_unidades, ] ]; } private static function generateEnvio($pedido_id, $multienvio = false) { $presupuestoDireccionesModel = model('App\Models\Presupuestos\PresupuestoDireccionesModel'); if (!$multienvio) { // solo hay una dirección, se obtiene de los albaranes $datosEnvio = $presupuestoDireccionesModel ->select(' presupuestos.id as presupuesto_id, presupuesto_direcciones.att, presupuesto_direcciones.direccion, presupuesto_direcciones.provincia as ciudad, presupuesto_direcciones.cp, presupuesto_direcciones.telefono, presupuesto_direcciones.email, presupuesto_direcciones.pais_id, presupuesto_direcciones.cantidad - IFNULL(SUM(envios_lineas.unidades_envio), 0) as cantidad, presupuesto_direcciones.cantidad as cantidad_total, presupuestos.cliente_id as cliente_id ') ->join('pedidos_linea', 'pedidos_linea.presupuesto_id = presupuesto_direcciones.presupuesto_id') ->join('pedidos', 'pedidos.id = pedidos_linea.pedido_id') ->join('presupuestos', 'pedidos_linea.presupuesto_id = presupuestos.id') ->join('envios_lineas', 'envios_lineas.pedido_id = pedidos.id', 'left') ->join('envios', 'envios.id = envios_lineas.envio_id', 'left') ->where('pedidos.id', $pedido_id) ->groupBy('presupuesto_direcciones.id') // Necesario por el uso de SUM ->first(); // se genera un nuevo envio con estos datos $EnvioModel = model('App\Models\Logistica\EnvioModel'); $EnvioModel->set('cliente_id', $datosEnvio->cliente_id); $EnvioModel->set('att', $datosEnvio->att); $EnvioModel->set('direccion', $datosEnvio->direccion); $EnvioModel->set('ciudad', $datosEnvio->ciudad); $EnvioModel->set('cp', $datosEnvio->cp); $EnvioModel->set('telefono', $datosEnvio->telefono); $EnvioModel->set('email', $datosEnvio->email); $EnvioModel->set('pais_id', $datosEnvio->pais_id); $EnvioModel->set('cantidad', $datosEnvio->cantidad); $EnvioModel->set('cajas', 1); $EnvioModel->set('multienvio', $multienvio ? 1 : 0); $EnvioModel->set('created_at', date('Y-m-d H:i:s')); $EnvioModel->set('updated_at', date('Y-m-d H:i:s')); $EnvioModel->insert(); $idEnvio = $EnvioModel->insertID(); // se genera la linea de envio $EnvioLineasModel = model('App\Models\Logistica\EnvioLineaModel'); $EnvioLineasModel->save([ 'envio_id' => $idEnvio, 'pedido_id' => $pedido_id, 'unidades_envio' => $datosEnvio->cantidad, 'unidades_total' => $datosEnvio->cantidad_total, 'cajas' => 1, 'unidades_cajas' => 1, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s'), 'created_by' => auth()->user()->id, 'updated_by' => auth()->user()->id, 'presupuesto_id' => (int) $datosEnvio->presupuesto_id ]); return [ 'status' => true, 'data' => [ 'id_envio' => $idEnvio, 'multienvio' => false, ], ]; } if (empty($datosEnvio)) { return [ 'status' => false, 'message' => lang('Logistica.errors.noAddresses'), ]; } } public static function finalizarEnvio($envio_id, $finalizar_ot = false) { // hay que comprobar que para todas las lineas de envio de este envio // se ha enviado toda la cantidad teniendo en cuenta otros envios $EnvioModel = model('App\Models\Logistica\EnvioModel'); $EnvioLineasModel = model('App\Models\Logistica\EnvioLineaModel'); $ots = []; $envio = $EnvioModel->find($envio_id); if (empty($envio)) { return [ 'status' => false, 'message' => lang('Logistica.errors.noEnvio'), ]; } $lineasEnvio = $EnvioLineasModel->where('envio_id', $envio_id) ->findAll(); if (empty($lineasEnvio)) { return [ 'status' => false, 'message' => lang('Logistica.errors.noEnvioLineas'), ]; } foreach ($lineasEnvio as $linea) { $pedido = model('App\Models\Pedidos\PedidoModel')->find($linea->pedido_id); if (empty($pedido)) { return [ 'status' => false, 'message' => lang('Logistica.errors.notFound'), ]; } $cantidad_enviada = $EnvioLineasModel->select('SUM(envios_lineas.unidades_envio) as unidades_enviadas') ->where('envios_lineas.pedido_id', $linea->pedido_id) ->where('envios_lineas.envio_id !=', $envio_id) ->where('envios.finalizado', 1) ->join('envios', 'envios.id = envios_lineas.envio_id') ->get()->getResult(); if ( count($cantidad_enviada) == 0 || empty($cantidad_enviada[0]->unidades_enviadas) || $cantidad_enviada[0]->unidades_enviadas == null ) { $cantidad_enviada = 0; } else { $cantidad_enviada = $cantidad_enviada[0]->unidades_enviadas; } if ($cantidad_enviada + $linea->unidades_envio == $linea->unidades_total) { $otModel = model('App\Models\OrdenTrabajo\OrdenTrabajoModel'); $ot = $otModel->where('pedido_id', $linea->pedido_id) ->first(); $ps = (new ProductionService())->init($ot->id); $ps->updateOrdenTrabajoDate([ "name" => "envio_at", "envio_at" => date('Y-m-d H:i:s') ]); if ($finalizar_ot) { $ps->updateOrdenTrabajo( [ "estado" => 'F' ] ); array_push($ots, $ot->id); } } } $EnvioModel->update($envio_id, ['finalizado' => 1]); $data_return = [ 'status' => true, 'message' => lang('Logistica.success.finalizado'), ]; if ($finalizar_ot) { $data_return['ots'] = $ots; } return $data_return; } }