Add subtotal to Odoo Point of Sale Screen - odoo-10

I'm trying to add a subtotal to the Point of Sale screen in the section where products are being added so that the cashier can see not only the tax and total but also subtotal.
I've successfully added the subtotal by extending the OrderWidget in the static XML.
Now I'm trying to extend the javascript code that I think modify the value of the tax and total as you're adding products. this is the name of the class I'm extending OrderWidget and this is the method I'm extending update_summary
I follow the same coding I did to extend the PosModel from the models javascript module but in this case, I'm using the screens module
This is the code I have but for some reason, my method is not being called. Am I extending wrong the Widget?
var OrderWidgetParent = screens.OrderWidget.prototype;
screens.OrderWidget = screens.OrderWidget.extend({
update_summary: function() {
console.debug('--------------- START');
OrderWidgetParent.update_summary.call(this);
var order = this.pos.get_order();
if (!order.get_orderlines().length) {
return;
}
this.el.querySelector('.summary .total .subentry .subtotal')
.textContent = this.format_currency(total - taxes);
console.debug('--------------- END');
}
});

You just need to call base method of models.js in your xml template file. Method is: 'get_total_without_tax'
This method get total excluded tax. So you can consider this as a subtotal of your order.

The solution was to use include instead of extend.

Related

How to check programmatically if Magento getSelectionsCollection don't have any product

what is this output of $selectionCollection given if no selection product is found in this code for magento bundle product list
$bundled_product_custom = new Mage_Catalog_Model_Product();
$bundled_product_custom->load($bundleParentProductId);
$selectionCollection = $bundled_product_custom->getTypeInstance(true)->getSelectionsCollection(
$bundled_product_custom->getTypeInstance(true)->getOptionsIds($bundled_product_custom), $bundled_product_custom
);
Actually I need to check if this bundle product has selection products or not.
First of all you should avoid instantiating an object with the new operator. I suggest you use the Magento's factory method as shown below:
$bundled_product_custom = Mage::getModel('catalog/product');
This way if a third party extension overrides the Mage_Catalog_Model_Product class then the factory method instantiates the right object according to the override rules.
To answer your question, try to count the elements in the collection this way:
$selectionCollection->count();
// or
count($selectionCollection);

Replacing "product name" with "Item + productId" when product is added in Magento via admin panel

