<NME> product.js
<BEF> ADDFILE
<MSG> Merge pull request #21 from Bladrak/autoPriceUpdate

Auto price update
<DFF> @@ -0,0 +1,81 @@
+// This file is part of the Sonata package.
+// 
+// (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
+// 
+// For the full copyright and license information, please view the LICENSE
+// file that was distributed with this source code.
+
+var Sonata = Sonata || {};
+
+Sonata.Product = {
+    /**
+     * URLs to use when performing ajax operations
+     *
+     * @var Object
+     */
+    url: {
+        infoStockPrice: null
+    },
+
+    /**
+     * Object events sources & targets
+     *
+     * @var Object
+     */
+    targets: {
+        inputAddBasket:  null,
+        productPrice:    null,
+        submitBasketBtn: null,
+        addBasketError:  null
+    },
+    
+    init: function(options) {
+        options = options || [];
+        for (property in options) {
+            this[property] = options[property];
+        }
+
+        this.initAddBasket();
+    },
+    
+    initAddBasket: function() {
+        this.targets.inputAddBasket.change(jQuery.proxy(this.changeAddBasket, this));
+    },
+    
+    changeAddBasket: function(event) {
+        this.resetElements();
+        
+        var url = this.buildInfoStockPriceUrl(event.currentTarget.value);
+        jQuery.getJSON(url, jQuery.proxy(this.processAddBasketResults, this));
+    },
+    
+    resetElements: function() {
+        this.targets.addBasketError.css('display', 'none');
+        this.targets.submitBasketBtn.removeClass('disabled');
+        this.targets.submitBasketBtn.prop('disabled', false);
+    },
+    
+    processAddBasketResults: function(data) {
+        if (data.errors.stock) {
+            jQuery.proxy(this.addBasketAddErrors(data.errors), this);
+        }
+        jQuery.proxy(this.addBasketProcessPrice(data.price_text), this);
+    },
+    
+    buildInfoStockPriceUrl: function(quantity) {
+        return this.url.infoStockPrice.substr(0, this.url.infoStockPrice.length-1)+quantity;
+    },
+    
+    addBasketAddErrors: function(errors) {
+        this.targets.addBasketError.text(errors.stock);
+        this.targets.addBasketError.css('display', 'block');
+        this.targets.submitBasketBtn.addClass('disabled');
+        this.targets.submitBasketBtn.prop('disabled', true);
+    },
+    
+    addBasketProcessPrice: function(price) {
+        this.targets.productPrice.text(price);
+    }
+}
+
+

