diff --git a/application/backend/controllers/WarehouseController.php b/application/backend/controllers/WarehouseController.php new file mode 100644 index 000000000..6b3cd85fc --- /dev/null +++ b/application/backend/controllers/WarehouseController.php @@ -0,0 +1,131 @@ + [ + 'class' => AccessControl::className(), + 'rules' => [ + [ + 'allow' => true, + 'roles' => ['product manage'], + ], + ], + ], + ]; + } + + /** + * @inheritdoc + */ + public function actions() + { + return [ + 'remove-all' => [ + 'class' => MultipleDelete::className(), + 'modelName' => Warehouse::className(), + ], + 'delete' => [ + 'class' => DeleteOne::className(), + 'modelName' => Warehouse::className(), + ], + 'update-editable' => [ + 'class' => UpdateEditable::className(), + 'modelName' => Warehouse::className(), + 'allowedAttributes' => [ + ], + ], + ]; + } + + public function actionIndex() + { + $searchModel = new Warehouse(); + $dataProvider = $searchModel->search($_GET); + + return $this->render( + 'index', + [ + 'dataProvider' => $dataProvider, + 'searchModel' => $searchModel, + ] + ); + } + + public function actionEdit($id = null) + { + $model = new Warehouse; + $model->loadDefaultValues(); + + if ($id !== null) { + $model = Warehouse::findOne($id); + } + + + + $post = \Yii::$app->request->post(); + + if ($model->load($post) && $model->validate()) { + + $save_result = $model->save(); + if ($save_result) { + Yii::$app->session->setFlash('info', Yii::t('app', 'Object saved')); + return $this->redirect(['/backend/warehouse/edit', 'id' => $model->id]); + } else { + \Yii::$app->session->setFlash('error', Yii::t('app', 'Cannot update data')); + } + + + } + + return $this->render( + 'form', + [ + 'model' => $model, + ] + ); + } + + public function actionUpdateRemains() + { + $post = Yii::$app->request->post('remain', null); + if (isset($post)) { + + Yii::$app->response->format = \yii\web\Response::FORMAT_JSON; + $remainId = current(array_keys($post)); + $model = WarehouseProduct::findOne($remainId); + if ($model === null) { + throw new NotFoundHttpException; + } + + $model->setAttributes(current($post)); + TagDependency::invalidate(Yii::$app->cache, ActiveRecordHelper::getObjectTag(\app\models\Product::className(), $model->product_id)); + return $model->save(); + + + } else { + throw new HttpException(400); + } + } + +} diff --git a/application/backend/views/product/product-form.php b/application/backend/views/product/product-form.php index 2b52ce6b6..0f8cab105 100644 --- a/application/backend/views/product/product-form.php +++ b/application/backend/views/product/product-form.php @@ -245,6 +245,22 @@ BackendWidget::end(); ?> + Yii::t('app', 'Warehouse'), + 'icon'=>'archive', + 'footer'=>$this->blocks['submit'] + ] + ); ?> + + field($model, 'sku') ?> + field($model, 'unlimited_count')->widget(\kartik\switchinput\SwitchInput::className())?> + $model, + ]) ?> + + - Yii::t('app', 'Warehouse'), - 'icon'=>'archive', - 'footer'=>$this->blocks['submit'] - ] - ); ?> - - field($model, 'sku') ?> - field($model, 'in_warehouse')?> - field($model, 'unlimited_count')->widget(\kartik\switchinput\SwitchInput::className())?> - field($model, 'reserved_count')?> - parent_id == 0) : ?> diff --git a/application/backend/widgets/WarehousesRemains.php b/application/backend/widgets/WarehousesRemains.php new file mode 100644 index 000000000..ed025b263 --- /dev/null +++ b/application/backend/widgets/WarehousesRemains.php @@ -0,0 +1,67 @@ +model === null) { + throw new InvalidConfigException("Model should be set for WarehousesRemains widget"); + } + + $state = $this->model->getWarehousesState(); + + $activeWarehousesIds = app\models\Warehouse::activeWarehousesIds(); + $remains = []; + foreach ($state as $remain) { + $remains[$remain->warehouse_id] = $remain; + if(($key = array_search($remain->warehouse_id, $activeWarehousesIds)) !== false) { + unset($activeWarehousesIds[$key]); + } + } + + // if we have new warehouses that not represented in warehouses state + if (count($activeWarehousesIds) > 0) { + foreach ($activeWarehousesIds as $id) { + // create new record with default values + $remain = new app\models\WarehouseProduct; + $remain->warehouse_id = $id; + $remain->product_id = $this->model->id; + $remain->save(); + + // add to remains + $remains[$remain->warehouse_id] = $remain; + } + TagDependency::invalidate(Yii::$app->cache, ActiveRecordHelper::getObjectTag($this->model->className(), $this->model->id)); + } + + return $this->render( + 'warehouses-remains', + [ + 'model' => $this->model, + 'remains' => $remains, + ] + ); + } +} \ No newline at end of file diff --git a/application/backend/widgets/views/warehouses-remains.php b/application/backend/widgets/views/warehouses-remains.php new file mode 100644 index 000000000..c4d1f9931 --- /dev/null +++ b/application/backend/widgets/views/warehouses-remains.php @@ -0,0 +1,93 @@ + + + + + + + + + + + + + $remain): ?> + + + + + + + + +
+ + + + + + + +
+ warehouse->name ?> + + id . '][in_warehouse]', + $remain->in_warehouse, + [ + 'class' => 'warehouse-remain-input form-control', + 'placeholder' => Yii::t('app', 'In warehouse'), + ] + ) ?> + + id . '][reserved_count]', + $remain->reserved_count, + [ + 'class' => 'warehouse-remain-input form-control', + 'placeholder' => Yii::t('app', 'Reserved count'), + ] + ) ?> + + id . '][sku]', + $remain->sku, + [ + 'class' => 'warehouse-remain-input form-control', + 'placeholder' => Yii::t('app', 'SKU'), + ] + ) ?> +
+ + \ No newline at end of file diff --git a/application/messages/ru/app.php b/application/messages/ru/app.php index 1719cbdc9..75c8eaf8d 100755 --- a/application/messages/ru/app.php +++ b/application/messages/ru/app.php @@ -221,6 +221,8 @@ 'Is active' => 'Активен', 'Item {value} is not assigned:' => '', 'Items in warehouse' => 'На складе', + 'In warehouse' => 'На складе', + 'Reserved count' => 'Зарезерировано', 'Items inside item: ' => 'Элементы внутри элемента: ', 'Items reserved' => 'Зарезервировано', 'ISO-4217 code' => 'ISO-4217 код', diff --git a/application/migrations/m150228_090542_multiple_warehouses.php b/application/migrations/m150228_090542_multiple_warehouses.php new file mode 100644 index 000000000..73b594a3b --- /dev/null +++ b/application/migrations/m150228_090542_multiple_warehouses.php @@ -0,0 +1,306 @@ +createTable( + '{{%warehouse}}', + [ + 'id' => Schema::TYPE_PK, + 'name' => Schema::TYPE_STRING, + 'is_active' => Schema::TYPE_BOOLEAN . ' NOT NULL DEFAULT 1', + 'country_id' => Schema::TYPE_INTEGER . ' NOT NULL', + 'city_id' => Schema::TYPE_INTEGER . ' NOT NULL', + 'address' => Schema::TYPE_TEXT, + 'description' => Schema::TYPE_TEXT, + 'sort_order' => Schema::TYPE_INTEGER . ' NOT NULL DEFAULT 0', + 'map_latitude' => Schema::TYPE_STRING . ' NOT NULL DEFAULT \'\'', + 'map_longitude' => Schema::TYPE_STRING . ' NOT NULL DEFAULT \'\'', + 'shipping_center' => Schema::TYPE_BOOLEAN . ' NOT NULL DEFAULT 1', + 'issuing_center' => Schema::TYPE_BOOLEAN . ' NOT NULL DEFAULT 1', + 'xml_id' => Schema::TYPE_STRING . ' NOT NULL DEFAULT \'\'', + ], + $tableOptions + ); + + $this->createTable( + '{{%warehouse_phone}}', + [ + 'id' => Schema::TYPE_PK, + 'warehouse_id' => Schema::TYPE_INTEGER . ' NOT NULL', + 'sort_order' => Schema::TYPE_INTEGER . ' NOT NULL DEFAULT 0', + 'phone' => Schema::TYPE_STRING . ' NOT NULL', + 'name' => Schema::TYPE_STRING, + ], + $tableOptions + ); + + $this->createTable( + '{{%warehouse_email}}', + [ + 'id' => Schema::TYPE_PK, + 'warehouse_id' => Schema::TYPE_INTEGER . ' NOT NULL', + 'sort_order' => Schema::TYPE_INTEGER . ' NOT NULL DEFAULT 0', + 'email' => Schema::TYPE_STRING . ' NOT NULL', + 'name' => Schema::TYPE_STRING, + ], + $tableOptions + ); + + $this->createTable( + '{{%warehouse_openinghours}}', + [ + 'id' => Schema::TYPE_PK, + 'warehouse_id' => Schema::TYPE_INTEGER . ' NOT NULL', + 'sort_order' => Schema::TYPE_INTEGER . ' NOT NULL DEFAULT 0', + 'monday' => Schema::TYPE_BOOLEAN . ' NOT NULL DEFAULT 0', + 'tuesday' => Schema::TYPE_BOOLEAN . ' NOT NULL DEFAULT 0', + 'wednesday' => Schema::TYPE_BOOLEAN . ' NOT NULL DEFAULT 0', + 'thursday' => Schema::TYPE_BOOLEAN . ' NOT NULL DEFAULT 0', + 'friday' => Schema::TYPE_BOOLEAN . ' NOT NULL DEFAULT 0', + 'saturday' => Schema::TYPE_BOOLEAN . ' NOT NULL DEFAULT 0', + 'sunday' => Schema::TYPE_BOOLEAN . ' NOT NULL DEFAULT 0', + 'all_day' => Schema::TYPE_BOOLEAN . ' NOT NULL DEFAULT 0', // 24h + 'opens' => Schema::TYPE_STRING, + 'closes' => Schema::TYPE_STRING, + 'break_from' => Schema::TYPE_STRING, + 'break_to' => Schema::TYPE_STRING, + + ], + $tableOptions + ); + + $this->createTable( + '{{%country}}', + [ + 'id' => Schema::TYPE_PK, + 'name' => Schema::TYPE_STRING, + 'iso_code' => Schema::TYPE_STRING, // ISO 3166-1 alpha-3 + 'sort_order' => Schema::TYPE_INTEGER . ' NOT NULL DEFAULT 0', + 'slug' => Schema::TYPE_STRING, + ], + $tableOptions + ); + + $this->insert( + '{{%country}}', + [ + 'name' => 'Россия', + 'iso_code' => 'RUS', + 'sort_order' => 0, + 'slug' => 'rossiya', + ] + ); + + $this->insert( + '{{%country}}', + [ + 'name' => 'USA', + 'iso_code' => 'USA', + 'sort_order' => 1, + 'slug' => 'usa', + ] + ); + + $this->createTable( + '{{%city}}', + [ + 'id' => Schema::TYPE_PK, + 'name' => Schema::TYPE_STRING, + 'sort_order' => Schema::TYPE_INTEGER . ' NOT NULL DEFAULT 0', + 'slug' => Schema::TYPE_STRING, + 'country_id' => Schema::TYPE_INTEGER . ' NOT NULL', + ], + $tableOptions + ); + + $this->insert( + '{{%city}}', + [ + 'name' => 'Москва', + 'slug' => 'moscow', + 'country_id' => 1, + ] + ); + $this->insert( + '{{%city}}', + [ + 'name' => 'Санкт-Петербург', + 'slug' => 'spb', + 'country_id' => 1, + ] + ); + $this->insert( + '{{%city}}', + [ + 'name' => 'New York', + 'slug' => 'ny', + 'country_id' => 2, + ] + ); + + $this->createIndex('city_country', '{{%city}}', 'country_id'); + $this->createIndex('wh_country', '{{%warehouse}}', 'country_id'); + $this->createIndex('wh_city', '{{%warehouse}}', 'city_id'); + $this->createIndex('wh_phone', '{{%warehouse_phone}}', 'warehouse_id'); + $this->createIndex('wh_email', '{{%warehouse_email}}', 'warehouse_id'); + $this->createIndex('wh_hours', '{{%warehouse_openinghours}}', 'warehouse_id'); + + $this->insert( + '{{%warehouse}}', + [ + 'name' => 'Main warehouse', + 'country_id' => 1, + 'city_id' => 1, + 'address' => 'Kremlin', + ] + ); + + $this->insert( + '{{%warehouse_phone}}', + [ + 'name' => 'Sales', + 'warehouse_id' => 1, + 'phone' => '+7 (495) 123-45-67', + ] + ); + + $this->insert( + '{{%warehouse_email}}', + [ + 'name' => 'Sales', + 'warehouse_id' => 1, + 'email' => 'moscow@example.com', + ] + ); + + $this->insert( + '{{%warehouse_openinghours}}', + [ + 'warehouse_id' => 1, + 'monday' => 1, + 'tuesday' => 1, + 'wednesday' => 1, + 'thursday' => 1, + 'friday' => 1, + 'saturday' => 1, + 'sunday' => 1, + 'all_day' => 1, + 'opens' => '', + 'closes' => '', + 'break_from' => '12:00', + 'break_to' => '13:00', + ] + ); + + $this->insert( + '{{%warehouse}}', + [ + 'name' => 'Second warehouse', + 'country_id' => 2, + 'city_id' => 3, + 'address' => 'The WallStreet hidden warehouse', + ] + ); + + $this->insert( + '{{%warehouse_phone}}', + [ + 'name' => 'Sales', + 'warehouse_id' => 2, + 'phone' => '+1 800 1-WAREHOUSE-1', + ] + ); + + $this->insert( + '{{%warehouse_email}}', + [ + 'name' => 'Sales', + 'warehouse_id' => 2, + 'email' => 'nyc@example.com', + ] + ); + + $this->insert( + '{{%warehouse_openinghours}}', + [ + 'warehouse_id' => 2, + 'monday' => 1, + 'tuesday' => 1, + 'wednesday' => 1, + 'thursday' => 1, + 'friday' => 0, + 'saturday' => 0, + 'sunday' => 1, + 'all_day' => 0, + 'opens' => '9:00', + 'closes' => '22:00', + 'break_from' => '', + 'break_to' => '', + ] + ); + + // product bindings + + $this->createTable( + '{{%warehouse_product}}', + [ + 'id' => Schema::TYPE_PK, + 'warehouse_id' => Schema::TYPE_INTEGER . ' NOT NULL', + 'product_id' => Schema::TYPE_INTEGER . ' NOT NULL', + 'in_warehouse' => Schema::TYPE_FLOAT . ' NOT NULL DEFAULT 0', + 'reserved_count' => Schema::TYPE_FLOAT . ' NOT NULL DEFAULT 0', + 'sku' => Schema::TYPE_STRING . ' NOT NULL DEFAULT \'\'', + ], + $tableOptions + ); + + + // migrate old data to new data + $this->execute( + 'INSERT INTO {{%warehouse_product}} (warehouse_id, product_id, in_warehouse, reserved_count) + SELECT 1, p.id, p.in_warehouse, p.reserved_count FROM {{%product}} p' + ); + + $this->createIndex('wh_pr', '{{%warehouse_product}}', ['warehouse_id', 'product_id'], true); + + $this->dropColumn( + '{{%product}}', + 'in_warehouse' + ); + + $this->dropColumn( + '{{%product}}', + 'reserved_count' + ); + } + + public function down() + { + $this->dropTable('{{%warehouse}}'); + $this->dropTable('{{%warehouse_openinghours}}'); + $this->dropTable('{{%warehouse_email}}'); + $this->dropTable('{{%warehouse_phone}}'); + $this->dropTable('{{%country}}'); + $this->dropTable('{{%city}}'); + + $this->addColumn('{{%product}}', 'in_warehouse', Schema::TYPE_FLOAT . ' NOT NULL DEFAULT 0'); + $this->addColumn('{{%product}}', 'reserved_count', Schema::TYPE_FLOAT . ' NOT NULL DEFAULT 0'); + + $this->execute( + 'UPDATE {{%product}} p SET p.in_warehouse = (SELECT wp.in_warehouse FROM {{%warehouse_product}} wp WHERE wp.product_id = p.id)' + ); + $this->execute( + 'UPDATE {{%product}} p SET p.in_warehouse = (SELECT wp.reserved_count FROM {{%warehouse_product}} wp WHERE wp.product_id = p.id)' + ); + $this->dropTable('{{%warehouse_product}}'); + + + } +} diff --git a/application/models/City.php b/application/models/City.php new file mode 100644 index 000000000..34df28d40 --- /dev/null +++ b/application/models/City.php @@ -0,0 +1,51 @@ + 255] + ]; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'id' => Yii::t('app', 'ID'), + 'name' => Yii::t('app', 'Name'), + 'sort_order' => Yii::t('app', 'Sort Order'), + 'slug' => Yii::t('app', 'Slug'), + 'country_id' => Yii::t('app', 'Country ID'), + ]; + } +} diff --git a/application/models/Country.php b/application/models/Country.php new file mode 100644 index 000000000..7a2bde069 --- /dev/null +++ b/application/models/Country.php @@ -0,0 +1,50 @@ + 255] + ]; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'id' => Yii::t('app', 'ID'), + 'name' => Yii::t('app', 'Name'), + 'iso_code' => Yii::t('app', 'Iso Code'), + 'sort_order' => Yii::t('app', 'Sort Order'), + 'slug' => Yii::t('app', 'Slug'), + ]; + } +} diff --git a/application/models/Product.php b/application/models/Product.php index e9eece1ad..4412708fb 100644 --- a/application/models/Product.php +++ b/application/models/Product.php @@ -41,6 +41,8 @@ * @property integer $parent_id * @property integer $currency_id * @property Product[] $relatedProducts + * @property string $sku + * @property boolean unlimited_count */ class Product extends ActiveRecord implements ImportableInterface, ExportableInterface { @@ -50,6 +52,11 @@ class Product extends ActiveRecord implements ImportableInterface, ExportableInt public $relatedProductsArray = []; + /** + * @var null|WarehouseProduct[] Stores warehouses state of product. Use Product::getWarehousesState() to retrieve + */ + private $activeWarehousesState = null; + /** * @inheritdoc */ @@ -70,12 +77,8 @@ public function rules() 'main_category_id', 'slug_absolute', 'sort_order', - 'active', 'parent_id', 'is_deleted', - 'in_warehouse', - 'unlimited_count', - 'reserved_count', 'currency_id', ], 'integer' @@ -94,11 +97,20 @@ public function rules() ], 'string' ], + [ + [ + 'unlimited_count', + 'active', + 'slug_absolute', + ], + 'boolean', + ], [['price', 'old_price'], 'number'], [['slug'], 'string', 'max' => 80], [['slug_compiled'], 'string', 'max' => 180], - [['old_price', 'price', 'in_warehouse', 'reserved_count'], 'default', 'value' => 0,], - [['active', 'unlimited_count'], 'default', 'value' => 1], + [['old_price', 'price',], 'default', 'value' => 0,], + [['active','unlimited_count'], 'default', 'value' => true], + [['slug_absolute'], 'default', 'value' => false], [['parent_id', 'slug_absolute', 'sort_order', 'is_deleted'], 'default', 'value' => 0], [['relatedProductsArray'], 'safe'], @@ -294,6 +306,34 @@ public function getRelatedProducts() ->viaTable(RelatedProduct::tableName(), ['product_id' => 'id']); } + /** + * Returns remains of this product in all active warehouses. + * Note that if warehouse was added after product edit - it will not be shown here. + * @return WarehouseProduct[] + */ + public function getWarehousesState() + { + if ($this->activeWarehousesState === null) { + $this->activeWarehousesState = WarehouseProduct::getDb()->cache( + function($db) { + return WarehouseProduct::find() + ->where(['in', 'warehouse_id', Warehouse::activeWarehousesIds()]) + ->andWhere('product_id=:product_id', [':product_id'=>$this->id]) + ->with('warehouse') + ->all(); + }, + 86400, + new TagDependency([ + 'tags' => [ + ActiveRecordHelper::getObjectTag($this->className(), $this->id), + ] + ]) + ); + } + + return $this->activeWarehousesState; + } + public function beforeSave($insert) { if (1 === $this->is_deleted) { diff --git a/application/models/Warehouse.php b/application/models/Warehouse.php new file mode 100644 index 000000000..f7f86e223 --- /dev/null +++ b/application/models/Warehouse.php @@ -0,0 +1,112 @@ + 255] + ]; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'id' => Yii::t('app', 'ID'), + 'name' => Yii::t('app', 'Name'), + 'is_active' => Yii::t('app', 'Is Active'), + 'country_id' => Yii::t('app', 'Country ID'), + 'city_id' => Yii::t('app', 'City ID'), + 'address' => Yii::t('app', 'Address'), + 'description' => Yii::t('app', 'Description'), + 'sort_order' => Yii::t('app', 'Sort Order'), + 'map_latitude' => Yii::t('app', 'Map Latitude'), + 'map_longitude' => Yii::t('app', 'Map Longitude'), + 'shipping_center' => Yii::t('app', 'Shipping Center'), + 'issuing_center' => Yii::t('app', 'Issuing Center'), + 'xml_id' => Yii::t('app', 'Xml ID'), + ]; + } + + /** + * @inheritdoc + */ + public function behaviors() + { + return [ + [ + 'class' => \devgroup\TagDependencyHelper\ActiveRecordHelper::className(), + ], + ]; + } + + + /** + * Returns array of ID of all active warehouses + * @return integer[] + * @throws \Exception + */ + public static function activeWarehousesIds() + { + if (static::$activeWarehousesIds === null) { + static::$activeWarehousesIds = Warehouse::getDb()->cache( + function($db) { + return Warehouse::find() + ->where('is_active=1') + ->select('id') + ->orderBy('sort_order ASC') + ->asArray() + ->column($db); + }, + 86400, + new TagDependency([ + 'tags' => [ + ActiveRecordHelper::getCommonTag(Warehouse::className()) + ] + ]) + ); + } + return static::$activeWarehousesIds; + } +} diff --git a/application/models/WarehouseEmail.php b/application/models/WarehouseEmail.php new file mode 100644 index 000000000..7840e598a --- /dev/null +++ b/application/models/WarehouseEmail.php @@ -0,0 +1,51 @@ + 255] + ]; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'id' => Yii::t('app', 'ID'), + 'warehouse_id' => Yii::t('app', 'Warehouse ID'), + 'sort_order' => Yii::t('app', 'Sort Order'), + 'email' => Yii::t('app', 'Email'), + 'name' => Yii::t('app', 'Name'), + ]; + } +} diff --git a/application/models/WarehouseOpeninghours.php b/application/models/WarehouseOpeninghours.php new file mode 100644 index 000000000..5ffccd587 --- /dev/null +++ b/application/models/WarehouseOpeninghours.php @@ -0,0 +1,71 @@ + 255] + ]; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'id' => Yii::t('app', 'ID'), + 'warehouse_id' => Yii::t('app', 'Warehouse ID'), + 'sort_order' => Yii::t('app', 'Sort Order'), + 'monday' => Yii::t('app', 'Monday'), + 'tuesday' => Yii::t('app', 'Tuesday'), + 'wednesday' => Yii::t('app', 'Wednesday'), + 'thursday' => Yii::t('app', 'Thursday'), + 'friday' => Yii::t('app', 'Friday'), + 'saturday' => Yii::t('app', 'Saturday'), + 'sunday' => Yii::t('app', 'Sunday'), + 'all_day' => Yii::t('app', 'All Day'), + 'opens' => Yii::t('app', 'Opens'), + 'closes' => Yii::t('app', 'Closes'), + 'break_from' => Yii::t('app', 'Break From'), + 'break_to' => Yii::t('app', 'Break To'), + ]; + } +} diff --git a/application/models/WarehousePhone.php b/application/models/WarehousePhone.php new file mode 100644 index 000000000..5246014b6 --- /dev/null +++ b/application/models/WarehousePhone.php @@ -0,0 +1,51 @@ + 255] + ]; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'id' => Yii::t('app', 'ID'), + 'warehouse_id' => Yii::t('app', 'Warehouse ID'), + 'sort_order' => Yii::t('app', 'Sort Order'), + 'phone' => Yii::t('app', 'Phone'), + 'name' => Yii::t('app', 'Name'), + ]; + } +} diff --git a/application/models/WarehouseProduct.php b/application/models/WarehouseProduct.php new file mode 100644 index 000000000..785a6115d --- /dev/null +++ b/application/models/WarehouseProduct.php @@ -0,0 +1,78 @@ + 255], + [['in_warehouse', 'reserved_count'], 'default', 'value' => 0], + [['warehouse_id', 'product_id'], 'unique', 'targetAttribute' => ['warehouse_id', 'product_id'], 'message' => 'The combination of Warehouse ID and Product ID has already been taken.'] + ]; + } + + /** + * @inheritdoc + */ + public function attributeLabels() + { + return [ + 'id' => Yii::t('app', 'ID'), + 'warehouse_id' => Yii::t('app', 'Warehouse ID'), + 'product_id' => Yii::t('app', 'Product ID'), + 'in_warehouse' => Yii::t('app', 'In Warehouse'), + 'reserved_count' => Yii::t('app', 'Reserved Count'), + 'sku' => Yii::t('app', 'Sku'), + ]; + } + + /** + * Relation to Warehouse + * @return \yii\db\ActiveQuery + */ + public function getWarehouse() + { + return $this->hasOne(Warehouse::className(), ['id' => 'warehouse_id']); + } + + /** + * @inheritdoc + */ + public function behaviors() + { + return [ + [ + 'class' => \devgroup\TagDependencyHelper\ActiveRecordHelper::className(), + ], + ]; + } +}