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:
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