Selaa lähdekoodia

commit inicial

Rodney Elpidio Enciso Arias 6 vuotta sitten
commit
bbff91ed43

+ 24 - 0
__init__.py

@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    This module copyright (C) 2016 ePillars Systems (<http://epillars.com>)
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+import pos
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

BIN
__init__.pyc


+ 47 - 0
__openerp__.py

@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    This module copyright (C) 2016 ePillars Systems (<http://epillars.com>)
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+{
+    'name': 'POS Multi-Currency',
+    'version': '1.0',
+    'category': 'Point of Sale',
+    'summary': 'Multi-currency support for POS interface',
+    'description': """ Enable multiple currency for POS. Ability to view amount totals in any currency and
+                      and enter currency in that total. The value will automatically be converted
+                      to base currency for payment.""",
+    'author': 'ePillars Systems',
+    'website': 'http://www.epillars.com',
+    'depends': ['point_of_sale'],
+    'data':[
+            "security/ir.model.access.csv",
+            "web_customization_data.xml",
+            "pos_view.xml"
+            ],
+    'qweb':["static/src/xml/pos.xml"],
+    'demo': [],
+    'installable': True,
+    'application': True,
+    'auto_install': False,
+    'price':30.00,
+    'currency':'EUR',
+}
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

+ 52 - 0
pos.py

@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2016 ePillars Systems (<http://epillars.com>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+from openerp.osv import fields, osv
+
+class pos_config(osv.osv):
+    _inherit="pos.config"
+    
+    _columns={
+              'multi_currency_enable':fields.boolean('Enable Multi-Currency',
+                                                     help='Select this to enable Multi-currency options in POS'),
+              'display_conversion':fields.boolean('Display Conversion on POS',
+                                                  help='Check this to display the conversion factor on the POS terminal'),
+              'fetch_master':fields.boolean('Fetch Currency Master',
+                             help='Check this if you would like to fetch all conversion factors and currencies from the master table'),
+              'currency_lines':fields.one2many('pos.currency.line','pos_config_id','POS Currency Lines'),
+              }
+    
+    _defaults={
+               'multi_currency_enable':True,
+               'display_conversion':True,
+               'fetch_master':True,
+               }
+    
+class pos_currency_line(osv.osv):
+    _name="pos.currency.line"
+    _description="POS Currency Lines"
+    
+    _columns={
+              'pos_config_id':fields.many2one('pos.config','POS Config'),
+              'currency_id':fields.many2one('res.currency','Currency'),
+              'rate_silent':fields.float('Conversion Factor', digits=(12,6)),
+              }
+

BIN
pos.pyc


+ 32 - 0
pos_view.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+    <data>
+    
+    <record model="ir.ui.view" id="view_pos_config_form">
+		<field name="name">POS Multi-Currency</field>
+		<field name="model">pos.config</field>
+		<field name="inherit_id" ref="point_of_sale.view_pos_config_form"/>
+		<field name="arch" type="xml">
+			<xpath expr="//group[@string='Features']" position="before">
+				<group string="Multi-Currency Options">
+					<group>
+						<field name="multi_currency_enable" />
+						<field name="display_conversion" />
+					</group>
+					<group>
+						<field name="fetch_master" string="Fetch All Values from Currency Master" />
+					</group>
+				</group>
+				<field name="currency_lines" attrs="{'invisible':[('fetch_master','=',True)]}">
+					<tree editable="bottom">
+						<field name="currency_id" />
+						<field name="rate_silent" />
+					</tree>
+				</field>
+
+			</xpath>
+		</field>
+	</record>
+	
+    </data>
+</openerp>

+ 3 - 0
security/ir.model.access.csv

@@ -0,0 +1,3 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_pos_currency_line,pos.currency.line user,model_pos_currency_line,point_of_sale.group_pos_user,1,0,0,0
+access_pos_currency_line2,pos.currency.line manager,model_pos_currency_line,point_of_sale.group_pos_manager,1,1,1,1

BIN
static/description/default_pos.png


BIN
static/description/foreign.png


BIN
static/description/icon.png


+ 80 - 0
static/description/index.html

@@ -0,0 +1,80 @@
+<section class="oe_container">
+    <div class="oe_row oe_spaced">
+        <div class="oe_span12">
+            <h2 class="oe_slogan">Point of Sale Multi-Currency Support</h2>
+        </div>
+        <div class="oe_span12 text-center">
+            <p class="oe_mt32">
+				Display foreign currency total, paid and change amounts in POS terminal.<br/>
+				Note: This module is to be used only to view the equivalent amounts in foreign currency.
+				All amounts are converted into the base currency. Therefore, it will only support journals
+				configured in the base currency.
+            </p>
+        </div>
+    </div>
+</section>
+
+<section class="oe_container oe_dark">
+    <div class="oe_row oe_spaced">
+        <h2 class="oe_slogan">Configurable parameters </h2>
+        <div class="oe_span6">
+            <p class="oe_mt32">
+            	Specify whether to Fetch Values from Master to directly use the pre-defined currency rates.
+            	Choose to display conversion rates on the POS terminal for users.
+            </p>
+        </div>
+        <div class="oe_span6">
+            <div class="oe_row_img oe_centered">
+                <img class="oe_picture oe_screenshot" src="pos_screen2.png">
+            </div>
+        </div>
+    </div>
+</section>
+
+<section class="oe_container">
+    <div class="oe_row oe_spaced">
+        <h2 class="oe_slogan">Set custom currency rates</h2>
+        <div class="oe_span6">
+            <p class="oe_mt32">
+            	Provision to set your selected acceptable currencies and define rates for them.
+            	Leave conversion rate as 0 to use the default rate.
+            </p>
+        </div>
+        <div class="oe_span6">
+            <div class="oe_row_img oe_centered">
+                <img class="oe_picture oe_screenshot" src="pos_screen1.png">
+            </div>
+        </div>
+    </div>
+</section>
+
+<section class="oe_container oe_dark">
+    <div class="oe_row oe_spaced">
+        <h2 class="oe_slogan">View amounts in foreign currency</h2>
+        <div class="oe_span6">
+            <p class="oe_mt32">
+            	POS terminal will display the conversion rate (optional), the total amount due and change due in the selected currency.
+            	Enter the amount received and the selected payment line will automatically populate
+            	with the equivalent amount in your base currency. The remaining default POS functionality will
+            	take care on its own.
+            </p>
+        </div>
+        <div class="oe_span6">
+            <div class="oe_row_img oe_centered">
+                <img class="oe_picture oe_screenshot" src="foreign.png">
+            </div>
+        </div>
+    </div>
+</section>
+
+<section class="oe_container oe_dark">
+    <div class="oe_row oe_spaced">
+        <h2 class="oe_slogan">Support</h2>
+        <div class="oe_span12 text-center">
+            <p class="oe_mt32">
+            	Please e-mail support@epillars.com for any queries.
+            </p>
+        </div>
+    </div>
+</section>
+

BIN
static/description/pos_screen1.png


BIN
static/description/pos_screen2.png


+ 74 - 0
static/src/css/pos.css

@@ -0,0 +1,74 @@
+.pos .paymentline-input-foreign{
+    font-size: 15px;
+    font-family: Lato;
+    display: block;
+    width: 50%;
+    height:30px;
+    box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    outline: none;
+    border: none;
+    padding: 6px 8px;
+    background: white;
+    color: #484848;
+    text-align: right;
+    border-radius: 3px;
+    box-shadow: 0px 2px rgba(143, 143, 143, 0.3) inset;
+}
+
+.pos .pos-payment-container .foreign_infoline{
+    margin-top:5px;
+    margin-bottom:5px;
+    padding: 0px 8px;
+}
+
+
+.pos .currency_value{
+    font-size: 20px;
+    font-family: Lato;
+    display: inline-block;
+    width: 100%;
+    box-sizing: border-box;
+    -moz-box-sizing: border-box;
+    outline: none;
+    border: none;
+    padding: 6px 8px;
+    background: white;
+    color: #484848;
+    text-align: right;
+    border-radius: 3px;
+    box-shadow: 0px 2px rgba(143, 143, 143, 0.3) inset;
+}
+
+.onoffswitch {
+    position: relative; width: 65px;
+    -webkit-user-select:none; -moz-user-select:none; -ms-user-select: none;
+}
+.onoffswitch-checkbox {
+    display: none;
+}
+.onoffswitch-label {
+    display: block; overflow: hidden; cursor: pointer;
+    height: 25px; padding: 0; line-height: 25px;
+    border: 2px solid #CCCCCC; border-radius: 27px;
+    background-color: #CFC0C0;
+    transition: background-color 0.2s ease-in;
+}
+.onoffswitch-label:before {
+    content: "";
+    display: block; width: 27px; margin: 0px;
+    background: #FFFFFF;
+    position: absolute; top: 0; bottom: 0;
+    right: 42px;
+    border: 2px solid #CCCCCC; border-radius: 27px;
+    transition: all 0.2s ease-in 0s; 
+}
+.onoffswitch-checkbox:checked + .onoffswitch-label {
+    background-color: #49E845;
+}
+.onoffswitch-checkbox:checked + .onoffswitch-label, .onoffswitch-checkbox:checked + .onoffswitch-label:before {
+   border-color: #49E845;
+}
+.onoffswitch-checkbox:checked + .onoffswitch-label:before {
+    right: 0px; 
+}

+ 13 - 0
static/src/js/main.js

@@ -0,0 +1,13 @@
+openerp.pos_multi_currency = function(instance) {
+
+    instance.pos_multi_currency = {};
+
+    var module = instance.point_of_sale;
+
+
+    ep_pos_models(instance,module);     // import pos_models.js
+
+    ep_pos_screens(instance,module);    // import pos_screens.js
+
+    instance.web.client_actions.add('pos.ui', 'instance.point_of_sale.PosWidget');
+};

+ 130 - 0
static/src/js/models.js

@@ -0,0 +1,130 @@
+function ep_pos_models(instance,module)
+{
+	var QWeb = instance.web.qweb;
+	var _t = instance.web._t;
+
+    var round_di = instance.web.round_decimals;
+    var round_pr = instance.web.round_precision;
+    
+    module.PosModel.prototype.models.push(
+	{
+        model:  'pos.currency.line',
+        fields: ['pos_config_id','currency_id','rate_silent'],
+        domain: function(self){return [['pos_config_id','=', self.pos_session.config_id[0]]]; },
+        loaded: function(self, currency_list_lines)
+        {
+        	self.currency_list_lines=currency_list_lines;
+        },
+    },
+	{
+        model:  'res.currency',
+        fields: ['name','rate_silent','rounding','symbol','position','accuracy'],
+        domain:  function(self)
+		{
+			if (self.config.multi_currency_enable && self.config.fetch_master)
+				return [[1,'=',1]];
+			else if (self.config.multi_currency_enable && !self.config.fetch_master)
+			{
+				selected_ids=[]
+				for (i in self.currency_list_lines)
+				{
+					selected_ids.push(self.currency_list_lines[i].currency_id[0]);
+				}
+				return [['id','in',selected_ids]];
+			}
+		},
+        loaded: function(self, currency_list)
+        {
+        	if (self.config.multi_currency_enable && self.config.fetch_master)
+    		{
+        		self.currency_list = currency_list;
+	            var length = 0;
+	
+			    for(var prop in self.currency_list) 
+			    {
+			        if(currency_list.hasOwnProperty(prop))
+		        	{ 
+			            ++length;
+				        if (self.currency_list[prop].rounding > 0) 
+			                self.currency_list[prop].decimals = Math.ceil(Math.log(1.0 /  self.currency_list[prop].rounding) / Math.log(10));
+				        else 
+				        	self.currency_list[prop].decimals = 0;
+		        	}
+			    }
+	
+			    self.currency_list.length=length;
+    		}
+        	else if(self.config.multi_currency_enable && self.config.fetch_master==false)
+    		{
+        		currency_ids=[];
+        		for (i in self.currency_list_lines)
+    			{
+        			currency_ids.push(self.currency_list_lines[i].currency_id[0]);
+    			}
+        		self.currency_list=[];
+        		for (i in currency_list)
+        			for (j in self.currency_list_lines)
+        				if (currency_list[i].id == self.currency_list_lines[j].currency_id[0])
+	    				{
+        					if (self.currency_list_lines[j].rate_silent>0)
+        						currency_list[i].rate_silent=self.currency_list_lines[j].rate_silent;
+	        				self.currency_list.push(currency_list[i]);
+	    				}
+
+        		var length = 0;
+			    for(var prop in self.currency_list) 
+			    {
+			        if(currency_list.hasOwnProperty(prop))
+		        	{ 
+			            ++length;
+				        if (self.currency_list[prop].rounding > 0) 
+			                self.currency_list[prop].decimals = Math.ceil(Math.log(1.0 /  self.currency_list[prop].rounding) / Math.log(10));
+				        else 
+				        	self.currency_list[prop].decimals = 0;
+		        	}
+			    }
+	
+			    self.currency_list.length=length;
+    		}
+        	
+        },
+    });
+    
+    module.Order = module.Order.extend(
+	{
+		initialize: function(attributes)
+		{
+            Backbone.Model.prototype.initialize.apply(this, arguments);
+            this.pos = attributes.pos; 
+            this.sequence_number = this.pos.pos_session.sequence_number++;
+            this.uid =     this.generateUniqueId();
+            this.set(
+        		{
+                creationDate:   new Date(),
+                orderLines:     new module.OrderlineCollection(),
+                paymentLines:   new module.PaymentlineCollection(),
+                name:           _t("Order ") + this.uid,
+                client:         null,
+        		});
+            this.selected_orderline   = undefined;
+            this.selected_paymentline = undefined;
+            this.screen_data = {};  // see ScreenSelector
+            this.receipt_type = 'receipt';  // 'receipt' || 'invoice'
+            this.temporary = attributes.temporary || false;
+
+            if (this.pos.config.multi_currency_enable)
+        	{
+	            if (this.pos.currency_list.length>0)
+	            	this.foreign_currency=$.extend({}, this.pos.currency_list[0]);
+	            else
+	            	this.foreign_currency=false;
+	            this.multi_currency_checked=false;
+	            this.currency_total=0;
+	            this.currency_change=0;
+	            this.currency_paid=0;
+	            this.curr_input_selected=false;
+        	}
+            return this;
+        },
+	});
+}

+ 255 - 0
static/src/js/screens.js

@@ -0,0 +1,255 @@
+function ep_pos_screens(instance,module)
+{
+	var QWeb = instance.web.qweb;
+	var _t = instance.web._t;
+
+	var round_di = instance.web.round_decimals;
+	var round_pr = instance.web.round_precision;
+
+	module.PaymentScreenWidget=module.PaymentScreenWidget.extend(
+	{
+		init:function(parent,options)
+		{
+			var self=this;
+			
+			this._super(parent,options);
+			this.line_click_handler = function(event){
+                var node = this;
+                self.pos.get('selectedOrder').curr_input_selected=false;
+                while(node && !node.classList.contains('paymentline')){
+                    node = node.parentNode;
+                }
+                if(node){
+                    self.pos.get('selectedOrder').selectPaymentline(node.line);
+                }
+            };
+		},
+		findWithAttr: function(array, attr, value) 
+		{
+		    for(var i = 0; i < array.length; i += 1) 
+		    {
+		        if(array[i][attr] === value) 
+		            return i;
+		    }
+		},
+		
+		format_foreign: function(amount,currency,precision)
+		{
+            var decimals = currency.decimals;
+            
+            if (precision && (typeof this.pos.dp[precision]) !== undefined) {
+                decimals = this.pos.dp[precision];
+            }
+            if (typeof amount === 'number') {
+                amount = round_di(amount,decimals).toFixed(decimals);
+                amount = openerp.instances[this.session.name].web.format_value(round_di(amount, decimals), { type: 'float', digits: [69, decimals]});
+            }
+
+            if (currency.position === 'after') {
+                return amount + ' ' + (currency.symbol || '');
+            } else {
+                return (currency.symbol || '') + ' ' + amount;
+            }
+        },
+        
+        set_foreign_values: function()
+		{
+			var self=this;
+			var currentOrder=self.pos.get('selectedOrder');
+			
+			var currency_id=currentOrder.foreign_currency.id;
+			var name=currentOrder.foreign_currency.name;
+			var rate_silent=currentOrder.foreign_currency.rate_silent;
+			var decimals=currentOrder.foreign_currency.decimals;
+			
+			if (self.pos.config.display_conversion)
+				// '1 '+self.pos.currency.name+' = '+
+				self.$('#conversion_rate').html('Cambio de ' + name + ' = ' + rate_silent + ' '); 
+						
+			
+			self.$('#currency_value_label').html('Total en '+ name + ':');
+			self.$('#foreign_input_label').html('Pagado en '+ name + ':');
+			self.$('#currency_value').html(self.format_foreign(currentOrder.currency_total,currentOrder.foreign_currency));
+			self.$('#foreign_change_label').html('Cambio en ' + name + ':');
+			self.$('#foreign_change_value').html(self.format_foreign(0,currentOrder.foreign_currency));
+		},
+		
+		show: function()
+		{
+            this._super();
+            var self = this;
+            if (self.pos.config.multi_currency_enable)
+        	{
+            	currentOrder=self.pos.get('selectedOrder');
+            	self.$('#curr_input').focus(function(e){
+            		if (this.value!='')
+            			$(this).select();
+            		if(self.numpad_state){
+                        self.numpad_state.reset();
+                    }
+            		currentOrder.curr_input_selected=true;
+            		
+            		e.stopImmediatePropagation();
+        		});
+	            self.$('#toggle_multi_currency').change(function(e)
+	    		{
+	            	if (self.pos.currency_list.length==0)
+	        		{
+		            	self.pos_widget.screen_selector.show_popup('error',{
+	                        message: 'No Foreign Currency found !',
+	                        comment: 'No foreign currencies have been defined. Either set the parameter to fetch from master or define them manually in the POS session configuration.'
+	                    });
+		            	return false;
+	        		}
+
+	            	currentOrder.multi_currency_checked=self.$('#toggle_multi_currency').prop("checked");
+	    			if (currentOrder.multi_currency_checked)
+    				{
+	    				self.$('#multi_currency').show();
+		            	self.$('#foreign_change_div').show();
+	    				self.$('#curr_input').focus();
+	    				if (self.$('#curr_input').val()!='')
+	    					self.$('#curr_input').select();
+	    				currentOrder.curr_input_selected=true;
+	    				if(self.numpad_state){
+	                        self.numpad_state.reset();
+	                    }
+    				}
+	    			else
+    				{
+	    				self.$('#multi_currency').hide();
+	            		self.$('#foreign_change_div').hide();
+	            		currentOrder.curr_input_selected=false;
+	    				self.focus_selected_line();
+    				}
+
+	    			e.stopImmediatePropagation();
+	    		});
+	            
+	            self.$('#toggle_multi_currency').prop("checked",currentOrder.multi_currency_checked);
+	            
+	            if(currentOrder.multi_currency_checked && currentOrder.foreign_currency)
+	        	{
+		            self.$('#curr_input').trigger('keyup');
+	        	}
+	            var foreign_decimals=currentOrder.foreign_currency.decimals;
+	            var foreign_currency_rate=currentOrder.foreign_currency.rate_silent;
+	            // Modificacion
+				currentOrder.currency_total=round_di(currentOrder.getTotalTaxIncluded()/foreign_currency_rate,foreign_decimals).toFixed(foreign_decimals);
+	            
+	            self.set_foreign_values();
+	            if (currentOrder.currency_paid==0)
+	            	self.$('#curr_input').val('');
+	            else
+	            	self.$('#curr_input').val(currentOrder.currency_paid);
+	            
+	            self.$('#curr_input').keyup(function(e)
+				{
+					currentOrder.currency_paid=self.$('#curr_input').val();
+					var line = currentOrder.selected_paymentline;
+					if (line==undefined)
+					{
+						self.pos_widget.screen_selector.show_popup('error',{
+	                        message: 'No Payment Line selected !',
+	                        comment: 'Please selected the payment line you would like the converted currency to display'
+	                    });
+						return false;
+					}
+					converted_value=round_di(this.value*currentOrder.foreign_currency.rate_silent,self.pos.currency.decimals).toFixed(self.pos.currency.decimals);
+					line.set_amount(converted_value);
+					self.$('.paymentline.selected input').val(converted_value);
+					
+					e.stopImmediatePropagation();
+				});
+	            
+	            self.$("#currency_selection").change(function(e)
+				{
+					var currentOrder=self.pos.get('selectedOrder');
+					var selected_currency=parseInt($(this).val());
+					
+					selected_id=self.findWithAttr(self.pos.currency_list, 'id', selected_currency);
+					currentOrder.foreign_currency=$.extend({}, self.pos.currency_list[selected_id]);
+					
+					var foreign_currency_rate=currentOrder.foreign_currency.rate_silent;
+
+					currentOrder.currency_total=round_di(currentOrder.getTotalTaxIncluded()/foreign_currency_rate,foreign_decimals).toFixed(foreign_decimals);
+					self.$('#curr_input').val(0);
+					
+					var line = currentOrder.selected_paymentline;
+					if (line==undefined)
+					{
+						self.$('.paymentline input').val(0);
+						return false;
+					}
+					line.set_amount(0);
+					self.$('.paymentline.selected input').val(0);
+					
+					self.set_foreign_values();
+					
+					e.stopImmediatePropagation();
+				});
+	            
+	            self.$("#currency_selection").val(currentOrder.foreign_currency.id);
+	            self.$('#toggle_multi_currency').trigger('change');
+        	}
+		},
+		
+		add_paymentline: function(line){
+			this._super(line);
+			this.pos.get('selectedOrder').curr_input_selected=false;
+		},
+		
+        set_value: function(val) {
+        	
+        	var self=this;
+        	var curr_input_selected=this.pos.get('selectedOrder').curr_input_selected;
+        	if (curr_input_selected)
+        	{
+        		var foreign_decimals=currentOrder.foreign_currency.decimals;
+        		value=round_di(val,foreign_decimals).toFixed(foreign_decimals);
+        		self.$('#curr_input').val(value);
+	            self.$('#curr_input').trigger('keyup');
+        	}
+        	else
+        	{
+	            var selected_line =this.pos.get('selectedOrder').selected_paymentline;
+	            if(selected_line){
+	                selected_line.set_amount(val);
+	                selected_line.node.querySelector('input').value = selected_line.amount.toFixed(2);
+	            }
+        	}
+        },
+		
+		update_payment_summary: function()
+		{
+			this._super();
+			
+			var self=this;
+			var currentOrder=self.pos.get('selectedOrder');
+			
+			if(self.pos.config.multi_currency_enable && currentOrder.foreign_currency)
+			{
+				var paidTotal = currentOrder.getPaidTotal();
+	            var dueTotal = currentOrder.getTotalTaxIncluded();
+	            var remaining = dueTotal > paidTotal ? dueTotal - paidTotal : 0;
+	            var change = paidTotal > dueTotal ? paidTotal - dueTotal : 0;
+				
+				var fc=currentOrder.foreign_currency;
+				var rate=fc.rate_silent;
+				var decimals=fc.decimals;
+
+				var converted_value=round_di(change/rate,decimals).toFixed(decimals);
+				
+				currentOrder.currency_change=converted_value;
+				self.$('#foreign_change_value').html(self.format_foreign(converted_value,fc));
+			}
+		},
+		
+		get_currency_selection:function()
+		{
+			var self=this;
+			var currentOrder=this.pos.get('selectedOrder');
+			return currentOrder.pos.currency_list[0];
+		},
+	});
+}

+ 76 - 0
static/src/xml/pos.xml

@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<templates>
+	<t t-extend="PaymentScreenWidget">
+		<t t-jquery=".payment-due-total" t-operation="after">
+			<t t-if="widget.pos.config.multi_currency_enable">
+				<div>
+					<div class="onoffswitch" style="float:left">
+					    <input type="checkbox" name="toggle_multi_currency" class="onoffswitch-checkbox" id="toggle_multi_currency" />
+					    <label class="onoffswitch-label" for="toggle_multi_currency">
+					        <span class="onoffswitch-inner"></span>
+					        <span class="onoffswitch-switch"></span>
+					    </label>
+					</div>
+					<div style="padding:5px;text-align:right !important;float:left">
+						<span> Moneda Extranjera</span>
+					</div>
+				</div>
+				<br/><br/>
+				<div id="multi_currency" style="display:none;border:1px solid lightgrey;">
+					
+					<div class="foreign_infoline">
+						<label class="left-block" id="currency_selection_label" 
+									for="currency_selection">Moneda: </label>
+						
+						<t t-set="selected_curr" t-value="widget.get_currency_selection()" />
+						<select style="height:30px;width:50%;" 
+								class="right-block" id="currency_selection">
+						    <t t-foreach="widget.pos.currency_list" t-as="currencylist">
+						    	<t t-if="selected_curr==currencylist.id">
+							        <option selected="selected" t-att-value="currencylist.id">
+							        	<b><t t-esc="currencylist.name"/></b>
+						        	</option>
+					        	</t>
+					        	<t t-if="selected_curr!=currencylist.id">
+							        <option t-att-value="currencylist.id">
+							        	<b><t t-esc="currencylist.name"/></b>
+						        	</option>
+					        	</t>
+						    </t>
+						</select>
+					</div>
+					<t t-if="widget.pos.config.display_conversion">
+						<div class="foreign_infoline" style="text-align:center;font-weight:bold"
+							 id="conversion_rate">
+						 </div>
+					 </t>
+					<div class="foreign_infoline">
+						<span class="left-block" id="currency_value_label"></span>
+						<span id="currency_value" class="right-block"></span>
+					</div>
+					<div class="foreign_infoline">
+						<span id="foreign_input_label" class="left-block"></span>
+						<input placeholder="Ingresar Valor" 
+								class="paymentline-input-foreign right-block" 
+								id="curr_input" type="number" step="0.01" pattern="!/^([0-9])*$/" min="0.0"></input>
+								<!-- Expresion regular orginal -->
+								<!-- [0-9]+([\.][0-9]+)? -->
+								<!-- Nueva expresion regular -->
+								<!-- !/^([0-9])*$/ -->
+					</div>
+				</div>
+				<br/>
+			</t>
+		</t>
+		<t t-jquery=".infoline.bigger" t-operation="after">
+			<t t-if="widget.pos.config.multi_currency_enable">
+				<div class="infoline bigger" id="foreign_change_div" style="display:none">
+	               <span class='left-block' id="foreign_change_label">
+	               </span>
+	               <span class="right-block" id="foreign_change_value"></span>
+	           </div>
+           </t>
+		</t>
+	</t>
+</templates>
+

+ 19 - 0
web_customization_data.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+    <data>
+    
+    <template id="index" inherit_id='point_of_sale.index' name="mom">&lt;!DOCTYPE html&gt;
+            <xpath expr="//link[@id='pos-stylesheet']" position="after">
+                <link rel="stylesheet" href="/pos_multi_currency/static/src/css/pos.css" />
+            </xpath>
+        </template>
+    
+     <template id="assets_frontend" inherit_id="web.assets_common">
+          <xpath expr="." position="inside">
+			<script type="text/javascript" src="/pos_multi_currency/static/src/js/main.js"/>
+			<script type="text/javascript" src="/pos_multi_currency/static/src/js/models.js"/>
+			<script type="text/javascript" src="/pos_multi_currency/static/src/js/screens.js"/>
+          </xpath>
+        </template>
+    </data>
+</openerp>