partkeepr

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

commit 9ba816194946a4a99e4d569dd73eb44ec28d8650
parent 21fecf7b66119f8d0fccc8d0e6bab4d4e2c88832
Author: Timo A. Hummel <felicitus@felicitus.org>
Date:   Mon, 11 Jan 2016 16:28:46 +0100

Merge pull request #557 from partkeepr/PartKeepr-551

Fix for #551
Diffstat:
MCHANGELOG.md | 25+++++++++++++++++++++++++
Mapp/config/config_partkeepr.yml | 12+++++++++---
Mdocumentation/internals/NEW-RELEASE | 2++
Asrc/PartKeepr/PartBundle/Action/PartPutAction.php | 83+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/PartKeepr/PartBundle/Listeners/StockLevelListener.php | 4+++-
Msrc/PartKeepr/PartBundle/Resources/config/actions.xml | 4++++
Asrc/PartKeepr/PartBundle/Tests/Issues/StockHistoryLostTest.php | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/PartKeepr/StockBundle/Entity/StockEntry.php | 2+-
Mweb/setup/js/PartKeeprSetup.js | 2+-
9 files changed, 201 insertions(+), 6 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -1,5 +1,30 @@ # Changelog +## PartKeepr 0.77 + +This is mainly a bugfix release. Noteworthy bugfixes: + +* The HTTP Status code is now shown in exception windows for easier debugging [#549](https://github.com/partkeepr/PartKeepr/issues/549) +* Obsolete database tables from 0.1.9 are now removed [#548](https://github.com/partkeepr/PartKeepr/issues/548) +* Fixed drag'n'drop of parts [#540](https://github.com/partkeepr/PartKeepr/issues/540) +* Initial stock level value is now correctly entered in the database [#534](https://github.com/partkeepr/PartKeepr/issues/534) +* The ubuntu font is now loaded via HTTPS [#520](https://github.com/partkeepr/PartKeepr/issues/520) +* Footprint images are now shown again [#518](https://github.com/partkeepr/PartKeepr/issues/518) + +For a mostly complete list of bugfixes, please refer to [GitHub](https://github.com/partkeepr/PartKeepr/issues?q=milestone%3A0.77+is%3Aclosed) + +## PartKeepr 0.76 + +Noteworthy new features and bugfixes: + +* It is now possible to search for a manufacturer's part number [#489](https://github.com/partkeepr/PartKeepr/issues/489) +* Re-added "used in projects", footprint, storage location and category name as in PartKeepr 0.1.9 [#514](https://github.com/partkeepr/PartKeepr/issues/514) +* Added APC cache support +* Setup now prompts for the authentication method to use +* Icons are now displayed properly again in Firefox [#481](https://github.com/partkeepr/PartKeepr/issues/481) + +For a mostly complete list of new features and bugfixes, please refer to [GitHub](https://github.com/partkeepr/PartKeepr/issues?q=milestone%3A0.76+is%3Aclosed) + ## PartKeepr 0.75 Noteworthy new features: diff --git a/app/config/config_partkeepr.yml b/app/config/config_partkeepr.yml @@ -283,11 +283,17 @@ services: factory: [ "@api.operation_factory", "createItemOperation" ] arguments: [ "@resource.part", "GET" ] - resource.part.item_operation.put: + resource.part.item_operation.custom_put: class: "Dunglas\ApiBundle\Api\Operation\Operation" public: false factory: [ "@api.operation_factory", "createItemOperation" ] - arguments: [ "@resource.part", "PUT" ] + arguments: + - "@resource.part" + - [ "PUT" ] + - "/parts/{id}" + - "partkeepr.part.put" + - "PartPut" + resource.part.item_operation.delete: class: "Dunglas\ApiBundle\Api\Operation\Operation" @@ -334,7 +340,7 @@ services: tags: [ { name: "api.resource" } ] calls: - method: "initItemOperations" - arguments: [ [ "@resource.part.item_operation.get", "@resource.part.item_operation.put", "@resource.part.item_operation.delete", "@resource.part.item_operation.add_stock", "@resource.part.item_operation.remove_stock", "@resource.part.item_operation.set_stock" ] ] + arguments: [ [ "@resource.part.item_operation.get", "@resource.part.item_operation.custom_put", "@resource.part.item_operation.delete", "@resource.part.item_operation.add_stock", "@resource.part.item_operation.remove_stock", "@resource.part.item_operation.set_stock" ] ] - method: "initCollectionOperations" arguments: [ [ "@resource.part.collection_operation.get", "@resource.part.collection_operation.custom_post" ] ] - method: "initFilters" diff --git a/documentation/internals/NEW-RELEASE b/documentation/internals/NEW-RELEASE @@ -2,6 +2,8 @@ The following steps describe how a new PartKeepr release is being built: * Check if any unit tests have failed +* Edit CHANGELOG.md within the repository + * Create a new GIT tag using: git tag -s <version> diff --git a/src/PartKeepr/PartBundle/Action/PartPutAction.php b/src/PartKeepr/PartBundle/Action/PartPutAction.php @@ -0,0 +1,83 @@ +<?php +namespace PartKeepr\PartBundle\Action; + + +use Dunglas\ApiBundle\Action\ActionUtilTrait; +use Dunglas\ApiBundle\Api\ResourceInterface; +use Dunglas\ApiBundle\Exception\RuntimeException; +use Dunglas\ApiBundle\Model\DataProviderInterface; +use PartKeepr\AuthBundle\Exceptions\UserLimitReachedException; +use PartKeepr\AuthBundle\Exceptions\UserProtectedException; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; +use Symfony\Component\Serializer\SerializerInterface; + +class PartPutAction +{ + use ActionUtilTrait; + + /** + * @var DataProviderInterface + */ + private $dataProvider; + + /** + * @var SerializerInterface + */ + private $serializer; + + public function __construct( + DataProviderInterface $dataProvider, + SerializerInterface $serializer + ) { + $this->dataProvider = $dataProvider; + $this->serializer = $serializer; + } + + /** + * Create a new item. + * + * @param Request $request + * @param string|int $id + * + * @return mixed + * + * @throws NotFoundHttpException + * @throws RuntimeException + * @throws UserProtectedException + * @throws UserLimitReachedException + */ + public function __invoke(Request $request, $id) + { + /** + * @var $resourceType ResourceInterface + */ + list($resourceType, $format) = $this->extractAttributes($request); + + /** + * Workaround to ensure stockLevels are not overwritten in a PUT request. + * @see https://github.com/partkeepr/PartKeepr/issues/551 + */ + $data = json_decode($request->getContent(), true); + + if (array_key_exists("stockLevels", $data)) { + unset($data["stockLevels"]); + } + + $requestData = json_encode($data); + + $data = $this->getItem($this->dataProvider, $resourceType, $id); + + $context = $resourceType->getDenormalizationContext(); + $context['object_to_populate'] = $data; + + $data = $this->serializer->deserialize( + $requestData, + $resourceType->getEntityClass(), + $format, + $context + ); + + return $data; + } +} diff --git a/src/PartKeepr/PartBundle/Listeners/StockLevelListener.php b/src/PartKeepr/PartBundle/Listeners/StockLevelListener.php @@ -37,7 +37,9 @@ class StockLevelListener extends ContainerAware } foreach ($parts as $part) { - $this->updateStockLevel($part, $eventArgs); + if ($part !== null) { + $this->updateStockLevel($part, $eventArgs); + } } } diff --git a/src/PartKeepr/PartBundle/Resources/config/actions.xml b/src/PartKeepr/PartBundle/Resources/config/actions.xml @@ -9,6 +9,10 @@ <argument type="service" id="api.serializer" /> <argument type="service" id="partkeepr.part_service" /> </service> + <service id="partkeepr.part.put" class="PartKeepr\PartBundle\Action\PartPutAction"> + <argument type="service" id="api.data_provider"/> + <argument type="service" id="api.serializer" /> + </service> <service id="partkeepr.part.add_stock" class="PartKeepr\PartBundle\Action\AddStockAction"> <argument type="service" id="api.data_provider"/> <argument type="service" id="partkeepr.userservice" /> diff --git a/src/PartKeepr/PartBundle/Tests/Issues/StockHistoryLostTest.php b/src/PartKeepr/PartBundle/Tests/Issues/StockHistoryLostTest.php @@ -0,0 +1,73 @@ +<?php +namespace PartKeepr\PartBundle\Tests\Issues; + +use Doctrine\Common\DataFixtures\ProxyReferenceRepository; +use PartKeepr\CoreBundle\Tests\WebTestCase; +use PartKeepr\PartBundle\Entity\Part; +use PartKeepr\StockBundle\Entity\StockEntry; + +/** + * Class StockHistoryLostTest + * + * Unit test against issue #551 (stock history gets removed after saving part) + */ +class StockHistoryLostTest extends WebTestCase +{ + /** + * @var ProxyReferenceRepository + */ + protected $fixtures; + + public function setUp() + { + $this->fixtures = $this->loadFixtures( + array( + 'PartKeepr\StorageLocationBundle\DataFixtures\CategoryDataLoader', + 'PartKeepr\StorageLocationBundle\DataFixtures\StorageLocationLoader', + 'PartKeepr\PartBundle\DataFixtures\CategoryDataLoader', + 'PartKeepr\PartBundle\DataFixtures\PartDataLoader', + 'PartKeepr\AuthBundle\DataFixtures\LoadUserData', + 'PartKeepr\ManufacturerBundle\Tests\DataFixtures\ManufacturerDataLoader', + 'PartKeepr\DistributorBundle\Tests\DataFixtures\DistributorDataLoader', + ) + )->getReferenceRepository(); + } + + public function testStockHistory () { + $client = static::makeClient(true); + + /** + * @var $part1 Part + */ + $part1 = $this->fixtures->getReference("part.1"); + + $stockLevel = new StockEntry(); + $stockLevel->setPart($part1); + $stockLevel->setStockLevel(5); + + $fosUser = $this->fixtures->getReference("user.admin"); + $userService = $this->getContainer()->get("partkeepr.userservice"); + $user = $userService->getProxyUser($fosUser->getUsername(), $userService->getBuiltinProvider(), true); + + $stockLevel->setUser($user); + $part1->addStockLevel($stockLevel); + + $this->getContainer()->get("doctrine.orm.default_entity_manager")->flush(); + + $iriCoverter = $this->getContainer()->get("api.iri_converter"); + $iri = $iriCoverter->getIriFromItem($part1); + + $client->request("GET", $iri); + + $response = $client->getResponse()->getContent(); + $responseObj = json_decode($response, true); + $responseObj["stockLevels"] = array(); + + $client->request("PUT", $iri, array(), array(), array(), json_encode($responseObj)); + + $this->assertEquals(200, $client->getResponse()->getStatusCode()); + + $this->getContainer()->get("doctrine.orm.default_entity_manager")->refresh($part1); + $this->assertEquals(1, count($part1->getStockLevels())); + } +} diff --git a/src/PartKeepr/StockBundle/Entity/StockEntry.php b/src/PartKeepr/StockBundle/Entity/StockEntry.php @@ -166,7 +166,7 @@ class StockEntry extends BaseEntity * * @param Part $part The part to set */ - public function setPart(Part $part) + public function setPart(Part $part = null) { $this->part = $part; } diff --git a/web/setup/js/PartKeeprSetup.js b/web/setup/js/PartKeeprSetup.js @@ -19,7 +19,7 @@ Ext.application({ database_name: "", database_user: "", database_password: "", - authentication_provider: "PartKeepr.Auth.WSSEAuthenticationProvider", + authentication_provider: "PartKeepr.Auth.HTTPBasicAuthenticationProvider", locale: "en" }, adminuser: {