0

I have a table rawmaterial. The fields are - rmname, usedate, useqty, unitcost, productname, chargenumber. I've added a gridview (which comes from rmtemplate table) with a checkboxcolumn in the form. The gridview contains columns productname, rmname, qty, unitcost. How can I insert the checked rows along with usedate, chargenumber(which come from respective textboxes) in the table rawmaterial.

I've checked ActiveRecord batch insert (yii2) but not getting how to use it with checkbocolumn.

Checked How I can process a checkbox column from Yii2 gridview? - not quite sure with it.

Checked Yii2 How to properly create checkbox column in gridview for bulk actions? - I think it's not using activeform.

form.php

<?php

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

/* @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-12 col-sm-12 col-lg-12">
            <?= $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-12 col-sm-12 col-lg-12">
            <?= GridView::widget([
            'dataProvider' => $dataProvider2,
            'filterModel' => $searchModel2,
            'columns' => [
                ['class' => 'kartik\grid\CheckboxColumn'],

                //'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',
                [
                 'attribute' => 'unitcost',
                 'value' => 'unitcost.unitcost',
                ],

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




    <?= $form->field($model, 'chargenumber')->textInput()->hiddenInput()->label(false) ?>



    <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);
      $('#rawmaterial-chargenumber').attr('value',data.chargeno);
  }
  );
});
EOD;
$this->registerJs($script);
/*end getting the chargeno */
?>

And it looks like below. enter image description here

CreateAction looks like -

public function actionCreate()
    {
        $model = new Rawmaterial();
        $searchModel2 = new RmtemplateSearch();
        $dataProvider2 = $searchModel2->search(Yii::$app->request->queryParams);

        if (isset($_POST['submit'])) { 

            if ($_POST('submit')  == 'create_update' )  {
            // then perform the insert 
                if ($model->load(Yii::$app->request->post()) && $model->save()) {
                return $this->redirect(['view', 'id' => $model->id]);
                } else {
                    return $this->render('create', [
                        'model' => $model,
                        'searchModel2' => $searchModel2,
                        'dataProvider2' => $dataProvider2,
                    ]);
                }
            }
            }  else {
                 // no insert  but render for filter ..
                return $this->render('create', [
                        'model' => $model,
                        'searchModel2' => $searchModel2,
                        'dataProvider2' => $dataProvider2,
                    ]);
            }


    }

Update RawMaterialForm.php

<?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
{
    /**
     * @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',
            'vname' => 'Vname',
            'challan' => 'Challan',
            'purchasedate' => 'Purchasedate',
            'purchaseqty' => 'Purchaseqty',
            'rate' => 'Rate',
            'rmname' => 'Rmname',
            'usedate' => 'Usedate',
            'useqty' => 'Useqty',
            'unitcost' => 'Unitcost',
            'productname' => 'Productname',
            'chargenumber' => 'Chargenumber',
        ];
    }
}

RawmaterialController

<?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;
}
}

Error enter image description here

Community
  • 1
  • 1
Alias
  • 681
  • 16
  • 55
  • Looks like you need to prepare additional model to handle the form data. I guess you want to copy the selected GridView rows models' fields to rawmaterial table but you never mentioned how you want them to be copied, I can only assume the same name fields should be copied but what about `useqty`? Also primary key of the rawmaterial is required. – Bizley Nov 01 '16 at 07:32
  • The column 'qty' from gridview should be entered into 'useqty' of rawmaterial table. Also, the primary key of rawmaterial 'id' is auto increment. Now, I'm not quite sure how to copy these columns or rows into rawmaterial table. That's why didn't progress in it that much. – Alias Nov 01 '16 at 08:15

2 Answers2

0

According to my understanding, you have to do two things.

  • Firstly, you have to grab all the checked rows data of the grid view as an array or object. You can see how to do that from Get Grid Data .
  • Secondly you have to change your create action for handling the data you fetch from that grid. You can take help from Batch Insert

Hope it helps...

Community
  • 1
  • 1
masud_moni
  • 1,121
  • 16
  • 33
0

Prepare additional model like RawMaterialForm with properties that will be taken from ActiveForm usedate, chargenumber and rmtemplate_ids. The last one is the array of GridView IDs. Remember to add rules() in the RawMaterialForm for the properties.

The view - just the GridView needs some tweaks. Extend the configuration for Checkbox column.

[
    'class' => 'kartik\grid\CheckboxColumn',
    'name' => 'RawMaterialForm[rmtemplate_ids]',
    'checkboxOptions' => function ($model, $key, $index, $column) {
        return ['value' => $model->id];
    }
],

The action:

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

    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        return $this->redirect(
            // 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,
    ]);
}

RawMaterialForm's save() method:

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;
}

This will copy every selected row into a new Rawmaterial row with additional inputs from ActiveForm. In case of errors in $rawMaterial saving check $rawMaterial->errors property.

Fair warning - depending on the system performance this can be slow (or even fatal) in case of selecting many rows at once.

Bizley
  • 17,392
  • 5
  • 49
  • 59
  • Sorry for late reply. I've placed the codes asfar I understood. I've given my current position under update in the question. Now I'm getting error as shown in the question. Then I've tried adding public $rmtemplate_ids in the RawMaterialForm model. Then the error is gone but only the usedate is inserted in the rawmaterial table and that too only once. – Alias Nov 03 '16 at 06:08
  • Well, like I wrote in the first sentence you need to prepare this model with all the attributes and it means you have to list all the attributes and add validation rules for them. – Bizley Nov 03 '16 at 06:58
  • I think I've written it in the RawMaterialForm model as shown in the question(in the update section). If that's not what you mean then please show an example and I'll do the rest. I'm not quite getting it. – Alias Nov 04 '16 at 03:43