Yii Framework Forum

Seleccionar datos desde otro modelo en un maestro detalle


(ra_ro_sa) #1

Hola comunidad, buenas tardes, estoy presentando un problema con selecionar datos de otro modelo para los detalles en un maestro detalle.
El problema es que estoy haciendo unas facturas donde tengo dos tablas para las facturas

  1. facturas (principal)
  2. detallesfacturas (detalles de facturas)
    en la tabla facturas tengo los campos:
    Id int autonumerico llave primaria
    numero varchar 20 llave para enlace con la tabla detallesfacturas
    norden varchar 20
    cliente, importes, entidad, etc.
    en la tabla detallesfacturas tengo los campos:
    Id int autonumerico llave primaria
    Id_fac varchar 20 (relacionada uno a varios con el campo numero de la tabla facturas)
    cod_producto, precios, importes, etc.
    Previamente he creado otro maestro detalle donde se va a hacer una orden de despacho para luego hacer la factura.
    aqui tengo dos tablas también:
  3. Dorden principal
  4. detallesorden (detalles)
    con los campos:
    en la tabla dorden tengo los campos:
    Id int autonumerico llave primaria
    norden varchar 20 llave para enlace con la tabla detallesfacturas
    cliente, importes, entidad, etc.
    en la tabla detallesorden tengo los campos:
    Id int autonumerico llave primaria
    _Id_fac varchar 20 (relacionada uno a varios con el campo numero de la tabla dorden)
    cod_producto, precios, importes, etc.
    Este maestro detalles se hace perfectamente, el problema es que al hacer la factua que corresponde a una orden de despacho, quiero tomar los datos de las tablas anteriores directamente para no tener que volver a poner productos cliente etc.
    Solo en el formulario escoger la entidad, y el numero de orden despacho (norden) que esta relacionada con la tabla dorden (norden) uno a uno.
    asi tomo de la tabla dorden los demas valores de la tabla facturas y quiero tomar de la tabla detallesorden los valores de la tabla detallesfacturas, voy a mostrar la accion del controlador aqui:
public function actionCreate() {
        $model = new Facturas;
        $detalles = new Detallesfactura;
        $importeTotal = 0;
        $importeTotalc = 0;
        $impdl = 0;
        $imventas = 0;
        $imrecargo = 0;
        $imdescuento = 0;
        $e = $model->CodUEB;
        $n = 0;
        do {
            $e = floor($e / 10);
            $n = $n + 1;
        } while ($e > 0);
        // Uncomment the following line if AJAX validation is needed
        // $this->performAjaxValidation($model);
        $model = new Facturas;
        $detalles = new Detallesfactura;
        // Uncomment the following line if AJAX validation is needed
        //   $this->performAjaxValidation(array($model));
        if (isset($_POST['Facturas'])) {
            $model->attributes = $_POST['Facturas'];
            $orden = Dorden::model()->find('norden=:norden', array(':norden' => $model->norden)); //para buscar los valores y asignarlos a la tabla facturas
            $model->CodOp = $orden->CodOp;
            $model->Codde = $orden->Codde;
            $model->cliente= $orden->cliente;
            $model->CI = $orden->CI;
            $model->CodDoc = 2;
            $model->fechac = date('Y-m-d_h.i.s');
            if ($model->save(false)) {
                $fecha = date("y");
                $cadena = $model->CodUEB; // en este caso tiene 7 digitos
                $contar = strlen($cadena); // da la cantidad de digitos de la cadena
                $cadena1 = substr($cadena, -$n);
                $cadena2 = "1";
                $cadena4 = "$model->Id"; //
                $cadena5 = "0";
                $cadena6 = "00";
                $cadena7 = "000";
                $cadena8 = "N";
                //llenar numero de factura
                if ($this) {
                    $criteria = new CDbCriteria;
                    $criteria->addCondition('Id=:Id');
                    $criteria->params = array(':Id' => $model->Id);
                    $objFact = Facturas::model()->find($criteria);
                    if ($model->Id <= 9) {
                        $objFact->numero= $fecha . $cadena1 . $cadena2 . $cadena8 . $cadena7 . $cadena4;
                    } elseif ($model->Id >= 10 & $model->Idn <= 99) {
                        $objFact->numero= $fecha . $cadena1 . $cadena2 . $cadena8 . $cadena6 . $cadena4;
                    } elseif ($model->Id >= 100 & $model->Idn <= 999) {
                        $objFact->numero= $fecha . $cadena1 . $cadena2 . $cadena8 . $cadena5 . $cadena4;
                    } elseif ($model->Id >= 1000) {
                        $objFact->numero= $fecha . $cadena1 . $cadena2 . $cadena8 . $cadena4;
                    }
                    $objFact->save();
                }
                           
                $detaor = Detallesorden::model()->find('Id_fac=:Id_fac', array(':Id_fac' => $orden->norden));  //para buscar los valores de los detalles 6y asignarlos a detallesfacturas  
**_//aqui se que debe ir un foreach o algo asi, para que me tome todos los valores, pero no se como hacerlo, siempre que lo intento no lo hace bien y solo me toma un producto y quiero que si detallesorden tiene 3 productos, me pase los tres a detallesfacturas**          
                $detalles->Id_fac = $objFact->numero;
                $detalles->cantidad = $detaor->cantidad;
                $detalles->premn = $detaor->premn;
                $detalles->cmay = $detaor->cmay;
                $detalles->cod_producto= $detaor->cod_producto;
                $detalles->Codpro = $detaor->Codpro;
                $produ = Productos::model()->find('cod_producto=:Codprod', array(':cod_producto' => $detaor->cod_producto));
                $produp = Subproductos::model()->find('Codpro=:Codpro', array(':Codpro' => $detaor->Codpro));
                $prodtipo = Tipoprod::model()->find('Codtipo = :Codtipo', array(':Codtipo' => $produp->Codtipo));
                $turcad = Turcad::model()->find('CodOp=:CodOp', array(':CodOp' => $orden->CodOp));
                // $producmayor = submayor::model()->find('Codpro=:Codpro and CodPVen=:codpven', array(':Codpro' => $produp->Codpro, ':codpven' => $venta));
                $producmayor = Submayor::model()->find('Codpro=:Codpro', array(':Codpro' => $produp->Codpro));
                $detalles->CodPVen = $producmayor->CodPVen;
                $detalles->SaldoDes = $producmayor->SaldoAct - $detalles->cantidad;
                $detalles->SaldoIni = $producmayor->SaldoAct;
                $mayor = Cmayorista::model()->find('IdMay=:IdMay', array(':IdMay' => $detaor->cmay));
                $detalles->importemn = ROUND($detalles->premn * $detalles->cantidad, 2);
                //iventas mn
                if ($detalles->cmay <> 1) {
                    $detalles->imventas = ROUND((($detalles->premn - $produ->PreMay)) * $detalles->cantidad, 2);
                } elseif ($detalles->cmay <> 2) {
                    0;
                }
                // $detalles->imventas = ROUND((($produ->PreMay / $turcadm->Tasa - $produ->PreMay)) * $detalles->cantidad, 2);
                //recargo
                //recargo comercial
                if ($model->Idrecargo <> 1) {
                    $detalles->Recargoca = ROUND($detalles->cantidad * $prodtipo->recargo, 2);
                }
                //descuento comercial con formula: ($detalles->precuc * $detalles->cantidad) * $turcad->Coddes  
                if ($orden->Iddescuento <> 1) {
                    $detalles->descuento = ROUND($detalles->importemn * $turcad->Coddes, 2);
                }              
               
                //llenar otros calculos
                if ($this) {// - $detalles->descuento
                    $criteria = new CDbCriteria;
                    $criteria->addCondition('numero=:numero');
                    $criteria->params = array(':numero' => $objFact->numero);
                    $objFac = Facturas::model()->find($criteria);              
                    $objFac->Imporventas = $imventas;                
                    $objFac->Recargo = $imrecargo;               
                    $objFac->ImporteMN = $importeTotal;                  
                    $objFac->Descuento = $imdescuento;                 
                    $objFac->ImporteTotal = $importeTotal + $imrecargo - $imdescuento;                  
                    $objFac->save();             
                }
        
            }
            $this->redirect(array('admin', 'id' => $model->Id));
        }
        $this->render('create', array(
            'model' => $model,
            'detallesfactura' => $detalles,
         ));
    }

