partkeepr

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

commit 36a6aac0a0509f9338a08cf3080ebf3867abb257
parent 422239a7e56f9ec64b1c6556ebf03c6b0ad3c92b
Author: Felicitus <felicitus@felicitus.org>
Date:   Sun, 25 Dec 2011 16:39:43 +0100

Added project reports

Diffstat:
Asrc/backend/de/RaumZeitLabor/PartKeepr/ProjectReport/ProjectReportService.php | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/frontend/js/Components/MenuBar.js | 14++++++++++++++
Asrc/frontend/js/Components/Project/ProjectReport.js | 170+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/frontend/js/Components/Widgets/DistributorComboBox.js | 20+++++++++++++++++++-
Asrc/frontend/js/Models/ProjectReport.js | 18++++++++++++++++++
5 files changed, 273 insertions(+), 1 deletion(-)

diff --git a/src/backend/de/RaumZeitLabor/PartKeepr/ProjectReport/ProjectReportService.php b/src/backend/de/RaumZeitLabor/PartKeepr/ProjectReport/ProjectReportService.php @@ -0,0 +1,51 @@ +<?php +namespace de\RaumZeitLabor\PartKeepr\ProjectReport; +use de\RaumZeitLabor\PartKeepr\Service\RestfulService; + +declare(encoding = 'UTF-8'); + +use de\RaumZeitLabor\PartKeepr\Service\Service; +use de\RaumZeitLabor\PartKeepr\Project\ProjectManager, + de\RaumZeitLabor\PartKeepr\PartKeepr, + de\RaumZeitLabor\PartKeepr\Part\Part, + de\RaumZeitLabor\PartKeepr\Manager\ManagerFilter; + +class ProjectReportService extends Service implements RestfulService { + /** + * (non-PHPdoc) + * @see de\RaumZeitLabor\PartKeepr\Service.RestfulService::get() + */ + public function get () { + $reportIds = explode(",",$this->getParameter("reports")); + + $dql = "SELECT SUM(pp.quantity) AS quantity, p.id AS part_id, st.name AS storageLocation_name, p.stockLevel "; + $dql .= "AS stockLevel FROM de\RaumZeitLabor\PartKeepr\Project\ProjectPart pp JOIN pp.part p JOIN "; + $dql .= "p.storageLocation st JOIN pp.project pr WHERE pr.id IN (:projects) GROUP BY pp.part"; + + $query = PartKeepr::getEM()->createQuery($dql); + $query->setParameter("projects", $reportIds); + + $aFinalResult = array(); + foreach ($query->getResult() as $record) { + $missing = $record["quantity"] - $record["stockLevel"]; + + if ($missing < 0) { $missing = 0; } + + $aFinalResult[] = array( + "quantity" => $record["quantity"], + "available" => $record["stockLevel"], + "missing" => $missing, + "part" => array("response" => array("totalCount" => 1, "data" => Part::loadById($record["part_id"])->serialize())), + "storageLocation_name" => $record["storageLocation_name"], + "sum_order" => 0 + ); + } + return array("data" => $aFinalResult); + } + + public function create () {} + + public function update () {} + + public function destroy () {} +}+ \ No newline at end of file diff --git a/src/frontend/js/Components/MenuBar.js b/src/frontend/js/Components/MenuBar.js @@ -62,6 +62,10 @@ Ext.define('PartKeepr.MenuBar', { text: i18n("System Information"), handler: this.showSystemInformation, icon: 'resources/fugue-icons/icons/system-monitor.png' + },{ + text: i18n("Project Reports"), + handler: this.showProjectReports, + icon: 'resources/fugue-icons/icons/drill.png' } ] }); @@ -229,6 +233,16 @@ Ext.define('PartKeepr.MenuBar', { PartKeepr.getApplication().addItem(j); j.show(); }, + showProjectReports: function () { + var j = Ext.create("PartKeepr.ProjectReportView", { + title: i18n("Project Reports"), + iconCls: 'icon-drill', + closable: true + }); + + PartKeepr.getApplication().addItem(j); + j.show(); + }, displayComponent: function (component) { var j = Ext.create(component.type, { title: component.title, diff --git a/src/frontend/js/Components/Project/ProjectReport.js b/src/frontend/js/Components/Project/ProjectReport.js @@ -0,0 +1,169 @@ +/** + * Represents the project report view + */ +Ext.define('PartKeepr.ProjectReportView', { + extend: 'Ext.panel.Panel', + alias: 'widget.ProjectReportView', + + bodyStyle: 'background:#DBDBDB;padding: 10px;', + border: false, + layout: { + type: 'vbox', + align : 'stretch', + pack : 'start' + }, + initComponent: function () { + + this.createStores(); + + this.reportList = Ext.create("Ext.grid.Panel", { + title: i18n("Choose Projects to create a report for"), + selModel: { + + mode: 'MULTI' + }, + selType: 'checkboxmodel', + flex: 1, + columns: [{ + header: i18n("Project Name"), dataIndex: 'name', + flex: 1 + }], + store: this.store + }); + + this.editing = Ext.create('Ext.grid.plugin.CellEditing', { + clicksToEdit: 1 + }); + + this.reportResult = Ext.create("Ext.grid.Panel", { + title: i18n("Project Report"), + flex: 1, + features: [{ + ftype: 'summary' + }], + columns: [{ + header: i18n("Quantity"), dataIndex: 'quantity', + width: 50 + },{ + header: i18n("Part"), + renderer: function (val, p, rec) { + return rec.part().getAt(0).get("name"); + }, + flex: 1 + },{ + header: i18n("Storage Location"), dataIndex: 'storageLocation_name', + width: 100 + },{ + header: i18n("Available"), dataIndex: 'available', + width: 75 + },{ + header: i18n("Missing"), dataIndex: 'missing', + width: 75 + },{ + header: i18n("Distributor"), dataIndex: 'distributor_id', + renderer: function (val,p,rec) { + return rec.get("distributor_name"); + }, + flex: 1, + editor: { + xtype: 'DistributorComboBox', + triggerAction: 'query', + ignoreQuery: true, + forceSelection: true, + editable: false + } + },{ + header: i18n("Price per Item"), dataIndex: 'price', + width: 100 + },{ + header: i18n("Sum"), + renderer: function (val,p,rec) { + if (!isNaN(rec.get("price"))) { + return rec.get("quantity") * rec.get("price"); + } + + return 0; + + }, + width: 100 + },{ + header: i18n("Sum (Order)"), + dataIndex: 'sum_order', + summaryType: 'sum', + width: 100 + }], + store: this.projectReportStore, + plugins: [ this.editing ] + }); + + this.reportResult.on("beforeedit", this.onBeforeEdit, this); + this.reportResult.on("edit", this.onEdit, this); + this.items = [ this.reportList, { xtype: 'button', text: i18n("Create Report"), margin: { top: 5, bottom: 5 }, listeners: { click: this.onCreateReportClick, scope: this }}, this.reportResult ]; + + + + this.callParent(); + }, + onBeforeEdit: function (e) { + + var distributors = e.record.part().getAt(0).distributors(); + + var filterIds = new Array(); + for (var i=0;i<distributors.count();i++) { + filterIds.push(distributors.getAt(i).get("distributor_id")); + } + + e.column.getEditor().store.clearFilter(); + e.column.getEditor().store.filter({filterFn: function(item) { + for (var i=0;i<filterIds.length;i++) { + if (item.get("id") == filterIds[i]) { + return true; + } + } + return false; + }}); + }, + onEdit: function (editor, e) { + if (e.field == "distributor_id") { + var distributors = e.record.part().getAt(0).distributors(); + + for (var i = 0; i < distributors.count(); i++) { + if (distributors.getAt(i).get("distributor_id") == e.value) { + e.record.set("distributor_name", distributors.getAt(i).get("distributor_name")); + e.record.set("price", distributors.getAt(i).get("price")); + + e.record.set("sum_order", e.record.get("missing") * e.record.get("price")); + } + } + } + + this.reportResult.getView().refresh(true); + + }, + onCreateReportClick: function () { + selection = this.reportList.getSelectionModel().getSelection(); + + var params = new Array(); + + for (var i=0;i<selection.length;i++) { + params.push(selection[i].get("id")); + } + + this.projectReportStore.getProxy().extraParams.reports = params.join(","); + this.projectReportStore.load(); + }, + createStores: function () { + var config = { + autoLoad: true, + model: "PartKeepr.Project", + pageSize: -1 + }; + + this.store = Ext.create('Ext.data.Store', config); + + this.projectReportStore = Ext.create('Ext.data.Store', { + model: "PartKeepr.ProjectReport", + pageSize: -1 + }); + } +});+ \ No newline at end of file diff --git a/src/frontend/js/Components/Widgets/DistributorComboBox.js b/src/frontend/js/Components/Widgets/DistributorComboBox.js @@ -7,7 +7,8 @@ Ext.define("PartKeepr.DistributorComboBox",{ queryMode: 'local', triggerAction: 'all', forceSelection: true, - editable: true, + editable: true, + ignoreQuery: false, initComponent: function () { this.store = PartKeepr.getApplication().getDistributorStore(); @@ -22,6 +23,23 @@ Ext.define("PartKeepr.DistributorComboBox",{ }, this); this.callParent(); + }, + onTriggerClick: function() { + if (!this.ignoreQuery) { + this.callParent(); + } else { + var me = this; + if (!me.readOnly && !me.disabled) { + if (me.isExpanded) { + me.collapse(); + } else { + me.onFocus({}); + me.expand(); + } + me.inputEl.focus(); + } + } + } }); diff --git a/src/frontend/js/Models/ProjectReport.js b/src/frontend/js/Models/ProjectReport.js @@ -0,0 +1,17 @@ +/** + * Represents a project report + */ +Ext.define("PartKeepr.ProjectReport", { + extend: "Ext.data.Model", + fields: [ + { name: 'quantity', type: 'int'}, + { name: 'storageLocation_name', type: 'string'}, + { name: 'available', type: 'int'}, + { name: 'missing', type: 'int'}, + { name: 'sum_order', type: 'float'} + ], + hasMany: [ + { model: 'PartKeepr.Part', name: 'part'} + ], + proxy: PartKeepr.getRESTProxy("ProjectReport") +});+ \ No newline at end of file