partkeepr

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

commit 294d4bcb9e08cac4b4835a879d4277b73bcd6031
parent 82063d7bbcb36e6f21db7cd11aac3ed67a29c00f
Author: Felicitus <felicitus@felicitus.org>
Date:   Thu, 23 Jun 2011 11:33:08 +0200

Refactored parts to match the new serialize/deserialize model

Diffstat:
Mfrontend/js/Components/Editor/Editor.js | 5++++-
Mfrontend/js/Components/Footprint/FootprintEditorComponent.js | 7+++----
Rfrontend/js/Components/Part/PartAttachmentGrid.js -> frontend/js/Components/Part/Editor/PartAttachmentGrid.js | 0
Rfrontend/js/Components/Part/PartDistributorGrid.js -> frontend/js/Components/Part/Editor/PartDistributorGrid.js | 0
Afrontend/js/Components/Part/Editor/PartEditor.js | 135+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Afrontend/js/Components/Part/Editor/PartEditorWindow.js | 41+++++++++++++++++++++++++++++++++++++++++
Rfrontend/js/Components/Part/PartManufacturerGrid.js -> frontend/js/Components/Part/Editor/PartManufacturerGrid.js | 0
Rfrontend/js/Components/Part/PartParameterGrid.js -> frontend/js/Components/Part/Editor/PartParameterGrid.js | 0
Mfrontend/js/Components/Part/PartDisplay.js | 16++++++----------
Dfrontend/js/Components/Part/PartEditor.js | 141-------------------------------------------------------------------------------
Dfrontend/js/Components/Part/PartEditorWindow.js | 49-------------------------------------------------
Mfrontend/js/Components/Part/PartsGrid.js | 2+-
Mfrontend/js/Components/Part/PartsManager.js | 35+++++++++++++++++++++++++----------
Mfrontend/js/Components/Widgets/FootprintComboBox.js | 3++-
Mfrontend/js/Models/Part.js | 50+++++++++++++++++++++++++++-----------------------
Mfrontend/js/Models/PartAttachment.js | 13++++++-------
Msrc/de/RaumZeitLabor/PartKeepr/Part/Part.php | 125++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
Msrc/de/RaumZeitLabor/PartKeepr/Part/PartAttachment.php | 30++++++++++++++++++++++++++----
Msrc/de/RaumZeitLabor/PartKeepr/Part/PartDistributor.php | 29+++++++++++++++++++++++++----
Msrc/de/RaumZeitLabor/PartKeepr/Part/PartManager.php | 2+-
Msrc/de/RaumZeitLabor/PartKeepr/Part/PartManufacturer.php | 27++++++++++++++++++++-------
Msrc/de/RaumZeitLabor/PartKeepr/Part/PartService.php | 113+++++++++++++++++++------------------------------------------------------------
Msrc/de/RaumZeitLabor/PartKeepr/PartParameter/PartParameter.php | 102+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
23 files changed, 495 insertions(+), 430 deletions(-)