en la tabla detalles facturas solo toma el primer elemento de la tabla detallesorden y debe tomar todos los valores (detalles)
agradecido por la ayuda que me puedan dar.


(Jiuly Rojas) #2

aqui veo varias cositas . Declaras un new model para un mismo controlador. Hay maneras de trabajar multimodelos y asi no es la mas adecuada.

Aparte de eso hay algo en ingles que se llama Fat Models and skinny controllers (modelos gordos, controladores flacos). Todo los detalles de las relaciones entre los modelos deberían hacerse en modelo y no en el controlador . Sin embargo como ya tienes esto adelantado te doy dos opciones.

1.- crea el modelo y guarda factura y luego guarda los detalles de la factura con el id factura

2.- crea una vista con el encabezado o la tabla factura y luego ve a la vista detalle. A veces colocar todo en una misma vista complica las cosas.


(ra_ro_sa) #3

Gracias jiuly por responder, tu siempre muy amable, te explico algunas cosas:
necesito obtener los valores de los detalles de la orden de despacho para asignarselos a los detalles de factura, o sea, que los valores de la orden de despacho (detalles), sean los de los de detalles de factura, pero si la orden de despacho tiene 3 filas (productos), esa cantidad de fila sean los de los detalles de facturas, para ello estoy intentado mediante una consulta obtener los valores de orden de despacho:

  $ufid = $orden->norden;
                $sql = "SELECT *
                       FROM  detallesorden
                            JOIN
                              dorden
                            ON (detallesorden.Id_sal = dorden.norden)
                       WHERE detallesorden.Id_sal = :UFID";
                $funds = $this->fetch($sql, array(':UFID' => $ufid), 'queryRow');

con la funcion fetch:

public function fetch($sql = "", $bindValues = array(), $method = 'queryAll') {
        return Yii::app()->db
                        ->createCommand($sql)
                        ->bindValues($bindValues)
                        ->{$method}();
    }

despues intento asignarlos a los detalles para que me los tome todos, asi:

 foreach ($_POST['Facturas'] as $item) {
  $detalles->Id_sal = $objFact->nfactura;//numero de la factura del modelo facturas
//o Id de las facturas
  $detalles->cantidad = $sql->cantidad;//aqui explota y dice que esta vacio, 
//osea, Trying to get property of non-object 
.......

espero respuestas de esto