Your Location is: Home > Php

How to update records greater than selected one to update in Yii 2

From: Puerto View: 3206 Questions 

Question

I am using Yii2 basic. I have a table called groupsavingdetails which saves monthly groups saving.

I have records for Group with Id 29 and from Year 2017 and month August. Similarly I have the records for this particular group from 2017 September, October, November and December. Also there are data for this group for Year 2018 and Months January and March as shown in image.

enter image description here

The process is that For month August there was no entry for this group (i.e, it was the first time data entry, so Opening Balance is set to 0). Now for september the closing balance of August is taken as the Opening Balance and so on. So these are dependent.

Now the situation is when I want to change September months record, then its closing balance will get changed and thus this new closing balance will be set to opening balance for the October month and so on. How should I do this?

Below is the actionUpdate function which gives me error as Call to a member function save() on array


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

        if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
            Yii::$app->response->format = Response::FORMAT_JSON;
            return ActiveForm::validate($model);
        }

        if ($model->load(Yii::$app->request->post())) {

            $count = Yii::$app->db->createCommand('SELECT COUNT(*) FROM groupsavingdetails WHERE ((groupsavingdetails.GroupId=:Id and Year>=:year and Month>:month) OR (GroupId=:Id and Year>:year AND Month>0))')->bindValues([':Id' => $model->GroupId, ':year' => $model->Year, ':month' => $model->Month]->queryAll();


            if ($count == 0) {

            }

            if ($count == 1) {

            }

            if ($count > 1) {

                if ($model->LoanGiven != 0) {
                    $model->TotalValueofLoanGiven += $model->LoanGiven;
                }



                if ($model->LoanRecovery != 0) {
                    $model->LoanRepaidUptilNow += $model->LoanRecovery;
                }


                $model->TotalValueOfLoanOutstanding = $model->TotalValueofLoanGiven - $model->LoanRepaidUptilNow;

                $model->ClosingBalance = ($model->OpeningBalance + $model->TotalSaving + $model->LoanRecovery + $model->LoanInterest + $model->Fine + $model->BankInterest + $model->BankLoan - $model->Expenses - $model->LoanGiven);



                $groups = Yii::$app->db->createCommand('SELECT * FROM groupsavingdetails WHERE ((groupsavingdetails.GroupId=:Id and Year>=:year and Month>:month) OR (GroupId=:Id and Year>:year AND Month>0))')->bindValues([':Id' => $model->GroupId, ':year' => $model->Year, ':month' => $model->Month])->queryAll();


                foreach ($groups as $k => $group) {
                    if ($k == 0) {

                        $groups[$k]['OpeningBalance'] = $model->ClosingBalance;
                        $groups[$k]['TotalValueofLoanGiven'] = $model->TotalValueofLoanGiven;
                        $groups[$k]['LoanRepaidUptilNow'] = $model->LoanRepaidUptilNow;
                        $groups[$k]['TotalValueOfLoanOutstanding'] = $model->TotalValueOfLoanOutstanding;
                    }
                }


                $groups->save();   // Here it gives me error even if i write $groups[$k]->save()

                $model->save();



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

Best answer

You can't call save() (or any other function) on an array. Functions are called on objects. So you'll have to make sure you have an object, load the data onto the object and then save that object. You could do it like this:

foreach ($groups as $k => $group) {
    if ($k === 0) {
        $groupModel = new GroupSavingDetails(); // Or whatever the model is called..

        // Load the data onto the model
        $groupModel->OpeningBalance = $model->ClosingBalance;
        $groupModel->TotalValueofLoanGiven = $model->TotalValueofLoanGiven;
        $groupModel->LoanRepaidUptilNow = $model->LoanRepaidUptilNow;
        $groupModel->TotalValueOfLoanOutstanding = $model->TotalValueOfLoanOutstanding;

        // Save the model
        $groupModel->save();
    }
}

// Don't save $groups after the foreach, because that's still an array

This will (probably/hopefully) fix the code. But it might still not be the best way to do it. It seems like you could also accomplish updating all these records with just one UPDATE query. I did not test the code below, but this would create an update query that can be modified to update the correct rows. This way you don't have to retrieve all the individual records, update them one by one and the run an update command for each row.

Yii::$app->createCommand()->update(
    'groupsavingdetails', // Or GroupSavingDetails::tableName()
    [
        'OpeningBalance' => $model->ClosingBalance;
        'TotalValueofLoanGiven' => $model->TotalValueofLoanGiven,
        'LoanRepaidUptilNow' => $model->LoanRepaidUptilNow,
        'TotalValueOfLoanOutstanding' => $model->TotalValueOfLoanOutstanding,
    ],
    [
        'OR',
        [
            'AND',
            ['GroupId' => $model->groupId],
            ['>=', 'Year', $model->Year],
            ['>', 'Month', $model->Month],
        ],
        [
            'AND',
            ['GroupId' => $model->groupId],
            ['>', 'Year', $model->Year],
            ['>', 'Month', 0],
        ],
    ]
)->execute()