0

With reference to Insert multiple rows into table by checkboxcolumn in yii2 I'm asking this question. I'm trying to insert data into rawmaterial table. The data that will be inserted is coming from rmtemplate table. I've added a gridview that loads data from rmtemplate in the rawmaterial form. Along with the checked rows I have two more fields usedate, chargenumber which will be inserted with each row.

Bythe code below it only inserts a single row with no other data except chargenumber,usedate

_form.php

<?php

use yii\helpers\Html;
use yii\helpers\Url;
use yii\widgets\ActiveForm;
use kartik\grid\GridView;
use dosamigos\datepicker\DatePicker;
use kartik\select2\Select2;
use yii\helpers\ArrayHelper;
use frontend\models\Rmtemplate;
use yii\helpers\Json;
use yii\web\View;

/* @var $this yii\web\View */
/* @var $model frontend\models\Rawmaterial */
/* @var $form yii\widgets\ActiveForm */
?>

<div class="rawmaterial-form">

    <?php $form = ActiveForm::begin(); ?>
    <div class="form-group">
        <div class="col-xs-6 col-sm-6 col-lg-6">
            <?= $form->field($model, 'usedate')->widget(
                DatePicker::className(), [
                // inline too, not bad
                 'inline' => false, 
                 // modify template for custom rendering
                //'template' => '<div class="well well-sm" style="background-color: #fff; width:250px">{input}</div>',
                'clientOptions' => [
                    'autoclose' => true,
                    'todayHighlight' => true,
                    'format' => 'yyyy-mm-dd'
                ]
            ]);?>
        </div>

        <div class="col-xs-6 col-sm-6 col-lg-6">
            <?= $form->field($model, 'chargenumber')->textInput(['readOnly' => true]) ?>
        </div>

        <div class="col-xs-12 col-sm-12 col-lg-12">
            <?= GridView::widget([
            'dataProvider' => $dataProvider2,
            'filterModel' => $searchModel2,
            //'id' => $mytable,
            'columns' => [
                [
                'class' => 'kartik\grid\CheckboxColumn',
                'name' => 'RawMaterialForm[rmtemplate_ids]',
                'checkboxOptions' => function ($model, $key, $index, $column) {
                    return ['value' => $model->id];
                }
                ],

                //'id',
                //'productname',
                [
                    'attribute'=>'productname',
                    'filterType'=>GridView::FILTER_SELECT2,
                    'filter'=>ArrayHelper::map(Rmtemplate::find()->orderBy(['productname' => SORT_ASC])->asArray()->all(), 'productname', 'productname'),
                    'filterWidgetOptions'=>[
                    'pluginOptions'=>['allowClear'=>true],
                                        ],
                    'filterInputOptions'=>['placeholder'=>'Charge Name'],
                ],
                'rmname',
                'qty',
                'cost',

                //['class' => 'yii\grid\ActionColumn'],
            ],
        ]); ?>
        </div>
    </div>  


    <div class="form-group">
        <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary','name' => 'submit', 'value' => 'create_update']) ?>
    </div>

    <?php ActiveForm::end(); ?>

</div>

<?php
/* start getting the chargeno */
$script = <<<EOD
  $(window).load(function(){
  $.get('index.php?r=rmprod/rawmaterial/get-for-chargeno',{ orderid : 1 }, function(data){
      //alert(data);
      var data = $.parseJSON(data);
      $('#rawmaterialform-chargenumber').attr('value',data.chargeno);
  }
  );
});
EOD;
$this->registerJs($script);
/*end getting the chargeno */
?>

Rwmaterial model

<?php

namespace frontend\modules\rmprod\models;

use Yii;

/**
 * This is the model class for table "rawmaterial".
 *
 * @property integer $id
 * @property string $vname
 * @property integer $rm_chid
 * @property string $challan
 * @property string $purchasedate
 * @property string $purchaseqty
 * @property string $rate
 * @property string $rmname
 * @property string $usedate
 * @property string $useqty
 * @property string $unitcost
 * @property string $productname
 * @property integer $chargenumber
 *
 * @property Pursum $rmCh
 */