I want to auto generate product names in Magento.
When I'm going to add a product, for the product name I will type some string.
When I save the product, I want the product name to be automatically generated such that the product name becomes Item."productId".
Answering assuming that OP wants to incorporate the auto-increment value from the entity table into business data. This is generally not a great idea.
This is an interesting task which can be easily accomplished with Magento's EAV implementation - particularly when working in the catalog module. First, some background.
When an EAV entity is saved, it has a nice, neat array of key => value pairs which represent the attributes and attribute values for that entity:
Mage_Catalog_Model_Product->_data['attribute_code'] = 'attribute value';
During the save process, the EAV resource model takes this array and iterates over it. For each attribute, identified by its code (attribute_code in the above example) and its entity (catalog_product in the case of products), the configuration for the attribute itself is loaded. Of particular importance is the "backend model" for an attribute, as it is invoked to do pre- and post-processing of/relating to the value.
In the current case, there is a piece of information which will not be present when we are saving the attribute, at least, not in a way in which we can use it: the new product id. This can be used to adjust the original value as part of the save process.
It's always nice to have an example from the core, so, refer to the price attribute and its backend model, Mage_Catalog_Model_Product_Attribute_Backend_Price which can be seen in the eav_attribute table:
SELECT `attribute_code`, `backend_model`
FROM `eav_attribute`
LEFT JOIN `eav_entity_type` USING (`entity_type_id`)
WHERE `attribute_code` = 'price';
#+----------------+-----------------------------------------+
#| attribute_code | backend_model |
#+----------------+-----------------------------------------+
#| price | catalog/product_attribute_backend_price |
#+----------------+-----------------------------------------+
#1 row in set (0.00 sec)
When a product is saved, the price attribute's backend_model is instantiated and (in this case) the afterSave() method is called. Incidentally, this method is what updates pricing by conversion rate for website-scoped pricing. This same approach can be used to modify the name attribute.
The following setup script will add the backend model:
<?php
$installer = Mage::getResourceModel('catalog/setup','default_setup');
$installer->startSetup();
$installer->updateAttribute(
'catalog_product',
'name',
'backend_model',
'custom/product_attribute_backend_name'
);
$installer->endSetup();
The corresponding afterSave() method should do the trick:
public function afterSave($object)
{
$value = $object->getData($this->getAttribute()->getAttributeCode());
$origData = $object->getOrigData();
$origValueExist = $origData && array_key_exists($this->getAttribute()->getAttributeCode(), $origData);
//don't do this in case of update
if ($object->getStoreId() != 0 || !$value || $origValueExist) {
return $this;
}
//append autoinc id
$newValue = $value .'.'. $object->getId(); // or whatever
//assume global store, otherwise the stated need is getting weird!
$object->addAttributeUpdate($this->getAttribute()->getAttributeCode(), $newValue, 0);
return $this;
}
If you're doing this from the admin panel product edit screen, you're going to have to remove the "Required" class from the "Name" field so you can save it without the name. This means overriding the Edit form to replace that field specifically. Then you'll have to overload the save-related methods on the product model (or you can do it from the controller), but the child will have to generate the name on save before it goes to the database.
For example:
class Module_Catalog_Model_Product extends Mage_Catalog_Model_Product
{
protected function _beforeSave()
{
parent::_beforeSave();
$productName = 'Item' . $this->getId();
if (!$this->getId() && !$this->getName())
{
$this->setName('Item Unnamed');
} elseif ($this->getId()) && strcasecmp($this->getName(), $productName) <> 0)
{
$this->setName($productName);
}
}
}
The only problem with this is that it requires two saves. If you want to have it work on the fly, you'll have to do a second save using the _afterSave() method. Or, once again, you can do it from the controller.
I would use a Magento Event to do this:
Since Models in Magento have an event prefixes (just take a look at Mage_Catalog_Model_Product and look for $_eventPrefix, for our current model the eventPrefix is set to catalog_product.
If you now take a look at Mage_Core_Model_Abstract and search for _eventPrefix. You see that eventPrefix are found in _beforeLoad, _afterLoad, _beforeSave, _afterSave and a few others. In these methods you can see an event is dispatched using something as below:
Mage::dispatchEvent($this->_eventPrefix.'_save_before', $this->_getEventData());
This means you have an event available called catalog_product_save_before. With this event you can hook into Magento at that time and do your thing, change the field in this case, and Magento handles the rest.
Take a look at http://www.magentocommerce.com/wiki/5_-_modules_and_development/0_-_module_development_in_magento/customizing_magento_using_event-observer_method for more information how to use these events and turn them into a module. If you don't know how to build modules for Magento and want to learn, there are some awesome on-demand video's for free: http://www.magentocommerce.com/training/on-demand
First I want to thanks to all users which write in the topic. Thanks a lot of guys!
I did it, but I make it easier. (because I have very basic knowledge in Magento and it would toke more time)
So... With my colegues decided to make it with php/jquery/ajax.
First we create one single php file, which return the last id:
<?php
header('Access-Control-Allow-Origin: *');
require_once 'app/Mage.php';
umask(o);
Mage::app('default');
Mage::getSingleton('core/session', array('name'=>'frontend'));
$model = Mage::getModel('catalog/product'); //getting product model
$collection = $model->getCollection(); //products collection
foreach ($collection as $product) //loop for getting products
{
$id=$product->getId();
}
if($id)echo $id+1; //id of product
else{
echo 0;
}
?>
After step one I set the value of input (i.e. I auto generate the name):
if($j('#name').val()=='' && window.location.href.indexOf("admin/catalog_product/new/") > -1) {
$j.post('http://www.website.com/file.php', function(data) {
$j('#name').val('Item №'+data);
});
}
Thanks again for help.
Best Regards,
Jordan!

How to show all products in nopCommerce?

I would like to show all products without creating any new category and mapping to it.
Can any one help me?
Thanks in advance.
It's true; in order for a product to be displayed in nopCommerce, it must be assigned to a category. Your best bet is to create a top-level umbrella category, like "All Products", and add all of your products to that umbrella category.
As far as I know their must be a category associated with product.
You can create a plugin, map a route to it (for example map to 'allproducts' route), and create your own Controllers, Actions and Views within the plugin. Then insert in the main menu a link to the route by mean of
#Html.RouteLink(routeName, null) //or similar overloads
The plugin creation part is too huge to be described here. http://www.nopcommerce.com/documentation.aspx is a good start.
PS:/ Regarding routing, each plugin can implement a route registrar by implementing the "IRouteProvider" interface.
:)
You can do that by modifying the code. I have done it before. It is actually quite simple.
Modify the Category action of the Catalogue controller to receive a nullable CategoryId:
public ActionResult Category(int? categoryId, CatalogPagingFilteringModel command){
modify the action to not break because of this nullable paramters.
The most important part to modify is where you build the list of category Ids to filter:
var categoryIds = new List<int>();
if (category != null)
{
categoryIds.Add(category.Id);
}
if (_catalogSettings.ShowProductsFromSubcategories)
{
//include subcategories
categoryIds.AddRange(GetChildCategoryIds(category.Id));
}
The mothod _productService.SearchProducts will receive an empty list of category Ids and will not filter any products.

Magento Payment Info Block

I have created new payment method (gateway). In this gateway I sending information to bank for credit payment and I use some additional payment options like Name/Person Age/Person Profit/Credit Term/...
By this fields I calculate Credit Term and send all of this data to bank.
I would like to show this information in Payment Method info block (right sidebar in default theme), but I would not like to save this fields to database (so in admin area later I will have information like it was standart Check/Money Order payment and just payment method name would be another)
I can't show this fields in Payment Method info block, because it shows only fields stored in database and only way that I found - store this data in core/session and then in info block retrieve this data back
I doing something like this in Payment Model:
class OS_LacPayCS_Model_Payment extends Mage_Payment_Model_Method_Abstract
{
...
public function assignData($data)
{
parent::assignData($data);
$session = Mage::getSingleton('core/session');
$session->setData('payment_additional', $data);
return $this;
}
...
}
and then getting it
class OS_LacPayCS_Block_Payment_Info extends Mage_Payment_Block_Info
{
...
public function getPaymentInfo()
{
$session = Mage::getSingleton('core/session');
return $session->getData('payment_additional');
}
...
}
Is there another way to get this data?
And also I wish to add some additional rows in Order Review Tab on checkout, how can I add them w/o rewriting review template and block?
Thanx
Magento payment api defines additional_information field that is saved as serialized array to db and that you can use for storing the data you might need to display. You can set data to there by assignData($data) method

Magento: showing prices ex/inc TAX/VAT depending on customer group

Previously I have implemented a 'trade only' store front that shows both in and ex-VAT prices for trade customers. They still get billed the VAT, it is just the catalog shows ex-VAT prices as well as the regular inc VAT prices.
I would like to be able to implement the same functionality without creating a new store front, i.e. if someone is in the 'trade' customer group, they get prices shown inc and ex vat. They are still on the same tax rate as everyone else, so I am not looking to have a 0% tax group, what I want is just to be able to switch the prices based on their group. This also includes the labels, so there isn't just a price but a clear indication of inc/ex VAT/TAX.
It took me a while to Google this with 'tax' instead of 'VAT', however, to date I haven't found many clues as to where to start. If there is a reason why this cannot be done easily then I would like to know. Failing that, if there is a frontend hack to try, e.g. some conditional prototype to un-css-hide the prices/labels then that will have to be the route to go.
EDIT
Inspired by Clockworkgeek I did this, not yet the perfect module solution, but something that works for me for now:
Cloned core file to app/code/local/Mage/Tax/Model/Config.php and updated the getPriceDisplayType function:
public function getPriceDisplayType($store = null)
{ $customer = Mage::helper('customer')->getCustomer();
if ($customer->getGroupId() > 1) {
return self::DISPLAY_TYPE_BOTH;
} else {
return (int)Mage::getStoreConfig(self::CONFIG_XML_PATH_PRICE_DISPLAY_TYPE, $store);
}
}
This relies on 0 being not logged in, 1 being normal customers and any 'special' group higher than that. I did not think it was working at first, but then I logged in...
There is a config setting for whether to include or exclude tax but it is not customer-specific. I believe the most direct way would be to override the point where this is read. The following is pseudocode...
class Your_Module_Model_Config extends Mage_Tax_Model_Config
{
public function getPriceDisplayType($store = null)
{
$customer = Mage::helper('customer')->getCustomer();
if ($customer->getGroupId() == 'TRADE') {
return self::DISPLAY_TYPE_BOTH;
}
return parent::getPriceDisplayType($store);
}
}
You can try this to show prices without tax only for specified customer groups:
http://www.magentocommerce.com/magento-connect/catalog/product/view/id/18364/

Resources