partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

commit 903389118b7f2400e7d35c9573771f1b16ab9adb
parent 324cbdbf7a366143b3abf2b6afbb02695781bdbd
Author: Felicitus <felicitus@felicitus.org>
Date:   Wed, 29 Jun 2011 17:45:29 +0200

Added multi-create dialog for storage locations

Diffstat:
Mfrontend/js/Components/StorageLocation/StorageLocationGrid.js | 36+++++++++++++++++++++++++++++++++++-
Afrontend/js/Components/StorageLocation/StorageLocationMultiAddDialog.js | 207+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Afrontend/js/Components/StorageLocation/StorageLocationMultiAddWindow.js | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/de/RaumZeitLabor/PartKeepr/StorageLocation/StorageLocationManager.php | 7+++++++
Msrc/de/RaumZeitLabor/PartKeepr/StorageLocation/StorageLocationService.php | 55+++++++++++++++++++++----------------------------------
5 files changed, 348 insertions(+), 35 deletions(-)

diff --git a/frontend/js/Components/StorageLocation/StorageLocationGrid.js b/frontend/js/Components/StorageLocation/StorageLocationGrid.js @@ -5,5 +5,39 @@ Ext.define('PartKeepr.StorageLocationGrid', { {header: i18n("Storage Location"), dataIndex: 'name', flex: 1} ], addButtonText: i18n("Add Storage Location"), - deleteButtonText: i18n("Delete Storage Location") + deleteButtonText: i18n("Delete Storage Location"), + initComponent: function () { + this.callParent(); + + // Adds a button which shows the multi-create window + this.multiCreateButton = Ext.create("Ext.button.Button", { + icon: 'resources/silkicons/table_multiple.png', + tooltip: i18n("Multi-create storage locations"), + handler: this.onMultiCreateClick, + scope: this + }); + + this.topToolbar.insert(2, {xtype: 'tbseparator'}); + this.topToolbar.insert(3, this.multiCreateButton); + }, + /** + * Creates a new storage location multi-create window. + */ + onMultiCreateClick: function () { + var j = Ext.create("PartKeepr.StorageLocationMultiCreateWindow", { + listeners: { + destroy: { + fn: this.onMultiCreateWindowDestroy, + scope: this + } + } + }); + j.show(); + }, + /** + * Reloads the store after the multi-create window was closed + */ + onMultiCreateWindowDestroy: function () { + this.store.load(); + } }); \ No newline at end of file diff --git a/frontend/js/Components/StorageLocation/StorageLocationMultiAddDialog.js b/frontend/js/Components/StorageLocation/StorageLocationMultiAddDialog.js @@ -0,0 +1,206 @@ +/** + * Represents a form which is used to create multiple storage locations at once. + * @class PartKeepr.StorageLocationMultiAddDialog + */ +Ext.define('PartKeepr.StorageLocationMultiAddDialog', { + extend: 'Ext.form.Panel', + + // Layout settings + layout: 'anchor', + defaults: { + anchor: '100%' + }, + + // Styling + border: false, + bodyStyle: 'background:#DFE8F6;padding: 10px;', + + /** + * Initializes the component. Adds all form fields + */ + initComponent: function () { + + /** + * The prefix represents the first part of the storage location name, + * e.g. "A" for storage locations "A0001". + */ + this.storageLocationPrefix = Ext.create("Ext.form.field.Text", { + fieldLabel: i18n("Name Prefix"), + listeners: { + change: { + fn: this.onFormChange, + scope: this + } + } + }); + + /** + * Specifies the start of the numeric range. + */ + this.storageLocationStart = Ext.create("Ext.form.field.Number", { + fieldLabel: i18n("Start"), + value: 1, + minValue: 0, + columnWidth: 0.5, + listeners: { + change: { + fn: this.onFormChange, + scope: this + } + } + }); + + /** + * Specifies the end of the numeric range. + */ + this.storageLocationEnd = Ext.create("Ext.form.field.Number", { + fieldLabel: i18n("End"), + value: 10, + minValue: 1, + columnWidth: 0.5, + margin: "0 0 0 5", + listeners: { + change: { + fn: this.onFormChange, + scope: this + } + } + }); + + /** + * Specifies if the storage locations should be prefixed with a zero (e.g. creates A0001 instead of A1). + */ + this.storageLocationZeroPrefix = Ext.create("Ext.form.field.Checkbox", { + boxLabel: i18n("Prefix with zeroes"), + hideEmptyLabel: false, + columnWidth: 0.5, + listeners: { + change: { + fn: this.onFormChange, + scope: this + } + } + }); + + /** + * Specifies the overall length of the storage location name. If you have a prefix "A" and numbers up to + * 100, you can set the overall length to 5 to achieve "A0100", or to 6 to achieve "A00100". + */ + this.storageLocationOverallLength = Ext.create("Ext.form.field.Number", { + fieldLabel: i18n("Length"), + columnWidth: 0.5, + margin: "0 0 0 5", + disabled: true, + listeners: { + change: { + fn: this.onFormChange, + scope: this + } + } + }); + + /** + * Creates a field which displays the storage locations to be created. + */ + this.outputField = Ext.create("Ext.form.field.TextArea", { + fieldLabel: i18n("Sample"), + readOnly: true, + anchor: '100% -70' + }); + + this.items = [ + this.storageLocationPrefix, + { + layout: 'column', + border: false, + bodyStyle: 'background:#DFE8F6;', + items: [ + this.storageLocationStart, + this.storageLocationEnd + ] + }, + { + layout: 'column', + border: false, + plain: true, + bodyStyle: 'background:#DFE8F6;', + items: [ + this.storageLocationZeroPrefix, + this.storageLocationOverallLength + ] + }, + this.outputField + ]; + + this.callParent(); + + this.recalculateDemo(); + }, + /** + * Called when something in the form has changed. + */ + onFormChange: function () { + /** + * If the overall length is less than the prefix plus the length of the highest number, update it + */ + if (this.storageLocationOverallLength.getValue() < this.getMinLength()) { + this.storageLocationOverallLength.setValue(this.getMinLength()); + } + + /** + * Make sure that the end value is bigger than the start value. + */ + if (this.storageLocationStart.getValue() > this.storageLocationEnd.getValue()) { + this.storageLocationEnd.setValue(this.storageLocationStart.getValue()); + } + + /** + * Enable/Disable the length field if zero prefix is wanted + */ + if (this.storageLocationZeroPrefix.getValue()) { + this.storageLocationOverallLength.enable(); + } else { + this.storageLocationOverallLength.disable(); + } + + this.recalculateDemo(); + }, + /** + * Calculates the minimum length possible + * @returns int The minimum length possible + */ + getMinLength: function () { + return strlen(this.storageLocationPrefix.getValue()) + + strlen((this.storageLocationEnd.getValue()).toString()); + }, + /** + * Updates the sample field + */ + recalculateDemo: function () { + this.outputField.setValue(implode("\n", this.getStorageLocations())); + }, + /** + * Returns all storage locations which are to be created + * @returns {Array} The storage locations + */ + getStorageLocations: function () { + var j = []; + + for (var i=this.storageLocationStart.getValue();i<this.storageLocationEnd.getValue()+1;i++) { + if (!this.storageLocationZeroPrefix.getValue()) { + // No padding wanted + j.push(this.storageLocationPrefix.getValue()+i); + } else { + var padLength = this.storageLocationOverallLength.getValue() - + ( strlen(this.storageLocationPrefix.getValue()) + + strlen(i)); + + j.push(this.storageLocationPrefix.getValue() + str_repeat("0", padLength)+ i); + } + + } + + return j; + } + +});+ \ No newline at end of file diff --git a/frontend/js/Components/StorageLocation/StorageLocationMultiAddWindow.js b/frontend/js/Components/StorageLocation/StorageLocationMultiAddWindow.js @@ -0,0 +1,77 @@ +/** + * Represents the multi create window. + * @class PartKeepr.StorageLocationMultiCreateWindow + */ +Ext.define("PartKeepr.StorageLocationMultiCreateWindow", { + extend: 'Ext.Window', + + // Layout stuff + layout: 'fit', + width: 500, + height: 250, + + // Title + title: i18n("Multi-Create Storage Locations"), + + /** + * Initializes the window by adding the buttons and the form + */ + initComponent: function () { + this.form = Ext.create("PartKeepr.StorageLocationMultiAddDialog"); + + this.items = [ this.form ]; + + // Creates the add button as instance, so we can disable it easily. + this.addButton = Ext.create("Ext.button.Button", { + text: i18n("Create Storage Locations"), + icon: 'resources/silkicons/add.png', + handler: this.onAddClick, + scope: this + }); + + this.bbar = [ + this.addButton, + { + text: i18n("Close"), + handler: this.onCloseClick, + scope: this, + icon: 'resources/silkicons/cancel.png' + }]; + + this.callParent(); + }, + /** + * Called when the "Add" button was clicked. Sends a call to the server + * to create the storage locations + */ + onAddClick: function () { + this.addButton.disable(); + var call = new PartKeepr.ServiceCall("StorageLocation", "massCreate"); + call.setParameter("storageLocations", this.form.getStorageLocations()); + call.setHandler(Ext.bind(this.onAdded, this)); + call.doCall(); + + }, + /** + * Called when the service call was completed. Displays an error dialog + * if something went wrong. + * @param response The server response + */ + onAdded: function (response) { + this.addButton.enable(); + + + if (response.data.length > 0) { + Ext.Msg.alert(i18n("Errors occured"), implode("<br>", response.data)); + } else { + this.close(); + } + }, + /** + * Close the dialog + */ + onCloseClick: function () { + this.close(); + } + +});+ \ No newline at end of file diff --git a/src/de/RaumZeitLabor/PartKeepr/StorageLocation/StorageLocationManager.php b/src/de/RaumZeitLabor/PartKeepr/StorageLocation/StorageLocationManager.php @@ -55,6 +55,13 @@ class StorageLocationManager extends Singleton { } } + public function getStorageLocationByName ($name) { + $query = PartKeepr::getEM()->createQuery("SELECT s FROM de\RaumZeitLabor\PartKeepr\StorageLocation\StorageLocation s WHERE s.name = :name"); + $query->setParameter("name", $name); + + return $query->getSingleResult(); + } + public function addStorageLocation ($name) { $storageLocation = new StorageLocation(); $storageLocation->setName($name); diff --git a/src/de/RaumZeitLabor/PartKeepr/StorageLocation/StorageLocationService.php b/src/de/RaumZeitLabor/PartKeepr/StorageLocation/StorageLocationService.php @@ -66,44 +66,31 @@ class StorageLocationService extends Service implements RestfulService { return array("data" => null); } - // Old Stuff below - public function getStorageLocations() { - return StorageLocationManager::getInstance()->getStorageLocations( - $this->getParameter("start", 0), - $this->getParameter("limit", 10), - $this->getParameter("sortby", "name"), - $this->getParameter("dir", "asc"), - $this->getParameter("filter", "")); - } - - public function addStorageLocation () { - $this->requireParameter("name"); - - StorageLocationManager::getInstance()->addStorageLocation($this->getParameter("name")); - } - - public function deleteStorageLocation () { - $this->requireParameter("id"); - - StorageLocationManager::getInstance()->deleteStorageLocation($this->getParameter("id")); - } - - public function getStorageLocation () { - $this->requireParameter("id"); - - return StorageLocationManager::getInstance()->getStorageLocation($this->getParameter("id"))->serialize(); - } - - public function saveStorageLocation () { - $this->requireParameter("id"); - $this->requireParameter("name"); + /** + * Creates multiple storage locations at once. + * + * Requires that the parameter "storageLocations" is set to an array with the names of the storage locations. + * Returns all error messages as "data" index in the result array. + */ + public function massCreate () { + $this->requireParameter("storageLocations"); - $storageLocation = StorageLocationManager::getInstance()->getStorageLocation($this->getParameter("id")); + $aMessages = array(); - $storageLocation->setName($this->getParameter("name")); + foreach ($this->getParameter("storageLocations") as $storageLocation) { + try { + $obj = StorageLocationManager::getInstance()->getStorageLocationByName($storageLocation); + $aMessages[] = sprintf(PartKeepr::i18n("Storage Location %s already exists"), $storageLocation); + } catch (\Exception $e) { + $obj = new StorageLocation(); + $obj->setName($storageLocation); + PartKeepr::getEM()->persist($obj); + } + + } PartKeepr::getEM()->flush(); - return $storageLocation->serialize(); + return array("data" => $aMessages); } } \ No newline at end of file