2

Longtime passive user of StackExchange and I am at a loss here. It's probably super simple, but I'm stuck. I've used gii-enhanced to build the models and CRUD.

  • I have two models: ordenes and facturas.

  • When I'm updating a facturas model I can link it to an already existing ordenes model.

  • A facturas model can be linked to an ordenes model.

  • Ordenes has an amount field and so does facturas.

What I currently have: I can link a facturas model to an already existing ordenes model. One facturas model can have only one ordenes model, while an ordenes model can have more than one facturas model linked to it.

What I'd like to achieve is that when I link a facturas model to an ordenes model the amount from the facturas model is subtracted from the amount of the ordenes model and the new value saved to the ordenes table. So, if I already have a ordenes model with an amount of, say $200000, and link to it a facturas model with an amount of $150000, the updated ordenes model should have an amount of $50000.

The relevant code in facturasController:

public function actionUpdate($id)
    {
        $model = $this->findModel($id);

        if ($model->loadAll(Yii::$app->request->post()) && $model->saveAll()) {
            return $this->redirect(['view', 'id' => $model->idfacturas]);
        } else {
            return $this->render('update', [
                'model' => $model,
            ]);
        }
    }

The relevant field in the view:

<?= $form->field($model, 'ordenes_idordenes')->widget(\kartik\widgets\Select2::classname(), [
        'data' => \yii\helpers\ArrayHelper::map(\frontend\models\Ordenes::find()->orderBy('idordenes')->asArray()->all(), 'idordenes', 'numero'),
        'options' => ['placeholder' => Yii::t('app', 'Vincular Orden de Compra')],
        'pluginOptions' => [
            'allowClear' => true
        ],
    ]); ?>

