From 5327869356ca629728ef45ebdef2598c1d02dd4b Mon Sep 17 00:00:00 2001
From: Darshan Kalola <dka@openerp.com>
Date: Mon, 17 Aug 2015 11:24:52 +0530
Subject: [PATCH] [IMP]point of sale: added fiscal_position_id field in pos
 config to set fiscal postion on each shop.

---
 addons/point_of_sale/point_of_sale.py        | 48 ++++++++++----------
 addons/point_of_sale/point_of_sale_view.xml  | 18 ++++----
 addons/point_of_sale/static/src/js/models.js | 27 +++++++++--
 3 files changed, 57 insertions(+), 36 deletions(-)

diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py
index dfc452962278..5bf2d7e43864 100644
--- a/addons/point_of_sale/point_of_sale.py
+++ b/addons/point_of_sale/point_of_sale.py
@@ -126,6 +126,7 @@ class pos_config(osv.osv):
         'group_pos_manager_id': fields.many2one('res.groups','Point of Sale Manager Group', help='This field is there to pass the id of the pos manager group to the point of sale client'),
         'group_pos_user_id':    fields.many2one('res.groups','Point of Sale User Group', help='This field is there to pass the id of the pos user group to the point of sale client'),
         'tip_product_id':       fields.many2one('product.product','Tip Product', help="The product used to encode the customer tip. Leave empty if you do not accept tips."),
+        'fiscal_position_id': fields.many2one('account.fiscal.position', 'Fiscal Position'),
     }
 
     def _check_company_location(self, cr, uid, ids, context=None):
@@ -663,7 +664,7 @@ class pos_order(osv.osv):
     _order = "id desc"
 
     def _amount_line_tax(self, cr, uid, line, context=None):
-        taxes = line.product_id.taxes_id.filtered(lambda t: t.company_id.id == line.order_id.company_id.id)
+        taxes = (line.tax_ids or line.product_id.taxes_id).filtered(lambda t: t.company_id.id == line.order_id.company_id.id)
         price = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
         cur = line.order_id.pricelist_id.currency_id
         taxes = taxes.compute_all(price, cur, line.qty, product=line.product_id, partner=line.order_id.partner_id or False)['taxes']
@@ -1148,10 +1149,10 @@ class pos_order(osv.osv):
                 #Oldlin trick
                 invoice_line = inv_line_ref.new(cr, SUPERUSER_ID, inv_line, context=local_context)
                 invoice_line._onchange_product_id()
-                invoice_line.invoice_line_tax_ids = [tax.id for tax in invoice_line.invoice_line_tax_ids if tax.company_id.id == company_id]
                 # We convert a new id object back to a dictionary to write to bridge between old and new api
                 inv_line = invoice_line._convert_to_write(invoice_line._cache)
-                inv_line.update(price_unit=line.price_unit, discount=line.discount)
+                taxes = (line.tax_ids or invoice_line.invoice_line_tax_ids).filtered(lambda t: t.company_id.id == company_id)
+                inv_line.update(price_unit=line.price_unit, discount=line.discount, invoice_line_tax_ids=[(6, 0, taxes.ids)])
                 inv_line_ref.create(cr, SUPERUSER_ID, inv_line, context=local_context)
             inv_ref.compute_taxes(cr, SUPERUSER_ID, [inv_id], context=local_context)
             self.signal_workflow(cr, uid, [order.id], 'invoice')
@@ -1313,12 +1314,10 @@ class pos_order(osv.osv):
 
                 # Create the tax lines
                 taxes = []
-                for t in line.product_id.taxes_id:
-                    if t.company_id.id == current_company.id:
-                        taxes.append(t.id)
+                taxes = (line.tax_ids or line.product_id.taxes_id).filtered(lambda t: t.company_id.id == current_company.id)
                 if not taxes:
                     continue
