From 9a9f8267e4fd91db8142cc71f28ac85e54d04778 Mon Sep 17 00:00:00 2001 From: John Kleinschmidt Date: Wed, 15 Apr 2015 17:04:50 -0400 Subject: [PATCH] Starting batch inventory entry Work for HospitalRun/frontend#75 --- app/inventory/edit/controller.js | 10 --- app/inventory/edit/template.hbs | 38 +-------- app/inventory/invoice/controller.js | 107 ++++++++++++++++++++++++++ app/inventory/invoice/route.js | 18 +++++ app/inventory/invoice/template.hbs | 78 +++++++++++++++++++ app/inventory/invoice/view.js | 2 + app/inventory/quick-add/controller.js | 16 ++++ app/inventory/quick-add/template.hbs | 3 + app/inventory/quick-add/view.js | 2 + app/mixins/inventory-type-list.js | 12 ++- app/models/inventory-invoice.js | 39 ++++++++++ app/router.js | 1 + app/templates/inventory-basic.hbs | 37 +++++++++ 13 files changed, 315 insertions(+), 48 deletions(-) create mode 100755 app/inventory/invoice/controller.js create mode 100755 app/inventory/invoice/route.js create mode 100755 app/inventory/invoice/template.hbs create mode 100755 app/inventory/invoice/view.js create mode 100644 app/inventory/quick-add/controller.js create mode 100644 app/inventory/quick-add/template.hbs create mode 100644 app/inventory/quick-add/view.js create mode 100644 app/models/inventory-invoice.js create mode 100644 app/templates/inventory-basic.hbs diff --git a/app/inventory/edit/controller.js b/app/inventory/edit/controller.js index a106b3de34..f309809b5f 100644 --- a/app/inventory/edit/controller.js +++ b/app/inventory/edit/controller.js @@ -45,16 +45,6 @@ export default AbstractEditController.extend(InventoryLocations, InventoryTypeLi return transactions !== null; }.property('transactions.@each'), - inventoryTypes: function() { - var defaultInventoryTypes = this.get('defaultInventoryTypes'), - inventoryTypeList = this.get('inventoryTypeList'); - if (Ember.isEmpty(inventoryTypeList)) { - return defaultInventoryTypes; - } else { - return inventoryTypeList; - } - }.property('inventoryTypeList', 'defaultInventoryTypes'), - locationQuantityTotal: function() { var locations = this.get('locations'); var total = locations.reduce(function(previousValue, location) { diff --git a/app/inventory/edit/template.hbs b/app/inventory/edit/template.hbs index 79c0808c42..a3b6bd9ae5 100644 --- a/app/inventory/edit/template.hbs +++ b/app/inventory/edit/template.hbs @@ -1,41 +1,5 @@ {{#em-form model=this submit_button=false }} -
- {{#unless isNew}} -
- - {{input class="form-control" value=friendlyId type="text" disabled=true }} -
- {{/unless}} - {{em-input property="name" label="Name" class="required col-sm-8"}} - {{#unless isNew}} -
- -

{{quantity}}

-
- {{/unless}} - -
- {{em-text label="Description" property="description" rows=1 }} -
- {{em-select label="Type" property="type" - content=inventoryTypes - optionValuePath="content" - optionLabelPath="content" - class="required col-sm-4" - }} - {{em-input property="crossReference" label="Cross Reference" class="col-sm-8"}} -
-
- {{em-input property="reorderPoint" label="Reorder Point" class="col-sm-3"}} - {{em-input property="price" label="Price Per Unit" class="col-sm-3"}} - {{em-select label="Distribution Unit" class="col-sm-3" - property="distributionUnit" - content=unitList - optionLabelPath="content" - optionValuePath="content" - - }} -
+ {{partial 'inventory-basic'}} {{#if isNew}}

Purchase information

{{partial 'inv-purchase'}} diff --git a/app/inventory/invoice/controller.js b/app/inventory/invoice/controller.js new file mode 100755 index 0000000000..60b0c0834b --- /dev/null +++ b/app/inventory/invoice/controller.js @@ -0,0 +1,107 @@ +import AbstractEditController from 'hospitalrun/controllers/abstract-edit-controller'; +import InventorySelection from 'hospitalrun/mixins/inventory-selection'; +import Ember from 'ember'; + +export default AbstractEditController.extend(InventorySelection, { + needs: ['inventory','pouchdb'], + + warehouseList: Ember.computed.alias('controllers.inventory.warehouseList'), + aisleLocationList: Ember.computed.alias('controllers.inventory.aisleLocationList'), + + + inventoryList: function() { + var inventoryItems = this.get('inventoryItems'); + if (!Ember.isEmpty(inventoryItems)) { + var mappedItems = inventoryItems.map(function(item) { + return item.doc; + }); + return mappedItems; + } + }.property('inventoryItems.[]'), + + lookupListsToUpdate: [{ + name: 'aisleLocationList', //Name of property containing lookup list + property: 'deliveryAisle', //Corresponding property on model that potentially contains a new value to add to the list + id: 'aisle_location_list' //Id of the lookup list to update + }, { + name: 'warehouseList', //Name of property containing lookup list + property: 'deliveryLocation', //Corresponding property on model that potentially contains a new value to add to the list + id: 'warehouse_list' //Id of the lookup list to update + }], + + + showInvoiceItems: function() { + var invoiceItems = this.get('invoiceItems'); + return !Ember.isEmpty(invoiceItems); + }.property('invoiceItems.@each'), + + updateCapability: 'add_inventory_item', + + _addNewInventoryItem: function() { + var inventoryItem = this.store.createRecord('inventory', { + name: this.get('inventoryItemTypeAhead'), + quantity: this.get('quantity') + }); + this.send('openModal', 'inventory.quick-add', inventoryItem); + }, + + _addInvoiceItem: function() { + var inventoryItem = this.get('inventoryItem'), + invoiceItems = this.get('invoiceItems'), + purchaseCost = this.get('purchaseCost'), + quantity = this.get('quantity'), + vendorItemNo = this.get('vendorItemNo'), + invoiceItem = Ember.Object.create({ + item: inventoryItem, + quantity: quantity, + purchaseCost: purchaseCost, + vendorItemNo: vendorItemNo + }); + invoiceItems.addObject(invoiceItem); + this.set('inventoryItem'); + this.set('inventoryItemTypeAhead'); + this.set('purchaseCost'); + this.set('quantity'); + this.set('selectedInventoryItem'); + this.set('vendorItemNo'); + }, + + actions: { + addInventoryItem: function() { + var model = this.get('model'), + inventoryItemTypeAhead = this.get('inventoryItemTypeAhead'), + purchaseCost = this.get('purchaseCost'), + quantity = this.get('quantity'); + model.validate(); + if (this.get('isValid') && !Ember.isEmpty(inventoryItemTypeAhead) && !Ember.isEmpty(quantity) && !Ember.isEmpty(purchaseCost)) { + if (Ember.isEmpty(this.get('selectedInventoryItem'))) { + this._addNewInventoryItem(); + } else { + this._addInvoiceItem(); + } + } + }, + + addedNewInventoryItem: function(inventoryItem) { + this.set('inventoryItem', inventoryItem); + this._addInvoiceItem(); + this.send('closeModal'); + }, + + removeItem: function(removeInfo) { + var invoiceItems = this.get('invoiceItems'), + item = removeInfo.itemToRemove; + invoiceItems.removeObject(item); + this.send('closeModal'); + }, + + showRemoveItem: function(item) { + var message= 'Are you sure you want to remove this item from this invoice?', + model = Ember.Object.create({ + itemToRemove: item + }), + title = 'Remove Item'; + this.displayConfirm(title, message, 'removeItem', model); + }, + } +}); \ No newline at end of file diff --git a/app/inventory/invoice/route.js b/app/inventory/invoice/route.js new file mode 100755 index 0000000000..d496c994d3 --- /dev/null +++ b/app/inventory/invoice/route.js @@ -0,0 +1,18 @@ +import InventoryRequestRoute from 'hospitalrun/inventory/request/route'; +import Ember from 'ember'; +export default InventoryRequestRoute.extend({ + editTitle: 'Invoice Received', + modelName: 'inventory-invoice', + newTitle: 'Invoice Received', + getNewData: function() { + return Ember.RSVP.resolve({ + invoiceItems: [] + }); + }, + + actions: { + addedNewInventoryItem: function(model) { + this.controller.send('addedNewInventoryItem', model); + } + }, +}); \ No newline at end of file diff --git a/app/inventory/invoice/template.hbs b/app/inventory/invoice/template.hbs new file mode 100755 index 0000000000..ae70b3f3d9 --- /dev/null +++ b/app/inventory/invoice/template.hbs @@ -0,0 +1,78 @@ +{{#em-form model=this submit_button=false }} +
+
+ {{em-input property="vendor" label="Vendor"}} +
+
+ {{em-input property="invoiceNo" label="Invoice Number"}} +
+
+
+ {{inventory-typeahead + class="col-sm-4 required" + property="inventoryItemTypeAhead" + label="Inventory Item" + content=inventoryList + selection=selectedInventoryItem + showQuantity=false + }} + {{em-input property="quantity" label="Quantity" class="col-sm-2 required"}} + {{em-input property="purchaseCost" label="Purchase Cost" class="col-sm-2 required"}} + {{em-input property="vendorItemNo" label="Vendor Item Number" class="col-sm-3"}} +
+ +

+ +

+
+
+ +{{#if invoiceItems}} +

Invoice Items

+ + + + + + + + + {{#each invoiceItems}} + + + + + + + + {{/each}} +
NameQuantityCostItem NumberAction
+ {{item.name}} + +
+ {{input class="form-control" value=quantity }} +
+
+
+ {{input class="form-control" value=purchaseCost }} +
+
+
+ {{input class="form-control" value=vendorItemNo }} +
+
+ +
+{{/if}} + +{{/em-form}} \ No newline at end of file diff --git a/app/inventory/invoice/view.js b/app/inventory/invoice/view.js new file mode 100755 index 0000000000..a923c4c988 --- /dev/null +++ b/app/inventory/invoice/view.js @@ -0,0 +1,2 @@ +import PanelView from 'hospitalrun/views/panel'; +export default PanelView.extend(); \ No newline at end of file diff --git a/app/inventory/quick-add/controller.js b/app/inventory/quick-add/controller.js new file mode 100644 index 0000000000..66788bc01e --- /dev/null +++ b/app/inventory/quick-add/controller.js @@ -0,0 +1,16 @@ +import InventoryEditController from 'hospitalrun/inventory/edit/controller'; +export default InventoryEditController.extend({ + title: 'New Inventory Item', + + updateCapability: 'add_inventory_item', + + actions: { + cancel: function() { + this.send('closeModal'); + } + }, + + afterUpdate: function(record) { + this.send('addedNewInventoryItem', record); + } +}); \ No newline at end of file diff --git a/app/inventory/quick-add/template.hbs b/app/inventory/quick-add/template.hbs new file mode 100644 index 0000000000..0c558d1b30 --- /dev/null +++ b/app/inventory/quick-add/template.hbs @@ -0,0 +1,3 @@ +{{#em-form model=this submit_button=false }} + {{partial 'inventory-basic'}} +{{/em-form}} \ No newline at end of file diff --git a/app/inventory/quick-add/view.js b/app/inventory/quick-add/view.js new file mode 100644 index 0000000000..bc09ead4e5 --- /dev/null +++ b/app/inventory/quick-add/view.js @@ -0,0 +1,2 @@ +import ModalView from 'hospitalrun/views/modal'; +export default ModalView.extend(); \ No newline at end of file diff --git a/app/mixins/inventory-type-list.js b/app/mixins/inventory-type-list.js index dc0765253d..01b3ebd22e 100644 --- a/app/mixins/inventory-type-list.js +++ b/app/mixins/inventory-type-list.js @@ -3,5 +3,15 @@ export default Ember.Mixin.create({ defaultInventoryTypes: [ 'Medication', 'Supply' - ] + ], + + inventoryTypes: function() { + var defaultInventoryTypes = this.get('defaultInventoryTypes'), + inventoryTypeList = this.get('inventoryTypeList'); + if (Ember.isEmpty(inventoryTypeList)) { + return defaultInventoryTypes; + } else { + return inventoryTypeList; + } + }.property('inventoryTypeList', 'defaultInventoryTypes') }); \ No newline at end of file diff --git a/app/models/inventory-invoice.js b/app/models/inventory-invoice.js new file mode 100644 index 0000000000..42d8295f60 --- /dev/null +++ b/app/models/inventory-invoice.js @@ -0,0 +1,39 @@ +import AbstractModel from "hospitalrun/models/abstract"; +import Ember from "ember"; + +/** + * Model to represent a request for inventory items. + */ +export default AbstractModel.extend({ + + haveInvoiceItems: function() { + var invoiceItems = this.get('invoiceItems'); + return (Ember.isEmpty(invoiceItems)); + }, + + validations: { + inventoryItemTypeAhead: { + presence: { + if: function(object) { + return object.haveInvoiceItems(); + } + } + }, + purchaseCost: { + numericality: { + greaterThan: 0, + if: function(object) { + return object.haveInvoiceItems(); + } + } + }, + quantity: { + numericality: { + greaterThan: 0, + if: function(object) { + return object.haveInvoiceItems(); + } + } + } + } +}); \ No newline at end of file diff --git a/app/router.js b/app/router.js index 4ad7938624..653494cd6c 100755 --- a/app/router.js +++ b/app/router.js @@ -35,6 +35,7 @@ Router.map(function() { this.route('barcode', { path: "/barcode/:inventory_id" }); this.route('delivery', { path: "/delivery/:inv-request_id" }); this.route('edit', { path: "/edit/:inventory_id" }); + this.route('invoice', { path: "/invoice/:inventory-invoice_id" }); this.route('listing'); this.route('reports'); this.route('request', { path: "/request/:inv-request_id" }); diff --git a/app/templates/inventory-basic.hbs b/app/templates/inventory-basic.hbs new file mode 100644 index 0000000000..728054d46f --- /dev/null +++ b/app/templates/inventory-basic.hbs @@ -0,0 +1,37 @@ +
+ {{#unless isNew}} +
+ + {{input class="form-control" value=friendlyId type="text" disabled=true }} +
+ {{/unless}} + {{em-input property="name" label="Name" class="required col-sm-8"}} + {{#unless isNew}} +
+ +

{{quantity}}

+
+ {{/unless}} + +
+{{em-text label="Description" property="description" rows=1 }} +
+ {{em-select label="Type" property="type" + content=inventoryTypes + optionValuePath="content" + optionLabelPath="content" + class="required col-sm-4" + }} + {{em-input property="crossReference" label="Cross Reference" class="col-sm-8"}} +
+
+ {{em-input property="reorderPoint" label="Reorder Point" class="col-sm-3"}} + {{em-input property="price" label="Price Per Unit" class="col-sm-3"}} + {{em-select label="Distribution Unit" class="col-sm-3" + property="distributionUnit" + content=unitList + optionLabelPath="content" + optionValuePath="content" + + }} +
\ No newline at end of file