{'commit': 'diff --git a/src/Sonata/BasketBundle/Resources/views/Basket/add_product_form.html.twig b/src/Sonata/BasketBundle/Resources/views/Basket/add_product_form.html.twig\nindex 4414edff..99830c03 100644\n--- a/src/Sonata/BasketBundle/Resources/views/Basket/add_product_form.html.twig\n+++ b/src/Sonata/BasketBundle/Resources/views/Basket/add_product_form.html.twig\n@@ -19,7 +19,7 @@ file that was distributed with this source code.\n         </div>\n \n         <div class="control-group">\n-            <button type="submit" class="btn btn-small btn-primary">\n+            <button type="submit" class="btn btn-small btn-primary" id="sonata_add_basket_submit">\n                 <i class="icon-shopping-cart icon-white"></i>{% trans from \'SonataProductBundle\' %}sonata.product.btn_add_to_basket{% endtrans %}\n             </button>\n         </div>\ndiff --git a/src/Sonata/Component/Product/ProductProviderInterface.php b/src/Sonata/Component/Product/ProductProviderInterface.php\nindex 81226994..9fbf0acc 100644\n--- a/src/Sonata/Component/Product/ProductProviderInterface.php\n+++ b/src/Sonata/Component/Product/ProductProviderInterface.php\n@@ -114,10 +114,11 @@ interface ProductProviderInterface\n      *\n      * @param ProductInterface          $product\n      * @param CurrencyInterface|null    $currency\n+     * @param int                       $quantity Defaults to one\n      *\n      * @return float\n      */\n-    public function calculatePrice(ProductInterface $product, CurrencyInterface $currency = null);\n+    public function calculatePrice(ProductInterface $product, CurrencyInterface $currency, $quantity = 1);\n \n     /**\n      * Return true if the product can be added to the provided basket\n@@ -270,4 +271,12 @@ interface ProductProviderInterface\n      * @return null|ProductInterface\n      */\n     public function getCheapestEnabledVariation(ProductInterface $product);\n+\n+    /**\n+     * return the stock available for the current product\n+     *\n+     * @param  \\Sonata\\Component\\Product\\ProductInterface $product\n+     * @return int                                        the stock available\n+     */\n+    public function getStockAvailable(ProductInterface $product);\n }\ndiff --git a/src/Sonata/ProductBundle/Controller/ProductController.php b/src/Sonata/ProductBundle/Controller/ProductController.php\nindex 2ecfebdc..2c7503a9 100644\n--- a/src/Sonata/ProductBundle/Controller/ProductController.php\n+++ b/src/Sonata/ProductBundle/Controller/ProductController.php\n@@ -12,6 +12,8 @@\n namespace Sonata\\ProductBundle\\Controller;\n \n use Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller;\n+use Symfony\\Component\\HttpFoundation\\JsonResponse;\n+use Symfony\\Component\\HttpKernel\\Exception\\BadRequestHttpException;\n use Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException;\n use Symfony\\Component\\Form\\FormView;\n use Symfony\\Component\\HttpFoundation\\Response;\n@@ -30,7 +32,7 @@ class ProductController extends Controller\n      */\n     public function viewAction($productId, $slug)\n     {\n-        $product = is_object($productId) ? $productId : $this->get(\'sonata.product.set.manager\')->findEnabledFromIdAndSlug($productId, $slug);\n+        $product = $this->get(\'sonata.product.set.manager\')->findEnabledFromIdAndSlug($productId, $slug);\n \n         if (!$product) {\n             throw new NotFoundHttpException(sprintf(\'Unable to find the product with id=%d\', $productId));\n@@ -91,6 +93,55 @@ class ProductController extends Controller\n         return $response;\n     }\n \n+    /**\n+     * Returns price for $productId in given $quantity and stock information\n+     * as JSON.\n+     *\n+     * @param $productId\n+     * @param $quantity\n+     *\n+     * @return JsonResponse\n+     */\n+    public function getPriceStockForQuantityAction($productId, $quantity)\n+    {\n+        if (!$this->getRequest()->isXmlHttpRequest()) {\n+            throw new BadRequestHttpException;\n+        }\n+\n+        $product = $this->get(\'sonata.product.set.manager\')->findOneBy(array(\'id\' => $productId, \'enabled\' => true));\n+\n+        if (!$product) {\n+            throw new NotFoundHttpException(sprintf(\'Unable to find the product with id=%d\', $productId));\n+        }\n+\n+        $errors = array();\n+\n+        /** @var \\Sonata\\Component\\Product\\Pool $productPool */\n+        $productPool = $this->get(\'sonata.product.pool\');\n+        $provider = $productPool->getProvider($product);\n+\n+        if ($provider->hasVariations($product)) {\n+            $errors[\'variations\'] = "This is a master product, it has no price";\n+        }\n+\n+        $stock = $provider->getStockAvailable($product) ?: 0;\n+\n+        if ($quantity > $stock) {\n+            $errors[\'stock\'] = $this->get(\'translator\')->trans(\'product_out_of_stock_quantity\', array(), "SonataProductBundle");\n+        }\n+\n+        $currency = $this->get(\'sonata.basket\')->getCurrency();\n+\n+        $price = $provider->calculatePrice($product, $currency, $quantity);\n+\n+        return new JsonResponse(array(\n+            \'stock\'      => $stock,\n+            \'price\'      => $price,\n+            \'price_text\' => $this->get(\'sonata.intl.templating.helper.number\')->formatCurrency($price, $currency),\n+            \'errors\'     => $errors\n+        ));\n+    }\n+\n     /**\n      * @param \\Sonata\\Component\\Basket\\BasketElementInterface $basketElement\n      * @param \\Sonata\\Component\\Basket\\BasketInterface        $basket\ndiff --git a/src/Sonata/ProductBundle/Model/BaseProductProvider.php b/src/Sonata/ProductBundle/Model/BaseProductProvider.php\nindex b5584a2a..a2814acb 100644\n--- a/src/Sonata/ProductBundle/Model/BaseProductProvider.php\n+++ b/src/Sonata/ProductBundle/Model/BaseProductProvider.php\n@@ -23,6 +23,7 @@ use Sonata\\Component\\Product\\ProductProviderInterface;\n use Sonata\\Component\\Basket\\BasketElementInterface;\n use Sonata\\Component\\Basket\\BasketInterface;\n use Sonata\\AdminBundle\\Validator\\ErrorElement;\n+use Sonata\\CoreBundle\\Exception\\InvalidParameterException;\n use Symfony\\Component\\Form\\FormBuilder;\n use Sonata\\AdminBundle\\Form\\FormMapper;\n use Sonata\\Component\\Product\\ProductCollectionManagerInterface;\n@@ -828,15 +829,19 @@ abstract class BaseProductProvider implements ProductProviderInterface\n      */\n     public function basketCalculatePrice(BasketInterface $basket, BasketElementInterface $basketElement)\n     {\n-        return $this->currencyPriceCalculator->getPrice($basketElement->getProduct(), $basket->getCurrency());\n+        return $this->calculatePrice($basketElement->getProduct(), $basket->getCurrency(), $basketElement->getQuantity());\n     }\n \n     /**\n      * {@inheritdoc}\n      */\n-    public function calculatePrice(ProductInterface $product, CurrencyInterface $currency = null)\n+    public function calculatePrice(ProductInterface $product, CurrencyInterface $currency, $quantity = 1)\n     {\n-        return $this->currencyPriceCalculator->getPrice($product, $currency);\n+        if (!is_int($quantity) || $quantity < 1) {\n+            throw new InvalidParameterException("Expected integer >= 1 for quantity, ".$quantity." given.");\n+        }\n+\n+        return floatval(bcmul($this->currencyPriceCalculator->getPrice($product, $currency), $quantity));\n     }\n \n     /**\n@@ -883,10 +888,7 @@ abstract class BaseProductProvider implements ProductProviderInterface\n     }\n \n     /**\n-     * return the stock available for the current product\n-     *\n-     * @param  \\Sonata\\Component\\Product\\ProductInterface $product\n-     * @return int                                        the stock available\n+     * {@inheritdoc}\n      */\n     public function getStockAvailable(ProductInterface $product)\n     {\ndiff --git a/src/Sonata/ProductBundle/Resources/config/routing/product.xml b/src/Sonata/ProductBundle/Resources/config/routing/product.xml\nindex 2faa2bbc..f64b69a5 100644\n--- a/src/Sonata/ProductBundle/Resources/config/routing/product.xml\n+++ b/src/Sonata/ProductBundle/Resources/config/routing/product.xml\n@@ -8,6 +8,10 @@\n         <default key="_controller">SonataProductBundle:Product:view</default>\n     </route>\n \n+    <route id="sonata_product_price_stock" pattern="/info/{productId}/{quantity}">\n+        <default key="_controller">SonataProductBundle:Product:getPriceStockForQuantity</default>\n+    </route>\n+\n     <route id="sonata_product_view_variations" pattern="/{productId}/{slug}/variations">\n         <default key="_controller">SonataProductBundle:Product:viewVariations</default>\n     </route>\ndiff --git a/src/Sonata/ProductBundle/Resources/public/js/product.js b/src/Sonata/ProductBundle/Resources/public/js/product.js\nnew file mode 100644\nindex 00000000..a555ee11\n--- /dev/null\n+++ b/src/Sonata/ProductBundle/Resources/public/js/product.js\n@@ -0,0 +1,81 @@\n+// This file is part of the Sonata package.\n+// \n+// (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>\n+// \n+// For the full copyright and license information, please view the LICENSE\n+// file that was distributed with this source code.\n+\n+var Sonata = Sonata || {};\n+\n+Sonata.Product = {\n+    /**\n+     * URLs to use when performing ajax operations\n+     *\n+     * @var Object\n+     */\n+    url: {\n+        infoStockPrice: null\n+    },\n+\n+    /**\n+     * Object events sources & targets\n+     *\n+     * @var Object\n+     */\n+    targets: {\n+        inputAddBasket:  null,\n+        productPrice:    null,\n+        submitBasketBtn: null,\n+        addBasketError:  null\n+    },\n+    \n+    init: function(options) {\n+        options = options || [];\n+        for (property in options) {\n+            this[property] = options[property];\n+        }\n+\n+        this.initAddBasket();\n+    },\n+    \n+    initAddBasket: function() {\n+        this.targets.inputAddBasket.change(jQuery.proxy(this.changeAddBasket, this));\n+    },\n+    \n+    changeAddBasket: function(event) {\n+        this.resetElements();\n+        \n+        var url = this.buildInfoStockPriceUrl(event.currentTarget.value);\n+        jQuery.getJSON(url, jQuery.proxy(this.processAddBasketResults, this));\n+    },\n+    \n+    resetElements: function() {\n+        this.targets.addBasketError.css(\'display\', \'none\');\n+        this.targets.submitBasketBtn.removeClass(\'disabled\');\n+        this.targets.submitBasketBtn.prop(\'disabled\', false);\n+    },\n+    \n+    processAddBasketResults: function(data) {\n+        if (data.errors.stock) {\n+            jQuery.proxy(this.addBasketAddErrors(data.errors), this);\n+        }\n+        jQuery.proxy(this.addBasketProcessPrice(data.price_text), this);\n+    },\n+    \n+    buildInfoStockPriceUrl: function(quantity) {\n+        return this.url.infoStockPrice.substr(0, this.url.infoStockPrice.length-1)+quantity;\n+    },\n+    \n+    addBasketAddErrors: function(errors) {\n+        this.targets.addBasketError.text(errors.stock);\n+        this.targets.addBasketError.css(\'display\', \'block\');\n+        this.targets.submitBasketBtn.addClass(\'disabled\');\n+        this.targets.submitBasketBtn.prop(\'disabled\', true);\n+    },\n+    \n+    addBasketProcessPrice: function(price) {\n+        this.targets.productPrice.text(price);\n+    }\n+}\n+\n+\ndiff --git a/src/Sonata/ProductBundle/Resources/translations/SonataProductBundle.en.xliff b/src/Sonata/ProductBundle/Resources/translations/SonataProductBundle.en.xliff\nindex fd93c020..9983b79b 100644\n--- a/src/Sonata/ProductBundle/Resources/translations/SonataProductBundle.en.xliff\n+++ b/src/Sonata/ProductBundle/Resources/translations/SonataProductBundle.en.xliff\n@@ -298,6 +298,10 @@\n                 <source>product_out_of_stock</source>\n                 <target>Warning : this product is currently out of stock !</target>\n             </trans-unit>\n+            <trans-unit id="product_out_of_stock_quantity">\n+                <source>product_out_of_stock_quantity</source>\n+                <target>There is not enough stock to satisfy the asked quantity.</target>\n+            </trans-unit>\n             <!-- End - Product view translations -->\n \n             <!-- Begin - Product create variations -->\ndiff --git a/src/Sonata/ProductBundle/Resources/translations/SonataProductBundle.fr.xliff b/src/Sonata/ProductBundle/Resources/translations/SonataProductBundle.fr.xliff\nindex 3acdab94..87d14b07 100644\n--- a/src/Sonata/ProductBundle/Resources/translations/SonataProductBundle.fr.xliff\n+++ b/src/Sonata/ProductBundle/Resources/translations/SonataProductBundle.fr.xliff\n@@ -298,6 +298,10 @@\n                 <source>product_out_of_stock</source>\n                 <target>Attention : ce produit n\'est pas disponible actuellement !</target>\n             </trans-unit>\n+            <trans-unit id="product_out_of_stock_quantity">\n+                <source>product_out_of_stock_quantity</source>\n+                <target>Il n\'y a pas assez de stock pour répondre à la quantité demandée.</target>\n+            </trans-unit>\n             <!-- End - Product view translations -->\n \n             <!-- Begin - Product create variations -->\ndiff --git a/src/Sonata/ProductBundle/Resources/views/Product/view.html.twig b/src/Sonata/ProductBundle/Resources/views/Product/view.html.twig\nindex eb4b0928..e4f3962b 100644\n--- a/src/Sonata/ProductBundle/Resources/views/Product/view.html.twig\n+++ b/src/Sonata/ProductBundle/Resources/views/Product/view.html.twig\n@@ -9,6 +9,24 @@ file that was distributed with this source code.\n \n #}\n \n+{% block product_javascript_init %}\n+    <script>\n+        jQuery(document).ready(function() {\n+            Sonata.Product.init({\n+                url: {\n+                    infoStockPrice: \'{{ path(\'sonata_product_price_stock\', {\'productId\': product.id, \'quantity\': 1}) }}\'\n+                },\n+                targets: {\n+                    inputAddBasket:  $(\'#add_basket_quantity\'),\n+                    productPrice:    $(\'#sonata_product_price\'),\n+                    submitBasketBtn: $(\'#sonata_add_basket_submit\'),\n+                    addBasketError:  $(\'#sonata_add_basket_error\')\n+                }\n+            });\n+        });\n+    </script>\n+{% endblock %}\n+\n {% block product %}\n     <!-- Begin product display -->\n     <div class="row-fluid" itemscope itemtype="http://schema.org/Product">\n@@ -69,7 +87,7 @@ file that was distributed with this source code.\n \n                                 </dt>\n \n-                                <dd itemprop="price" style="margin-left: 110px;">\n+                                <dd itemprop="price" style="margin-left: 110px;" id="sonata_product_price">\n                                     {% block product_price_price %}\n                                         {% if provider.hasEnabledVariations(product) %}\n                                             {{ cheapest_variation.price|number_format_currency(currency) }}\n@@ -107,6 +125,7 @@ file that was distributed with this source code.\n                         <hr/>\n \n                         {% block product_basket %}\n+                            <div class="alert alert-error" id="sonata_add_basket_error" style="display:none;"></div>\n                             {% include "SonataBasketBundle:Basket:add_product_form.html.twig" %}\n                         {% endblock %}\n \ndiff --git a/tests/Sonata/Tests/BasketBundle/Block/BasketBlockServiceTest.php b/tests/Sonata/Tests/BasketBundle/Block/BasketBlockServiceTest.php\nindex 9bf0bac5..f4442dcf 100644\n--- a/tests/Sonata/Tests/BasketBundle/Block/BasketBlockServiceTest.php\n+++ b/tests/Sonata/Tests/BasketBundle/Block/BasketBlockServiceTest.php\n@@ -11,6 +11,7 @@\n namespace Sonata\\Tests\\BasketBundle\\Block;\n \n use Sonata\\BasketBundle\\Block\\BasketBlockService;\n+use Symfony\\Component\\HttpFoundation\\Response;\n \n /**\n  * Class BasketBlockServiceTest\n@@ -24,9 +25,18 @@ class BasketBlockServiceTest extends \\PHPUnit_Framework_TestCase\n     public function testGetName()\n     {\n         $engineInterfaceMock = $this->getMockBuilder(\'Symfony\\Bundle\\FrameworkBundle\\Templating\\EngineInterface\')->disableOriginalConstructor()->getMock();\n-        $customerManagerInterfaceMock = $this->getMockBuilder(\'Sonata\\Component\\Customer\\CustomerManagerInterface\')->disableOriginalConstructor()->getMock();\n         $block = new BasketBlockService(\'test\', $engineInterfaceMock);\n \n         $this->assertEquals(\'Basket items\', $block->getName());\n     }\n+\n+    public function testExecute()\n+    {\n+        $engineInterfaceMock = $this->getMockBuilder(\'Symfony\\Bundle\\FrameworkBundle\\Templating\\EngineInterface\')->disableOriginalConstructor()->getMock();\n+        $engineInterfaceMock->expects($this->once())->method(\'renderResponse\')->will($this->returnValue(new Response()));\n+        $context = $this->getMock(\'Sonata\\BlockBundle\\Block\\BlockContextInterface\');\n+        $block = new BasketBlockService(\'test\', $engineInterfaceMock);\n+\n+        $this->assertInstanceOf(\'Symfony\\Component\\HttpFoundation\\Response\', $block->execute($context));\n+    }\n }\ndiff --git a/tests/Sonata/Tests/ProductBundle/Model/BaseProductProviderTest.php b/tests/Sonata/Tests/ProductBundle/Model/BaseProductProviderTest.php\nindex 5f706974..b1cc32bb 100644\n--- a/tests/Sonata/Tests/ProductBundle/Model/BaseProductProviderTest.php\n+++ b/tests/Sonata/Tests/ProductBundle/Model/BaseProductProviderTest.php\n@@ -10,6 +10,7 @@\n \n namespace Sonata\\Test\\ProductBundle\\Model;\n \n+use Sonata\\Component\\Currency\\CurrencyPriceCalculator;\n use Sonata\\Component\\Product\\ProductInterface;\n use Sonata\\ProductBundle\\Entity\\BaseProduct;\n use Sonata\\ProductBundle\\Model\\BaseProductProvider;\n@@ -403,6 +404,18 @@ class BaseProductProviderTest extends \\PHPUnit_Framework_TestCase\n         $this->assertEquals($variationB, $provider->getCheapestEnabledVariation($product));\n     }\n \n+    public function testCalculatePrice()\n+    {\n+        $product = new ProductTest();\n+        $product->setPrice(42);\n+\n+        $provider = $this->createNewProductProvider();\n+\n+        $this->assertEquals(42*4, $provider->calculatePrice($product, 4));\n+        $this->assertEquals(42*4, $provider->calculatePrice($product, 4.32));\n+        $this->assertEquals(42, $provider->calculatePrice($product));\n+    }\n+\n     /**\n      * @return ProductProviderTest\n      */\n@@ -410,6 +423,10 @@ class BaseProductProviderTest extends \\PHPUnit_Framework_TestCase\n     {\n         $serializer = $this->getMockBuilder(\'JMS\\Serializer\\Serializer\')->disableOriginalConstructor()->getMock();\n \n-        return new ProductProviderTest($serializer);\n+        $provider = new ProductProviderTest($serializer);\n+\n+        $provider->setCurrencyPriceCalculator(new CurrencyPriceCalculator());\n+\n+        return $provider;\n     }\n }\n', 'commit_subject': 'Merge pull request #21 from Bladrak/autoPriceUpdate', 'repo_name': 'sonata-project/ecommerce', 'committer': {'name': 'Thomas', 'email': '583eaba57026faea610644b601ef5935608a45fe@gmail.com', 'time_sec': '1387365379', 'tz_offset': '-480', 'date': {'seconds': '1387365379'}}, 'commit_tree': '37cf41ea4d0387a54d0bde208e08d87a727d3d9a', 'commit_message': 'Merge pull request #21 from Bladrak/autoPriceUpdate\n\nAuto price update', 'language_name': 'Shell', 'license': 'mit', 'hunks': "@@ -0,0 +1,81 @@\n+// This file is part of the Sonata package.\n+// \n+// (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>\n+// \n+// For the full copyright and license information, please view the LICENSE\n+// file that was distributed with this source code.\n+\n+var Sonata = Sonata || {};\n+\n+Sonata.Product = {\n+    /**\n+     * URLs to use when performing ajax operations\n+     *\n+     * @var Object\n+     */\n+    url: {\n+        infoStockPrice: null\n+    },\n+\n+    /**\n+     * Object events sources & targets\n+     *\n+     * @var Object\n+     */\n+    targets: {\n+        inputAddBasket:  null,\n+        productPrice:    null,\n+        submitBasketBtn: null,\n+        addBasketError:  null\n+    },\n+    \n+    init: function(options) {\n+        options = options || [];\n+        for (property in options) {\n+            this[property] = options[property];\n+        }\n+\n+        this.initAddBasket();\n+    },\n+    \n+    initAddBasket: function() {\n+        this.targets.inputAddBasket.change(jQuery.proxy(this.changeAddBasket, this));\n+    },\n+    \n+    changeAddBasket: function(event) {\n+        this.resetElements();\n+        \n+        var url = this.buildInfoStockPriceUrl(event.currentTarget.value);\n+        jQuery.getJSON(url, jQuery.proxy(this.processAddBasketResults, this));\n+    },\n+    \n+    resetElements: function() {\n+        this.targets.addBasketError.css('display', 'none');\n+        this.targets.submitBasketBtn.removeClass('disabled');\n+        this.targets.submitBasketBtn.prop('disabled', false);\n+    },\n+    \n+    processAddBasketResults: function(data) {\n+        if (data.errors.stock) {\n+            jQuery.proxy(this.addBasketAddErrors(data.errors), this);\n+        }\n+        jQuery.proxy(this.addBasketProcessPrice(data.price_text), this);\n+    },\n+    \n+    buildInfoStockPriceUrl: function(quantity) {\n+        return this.url.infoStockPrice.substr(0, this.url.infoStockPrice.length-1)+quantity;\n+    },\n+    \n+    addBasketAddErrors: function(errors) {\n+        this.targets.addBasketError.text(errors.stock);\n+        this.targets.addBasketError.css('display', 'block');\n+        this.targets.submitBasketBtn.addClass('disabled');\n+        this.targets.submitBasketBtn.prop('disabled', true);\n+    },\n+    \n+    addBasketProcessPrice: function(price) {\n+        this.targets.productPrice.text(price);\n+    }\n+}\n+\n+\n", 'addition_count': 81, 'deletion_count': 0, 'src_file': '/dev/null', 'tgt_file': 'b/src/Sonata/ProductBundle/Resources/public/js/product.js', 'file_extension': '.js', 'before_file': 'ADDFILE', 'message': 'Merge pull request #21 from Bladrak/autoPriceUpdate\n\nAuto price update', 'author_name': 'Thomas', 'lang': 'js'}