diff --git a/addon/components/purchase-order-form-panel.js b/addon/components/purchase-order-form-panel.js
index 7d21da2e..3e56a19e 100644
--- a/addon/components/purchase-order-form-panel.js
+++ b/addon/components/purchase-order-form-panel.js
@@ -143,7 +143,7 @@ export default class PurchaseOrderFormPanelComponent extends Component {
@action onPressCancel() {
return contextComponentCallback(this, 'onPressCancel', this.purchaseOrder);
}
-
+
@action setExpectedDeliveryDate(event) {
const {
target: { value },
diff --git a/addon/components/supplier-form-panel.hbs b/addon/components/supplier-form-panel.hbs
index ab99f884..6180fb0f 100644
--- a/addon/components/supplier-form-panel.hbs
+++ b/addon/components/supplier-form-panel.hbs
@@ -54,7 +54,8 @@
@triggerClass="form-select form-input"
@infiniteScroll={{false}}
@renderInPlace={{true}}
- @onChange={{this.supplier.place.address}}
+ @onChange={{fn (mut this.supplier.place)}}
+ @onChangeId={{fn (mut this.supplier.place_uuid)}}
as |model|
>
diff --git a/addon/controllers/admin/product-category.js b/addon/controllers/admin/product-category.js
new file mode 100644
index 00000000..948d3a6e
--- /dev/null
+++ b/addon/controllers/admin/product-category.js
@@ -0,0 +1,3 @@
+import Controller from '@ember/controller';
+
+export default class AdminProductCategoryController extends Controller {}
diff --git a/addon/controllers/inventory/expired-stock.js b/addon/controllers/inventory/expired-stock.js
index 89bd0450..a4136955 100644
--- a/addon/controllers/inventory/expired-stock.js
+++ b/addon/controllers/inventory/expired-stock.js
@@ -69,7 +69,7 @@ export default class InventoryExpiredStockController extends Controller {
*/
@tracked page = 1;
- @tracked view = 'expired_stock'
+ @tracked view = 'expired_stock';
/**
* The maximum number of items to show per page
@@ -136,6 +136,7 @@ export default class InventoryExpiredStockController extends Controller {
{
label: 'Product',
valuePath: 'product.name',
+ action: this.viewInventory,
width: '170px',
cellComponent: 'cell/product-info',
modelPath: 'product',
@@ -159,16 +160,6 @@ export default class InventoryExpiredStockController extends Controller {
valuePath: 'quantity',
width: '120px',
},
- {
- label: 'Warehouse',
- valuePath: 'warehouse.address',
- width: '120px',
- cellComponent: 'click-to-copy',
- resizable: true,
- sortable: true,
- filterable: true,
- filterComponent: 'filter/string',
- },
{
label: 'Batch',
valuePath: 'batch.name',
@@ -199,16 +190,6 @@ export default class InventoryExpiredStockController extends Controller {
filterable: true,
filterComponent: 'filter/date',
},
- {
- label: 'Expiry Date',
- valuePath: 'expiredAt',
- sortParam: 'expiry_date_at',
- width: '10%',
- resizable: true,
- sortable: true,
- filterable: true,
- filterComponent: 'filter/date',
- },
{
label: 'Updated At',
valuePath: 'updatedAt',
diff --git a/addon/controllers/inventory/index.js b/addon/controllers/inventory/index.js
index c9f60c47..6f93ba48 100644
--- a/addon/controllers/inventory/index.js
+++ b/addon/controllers/inventory/index.js
@@ -134,6 +134,7 @@ export default class InventoryIndexController extends Controller {
{
label: 'Product',
valuePath: 'product.name',
+ action: this.viewInventory,
width: '170px',
cellComponent: 'cell/product-info',
modelPath: 'product',
@@ -157,16 +158,6 @@ export default class InventoryIndexController extends Controller {
valuePath: 'quantity',
width: '120px',
},
- {
- label: 'Warehouse',
- valuePath: 'warehouse.address',
- width: '120px',
- cellComponent: 'click-to-copy',
- resizable: true,
- sortable: true,
- filterable: true,
- filterComponent: 'filter/string',
- },
{
label: 'Batch',
valuePath: 'batch.batch_number',
@@ -199,7 +190,7 @@ export default class InventoryIndexController extends Controller {
},
{
label: 'Expiry Date',
- valuePath: 'expiredAt',
+ valuePath: 'expiryDate',
sortParam: 'expiry_date_at',
width: '10%',
resizable: true,
@@ -286,7 +277,7 @@ export default class InventoryIndexController extends Controller {
* @void
*/
@action viewInventory(inventory) {
- return this.transitionToRoute('inventory.index.details', inventory);
+ return this.transitionToRoute('inventory.index.details', inventory.public_id);
}
/**
@@ -313,41 +304,4 @@ export default class InventoryIndexController extends Controller {
@action async editInventory(inventory) {
return this.transitionToRoute('inventory.index.edit', inventory);
}
-
- /**
- * Delete a `inventory` via confirm prompt
- *
- * @param {InventoryModel} inventory
- * @param {Object} options
- * @void
- */
- @action deleteInventory(inventory, options = {}) {
- this.crud.delete(inventory, {
- onConfirm: () => {
- return this.hostRouter.refresh();
- },
- ...options,
- });
- }
-
- /**
- * Bulk deletes selected `inventory` via confirm prompt
- *
- * @param {Array} selected an array of selected models
- * @void
- */
- @action bulkDeleteInventorys() {
- const selected = this.table.selectedRows;
-
- this.crud.bulkDelete(selected, {
- modelNamePath: `public_id`,
- acceptButtonText: 'Delete Inventories',
- fetchOptions: {
- namespace: 'pallet/int/v1',
- },
- onSuccess: () => {
- return this.hostRouter.refresh();
- },
- });
- }
}
diff --git a/addon/controllers/inventory/low-stock.js b/addon/controllers/inventory/low-stock.js
index 9c126114..8409f7af 100644
--- a/addon/controllers/inventory/low-stock.js
+++ b/addon/controllers/inventory/low-stock.js
@@ -159,16 +159,6 @@ export default class InventoryLowStockController extends Controller {
valuePath: 'quantity',
width: '120px',
},
- {
- label: 'Warehouse',
- valuePath: 'warehouse.address',
- width: '120px',
- cellComponent: 'click-to-copy',
- resizable: true,
- sortable: true,
- filterable: true,
- filterComponent: 'filter/string',
- },
{
label: 'Batch',
valuePath: 'batch.name',
@@ -199,16 +189,6 @@ export default class InventoryLowStockController extends Controller {
filterable: true,
filterComponent: 'filter/date',
},
- {
- label: 'Expiry Date',
- valuePath: 'expiredAt',
- sortParam: 'expiry_date_at',
- width: '10%',
- resizable: true,
- sortable: true,
- filterable: true,
- filterComponent: 'filter/date',
- },
{
label: 'Updated At',
valuePath: 'updatedAt',
diff --git a/addon/controllers/sales-orders/index.js b/addon/controllers/sales-orders/index.js
index 904d080b..9394614c 100644
--- a/addon/controllers/sales-orders/index.js
+++ b/addon/controllers/sales-orders/index.js
@@ -77,7 +77,6 @@ export default class SalesOrdersIndexController extends Controller {
*/
@tracked page = 1;
-
/**
* The maximum number of items to show per page
*
@@ -291,7 +290,7 @@ export default class SalesOrdersIndexController extends Controller {
this.crud.bulkDelete(selected, {
modelNamePath: 'public_id',
- acceptButtonText: "Delete Sales Orders",
+ acceptButtonText: 'Delete Sales Orders',
fetchOptions: {
namespace: 'pallet/int/v1',
},
diff --git a/addon/engine.js b/addon/engine.js
index cd7809bb..944b547e 100644
--- a/addon/engine.js
+++ b/addon/engine.js
@@ -3,6 +3,7 @@ import loadInitializers from 'ember-load-initializers';
import Resolver from 'ember-resolver';
import config from './config/environment';
import services from '@fleetbase/ember-core/exports/services';
+import AdminVisibilityControlsComponent from './components/admin/visibility-controls';
const { modulePrefix } = config;
const externalRoutes = ['console', 'extensions'];
@@ -16,7 +17,37 @@ export default class PalletEngine extends Engine {
};
setupExtension = function (app, engine, universe) {
// register menu item in header
- universe.registerHeaderMenuItem('Pallet', 'console.pallet', { icon: 'pallet', priority: 1 });
+ universe.registerHeaderMenuItem('Pallet', 'console.pallet', { icon: 'pallet', priority: 0 });
+
+ // register admin settings -- create a pallet menu panel with it's own setting options
+ universe.registerAdminMenuPanel(
+ 'Pallet Config',
+ [
+ {
+ title: 'Visibility Controls',
+ icon: 'eye',
+ component: AdminVisibilityControlsComponent,
+ },
+ ],
+ {
+ slug: 'pallet',
+ }
+ );
+
+ // create primary registry for engine
+ universe.createRegistry('engine:pallet');
+
+ // register the product panel
+ universe.createRegistry('component:product-panel');
+
+ // register the inventory panel
+ universe.createRegistry('component:inventory-panel');
+
+ // register the supplier panel
+ universe.createRegistry('component:supplier-panel');
+
+ // register the warehouse panel
+ universe.createRegistry('component:warehouse-panel');
};
}
diff --git a/addon/models/stock-adjustment.js b/addon/models/stock-adjustment.js
index 4e13f5d0..4e6ec3be 100644
--- a/addon/models/stock-adjustment.js
+++ b/addon/models/stock-adjustment.js
@@ -37,6 +37,20 @@ export default class StockAdjustmentModel extends Model {
return formatDistanceToNow(this.created_at);
}
+ @computed('created_at') get createdAt() {
+ if (!isValidDate(this.created_at)) {
+ return null;
+ }
+ return formatDate(this.created_at, 'PPP p');
+ }
+
+ @computed('created_at') get createdAtShort() {
+ if (!isValidDate(this.created_at)) {
+ return null;
+ }
+ return formatDate(this.created_at, 'PP');
+ }
+
@computed('updated_at') get updatedAgo() {
if (!isValidDate(this.updated_at)) {
return null;
@@ -50,4 +64,11 @@ export default class StockAdjustmentModel extends Model {
}
return formatDate(this.updated_at, 'PPP p');
}
+
+ @computed('updated_at') get updatedAtShort() {
+ if (!isValidDate(this.updated_at)) {
+ return null;
+ }
+ return formatDate(this.updated_at, 'PP');
+ }
}
diff --git a/addon/routes/admin/product-category.js b/addon/routes/admin/product-category.js
new file mode 100644
index 00000000..0ada6d8f
--- /dev/null
+++ b/addon/routes/admin/product-category.js
@@ -0,0 +1,24 @@
+import Route from '@ember/routing/route';
+import { inject as service } from '@ember/service';
+
+export default class AdminProductCategoryRoute extends Route {
+ @service store;
+
+ queryParams = {
+ page: { refreshModel: true },
+ limit: { refreshModel: true },
+ sort: { refreshModel: true },
+ query: { refreshModel: true },
+ created_at: { refreshModel: true },
+ };
+
+ /**
+ * Fetch the model data based on the specified parameters.
+ *
+ * @param {Object} params - Query parameters for fetching notifications.
+ * @returns {Promise} - A promise that resolves with the notification data.
+ */
+ model(params = {}) {
+ return this.store.query('notification', params);
+ }
+}
diff --git a/addon/serializers/stock-adjustment.js b/addon/serializers/stock-adjustment.js
new file mode 100644
index 00000000..cd7e6745
--- /dev/null
+++ b/addon/serializers/stock-adjustment.js
@@ -0,0 +1,15 @@
+import ApplicationSerializer from '@fleetbase/ember-core/serializers/application';
+import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest';
+
+export default class StockAdjustment extends ApplicationSerializer.extend(EmbeddedRecordsMixin) {
+ /**
+ * Embedded relationship attributes
+ *
+ * @var {Object}
+ */
+ get attrs() {
+ return {
+ product: { embedded: 'always' },
+ };
+ }
+}
diff --git a/addon/templates/admin/product-category.hbs b/addon/templates/admin/product-category.hbs
new file mode 100644
index 00000000..4abdd78c
--- /dev/null
+++ b/addon/templates/admin/product-category.hbs
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/components/admin/product-category.js b/app/components/admin/product-category.js
new file mode 100644
index 00000000..6d81baa9
--- /dev/null
+++ b/app/components/admin/product-category.js
@@ -0,0 +1 @@
+export { default } from '@fleetbase/pallet-engine/components/admin/product-category';
diff --git a/app/components/admin/visibility-controls.js b/app/components/admin/visibility-controls.js
new file mode 100644
index 00000000..94d6bebc
--- /dev/null
+++ b/app/components/admin/visibility-controls.js
@@ -0,0 +1 @@
+export { default } from '@fleetbase/pallet-engine/components/admin/visibility-controls';
diff --git a/app/controllers/admin/product-category.js b/app/controllers/admin/product-category.js
new file mode 100644
index 00000000..fa08e325
--- /dev/null
+++ b/app/controllers/admin/product-category.js
@@ -0,0 +1 @@
+export { default } from '@fleetbase/pallet-engine/controllers/admin/product-category';
diff --git a/app/routes/admin/product-category.js b/app/routes/admin/product-category.js
new file mode 100644
index 00000000..1ece2cae
--- /dev/null
+++ b/app/routes/admin/product-category.js
@@ -0,0 +1 @@
+export { default } from '@fleetbase/pallet-engine/routes/admin/product-category';
diff --git a/app/serializers/stock-adjustment.js b/app/serializers/stock-adjustment.js
new file mode 100644
index 00000000..d79dd4f4
--- /dev/null
+++ b/app/serializers/stock-adjustment.js
@@ -0,0 +1 @@
+export { default } from '@fleetbase/pallet-engine/serializers/stock-adjustment';
diff --git a/app/templates/admin/product-category.js b/app/templates/admin/product-category.js
new file mode 100644
index 00000000..3a750f16
--- /dev/null
+++ b/app/templates/admin/product-category.js
@@ -0,0 +1 @@
+export { default } from '@fleetbase/pallet-engine/templates/admin/product-category';
diff --git a/server/src/Http/Controllers/InventoryController.php b/server/src/Http/Controllers/InventoryController.php
index d0ba6038..b2bc61ad 100644
--- a/server/src/Http/Controllers/InventoryController.php
+++ b/server/src/Http/Controllers/InventoryController.php
@@ -66,6 +66,8 @@ public function createRecord(Request $request)
'product_uuid' => data_get($data, 'product_uuid'),
'batch_number' => data_get($data, 'batch_number', now()->format('Y-m-d')),
'quantity' => data_get($data, 'quantity', 0),
+ 'expiry_date_at' => data_get($data, 'expiry_date_at'),
+ 'manufacture_date_at' => data_get($data, 'manufacture_date_at'),
]);
$batch->save();
@@ -80,7 +82,6 @@ public function createRecord(Request $request)
'min_quantity' => data_get($data, 'min_quantity', 0),
'comments' => data_get($data, 'comments'),
'expiry_date_at' => data_get($data, 'expiry_date_at'),
- 'manufactured_date_at' => data_get($data, 'manufactured_date_at')
]);
$inventory->batch()->associate($batch);
diff --git a/server/src/Http/Resources/Batch.php b/server/src/Http/Resources/Batch.php
index 1df28dd4..e822dc89 100644
--- a/server/src/Http/Resources/Batch.php
+++ b/server/src/Http/Resources/Batch.php
@@ -17,13 +17,15 @@ class Batch extends FleetbaseResource
public function toArray($request)
{
return [
- 'id' => $this->when(Http::isInternalRequest(), $this->incrementing_id, $this->public_id),
- 'uuid' => $this->when(Http::isInternalRequest(), $this->uuid),
- 'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
- 'batch_number' => $this->batch_number,
- 'batch_quantity' => $this->batch_quantity,
- 'updated_at' => $this->updated_at,
- 'created_at' => $this->created_at,
+ 'id' => $this->when(Http::isInternalRequest(), $this->incrementing_id, $this->public_id),
+ 'uuid' => $this->when(Http::isInternalRequest(), $this->uuid),
+ 'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
+ 'batch_number' => $this->batch_number,
+ 'batch_quantity' => $this->batch_quantity,
+ 'updated_at' => $this->updated_at,
+ 'created_at' => $this->created_at,
+ 'expiry_date_at' => $this->expiry_date_at,
+ 'manufacture_date_at' => $this->manufacture_date_at,
];
}
}
diff --git a/server/src/Http/Resources/Inventory.php b/server/src/Http/Resources/Inventory.php
index 09d01c54..db766e17 100644
--- a/server/src/Http/Resources/Inventory.php
+++ b/server/src/Http/Resources/Inventory.php
@@ -32,7 +32,6 @@ public function toArray($request)
'min_quantity' => (int) $this->min_quantity,
'comments' => $this->comments,
'expiry_date_at' => $this->expiry_date_at,
- 'manufactured_date_at' => $this->manufactured_date_at,
'updated_at' => $this->updated_at,
'created_at' => $this->created_at,
];
diff --git a/server/src/Http/Resources/StockAdjustment.php b/server/src/Http/Resources/StockAdjustment.php
new file mode 100644
index 00000000..c8edc8ec
--- /dev/null
+++ b/server/src/Http/Resources/StockAdjustment.php
@@ -0,0 +1,32 @@
+ $this->when(Http::isInternalRequest(), $this->id, $this->public_id),
+ 'uuid' => $this->when(Http::isInternalRequest(), $this->uuid),
+ 'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
+ 'product_uuid' => $this->product_uuid,
+ 'product' => $this->whenLoaded('product', $this->product),
+ 'quantity' => (int) $this->quantity,
+ 'before_quantity' => (int) $this->before_quantity,
+ 'after_quantity' => (int) $this->after_quantity,
+ 'updated_at' => $this->updated_at,
+ 'created_at' => $this->created_at,
+ ];
+ }
+}
diff --git a/server/src/Models/Batch.php b/server/src/Models/Batch.php
index fc8bc1af..f432ffb0 100644
--- a/server/src/Models/Batch.php
+++ b/server/src/Models/Batch.php
@@ -59,6 +59,10 @@ class Batch extends Model
'updated_at',
];
+ public $timestamps = true;
+
+ protected $dates = ['expiry_date_at'];
+
/**
* The attributes that should be cast to native types.
*
@@ -120,4 +124,14 @@ public function product()
{
return $this->belongsTo(Product::class);
}
+
+ protected static function boot()
+ {
+ parent::boot();
+
+ static::creating(function ($model) {
+ $model->created_at = now();
+ $model->manufacture_date_at = now();
+ });
+ }
}
diff --git a/server/src/Models/Inventory.php b/server/src/Models/Inventory.php
index 8d7581dd..8f04a239 100644
--- a/server/src/Models/Inventory.php
+++ b/server/src/Models/Inventory.php
@@ -48,6 +48,10 @@ class Inventory extends Model
* @var array
*/
protected $fillable = [
+ 'supplier',
+ 'supplier_uuid',
+ 'company_uuid',
+ 'created_by_uuid',
'manufactured_date_at',
'expiry_date_at',
'created_at',
@@ -88,14 +92,15 @@ class Inventory extends Model
*/
protected $hidden = [];
- protected $with = ['product', 'batch', 'warehouse'];
+ protected $with = ['product', 'batch', 'warehouse', 'supplier'];
+
+ protected $filterParams = ['comments', 'expiry_date_at', 'status', 'company', 'createdBy',];
- protected $filterParams = ['supplier_uuid', 'comments', 'expiry_date_at', 'status', 'company', 'createdBy', 'supplier'];
-
/**
* @return null|int
*/
- public function getIncrementingIdAttribute(): ?int {
+ public function getIncrementingIdAttribute(): ?int
+ {
return static::select('id')->where('uuid', $this->uuid)->value('id');
}
@@ -143,28 +148,30 @@ public function scopeSummarizeByProduct($query)
return $query
->selectRaw('
pallet_inventories.product_uuid,
+ pallet_inventories.batch_uuid,
+ pallet_inventories.supplier_uuid,
+ pallet_inventories.warehouse_uuid,
MAX(pallet_inventories.created_at) as latest_created_at,
MAX(pallet_inventories.updated_at) as latest_updated_at,
MAX(pallet_inventories.public_id) as latest_public_id,
MAX(pallet_inventories.uuid) as latest_uuid,
MAX(pallet_inventories.comments) as latest_comments,
- GROUP_CONCAT(DISTINCT pallet_batches.uuid) as batch_uuids,
- GROUP_CONCAT(DISTINCT pallet_batches.batch_number) as batch_numbers,
+ (SELECT GROUP_CONCAT(DISTINCT pallet_batches.uuid) FROM pallet_batches WHERE pallet_batches.uuid = pallet_inventories.batch_uuid) as batch_uuids,
+ (SELECT GROUP_CONCAT(DISTINCT pallet_batches.batch_number) FROM pallet_batches WHERE pallet_batches.uuid = pallet_inventories.batch_uuid) as batch_numbers,
SUM(pallet_inventories.quantity) as total_quantity,
MAX(pallet_inventories.min_quantity) as minimum_quantity,
MAX(pallet_inventories.expiry_date_at) as latest_expiry_date_at
')
->leftJoin('pallet_batches', 'pallet_inventories.batch_uuid', '=', 'pallet_batches.uuid')
- ->groupBy('pallet_inventories.product_uuid');
+ ->groupBy('pallet_inventories.product_uuid', 'pallet_inventories.batch_uuid', 'pallet_inventories.supplier_uuid', 'pallet_inventories.warehouse_uuid');
}
-
+
protected static function boot()
{
parent::boot();
static::creating(function ($model) {
$model->created_at = now();
- $model->manufactured_date_at = now();
});
}
}
diff --git a/server/src/Models/StockAdjustment.php b/server/src/Models/StockAdjustment.php
index 95e02b91..d2810f1d 100644
--- a/server/src/Models/StockAdjustment.php
+++ b/server/src/Models/StockAdjustment.php
@@ -2,13 +2,16 @@
namespace Fleetbase\Pallet\Models;
+use Fleetbase\Casts\Json;
use Fleetbase\Models\Model;
use Fleetbase\Traits\HasApiModelBehavior;
+use Fleetbase\Traits\HasPublicId;
use Fleetbase\Traits\HasUuid;
class StockAdjustment extends Model
{
use HasUuid;
+ use HasPublicId;
use HasApiModelBehavior;
/**
@@ -25,12 +28,26 @@ class StockAdjustment extends Model
*/
protected $singularName = 'stock_adjustment';
+ /**
+ * Overwrite both entity resource name with `payloadKey`.
+ *
+ * @var string
+ */
+ protected $payloadKey = 'stock_adjustment';
+
+ /**
+ * The type of `public_id` to generate.
+ *
+ * @var string
+ */
+ protected $publicIdType = 'stock_adjustment';
+
/**
* These attributes that can be queried.
*
* @var array
*/
- protected $searchableColumns = ['uuid', 'public_id', 'company_uuid', 'created_by_uuid', 'product_uuid', 'created_at'];
+ protected $searchableColumns = ['reason'];
/**
* The attributes that are mass assignable.
@@ -44,7 +61,6 @@ class StockAdjustment extends Model
'created_by_uuid',
'product_uuid',
'assignee_uuid',
- 'meta',
'type',
'reason',
'approval_required',
@@ -61,7 +77,7 @@ class StockAdjustment extends Model
* @var array
*/
protected $casts = [
- 'meta' => 'json',
+ 'meta' => JSON::class,
];
/**
@@ -105,7 +121,7 @@ public function createdBy()
*/
public function product()
{
- return $this->belongsTo(Entity::class, 'product_uuid', 'uuid');
+ return $this->belongsTo(Product::class, 'product_uuid', 'uuid');
}
public function user()
diff --git a/tests/integration/components/admin/product-category-test.js b/tests/integration/components/admin/product-category-test.js
new file mode 100644
index 00000000..5e37ee18
--- /dev/null
+++ b/tests/integration/components/admin/product-category-test.js
@@ -0,0 +1,26 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'dummy/tests/helpers';
+import { render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module('Integration | Component | admin/product-category', function (hooks) {
+ setupRenderingTest(hooks);
+
+ test('it renders', async function (assert) {
+ // Set any properties with this.set('myProperty', 'value');
+ // Handle any actions with this.set('myAction', function(val) { ... });
+
+ await render(hbs`
`);
+
+ assert.dom(this.element).hasText('');
+
+ // Template block usage:
+ await render(hbs`
+
+ template block text
+
+ `);
+
+ assert.dom(this.element).hasText('template block text');
+ });
+});
diff --git a/tests/integration/components/admin/visibility-controls-test.js b/tests/integration/components/admin/visibility-controls-test.js
new file mode 100644
index 00000000..40f2675b
--- /dev/null
+++ b/tests/integration/components/admin/visibility-controls-test.js
@@ -0,0 +1,26 @@
+import { module, test } from 'qunit';
+import { setupRenderingTest } from 'dummy/tests/helpers';
+import { render } from '@ember/test-helpers';
+import { hbs } from 'ember-cli-htmlbars';
+
+module('Integration | Component | admin/visibility-controls', function (hooks) {
+ setupRenderingTest(hooks);
+
+ test('it renders', async function (assert) {
+ // Set any properties with this.set('myProperty', 'value');
+ // Handle any actions with this.set('myAction', function(val) { ... });
+
+ await render(hbs`
`);
+
+ assert.dom(this.element).hasText('');
+
+ // Template block usage:
+ await render(hbs`
+
+ template block text
+
+ `);
+
+ assert.dom(this.element).hasText('template block text');
+ });
+});
diff --git a/tests/unit/controllers/admin/product-category-test.js b/tests/unit/controllers/admin/product-category-test.js
new file mode 100644
index 00000000..d2898401
--- /dev/null
+++ b/tests/unit/controllers/admin/product-category-test.js
@@ -0,0 +1,12 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'dummy/tests/helpers';
+
+module('Unit | Controller | admin/product-category', function (hooks) {
+ setupTest(hooks);
+
+ // TODO: Replace this with your real tests.
+ test('it exists', function (assert) {
+ let controller = this.owner.lookup('controller:admin/product-category');
+ assert.ok(controller);
+ });
+});
diff --git a/tests/unit/routes/admin/product-category-test.js b/tests/unit/routes/admin/product-category-test.js
new file mode 100644
index 00000000..f9371676
--- /dev/null
+++ b/tests/unit/routes/admin/product-category-test.js
@@ -0,0 +1,11 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'dummy/tests/helpers';
+
+module('Unit | Route | admin/product-category', function (hooks) {
+ setupTest(hooks);
+
+ test('it exists', function (assert) {
+ let route = this.owner.lookup('route:admin/product-category');
+ assert.ok(route);
+ });
+});
diff --git a/tests/unit/serializers/stock-adjustment-test.js b/tests/unit/serializers/stock-adjustment-test.js
new file mode 100644
index 00000000..524f1180
--- /dev/null
+++ b/tests/unit/serializers/stock-adjustment-test.js
@@ -0,0 +1,23 @@
+import { module, test } from 'qunit';
+import { setupTest } from 'dummy/tests/helpers';
+
+module('Unit | Serializer | stock adjustment', function (hooks) {
+ setupTest(hooks);
+
+ // Replace this with your real tests.
+ test('it exists', function (assert) {
+ let store = this.owner.lookup('service:store');
+ let serializer = store.serializerFor('stock-adjustment');
+
+ assert.ok(serializer);
+ });
+
+ test('it serializes records', function (assert) {
+ let store = this.owner.lookup('service:store');
+ let record = store.createRecord('stock-adjustment', {});
+
+ let serializedRecord = record.serialize();
+
+ assert.ok(serializedRecord);
+ });
+});