class Rawmaterial extends \yii\db\ActiveRecord
{
    public $mytable;
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'rawmaterial';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['rm_chid', 'chargenumber'], 'integer'],
            [['purchasedate', 'usedate'], 'safe'],
            [['vname', 'productname'], 'string', 'max' => 40],
            [['challan'], 'string', 'max' => 20],
            [['purchaseqty', 'rmname', 'useqty'], 'string', 'max' => 50],
            [['rate', 'unitcost'], 'string', 'max' => 10],
            [['rm_chid'], 'exist', 'skipOnError' => true, 'targetClass' => Pursum::className(), 'targetAttribute' => ['rm_chid' => 'ps_chid']],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'vname' => 'Vname',
            'rm_chid' => 'Rm Chid',
            'challan' => 'Challan',
            'purchasedate' => 'Purchasedate',
            'purchaseqty' => 'Purchaseqty',
            'rate' => 'Rate',
            'rmname' => 'Rmname',
            'usedate' => 'Usedate',
            'useqty' => 'Useqty',
            'unitcost' => 'Unitcost',
            'productname' => 'Productname',
            'chargenumber' => 'Chargenumber',
        ];
    }

    /**
     * @return \yii\db\ActiveQuery
     */
    public function getRmCh()
    {
        return $this->hasOne(Pursum::className(), ['ps_chid' => 'rm_chid']);
    }
}

RawmaterialForm model

<?php

namespace frontend\modules\rmprod\models;

use Yii;

/**
 * This is the model class for table "rawmaterial".
 *
 * @property integer $id
 * @property string $vname
 * @property string $challan
 * @property string $purchasedate
 * @property string $purchaseqty
 * @property string $rate
 * @property string $rmname
 * @property string $usedate
 * @property string $useqty
 * @property string $unitcost
 * @property string $productname
 * @property integer $chargenumber
 */
class RawMaterialForm extends \yii\db\ActiveRecord
{
    public $rmtemplate_ids;
    public $mytable;
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'rawmaterial';
    }

    /**
     * @inheritdoc
     */
    // public function rules()
    // {
    //     return [
    //         [['purchasedate', 'usedate'], 'safe'],
    //         [['chargenumber'], 'integer'],
    //         [['vname', 'productname'], 'string', 'max' => 40],
    //         [['challan'], 'string', 'max' => 20],
    //         [['purchaseqty', 'rmname', 'useqty'], 'string', 'max' => 50],
    //         [['rate', 'unitcost'], 'string', 'max' => 10],
    //     ];
    // }

    public function rules()
    {
        return [
            [['usedate'], 'safe'],
            [['chargenumber'], 'integer'],
            [['productname'], 'string', 'max' => 40],
            [['rmname', 'useqty'], 'string', 'max' => 50],
            [['unitcost'], 'string', 'max' => 10],
            [['rmtemplate_ids'], 'safe'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'rmname' => 'Rmname',
            'usedate' => 'Usedate',
            'useqty' => 'Useqty',
            'unitcost' => 'Unitcost',
            'productname' => 'Productname',
            'chargenumber' => 'Chargenumber',
        ];
    }

}

Rawmaterial controller

<?php

namespace frontend\modules\rmprod\controllers;

use Yii;
use frontend\models\Rawmaterial;
use frontend\modules\rmprod\models\RawmaterialSearch;
use frontend\modules\rmprod\models\RmtemplateSearch;
use frontend\modules\rmprod\models\RawMaterialForm;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\helpers\Json;

/**
 * RawmaterialController implements the CRUD actions for Rawmaterial model.
 */