diff --git a/frontend/js/Components/Editor/Editor.js b/frontend/js/Components/Editor/Editor.js @@ -77,7 +77,7 @@ Ext.define('PartKeepr.Editor', { this.getForm().loadRecord(this.record); this.show(); if (this.record.getRecordName() !== "") { - this.setTitle(this.record.getRecordName()); + this._setTitle(this.record.getRecordName()); } this.change = false; @@ -100,5 +100,8 @@ Ext.define('PartKeepr.Editor', { _onSave: function (record) { this.record = record; this.fireEvent("itemSaved", this.record); + }, + _setTitle: function (title) { + this.setTitle(title); } }); \ No newline at end of file diff --git a/frontend/js/Components/Footprint/FootprintEditorComponent.js b/frontend/js/Components/Footprint/FootprintEditorComponent.js @@ -26,13 +26,12 @@ Ext.define('PartKeepr.FootprintEditorComponent', { var call = new PartKeepr.ServiceCall("Footprint", "destroy"); call.setParameter("id", r.get("footprintId")); call.setHandler(Ext.bind(function () { - console.log("My footprint id is:"+r.get("footprintId")); var oldRecordIndex = PartKeepr.getApplication().getFootprintStore().find("id", r.get("footprintId")); - console.log(oldRecordIndex); - PartKeepr.getApplication().getFootprintStore().removeAt(oldRecordIndex); - this.navigation.loadCategories(); }, this)); + this.navigation.loadCategories(); + }, this)); + call.doCall(); diff --git a/frontend/js/Components/Part/PartAttachmentGrid.js b/frontend/js/Components/Part/Editor/PartAttachmentGrid.js diff --git a/frontend/js/Components/Part/PartDistributorGrid.js b/frontend/js/Components/Part/Editor/PartDistributorGrid.js diff --git a/frontend/js/Components/Part/Editor/PartEditor.js b/frontend/js/Components/Part/Editor/PartEditor.js @@ -0,0 +1,135 @@ +/** + * @class PartKeepr.PartEditor + + * <p>The PartEditor provides an editing form for a part. It contains multiple tabs, one for each nested record.</p> + */ +Ext.define('PartKeepr.PartEditor', { + extend: 'PartKeepr.Editor', + border: false, + model: 'PartKeepr.Part', + layout: 'fit', + bodyStyle: 'background:#DFE8F6;', + initComponent: function () { + var basicEditorFields = [{ + xtype: 'textfield', + name: 'name', + fieldLabel: i18n("Name"), + allowBlank: false + },{ + xtype: 'numberfield', + fieldLabel: i18n('Minimum Stock'), + allowDecimals: false, + allowBlank: false, + name: 'minStockLevel', + value: 0, + minValue: 0 + },{ + xtype: 'PartUnitComboBox', + fieldLabel: i18n("Part Unit"), + name: 'partUnit' + },{ + xtype: 'CategoryComboBox', + fieldLabel: i18n("Category"), + name: 'category' + },{ + xtype: 'StorageLocationComboBox', + fieldLabel: i18n("Storage Location"), + name: 'storageLocation', + allowBlank: false + },{ + xtype: 'FootprintComboBox', + fieldLabel: i18n("Footprint"), + name: 'footprint' + },{ + xtype: 'textarea', + fieldLabel: i18n("Comment"), + name: 'comment' + }]; + + this.partDistributorGrid = Ext.create("PartKeepr.PartDistributorGrid", { + title: i18n("Distributors"), + layout: 'fit' + }); + + this.partManufacturerGrid = Ext.create("PartKeepr.PartManufacturerGrid", { + title: i18n("Manufacturers"), + layout: 'fit' + }); + + this.partParameterGrid = Ext.create("PartKeepr.PartParameterGrid", { + title: i18n("Parameters"), + layout: 'fit' + }); + + this.partAttachmentGrid = Ext.create("PartKeepr.PartAttachmentGrid", { + title: i18n("Attachments"), + layout: 'fit' + }); + + this.items = { + xtype: 'tabpanel', + border: false, + plain: true, + items: [{ + xtype: 'panel', + border: false, + autoScroll: true, + layout: 'anchor', + defaults: { + anchor: '100%', + labelWidth: 150 + }, + bodyStyle: 'background:#DFE8F6;padding: 10px;', + title: i18n("Basic Data"), + items: basicEditorFields + }, + this.partDistributorGrid, + this.partManufacturerGrid, + this.partParameterGrid, + this.partAttachmentGrid + ] + }; + + this.on("startEdit", this.onEditStart, this, { delay: 200 }); + this.on("itemSaved", this._onItemSaved, this); + + this.addEvents("partSaved", "titleChange"); + + this.callParent(); + }, + onEditStart: function () { + this.bindChildStores(); + }, + _onItemSaved: function () { + this.fireEvent("partSaved", this.record); + this.bindChildStores(); + }, + bindChildStores: function () { + this.partDistributorGrid.bindStore(this.record.distributors()); + this.partManufacturerGrid.bindStore(this.record.manufacturers()); + this.partParameterGrid.bindStore(this.record.parameters()); + this.partAttachmentGrid.bindStore(this.record.attachments()); + }, + onItemSave: function () { + if (!this.getForm().isValid()) { + return; + } + + this.callParent(); + }, + _setTitle: function (title) { + var tmpTitle; + + if (this.record.phantom) { + tmpTitle = i18n("Add Part"); + } else { + tmpTitle = i18n("Edit Part"); + } + + if (title !== "") { + tmpTitle = tmpTitle + ": " + title; + } + + this.fireEvent("titleChange", tmpTitle); + } +}); diff --git a/frontend/js/Components/Part/Editor/PartEditorWindow.js b/frontend/js/Components/Part/Editor/PartEditorWindow.js @@ -0,0 +1,41 @@ +/** + * @class PartKeepr.PartEditorWindow + + * <p>The PartEditorWindow encapsulates the PartKeepr.PartEditor within a window.</p> + */ +Ext.define('PartKeepr.PartEditorWindow', { + extend: 'Ext.window.Window', + + /* Constrain the window to fit the viewport */ + constrainHeader: true, + + /* Fit the editor within the window */ + layout: 'fit', + + /* Width and height settings */ + width: 600, + minWidth: 600, + minHeight: 300, + height: 450, + + title: i18n("Add Part"), + + initComponent: function () { + this.editor = Ext.create("PartKeepr.PartEditor", { + border: false + }); + this.items = [ this.editor ]; + + this.editor.on("editorClose", function () { this.close(); }, this); + + + /** + * We need a delay, since if others are listening for "partSaved", the dialog plus the record could be destroyed + * before any following listeners have a chance to receive the record, resulting in strange problems. + */ + this.editor.on("partSaved", function (record) { this.close();}, this, { delay: 200 }); + + this.editor.on("titleChange", function (val) { this.setTitle(val); }, this); + this.callParent(); + } +}); diff --git a/frontend/js/Components/Part/PartManufacturerGrid.js b/frontend/js/Components/Part/Editor/PartManufacturerGrid.js diff --git a/frontend/js/Components/Part/PartParameterGrid.js b/frontend/js/Components/Part/Editor/PartParameterGrid.js diff --git a/frontend/js/Components/Part/PartDisplay.js b/frontend/js/Components/Part/PartDisplay.js @@ -134,7 +134,6 @@ Ext.define('PartKeepr.PartDisplay', { deletePartPrompt: function () { var j = new PartKeepr.PartStockWindow(); j.removeStock(this.deletePartHandler, this); - //Ext.Msg.prompt(i18n("Remove Stock"), i18n("Amount"), this.deletePartHandler, this); }, /** * Callback after the "delete stock" dialog is complete. @@ -158,19 +157,16 @@ Ext.define('PartKeepr.PartDisplay', { * Load the part from the database. */ loadPart: function (id) { - var call = new PartKeepr.ServiceCall( - "Part", - "getPart"); - call.setParameter("part", id); - call.setLoadMessage('$[de.RaumZeitLabor.PartKeepr.CategoryEditor.loadCategories]'); - call.setHandler(Ext.bind(this.onPartLoaded, this)); - call.doCall(); + PartKeepr.Part.load(id, { + scope: this, + success: this.onPartLoaded + }); }, /** * Callback after the part is loaded */ - onPartLoaded: function (response) { - this.record.set(response); + onPartLoaded: function (record) { + this.record = record; this.setValues(this.record); this.record.commit(); } diff --git a/frontend/js/Components/Part/PartEditor.js b/frontend/js/Components/Part/PartEditor.js @@ -1,141 +0,0 @@ -Ext.define('PartKeepr.PartEditor', { - extend: 'PartKeepr.Editor', - border: false, - model: 'PartKeepr.Part', - mode: 'add', - layout: 'fit', - bodyStyle: 'background:#DFE8F6;', - initComponent: function () { - var basicEditorFields = [{ - xtype: 'textfield', - name: 'name', - fieldLabel: i18n("Name"), - allowBlank: false - },{ - xtype: 'numberfield', - fieldLabel: i18n('Minimum Stock'), - allowDecimals: false, - allowBlank: false, - name: 'minStockLevel', - value: 0, - minValue: 0 - },{ - xtype: 'PartUnitComboBox', - fieldLabel: i18n("Part Unit"), - name: 'partUnit_id' - },{ - xtype: 'CategoryComboBox', - fieldLabel: i18n("Category"), - name: 'category_id' - },{ - xtype: 'StorageLocationComboBox', - fieldLabel: i18n("Storage Location"), - name: 'storageLocation_id', - allowBlank: false - },{ - xtype: 'FootprintComboBox', - fieldLabel: i18n("Footprint"), - name: 'footprint_id' - },{ - xtype: 'textarea', - fieldLabel: i18n("Comment"), - name: 'comment' - }]; - - this.partDistributorGrid = Ext.create("PartKeepr.PartDistributorGrid", { - title: i18n("Distributors"), - layout: 'fit' - }); - - this.partManufacturerGrid = Ext.create("PartKeepr.PartManufacturerGrid", { - title: i18n("Manufacturers"), - layout: 'fit' - }); - - this.partParameterGrid = Ext.create("PartKeepr.PartParameterGrid", { - title: i18n("Parameters"), - layout: 'fit' - }); - - this.partAttachmentGrid = Ext.create("PartKeepr.PartAttachmentGrid", { - title: i18n("Attachments"), - layout: 'fit' - }); - - this.items = { - xtype: 'tabpanel', - border: false, - plain: true, - items: [{ - xtype: 'panel', - border: false, - autoScroll: true, - layout: 'anchor', - defaults: { - anchor: '100%', - labelWidth: 150 - }, - bodyStyle: 'background:#DFE8F6;padding: 10px;', - title: i18n("Basic Data"), - items: basicEditorFields - }, - this.partDistributorGrid, - this.partManufacturerGrid, - this.partParameterGrid, - this.partAttachmentGrid - ] - }; - - this.on("startEdit", function () { this.mode = "edit"; }, this); - - this.addEvents("partSaved"); - - this.callParent(); - }, - onItemSave: function () { - if (!this.getForm().isValid()) { - return; - } - - var call = new PartKeepr.ServiceCall( - "Part", - "addOrUpdatePart"); - - if (this.rawValues.id) { - call.setParameter("part", this.rawValues.id); - } - - var values = this.getForm().getFieldValues(); - - values.distributorChanges = { - "inserts": PartKeepr.serializeRecords(this.partDistributorGrid.getStore().getNewRecords()), - "updates": PartKeepr.serializeRecords(this.partDistributorGrid.getStore().getUpdatedRecords()), - "removals": PartKeepr.serializeRecords(this.partDistributorGrid.getStore().getRemovedRecords()) - }; - - values.manufacturerChanges = { - "inserts": PartKeepr.serializeRecords(this.partManufacturerGrid.getStore().getNewRecords()), - "updates": PartKeepr.serializeRecords(this.partManufacturerGrid.getStore().getUpdatedRecords()), - "removals": PartKeepr.serializeRecords(this.partManufacturerGrid.getStore().getRemovedRecords()) - }; - - values.parameterChanges = { - "inserts": PartKeepr.serializeRecords(this.partParameterGrid.getStore().getNewRecords()), - "updates": PartKeepr.serializeRecords(this.partParameterGrid.getStore().getUpdatedRecords()), - "removals": PartKeepr.serializeRecords(this.partParameterGrid.getStore().getRemovedRecords()) - }; - - values.attachmentChanges = { - "inserts": PartKeepr.serializeRecords(this.partAttachmentGrid.getStore().getNewRecords()), - "updates": PartKeepr.serializeRecords(this.partAttachmentGrid.getStore().getUpdatedRecords()), - "removals": PartKeepr.serializeRecords(this.partAttachmentGrid.getStore().getRemovedRecords()) - }; - - call.setParameters(values); - call.setHandler(Ext.bind(this.onPartSave, this)); - call.doCall(); - }, - onPartSave: function () { - this.fireEvent("partSaved"); - } -}); diff --git a/frontend/js/Components/Part/PartEditorWindow.js b/frontend/js/Components/Part/PartEditorWindow.js @@ -1,49 +0,0 @@ -Ext.define('PartKeepr.PartEditorWindow', { - extend: 'Ext.window.Window', - constrainHeader: true, - width: 600, - minWidth: 600, - minHeight: 300, - height: 450, - layout: 'fit', - title: i18n("Add Part"), - initComponent: function () { - this.editor = Ext.create("PartKeepr.PartEditor", { - border: false - }); - this.items = [ this.editor ]; - - this.editor.on("editorClose", function () { this.close(); }, this); - this.editor.on("partSaved", function () { this.close();}, this); - this.callParent(); - }, - applyRecord: function (r) { - if (r.id) { - this.setTitle(i18n("Edit Part")); - } - - this.editor.getForm().setValues(r); - this.editor.rawValues = r; - - if (!r.distributors) { - r.distributors = []; - } - - if (!r.manufacturers) { - r.manufacturers = []; - } - - if (!r.parameters) { - r.parameters = []; - } - - if (!r.attachments) { - r.attachments = []; - } - - this.editor.partDistributorGrid.getStore().loadData(r.distributors); - this.editor.partManufacturerGrid.getStore().loadData(r.manufacturers); - this.editor.partParameterGrid.getStore().loadData(r.parameters); - this.editor.partAttachmentGrid.getStore().loadData(r.attachments); - } -}); diff --git a/frontend/js/Components/Part/PartsGrid.js b/frontend/js/Components/Part/PartsGrid.js @@ -85,7 +85,7 @@ Ext.define('PartKeepr.PartsGrid', { stockLevelRenderer: function (val,q,rec) { if (rec.get("partUnitDefault") !== true) { - return val + " " + rec.get("partUnit"); + return val + " " + rec.get("partUnitName"); } else { return val; } diff --git a/frontend/js/Components/Part/PartsManager.js b/frontend/js/Components/Part/PartsManager.js @@ -114,10 +114,12 @@ Ext.define('PartKeepr.PartManager', { var defaultPartUnit = PartKeepr.getApplication().getPartUnitStore().find("default", true); - defaults.partUnit_id = defaultPartUnit; - defaults.category_id = this.grid.currentCategory; + defaults.partUnit = defaultPartUnit; + defaults.category = this.grid.currentCategory; - j.applyRecord(defaults); + record = Ext.create("PartKeepr.Part", defaults); + + j.editor.editItem(record); j.show(); }, /** @@ -131,9 +133,21 @@ Ext.define('PartKeepr.PartManager', { */ onPartLoaded: function (f,g) { var j = Ext.create("PartKeepr.PartEditorWindow"); - j.applyRecord(f); + j.editor.on("partSaved", this.onPartSaved, this); + j.editor.editItem(f); j.show(); }, + onPartSaved: function (record) { + + var idx = this.grid.store.find("id", record.get("id")); + + // Only reload the grid if the edited record is contained + if (idx !== -1) { + this.grid.store.load(); + } + + this.detail.setValues(record); + }, /** * Called when a part was selected in the grid. Displays the details for this part. */ @@ -156,12 +170,13 @@ Ext.define('PartKeepr.PartManager', { * @param {Function} handler The callback to call when the part was loaded */ loadPart: function (id, handler) { - var call = new PartKeepr.ServiceCall( - "Part", - "getPart"); - call.setParameter("part", id); - call.setHandler(handler); - call.doCall(); + // @todo we have this method duplicated in PartEditor + var model = Ext.ModelManager.getModel("PartKeepr.Part"); + + model.load(id, { + scope: this, + success: handler + }); }, /** * Creates the store diff --git a/frontend/js/Components/Widgets/FootprintComboBox.js b/frontend/js/Components/Widgets/FootprintComboBox.js @@ -6,7 +6,8 @@ Ext.define("PartKeepr.FootprintComboBox",{ autoSelect: true, queryMode: 'local', triggerAction: 'all', - + forceSelection: true, + editable: false, initComponent: function () { this.store = PartKeepr.getApplication().getFootprintStore(); diff --git a/frontend/js/Models/Part.js b/frontend/js/Models/Part.js @@ -2,20 +2,20 @@ Ext.define("PartKeepr.Part", { extend: "Ext.data.Model", fields: [ { id: 'id', name: 'id', type: 'int' }, - { name: 'category_id', type: 'int'}, - { name: 'categoryName', type: 'string'}, - { name: 'footprint_id', type: 'int'}, - { name: 'footprintName', type: 'string'}, - { name: 'manufacturer_id',type: 'int'}, - { name: 'storageLocation_id',type: 'int'}, - { name: 'storageLocationName',type: 'string'}, - { name: 'partUnit',type: 'string'}, + { name: 'category', type: 'int'}, + { name: 'footprint', type: 'int'}, + { name: 'storageLocation',type: 'int'}, + { name: 'partUnit',type: 'int'}, { name: 'averagePrice',type: 'float'}, + { name: 'name',type: 'string'}, + { name: 'comment',type: 'string'}, + { name: 'stockLevel',type: 'int'}, + { name: 'minStockLevel',type: 'int'}, - /* - * The partUnitDefault would belong into an association. Unless we know how to - * access associations in e.g. a grid, we need to pass it as this one. - */ + { name: 'partUnitName',type: 'string'}, + { name: 'footprintName', type: 'string'}, + { name: 'storageLocationName',type: 'string'}, + { name: 'categoryName', type: 'string'}, { name: 'partUnitDefault', type: 'boolean', @@ -24,18 +24,22 @@ Ext.define("PartKeepr.Part", { { return true; } else { return false; } } - }, - { name: 'name',type: 'string'}, - { name: 'comment',type: 'string'}, - { name: 'stockLevel',type: 'int'}, - { name: 'minStockLevel',type: 'int'} + } + ], belongsTo: [ - { model: 'PartKeepr.Manufacturer', primaryKey: 'id', foreignKey: 'manufacturer_id'}, - { model: 'PartKeepr.StorageLocation', primaryKey: 'id', foreignKey: 'storageLocation_id'}, - { model: 'PartKeepr.Footprint', primaryKey: 'id', foreignKey: 'footprint_id'}, - { model: 'PartKeepr.PartCategory', primaryKey: 'id', foreignKey: 'category_id'} + { model: 'PartKeepr.StorageLocation', primaryKey: 'id', foreignKey: 'storageLocation'}, + { model: 'PartKeepr.Footprint', primaryKey: 'id', foreignKey: 'footprint'}, + { model: 'PartKeepr.PartCategory', primaryKey: 'id', foreignKey: 'category'} ], - hasMany: { model: 'PartKeepr.PartDistributor', name: 'distributors'}, - proxy: PartKeepr.getRESTProxy("Part") + hasMany: [ + { model: 'PartKeepr.PartDistributor', name: 'distributors'}, + { model: 'PartKeepr.PartManufacturer', name: 'manufacturers'}, + { model: 'PartKeepr.PartParameter', name: 'parameters'}, + { model: 'PartKeepr.PartAttachment', name: 'attachments'}, + ], + proxy: PartKeepr.getRESTProxy("Part"), + getRecordName: function () { + return this.get("name"); + } }); \ No newline at end of file diff --git a/frontend/js/Models/PartAttachment.js b/frontend/js/Models/PartAttachment.js @@ -1,14 +1,14 @@ Ext.define("PartKeepr.PartAttachment", { extend: "Ext.data.Model", fields: [ - { id: 'id', name: 'id', type: 'int' }, - { name: 'originalFilename', type: 'string' }, + { id: 'id', name: 'id', type: 'string' }, + { name: 'originalFilename', type: 'string' }, + { name: 'footprint_id', type: 'int' }, { name: 'mimetype', type: 'string' }, { name: 'extension', type: 'string' }, { name: 'description', type: 'string' }, - { name: 'size', type: 'string' }, - { name: 'tmp_id', type: 'int' } + { name: 'size', type: 'string' } ], - belongsTo: { type: 'belongsTo', model: 'PartKeepr.Part', primaryKey: 'id', foreignKey: 'part_id'}, + belongsTo: { type: 'belongsTo', model: 'PartKeepr.Part', primaryKey: 'id', foreignKey: 'part_id'}, proxy: PartKeepr.getRESTProxy("PartAttachment") -});- \ No newline at end of file +}); diff --git a/src/de/RaumZeitLabor/PartKeepr/Part/Part.php b/src/de/RaumZeitLabor/PartKeepr/Part/Part.php @@ -1,5 +1,10 @@ <?php namespace de\RaumZeitLabor\PartKeepr\Part; +use de\RaumZeitLabor\PartKeepr\StorageLocation\StorageLocation; +use de\RaumZeitLabor\PartKeepr\Footprint\Footprint; + +use de\RaumZeitLabor\PartKeepr\Util\Deserializable; + use de\RaumZeitLabor\PartKeepr\PartCategory\PartCategory; use de\RaumZeitLabor\PartKeepr\Util\Serializable; @@ -15,7 +20,7 @@ use de\RaumZeitLabor\PartKeepr\PartKeepr, /** * Represents a part in the database. The heart of our project. Handle with care! * @Entity **/ -class Part extends BaseEntity implements Serializable { +class Part extends BaseEntity implements Serializable, Deserializable { /** * The category of the part * @ManyToOne(targetEntity="de\RaumZeitLabor\PartKeepr\PartCategory\PartCategory") @@ -217,7 +222,7 @@ class Part extends BaseEntity implements Serializable { * Sets the storage location for this part * @param \de\RaumZeitLabor\PartKeepr\StorageLocation\StorageLocation $storageLocation The storage location */ - public function setStorageLocation (\de\RaumZeitLabor\PartKeepr\StorageLocation\StorageLocation $storageLocation) { + public function setStorageLocation (StorageLocation $storageLocation) { $this->storageLocation = $storageLocation; } @@ -225,7 +230,7 @@ class Part extends BaseEntity implements Serializable { * Sets the footprint for this part * @param \de\RaumZeitLabor\PartKeepr\Footprint\Footprint $footprint The footprint to set */ - public function setFootprint (\de\RaumZeitLabor\PartKeepr\Footprint\Footprint $footprint = null) { + public function setFootprint (Footprint $footprint = null) { $this->footprint = $footprint; } @@ -302,52 +307,86 @@ class Part extends BaseEntity implements Serializable { * @see de\RaumZeitLabor\PartKeepr\Util.Serializable::serialize() */ public function serialize () { - $aManufacturers = array(); - - foreach ($this->getManufacturers() as $manufacturer) { - $aManufacturers[] = $manufacturer->serialize(); - } - - $aDistributors = array(); - - foreach ($this->getDistributors() as $distributor) { - $aDistributors[] = $distributor->serialize(); - } - - $aParameters = array(); - foreach ($this->getParameters() as $parameter) { - $aParameters[] = $parameter->serialize(); - } - - $aImages = array(); - foreach ($this->getImages() as $image) { - $aImages[] = $image->serialize(); - } - - $aAttachments = array(); - foreach ($this->getAttachments() as $attachment) { - $aAttachments[] = $attachment->serialize(); - } - return array( "id" => $this->getId(), "name" => $this->getName(), "comment" => $this->getComment(), "stockLevel" => $this->getStockLevel(), - "footprint_id" => is_object($this->footprint) ? $this->footprint->getId() : null, + "footprint" => is_object($this->footprint) ? $this->footprint->getId() : null, "minStockLevel" => $this->minStockLevel, - "storageLocation_id" => is_object($this->storageLocation) ? $this->storageLocation->getId() : null, - "storageLocationName" => is_object($this->storageLocation) ? $this->storageLocation->getName() : null, - "category_id" => is_object($this->category) ? $this->category->getId() : null, - "partUnit_id" => is_object($this->partUnit) ? $this->getPartUnit()->getId() : null, - "partUnit_name" => is_object($this->partUnit) ? $this->getPartUnit()->getId() : PartKeepr::i18n("Pieces"), - "partUnit_shortName" => is_object($this->partUnit) ? $this->getPartUnit()->getId() : "", - "manufacturers" => $aManufacturers, - "distributors" => $aDistributors, - "images" => $aImages, - "attachments" => $aAttachments, - "parameters" => $aParameters - + "storageLocation" => is_object($this->storageLocation) ? $this->storageLocation->getId() : null, + "category" => is_object($this->category) ? $this->category->getId() : null, + "partUnit" => is_object($this->partUnit) ? $this->getPartUnit()->getId() : null, + "manufacturers" => $this->serializeChildren($this->getManufacturers()), + "distributors" => $this->serializeChildren($this->getDistributors()), + "images" => $this->serializeChildren($this->getImages()), + "attachments" => $this->serializeChildren($this->getAttachments()), + "parameters" => $this->serializeChildren($this->getParameters()), + + // Additional things we serialize to make displaying stuff in the frontend easier + "categoryName" => is_object($this->category) ? $this->category->getName() : null, + "footprintName" => is_object($this->footprint) ? $this->footprint->getName() : null, + "storageLocationName" => is_object($this->storageLocation) ? $this->storageLocation->getName() : null ); } + + /** + * Deserializes the manufacturer + * @param array $parameters The array with the parameters to set + */ + public function deserialize (array $parameters) { + foreach ($parameters as $key => $value) { + switch ($key) { + case "name": + $this->setName($value); + break; + case "comment": + $this->setComment($value); + break; + case "footprint": + $footprint = Footprint::loadById($value); + $this->setFootprint($footprint); + break; + case "minStockLevel": + $this->setMinStockLevel($value); + break; + case "partUnit": + $partUnit = PartUnit::loadById($value); + $this->setPartUnit($partUnit); + break; + case "category": + $category = PartCategory::loadById($value); + $this->setCategory($category); + break; + case "storageLocation": + $storageLocation = StorageLocation::loadById($value); + $this->setStorageLocation($storageLocation); + break; + case "manufacturers": + $this->deserializeChildren($value, $this->getManufacturers(), "de\RaumZeitLabor\PartKeepr\Part\PartManufacturer"); + foreach ($this->getManufacturers() as $manufacturer) { + $manufacturer->setPart($this); + } + break; + case "distributors": + $this->deserializeChildren($value, $this->getDistributors(), "de\RaumZeitLabor\PartKeepr\Part\PartDistributor"); + foreach ($this->getDistributors() as $distributor) { + $distributor->setPart($this); + } + break; + case "parameters": + $this->deserializeChildren($value, $this->getParameters(), "de\RaumZeitLabor\PartKeepr\PartParameter\PartParameter"); + foreach ($this->getParameters() as $parameter) { + $parameter->setPart($this); + } + break; + case "attachments": + $this->deserializeChildren($value, $this->getAttachments(), "de\RaumZeitLabor\PartKeepr\Part\PartAttachment"); + foreach ($this->getAttachments() as $attachment) { + $attachment->setPart($this); + } + break; + } + } + } } diff --git a/src/de/RaumZeitLabor/PartKeepr/Part/PartAttachment.php b/src/de/RaumZeitLabor/PartKeepr/Part/PartAttachment.php @@ -1,5 +1,7 @@ <?php namespace de\RaumZeitLabor\PartKeepr\Part; +use de\RaumZeitLabor\PartKeepr\Util\Deserializable; + use de\RaumZeitLabor\PartKeepr\Util\Serializable; declare(encoding = 'UTF-8'); @@ -10,14 +12,14 @@ use de\RaumZeitLabor\PartKeepr\UploadedFile\UploadedFile; * Holds a part attachment * @Entity **/ -class PartAttachment extends UploadedFile implements Serializable { +class PartAttachment extends UploadedFile implements Serializable, Deserializable { /** * The description of this attachment * @Column(type="text") * @var string */ private $description; - + /** * Creates a new part attachment */ @@ -47,7 +49,7 @@ class PartAttachment extends UploadedFile implements Serializable { public function getPart () { return $this->part; } - + /** * Sets the description for this attachment * @param string $description The attachment description @@ -55,7 +57,7 @@ class PartAttachment extends UploadedFile implements Serializable { public function setDescription ($description) { $this->description = $description; } - + /** * Returns the description for this attachment * @return string The description @@ -79,4 +81,24 @@ class PartAttachment extends UploadedFile implements Serializable { "size" => $this->getSize(), "description" => $this->getDescription()); } + + /** + * Deserializes the footprint attachment + * @param array $parameters The array with the parameters to set + */ + public function deserialize (array $parameters) { + if (array_key_exists("id", $parameters)) { + if (substr($parameters["id"], 0, 4) === "TMP:") { + $this->replaceFromTemporaryFile($parameters["id"]); + } + } + + foreach ($parameters as $key => $value) { + switch ($key) { + case "description": + $this->setDescription($value); + break; + } + } + } } \ No newline at end of file diff --git a/src/de/RaumZeitLabor/PartKeepr/Part/PartDistributor.php b/src/de/RaumZeitLabor/PartKeepr/Part/PartDistributor.php @@ -1,5 +1,7 @@ <?php namespace de\RaumZeitLabor\PartKeepr\Part; +use de\RaumZeitLabor\PartKeepr\Util\Deserializable; + use de\RaumZeitLabor\PartKeepr\Util\Serializable; use de\RaumZeitLabor\PartKeepr\Util\BaseEntity; @@ -12,7 +14,7 @@ use de\RaumZeitLabor\PartKeepr\PartKeepr, /** * This class represents the link between a part and a distributor. * @Entity **/ -class PartDistributor extends BaseEntity implements Serializable { +class PartDistributor extends BaseEntity implements Serializable, Deserializable { /** * @ManyToOne(targetEntity="de\RaumZeitLabor\PartKeepr\Part\Part") */ @@ -45,9 +47,7 @@ class PartDistributor extends BaseEntity implements Serializable { * @param Part $part The part * @param Distributor $distributor The distributor */ - public function __construct (Part $part, Distributor $distributor) { - $this->setPart($part); - $this->setDistributor($distributor); + public function __construct () { $this->setPackagingUnit(1); } @@ -144,4 +144,25 @@ class PartDistributor extends BaseEntity implements Serializable { "part_name" => $this->getPart()->getName(), "packagingUnit" => $this->getPackagingUnit()); } + + /** + * Deserializes the part manufacturer + * @param array $parameters The array with the parameters to set + */ + public function deserialize (array $parameters) { + foreach ($parameters as $key => $value) { + switch ($key) { + case "distributor_id": + $distributor = Distributor::loadById($value); + $this->setDistributor($distributor); + break; + case "orderNumber": + $this->setOrderNumber($value); + break; + case "packagingUnit": + $this->setPackagingUnit($value); + break; + } + } + } } \ No newline at end of file diff --git a/src/de/RaumZeitLabor/PartKeepr/Part/PartManager.php b/src/de/RaumZeitLabor/PartKeepr/Part/PartManager.php @@ -108,7 +108,7 @@ class PartManager extends Singleton { - $qb->select("p.averagePrice, p.name, p.id, p.stockLevel, p.minStockLevel, p.comment, st.id AS storageLocation_id, st.name as storageLocationName, f.id AS footprint_id, f.name AS footprintName, c.id AS category_id, c.name AS categoryName, pu.name AS partUnit, pu.is_default AS partUnitDefault"); + $qb->select("p.averagePrice, p.name, p.id, p.stockLevel, p.minStockLevel, p.comment, st.id AS storageLocation_id, st.name as storageLocationName, f.id AS footprint_id, f.name AS footprintName, c.id AS category_id, c.name AS categoryName, pu.id AS partUnit, pu.name AS partUnitName, pu.is_default AS partUnitDefault"); $qb->orderBy($orderBy, $dir); if ($limit > -1) { $qb->setMaxResults($limit); diff --git a/src/de/RaumZeitLabor/PartKeepr/Part/PartManufacturer.php b/src/de/RaumZeitLabor/PartKeepr/Part/PartManufacturer.php @@ -1,5 +1,7 @@ <?php namespace de\RaumZeitLabor\PartKeepr\Part; +use de\RaumZeitLabor\PartKeepr\Util\Deserializable; + use de\RaumZeitLabor\PartKeepr\Util\Serializable; use de\RaumZeitLabor\PartKeepr\Util\BaseEntity; @@ -10,7 +12,7 @@ use de\RaumZeitLabor\PartKeepr\PartKeepr, de\RaumZeitLabor\PartKeepr\Manufacturer\Manufacturer; /** @Entity **/ -class PartManufacturer extends BaseEntity implements Serializable { +class PartManufacturer extends BaseEntity implements Serializable, Deserializable { /** * @ManyToOne(targetEntity="de\RaumZeitLabor\PartKeepr\Part\Part") */ @@ -28,11 +30,6 @@ class PartManufacturer extends BaseEntity implements Serializable { */ private $partNumber; - public function __construct (Part $part, Manufacturer $manufacturer) { - $this->setPart($part); - $this->setManufacturer($manufacturer); - } - public function setPart (Part $part) { $this->part = $part; } @@ -71,5 +68,21 @@ class PartManufacturer extends BaseEntity implements Serializable { "part_name" => $this->getPart()->getName()); } - + /** + * Deserializes the part manufacturer + * @param array $parameters The array with the parameters to set + */ + public function deserialize (array $parameters) { + foreach ($parameters as $key => $value) { + switch ($key) { + case "manufacturer_id": + $manufacturer = Manufacturer::loadById($value); + $this->setManufacturer($manufacturer); + break; + case "partNumber": + $this->setPartNumber($value); + break; + } + } + } } \ No newline at end of file diff --git a/src/de/RaumZeitLabor/PartKeepr/Part/PartService.php b/src/de/RaumZeitLabor/PartKeepr/Part/PartService.php @@ -14,7 +14,7 @@ use de\RaumZeitLabor\PartKeepr\Part\PartManager, class PartService extends Service implements RestfulService { public function get () { if ($this->hasParameter("id")) { - return PartManager::getInstance()->getPart($this->getParameter("id"))->serialize(); + return array("data" => PartManager::getInstance()->getPart($this->getParameter("id"))->serialize()); } else { if ($this->hasParameter("sort")) { $tmp = json_decode($this->getParameter("sort"), true); @@ -39,14 +39,36 @@ class PartService extends Service implements RestfulService { } } + /** + * (non-PHPdoc) + * @see de\RaumZeitLabor\PartKeepr\Service.RestfulService::create() + */ public function create () { - throw new \Exception("Not yet implemented"); + $part = new Part(); + $part->deserialize($this->getParameters()); + + PartKeepr::getEM()->persist($part); + + PartKeepr::getEM()->flush(); + + return array("data" => $part->serialize()); } + /** + * (non-PHPdoc) + * @see de\RaumZeitLabor\PartKeepr\Service.RestfulService::update() + */ public function update () { - throw new \Exception("Not yet implemented"); + $this->requireParameter("id"); + $part = Part::loadById($this->getParameter("id")); + $part->deserialize($this->getParameters()); + + PartKeepr::getEM()->flush(); + + return array("data" => $part->serialize()); } + public function destroy () { throw new \Exception("Not yet implemented"); } @@ -80,19 +102,6 @@ class PartService extends Service implements RestfulService { PartKeepr::getEM()->flush(); } - // Old stuff below - public function getParts () { - $aParameters = array( - "start" => $this->getParameter("start", 0), - "limit" => $this->getParameter("limit", 15), - "sort" => $this->getParameter("sort", "name"), - "dir" => $this->getParameter("dir", "asc"), - "filter" => $this->getParameter("filter", ""), - "category" => $this->getParameter("category", 0), - "stockmode" => $this->getParameter("stockmode", "all") - ); - return PartManager::getInstance()->getParts($aParameters); - } public function addStock () { $part = PartManager::getInstance()->getPart($this->getParameter("part")); @@ -114,67 +123,9 @@ class PartService extends Service implements RestfulService { PartKeepr::getEM()->flush(); - return true; + return array("data" => $part->serialize()); } - public function addOrUpdatePart () { - $aParameters = array(); - - $aParameters["part"] = $this->getParameter("part", null); - - if ($this->hasParameter("name")) { - $aParameters["name"] = $this->getParameter("name"); - } - - if ($this->hasParameter("minStockLevel")) { - $aParameters["minstock"] = $this->getParameter("minStockLevel"); - } - - if ($this->hasParameter("storageLocation_id")) { - $aParameters["storagelocation"] = $this->getParameter("storageLocation_id"); - } - - if ($this->hasParameter("category_id")) { - $aParameters["category"] = $this->getParameter("category_id"); - } - - if ($this->hasParameter("footprint_id")) { - $aParameters["footprint"] = $this->getParameter("footprint_id"); - } - - if ($this->hasParameter("comment")) { - $aParameters["comment"] = $this->getParameter("comment"); - } - - if ($this->hasParameter("quantity")) { - $aParameters["quantity"] = $this->getParameter("quantity"); - } - - if ($this->hasParameter("distributorChanges")) { - $aParameters["distributorChanges"] = $this->getParameter("distributorChanges"); - } - - if ($this->hasParameter("manufacturerChanges")) { - $aParameters["manufacturerChanges"] = $this->getParameter("manufacturerChanges"); - } - - if ($this->hasParameter("parameterChanges")) { - $aParameters["parameterChanges"] = $this->getParameter("parameterChanges"); - } - - if ($this->hasParameter("attachmentChanges")) { - $aParameters["attachmentChanges"] = $this->getParameter("attachmentChanges"); - } - - if ($this->hasParameter("partUnit_id")) { - $aParameters["partUnit"] = $this->getParameter("partUnit_id"); - } - - PartManager::getInstance()->addOrUpdatePart($aParameters); - - return true; - } - public function deleteStock () { $part = PartManager::getInstance()->getPart($this->getParameter("part")); @@ -189,20 +140,10 @@ class PartService extends Service implements RestfulService { PartKeepr::getEM()->flush(); - return true; - } - - public function getPart () { - $part = PartManager::getInstance()->getPart($this->getParameter("part")); - - return $this->serializePart($part); + return array("data" => $part->serialize()); } public function deletePart () { PartManager::getInstance()->deletePart($this->getParameter("part")); } - - private function serializePart ($part) { - return $part->serialize(); - } } \ No newline at end of file diff --git a/src/de/RaumZeitLabor/PartKeepr/PartParameter/PartParameter.php b/src/de/RaumZeitLabor/PartKeepr/PartParameter/PartParameter.php @@ -3,16 +3,16 @@ namespace de\RaumZeitLabor\PartKeepr\PartParameter; declare(encoding = 'UTF-8'); use de\RaumZeitLabor\PartKeepr\PartKeepr, - de\RaumZeitLabor\PartKeepr\Util\Exceptions\OutOfRangeException, - de\RaumZeitLabor\PartKeepr\Unit\Unit, - de\RaumZeitLabor\PartKeepr\Part\Part, - de\RaumZeitLabor\PartKeepr\SiPrefix\SiPrefix; +de\RaumZeitLabor\PartKeepr\Util\Exceptions\OutOfRangeException, +de\RaumZeitLabor\PartKeepr\Unit\Unit, +de\RaumZeitLabor\PartKeepr\Part\Part, +de\RaumZeitLabor\PartKeepr\SiPrefix\SiPrefix; /** * This object represents a parameter. Each parameter can have an unit (defined by the class "Unit") associated with - * a numeric value. - * + * a numeric value. + * * @Entity @HasLifecycleCallbacks **/ class PartParameter { @@ -22,60 +22,60 @@ class PartParameter { * @var integer */ private $id; - + /** * @ManyToOne(targetEntity="de\RaumZeitLabor\PartKeepr\Part\Part") * The part this parameter is bound to * @var Part */ private $part; - + /** * The name of the parameter (e.g. Resistance, Voltage) * @Column(type="string") * @var string */ private $name; - + /** * A description for this parameter * @Column(type="string") * @var string */ private $description; - + /** * The unit for this type. May be null. - * + * * @ManyToOne(targetEntity="de\RaumZeitLabor\PartKeepr\Unit\Unit") * @var Unit */ private $unit; - + /** * The value of the unit. Together with the prefix, it becomes the actual value. - * + * * Example: If you have 10µ, the value field will contain "10", the prefix object is linked to the SiPrefix * representing "µ" and the rawValue field will contain 0.000001 * @Column(type="float") * @var float */ private $value; - + /** * The SiPrefix of the unit * @ManyToOne(targetEntity="de\RaumZeitLabor\PartKeepr\SiPrefix\SiPrefix") * @var object */ private $siPrefix; - + /** * The raw value of the unit. * @Column(type="float") * @var float */ private $rawValue; - + /** * Sets the name for this parameter * @param string $name The name @@ -83,7 +83,7 @@ class PartParameter { public function setName ($name) { $this->name = $name; } - + /** * Returns the name for this parameter * @return string The name for this parameter @@ -91,7 +91,7 @@ class PartParameter { public function getName () { return $this->name; } - + /** * Sets the description for this parameter * @param string $description The description @@ -99,7 +99,7 @@ class PartParameter { public function setDescription ($description) { $this->description = $description; } - + /** * Returns the description * @return string The description @@ -107,7 +107,7 @@ class PartParameter { public function getDescription () { return $this->description; } - + /** * Sets the unit * @param Unit $unit The unit to set @@ -115,15 +115,15 @@ class PartParameter { public function setUnit (Unit $unit = null) { $this->unit = $unit; } - + /** * Returns the unit * @return Unit the unit */ public function getUnit () { - return $this->unit; + return $this->unit; } - + /** * Sets the part * @param Part $part The part to set @@ -131,15 +131,15 @@ class PartParameter { public function setPart (Part $part) { $this->part = $part; } - + /** * Returns the part * @return Part the part */ public function getPart () { - return $this->part; + return $this->part; } - + /** * Sets the value * @param float $value The value to set @@ -149,7 +149,7 @@ class PartParameter { $this->recalculateRawValue(); } - + /** * Returns the value * @return float The value @@ -157,14 +157,14 @@ class PartParameter { public function getValue () { return $this->value; } - + /** * Sets the si prefix for this parameter * @param SiPrefix $prefix The prefix to set, or null */ public function setSiPrefix (SiPrefix $prefix = null) { $this->siPrefix = $prefix; - + $this->recalculateRawValue(); } @@ -175,7 +175,7 @@ class PartParameter { public function getSiPrefix () { return $this->siPrefix; } - + /** * Returns the ID for this object. * @param none @@ -183,18 +183,18 @@ class PartParameter { */ public function getId () { return $this->id; - } - + } + private function recalculateRawValue () { if (is_object($this->getSiPrefix())) { $power = $this->getSiPrefix()->getPower(); } else { $power = 0; } - + $this->rawValue = $this->getValue() * pow(10, $power); } - + /** * Returns the data of this object in a serialized form. * @return array The result array @@ -208,14 +208,41 @@ class PartParameter { "part_id" => $this->getPart()->getId(), "siprefix_id" => is_object($this->getSiPrefix()) ? $this->getSiPrefix()->getId() : null, "prefixedValue" => array( - /* We duplicate most data because of strange ExtJS stuff... */ + /* We duplicate most data because of strange ExtJS stuff... */ "value" => $this->getValue(), "power" => is_object($this->getSiPrefix()) ? $this->getSiPrefix()->getPower() : 0, "symbol" => is_object($this->getSiPrefix()) ? $this->getSiPrefix()->getSymbol() : "", "siprefix_id" => is_object($this->getSiPrefix()) ? $this->getSiPrefix()->getId() : null - ), + ), "unit_id" => is_object($this->getUnit()) ? $this->getUnit()->getId() : null ); } + + /** + * Deserializes the part parameter + * @param array $parameters The array with the parameters to set + */ + public function deserialize (array $parameters) { + foreach ($parameters as $key => $value) { + switch ($key) { + case "name": + $this->setName($value); + break; + case "description": + $this->setDescription($value); + break; + case "value": + $this->setValue($value); + break; + case "siprefix_id": + $prefix = SiPrefix::loadById($value); + $this->setSiPrefix($prefix); + break; + case "unit_id": + $unit = Unit::loadById($value); + $this->setUnit($unit); + break; + } + } + } } - - \ No newline at end of file