-                for tax in account_tax_obj.browse(cr,uid, taxes, context=context).compute_all(line.price_unit * (100.0-line.discount) / 100.0, cur, line.qty)['taxes']:
+                for tax in taxes.compute_all(line.price_unit * (100.0-line.discount) / 100.0, cur, line.qty)['taxes']:
                     insert_data('tax', {
                         'name': _('Tax') + ' ' + tax['name'],
                         'product_id': line.product_id.id,
@@ -1395,19 +1394,18 @@ class pos_order_line(osv.osv):
 
     def _amount_line_all(self, cr, uid, ids, field_names, arg, context=None):
         res = dict([(i, {}) for i in ids])
-        account_tax_obj = self.pool.get('account.tax')
         for line in self.browse(cr, uid, ids, context=context):
             cur = line.order_id.pricelist_id.currency_id
-            taxes_ids = [ tax.id for tax in line.product_id.taxes_id if tax.company_id.id == line.order_id.company_id.id ]
+            taxes = (line.tax_ids or line.product_id.taxes_id).filtered(lambda t: t.company_id.id == line.order_id.company_id.id)
             price = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
             res[line.id]['price_subtotal'] = res[line.id]['price_subtotal_incl'] = price * line.qty
-            if taxes_ids:
-                taxes = account_tax_obj.browse(cr, uid, taxes_ids, context).compute_all(price, cur, line.qty, product=line.product_id, partner=line.order_id.partner_id or False)
-                res[line.id]['price_subtotal'] = taxes['total_excluded']
-                res[line.id]['price_subtotal_incl'] = taxes['total_included']
+            if taxes:
+                dict_taxes = taxes.compute_all(price, cur, line.qty, product=line.product_id, partner=line.order_id.partner_id or False)
+                res[line.id]['price_subtotal'] = dict_taxes['total_excluded']
+                res[line.id]['price_subtotal_incl'] = dict_taxes['total_included']
         return res
 
-    def onchange_product_id(self, cr, uid, ids, pricelist, product_id, qty=0, partner_id=False, context=None):
+    def onchange_product_id(self, cr, uid, ids, pricelist, product_id, qty=0, partner_id=False, session_id=False, context=None):
         context = context or {}
         if not product_id:
            return {}
@@ -1419,28 +1417,30 @@ class pos_order_line(osv.osv):
         price = self.pool.get('product.pricelist').price_get(cr, uid, [pricelist],
                product_id, qty or 1.0, partner_id)[pricelist]
 
-        result = self.onchange_qty(cr, uid, ids, pricelist, product_id, 0.0, qty, price, context=context)
+        result = self.onchange_qty(cr, uid, ids, pricelist=pricelist, product=product_id, discount=0.0, qty=qty, price_unit=price, session_id=session_id, context=context)
         result['value']['price_unit'] = price
         return result
 
-    def onchange_qty(self, cr, uid, ids, pricelist, product, discount, qty, price_unit, context=None):
+    def onchange_qty(self, cr, uid, ids, pricelist, product, discount, qty, price_unit, session_id=False, context=None):
         result = {}
         if not product:
             return result
         if not pricelist:
            raise UserError(_('You have to select a pricelist in the sale form !'))
 
-        account_tax_obj = self.pool.get('account.tax')
-
+        session = self.pool['pos.session'].browse(cr, uid, session_id, context)
         prod = self.pool.get('product.product').browse(cr, uid, product, context=context)
-
+        taxes = prod.taxes_id
+        if session.config_id and session.config_id.fiscal_position_id:
+            taxes = session.config_id.fiscal_position_id.map_tax(prod.taxes_id)
         price = price_unit * (1 - (discount or 0.0) / 100.0)
         result['price_subtotal'] = result['price_subtotal_incl'] = price * qty
         cur = self.pool.get('product.pricelist').browse(cr, uid, [pricelist], context=context).currency_id
-        if (prod.taxes_id):
-            taxes = prod.taxes_id.compute_all(price, cur, qty, product=prod, partner=False)
-            result['price_subtotal'] = taxes['total_excluded']
-            result['price_subtotal_incl'] = taxes['total_included']
+        if (taxes):
+            dict_taxes = taxes.compute_all(price, cur, qty, product=prod, partner=False)
+            result['price_subtotal'] = dict_taxes['total_excluded']
+            result['price_subtotal_incl'] = dict_taxes['total_included']
+            result['tax_ids'] = taxes
         return {'value': result}
 
     _columns = {
@@ -1455,7 +1455,7 @@ class pos_order_line(osv.osv):
         'discount': fields.float('Discount (%)', digits=0),
         'order_id': fields.many2one('pos.order', 'Order Ref', ondelete='cascade'),
         'create_date': fields.datetime('Creation Date', readonly=True),
-        'tax_ids': fields.many2many('account.tax', string='Taxes', readonly=True),
+        'tax_ids': fields.many2many('account.tax', string='Taxes'),
     }
 
     _defaults = {
diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml
index 6abcd3231337..e192e5e9322e 100644
--- a/addons/point_of_sale/point_of_sale_view.xml
+++ b/addons/point_of_sale/point_of_sale_view.xml
@@ -34,20 +34,21 @@
                         <page string="Products">
                             <field name="lines" colspan="4" nolabel="1">
                                 <tree string="Order lines" editable="bottom">
-                                    <field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,qty,parent.partner_id)"/>
-                                    <field name="qty" on_change="onchange_qty(parent.pricelist_id,product_id, discount, qty, price_unit, context)"/>
-                                    <field name="price_unit" on_change="onchange_qty(parent.pricelist_id,product_id, discount, qty, price_unit, context)" widget="monetary"/>
-                                    <field name="discount"  on_change="onchange_qty(parent.pricelist_id,product_id, discount, qty, price_unit, context)" widget="monetary"/>
+                                    <field name="product_id" on_change="onchange_product_id(parent.pricelist_id, product_id, qty, parent.partner_id, parent.session_id)"/>
+                                    <field name="qty" on_change="onchange_qty(parent.pricelist_id,product_id, discount, qty, price_unit, parent.session_id, context)"/>
+                                    <field name="price_unit" on_change="onchange_qty(parent.pricelist_id,product_id, discount, qty, price_unit, parent.session_id, context)" widget="monetary"/>
+                                    <field name="discount"  on_change="onchange_qty(parent.pricelist_id,product_id, discount, qty, price_unit, parent.session_id, context)" widget="monetary"/>
                                     <field name="tax_ids" widget="many2many_tags"/>
                                     <field name="price_subtotal" widget="monetary"/>
                                     <field name="price_subtotal_incl" widget="monetary"/>
                                 </tree>
                                 <form string="Order lines">
                                     <group col="4">
-                                        <field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,qty,parent.partner_id)"/>
-                                        <field name="qty" on_change="onchange_qty(parent.pricelist_id,product_id, discount, qty, price_unit, context)"/>
-                                        <field name="discount"  on_change="onchange_qty(parent.pricelist_id,product_id, discount, qty, price_unit, context)" widget="monetary"/>
-                                        <field name="price_unit" on_change="onchange_qty(parent.pricelist_id,product_id, discount, qty, price_unit, context)" widget="monetary"/>
+                                        <field name="product_id" on_change="onchange_product_id(parent.pricelist_id, product_id, qty, parent.partner_id, parent.session_id)"/>
+                                        <field name="qty" on_change="onchange_qty(parent.pricelist_id,product_id, discount, qty, price_unit, parent.session_id, context)"/>
+                                        <field name="price_unit" on_change="onchange_qty(parent.pricelist_id,product_id, discount, qty, price_unit, parent.session_id, context)" widget="monetary"/>
+                                        <field name="discount" on_change="onchange_qty(parent.pricelist_id, product_id, discount, qty, price_unit, parent.session_id, context)" widget="monetary"/>
+                                        <field name="tax_ids" widget="many2many_tags"/>
                                         <field name="price_subtotal" invisible="1" widget="monetary"/>
                                         <field name="price_subtotal_incl" invisible="1" widget="monetary"/>
                                         <field name="notice"/>
@@ -661,6 +662,7 @@
                             <field name="group_by" groups="account.group_account_user"/>
                             <field name="barcode_nomenclature_id" />
                             <field name="sequence_id" readonly="1" groups="base.group_no_one"/>
+                            <field name="fiscal_position_id" options="{'no_create': True}"/>
                             <field name="currency_id" invisible="1"/>
                         </group>
                         <separator string="Available Payment Methods" colspan="4"/>
diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js
index 84fc1f426349..75d3c1d00ce0 100644
--- a/addons/point_of_sale/static/src/js/models.js
+++ b/addons/point_of_sale/static/src/js/models.js
@@ -276,6 +276,13 @@ exports.PosModel = Backbone.Model.extend({
             self.users = pos_users; 
         },
     },{
+        model:  'account.fiscal.position.tax',
+        fields: ['position_id', 'tax_src_id', 'tax_dest_id'],
+        domain: function(self) { return [['position_id', '=', self.config.fiscal_position_id && self.config.fiscal_position_id[0]]]; },
+        loaded: function(self, fiscal_position_tax) {
+            self.fiscal_position_tax = fiscal_position_tax;
+        },
+     },{
         model: 'stock.location',
         fields: [],
         ids:    function(self){ return [self.config.stock_location_id[0]]; },
@@ -1241,11 +1248,24 @@ exports.Orderline = Backbone.Model.extend({
     get_tax: function(){
         return this.get_all_prices().tax;
     },
+    get_fiscal_tax: function() {
+        var self = this;
+        var product_tax = this.get_product().taxes_id;
+        if(product_tax && this.pos.config.fiscal_position_id) {
+            _.each(product_tax, function(v, i) {
+                var fiscal_tax = _.filter(self.pos.fiscal_position_tax, function(t) { return t.tax_src_id[0] == v });
+                if(fiscal_tax.length) {
+                    product_tax[i] = fiscal_tax[0].tax_dest_id[0];
+                }
+            });
+        }
+        return _.uniq(_.compact(product_tax));
+    },
     get_applicable_taxes: function(){
         var i;
         // Shenaningans because we need
         // to keep the taxes ordering.
-        var ptaxes_ids = this.get_product().taxes_id;
+        var ptaxes_ids = this.get_fiscal_tax();
         var ptaxes_set = {};
         for (i = 0; i < ptaxes_ids.length; i++) {
             ptaxes_set[ptaxes_ids[i]] = true;
@@ -1262,7 +1282,7 @@ exports.Orderline = Backbone.Model.extend({
         return this.get_all_prices().taxDetails;
     },
     get_taxes: function(){
-        var taxes_ids = this.get_product().taxes_id;
+        var taxes_ids = this.get_fiscal_tax();
         var taxes = [];
         for (var i = 0; i < taxes_ids.length; i++) {
             taxes.push(this.pos.taxes_by_id[taxes_ids[i]]);
@@ -1332,8 +1352,7 @@ exports.Orderline = Backbone.Model.extend({
         var price_unit = this.get_unit_price() * (1.0 - (this.get_discount() / 100.0));
         var taxtotal = 0;
 
-        var product =  this.get_product();
-        var taxes_ids = product.taxes_id;
+        var taxes_ids = this.get_fiscal_tax();
         var taxes =  this.pos.taxes;
         var taxdetail = {};
         var product_taxes = [];
-- 
GitLab