class RawmaterialController extends Controller
{
    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'delete' => ['POST'],
                ],
            ],
        ];
    }

    /**
     * Lists all Rawmaterial models.
     * @return mixed
     */
    public function actionIndex()
    {
        $searchModel = new RawmaterialSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

        $searchModel2 = new RmtemplateSearch();
        $dataProvider2 = $searchModel->search(Yii::$app->request->queryParams);

        return $this->render('index', [
            'searchModel' => $searchModel,
            'dataProvider' => $dataProvider,

            'searchModel2' => $searchModel2,
            'dataProvider2' => $dataProvider2,
        ]);
    }

    /**
     * Displays a single Rawmaterial model.
     * @param integer $id
     * @return mixed
     */
    public function actionView($id)
    {
        return $this->render('view', [
            'model' => $this->findModel($id),
        ]);
    }

    /**
     * Creates a new Rawmaterial model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     * @return mixed
     */
    public function actionCreate()
{
    $model = new RawMaterialForm();

    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        return $this->redirect(
            ['create']
            // redirect to where you want
        );
    }

    $searchModel2 = new RmtemplateSearch();
    $dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams);

    return $this->render('create', [
        'model' => $model,
        'searchModel2' => $searchModel2,
        'dataProvider2' => $dataProvider2,
    ]);
}

    /**
     * Updates an existing Rawmaterial model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id
     * @return mixed
     */
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);

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

    /**
     * Deletes an existing Rawmaterial model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param integer $id
     * @return mixed
     */
    public function actionDelete($id)
    {
        $this->findModel($id)->delete();

        return $this->redirect(['index']);
    }
    public function actionGetForChargeno($orderid)
    {
        $rates = Rawmaterial::find()->select('(max(chargenumber) + 1) as chargeno')->asArray()->one();
        echo Json::encode($rates);
    }
    /**
     * Finds the Rawmaterial model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param integer $id
     * @return Rawmaterial the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($id)
    {
        if (($model = Rawmaterial::findOne($id)) !== null) {
            return $model;
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }
    public function save()
    {
        try {
            if ($this->validate()) {
                // assuming Rmtemplate is the model used in RmtemplateSearch
                $selectedRmtemplate = Rmtemplate::find()->where(['id' => $this->rmtemplate_ids]);
                foreach ($selectedRmtemplate->each() as $rm) {
                    $rawMaterial = new Rawmaterial();
                    $rawMaterial->rmname = $rm->rmname;
                    $rawMaterial->usedate = $this->usedate;
                    $rawMaterial->useqty = $rm->qty;
                    $rawMaterial->unitcost = $rm->unitcost;
                    $rawMaterial->productname = $rm->productname;
                    $rawMaterial->chargenumber = $this->chargenumber;
                    if (!$rawMaterial->save()) {
                        throw new \Exception('Error while saving rawMaterial!');
                    }
                }
                return true;
            }
        } catch (\Exception $exc) {
            \Yii::error($exc->getMessage());
        }
        return false;
    }
}

The debug toolbar shows the following - enter image description here

enter image description here

enter image description here

After moving save function to RawmaterialForm model

enter image description here

VarDump

public function actionCreate()
    {
    $model = new RawMaterialForm();

    if ($model->load(Yii::$app->request->post()) && $model->validate()) {
        if($model->saveRawTemlate($model)) {
            // success message
        } else {
            // failure message
        }
        return $this->redirect(['create']);
    }
    if ($rawMaterial->save()) { throw new \Exception('Error while saving rawMaterial!'); } else { var_dump($rawMaterial->getErrors());}

    $searchModel2 = new RmtemplateSearch();
    $dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams);

    return $this->render('create', [
        'model' => $model,
        'searchModel2' => $searchModel2,
        'dataProvider2' => $dataProvider2,
    ]);
    }

Vardump in Function

public function saveRawTemlate($model)
{
    try {
        // assuming Rmtemplate is the model used in RmtemplateSearch
        $selectedRmtemplate = Rmtemplate::find()->where(['id' => $model->rmtemplate_ids]);
        foreach ($selectedRmtemplate->each() as $rm) {
            $rawMaterial = new Rawmaterial();
            $rawMaterial->rmname = $rm->rmname;
            $rawMaterial->usedate = $model->usedate;
            $rawMaterial->useqty = $rm->qty;
            $rawMaterial->unitcost = $rm->unitcost;
            $rawMaterial->productname = $rm->productname;
            $rawMaterial->chargenumber = $model->chargenumber;
            if (!$rawMaterial->save()) {
                throw new \Exception('Error while saving rawMaterial!');
            }
        }
    return true;
    } catch (\Exception $exc) {
        \Yii::error($exc->getMessage());
    }
    if ($rawMaterial->save()) { throw new \Exception('Error while saving rawMaterial!'); } else { var_dump($rawMaterial->getErrors());}
    return false;
}

function saveRawTemlate

public function saveRawTemlate($model)
{
    try {
        // assuming Rmtemplate is the model used in RmtemplateSearch
        //$selectedRmtemplate = Rmtemplate::find()->where(['id' => $model->rmtemplate_ids]);
        $selectedRmtemplate = Rmtemplate::find()->where(['id' => $model->rmtemplate_ids])->all();
        var_dump($selectedRmtemplate);
        foreach ($selectedRmtemplate->each() as $rm) {
            $rawMaterial = new Rawmaterial();
            $rawMaterial->rmname = $rm->rmname;
            $rawMaterial->usedate = $model->usedate;
            $rawMaterial->useqty = $rm->qty;
            $rawMaterial->unitcost = $rm->unitcost;
            $rawMaterial->productname = $rm->productname;
            $rawMaterial->chargenumber = $model->chargenumber;
            if (!$rawMaterial->save()) {
                //var_dump($rawMaterial->getErrors()); exit;
                throw new \Exception('Error while saving rawMaterial!');
            }
        }
    return true;
    } catch (\Exception $exc) {
        \Yii::error($exc->getMessage());
    }

    return false;
}

Output enter image description here

Community
  • 1
  • 1
Alias
  • 681
  • 16
  • 55
  • Because `save()` method never called. For controller it would be `$this->save()` i guess. The `save()` function should be in model and don't try to override default model methods if not required. – Insane Skull Dec 14 '16 at 05:49
  • You mean save function should be in RawmaterialForm model? I've put it there and it's giving error - Declaration of frontend\modules\rmprod\models\RawMaterialForm::save() must be compatible with yii\db\ActiveRecordInterface::save($runValidation = true, $attributeNames = NULL) and also I'm not sure where to put $this->save() in controller action. Please let me know how to solve it. – Alias Dec 14 '16 at 06:17
  • `save()` is an ActiveRecordInterface method to save data that you are trying to override rename it move this method to model and look for how to save data using foreach or use batch insert. Busy right now will answer it when get time. – Insane Skull Dec 14 '16 at 07:13
  • ok. please let me know. – Alias Dec 16 '16 at 06:17

1 Answers1

0

Controller

public function actionCreate()
{
    $model = new RawMaterialForm();

    if ($model->load(Yii::$app->request->post()) && $model->validate()) {
        if($model->saveRawTemlate($model)) {
            // success message
        } else {
            // failure message
        }
        return $this->redirect(['create']);
    }

    $searchModel2 = new RmtemplateSearch();
    $dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams);

    return $this->render('create', [
        'model' => $model,
        'searchModel2' => $searchModel2,
        'dataProvider2' => $dataProvider2,
    ]);
}

Model

public function saveRawTemlate($model)
{
    try {
        // assuming Rmtemplate is the model used in RmtemplateSearch
        $selectedRmtemplate = Rmtemplate::find()->where(['id' => $model->rmtemplate_ids])->all();
        foreach ($selectedRmtemplate as $rm) {
            $rawMaterial = new Rawmaterial();
            $rawMaterial->rmname = $rm['rmname'];
            $rawMaterial->usedate = $model->usedate;
            $rawMaterial->useqty = $rm['qty'];
            $rawMaterial->unitcost = $rm['unitcost'];
            $rawMaterial->productname = $rm['productname'];
            $rawMaterial->chargenumber = $model->chargenumber;
            if (!$rawMaterial->save()) {
                throw new \Exception('Error while saving rawMaterial!');
            }
        }
    return true;
    } catch (\Exception $exc) {
        \Yii::error($exc->getMessage());
    }
    return false;
}
Insane Skull
  • 9,220
  • 9
  • 44
  • 63
  • Hi Insane Skull, Thanks for the answer. But it's not inserting anything in rawmaterial table. – Alias Dec 17 '16 at 03:23
  • `if ($rawMaterial->save()) { throw new \Exception('Error while saving rawMaterial!'); } else { var_dump($rawMaterial->getErrors());}` – Insane Skull Dec 18 '16 at 13:59
  • You mean in the controller? I've added the code with vardump in the question. – Alias Dec 19 '16 at 05:09
  • @Tanmay. no in model inside `saveRawTemlate()` function. – Insane Skull Dec 19 '16 at 05:16
  • I've added in the function and added the present code in the question. Please let me know if it's correct. And it is giving Exception - Error while saving rawMaterial! – Alias Dec 19 '16 at 05:37
  • @Tanmay remove `if ($rawMaterial->save()) { throw new \Exception('Error while saving rawMaterial!'); } else { var_dump($rawMaterial->getErrors());} return false;` from model and see updated answer. – Insane Skull Dec 19 '16 at 08:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/130923/discussion-between-insane-skull-and-tanmay). – Insane Skull Dec 19 '16 at 08:47
  • I'm not so sure if I'm writing the correct code or not. Somehow 1 row of data inserted into the database and I don't recognize how. because no field inserted in rawmaterial table except rmname,usedate,useqty. But productname, unitcost,chargenumber was not inserted. Can we retry it? – Alias Dec 20 '16 at 06:42
  • @Tanmay. `$selectedRmtemplate = Rmtemplate::find()->where(['id' => $model->rmtemplate_ids])->all();` then check result `var_dump($selectedRmtemplate);` make sure your loop working correctly. – Insane Skull Dec 20 '16 at 06:56
  • Hi InsaneSkull, I think the loop is working partially. only rmname and qty field is getting the data other fields are not. Please check the updated present code and output in the question. – Alias Dec 20 '16 at 07:10
  • unitcost is not from rmtemplate model. It is a calculated field with the data from rmtemplate model that is present in the gridview in the form. With the updated code - still the same result. In yii debug tool, in the Database tab - I can see that there's no insert command running after I'm clicking on create. – Alias Dec 20 '16 at 14:04
  • As you mentioned, can it be done by batch insert or anything else. – Alias Dec 24 '16 at 14:21
  • @Tanmay. yes, it can be done by [batch insert](http://www.yiiframework.com/doc-2.0/yii-db-command.html#batchInsert()-detail) – Insane Skull Dec 26 '16 at 04:24