Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Warehouse identifier for orders and users #100

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM cgsmith105/yii2-php:8.0-apache
FROM yiisoftware/yii2-php:8.1-apache

# Change document root for Apache
RUN sed -i -e 's|/app/web|/app/api/web|g' /etc/apache2/sites-available/000-default.conf
46 changes: 46 additions & 0 deletions common/models/UserWarehouse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace common\models;

use Yii;

/**
* This is the model class for table "user_warehouse".
*
* @property int $id
* @property int $warehouse_id
* @property int $user_id
*/
class UserWarehouse extends \yii\db\ActiveRecord
{
/**
* {@inheritdoc}
*/
public static function tableName()
{
return 'user_warehouse';
}

/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['warehouse_id', 'user_id'], 'required'],
[['warehouse_id', 'user_id'], 'integer'],
];
}

/**
* {@inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'warehouse_id' => 'Warehouse ID',
'user_id' => 'User ID',
];
}
}
101 changes: 101 additions & 0 deletions common/models/Warehouse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php

namespace common\models;

use common\models\query\WarehouseQuery;
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\helpers\ArrayHelper;

/**
* This is the model class for table "warehouse".
*
* @property int $id
* @property string $name
* @property int $created_at
* @property int $updated_at
*/
class Warehouse extends \yii\db\ActiveRecord
{
/**
* {@inheritdoc}
*/
public static function tableName()
{
return 'warehouse';
}

/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['name'], 'required'],
[['name'], 'string', 'max' => 255],
];
}

/**
* {@inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'name' => 'Name',
'created_at' => 'Created At',
'updated_at' => 'Updated At',
];
}

public function behaviors()
{
return [
TimestampBehavior::class,
];
}

/**
* Whether the customer is linked to given user
*
* @param int $userId
*
* @return bool
*/
public function isLinkedToUser($userId)
{
return $this->getUserWarehouse()->onCondition(['user_id' => (int)$userId])->exists();
}

public static function find()
{
return new WarehouseQuery(get_called_class());
}

/**
* Returns list of customers as array [id=>name]
*
* @param string $keyField Field name to use as key
* @param string $valueField Field name to use as value
*
* @todo getList is used in multiple spots and might be worthwhile to make an interface
* @return array
*/
public static function getList($keyField = 'id', $valueField = 'name')
{
$data = self::find()->orderBy([$valueField => SORT_ASC])->all();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How many warehouses are going to be in the database?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially it'll only be about 10 or so.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When it will grow big, this solution won't work.


return ArrayHelper::map($data, $keyField, $valueField);
}

/**
* Get UserCustomer
*
* @return \yii\db\ActiveQuery
*/
public function getUserWarehouse()
{
return $this->hasMany(UserWarehouse::class, ['warehouse_id' => 'id']);
}
}
11 changes: 10 additions & 1 deletion common/models/base/BaseOrder.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

namespace common\models\base;

use common\models\Warehouse;

/**
* This is the model class for table "orders".
*
* @property int $id
* @property int $customer_id
* @property int $warehouse_id
* @property string $order_reference
* @property string $customer_reference
* @property int $status_id
Expand Down Expand Up @@ -54,7 +57,7 @@ public function rules()
{
return [
[['customer_id', 'customer_reference', 'address_id'], 'required'],
[['customer_id', 'status_id', 'address_id', 'carrier_id', 'service_id', 'transit'], 'integer'],
[['customer_id', 'warehouse_id', 'status_id', 'address_id', 'carrier_id', 'service_id', 'transit'], 'integer'],
[['created_date', 'updated_date', 'requested_ship_date', 'must_arrive_by_date', 'carrier_id', 'service_id', 'transit'], 'safe'],
[['order_reference', 'tracking'], 'string', 'max' => 45],
[['customer_reference', 'origin', 'uuid'], 'string', 'max' => 64],
Expand Down Expand Up @@ -88,6 +91,7 @@ public function attributeLabels()
return [
'id' => 'ID',
'customer_id' => 'Customer ID',
'warehouse_id' => 'Warehouse ID',
'order_reference' => 'WMS Order #',
'customer_reference' => 'Customer Order #',
'status_id' => 'Status ID',
Expand All @@ -103,4 +107,9 @@ public function attributeLabels()
'label_type' => 'Label Type',
];
}

public function getWarehouse()
{
return $this->hasOne(Warehouse::class, ['id' => 'warehouse_id']);
}
}
54 changes: 22 additions & 32 deletions common/models/query/OrderQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,36 @@

use common\models\base\BaseBatch;
use common\models\Order;
use common\traits\LimitBy;
use yii\helpers\ArrayHelper;

/**
* This is the ActiveQuery class for [[Order]].
*
* @see Order
*/
class OrderQuery extends \yii\db\ActiveQuery
class OrderQuery extends BaseQuery
{
use LimitBy;

public function __construct($modelClass, $config = [])
{
parent::__construct($modelClass, $config);

if (\Yii::$app instanceof \yii\web\Application &&
\Yii::$app->id !== 'app-api' &&
!\Yii::$app->user->identity->isAdmin) {
// If a "warehouse" user limit orders only by the warehouse that is linked
if (\Yii::$app->user->identity->isWarehouseType()) {
$this->limitByWarehouse();
}

// If a "customer" user then limit the orders by the customers that they have access to
if (\Yii::$app->user->identity->isCustomerType()) {
$this->limitByCustomer();
}
}
}

/**
* @inheritdoc
Expand All @@ -32,37 +53,6 @@ public function one($db = null)
return parent::one($db);
}

/**
* Query condition to get orders for given customer id
*
* We assume that if $id passed is null then no condition to apply
*
* @param int $id Customer Id
*
* @return OrderQuery
*/
public function forCustomer($id)
{
return is_numeric($id)
? $this->andOnCondition([Order::tableName() . '.customer_id' => (int)$id])
: $this;
}

/**
* Query condition to get orders for multiple given customers
*
* @param array $ids Customer Ids
*
* @return OrderQuery
*/
public function forCustomers($ids = [])
{
if (!empty($ids)) {
return $this->andOnCondition([Order::tableName() . '.customer_id' => $ids]);
}
return $this;
}

/**
* Query condition to get order by customer reference ID - identifier in the customer database
*
Expand Down
34 changes: 34 additions & 0 deletions common/models/query/WarehouseQuery.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php


namespace common\models\query;


use common\models\Invoice;

class WarehouseQuery extends \yii\db\ActiveQuery
{

/**
* Ensures customer_id is maintained for users that require restriction on the model
*
* @todo this should move to the basequery then all models should reference
*
* @param $modelClass
* @param $config
*/
public function __construct($modelClass, $config = [])
{
parent::__construct($modelClass, $config);

// Admins can see all models - so admins skip this andWhere()
// skip if running from CLI - typically a Job
// also skip if running from API
// @todo load user while making requests to run through ACL
if (\Yii::$app instanceof \yii\web\Application &&
\Yii::$app->id !== 'app-api' &&
!\Yii::$app->user->identity->isAdmin) {
$this->andWhere(['in', 'id', \Yii::$app->user->identity->warehouseIds]);
}
}
}
16 changes: 16 additions & 0 deletions common/traits/LimitBy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace common\traits;

trait LimitBy
{
public function limitByWarehouse($ids = [])
{
$this->andWhere(['in', 'warehouse_id', \Yii::$app->user->identity->warehouseIds]);
}

public function limitByCustomer($ids = [])
{
$this->andWhere(['in', 'customer_id', \Yii::$app->user->identity->customerIds]);
}
}
Loading