partkeepr

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

commit ec3625c0498d078e9398b9339848e0a1f5124f72
parent cef890efcdaf12672cea4dd1e548596f1dc4c199
Author: Timo A. Hummel <timo@netraver.de>
Date:   Wed,  8 Jun 2011 23:47:26 +0200

Added stock history display

Diffstat:
Mfrontend/index.php | 2++
Afrontend/js/Components/Part/PartStockHistory.js | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mfrontend/js/Components/Part/PartsManager.js | 17++++++++++++++---
Afrontend/js/Models/StockEntry.js | 13+++++++++++++
Msrc/de/RaumZeitLabor/PartDB2/Stock/StockEntry.php | 40++++++++++++++++++++++++++++++++++++++++
Asrc/de/RaumZeitLabor/PartDB2/Stock/StockService.php | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 179 insertions(+), 3 deletions(-)

diff --git a/frontend/index.php b/frontend/index.php @@ -57,6 +57,7 @@ <script type="text/javascript" src="js/Models/Part.js"></script> <script type="text/javascript" src="js/Models/PartUnit.js"></script> <script type="text/javascript" src="js/Models/PartDistributor.js"></script> + <script type="text/javascript" src="js/Models/StockEntry.js"></script> <script type="text/javascript" src="js/Models/PartManufacturer.js"></script> <script type="text/javascript" src="js/Models/Message.js"></script> @@ -114,6 +115,7 @@ <script type="text/javascript" src="js/Components/Part/PartEditor.js"></script> <script type="text/javascript" src="js/Components/Part/PartDisplay.js"></script> <script type="text/javascript" src="js/Components/Part/PartStockWindow.js"></script> + <script type="text/javascript" src="js/Components/Part/PartStockHistory.js"></script> </head> <body> diff --git a/frontend/js/Components/Part/PartStockHistory.js b/frontend/js/Components/Part/PartStockHistory.js @@ -0,0 +1,57 @@ +Ext.define('PartDB2.PartStockHistory', { + extend: 'Ext.grid.Panel', + alias: 'widget.PartStockHistory', + + columns: [ + { + header: "", + xtype:'actioncolumn', + dataIndex: 'direction', + renderer: function (val) { + if (val == "out") + { + return '<img title="'+i18n("Parts removed")+'" src="resources/silkicons/brick_delete.png"/>'; + } else { + return '<img title="'+i18n("Parts added")+'" src="resources/silkicons/brick_add.png"/>'; + } + }, + width: 20 + }, + {header: i18n("User"), dataIndex: 'username', width: 80 }, + {header: i18n("Amount"), dataIndex: 'amount', width: 50}, + {header: i18n("Date"), dataIndex: 'datetime', width: 120}, + { + header: i18n("Price"), + dataIndex: 'price', + width: 60, + renderer: function (val, p, rec) { + if (rec.get("dir") == "out") { + return "-"; + } else { + return val; + } + } + } + ], + model: 'PartDB2.StockEntry', + initComponent: function () { + var config = { + autoLoad: false, + autoSync: false, // Do not change. If true, new (empty) records would be immediately commited to the database. + remoteFilter: false, + remoteSort: false, + model: 'StockEntry', + pageSize: -1}; + + this.store = Ext.create('Ext.data.Store', config); + + this.on("activate", this.onActivate, this); + this.callParent(); + }, + onActivate: function () { + var proxy = this.store.getProxy(); + proxy.extraParams.item = this.part; + + this.store.load(); + } +});+ \ No newline at end of file diff --git a/frontend/js/Components/Part/PartsManager.js b/frontend/js/Components/Part/PartsManager.js @@ -23,7 +23,7 @@ Ext.define('PartDB2.PartManager', { } }, this)); - this.detail = Ext.create("PartDB2.PartDisplay", { hidden: true, region: 'east', split: true, width: 300}); + this.detail = Ext.create("PartDB2.PartDisplay", { title: i18n("Part Details") }); this.detail.on("editPart", this.onEditPart, this); this.grid = Ext.create("PartDB2.PartsGrid", { region: 'center', layout: 'fit', store: this.getStore()}); @@ -33,7 +33,16 @@ Ext.define('PartDB2.PartManager', { this.detail.on("partChanged", function () { this.grid.getStore().load(); }, this); - this.items = [ this.tree, this.grid, this.detail /*this.editor*/ ]; + this.stockLevel = Ext.create("PartDB2.PartStockHistory", { title: "Stock History"}); + + this.detailPanel = Ext.create("Ext.tab.Panel", { + hidden: true, + region: 'east', + split: true, + width: 300, + items: [ this.detail, this.stockLevel ] + }); + this.items = [ this.tree, this.grid, this.detailPanel /*this.editor*/ ]; this.callParent(); }, @@ -80,8 +89,10 @@ Ext.define('PartDB2.PartManager', { j.show(); }, onItemSelect: function (r) { - this.detail.show(); + this.detailPanel.setActiveTab(this.detail); + this.detailPanel.show(); this.detail.setValues(r); + this.stockLevel.part = r.get("id"); }, loadPart: function (id, handler) { var call = new PartDB2.ServiceCall( diff --git a/frontend/js/Models/StockEntry.js b/frontend/js/Models/StockEntry.js @@ -0,0 +1,12 @@ +PartDB2.StockEntry = Ext.define("StockEntry", { + extend: "Ext.data.Model", + fields: [ + { id: 'id', name: 'id', type: 'int' }, + { name: 'username', type: 'string'}, + { name: 'datetime', type: 'datetime'}, + { name: 'amount', type: 'int'}, + { name: 'direction', type: 'string'}, + { name: 'price', type: 'float'} + ], + proxy: PartDB2.getRESTProxy("Stock") +});+ \ No newline at end of file diff --git a/src/de/RaumZeitLabor/PartDB2/Stock/StockEntry.php b/src/de/RaumZeitLabor/PartDB2/Stock/StockEntry.php @@ -36,6 +36,12 @@ class StockEntry { * @var float */ private $price; + + /** + * @Column(type="datetime") + * @var DateTime + */ + private $dateTime; /** * Creates a new stock entry. A stock entry tracks how many parts @@ -50,6 +56,24 @@ class StockEntry { $this->setPart($part); $this->setStockLevel($stockLevel); $this->setUser($user); + $this->setDateTime(new \DateTime()); + } + + + /** + * Sets the date+time + * @param \DateTime $dateTime The date+time + */ + private function setDateTime (\DateTime $dateTime) { + $this->dateTime = $dateTime; + } + + /** + * Returns the date+time when the record was created. + * @return \DateTime The date+time when the record was created + */ + public function getDateTime () { + return $this->dateTime; } /** @@ -106,6 +130,22 @@ class StockEntry { } /** + * Returns the user for this entry + * @return User the user + */ + public function getUser () { + return $this->user; + } + + /** + * Returns the ID for this entity. + * @return int The ID + */ + public function getId () { + return $this->id; + } + + /** * If the stock level is negative, we can't have a price. * @PrePersist */ diff --git a/src/de/RaumZeitLabor/PartDB2/Stock/StockService.php b/src/de/RaumZeitLabor/PartDB2/Stock/StockService.php @@ -0,0 +1,51 @@ +<?php +namespace de\raumzeitlabor\PartDB2\Stock; + +declare(encoding = 'UTF-8'); + +use de\RaumZeitLabor\PartDB2\Stock\StockEntry, + de\RaumZeitLabor\PartDB2\PartDB2, + de\RaumZeitLabor\PartDB2\Service\RestfulService, + de\RaumZeitLabor\PartDB2\Service\Service;; + + +class StockService extends Service implements RestfulService { + public function get () { + $qb = PartDB2::getEM()->createQueryBuilder(); + + $qb->select("se")->from("de\RaumZeitLabor\PartDB2\Stock\StockEntry","se") + ->where("se.part = :part") + ->orderBy("se.dateTime", "DESC") + ->setParameter("part", $this->getParameter("item")); + + $results = $qb->getQuery()->getResult(); + + $aData = array(); + + foreach ($results as $result) { + $aData[] = array( + "username" => is_object($result->getUser()) ? $result->getUser()->getUsername() : PartDB2::i18n("Unknown User"), + "amount" => abs($result->getStockLevel()), + "datetime" => $result->getDateTime()->format("Y-m-d H:i:s"), + "id" => $result->getId(), + "direction" => ($result->getStockLevel() < 0) ? "out" : "in", + "price" => $result->getPrice() + ); + } + + + return array("data" => $aData); + } + + public function create () { + throw new \Exception("Not yet implemented"); + } + + public function update () { + throw new \Exception("Not yet implemented"); + } + + public function destroy () { + throw new \Exception("Not yet implemented"); + } +}+ \ No newline at end of file