The relevant parts of the facturas Model:

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getOrdenesIdordenes()
    {
        return $this->hasOne(\frontend\models\Ordenes::className(), ['idordenes' => 'ordenes_idordenes'])->inverseOf('facturas');
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getProveedoresIdproveedores()
    {
        return $this->hasOne(\frontend\models\Proveedores::className(), ['idproveedores' => 'proveedores_idproveedores'])->inverseOf('facturas');
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    /*public function getUserIduser()
    {
        return $this->hasOne(\frontend\models\User::className(), ['id' => 'user_iduser'])->inverseOf('facturas');
    }*/
    public function getUserIduser()
    {
        return $this->hasOne(\backend\models\User::className(), ['id' => 'user_iduser'])->inverseOf('facturas');
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getOrdenes()
    {
        return $this->hasMany(\frontend\models\Ordenes::className(), ['facturas_idfacturas' => 'idfacturas'])->inverseOf('facturasIdfacturas');
    }

     /**
    * @return \yii\db\ActiveQuery
    */
   public function getEstadosContab()
   {
       return $this->hasOne(\frontend\models\EstadosContab::className(), ['idcontab' => 'estados_contab'])->inverseOf('facturas');
   }

/**
     * @inheritdoc
     * @return array mixed
     */ 
    public function behaviors()
    {
        return [
            'blameable' => [
                'class' => BlameableBehavior::className(),
                'createdByAttribute' => 'user_crea',
                'updatedByAttribute' => 'user_modif',
            ],
            'uuid' => [
                'class' => UUIDBehavior::className(),
                'column' => 'idfacturas',
            ],
        ];
    }

    /**
     * @inheritdoc
     * @return \frontend\models\FacturasQuery the active query used by this AR class.
     */
    public static function find()
    {
        return new \frontend\models\FacturasQuery(get_called_class());
    }
}

And the relevant parts of the Ordenes Model:

 /**
     * @return \yii\db\ActiveQuery
     */
    public function getFacturas()
    {
        return $this->hasMany(\frontend\models\Facturas::className(), ['ordenes_idordenes' => 'idordenes'])->inverseOf('ordenesIdordenes');
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getNotas()
    {
        return $this->hasMany(\frontend\models\Notas::className(), ['ordenes_idordenes' => 'idordenes'])->inverseOf('ordenesIdordenes');
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getEstado()
    {
        return $this->hasOne(\frontend\models\Estados::className(), ['idestados' => 'estado_id'])->inverseOf('ordenes');
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getNotasIdnotas()
    {
        return $this->hasOne(\frontend\models\Notas::className(), ['idnotas' => 'notas_idnotas'])->inverseOf('ordenes');
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getFacturasIdfacturas()
    {
        return $this->hasOne(\frontend\models\Facturas::className(), ['idfacturas' => 'facturas_idfacturas'])->inverseOf('ordenes');
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getProveedoresIdproveedores()
    {
        return $this->hasOne(\frontend\models\Proveedores::className(), ['idproveedores' => 'proveedores_idproveedores'])->inverseOf('ordenes');
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getTipocompra()
    {
        return $this->hasOne(\frontend\models\TipoCompra::className(), ['category_id' => 'tipocompra_id'])->inverseOf('ordenes');
    }

/**
     * @inheritdoc
     * @return array mixed
     */ 
    public function behaviors()
    {
        return [
            'blameable' => [
                'class' => BlameableBehavior::className(),
                'createdByAttribute' => 'created_by',
                'updatedByAttribute' => 'updated_by',
            ],
            'uuid' => [
                'class' => UUIDBehavior::className(),
                'column' => 'idordenes',
            ],
        ];
    }

    /**
     * @inheritdoc
     * @return \frontend\models\OrdenesQuery the active query used by this AR class.
     */
    public static function find()
    {
        return new \frontend\models\OrdenesQuery(get_called_class());
    }
}
ScaisEdge
  • 131,976
  • 10
  • 91
  • 107
Carlos
  • 93
  • 2
  • 7

1 Answers1

2

This is just a suggestion
you should populate model Facturas retriving the facturas related to this orders and then assign properly the value you need to the facturas model

use common\models\Facturas;

public function actionUpdate($id)
    {
        $model = $this->findModel($id);


        if ($model->loadAll(Yii::$app->request->post()){
           $modelFacturas = Facturas::find()
             ->(['your_id_fatcuras' => $model->your_id_facturas ])->one();
           $modelFacturas->you_field_to_change =  $model->value1 - $modelFacturas->value2;
           $model->save();
           $modelFacturas->save();

           return $this->redirect(['view', 'id' => $model->idfacturas]);
        } else {
            return $this->render('update', [
                'model' => $model,
            ]);
        }
    }

based on your last comment this could be a more precise answer to your question

Assuming you Orders Model is name Orders and in Facturas you have a field named fk_orders where you pass the value selectd by user in the view and that can link the related order

Then in Facturas Controller you can

use common\models\Orders;

public function actionUpdate($id)
    {
        $model = $this->findModel($id); // retrive the Factursa model


        if ($model->loadAll(Yii::$app->request->post()){
           $modelOrders = Orders::find()
             ->(['id_orders' => $model->fk_orders ])->one();
           $modelOrders->amount  =  $modelOrders->amount - $model->value_to_subtract;
           $model->save();
           $modelOrders->save();

           return $this->redirect(['view', 'id' => $model->idfacturas]);
        } else {
            return $this->render('update', [
                'model' => $model,
            ]);
        }
    }
ScaisEdge
  • 131,976
  • 10
  • 91
  • 107
  • The thing is, the **Facturas** model, when first created, doesn't have a related **Orders** model. It's when the user updates the Facturas model that a relation it's created (via a select box). It's at that point that the **monto** (amount) from the Facturas model should be subtracted from the monto of the **newly related** Orders model. All that from the update view of the Facturas model. – Carlos Apr 03 '17 at 14:40
  • then the main model is a Fatcuras model and the submit return also the reference for an orders model ? – ScaisEdge Apr 03 '17 at 15:35
  • Actually, the setup is like this: First, an Ordenes model is created. Later a Facturas model is created too. Both have an **amount** field that details how much money that document is worth. At some point a Facturas model must be linked to an Ordenes model. One Ordenes model can have many Facturas model relations, while a Facturas model can only have one Ordenes relation. The idea is that when the Facturas model is linked via the select box to an Ordenes model, both the Facturas and Ordenes model must be updated, but on different attributes (the ordenes FK for Facturas, the amount for Ordenes) – Carlos Apr 03 '17 at 20:18
  • The logic would be that bewtween the post and save, the controller would find the Ordenes model using the FK, then proceedo to do the math operation and finally saving both models and only then return to the view id. I understand it now. Excellent. – Carlos Apr 04 '17 at 19:54
  • However, I get a `syntax error, unexpected '{'` at the loadAll line. I've noticed that the first parenthesis at `if ($model` is not closed. Could that be the cause? – Carlos Apr 04 '17 at 20:15
  • i have removed the unexpected { .. answer updated – ScaisEdge Apr 05 '17 at 16:52
  • Somehow I kept getting that same warning. I've edited your code a bit: `if ($model->loadAll(Yii::$app->request->post()) && $model->saveAll()){....` I've accepted your solution since it helped me to understand a logic I had trouble with. Thank you, @scaisEdge. – Carlos Apr 05 '17 at 18:38
  • i see you have accepted the answer .. this mean that you have solved or understood the solution for the question?? – ScaisEdge Apr 05 '17 at 18:42
  • I have, yes. Thanks to your suggestions and input ;) – Carlos Apr 05 '17 at 19:36