@ -0,0 +1,21 @@ | 
				
			|||||
 | 
					================= | 
				
			||||
 | 
					Pos Discounts v19 | 
				
			||||
 | 
					================= | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					This module adds a feature to provide several types of discounts in point of sale. | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					Installation | 
				
			||||
 | 
					============ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					Just select it from available modules to install it, there is no need to extra installations. | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					Configuration | 
				
			||||
 | 
					============= | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					We need to specify a discount account when we create the point of sale. This account will be used to record the discount amount. | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					Credits | 
				
			||||
 | 
					======= | 
				
			||||
 | 
					Developer: Linto CT @ cybrosys, linto@cybrosys.in | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,4 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import models | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,52 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					############################################################################## | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    Cybrosys Technologies Pvt. Ltd. | 
				
			||||
 | 
					#    Copyright (C) 2017-TODAY Cybrosys Technologies(<https://www.cybrosys.com>). | 
				
			||||
 | 
					#    Author: LINTO C T(<https://www.cybrosys.com>) | 
				
			||||
 | 
					#    you can modify it under the terms of the GNU LESSER | 
				
			||||
 | 
					#    GENERAL PUBLIC LICENSE (LGPL v3), Version 3. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    It is forbidden to publish, distribute, sublicense, or sell copies | 
				
			||||
 | 
					#    of the Software or modified copies of the Software. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					#    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE | 
				
			||||
 | 
					#    GENERAL PUBLIC LICENSE (LGPL v3) along with this program. | 
				
			||||
 | 
					#    If not, see <https://www.gnu.org/licenses/>. | 
				
			||||
 | 
					# | 
				
			||||
 | 
					############################################################################## | 
				
			||||
 | 
					{ | 
				
			||||
 | 
					    'name': 'Point of Sale Discounts', | 
				
			||||
 | 
					    'version': '9.0.1.0.0', | 
				
			||||
 | 
					    'category': 'Point of Sale', | 
				
			||||
 | 
					    'summary': 'Discounts in the Point of Sale(Fixed and Percentage) ', | 
				
			||||
 | 
					    'author': 'Cybrosys Techno Solutions', | 
				
			||||
 | 
					    'company': 'Cybrosys Techno Solutions', | 
				
			||||
 | 
					    'images': ['static/description/banner.jpg'], | 
				
			||||
 | 
					    'website': 'https://www.cybrosys.com', | 
				
			||||
 | 
					    'depends': ['base', 'point_of_sale', 'account', 'report', 'account_accountant'], | 
				
			||||
 | 
					    'data': [ | 
				
			||||
 | 
					        'views/report_paperformat_new.xml', | 
				
			||||
 | 
					        'views/templates.xml', | 
				
			||||
 | 
					        'views/report_payment_new.xml', | 
				
			||||
 | 
					        'views/pos_reports_new_invoice.xml', | 
				
			||||
 | 
					        'views/report_saleslines_new.xml', | 
				
			||||
 | 
					        'views/report_receipt_new.xml', | 
				
			||||
 | 
					        'views/account_invoice_view_pos.xml', | 
				
			||||
 | 
					        'views/pos_reports_account_invoice.xml', | 
				
			||||
 | 
					        'views/pos_view.xml', | 
				
			||||
 | 
					    ], | 
				
			||||
 | 
					    'qweb': [ | 
				
			||||
 | 
					        'static/src/xml/discount.xml' | 
				
			||||
 | 
					        ], | 
				
			||||
 | 
					    'license': 'AGPL-3', | 
				
			||||
 | 
					    'installable': True, | 
				
			||||
 | 
					    'auto_install': False, | 
				
			||||
 | 
					} | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,7 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import pos_order_lines_new | 
				
			||||
 | 
					import pos_payment_report_new | 
				
			||||
 | 
					import pos_lines_new | 
				
			||||
 | 
					import pos_invoice_new | 
				
			||||
 | 
					import pos_receipt_new | 
				
			||||
@ -0,0 +1,49 @@ | 
				
			|||||
 | 
					import time | 
				
			||||
 | 
					from openerp.osv import osv | 
				
			||||
 | 
					from openerp.report import report_sxw | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class pos_payment_report(report_sxw.rml_parse): | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def __init__(self, cr, uid, name, context): | 
				
			||||
 | 
					        super(pos_payment_report, self).__init__(cr, uid, name, context=context) | 
				
			||||
 | 
					        self.total = 0.0 | 
				
			||||
 | 
					        self.localcontext.update({ | 
				
			||||
 | 
					            'time': time, | 
				
			||||
 | 
					            'pos_payment': self._pos_payment, | 
				
			||||
 | 
					            'pos_payment_total':self._pos_payment_total, | 
				
			||||
 | 
					        }) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def _pos_payment(self, obj): | 
				
			||||
 | 
					        self.total = 0 | 
				
			||||
 | 
					        data={} | 
				
			||||
 | 
					        sql = """ select id from pos_order where id = %d"""%(obj.id) | 
				
			||||
 | 
					        self.cr.execute(sql) | 
				
			||||
 | 
					        if self.cr.fetchone(): | 
				
			||||
 | 
					            self.cr.execute ("select pt.name,pp.default_code as code,pol.qty,pu.name as uom,pol.discount,pol.price_unit, " \ | 
				
			||||
 | 
					                                 "(pol.price_unit * pol.qty * (1 - (pol.discount) / 100.0)) as total  " \ | 
				
			||||
 | 
					                                 "from pos_order as po,pos_order_line as pol,product_product as pp,product_template as pt, product_uom as pu " \ | 
				
			||||
 | 
					                                 "where pt.id=pp.product_tmpl_id and pp.id=pol.product_id and po.id = pol.order_id  and pu.id=pt.uom_id " \ | 
				
			||||
 | 
					                                 "and po.state IN ('paid','invoiced') and to_char(date_trunc('day',po.date_order),'YYYY-MM-DD')::date = current_date and po.id=%d"%(obj.id)) | 
				
			||||
 | 
					            data=self.cr.dictfetchall() | 
				
			||||
 | 
					        else: | 
				
			||||
 | 
					            self.cr.execute ("select pt.name,pp.default_code as code,pol.qty,pu.name as uom,pol.discount,pol.price_unit, " \ | 
				
			||||
 | 
					                                 "(pol.price_unit * pol.qty * (1 - (pol.discount) / 100.0)) as total  " \ | 
				
			||||
 | 
					                                 "from pos_order as po,pos_order_line as pol,product_product as pp,product_template as pt, product_uom as pu  " \ | 
				
			||||
 | 
					                                 "where pt.id=pp.product_tmpl_id and pp.id=pol.product_id and po.id = pol.order_id and pu.id=pt.uom_id  " \ | 
				
			||||
 | 
					                                 "and po.state IN ('paid','invoiced') and to_char(date_trunc('day',po.date_order),'YYYY-MM-DD')::date = current_date") | 
				
			||||
 | 
					            data=self.cr.dictfetchall() | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        for d in data: | 
				
			||||
 | 
					            self.total += d['price_unit'] * d['qty'] | 
				
			||||
 | 
					        return data | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def _pos_payment_total(self, o): | 
				
			||||
 | 
					        return self.total | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class report_pos_payment(osv.AbstractModel): | 
				
			||||
 | 
					    _name = 'report.point_of_sale.report_payment' | 
				
			||||
 | 
					    _inherit = 'report.abstract_report' | 
				
			||||
 | 
					    _template = 'point_of_sale.report_payment' | 
				
			||||
 | 
					    _wrapped_report_class = pos_payment_report | 
				
			||||
@ -0,0 +1,166 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					from openerp import SUPERUSER_ID | 
				
			||||
 | 
					from openerp.osv import osv | 
				
			||||
 | 
					from openerp.tools import float_is_zero | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					from openerp.exceptions import UserError | 
				
			||||
 | 
					from openerp import api, fields, models, _ | 
				
			||||
 | 
					import openerp.addons.decimal_precision as dp | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class PosInvoiceReportNew(osv.AbstractModel): | 
				
			||||
 | 
					    _name = 'report.discounts_in_pos.report_invoice' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def render_html(self, cr, uid, ids, data=None, context=None): | 
				
			||||
 | 
					        report_obj = self.pool['report'] | 
				
			||||
 | 
					        posorder_obj = self.pool['pos.order'] | 
				
			||||
 | 
					        report = report_obj._get_report_from_name(cr, uid, 'discounts_in_pos.report_invoice') | 
				
			||||
 | 
					        selected_orders = posorder_obj.browse(cr, uid, ids, context=context) | 
				
			||||
 | 
					        ids_to_print = [] | 
				
			||||
 | 
					        invoiced_posorders_ids = [] | 
				
			||||
 | 
					        for order in selected_orders: | 
				
			||||
 | 
					            if order.invoice_id: | 
				
			||||
 | 
					                ids_to_print.append(order.invoice_id.id) | 
				
			||||
 | 
					                invoiced_posorders_ids.append(order.id) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        not_invoiced_orders_ids = list(set(ids) - set(invoiced_posorders_ids)) | 
				
			||||
 | 
					        if not_invoiced_orders_ids: | 
				
			||||
 | 
					            not_invoiced_posorders = posorder_obj.browse(cr, uid, not_invoiced_orders_ids, context=context) | 
				
			||||
 | 
					            not_invoiced_orders_names = list(map(lambda a: a.name, not_invoiced_posorders)) | 
				
			||||
 | 
					            raise UserError(_('No link to an invoice for %s.') % ', '.join(not_invoiced_orders_names)) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        docargs = { | 
				
			||||
 | 
					            'docs': self.pool['account.invoice'].browse(cr, uid, ids_to_print, context=context) | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return report_obj.render(cr, SUPERUSER_ID, ids, 'discounts_in_pos.report_invoice', docargs, context=context) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class POSInvoiceNew(models.Model): | 
				
			||||
 | 
					    _inherit = 'account.invoice.line' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    discount_fixed = fields.Float(string='Discount.Fixed', digits=dp.get_precision('DiscountFixed'), | 
				
			||||
 | 
					                            default=0.0) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.one | 
				
			||||
 | 
					    @api.depends('price_unit', 'discount', 'invoice_line_tax_ids', 'quantity', | 
				
			||||
 | 
					                 'product_id', 'invoice_id.partner_id', 'invoice_id.currency_id', 'invoice_id.company_id') | 
				
			||||
 | 
					    def _compute_price(self): | 
				
			||||
 | 
					        super(POSInvoiceNew, self)._compute_price() | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        currency = self.invoice_id and self.invoice_id.currency_id or None | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        price = self.price_unit * (1 - (self.discount or 0.0) / 100.0) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if self.discount != 0: | 
				
			||||
 | 
					            price = self.price_unit * (1 - (self.discount or 0.0) / 100.0) | 
				
			||||
 | 
					        if self.discount_fixed != 0: | 
				
			||||
 | 
					            price = self.price_unit | 
				
			||||
 | 
					        taxes = False | 
				
			||||
 | 
					        if self.invoice_line_tax_ids: | 
				
			||||
 | 
					            taxes = self.invoice_line_tax_ids.compute_all(price, currency, self.quantity, product=self.product_id, | 
				
			||||
 | 
					                                                          partner=self.invoice_id.partner_id) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        self.price_subtotal = price_subtotal_signed = taxes['total_excluded'] if taxes else self.quantity * price | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if self.discount != 0: | 
				
			||||
 | 
					            self.price_subtotal = price_subtotal_signed = taxes['total_excluded'] if taxes else self.quantity * price | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if self.discount_fixed != 0: | 
				
			||||
 | 
					            self.price_subtotal = price_subtotal_signed = taxes[ | 
				
			||||
 | 
					                'total_excluded'] if taxes else self.quantity * price - self.discount_fixed | 
				
			||||
 | 
					        if self.invoice_id.currency_id and self.invoice_id.currency_id != self.invoice_id.company_id.currency_id: | 
				
			||||
 | 
					            price_subtotal_signed = self.invoice_id.currency_id.compute(price_subtotal_signed, | 
				
			||||
 | 
					                                                                        self.invoice_id.company_id.currency_id) | 
				
			||||
 | 
					        sign = self.invoice_id.type in ['in_refund', 'out_refund'] and -1 or 1 | 
				
			||||
 | 
					        self.price_subtotal_signed = price_subtotal_signed * sign | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class POSInvoiceTotalDisc(models.Model): | 
				
			||||
 | 
					    _inherit = 'account.invoice' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    discount_total = fields.Float(string='Total Discount', default=0.0) | 
				
			||||
 | 
					    discount_percent = fields.Float(string='Total Discount(%)', default=0.0) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.one | 
				
			||||
 | 
					    @api.depends('invoice_line_ids.price_subtotal', 'tax_line_ids.amount', 'currency_id', 'company_id') | 
				
			||||
 | 
					    def _compute_amount(self): | 
				
			||||
 | 
					        super(POSInvoiceTotalDisc, self)._compute_amount() | 
				
			||||
 | 
					        self.amount_total = self.amount_untaxed + self.amount_tax | 
				
			||||
 | 
					        if self.discount_total > 0: | 
				
			||||
 | 
					            self.amount_total -= self.discount_total | 
				
			||||
 | 
					        if self.discount_percent > 0: | 
				
			||||
 | 
					            self.amount_total -= ((self.amount_untaxed + self.amount_tax) * self.discount_percent / 100) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def _compute_residual(self): | 
				
			||||
 | 
					        super(POSInvoiceTotalDisc, self)._compute_residual() | 
				
			||||
 | 
					        residual = 0.0 | 
				
			||||
 | 
					        residual_company_signed = 0.0 | 
				
			||||
 | 
					        sign = self.type in ['in_refund', 'out_refund'] and -1 or 1 | 
				
			||||
 | 
					        for line in self.sudo().move_id.line_ids: | 
				
			||||
 | 
					            if line.account_id.internal_type in ('receivable', 'payable'): | 
				
			||||
 | 
					                residual_company_signed += line.amount_residual | 
				
			||||
 | 
					                if line.currency_id == self.currency_id: | 
				
			||||
 | 
					                    residual += line.amount_residual_currency if line.currency_id else line.amount_residual | 
				
			||||
 | 
					                else: | 
				
			||||
 | 
					                    from_currency = (line.currency_id and line.currency_id.with_context(date=line.date)) or line.company_id.currency_id.with_context(date=line.date) | 
				
			||||
 | 
					                    residual += from_currency.compute(line.amount_residual, self.currency_id) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if self.discount_total > 0: | 
				
			||||
 | 
					            residual -= self.discount_total | 
				
			||||
 | 
					        if self.discount_percent > 0: | 
				
			||||
 | 
					            residual -= self.amount_untaxed * self.discount_percent / 100 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        self.residual_company_signed = abs(residual_company_signed) * sign | 
				
			||||
 | 
					        self.residual_signed = abs(residual) * sign | 
				
			||||
 | 
					        self.residual = abs(residual) | 
				
			||||
 | 
					        digits_rounding_precision = self.currency_id.rounding | 
				
			||||
 | 
					        if float_is_zero(self.residual, precision_rounding=digits_rounding_precision): | 
				
			||||
 | 
					            self.reconciled = True | 
				
			||||
 | 
					        else: | 
				
			||||
 | 
					            self.reconciled = False | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.multi | 
				
			||||
 | 
					    def action_move_create(self): | 
				
			||||
 | 
					        res = super(POSInvoiceTotalDisc, self).action_move_create() | 
				
			||||
 | 
					        order = self.env['pos.order'].search([('invoice_id', '=', self.id)]) | 
				
			||||
 | 
					        session = None | 
				
			||||
 | 
					        if order: | 
				
			||||
 | 
					            if order.discount_total > 0 or order.discount_percent > 0: | 
				
			||||
 | 
					                session = order.session_id | 
				
			||||
 | 
					                discount_ac = None | 
				
			||||
 | 
					                if session: | 
				
			||||
 | 
					                    if session.config_id.discount_account: | 
				
			||||
 | 
					                       discount_ac = session.config_id.discount_account | 
				
			||||
 | 
					                    else: | 
				
			||||
 | 
					                        raise UserError(_('Please set a discount account for this session')) | 
				
			||||
 | 
					                lines = self.env['account.move.line'].search([('move_id', '=', self.move_id.id), ('debit', '>', 0)], limit=1) | 
				
			||||
 | 
					                if order.discount_total > 0: | 
				
			||||
 | 
					                    discount = order.discount_total | 
				
			||||
 | 
					                elif order.discount_percent > 0: | 
				
			||||
 | 
					                    move_lines = self.env['account.move.line'].search([('move_id', '=', self.move_id.id), ('credit', '>', 0)]) | 
				
			||||
 | 
					                    sum = 0 | 
				
			||||
 | 
					                    for i in move_lines: | 
				
			||||
 | 
					                        sum += i.credit | 
				
			||||
 | 
					                    discount = sum - order.amount_total | 
				
			||||
 | 
					                lines.write({ | 
				
			||||
 | 
					                    'debit': lines.debit - discount | 
				
			||||
 | 
					                }) | 
				
			||||
 | 
					                temp2 = { | 
				
			||||
 | 
					                    'partner_id': self.partner_id.id, | 
				
			||||
 | 
					                    'name': "Discount", | 
				
			||||
 | 
					                    'credit': 0, | 
				
			||||
 | 
					                    'debit': discount, | 
				
			||||
 | 
					                    'account_id': discount_ac.id, | 
				
			||||
 | 
					                    'quantity': 1, | 
				
			||||
 | 
					                    'move_id': self.move_id.id, | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                self.env['account.move.line'].create(temp2) | 
				
			||||
 | 
					        return res | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class PosConfigNew(models.Model): | 
				
			||||
 | 
					    _inherit = 'pos.config' | 
				
			||||
 | 
					    # discount account is used to enter the total discount values | 
				
			||||
 | 
					    discount_account = fields.Many2one('account.account', string="Discount Account", required=True) | 
				
			||||
@ -0,0 +1,42 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import time | 
				
			||||
 | 
					from openerp.osv import osv | 
				
			||||
 | 
					from openerp.report import report_sxw | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class pos_lines(report_sxw.rml_parse): | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def __init__(self, cr, uid, name, context): | 
				
			||||
 | 
					        super(pos_lines, self).__init__(cr, uid, name, context=context) | 
				
			||||
 | 
					        self.total = 0.0 | 
				
			||||
 | 
					        self.localcontext.update({ | 
				
			||||
 | 
					            'time': time, | 
				
			||||
 | 
					            'total_quantity': self.__total_quantity__, | 
				
			||||
 | 
					            'taxes':self.__taxes__, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        }) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def __total_quantity__(self, obj): | 
				
			||||
 | 
					        tot = 0 | 
				
			||||
 | 
					        for line in obj.lines: | 
				
			||||
 | 
					            tot += line.qty | 
				
			||||
 | 
					        self.total = tot | 
				
			||||
 | 
					        return self.total | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def __taxes__(self, obj): | 
				
			||||
 | 
					        self.cr.execute ( " Select acct.name from pos_order as po " \ | 
				
			||||
 | 
					                              " LEFT JOIN pos_order_line as pol ON po.id = pol.order_id " \ | 
				
			||||
 | 
					                              " LEFT JOIN product_product as pp ON pol.product_id = pp.id" | 
				
			||||
 | 
					                              " LEFT JOIN product_taxes_rel as ptr ON pp.product_tmpl_id = ptr.prod_id " \ | 
				
			||||
 | 
					                              " LEFT JOIN account_tax as acct ON acct.id = ptr.tax_id " \ | 
				
			||||
 | 
					                              " WHERE pol.id = %s", (obj.id,)) | 
				
			||||
 | 
					        res=self.cr.fetchone()[0] | 
				
			||||
 | 
					        return res | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class report_pos_lines(osv.AbstractModel): | 
				
			||||
 | 
					    _name = 'report.discounts_in_pos.report_saleslines' | 
				
			||||
 | 
					    _inherit = 'report.abstract_report' | 
				
			||||
 | 
					    _template = 'discounts_in_pos.report_saleslines' | 
				
			||||
 | 
					    _wrapped_report_class = pos_lines | 
				
			||||
@ -0,0 +1,503 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import logging | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					from openerp import SUPERUSER_ID | 
				
			||||
 | 
					from openerp.osv import fields, osv | 
				
			||||
 | 
					from openerp.tools.translate import _ | 
				
			||||
 | 
					from openerp.exceptions import UserError | 
				
			||||
 | 
					import openerp.addons.decimal_precision as dp | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					from openerp import api, models, fields as Fields | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					_logger = logging.getLogger(__name__) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class NewPosOrder(osv.osv): | 
				
			||||
 | 
					    _inherit = "pos.order" | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    discount_total = Fields.Float(string='Total Discount(Fixed)', default=0.0) | 
				
			||||
 | 
					    discount_percent = Fields.Float(string='Total Discount(%)', default=0.0) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    _defaults = { | 
				
			||||
 | 
					        'discount_total': lambda *a: 0.0, | 
				
			||||
 | 
					        'discount_percent': lambda *a: 0.0, | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.onchange('discount_percent') | 
				
			||||
 | 
					    def change_discount_fixed(self): | 
				
			||||
 | 
					        if self.discount_percent: | 
				
			||||
 | 
					            self.discount_total = 0.0 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.onchange('discount_total') | 
				
			||||
 | 
					    def change_discount_percent(self): | 
				
			||||
 | 
					        if self.discount_total: | 
				
			||||
 | 
					            self.discount_percent = 0.0 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.depends('statement_ids', 'lines.price_subtotal_incl', 'lines.discount', 'lines.discount_fixed','discount_total','discount_percent') | 
				
			||||
 | 
					    def _compute_amount_all(self): | 
				
			||||
 | 
					        super(NewPosOrder, self)._compute_amount_all() | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        for order in self: | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            currency = order.pricelist_id.currency_id | 
				
			||||
 | 
					            amount_untaxed = currency.round(sum(line.price_subtotal for line in order.lines)) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            order.amount_total = order.amount_tax + amount_untaxed | 
				
			||||
 | 
					            if order.discount_total > 0: | 
				
			||||
 | 
					                order.amount_total -= order.discount_total | 
				
			||||
 | 
					            if order.discount_percent > 0: | 
				
			||||
 | 
					                order.amount_total -= ((order.amount_tax + amount_untaxed) * order.discount_percent / 100) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def _order_fields(self, cr, uid, ui_order, context=None): | 
				
			||||
 | 
					        new_discount = super(NewPosOrder, self)._order_fields(cr, uid, ui_order) | 
				
			||||
 | 
					        new_discount['discount_total'] = ui_order['discount_total'] | 
				
			||||
 | 
					        new_discount['discount_percent'] = ui_order['discount_percent'] | 
				
			||||
 | 
					        return new_discount | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def action_invoice(self, cr, uid, ids, context=None): | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        inv_ref = self.pool.get('account.invoice') | 
				
			||||
 | 
					        inv_line_ref = self.pool.get('account.invoice.line') | 
				
			||||
 | 
					        product_obj = self.pool.get('product.product') | 
				
			||||
 | 
					        inv_ids = [] | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        for order in self.pool.get('pos.order').browse(cr, uid, ids, context=context): | 
				
			||||
 | 
					            # Force company for all SUPERUSER_ID action | 
				
			||||
 | 
					            company_id = order.company_id.id | 
				
			||||
 | 
					            local_context = dict(context or {}, force_company=company_id, company_id=company_id) | 
				
			||||
 | 
					            if order.invoice_id: | 
				
			||||
 | 
					                inv_ids.append(order.invoice_id.id) | 
				
			||||
 | 
					                continue | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            if not order.partner_id: | 
				
			||||
 | 
					                raise UserError(_('Please provide a partner for the sale.')) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            acc = order.partner_id.property_account_receivable_id.id | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					# =============adding 'discount_total' to invoice================================================================ | 
				
			||||
 | 
					            inv = { | 
				
			||||
 | 
					                'name': order.name, | 
				
			||||
 | 
					                'origin': order.name, | 
				
			||||
 | 
					                'account_id': acc, | 
				
			||||
 | 
					                'journal_id': order.sale_journal.id or None, | 
				
			||||
 | 
					                'type': 'out_invoice', | 
				
			||||
 | 
					                'reference': order.name, | 
				
			||||
 | 
					                'partner_id': order.partner_id.id, | 
				
			||||
 | 
					                'comment': order.note or '', | 
				
			||||
 | 
					                'currency_id': order.pricelist_id.currency_id.id, # considering partner's sale pricelist's currency | 
				
			||||
 | 
					                'company_id': company_id, | 
				
			||||
 | 
					                'user_id': uid, | 
				
			||||
 | 
					                'discount_total': order.discount_total, | 
				
			||||
 | 
					                'discount_percent': order.discount_percent, | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            invoice = inv_ref.new(cr, uid, inv) | 
				
			||||
 | 
					            invoice._onchange_partner_id() | 
				
			||||
 | 
					            invoice.fiscal_position_id = order.fiscal_position_id | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            inv = invoice._convert_to_write(invoice._cache) | 
				
			||||
 | 
					            if not inv.get('account_id', None): | 
				
			||||
 | 
					                inv['account_id'] = acc | 
				
			||||
 | 
					            inv_id = inv_ref.create(cr, SUPERUSER_ID, inv, context=local_context) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            self.write(cr, uid, [order.id], {'invoice_id': inv_id, 'state': 'invoiced'}, context=local_context) | 
				
			||||
 | 
					            inv_ids.append(inv_id) | 
				
			||||
 | 
					            for line in order.lines: | 
				
			||||
 | 
					                inv_name = product_obj.name_get(cr, uid, [line.product_id.id], context=local_context)[0][1] | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					# ===============adding 'discount fixed' to invoice lines========================================== | 
				
			||||
 | 
					                inv_line = { | 
				
			||||
 | 
					                    'invoice_id': inv_id, | 
				
			||||
 | 
					                    'product_id': line.product_id.id, | 
				
			||||
 | 
					                    'quantity': line.qty, | 
				
			||||
 | 
					                    'account_analytic_id': self._prepare_analytic_account(cr, uid, line, context=local_context), | 
				
			||||
 | 
					                    'name': inv_name, | 
				
			||||
 | 
					                    'discount_fixed': line.discount_fixed, | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                #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] | 
				
			||||
 | 
					                fiscal_position_id = line.order_id.fiscal_position_id | 
				
			||||
 | 
					                if fiscal_position_id: | 
				
			||||
 | 
					                    invoice_line.invoice_line_tax_ids = fiscal_position_id.map_tax(invoice_line.invoice_line_tax_ids) | 
				
			||||
 | 
					                invoice_line.invoice_line_tax_ids = [tax.id for tax in invoice_line.invoice_line_tax_ids] | 
				
			||||
 | 
					                # 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, discount_fixed=line.discount_fixed) | 
				
			||||
 | 
					                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') | 
				
			||||
 | 
					            inv_ref.signal_workflow(cr, SUPERUSER_ID, [inv_id], 'validate') | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if not inv_ids: return {} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        mod_obj = self.pool.get('ir.model.data') | 
				
			||||
 | 
					        res = mod_obj.get_object_reference(cr, uid, 'account', 'invoice_form') | 
				
			||||
 | 
					        res_id = res and res[1] or False | 
				
			||||
 | 
					        return { | 
				
			||||
 | 
					            'name': _('Customer Invoice'), | 
				
			||||
 | 
					            'view_type': 'form', | 
				
			||||
 | 
					            'view_mode': 'form', | 
				
			||||
 | 
					            'view_id': [res_id], | 
				
			||||
 | 
					            'res_model': 'account.invoice', | 
				
			||||
 | 
					            'context': "{'type':'out_invoice'}", | 
				
			||||
 | 
					            'type': 'ir.actions.act_window', | 
				
			||||
 | 
					            'target': 'current', | 
				
			||||
 | 
					            'res_id': inv_ids and inv_ids[0] or False, | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def _create_account_move_line(self, cr, uid, ids, session=None, move_id=None, context=None): | 
				
			||||
 | 
					        # Tricky, via the workflow, we only have one id in the ids variable | 
				
			||||
 | 
					        """Create a account move line of order grouped by products or not.""" | 
				
			||||
 | 
					        account_move_obj = self.pool.get('account.move') | 
				
			||||
 | 
					        account_tax_obj = self.pool.get('account.tax') | 
				
			||||
 | 
					        property_obj = self.pool.get('ir.property') | 
				
			||||
 | 
					        cur_obj = self.pool.get('res.currency') | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        # session_ids = set(order.session_id for order in self.browse(cr, uid, ids, context=context)) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if session and not all( | 
				
			||||
 | 
					                        session.id == order.session_id.id for order in self.browse(cr, uid, ids, context=context)): | 
				
			||||
 | 
					            raise UserError(_('Selected orders do not have the same session!')) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        grouped_data = {} | 
				
			||||
 | 
					        have_to_group_by = session and session.config_id.group_by or False | 
				
			||||
 | 
					        rounding_method = session and session.config_id.company_id.tax_calculation_rounding_method | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        for order in self.browse(cr, uid, ids, context=context): | 
				
			||||
 | 
					            if order.account_move: | 
				
			||||
 | 
					                continue | 
				
			||||
 | 
					            if order.state != 'paid': | 
				
			||||
 | 
					                continue | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            current_company = order.sale_journal.company_id | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            group_tax = {} | 
				
			||||
 | 
					            account_def = property_obj.get(cr, uid, 'property_account_receivable_id', 'res.partner', | 
				
			||||
 | 
					                                           context=context) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            order_account = order.partner_id and \ | 
				
			||||
 | 
					                            order.partner_id.property_account_receivable_id and \ | 
				
			||||
 | 
					                            order.partner_id.property_account_receivable_id.id or \ | 
				
			||||
 | 
					                            account_def and account_def.id | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            if move_id is None: | 
				
			||||
 | 
					                # Create an entry for the sale | 
				
			||||
 | 
					                # FORWARD-PORT UP TO SAAS-12 | 
				
			||||
 | 
					                journal_id = self.pool['ir.config_parameter'].get_param(cr, SUPERUSER_ID, | 
				
			||||
 | 
					                                                                        'pos.closing.journal_id_%s' % ( | 
				
			||||
 | 
					                                                                        current_company.id), | 
				
			||||
 | 
					                                                                        default=order.sale_journal.id, | 
				
			||||
 | 
					                                                                        context=context) | 
				
			||||
 | 
					                move_id = self._create_account_move(cr, uid, order.session_id.start_at, order.name, int(journal_id), | 
				
			||||
 | 
					                                                    order.company_id.id, context=context) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            move = account_move_obj.browse(cr, SUPERUSER_ID, move_id, context=context) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            def insert_data(data_type, values): | 
				
			||||
 | 
					                # if have_to_group_by: | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                # 'quantity': line.qty, | 
				
			||||
 | 
					                # 'product_id': line.product_id.id, | 
				
			||||
 | 
					                values.update({ | 
				
			||||
 | 
					                    'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner( | 
				
			||||
 | 
					                        order.partner_id).id or False, | 
				
			||||
 | 
					                    'move_id': move_id, | 
				
			||||
 | 
					                }) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                if data_type == 'product': | 
				
			||||
 | 
					                    key = ('product', values['partner_id'], | 
				
			||||
 | 
					                           (values['product_id'], tuple(values['tax_ids'][0][2]), values['name']), | 
				
			||||
 | 
					                           values['analytic_account_id'], values['debit'] > 0) | 
				
			||||
 | 
					                elif data_type == 'tax': | 
				
			||||
 | 
					                    key = ('tax', values['partner_id'], values['tax_line_id'], values['debit'] > 0) | 
				
			||||
 | 
					                elif data_type == 'counter_part': | 
				
			||||
 | 
					                    key = ('counter_part', values['partner_id'], values['account_id'], values['debit'] > 0) | 
				
			||||
 | 
					                else: | 
				
			||||
 | 
					                    return | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                grouped_data.setdefault(key, []) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                # if not have_to_group_by or (not grouped_data[key]): | 
				
			||||
 | 
					                #     grouped_data[key].append(values) | 
				
			||||
 | 
					                # else: | 
				
			||||
 | 
					                #     pass | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                if have_to_group_by: | 
				
			||||
 | 
					                    if not grouped_data[key]: | 
				
			||||
 | 
					                        grouped_data[key].append(values) | 
				
			||||
 | 
					                    else: | 
				
			||||
 | 
					                        for line in grouped_data[key]: | 
				
			||||
 | 
					                            if line.get('tax_code_id') == values.get('tax_code_id'): | 
				
			||||
 | 
					                                current_value = line | 
				
			||||
 | 
					                                current_value['quantity'] = current_value.get('quantity', 0.0) + values.get( | 
				
			||||
 | 
					                                    'quantity', 0.0) | 
				
			||||
 | 
					                                current_value['credit'] = current_value.get('credit', 0.0) + values.get('credit', | 
				
			||||
 | 
					                                                                                                        0.0) | 
				
			||||
 | 
					                                current_value['debit'] = current_value.get('debit', 0.0) + values.get('debit', 0.0) | 
				
			||||
 | 
					                                break | 
				
			||||
 | 
					                        else: | 
				
			||||
 | 
					                            grouped_data[key].append(values) | 
				
			||||
 | 
					                else: | 
				
			||||
 | 
					                    grouped_data[key].append(values) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            # because of the weird way the pos order is written, we need to make sure there is at least one line, | 
				
			||||
 | 
					            # because just after the 'for' loop there are references to 'line' and 'income_account' variables (that | 
				
			||||
 | 
					            # are set inside the for loop) | 
				
			||||
 | 
					            # TOFIX: a deep refactoring of this method (and class!) is needed in order to get rid of this stupid hack | 
				
			||||
 | 
					            assert order.lines, _('The POS order must have lines when calling this method') | 
				
			||||
 | 
					            # Create an move for each order line | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            cur = order.pricelist_id.currency_id | 
				
			||||
 | 
					            for line in order.lines: | 
				
			||||
 | 
					                amount = line.price_subtotal | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                # Search for the income account | 
				
			||||
 | 
					                if line.product_id.property_account_income_id.id: | 
				
			||||
 | 
					                    income_account = line.product_id.property_account_income_id.id | 
				
			||||
 | 
					                elif line.product_id.categ_id.property_account_income_categ_id.id: | 
				
			||||
 | 
					                    income_account = line.product_id.categ_id.property_account_income_categ_id.id | 
				
			||||
 | 
					                else: | 
				
			||||
 | 
					                    raise UserError(_('Please define income ' \ | 
				
			||||
 | 
					                                      'account for this product: "%s" (id:%d).') \ | 
				
			||||
 | 
					                                    % (line.product_id.name, line.product_id.id)) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                name = line.product_id.name | 
				
			||||
 | 
					                if line.notice: | 
				
			||||
 | 
					                    # add discount reason in move | 
				
			||||
 | 
					                    name = name + ' (' + line.notice + ')' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                # Create a move for the line for the order line | 
				
			||||
 | 
					                insert_data('product', { | 
				
			||||
 | 
					                    'name': name, | 
				
			||||
 | 
					                    'quantity': line.qty, | 
				
			||||
 | 
					                    'product_id': line.product_id.id, | 
				
			||||
 | 
					                    'account_id': income_account, | 
				
			||||
 | 
					                    'analytic_account_id': self._prepare_analytic_account(cr, uid, line, context=context), | 
				
			||||
 | 
					                    'credit': ((amount > 0) and amount) or 0.0, | 
				
			||||
 | 
					                    'debit': ((amount < 0) and -amount) or 0.0, | 
				
			||||
 | 
					                    'tax_ids': [(6, 0, line.tax_ids_after_fiscal_position.ids)], | 
				
			||||
 | 
					                    'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner( | 
				
			||||
 | 
					                        order.partner_id).id or False | 
				
			||||
 | 
					                }) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                # Create the tax lines | 
				
			||||
 | 
					                taxes = [] | 
				
			||||
 | 
					                for t in line.tax_ids_after_fiscal_position: | 
				
			||||
 | 
					                    if t.company_id.id == current_company.id: | 
				
			||||
 | 
					                        taxes.append(t.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']: | 
				
			||||
 | 
					                    insert_data('tax', { | 
				
			||||
 | 
					                        'name': _('Tax') + ' ' + tax['name'], | 
				
			||||
 | 
					                        'product_id': line.product_id.id, | 
				
			||||
 | 
					                        'quantity': line.qty, | 
				
			||||
 | 
					                        'account_id': tax['account_id'] or income_account, | 
				
			||||
 | 
					                        'credit': ((tax['amount'] > 0) and tax['amount']) or 0.0, | 
				
			||||
 | 
					                        'debit': ((tax['amount'] < 0) and -tax['amount']) or 0.0, | 
				
			||||
 | 
					                        'tax_line_id': tax['id'], | 
				
			||||
 | 
					                        'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner( | 
				
			||||
 | 
					                            order.partner_id).id or False | 
				
			||||
 | 
					                    }) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            # round tax lines per order | 
				
			||||
 | 
					            if rounding_method == 'round_globally': | 
				
			||||
 | 
					                for group_key, group_value in grouped_data.iteritems(): | 
				
			||||
 | 
					                    if group_key[0] == 'tax': | 
				
			||||
 | 
					                        for line in group_value: | 
				
			||||
 | 
					                            line['credit'] = cur.round(line['credit']) | 
				
			||||
 | 
					                            line['debit'] = cur.round(line['debit']) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            if order.discount_total: | 
				
			||||
 | 
					                insert_data('counter_part', { | 
				
			||||
 | 
					                    'name': 'Discount', | 
				
			||||
 | 
					                    'account_id': order.session_id.config_id.discount_account.id, | 
				
			||||
 | 
					                    'credit': ((order.discount_total < 0) and -order.discount_total) or 0.0, | 
				
			||||
 | 
					                    'debit': ((order.discount_total > 0) and order.discount_total) or 0.0, | 
				
			||||
 | 
					                    'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner( | 
				
			||||
 | 
					                        order.partner_id).id or False | 
				
			||||
 | 
					                }) | 
				
			||||
 | 
					            elif order.discount_percent: | 
				
			||||
 | 
					                discount = (100 * order.amount_total) / (100 - order.discount_percent) | 
				
			||||
 | 
					                discount -= order.amount_total | 
				
			||||
 | 
					                print discount, "--------------" | 
				
			||||
 | 
					                insert_data('counter_part', { | 
				
			||||
 | 
					                    'name': 'Discount', | 
				
			||||
 | 
					                    'account_id': order.session_id.config_id.discount_account.id, | 
				
			||||
 | 
					                    'credit': ((discount < 0) and -discount) or 0.0, | 
				
			||||
 | 
					                    'debit': ((discount > 0) and discount) or 0.0, | 
				
			||||
 | 
					                    'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner( | 
				
			||||
 | 
					                        order.partner_id).id or False | 
				
			||||
 | 
					                }) | 
				
			||||
 | 
					            # counterpart | 
				
			||||
 | 
					            insert_data('counter_part', { | 
				
			||||
 | 
					                'name': _("Trade Receivables"),  # order.name, | 
				
			||||
 | 
					                'account_id': order_account, | 
				
			||||
 | 
					                'credit': ((order.amount_total < 0) and -order.amount_total) or 0.0, | 
				
			||||
 | 
					                'debit': ((order.amount_total > 0) and order.amount_total) or 0.0, | 
				
			||||
 | 
					                'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner( | 
				
			||||
 | 
					                    order.partner_id).id or False | 
				
			||||
 | 
					            }) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            order.write({'state': 'done', 'account_move': move_id}) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        all_lines = [] | 
				
			||||
 | 
					        for group_key, group_data in grouped_data.iteritems(): | 
				
			||||
 | 
					            for value in group_data: | 
				
			||||
 | 
					                all_lines.append((0, 0, value), ) | 
				
			||||
 | 
					        if move_id:  # In case no order was changed | 
				
			||||
 | 
					            self.pool.get("account.move").write(cr, SUPERUSER_ID, [move_id], {'line_ids': all_lines}, | 
				
			||||
 | 
					                                                context=dict(context or {}, dont_create_taxes=True)) | 
				
			||||
 | 
					            self.pool.get("account.move").post(cr, SUPERUSER_ID, [move_id], context=context) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return True | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class NewPosLines(osv.osv): | 
				
			||||
 | 
					    _inherit = "pos.order.line" | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    _columns = { | 
				
			||||
 | 
					        'price_unit': fields.float(string='Unit Price', digits=0), | 
				
			||||
 | 
					        'qty': fields.float('Quantity', digits_compute=dp.get_precision('Product Unit of Measure')), | 
				
			||||
 | 
					        'discount_fixed': fields.float('Discount Fixed'), | 
				
			||||
 | 
					        'discountStr': fields.char('discountStr'), | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    _defaults = { | 
				
			||||
 | 
					        'discount_fixed': lambda *a: 0.0, | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.onchange('discount_fixed') | 
				
			||||
 | 
					    def change_discount_fixed_line(self): | 
				
			||||
 | 
					        if self.discount_fixed: | 
				
			||||
 | 
					            self.discount = 0.0 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.onchange('discount') | 
				
			||||
 | 
					    def change_discount_line(self): | 
				
			||||
 | 
					        if self.discount: | 
				
			||||
 | 
					            self.discount_fixed = 0.0 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.onchange('qty') | 
				
			||||
 | 
					    def change_qty_line(self): | 
				
			||||
 | 
					        self._compute_amount_line_all() | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.onchange('price_unit') | 
				
			||||
 | 
					    def change_price_unit_line(self): | 
				
			||||
 | 
					        self._compute_amount_line_all() | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.depends('price_unit', 'tax_ids', 'qty', 'discount', 'discount_fixed', 'product_id') | 
				
			||||
 | 
					    def _compute_amount_line_all(self): | 
				
			||||
 | 
					        for line in self: | 
				
			||||
 | 
					            currency = line.order_id.pricelist_id.currency_id | 
				
			||||
 | 
					            taxes = line.tax_ids.filtered(lambda tax: tax.company_id.id == line.order_id.company_id.id) | 
				
			||||
 | 
					            fiscal_position_id = line.order_id.fiscal_position_id | 
				
			||||
 | 
					            if fiscal_position_id: | 
				
			||||
 | 
					                taxes = fiscal_position_id.map_tax(taxes) | 
				
			||||
 | 
					# =============== finding subtotal for each orderline========================================================= | 
				
			||||
 | 
					            if line.discount_fixed != 0: | 
				
			||||
 | 
					                price = line.price_unit | 
				
			||||
 | 
					                line.price_subtotal = line.price_subtotal_incl = price * line.qty - line.discount_fixed | 
				
			||||
 | 
					            else: | 
				
			||||
 | 
					                price = line.price_unit | 
				
			||||
 | 
					                line.price_subtotal = line.price_subtotal_incl = (price * line.qty) - (price * line.qty * (line.discount or 0.0) / 100) | 
				
			||||
 | 
					            if taxes: | 
				
			||||
 | 
					                taxes = taxes.compute_all(price, currency, line.qty, product=line.product_id, partner=line.order_id.partner_id or False) | 
				
			||||
 | 
					                line.price_subtotal = taxes['total_excluded'] | 
				
			||||
 | 
					                line.price_subtotal_incl = taxes['total_included'] | 
				
			||||
 | 
					            line.price_subtotal = currency.round(line.price_subtotal) | 
				
			||||
 | 
					            line.price_subtotal_incl = currency.round(line.price_subtotal_incl) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class AccountMoveLineExtra(models.Model): | 
				
			||||
 | 
					    _inherit = 'account.move.line' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    _sql_constraints = [ | 
				
			||||
 | 
					        ('credit_debit1', 'CHECK (credit*debit=0)', 'Wrong credit or debit value in accounting entry !'), | 
				
			||||
 | 
					        ('credit_debit2', 'CHECK (credit*debit=0)', 'Wrong credit or debit value in accounting entry !'), | 
				
			||||
 | 
					    ] | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.multi | 
				
			||||
 | 
					    def _update_check(self): | 
				
			||||
 | 
					        """ This module is overwritten, to avoid the warning raised when we edit the journal entries""" | 
				
			||||
 | 
					        move_ids = set() | 
				
			||||
 | 
					        for line in self: | 
				
			||||
 | 
					            err_msg = _('Move name (id): %s (%s)') % (line.move_id.name, str(line.move_id.id)) | 
				
			||||
 | 
					            if line.move_id.id not in move_ids: | 
				
			||||
 | 
					                move_ids.add(line.move_id.id) | 
				
			||||
 | 
					            self.env['account.move'].browse(list(move_ids))._check_lock_date() | 
				
			||||
 | 
					        return True | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.multi | 
				
			||||
 | 
					    def reconcile(self, writeoff_acc_id=False, writeoff_journal_id=False): | 
				
			||||
 | 
					        """ This function is overwritten to remove some warnings""" | 
				
			||||
 | 
					        # Perform all checks on lines | 
				
			||||
 | 
					        company_ids = set() | 
				
			||||
 | 
					        all_accounts = [] | 
				
			||||
 | 
					        partners = set() | 
				
			||||
 | 
					        for line in self: | 
				
			||||
 | 
					            company_ids.add(line.company_id.id) | 
				
			||||
 | 
					            all_accounts.append(line.account_id) | 
				
			||||
 | 
					            if (line.account_id.internal_type in ('receivable', 'payable')): | 
				
			||||
 | 
					                partners.add(line.partner_id.id) | 
				
			||||
 | 
					            if line.reconciled: | 
				
			||||
 | 
					                raise UserError(_('You are trying to reconcile some entries that are already reconciled!')) | 
				
			||||
 | 
					        if len(company_ids) > 1: | 
				
			||||
 | 
					            raise UserError(_('To reconcile the entries company should be the same for all entries!')) | 
				
			||||
 | 
					        if not all_accounts[0].reconcile: | 
				
			||||
 | 
					            raise UserError(_('The account %s (%s) is not marked as reconciliable !') % ( | 
				
			||||
 | 
					            all_accounts[0].name, all_accounts[0].code)) | 
				
			||||
 | 
					        # reconcile everything that can be | 
				
			||||
 | 
					        remaining_moves = self.auto_reconcile_lines() | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        # if writeoff_acc_id specified, then create write-off move with value the remaining amount from move in self | 
				
			||||
 | 
					        if writeoff_acc_id and writeoff_journal_id and remaining_moves: | 
				
			||||
 | 
					            all_aml_share_same_currency = all([x.currency_id == self[0].currency_id for x in self]) | 
				
			||||
 | 
					            writeoff_vals = { | 
				
			||||
 | 
					                'account_id': writeoff_acc_id.id, | 
				
			||||
 | 
					                'journal_id': writeoff_journal_id.id | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            if not all_aml_share_same_currency: | 
				
			||||
 | 
					                writeoff_vals['amount_currency'] = False | 
				
			||||
 | 
					            writeoff_to_reconcile = remaining_moves._create_writeoff(writeoff_vals) | 
				
			||||
 | 
					            # add writeoff line to reconcile algo and finish the reconciliation | 
				
			||||
 | 
					            remaining_moves = (remaining_moves + writeoff_to_reconcile).auto_reconcile_lines() | 
				
			||||
 | 
					            return writeoff_to_reconcile | 
				
			||||
 | 
					        return True | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class AccountMoveNew(models.Model): | 
				
			||||
 | 
					    _inherit = 'account.move' | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @api.multi | 
				
			||||
 | 
					    def assert_balanced(self): | 
				
			||||
 | 
					        """Overwritten to remove the warning raised.(For editing the journal entry)""" | 
				
			||||
 | 
					        if not self.ids: | 
				
			||||
 | 
					            return True | 
				
			||||
 | 
					        prec = self.env['decimal.precision'].precision_get('Account') | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        self._cr.execute("""\ | 
				
			||||
 | 
					                SELECT      move_id | 
				
			||||
 | 
					                FROM        account_move_line | 
				
			||||
 | 
					                WHERE       move_id in %s | 
				
			||||
 | 
					                GROUP BY    move_id | 
				
			||||
 | 
					                HAVING      abs(sum(debit) - sum(credit)) > %s | 
				
			||||
 | 
					                """, (tuple(self.ids), 10 ** (-max(5, prec)))) | 
				
			||||
 | 
					        return True | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,70 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import time | 
				
			||||
 | 
					from openerp.osv import osv | 
				
			||||
 | 
					from openerp.report import report_sxw | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class pos_payment_report_new(report_sxw.rml_parse): | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def __init__(self, cr, uid, name, context): | 
				
			||||
 | 
					        super(pos_payment_report_new, self).__init__(cr, uid, name, context=context) | 
				
			||||
 | 
					        self.total = 0.0 | 
				
			||||
 | 
					        self.localcontext.update({ | 
				
			||||
 | 
					            'time': time, | 
				
			||||
 | 
					            'pos_payment': self._pos_payment, | 
				
			||||
 | 
					            'pos_payment_total':self._pos_payment_total, | 
				
			||||
 | 
					            'pos_fixed_discount':self._pos_fixed_discount, | 
				
			||||
 | 
					            'pos_percent_discount': self._pos_percent_discount, | 
				
			||||
 | 
					        }) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def _pos_payment(self, obj): | 
				
			||||
 | 
					        self.total = 0 | 
				
			||||
 | 
					        self.discount_total = 0 | 
				
			||||
 | 
					        self.discount_percent = 0 | 
				
			||||
 | 
					        data={} | 
				
			||||
 | 
					        new_data={} | 
				
			||||
 | 
					        sql = """ select id from pos_order where id = %d"""%(obj.id) | 
				
			||||
 | 
					        self.cr.execute(sql) | 
				
			||||
 | 
					        if self.cr.fetchone(): | 
				
			||||
 | 
					            self.cr.execute ("select pol.id,pt.name,pp.default_code as code,pol.qty,pu.name as uom,pol.discount,pol.discount_fixed,pol.price_unit, " \ | 
				
			||||
 | 
					                                 "(pol.price_unit * pol.qty) as total  " \ | 
				
			||||
 | 
					                                 "from pos_order as po,pos_order_line as pol,product_product as pp,product_template as pt, product_uom as pu " \ | 
				
			||||
 | 
					                                 "where pt.id=pp.product_tmpl_id and pp.id=pol.product_id and po.id = pol.order_id  and pu.id=pt.uom_id " \ | 
				
			||||
 | 
					                                 "and po.state IN ('paid','invoiced') and to_char(date_trunc('day',po.date_order),'YYYY-MM-DD')::date = current_date and po.id=%d"%(obj.id)) | 
				
			||||
 | 
					            data = self.cr.dictfetchall() | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        else: | 
				
			||||
 | 
					            self.cr.execute ("select pt.name,pp.default_code as code,pol.qty,pu.name as uom,pol.discount,pol.discount_fixed,pol.price_unit, " \ | 
				
			||||
 | 
					                                 "(pol.price_unit * pol.qty) as total  " \ | 
				
			||||
 | 
					                                 "from pos_order as po,pos_order_line as pol,product_product as pp,product_template as pt, product_uom as pu  " \ | 
				
			||||
 | 
					                                 "where pt.id=pp.product_tmpl_id and pp.id=pol.product_id and po.id = pol.order_id and pu.id=pt.uom_id  " \ | 
				
			||||
 | 
					                                 "and po.state IN ('paid','invoiced') and to_char(date_trunc('day',po.date_order),'YYYY-MM-DD')::date = current_date") | 
				
			||||
 | 
					            data = self.cr.dictfetchall() | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        for d in data: | 
				
			||||
 | 
					            if d['discount_fixed'] != 0: | 
				
			||||
 | 
					                d['total'] = d['price_unit'] * d['qty'] - d['discount_fixed'] | 
				
			||||
 | 
					            else: | 
				
			||||
 | 
					                d['total'] = d['price_unit'] * d['qty'] * (1 - (d['discount'] / 100)) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        self.total = obj.amount_total | 
				
			||||
 | 
					        self.discount_total += obj.discount_total | 
				
			||||
 | 
					        self.discount_percent += obj.discount_percent | 
				
			||||
 | 
					        return data | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def _pos_payment_total(self, o): | 
				
			||||
 | 
					        return self.total | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def _pos_fixed_discount(self, o): | 
				
			||||
 | 
					        return self.discount_total | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def _pos_percent_discount(self, o): | 
				
			||||
 | 
					        return self.discount_percent | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class report_pos_payment(osv.AbstractModel): | 
				
			||||
 | 
					    _name = 'report.discounts_in_pos.report_payment' | 
				
			||||
 | 
					    _inherit = 'report.abstract_report' | 
				
			||||
 | 
					    _template = 'discounts_in_pos.report_payment' | 
				
			||||
 | 
					    _wrapped_report_class = pos_payment_report_new | 
				
			||||
@ -0,0 +1,65 @@ | 
				
			|||||
 | 
					# -*- coding: utf-8 -*- | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import time | 
				
			||||
 | 
					from openerp.osv import osv | 
				
			||||
 | 
					from openerp.report import report_sxw | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					def titlize(journal_name): | 
				
			||||
 | 
					    words = journal_name.split() | 
				
			||||
 | 
					    while words.pop() != 'journal': | 
				
			||||
 | 
					        continue | 
				
			||||
 | 
					    return ' '.join(words) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class order(report_sxw.rml_parse): | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def __init__(self, cr, uid, name, context): | 
				
			||||
 | 
					        super(order, self).__init__(cr, uid, name, context=context) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        user = self.pool['res.users'].browse(cr, uid, uid, context=context) | 
				
			||||
 | 
					        partner = user.company_id.partner_id | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        self.localcontext.update({ | 
				
			||||
 | 
					            'time': time, | 
				
			||||
 | 
					            'disc': self.discount, | 
				
			||||
 | 
					            'net': self.netamount, | 
				
			||||
 | 
					            'get_journal_amt': self._get_journal_amt, | 
				
			||||
 | 
					            'address': partner or False, | 
				
			||||
 | 
					            'titlize': titlize | 
				
			||||
 | 
					        }) | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def netamount(self, order_line_id): | 
				
			||||
 | 
					        sql = 'select (qty*price_unit) as net_price from pos_order_line where id = %s' | 
				
			||||
 | 
					        self.cr.execute(sql, (order_line_id,)) | 
				
			||||
 | 
					        res = self.cr.fetchone() | 
				
			||||
 | 
					        return res[0] | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def discount(self, order_id): | 
				
			||||
 | 
					        sql = 'select discount, discount_fixed, price_unit, qty from pos_order_line where order_id = %s ' | 
				
			||||
 | 
					        self.cr.execute(sql, (order_id,)) | 
				
			||||
 | 
					        res = self.cr.fetchall() | 
				
			||||
 | 
					        dsum = 0 | 
				
			||||
 | 
					        for line in res: | 
				
			||||
 | 
					            if line[1] != 0: | 
				
			||||
 | 
					                dsum = dsum + (line[1]) | 
				
			||||
 | 
					            else: | 
				
			||||
 | 
					                dsum = dsum + (line[3] * (line[0] * line[2] / 100)) | 
				
			||||
 | 
					        return dsum | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    def _get_journal_amt(self, order_id): | 
				
			||||
 | 
					        data={} | 
				
			||||
 | 
					        sql = """ select aj.name,absl.amount as amt from account_bank_statement as abs | 
				
			||||
 | 
					                        LEFT JOIN account_bank_statement_line as absl ON abs.id = absl.statement_id | 
				
			||||
 | 
					                        LEFT JOIN account_journal as aj ON aj.id = abs.journal_id | 
				
			||||
 | 
					                        WHERE absl.pos_statement_id =%d"""%(order_id) | 
				
			||||
 | 
					        self.cr.execute(sql) | 
				
			||||
 | 
					        data = self.cr.dictfetchall() | 
				
			||||
 | 
					        return data | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					class report_order_receipt(osv.AbstractModel): | 
				
			||||
 | 
					    _name = 'report.discounts_in_pos.report_receipt' | 
				
			||||
 | 
					    _inherit = 'report.abstract_report' | 
				
			||||
 | 
					    _template = 'discounts_in_pos.report_receipt' | 
				
			||||
 | 
					    _wrapped_report_class = order | 
				
			||||
| 
		 After Width: | Height: | Size: 91 KiB  | 
| 
		 After Width: | Height: | Size: 128 KiB  | 
| 
		 After Width: | Height: | Size: 50 KiB  | 
| 
		 After Width: | Height: | Size: 253 KiB  | 
| 
		 After Width: | Height: | Size: 16 KiB  | 
@ -0,0 +1,169 @@ | 
				
			|||||
 | 
					<section class="oe_container"> | 
				
			||||
 | 
					    <div class="oe_row oe_spaced"> | 
				
			||||
 | 
					        <h2 class="oe_slogan">POS Discount Total</h2> | 
				
			||||
 | 
					        <h3 class="oe_slogan">POS Discount Total(Fixed and Percentage)</h3> | 
				
			||||
 | 
					        <h4 class="oe_slogan">Cybrosys Technologies , www.cybrosys.com</h4> | 
				
			||||
 | 
					        <div> | 
				
			||||
 | 
					            <h4><p>Features:</p></h4> | 
				
			||||
 | 
					            <ul> | 
				
			||||
 | 
					                <li style="list-style:none !important;"><span style="color:green;"> ☑</span>   Percentage discount on order lines.</li> | 
				
			||||
 | 
					                <li style="list-style:none !important;"><span style="color:green;"> ☑</span>   Fixed discount on order lines.</li> | 
				
			||||
 | 
					                <li style="list-style:none !important;"><span style="color:green;"> ☑</span>   Percentage discount on order.</li> | 
				
			||||
 | 
					                <li style="list-style:none !important;"><span style="color:green;"> ☑</span>   Fixed discount on order.</li> | 
				
			||||
 | 
					            </ul> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					     </div> | 
				
			||||
 | 
					</section> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<section class="oe_container oe_dark"> | 
				
			||||
 | 
					     <div class="oe_row oe_spaced"> | 
				
			||||
 | 
					        <div class="oe_row oe_spaced"> | 
				
			||||
 | 
					            <div class="oe_span12"> | 
				
			||||
 | 
					                <center> | 
				
			||||
 | 
					                    <p class="oe_mt32"> | 
				
			||||
 | 
					                        This module allows us to provide different types of discounts in point of sale. | 
				
			||||
 | 
					                        Possible discounts are, fixed discounts and percentage discounts(Order lines and Order). | 
				
			||||
 | 
					                    </p> | 
				
			||||
 | 
					                </center> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					     </div> | 
				
			||||
 | 
					</section> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<section class="oe_container"> | 
				
			||||
 | 
					     <div class="oe_row oe_spaced"> | 
				
			||||
 | 
					        <h3 class="oe_slogan">Fixed discount on order lines.</h3> | 
				
			||||
 | 
					        <div class="oe_row oe_spaced"> | 
				
			||||
 | 
					            <div class="oe_span12"> | 
				
			||||
 | 
					                <center> | 
				
			||||
 | 
					                    <div class="oe_row_img oe_centered"> | 
				
			||||
 | 
					                        <img class="oe_picture oe_screenshot" src="discount-button.png"> | 
				
			||||
 | 
					                    </div> | 
				
			||||
 | 
					                </center> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					            <div class="oe_span12"> | 
				
			||||
 | 
					                    <p class="oe_mt32"> | 
				
			||||
 | 
					                        A new button 'Disc.Fixed' is added for providing fixed discounts on orderlines. By clicking on this | 
				
			||||
 | 
					                        button, we can enter the fixed discount. After we have entered the discount, | 
				
			||||
 | 
					                        it will be shown under the product name of the orderline to which we have applied the discount. | 
				
			||||
 | 
					                    </p> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					     </div> | 
				
			||||
 | 
					</section> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<section class="oe_container oe_dark"> | 
				
			||||
 | 
					     <div class="oe_row oe_spaced"> | 
				
			||||
 | 
					        <h3 class="oe_slogan">Percentage discount on order.</h3> | 
				
			||||
 | 
					        <div class="oe_row oe_spaced"> | 
				
			||||
 | 
					            <div class="oe_span12"> | 
				
			||||
 | 
					                <center> | 
				
			||||
 | 
					                    <p class="oe_mt32"> | 
				
			||||
 | 
					                        If we need to provide discount on the total amount of an order, it can be done using this module. | 
				
			||||
 | 
					                        The button 'Disc(Total%)' can be used to provide percentage discounts to an order. | 
				
			||||
 | 
					                    </p> | 
				
			||||
 | 
					                </center> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					     </div> | 
				
			||||
 | 
					</section> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<section class="oe_container"> | 
				
			||||
 | 
					     <div class="oe_row oe_spaced"> | 
				
			||||
 | 
					        <h3 class="oe_slogan">Fixed discount on order.</h3> | 
				
			||||
 | 
					        <div class="oe_row oe_spaced"> | 
				
			||||
 | 
					            <div class="oe_span12"> | 
				
			||||
 | 
					                <p class="oe_mt32"> | 
				
			||||
 | 
					                    This feature can be used to apply a fixed amount discount to an order. The button 'Dis.Fixed(Total)' | 
				
			||||
 | 
					                    can be used for this purpose.</p> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					     </div> | 
				
			||||
 | 
					</section> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<section class="oe_container oe_dark"> | 
				
			||||
 | 
					     <div class="oe_row oe_spaced"> | 
				
			||||
 | 
					        <div class="oe_row oe_spaced"> | 
				
			||||
 | 
					            <div class="oe_span12"> | 
				
			||||
 | 
					                <p class="oe_mt32"> | 
				
			||||
 | 
					                        We can have either one type of discount at a time for an order and order line. i.e, it is | 
				
			||||
 | 
					                        not possible to provide percentage discount and fixed discount at the same time. | 
				
			||||
 | 
					                        Suppose we have applied fixed discount on an order or orderline, then if we try to apply | 
				
			||||
 | 
					                        percentage discount, the existing discount will be removed and new one will be applied. | 
				
			||||
 | 
					                </p> | 
				
			||||
 | 
					                <p> | 
				
			||||
 | 
					                    The applied discounts will be shown in the receipts and the reports. | 
				
			||||
 | 
					                </p> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					            <div class="oe_span6"> | 
				
			||||
 | 
					                <div class="oe_row_img oe_centered"> | 
				
			||||
 | 
					                    <img class="oe_picture oe_screenshot" src="receipt.png"> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					            <div class="oe_span6"> | 
				
			||||
 | 
					                <center> | 
				
			||||
 | 
					                    <div class="oe_row_img oe_centered"> | 
				
			||||
 | 
					                        <img class="oe_picture oe_screenshot" src="receipt-percentage.png"> | 
				
			||||
 | 
					                    </div> | 
				
			||||
 | 
					                </center> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					     </div> | 
				
			||||
 | 
					</section> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<section class="oe_container"> | 
				
			||||
 | 
					     <div class="oe_row oe_spaced"> | 
				
			||||
 | 
					        <div class="oe_row oe_spaced"> | 
				
			||||
 | 
					            <div class="oe_span12"> | 
				
			||||
 | 
					                <img class="oe_picture oe_screenshot" src="total-disc.png"> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					     </div> | 
				
			||||
 | 
					</section> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<section class="oe_container oe_dark"> | 
				
			||||
 | 
					     <div class="oe_row oe_spaced"> | 
				
			||||
 | 
					        <div class="oe_row oe_spaced"> | 
				
			||||
 | 
					            <div class="oe_span12"> | 
				
			||||
 | 
					                <p class="oe_mt32"> | 
				
			||||
 | 
					                    Before providing discounts we need to set an account for recording the discount amount. It can be | 
				
			||||
 | 
					                    created when we are creating the point of sale. | 
				
			||||
 | 
					                </p> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					            <div class="oe_span12"> | 
				
			||||
 | 
					                <img class="oe_picture oe_screenshot" src="account.png"> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					     </div> | 
				
			||||
 | 
					</section> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<section class="oe_container"> | 
				
			||||
 | 
					        <h2 class="oe_slogan" style="margin-top:20px;" >Need Any Help?</h2> | 
				
			||||
 | 
					        <div class="oe_slogan" style="margin-top:10px !important;"> | 
				
			||||
 | 
					            <div> | 
				
			||||
 | 
					                <a  class="btn btn-primary btn-lg mt8" | 
				
			||||
 | 
					                style="color: #FFFFFF !important;border-radius: 0;" href="https://www.cybrosys.com"><i | 
				
			||||
 | 
					                class="fa fa-envelope"></i> Email </a> <a | 
				
			||||
 | 
					                class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;" | 
				
			||||
 | 
					                href="https://www.cybrosys.com/contact/"><i | 
				
			||||
 | 
					                class="fa fa-phone"></i> Contact Us </a> <a | 
				
			||||
 | 
					                class="btn btn-primary btn-lg mt8" style="color: #FFFFFF !important;border-radius: 0;" | 
				
			||||
 | 
					                href="https://www.cybrosys.com/odoo-customization-and-installation/"><i | 
				
			||||
 | 
					                class="fa fa-check-square"></i> Request Customization </a> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					            <br> | 
				
			||||
 | 
					            <img src="cybro_logo.png" style="width: 190px; margin-bottom: 20px;" class="center-block"> | 
				
			||||
 | 
					            <div> | 
				
			||||
 | 
					              <a href="https://twitter.com/cybrosys" target="_blank"><i class="fa fa-2x fa-twitter" style="color:white;background: #00a0d1;width:35px;"></i></a></td> | 
				
			||||
 | 
					              <a href="https://www.linkedin.com/company/cybrosys-technologies-pvt-ltd" target="_blank"><i class="fa fa-2x fa-linkedin" style="color:white;background: #31a3d6;width:35px;padding-left: 3px;"></i></a></td> | 
				
			||||
 | 
					              <a href="https://www.facebook.com/cybrosystechnologies" target="_blank"><i class="fa fa-2x fa-facebook" style="color:white;background: #3b5998;width:35px;padding-left: 8px;"></i></a></td> | 
				
			||||
 | 
					              <a href="https://plus.google.com/106641282743045431892/about" target="_blank"><i class="fa fa-2x fa-google-plus" style="color:white;background: #c53c2c;width:35px;padding-left: 3px;"></i></a></td> | 
				
			||||
 | 
					              <a href="https://in.pinterest.com/cybrosys" target="_blank"><i class="fa fa-2x fa-pinterest" style="color:white;background: #ac0f18;width:35px;padding-left: 3px;"></i></a></td> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					</section> | 
				
			||||
| 
		 After Width: | Height: | Size: 22 KiB  | 
| 
		 After Width: | Height: | Size: 23 KiB  | 
| 
		 After Width: | Height: | Size: 41 KiB  | 
@ -0,0 +1,486 @@ | 
				
			|||||
 | 
					odoo.define('discounts_in_pos', function (require) { | 
				
			||||
 | 
					"use strict"; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					var screens = require('point_of_sale.screens'); | 
				
			||||
 | 
					var models = require('point_of_sale.models'); | 
				
			||||
 | 
					var core = require('web.core'); | 
				
			||||
 | 
					var formats = require('web.formats'); | 
				
			||||
 | 
					var utils = require('web.utils'); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					var QWeb = core.qweb; | 
				
			||||
 | 
					var round_di = utils.round_decimals; | 
				
			||||
 | 
					var round_pr = utils.round_precision; | 
				
			||||
 | 
					     | 
				
			||||
 | 
					screens.OrderWidget.include({ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    set_value: function(val) { | 
				
			||||
 | 
					    	var order = this.pos.get_order(); | 
				
			||||
 | 
					    	if (order.get_selected_orderline()) { | 
				
			||||
 | 
					            var mode = this.numpad_state.get('mode'); | 
				
			||||
 | 
					            if( mode === 'quantity'){ | 
				
			||||
 | 
					                order.get_selected_orderline().set_quantity(val); | 
				
			||||
 | 
					            }else if( mode === 'discount'){ | 
				
			||||
 | 
					                order.get_selected_orderline().set_discount(val); | 
				
			||||
 | 
					            }else if( mode === 'price'){ | 
				
			||||
 | 
					                order.get_selected_orderline().set_unit_price(val); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					 // for the new button 'DiscFix'
 | 
				
			||||
 | 
					            else if( mode === 'discount_fixed'){ | 
				
			||||
 | 
					                console.log(order) | 
				
			||||
 | 
					                console.log(order.get_selected_orderline()) | 
				
			||||
 | 
					                order.get_selected_orderline().set_discount_fixed(val); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            else if( mode === 'discount_total'){ | 
				
			||||
 | 
					                order.get_selected_orderline().set_discount_total(val); | 
				
			||||
 | 
					                order.set_discount_total_order(val); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            else if( mode === 'discount_percent'){ | 
				
			||||
 | 
					                order.get_selected_orderline().set_discount_percent(val); | 
				
			||||
 | 
					                order.set_discount_percent_order(val); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					    	} | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					//    ============================updates total discount(fixed and percentage) on order ==========================================
 | 
				
			||||
 | 
					    update_summary: function(){ | 
				
			||||
 | 
					        var order = this.pos.get_order(); | 
				
			||||
 | 
					        if (!order.get_orderlines().length) { | 
				
			||||
 | 
					            return; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        var total     = order ? order.get_total_with_tax() : 0; | 
				
			||||
 | 
					        var taxes     = order ? total - order.get_total_without_tax() : 0; | 
				
			||||
 | 
					        var discount_total     = (order && order.get_discount_total_order() > 0) ? order.get_discount_total_order() : 0; | 
				
			||||
 | 
					        var discount_percent   = (order && order.get_discount_percent_order() > 0) ? order.get_discount_percent_order() : 0; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        this.el.querySelector('.summary .total > .value').textContent = this.format_currency(total); | 
				
			||||
 | 
					        this.el.querySelector('.summary .total .subentry .value').textContent = this.format_currency(taxes); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if (discount_total > 0) { | 
				
			||||
 | 
					        this.el.querySelector('.summary .total .subentry .value_discount_percent').textContent = ""; | 
				
			||||
 | 
					        this.el.querySelector('.summary .total .subentry .value_discount_total').textContent = "Discount(Total Fixed)" +this.format_currency(discount_total); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        else { | 
				
			||||
 | 
					        this.el.querySelector('.summary .total .subentry .value_discount_total').textContent = ""; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        if (discount_percent > 0) { | 
				
			||||
 | 
					        this.el.querySelector('.summary .total .subentry .value_discount_total').textContent = ""; | 
				
			||||
 | 
					        this.el.querySelector('.summary .total .subentry .value_discount_percent').textContent = "Discount(Total %)" + discount_percent; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        else { | 
				
			||||
 | 
					        this.el.querySelector('.summary .total .subentry .value_discount_percent').textContent = ""; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					}); | 
				
			||||
 | 
					var OrderlineSuper = models.Orderline; | 
				
			||||
 | 
					models.Orderline = models.Orderline.extend({ | 
				
			||||
 | 
					    initialize: function(attr,options){ | 
				
			||||
 | 
					        OrderlineSuper.prototype.initialize.call(this, attr,options); | 
				
			||||
 | 
					        this.discount_fixed = 0; | 
				
			||||
 | 
					        this.discount_total = 0; | 
				
			||||
 | 
					        this.discount_percent = 0; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    init_from_JSON: function(json) { | 
				
			||||
 | 
					        OrderlineSuper.prototype.init_from_JSON.call(this, json); | 
				
			||||
 | 
					        if(json.discount_fixed > 0) { | 
				
			||||
 | 
					         this.set_discount_fixed(json.discount_fixed); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        else { | 
				
			||||
 | 
					         this.set_discount(json.discount); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    clone: function(){ | 
				
			||||
 | 
					        var orderline = OrderlineSuper.prototype.clone.call(this); | 
				
			||||
 | 
					        orderline.discount_fixed = this.discount_fixed; | 
				
			||||
 | 
					        return orderline; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    set_discount: function(discount){ | 
				
			||||
 | 
					        OrderlineSuper.prototype.set_discount.call(this, discount); | 
				
			||||
 | 
					        this.discount_fixed = 0.0; | 
				
			||||
 | 
					        this.discount_total = 0.0; | 
				
			||||
 | 
					        this.discount_percent = 0.0; | 
				
			||||
 | 
					        this.discountStr = 'percentage'; | 
				
			||||
 | 
					        this.trigger('change',this); | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    set_discount_fixed: function(discount){ | 
				
			||||
 | 
					        this.discount_fixed = discount; | 
				
			||||
 | 
					        this.discount = 0.0; | 
				
			||||
 | 
					        this.discount_total = 0.0; | 
				
			||||
 | 
					        this.discount_percent = 0.0; | 
				
			||||
 | 
					        this.discountStr = 'fixed' ; | 
				
			||||
 | 
					        this.trigger('change',this); | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    set_discount_total: function(discount){ | 
				
			||||
 | 
					        this.discount_total = discount; | 
				
			||||
 | 
					        this.discount_percent = 0.0; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    set_discount_percent: function(discount){ | 
				
			||||
 | 
					        var disc = Math.min(Math.max(parseFloat(discount) || 0, 0),100); | 
				
			||||
 | 
					        this.discount_percent = disc; | 
				
			||||
 | 
					        this.discount_total = 0.0; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    get_discount_total: function(){ | 
				
			||||
 | 
					        return this.discount_total; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    get_discount_percent: function(){ | 
				
			||||
 | 
					        return this.discount_percent; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    get_discount_fixed: function(){ | 
				
			||||
 | 
					        return this.discount_fixed; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    set_quantity: function(quantity){ | 
				
			||||
 | 
					        var order = this.pos.get_order(); | 
				
			||||
 | 
					    	if (order) { | 
				
			||||
 | 
					    	    if(order.selected_orderline == undefined) { | 
				
			||||
 | 
					    	            	    order.set_discount_total_order(0); | 
				
			||||
 | 
					    	                    order.set_discount_percent_order(0); | 
				
			||||
 | 
					    	    } | 
				
			||||
 | 
					    	} | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        this.order.assert_editable(); | 
				
			||||
 | 
					        if(quantity === 'remove'){ | 
				
			||||
 | 
					            this.order.remove_orderline(this); | 
				
			||||
 | 
					            return; | 
				
			||||
 | 
					        }else{ | 
				
			||||
 | 
					            var quant = parseFloat(quantity) || 0; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            var unit = this.get_unit(); | 
				
			||||
 | 
					            if(unit){ | 
				
			||||
 | 
					                if (unit.rounding) { | 
				
			||||
 | 
					                    this.quantity    = round_pr(quant, unit.rounding); | 
				
			||||
 | 
					                    var decimals = this.pos.dp['Product Unit of Measure']; | 
				
			||||
 | 
					                    this.quantityStr = formats.format_value(round_di(this.quantity, decimals), { type: 'float', digits: [69, decimals]}); | 
				
			||||
 | 
					                } else { | 
				
			||||
 | 
					                    this.quantity    = round_pr(quant, 1); | 
				
			||||
 | 
					                    this.quantityStr = this.quantity.toFixed(0); | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					            }else{ | 
				
			||||
 | 
					                this.quantity    = quant; | 
				
			||||
 | 
					                this.quantityStr = '' + this.quantity; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        this.trigger('change',this); | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    can_be_merged_with: function(orderline){ | 
				
			||||
 | 
					        if( this.get_product().id !== orderline.get_product().id){    //only orderline of the same product can be merged
 | 
				
			||||
 | 
					            return false; | 
				
			||||
 | 
					        }else if(!this.get_unit() || !this.get_unit().groupable){ | 
				
			||||
 | 
					            return false; | 
				
			||||
 | 
					        }else if(this.get_product_type() !== orderline.get_product_type()){ | 
				
			||||
 | 
					            return false; | 
				
			||||
 | 
					        }else if(this.get_discount() > 0){             // we don't merge discounted orderlines
 | 
				
			||||
 | 
					            return false; | 
				
			||||
 | 
					        }else if(this.get_discount_fixed() > 0){             // we don't merge discounted orderlines
 | 
				
			||||
 | 
					            return false; | 
				
			||||
 | 
					        }else if(this.price !== orderline.price){ | 
				
			||||
 | 
					            return false; | 
				
			||||
 | 
					        }else{ | 
				
			||||
 | 
					            return true; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    export_as_JSON: function() { | 
				
			||||
 | 
					        return { | 
				
			||||
 | 
					            qty: this.get_quantity(), | 
				
			||||
 | 
					            price_unit: this.get_unit_price(), | 
				
			||||
 | 
					            discount: this.get_discount(), | 
				
			||||
 | 
					            discount_fixed: this.get_discount_fixed(), | 
				
			||||
 | 
					            discount_total: this.get_discount_total(), | 
				
			||||
 | 
					            discount_percent: this.get_discount_percent(), | 
				
			||||
 | 
					            discountStr:this.get_discount_str(), | 
				
			||||
 | 
					            product_id: this.get_product().id, | 
				
			||||
 | 
					            tax_ids: [[6, false, _.map(this.get_applicable_taxes(), function(tax){ return tax.id; })]], | 
				
			||||
 | 
					            id: this.id, | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    export_for_printing: function(){ | 
				
			||||
 | 
					        return { | 
				
			||||
 | 
					            quantity:           this.get_quantity(), | 
				
			||||
 | 
					            unit_name:          this.get_unit().name, | 
				
			||||
 | 
					            price:              this.get_unit_display_price(), | 
				
			||||
 | 
					            discount:           this.get_discount(), | 
				
			||||
 | 
					            discount_fixed:     this.get_discount_fixed(), | 
				
			||||
 | 
					            discount_total:     this.get_discount_total(), | 
				
			||||
 | 
					            discount_percent:     this.get_discount_percent(), | 
				
			||||
 | 
					            discountStr:        this.get_discount_str(), | 
				
			||||
 | 
					            product_name:       this.get_product().display_name, | 
				
			||||
 | 
					            price_display :     this.get_display_price(), | 
				
			||||
 | 
					            price_with_tax :    this.get_price_with_tax(), | 
				
			||||
 | 
					            price_without_tax:  this.get_price_without_tax(), | 
				
			||||
 | 
					            tax:                this.get_tax(), | 
				
			||||
 | 
					            product_description:      this.get_product().description, | 
				
			||||
 | 
					            product_description_sale: this.get_product().description_sale, | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    get_base_price:    function(){ | 
				
			||||
 | 
					        var rounding = this.pos.currency.rounding; | 
				
			||||
 | 
					        if(this.discount_fixed !== 0){ | 
				
			||||
 | 
					            return round_pr(this.get_unit_price() * this.get_quantity() - this.get_discount_fixed(), rounding); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return round_pr(this.get_unit_price() * this.get_quantity() * (1 - this.get_discount()/100), rounding); | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    get_all_prices: function(){ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					       if(this.discount_fixed > 0) | 
				
			||||
 | 
					       { | 
				
			||||
 | 
					            var price_unit = this.get_unit_price() * this.get_quantity() - this.get_discount_fixed(); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					       else { | 
				
			||||
 | 
					            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 =  this.pos.taxes; | 
				
			||||
 | 
					        var taxdetail = {}; | 
				
			||||
 | 
					        var product_taxes = []; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        _(taxes_ids).each(function(el){ | 
				
			||||
 | 
					            product_taxes.push(_.detect(taxes, function(t){ | 
				
			||||
 | 
					                return t.id === el; | 
				
			||||
 | 
					            })); | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        var all_taxes = this.compute_all(product_taxes, price_unit, this.get_quantity(), this.pos.currency.rounding); | 
				
			||||
 | 
					        _(all_taxes.taxes).each(function(tax) { | 
				
			||||
 | 
					            taxtotal += tax.amount; | 
				
			||||
 | 
					            taxdetail[tax.id] = tax.amount; | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					        if(this.get_discount_fixed() != 0) { | 
				
			||||
 | 
					            all_taxes.total_excluded = price_unit; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        return { | 
				
			||||
 | 
					            "priceWithTax": all_taxes.total_included, | 
				
			||||
 | 
					            "priceWithoutTax": all_taxes.total_excluded, | 
				
			||||
 | 
					            "tax": taxtotal, | 
				
			||||
 | 
					            "taxDetails": taxdetail, | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					}); | 
				
			||||
 | 
					     | 
				
			||||
 | 
					var OrderSuper = models.Order;  | 
				
			||||
 | 
					models.Order = models.Order.extend({ | 
				
			||||
 | 
					    initialize: function(attributes,options){ | 
				
			||||
 | 
					        var order = OrderSuper.prototype.initialize.call(this, attributes,options); | 
				
			||||
 | 
					        order.discount_total = 0; | 
				
			||||
 | 
					        order.discount_percent = 0; | 
				
			||||
 | 
					        return order; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    init_from_JSON: function(json) { | 
				
			||||
 | 
					        OrderSuper.prototype.init_from_JSON.call(this, json); | 
				
			||||
 | 
					        this.discount_total = json.discount_total; | 
				
			||||
 | 
					        this.discount_percent = json.discount_percent; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    export_as_JSON: function() { | 
				
			||||
 | 
					        var json_new = OrderSuper.prototype.export_as_JSON.call(this); | 
				
			||||
 | 
					        json_new.discount_total = this.get_discount_total_order(); | 
				
			||||
 | 
					        json_new.discount_percent = this.get_discount_percent_order(); | 
				
			||||
 | 
					        return json_new; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    export_for_printing: function(){ | 
				
			||||
 | 
					        var orderlines = []; | 
				
			||||
 | 
					        var self = this; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        this.orderlines.each(function(orderline){ | 
				
			||||
 | 
					            orderlines.push(orderline.export_for_printing()); | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        var paymentlines = []; | 
				
			||||
 | 
					        this.paymentlines.each(function(paymentline){ | 
				
			||||
 | 
					            paymentlines.push(paymentline.export_for_printing()); | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					        var client  = this.get('client'); | 
				
			||||
 | 
					        var cashier = this.pos.cashier || this.pos.user; | 
				
			||||
 | 
					        var company = this.pos.company; | 
				
			||||
 | 
					        var shop    = this.pos.shop; | 
				
			||||
 | 
					        var date    = new Date(); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        function is_xml(subreceipt){ | 
				
			||||
 | 
					            return subreceipt ? (subreceipt.split('\n')[0].indexOf('<!DOCTYPE QWEB') >= 0) : false; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        function render_xml(subreceipt){ | 
				
			||||
 | 
					            if (!is_xml(subreceipt)) { | 
				
			||||
 | 
					                return subreceipt; | 
				
			||||
 | 
					            } else { | 
				
			||||
 | 
					                subreceipt = subreceipt.split('\n').slice(1).join('\n'); | 
				
			||||
 | 
					                var qweb = new QWeb2.Engine(); | 
				
			||||
 | 
					                    qweb.debug = core.debug; | 
				
			||||
 | 
					                    qweb.default_dict = _.clone(QWeb.default_dict); | 
				
			||||
 | 
					                    qweb.add_template('<templates><t t-name="subreceipt">'+subreceipt+'</t></templates>'); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                return qweb.render('subreceipt',{'pos':self.pos,'widget':self.pos.chrome,'order':self, 'receipt': receipt}) ; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        var receipt = { | 
				
			||||
 | 
					            orderlines: orderlines, | 
				
			||||
 | 
					            paymentlines: paymentlines, | 
				
			||||
 | 
					            subtotal: this.get_subtotal(), | 
				
			||||
 | 
					            total_with_tax: this.get_total_with_tax(), | 
				
			||||
 | 
					            total_without_tax: this.get_total_without_tax(), | 
				
			||||
 | 
					            total_tax: this.get_total_tax(), | 
				
			||||
 | 
					            total_paid: this.get_total_paid(), | 
				
			||||
 | 
					            discount_total_fixed: this.get_discount_total_order(), | 
				
			||||
 | 
					            discount_total_percent: this.get_discount_percent_order(), | 
				
			||||
 | 
					            total_discount: this.get_total_discount(), | 
				
			||||
 | 
					            tax_details: this.get_tax_details(), | 
				
			||||
 | 
					            change: this.get_change(), | 
				
			||||
 | 
					            name : this.get_name(), | 
				
			||||
 | 
					            client: client ? client.name : null , | 
				
			||||
 | 
					            invoice_id: null,   //TODO
 | 
				
			||||
 | 
					            cashier: cashier ? cashier.name : null, | 
				
			||||
 | 
					            precision: { | 
				
			||||
 | 
					                price: 2, | 
				
			||||
 | 
					                money: 2, | 
				
			||||
 | 
					                quantity: 3, | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            date: { | 
				
			||||
 | 
					                year: date.getFullYear(), | 
				
			||||
 | 
					                month: date.getMonth(), | 
				
			||||
 | 
					                date: date.getDate(),       // day of the month
 | 
				
			||||
 | 
					                day: date.getDay(),         // day of the week
 | 
				
			||||
 | 
					                hour: date.getHours(), | 
				
			||||
 | 
					                minute: date.getMinutes() , | 
				
			||||
 | 
					                isostring: date.toISOString(), | 
				
			||||
 | 
					                localestring: date.toLocaleString(), | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            company:{ | 
				
			||||
 | 
					                email: company.email, | 
				
			||||
 | 
					                website: company.website, | 
				
			||||
 | 
					                company_registry: company.company_registry, | 
				
			||||
 | 
					                contact_address: company.partner_id[1], | 
				
			||||
 | 
					                vat: company.vat, | 
				
			||||
 | 
					                name: company.name, | 
				
			||||
 | 
					                phone: company.phone, | 
				
			||||
 | 
					                logo:  this.pos.company_logo_base64, | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            shop:{ | 
				
			||||
 | 
					                name: shop.name, | 
				
			||||
 | 
					            }, | 
				
			||||
 | 
					            currency: this.pos.currency, | 
				
			||||
 | 
					        }; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if (is_xml(this.pos.config.receipt_header)){ | 
				
			||||
 | 
					            receipt.header = ''; | 
				
			||||
 | 
					            receipt.header_xml = render_xml(this.pos.config.receipt_header); | 
				
			||||
 | 
					        } else { | 
				
			||||
 | 
					            receipt.header = this.pos.config.receipt_header || ''; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if (is_xml(this.pos.config.receipt_footer)){ | 
				
			||||
 | 
					            receipt.footer = ''; | 
				
			||||
 | 
					            receipt.footer_xml = render_xml(this.pos.config.receipt_footer); | 
				
			||||
 | 
					        } else { | 
				
			||||
 | 
					            receipt.footer = this.pos.config.receipt_footer || ''; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return receipt; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    set_discount_total_order: function(discount){ | 
				
			||||
 | 
					        this.discount_total = discount; | 
				
			||||
 | 
					        this.discount_percent = 0; | 
				
			||||
 | 
					        this.trigger('change',this); | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    get_discount_total_order: function(){ | 
				
			||||
 | 
					        return this.discount_total; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    set_discount_percent_order: function(discount){ | 
				
			||||
 | 
					        var disc = Math.min(Math.max(parseFloat(discount) || 0, 0),100); | 
				
			||||
 | 
					        this.discount_percent = disc; | 
				
			||||
 | 
					        this.discount_total = 0.0; | 
				
			||||
 | 
					        this.trigger('change',this); | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    get_discount_percent_order: function(){ | 
				
			||||
 | 
					        return this.discount_percent; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    get_total_without_tax: function() { | 
				
			||||
 | 
					        var total_fixed_disc = this.get_discount_total_order(); | 
				
			||||
 | 
					        var total_percent_disc = this.get_discount_percent_order(); | 
				
			||||
 | 
					        if (total_fixed_disc) { | 
				
			||||
 | 
					            return round_pr(this.orderlines.reduce((function(sum, orderLine) { | 
				
			||||
 | 
					            return sum + orderLine.get_price_without_tax(); | 
				
			||||
 | 
					        }), 0), this.pos.currency.rounding) - total_fixed_disc ; | 
				
			||||
 | 
					         } | 
				
			||||
 | 
					         if (total_percent_disc) { | 
				
			||||
 | 
					            var temp = round_pr(this.orderlines.reduce((function(sum, orderLine) { | 
				
			||||
 | 
					            return sum + orderLine.get_price_without_tax(); | 
				
			||||
 | 
					        }), 0), this.pos.currency.rounding); | 
				
			||||
 | 
					            return (temp - (temp * total_percent_disc / 100)) | 
				
			||||
 | 
					         } | 
				
			||||
 | 
					        return round_pr(this.orderlines.reduce((function(sum, orderLine) { | 
				
			||||
 | 
					            return sum + orderLine.get_price_without_tax(); | 
				
			||||
 | 
					        }), 0), this.pos.currency.rounding); | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					    get_total_discount: function() { | 
				
			||||
 | 
					        var sum = OrderSuper.prototype.get_total_discount.call(this); | 
				
			||||
 | 
					        sum = 0.0; | 
				
			||||
 | 
					        var disc = 0.0; | 
				
			||||
 | 
					        for (var i = 0; i < this.orderlines.length; i++) { | 
				
			||||
 | 
					        var NewOrder = this.orderlines.models[i]; | 
				
			||||
 | 
					        disc +=  (NewOrder.quantity * NewOrder.price); | 
				
			||||
 | 
					        if (NewOrder.discountStr == 'fixed') { | 
				
			||||
 | 
					            sum +=  parseFloat(NewOrder.discount_fixed); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        else { | 
				
			||||
 | 
					            sum +=  NewOrder.quantity * NewOrder.price * (parseFloat(NewOrder.discount) / 100); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        if (this.discount_total) { sum +=  parseFloat(this.discount_total); } | 
				
			||||
 | 
					        disc -= parseFloat(this.get_total_without_tax() + sum); | 
				
			||||
 | 
					        if (this.discount_percent) { sum +=  disc; } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return sum; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					});    | 
				
			||||
 | 
					models.PosModel = models.PosModel.extend({ | 
				
			||||
 | 
					    push_and_invoice_order: function(order){ | 
				
			||||
 | 
					        var self = this; | 
				
			||||
 | 
					        var invoiced = new $.Deferred(); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if(!order.get_client()){ | 
				
			||||
 | 
					            invoiced.reject({code:400, message:'Missing Customer', data:{}}); | 
				
			||||
 | 
					            return invoiced; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        var order_id = this.db.add_order(order.export_as_JSON()); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        this.flush_mutex.exec(function(){ | 
				
			||||
 | 
					            var done = new $.Deferred(); // holds the mutex
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            // send the order to the server
 | 
				
			||||
 | 
					            // we have a 30 seconds timeout on this push.
 | 
				
			||||
 | 
					            // FIXME: if the server takes more than 30 seconds to accept the order,
 | 
				
			||||
 | 
					            // the client will believe it wasn't successfully sent, and very bad
 | 
				
			||||
 | 
					            // things will happen as a duplicate will be sent next time
 | 
				
			||||
 | 
					            // so we must make sure the server detects and ignores duplicated orders
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            var transfer = self._flush_orders([self.db.get_order(order_id)], {timeout:30000, to_invoice:true}); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            transfer.fail(function(error){ | 
				
			||||
 | 
					                invoiced.reject(error); | 
				
			||||
 | 
					                done.reject(); | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            // on success, get the order id generated by the server
 | 
				
			||||
 | 
					            transfer.pipe(function(order_server_id){ | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                // generate the pdf and download it
 | 
				
			||||
 | 
					                self.chrome.do_action('discounts_in_pos.pos_invoice_report',{additional_context:{ | 
				
			||||
 | 
					                    active_ids:order_server_id, | 
				
			||||
 | 
					                }}); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                invoiced.resolve(); | 
				
			||||
 | 
					                done.resolve(); | 
				
			||||
 | 
					            }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            return done; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        }); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return invoiced; | 
				
			||||
 | 
					    }, | 
				
			||||
 | 
					}); | 
				
			||||
 | 
					}); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
@ -0,0 +1,223 @@ | 
				
			|||||
 | 
					<?xml version="1.0" encoding="UTF-8"?> | 
				
			||||
 | 
					<templates id="pos_extend_template" inherit_id="point_of_sale.template"> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<t t-extend="NumpadWidget"> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<t t-jquery="div.numpad" t-operation="inner"> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            <button class="input-button number-char">1</button> | 
				
			||||
 | 
					            <button class="input-button number-char">2</button> | 
				
			||||
 | 
					            <button class="input-button number-char">3</button> | 
				
			||||
 | 
					            <button class="mode-button" data-mode='quantity'>Qty</button> | 
				
			||||
 | 
					            <br /> | 
				
			||||
 | 
					            <button class="input-button number-char">4</button> | 
				
			||||
 | 
					            <button class="input-button number-char">5</button> | 
				
			||||
 | 
					            <button class="input-button number-char">6</button> | 
				
			||||
 | 
					            <button class="mode-button" data-mode='discount'>Disc</button> | 
				
			||||
 | 
					            <br /> | 
				
			||||
 | 
					            <button class="input-button number-char">7</button> | 
				
			||||
 | 
					            <button class="input-button number-char">8</button> | 
				
			||||
 | 
					            <button class="input-button number-char">9</button> | 
				
			||||
 | 
					            <button class="mode-button" data-mode='price'>Price</button> | 
				
			||||
 | 
					            <br /> | 
				
			||||
 | 
					            <button class="input-button numpad-minus" >+/-</button> | 
				
			||||
 | 
					            <button class="input-button number-char">0</button> | 
				
			||||
 | 
					            <button class="input-button number-char">.</button> | 
				
			||||
 | 
					            <button class="input-button numpad-backspace"> | 
				
			||||
 | 
					                <img style="pointer-events: none;" src="/point_of_sale/static/src/img/backspace.png" width="24" height="21" /> | 
				
			||||
 | 
					            </button> | 
				
			||||
 | 
					            <br /> | 
				
			||||
 | 
					            <button class="mode-button" data-mode='discount_fixed' style="width:100%;height:45px;">Disc.Fixed</button> | 
				
			||||
 | 
					            <button class="mode-button" data-mode='discount_percent' style="width:40%;height:45px;">Disc(Total %)</button> | 
				
			||||
 | 
					            <br /> | 
				
			||||
 | 
					            <button class="mode-button" data-mode='discount_total' style="width:60%;height:45px;">Dis.Fixed(Total)</button> | 
				
			||||
 | 
					</t> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					</t> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					<t t-name="Orderline"> | 
				
			||||
 | 
					        <li t-attf-class="orderline #{ line.selected ? 'selected' : '' }"> | 
				
			||||
 | 
					            <span class="product-name"> | 
				
			||||
 | 
					                <t t-esc="line.get_product().display_name"/> | 
				
			||||
 | 
					            </span> | 
				
			||||
 | 
					            <span class="price"> | 
				
			||||
 | 
					                <t t-esc="widget.format_currency(line.get_display_price())"/> | 
				
			||||
 | 
					            </span> | 
				
			||||
 | 
					            <ul class="info-list"> | 
				
			||||
 | 
					                <t t-if="line.get_quantity_str() !== '1' || line.selected "> | 
				
			||||
 | 
					                    <li class="info"> | 
				
			||||
 | 
					                        <em> | 
				
			||||
 | 
					                            <t t-esc="line.get_quantity_str()" /> | 
				
			||||
 | 
					                        </em> | 
				
			||||
 | 
					                        <t t-esc="line.get_unit().name" /> | 
				
			||||
 | 
					                        at | 
				
			||||
 | 
					                        <t t-esc="widget.format_currency(line.get_unit_display_price(),'Product Price')" /> | 
				
			||||
 | 
					                        / | 
				
			||||
 | 
					                        <t t-esc="line.get_unit().name" /> | 
				
			||||
 | 
					                    </li> | 
				
			||||
 | 
					                </t> | 
				
			||||
 | 
					                <t t-if="line.get_discount()"> | 
				
			||||
 | 
					                    <li class="info"> | 
				
			||||
 | 
					                        With a | 
				
			||||
 | 
					                        <em> | 
				
			||||
 | 
					                            <t t-esc="line.get_discount()" />% | 
				
			||||
 | 
					                        </em> | 
				
			||||
 | 
					                        discount | 
				
			||||
 | 
					                    </li> | 
				
			||||
 | 
					                </t> | 
				
			||||
 | 
					                <t t-if="line.get_discount_fixed()"> | 
				
			||||
 | 
					                    <li class="info"> | 
				
			||||
 | 
					                        With a | 
				
			||||
 | 
					                        <em> | 
				
			||||
 | 
					                            <t t-esc="widget.format_currency(line.get_discount_fixed())"/> | 
				
			||||
 | 
					                        </em> | 
				
			||||
 | 
					                        discount | 
				
			||||
 | 
					                    </li> | 
				
			||||
 | 
					                </t> | 
				
			||||
 | 
					            </ul> | 
				
			||||
 | 
					        </li> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    <t t-name="OrderWidget"> | 
				
			||||
 | 
					        <div class="order-container"> | 
				
			||||
 | 
					            <div class="order-scroller touch-scrollable"> | 
				
			||||
 | 
					                <div class="order"> | 
				
			||||
 | 
					                    <t t-if="orderlines.length === 0" > | 
				
			||||
 | 
					                        <div class='order-empty'> | 
				
			||||
 | 
					                            <i class='fa fa-shopping-cart' /> | 
				
			||||
 | 
					                            <h1>Your shopping cart is empty</h1> | 
				
			||||
 | 
					                        </div> | 
				
			||||
 | 
					                    </t> | 
				
			||||
 | 
					                    <t t-if="orderlines.length > 0"> | 
				
			||||
 | 
					                        <ul class="orderlines"></ul> | 
				
			||||
 | 
					                        <div class="summary clearfix"> | 
				
			||||
 | 
					                            <div class="line"> | 
				
			||||
 | 
					                                <div class='entry total'> | 
				
			||||
 | 
					                                    <span class="label">Total: </span> <span class="value">0.00 €</span> | 
				
			||||
 | 
					                                    <div class='subentry'>Taxes: <span class="value">0.00€</span></div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                                    <div class='subentry'><span class="value_discount_total"></span></div> | 
				
			||||
 | 
					                                    <div class='subentry'><span class="value_discount_percent"></span></div> | 
				
			||||
 | 
					                                </div> | 
				
			||||
 | 
					                            </div> | 
				
			||||
 | 
					                        </div> | 
				
			||||
 | 
					                    </t> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    <t t-name="PosTicket"> | 
				
			||||
 | 
					        <div class="pos-sale-ticket"> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            <div class="pos-center-align"><t t-esc="moment().format('L LT')"/> <t t-esc="order.name"/></div> | 
				
			||||
 | 
					            <br /> | 
				
			||||
 | 
					            <t t-esc="widget.pos.company.name"/><br /> | 
				
			||||
 | 
					            Phone: <t t-esc="widget.pos.company.phone || ''"/><br /> | 
				
			||||
 | 
					            User: <t t-esc="widget.pos.cashier ? widget.pos.cashier.name : widget.pos.user.name"/><br /> | 
				
			||||
 | 
					            Shop: <t t-esc="widget.pos.shop.name"/><br /> | 
				
			||||
 | 
					            <br /> | 
				
			||||
 | 
					            <t t-if="receipt.header"> | 
				
			||||
 | 
					                <div style='text-align:center'> | 
				
			||||
 | 
					                    <t t-esc="receipt.header" /> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <br /> | 
				
			||||
 | 
					            </t> | 
				
			||||
 | 
					            <table class='receipt-orderlines'> | 
				
			||||
 | 
					                <colgroup> | 
				
			||||
 | 
					                    <col width='50%' /> | 
				
			||||
 | 
					                    <col width='25%' /> | 
				
			||||
 | 
					                    <col width='25%' /> | 
				
			||||
 | 
					                </colgroup> | 
				
			||||
 | 
					                <tr t-foreach="orderlines" t-as="orderline"> | 
				
			||||
 | 
					                    <td> | 
				
			||||
 | 
					                        <t t-esc="orderline.get_product().display_name"/> | 
				
			||||
 | 
					                         <t t-if="orderline.get_discount() > 0"> | 
				
			||||
 | 
					                             <div class="pos-disc-font"> | 
				
			||||
 | 
					                                With a <t t-esc="orderline.get_discount()"/>% discount | 
				
			||||
 | 
					                             </div> | 
				
			||||
 | 
					                        </t> | 
				
			||||
 | 
					                        <t t-if="orderline.get_discount_fixed() > 0"> | 
				
			||||
 | 
					                            <div class="pos-disc-font"> | 
				
			||||
 | 
					                                With a <t t-esc="widget.format_currency(orderline.get_discount_fixed())"/> discount | 
				
			||||
 | 
					                            </div> | 
				
			||||
 | 
					                        </t> | 
				
			||||
 | 
					                    </td> | 
				
			||||
 | 
					                    <td class="pos-right-align"> | 
				
			||||
 | 
					                        <t t-esc="orderline.get_quantity_str_with_unit()"/> | 
				
			||||
 | 
					                    </td> | 
				
			||||
 | 
					                    <td class="pos-right-align"> | 
				
			||||
 | 
					                        <t t-esc="widget.format_currency(orderline.get_display_price())"/> | 
				
			||||
 | 
					                    </td> | 
				
			||||
 | 
					                </tr> | 
				
			||||
 | 
					            </table> | 
				
			||||
 | 
					            <br /> | 
				
			||||
 | 
					            <table class='receipt-total'> | 
				
			||||
 | 
					                <tr> | 
				
			||||
 | 
					                    <td>Subtotal:</td> | 
				
			||||
 | 
					                    <td class="pos-right-align"> | 
				
			||||
 | 
					                        <t t-esc="widget.format_currency(order.get_total_without_tax())"/> | 
				
			||||
 | 
					                    </td> | 
				
			||||
 | 
					                </tr> | 
				
			||||
 | 
					                <t t-foreach="order.get_tax_details()" t-as="taxdetail"> | 
				
			||||
 | 
					                    <tr> | 
				
			||||
 | 
					                        <td><t t-esc="taxdetail.name" /></td> | 
				
			||||
 | 
					                        <td class="pos-right-align"> | 
				
			||||
 | 
					                            <t t-esc="widget.format_currency(taxdetail.amount)" /> | 
				
			||||
 | 
					                        </td> | 
				
			||||
 | 
					                    </tr> | 
				
			||||
 | 
					                </t> | 
				
			||||
 | 
					                <tr> | 
				
			||||
 | 
					                    <td>Disc.Fixed(Total):</td> | 
				
			||||
 | 
					                    <td class="pos-right-align"> | 
				
			||||
 | 
					                        <t t-esc="widget.format_currency(order.get_discount_total_order())"/> | 
				
			||||
 | 
					                    </td> | 
				
			||||
 | 
					                </tr> | 
				
			||||
 | 
					                <tr> | 
				
			||||
 | 
					                    <td>Disc.Percent(Total):</td> | 
				
			||||
 | 
					                    <td class="pos-right-align"> | 
				
			||||
 | 
					                        <t t-esc="order.get_discount_percent_order()"/> % | 
				
			||||
 | 
					                    </td> | 
				
			||||
 | 
					                </tr> | 
				
			||||
 | 
					                <tr> | 
				
			||||
 | 
					                    <td>Total Discount:</td> | 
				
			||||
 | 
					                    <td class="pos-right-align"> | 
				
			||||
 | 
					                        <t t-esc="widget.format_currency(order.get_total_discount())"/> | 
				
			||||
 | 
					                    </td> | 
				
			||||
 | 
					                </tr> | 
				
			||||
 | 
					                <tr class="emph"> | 
				
			||||
 | 
					                    <td>Total:</td> | 
				
			||||
 | 
					                    <td class="pos-right-align"> | 
				
			||||
 | 
					                        <t t-esc="widget.format_currency(order.get_total_with_tax())"/> | 
				
			||||
 | 
					                    </td> | 
				
			||||
 | 
					                </tr> | 
				
			||||
 | 
					            </table> | 
				
			||||
 | 
					            <br /> | 
				
			||||
 | 
					            <table class='receipt-paymentlines'> | 
				
			||||
 | 
					                <t t-foreach="paymentlines" t-as="line"> | 
				
			||||
 | 
					                  <tr> | 
				
			||||
 | 
					                      <td> | 
				
			||||
 | 
					                          <t t-esc="line.name"/> | 
				
			||||
 | 
					                      </td> | 
				
			||||
 | 
					                      <td class="pos-right-align"> | 
				
			||||
 | 
					                          <t t-esc="widget.format_currency(line.get_amount())"/> | 
				
			||||
 | 
					                      </td> | 
				
			||||
 | 
					                  </tr> | 
				
			||||
 | 
					                </t> | 
				
			||||
 | 
					            </table> | 
				
			||||
 | 
					            <br /> | 
				
			||||
 | 
					            <table class='receipt-change'> | 
				
			||||
 | 
					                <tr><td>Change:</td><td class="pos-right-align"> | 
				
			||||
 | 
					                    <t t-esc="widget.format_currency(order.get_change())"/> | 
				
			||||
 | 
					                    </td></tr> | 
				
			||||
 | 
					            </table> | 
				
			||||
 | 
					            <t t-if="receipt.footer"> | 
				
			||||
 | 
					                <br /> | 
				
			||||
 | 
					                <div style='text-align:center'> | 
				
			||||
 | 
					                    <t t-esc="receipt.footer" /> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </t> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					</templates> | 
				
			||||
@ -0,0 +1,21 @@ | 
				
			|||||
 | 
					<?xml version="1.0"?> | 
				
			||||
 | 
					<openerp> | 
				
			||||
 | 
					    <data> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        <record model="ir.ui.view" id="view_pos_invoice_new_extended"> | 
				
			||||
 | 
					            <field name="name">pos.order.invoice.extend</field> | 
				
			||||
 | 
					            <field name="model">account.invoice</field> | 
				
			||||
 | 
					            <field name="inherit_id" ref="account.invoice_form"/> | 
				
			||||
 | 
					            <field name="arch" type="xml"> | 
				
			||||
 | 
					                <xpath expr="//field[@name='discount']" position="after"> | 
				
			||||
 | 
					                    <field name="discount_fixed" groups="sale.group_discount_per_so_line"/> | 
				
			||||
 | 
					                </xpath> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                <xpath expr="//field[@name='amount_tax']" position="after"> | 
				
			||||
 | 
					                    <field name="discount_total"/> | 
				
			||||
 | 
					                    <field name="discount_percent"/> | 
				
			||||
 | 
					                </xpath> | 
				
			||||
 | 
					            </field> | 
				
			||||
 | 
					    </record> | 
				
			||||
 | 
					    </data> | 
				
			||||
 | 
					</openerp> | 
				
			||||
@ -0,0 +1,186 @@ | 
				
			|||||
 | 
					<?xml version="1.0" encoding="iso-8859-1"?> | 
				
			||||
 | 
					<openerp> | 
				
			||||
 | 
					<data> | 
				
			||||
 | 
					    <template id="report_invoice_document_new"> | 
				
			||||
 | 
					    <t t-call="report.external_layout"> | 
				
			||||
 | 
					        <t t-set="o" t-value="o.with_context({'lang':o.partner_id.lang})" /> | 
				
			||||
 | 
					        <div class="page"> | 
				
			||||
 | 
					            <div class="row"> | 
				
			||||
 | 
					                <div class="col-xs-5 col-xs-offset-7"> | 
				
			||||
 | 
					                    <address t-field="o.partner_id" | 
				
			||||
 | 
					                        t-field-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}' /> | 
				
			||||
 | 
					                    <span t-if="o.partner_id.vat">TIN: <span t-field="o.partner_id.vat"/></span> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            <h2> | 
				
			||||
 | 
					                <span t-if="o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')">Invoice</span> | 
				
			||||
 | 
					                <span t-if="o.type == 'out_invoice' and o.state == 'proforma2'">PRO-FORMA</span> | 
				
			||||
 | 
					                <span t-if="o.type == 'out_invoice' and o.state == 'draft'">Draft Invoice</span> | 
				
			||||
 | 
					                <span t-if="o.type == 'out_invoice' and o.state == 'cancel'">Cancelled Invoice</span> | 
				
			||||
 | 
					                <span t-if="o.type == 'out_refund'">Refund</span> | 
				
			||||
 | 
					                <span t-if="o.type == 'in_refund'">Vendor Refund</span> | 
				
			||||
 | 
					                <span t-if="o.type == 'in_invoice'">Vendor Bill</span> | 
				
			||||
 | 
					                <span t-field="o.number"/> | 
				
			||||
 | 
					            </h2> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            <div class="row mt32 mb32"> | 
				
			||||
 | 
					                <div class="col-xs-2" t-if="o.name"> | 
				
			||||
 | 
					                    <strong>Description:</strong> | 
				
			||||
 | 
					                    <p t-field="o.name"/> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div class="col-xs-2" t-if="o.date_invoice"> | 
				
			||||
 | 
					                    <strong>Invoice Date:</strong> | 
				
			||||
 | 
					                    <p t-field="o.date_invoice"/> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div class="col-xs-2" t-if="o.date_due and o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')"> | 
				
			||||
 | 
					                    <strong>Due Date:</strong> | 
				
			||||
 | 
					                    <p t-field="o.date_due"/> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div class="col-xs-2" t-if="o.origin"> | 
				
			||||
 | 
					                    <strong>Source:</strong> | 
				
			||||
 | 
					                    <p t-field="o.origin"/> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div class="col-xs-2" t-if="o.partner_id.ref"> | 
				
			||||
 | 
					                    <strong>Customer Code:</strong> | 
				
			||||
 | 
					                    <p t-field="o.partner_id.ref"/> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div name="reference" class="col-xs-2" t-if="o.reference"> | 
				
			||||
 | 
					                    <strong>Reference:</strong> | 
				
			||||
 | 
					                    <p t-field="o.reference"/> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            <!-- Is there a discount on at least one line? --> | 
				
			||||
 | 
					            <t t-set="display_discount" t-value="any([l.discount_fixed for l in o.invoice_line_ids])"/> | 
				
			||||
 | 
					            <!--<t t-set="display_discount_fixed" t-value="any([l.discount_fixed for l in o.invoice_line_ids])"/>--> | 
				
			||||
 | 
					            <table class="table table-condensed"> | 
				
			||||
 | 
					                <thead> | 
				
			||||
 | 
					                    <tr> | 
				
			||||
 | 
					                        <th>Description</th> | 
				
			||||
 | 
					                        <th class="text-right">Quantity</th> | 
				
			||||
 | 
					                        <th class="text-right">Unit Price</th> | 
				
			||||
 | 
					                        <th class="text-right" groups="sale.group_discount_per_so_line">Disc.(%)</th> | 
				
			||||
 | 
					                        <th class="text-right" groups="sale.group_discount_per_so_line">Disc.Fixed</th> | 
				
			||||
 | 
					                        <th class="text-right">Taxes</th> | 
				
			||||
 | 
					                        <th class="text-right">Price</th> | 
				
			||||
 | 
					                    </tr> | 
				
			||||
 | 
					                </thead> | 
				
			||||
 | 
					                <tbody class="invoice_tbody"> | 
				
			||||
 | 
					                    <tr t-foreach="o.invoice_line_ids" t-as="l"> | 
				
			||||
 | 
					                        <td><span t-field="l.name"/></td> | 
				
			||||
 | 
					                        <td class="text-right"> | 
				
			||||
 | 
					                            <span t-field="l.quantity"/> | 
				
			||||
 | 
					                            <span t-field="l.uom_id"  groups="product.group_uom"/> | 
				
			||||
 | 
					                        </td> | 
				
			||||
 | 
					                        <td class="text-right"> | 
				
			||||
 | 
					                            <span t-field="l.price_unit"/> | 
				
			||||
 | 
					                        </td> | 
				
			||||
 | 
					                        <td class="text-right" groups="sale.group_discount_per_so_line"> | 
				
			||||
 | 
					                            <span t-field="l.discount"/> | 
				
			||||
 | 
					                        </td> | 
				
			||||
 | 
					                        <td class="text-right" groups="sale.group_discount_per_so_line"> | 
				
			||||
 | 
					                            <span t-field="l.discount_fixed"/> | 
				
			||||
 | 
					                        </td> | 
				
			||||
 | 
					                        <td class="text-right"> | 
				
			||||
 | 
					                            <span t-esc="', '.join(map(lambda x: (x.description or x.name), l.invoice_line_tax_ids))"/> | 
				
			||||
 | 
					                        </td> | 
				
			||||
 | 
					                        <td class="text-right"> | 
				
			||||
 | 
					                            <span t-field="l.price_subtotal" | 
				
			||||
 | 
					                                t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/> | 
				
			||||
 | 
					                        </td> | 
				
			||||
 | 
					                    </tr> | 
				
			||||
 | 
					                </tbody> | 
				
			||||
 | 
					            </table> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            <div class="row"> | 
				
			||||
 | 
					                <div class="col-xs-4 pull-right"> | 
				
			||||
 | 
					                    <table class="table table-condensed"> | 
				
			||||
 | 
					                        <tr class="border-black"> | 
				
			||||
 | 
					                            <td><strong>Subtotal</strong></td> | 
				
			||||
 | 
					                            <td class="text-right"> | 
				
			||||
 | 
					                                <span t-field="o.amount_untaxed" t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/> | 
				
			||||
 | 
					                            </td> | 
				
			||||
 | 
					                        </tr> | 
				
			||||
 | 
					                        <tr class="border-black"> | 
				
			||||
 | 
					                            <td><strong>Discount Fixed(Total)</strong></td> | 
				
			||||
 | 
					                            <td class="text-right"> | 
				
			||||
 | 
					                                <span t-field="o.discount_total" t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/> | 
				
			||||
 | 
					                            </td> | 
				
			||||
 | 
					                        </tr> | 
				
			||||
 | 
					                        <tr class="border-black"> | 
				
			||||
 | 
					                            <td><strong>Discount Percent(Total)</strong></td> | 
				
			||||
 | 
					                            <td class="text-right"> | 
				
			||||
 | 
					                                <span t-field="o.discount_percent"/>% | 
				
			||||
 | 
					                            </td> | 
				
			||||
 | 
					                        </tr> | 
				
			||||
 | 
					                        <t t-foreach="o._get_tax_amount_by_group()" t-as="amount_by_group"> | 
				
			||||
 | 
					                            <tr> | 
				
			||||
 | 
					                                <td><span t-esc="amount_by_group[0]"/></td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <span t-esc="amount_by_group[1]"/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                            </tr> | 
				
			||||
 | 
					                        </t> | 
				
			||||
 | 
					                        <tr class="border-black"> | 
				
			||||
 | 
					                            <td><strong>Total</strong></td> | 
				
			||||
 | 
					                            <td class="text-right"> | 
				
			||||
 | 
					                                 <span t-field="o.amount_total" t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/> | 
				
			||||
 | 
					                            </td> | 
				
			||||
 | 
					                        </tr> | 
				
			||||
 | 
					                    </table> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            <div class="row" t-if="o.tax_line_ids"> | 
				
			||||
 | 
					                <div class="col-xs-6"> | 
				
			||||
 | 
					                    <table class="table table-condensed"> | 
				
			||||
 | 
					                        <thead> | 
				
			||||
 | 
					                            <tr> | 
				
			||||
 | 
					                                <th>Tax</th> | 
				
			||||
 | 
					                                <th class="text-right">Base</th> | 
				
			||||
 | 
					                                <th class="text-right">Amount</th> | 
				
			||||
 | 
					                            </tr> | 
				
			||||
 | 
					                        </thead> | 
				
			||||
 | 
					                        <tbody> | 
				
			||||
 | 
					                            <tr t-foreach="o.tax_line_ids" t-as="t"> | 
				
			||||
 | 
					                                <td><span t-field="t.name"/></td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <span t-field="t.base" | 
				
			||||
 | 
					                                        t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <span t-field="t.amount" | 
				
			||||
 | 
					                                        t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                            </tr> | 
				
			||||
 | 
					                        </tbody> | 
				
			||||
 | 
					                    </table> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            <p t-if="o.comment"> | 
				
			||||
 | 
					                <strong>Comment:</strong> | 
				
			||||
 | 
					                <span t-field="o.comment"/> | 
				
			||||
 | 
					            </p> | 
				
			||||
 | 
					            <p t-if="o.payment_term_id"> | 
				
			||||
 | 
					                <span t-field="o.payment_term_id.note"/> | 
				
			||||
 | 
					            </p> | 
				
			||||
 | 
					            <p t-if="o.fiscal_position_id.note"> | 
				
			||||
 | 
					                <strong>Fiscal Position Remark:</strong> | 
				
			||||
 | 
					                <span t-field="o.fiscal_position_id.note"/> | 
				
			||||
 | 
					            </p> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					    </template> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    <template id="report_invoice_new"> | 
				
			||||
 | 
					    <t t-call="report.html_container"> | 
				
			||||
 | 
					        <t t-foreach="docs" t-as="o"> | 
				
			||||
 | 
					            <t t-call="discounts_in_pos.report_invoice_document_new" t-lang="o.partner_id.lang"/> | 
				
			||||
 | 
					        </t> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					    </template> | 
				
			||||
 | 
					</data> | 
				
			||||
 | 
					</openerp> | 
				
			||||
@ -0,0 +1,186 @@ | 
				
			|||||
 | 
					<?xml version="1.0" encoding="iso-8859-1"?> | 
				
			||||
 | 
					<openerp> | 
				
			||||
 | 
					<data> | 
				
			||||
 | 
					    <template id="report_invoice_document"> | 
				
			||||
 | 
					    <t t-call="report.external_layout"> | 
				
			||||
 | 
					        <t t-set="o" t-value="o.with_context({'lang':o.partner_id.lang})" /> | 
				
			||||
 | 
					        <div class="page"> | 
				
			||||
 | 
					            <div class="row"> | 
				
			||||
 | 
					                <div class="col-xs-5 col-xs-offset-7"> | 
				
			||||
 | 
					                    <address t-field="o.partner_id" | 
				
			||||
 | 
					                        t-field-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": true}' /> | 
				
			||||
 | 
					                    <span t-if="o.partner_id.vat">TIN: <span t-field="o.partner_id.vat"/></span> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            <h2> | 
				
			||||
 | 
					                <span t-if="o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')">Invoice</span> | 
				
			||||
 | 
					                <span t-if="o.type == 'out_invoice' and o.state == 'proforma2'">PRO-FORMA</span> | 
				
			||||
 | 
					                <span t-if="o.type == 'out_invoice' and o.state == 'draft'">Draft Invoice</span> | 
				
			||||
 | 
					                <span t-if="o.type == 'out_invoice' and o.state == 'cancel'">Cancelled Invoice</span> | 
				
			||||
 | 
					                <span t-if="o.type == 'out_refund'">Refund</span> | 
				
			||||
 | 
					                <span t-if="o.type == 'in_refund'">Vendor Refund</span> | 
				
			||||
 | 
					                <span t-if="o.type == 'in_invoice'">Vendor Bill</span> | 
				
			||||
 | 
					                <span t-field="o.number"/> | 
				
			||||
 | 
					            </h2> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            <div class="row mt32 mb32"> | 
				
			||||
 | 
					                <div class="col-xs-2" t-if="o.name"> | 
				
			||||
 | 
					                    <strong>Description:</strong> | 
				
			||||
 | 
					                    <p t-field="o.name"/> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div class="col-xs-2" t-if="o.date_invoice"> | 
				
			||||
 | 
					                    <strong>Invoice Date:</strong> | 
				
			||||
 | 
					                    <p t-field="o.date_invoice"/> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div class="col-xs-2" t-if="o.date_due and o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')"> | 
				
			||||
 | 
					                    <strong>Due Date:</strong> | 
				
			||||
 | 
					                    <p t-field="o.date_due"/> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div class="col-xs-2" t-if="o.origin"> | 
				
			||||
 | 
					                    <strong>Source:</strong> | 
				
			||||
 | 
					                    <p t-field="o.origin"/> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div class="col-xs-2" t-if="o.partner_id.ref"> | 
				
			||||
 | 
					                    <strong>Customer Code:</strong> | 
				
			||||
 | 
					                    <p t-field="o.partner_id.ref"/> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					                <div name="reference" class="col-xs-2" t-if="o.reference"> | 
				
			||||
 | 
					                    <strong>Reference:</strong> | 
				
			||||
 | 
					                    <p t-field="o.reference"/> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            <!-- Is there a discount on at least one line? --> | 
				
			||||
 | 
					            <t t-set="display_discount" t-value="any([l.discount_fixed for l in o.invoice_line_ids])"/> | 
				
			||||
 | 
					            <!--<t t-set="display_discount_fixed" t-value="any([l.discount_fixed for l in o.invoice_line_ids])"/>--> | 
				
			||||
 | 
					            <table class="table table-condensed"> | 
				
			||||
 | 
					                <thead> | 
				
			||||
 | 
					                    <tr> | 
				
			||||
 | 
					                        <th>Description</th> | 
				
			||||
 | 
					                        <th class="text-right">Quantity</th> | 
				
			||||
 | 
					                        <th class="text-right">Unit Price</th> | 
				
			||||
 | 
					                        <th class="text-right" groups="sale.group_discount_per_so_line">Disc.(%)</th> | 
				
			||||
 | 
					                        <th class="text-right" groups="sale.group_discount_per_so_line">Disc.Fixed</th> | 
				
			||||
 | 
					                        <th class="text-right">Taxes</th> | 
				
			||||
 | 
					                        <th class="text-right">Price</th> | 
				
			||||
 | 
					                    </tr> | 
				
			||||
 | 
					                </thead> | 
				
			||||
 | 
					                <tbody class="invoice_tbody"> | 
				
			||||
 | 
					                    <tr t-foreach="o.invoice_line_ids" t-as="l"> | 
				
			||||
 | 
					                        <td><span t-field="l.name"/></td> | 
				
			||||
 | 
					                        <td class="text-right"> | 
				
			||||
 | 
					                            <span t-field="l.quantity"/> | 
				
			||||
 | 
					                            <span t-field="l.uom_id"  groups="product.group_uom"/> | 
				
			||||
 | 
					                        </td> | 
				
			||||
 | 
					                        <td class="text-right"> | 
				
			||||
 | 
					                            <span t-field="l.price_unit"/> | 
				
			||||
 | 
					                        </td> | 
				
			||||
 | 
					                        <td class="text-right" groups="sale.group_discount_per_so_line"> | 
				
			||||
 | 
					                            <span t-field="l.discount"/> | 
				
			||||
 | 
					                        </td> | 
				
			||||
 | 
					                        <td class="text-right" groups="sale.group_discount_per_so_line"> | 
				
			||||
 | 
					                            <span t-field="l.discount_fixed"/> | 
				
			||||
 | 
					                        </td> | 
				
			||||
 | 
					                        <td class="text-right"> | 
				
			||||
 | 
					                            <span t-esc="', '.join(map(lambda x: (x.description or x.name), l.invoice_line_tax_ids))"/> | 
				
			||||
 | 
					                        </td> | 
				
			||||
 | 
					                        <td class="text-right"> | 
				
			||||
 | 
					                            <span t-field="l.price_subtotal" | 
				
			||||
 | 
					                                t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/> | 
				
			||||
 | 
					                        </td> | 
				
			||||
 | 
					                    </tr> | 
				
			||||
 | 
					                </tbody> | 
				
			||||
 | 
					            </table> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            <div class="row"> | 
				
			||||
 | 
					                <div class="col-xs-4 pull-right"> | 
				
			||||
 | 
					                    <table class="table table-condensed"> | 
				
			||||
 | 
					                        <tr class="border-black"> | 
				
			||||
 | 
					                            <td><strong>Subtotal</strong></td> | 
				
			||||
 | 
					                            <td class="text-right"> | 
				
			||||
 | 
					                                <span t-field="o.amount_untaxed" t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/> | 
				
			||||
 | 
					                            </td> | 
				
			||||
 | 
					                        </tr> | 
				
			||||
 | 
					                        <tr class="border-black"> | 
				
			||||
 | 
					                            <td><strong>Discount Fixed(Total)</strong></td> | 
				
			||||
 | 
					                            <td class="text-right"> | 
				
			||||
 | 
					                                <span t-field="o.discount_total" t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/> | 
				
			||||
 | 
					                            </td> | 
				
			||||
 | 
					                        </tr> | 
				
			||||
 | 
					                        <tr class="border-black"> | 
				
			||||
 | 
					                            <td><strong>Discount Percent(Total)</strong></td> | 
				
			||||
 | 
					                            <td class="text-right"> | 
				
			||||
 | 
					                                <span t-field="o.discount_percent"/>% | 
				
			||||
 | 
					                            </td> | 
				
			||||
 | 
					                        </tr> | 
				
			||||
 | 
					                        <t t-foreach="o._get_tax_amount_by_group()" t-as="amount_by_group"> | 
				
			||||
 | 
					                            <tr> | 
				
			||||
 | 
					                                <td><span t-esc="amount_by_group[0]"/></td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <span t-esc="amount_by_group[1]"/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                            </tr> | 
				
			||||
 | 
					                        </t> | 
				
			||||
 | 
					                        <tr class="border-black"> | 
				
			||||
 | 
					                            <td><strong>Total</strong></td> | 
				
			||||
 | 
					                            <td class="text-right"> | 
				
			||||
 | 
					                                 <span t-field="o.amount_total" t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/> | 
				
			||||
 | 
					                            </td> | 
				
			||||
 | 
					                        </tr> | 
				
			||||
 | 
					                    </table> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            <div class="row" t-if="o.tax_line_ids"> | 
				
			||||
 | 
					                <div class="col-xs-6"> | 
				
			||||
 | 
					                    <table class="table table-condensed"> | 
				
			||||
 | 
					                        <thead> | 
				
			||||
 | 
					                            <tr> | 
				
			||||
 | 
					                                <th>Tax</th> | 
				
			||||
 | 
					                                <th class="text-right">Base</th> | 
				
			||||
 | 
					                                <th class="text-right">Amount</th> | 
				
			||||
 | 
					                            </tr> | 
				
			||||
 | 
					                        </thead> | 
				
			||||
 | 
					                        <tbody> | 
				
			||||
 | 
					                            <tr t-foreach="o.tax_line_ids" t-as="t"> | 
				
			||||
 | 
					                                <td><span t-field="t.name"/></td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <span t-field="t.base" | 
				
			||||
 | 
					                                        t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <span t-field="t.amount" | 
				
			||||
 | 
					                                        t-field-options='{"widget": "monetary", "display_currency": "o.currency_id"}'/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                            </tr> | 
				
			||||
 | 
					                        </tbody> | 
				
			||||
 | 
					                    </table> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            <p t-if="o.comment"> | 
				
			||||
 | 
					                <strong>Comment:</strong> | 
				
			||||
 | 
					                <span t-field="o.comment"/> | 
				
			||||
 | 
					            </p> | 
				
			||||
 | 
					            <p t-if="o.payment_term_id"> | 
				
			||||
 | 
					                <span t-field="o.payment_term_id.note"/> | 
				
			||||
 | 
					            </p> | 
				
			||||
 | 
					            <p t-if="o.fiscal_position_id.note"> | 
				
			||||
 | 
					                <strong>Fiscal Position Remark:</strong> | 
				
			||||
 | 
					                <span t-field="o.fiscal_position_id.note"/> | 
				
			||||
 | 
					            </p> | 
				
			||||
 | 
					        </div> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					    </template> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    <template id="report_invoice"> | 
				
			||||
 | 
					    <t t-call="report.html_container"> | 
				
			||||
 | 
					        <t t-foreach="docs" t-as="o"> | 
				
			||||
 | 
					            <t t-call="discounts_in_pos.report_invoice_document" t-lang="o.partner_id.lang"/> | 
				
			||||
 | 
					        </t> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					    </template> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					</data> | 
				
			||||
 | 
					</openerp> | 
				
			||||
@ -0,0 +1,89 @@ | 
				
			|||||
 | 
					<?xml version="1.0" encoding="iso-8859-1"?> | 
				
			||||
 | 
					<openerp> | 
				
			||||
 | 
					    <data> | 
				
			||||
 | 
					        <record model="ir.ui.view" id="view_pos_config_form_extended"> | 
				
			||||
 | 
					            <field name="name">pos.config.extend</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="//field[@name='sequence_id']" position="after"> | 
				
			||||
 | 
					                    <field name="discount_account"/> | 
				
			||||
 | 
					                </xpath> | 
				
			||||
 | 
					            </field> | 
				
			||||
 | 
					        </record> | 
				
			||||
 | 
					        <record model="ir.ui.view" id="view_pos_new_form_extended"> | 
				
			||||
 | 
					                <field name="name">pos.order.extend</field> | 
				
			||||
 | 
					                <field name="model">pos.order</field> | 
				
			||||
 | 
					                <field name="inherit_id" ref="point_of_sale.view_pos_pos_form"/> | 
				
			||||
 | 
					                <field name="arch" type="xml"> | 
				
			||||
 | 
					                    <xpath expr="//field[@name='qty']" position="replace"> | 
				
			||||
 | 
					                        <field name="qty"/> | 
				
			||||
 | 
					                    </xpath> | 
				
			||||
 | 
					                    <xpath expr="//field[@name='price_unit']" position="replace"> | 
				
			||||
 | 
					                        <field name="price_unit"/> | 
				
			||||
 | 
					                    </xpath> | 
				
			||||
 | 
					                    <xpath expr="//field[@name='discount']" position="replace"> | 
				
			||||
 | 
					                        <field name="discount" widget="monetary"/> | 
				
			||||
 | 
					                    </xpath> | 
				
			||||
 | 
					                    <xpath expr="//field[@name='discount']" position="after"> | 
				
			||||
 | 
					                        <field name="discount_fixed" widget="monetary"/> | 
				
			||||
 | 
					                    </xpath> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                    <xpath expr="//field[@name='amount_tax']" position="after"> | 
				
			||||
 | 
					                        <field name="discount_total" /> | 
				
			||||
 | 
					                        <field name="discount_percent" /> | 
				
			||||
 | 
					                    </xpath> | 
				
			||||
 | 
					                </field> | 
				
			||||
 | 
					        </record> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        <report | 
				
			||||
 | 
					                id="pos_invoice_report" | 
				
			||||
 | 
					                string="Invoice" | 
				
			||||
 | 
					                model="pos.order" | 
				
			||||
 | 
					                report_type="qweb-pdf" | 
				
			||||
 | 
					                name="discounts_in_pos.report_invoice" | 
				
			||||
 | 
					                file="discounts_in_pos.report_invoice" | 
				
			||||
 | 
					            /> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    <!--in account.invoice --> | 
				
			||||
 | 
					        <report | 
				
			||||
 | 
					            id="account_invoices" | 
				
			||||
 | 
					            model="account.invoice" | 
				
			||||
 | 
					            string="Invoices" | 
				
			||||
 | 
					            report_type="qweb-pdf" | 
				
			||||
 | 
					            name="discounts_in_pos.report_invoice_new" | 
				
			||||
 | 
					            file="discounts_in_pos.report_invoice_new" | 
				
			||||
 | 
					            attachment_use="True" | 
				
			||||
 | 
					            attachment="(object.state in ('open','paid')) and ('INV'+(object.number or '').replace('/','')+'.pdf')" | 
				
			||||
 | 
					            /> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    <report | 
				
			||||
 | 
					            id="pos_payment_report" | 
				
			||||
 | 
					            string="Today's Payment" | 
				
			||||
 | 
					            model="pos.order" | 
				
			||||
 | 
					            report_type="qweb-pdf" | 
				
			||||
 | 
					            name="discounts_in_pos.report_payment" | 
				
			||||
 | 
					            file="discounts_in_pos.report_payment" | 
				
			||||
 | 
					         /> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    <report | 
				
			||||
 | 
					            id="action_report_pos_receipt" | 
				
			||||
 | 
					            string="Receipt" | 
				
			||||
 | 
					            model="pos.order" | 
				
			||||
 | 
					            report_type="qweb-pdf" | 
				
			||||
 | 
					            name="discounts_in_pos.report_receipt" | 
				
			||||
 | 
					            file="discounts_in_pos.report_receipt" | 
				
			||||
 | 
					            paperformat="discounts_in_pos.paperformat_posreceipt" | 
				
			||||
 | 
					        /> | 
				
			||||
 | 
					    <report | 
				
			||||
 | 
					            id="pos_lines_report" | 
				
			||||
 | 
					            string="Sales Lines" | 
				
			||||
 | 
					            model="pos.order" | 
				
			||||
 | 
					            report_type="qweb-pdf" | 
				
			||||
 | 
					            name="discounts_in_pos.report_saleslines" | 
				
			||||
 | 
					            file="discounts_in_pos.report_saleslines" | 
				
			||||
 | 
					            auto="False" | 
				
			||||
 | 
					         /> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    </data> | 
				
			||||
 | 
					</openerp> | 
				
			||||
@ -0,0 +1,20 @@ | 
				
			|||||
 | 
					<?xml version="1.0" encoding="utf-8"?> | 
				
			||||
 | 
					<openerp> | 
				
			||||
 | 
					    <data> | 
				
			||||
 | 
					        <record id="paperformat_posreceipt" model="report.paperformat"> | 
				
			||||
 | 
					            <field name="name">Point Of Sale Receipt</field> | 
				
			||||
 | 
					            <field name="default" eval="True"/> | 
				
			||||
 | 
					            <field name="format">custom</field> | 
				
			||||
 | 
					            <field name="page_height">150</field> | 
				
			||||
 | 
					            <field name="page_width">90</field> | 
				
			||||
 | 
					            <field name="orientation">Portrait</field> | 
				
			||||
 | 
					            <field name="margin_top">3</field> | 
				
			||||
 | 
					            <field name="margin_bottom">3</field> | 
				
			||||
 | 
					            <field name="margin_left">3</field> | 
				
			||||
 | 
					            <field name="margin_right">3</field> | 
				
			||||
 | 
					            <field name="header_line" eval="False" /> | 
				
			||||
 | 
					            <field name="header_spacing">3</field> | 
				
			||||
 | 
					            <field name="dpi">130</field> | 
				
			||||
 | 
					        </record> | 
				
			||||
 | 
					    </data> | 
				
			||||
 | 
					</openerp> | 
				
			||||
@ -0,0 +1,113 @@ | 
				
			|||||
 | 
					<?xml version="1.0" encoding="utf-8"?> | 
				
			||||
 | 
					<openerp> | 
				
			||||
 | 
					<data> | 
				
			||||
 | 
					<template id="report_payment"> | 
				
			||||
 | 
					    <t t-call="report.html_container"> | 
				
			||||
 | 
					        <t t-foreach="docs" t-as="o"> | 
				
			||||
 | 
					            <t t-call="report.internal_layout"> | 
				
			||||
 | 
					                <div class="page"> | 
				
			||||
 | 
					                    <h2>Today's Payments</h2> | 
				
			||||
 | 
					                    <div class="row mt32 mb32"> | 
				
			||||
 | 
					                        <div class="col-xs-3"> | 
				
			||||
 | 
					                            <strong>Company</strong>: | 
				
			||||
 | 
					                            <br/> | 
				
			||||
 | 
					                            <span t-field="res_company.name"/> | 
				
			||||
 | 
					                        </div> | 
				
			||||
 | 
					                        <div class="col-xs-3"> | 
				
			||||
 | 
					                            <strong>Print date</strong>: | 
				
			||||
 | 
					                            <br/> | 
				
			||||
 | 
					                            <t t-esc="formatLang(time.strftime('%Y-%m-%d'), date='True')"/> | 
				
			||||
 | 
					                        </div> | 
				
			||||
 | 
					                    </div> | 
				
			||||
 | 
					                    <t t-set="pos_payment" t-value="pos_payment(o)"/> | 
				
			||||
 | 
					                    <table class="table table-condensed" t-if="pos_payment"> | 
				
			||||
 | 
					                        <thead> | 
				
			||||
 | 
					                            <tr> | 
				
			||||
 | 
					                                <td> | 
				
			||||
 | 
					                                    <strong>Product</strong> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-center"> | 
				
			||||
 | 
					                                    <strong>Qty</strong> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-center"> | 
				
			||||
 | 
					                                    <strong>Disc.(%)</strong> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-center"> | 
				
			||||
 | 
					                                    <strong>Disc.Fixed</strong> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <strong>Unit Price</strong> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <strong>Total</strong> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                            </tr> | 
				
			||||
 | 
					                        </thead> | 
				
			||||
 | 
					                        <tbody> | 
				
			||||
 | 
					                            <tr t-foreach="pos_payment" t-as="line_ids"> | 
				
			||||
 | 
					                                <td> | 
				
			||||
 | 
					                                    <t t-if="line_ids['code']"> | 
				
			||||
 | 
					                                        <span t-esc="line_ids['code']"/> | 
				
			||||
 | 
					                                    </t> | 
				
			||||
 | 
					                                    <t t-if="line_ids['name']"> | 
				
			||||
 | 
					                                        <span t-esc="line_ids['name']"/> | 
				
			||||
 | 
					                                    </t> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <span t-esc="formatLang(line_ids['qty'])"/> | 
				
			||||
 | 
					                                    <t t-if="line_ids['uom']"> | 
				
			||||
 | 
					                                        <span t-esc="line_ids['uom']"/> | 
				
			||||
 | 
					                                    </t> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <span t-esc="formatLang(line_ids['discount'])"/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <span t-esc="formatLang(line_ids['discount_fixed'], currency_obj=res_company.currency_id)"/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <span t-esc="formatLang(line_ids['price_unit'])"/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <span t-esc="formatLang(line_ids['total'], currency_obj=res_company.currency_id)"/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                            </tr> | 
				
			||||
 | 
					                        </tbody> | 
				
			||||
 | 
					                    </table> | 
				
			||||
 | 
					                    <div class="row" t-if="pos_payment_total(o)"> | 
				
			||||
 | 
					                        <div class="col-xs-4 pull-right"> | 
				
			||||
 | 
					                            <table class="table table-condensed"> | 
				
			||||
 | 
					                                <tr class="border-black"> | 
				
			||||
 | 
					                                    <td> | 
				
			||||
 | 
					                                        <strong>Discount Fixed(Total)</strong> | 
				
			||||
 | 
					                                    </td> | 
				
			||||
 | 
					                                    <td class="text-right"> | 
				
			||||
 | 
					                                        <span t-esc="formatLang(pos_fixed_discount(o), currency_obj=res_company.currency_id)"/> | 
				
			||||
 | 
					                                    </td> | 
				
			||||
 | 
					                                </tr> | 
				
			||||
 | 
					                                <tr class="border-black"> | 
				
			||||
 | 
					                                    <td> | 
				
			||||
 | 
					                                        <strong>Discount Percent(Total)</strong> | 
				
			||||
 | 
					                                    </td> | 
				
			||||
 | 
					                                    <td class="text-right"> | 
				
			||||
 | 
					                                        <span t-esc="pos_percent_discount(o)"/> % | 
				
			||||
 | 
					                                    </td> | 
				
			||||
 | 
					                                </tr> | 
				
			||||
 | 
					                                <tr class="border-black"> | 
				
			||||
 | 
					                                    <td> | 
				
			||||
 | 
					                                        <strong>Net Total</strong> | 
				
			||||
 | 
					                                    </td> | 
				
			||||
 | 
					                                    <td class="text-right"> | 
				
			||||
 | 
					                                        <span t-esc="formatLang(pos_payment_total(o), currency_obj=res_company.currency_id)"/> | 
				
			||||
 | 
					                                    </td> | 
				
			||||
 | 
					                                </tr> | 
				
			||||
 | 
					                            </table> | 
				
			||||
 | 
					                        </div> | 
				
			||||
 | 
					                    </div> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </t> | 
				
			||||
 | 
					        </t> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					</template> | 
				
			||||
 | 
					</data> | 
				
			||||
 | 
					</openerp> | 
				
			||||
@ -0,0 +1,112 @@ | 
				
			|||||
 | 
					<?xml version="1.0" encoding="utf-8"?> | 
				
			||||
 | 
					<openerp> | 
				
			||||
 | 
					<data> | 
				
			||||
 | 
					<template id="report_receipt"> | 
				
			||||
 | 
					    <t t-call="report.html_container"> | 
				
			||||
 | 
					        <t t-foreach="docs" t-as="o"> | 
				
			||||
 | 
					            <div class="page"> | 
				
			||||
 | 
					                <div class="row"> | 
				
			||||
 | 
					                    <div class="col-xs-12 text-center"> | 
				
			||||
 | 
					                        <h2 t-esc="o.user_id.company_id.name"/> | 
				
			||||
 | 
					                        <div t-field="o.partner_id" | 
				
			||||
 | 
					                            t-field-options='{"widget": "contact", "fields": ["address", "name", "phone", "fax"], "no_marker": true, "phone_icons": true}'/> | 
				
			||||
 | 
					                        User: <span t-field="o.user_id"/><br/> | 
				
			||||
 | 
					                        Date: <span t-field="o.date_order"/><br/> | 
				
			||||
 | 
					                    </div> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                <div class="row"> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                <table class="table table-condensed"> | 
				
			||||
 | 
					                    <thead> | 
				
			||||
 | 
					                        <tr> | 
				
			||||
 | 
					                            <th>Description</th> | 
				
			||||
 | 
					                            <th class="text-right">Quantity</th> | 
				
			||||
 | 
					                            <th class="text-right">Price</th> | 
				
			||||
 | 
					                            <th class="text-right">Discount</th> | 
				
			||||
 | 
					                        </tr> | 
				
			||||
 | 
					                    </thead> | 
				
			||||
 | 
					                    <tbody> | 
				
			||||
 | 
					                        <tr t-foreach="o.lines" t-as="line"> | 
				
			||||
 | 
					                            <td><span t-field="line.product_id"/></td> | 
				
			||||
 | 
					                            <td class="text-right"> | 
				
			||||
 | 
					                                <t t-if="o.state != 'cancel' and o.statement_ids"> | 
				
			||||
 | 
					                                    <span t-field="line.qty"/> | 
				
			||||
 | 
					                                </t> | 
				
			||||
 | 
					                            </td> | 
				
			||||
 | 
					                            <td class="text-right"> | 
				
			||||
 | 
					                                <t t-if="o.state != 'cancel' and o.statement_ids"> | 
				
			||||
 | 
					                                    <span t-esc="formatLang(net(line.id), currency_obj=res_company.currency_id)"/> | 
				
			||||
 | 
					                                </t> | 
				
			||||
 | 
					                            </td> | 
				
			||||
 | 
					                            <td> | 
				
			||||
 | 
					                                <t t-if="line.discount != 0.0"> | 
				
			||||
 | 
					                                    <span t-esc="line.discount"/>% | 
				
			||||
 | 
					                                </t> | 
				
			||||
 | 
					                                <t t-if="line.discount_fixed != 0.0"> | 
				
			||||
 | 
					                                    <span t-esc="formatLang(line.discount_fixed, currency_obj=res_company.currency_id)"/> | 
				
			||||
 | 
					                                </t> | 
				
			||||
 | 
					                                <t t-if="line.discount == 0.0 and line.discount_fixed == 0.0"> | 
				
			||||
 | 
					                                    0 | 
				
			||||
 | 
					                                </t> | 
				
			||||
 | 
					                            </td> | 
				
			||||
 | 
					                        </tr> | 
				
			||||
 | 
					                    </tbody> | 
				
			||||
 | 
					                </table> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                <div class="row"> | 
				
			||||
 | 
					                    <div class="col-xs-6 pull-right"> | 
				
			||||
 | 
					                        <table class="table table-condensed"> | 
				
			||||
 | 
					                            <tr class="border-black"> | 
				
			||||
 | 
					                                <td><strong>Taxes</strong></td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <strong t-esc="formatLang(o.amount_tax, currency_obj=res_company.currency_id)"/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                            </tr> | 
				
			||||
 | 
					                            <tr class="border-black"> | 
				
			||||
 | 
					                                <td><strong>Discount Fixed(Total)</strong></td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <strong t-esc="formatLang(o.discount_total, currency_obj=res_company.currency_id)"/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                            </tr> | 
				
			||||
 | 
					                            <tr class="border-black"> | 
				
			||||
 | 
					                                <td><strong>Discount Percent(Total)</strong></td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <strong t-esc="o.discount_percent"/> % | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                            </tr> | 
				
			||||
 | 
					                            <tr> | 
				
			||||
 | 
					                                <td><strong>Total</strong></td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <strong t-esc="formatLang(o.amount_total, currency_obj=res_company.currency_id)"/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                            </tr> | 
				
			||||
 | 
					                        </table> | 
				
			||||
 | 
					                    </div> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                <table class="table table-condensed"> | 
				
			||||
 | 
					                    <thead> | 
				
			||||
 | 
					                        <tr> | 
				
			||||
 | 
					                            <th>Payment Mode</th> | 
				
			||||
 | 
					                            <th>Amount</th> | 
				
			||||
 | 
					                        </tr> | 
				
			||||
 | 
					                    </thead> | 
				
			||||
 | 
					                    <tbody> | 
				
			||||
 | 
					                        <tr t-foreach="get_journal_amt(o)" t-as="d"> | 
				
			||||
 | 
					                            <td> | 
				
			||||
 | 
					                                <span t-esc="d['name']"/> | 
				
			||||
 | 
					                            </td> | 
				
			||||
 | 
					                            <td> | 
				
			||||
 | 
					                                <span t-esc="formatLang(d['amt'], currency_obj=res_company.currency_id)"/> | 
				
			||||
 | 
					                            </td> | 
				
			||||
 | 
					                        </tr> | 
				
			||||
 | 
					                    </tbody> | 
				
			||||
 | 
					                </table> | 
				
			||||
 | 
					            </div> | 
				
			||||
 | 
					        </t> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					</template> | 
				
			||||
 | 
					</data> | 
				
			||||
 | 
					</openerp> | 
				
			||||
@ -0,0 +1,125 @@ | 
				
			|||||
 | 
					<?xml version="1.0" encoding="utf-8"?> | 
				
			||||
 | 
					<openerp> | 
				
			||||
 | 
					<data> | 
				
			||||
 | 
					<template id="report_saleslines"> | 
				
			||||
 | 
					    <t t-call="report.html_container"> | 
				
			||||
 | 
					        <t t-foreach="docs" t-as="o"> | 
				
			||||
 | 
					            <t t-call="report.internal_layout"> | 
				
			||||
 | 
					                <div class="page"> | 
				
			||||
 | 
					                    <h2>POS Lines</h2> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                    <div class="row mt32 mb32"> | 
				
			||||
 | 
					                        <div class="col-xs-3"> | 
				
			||||
 | 
					                            <strong>Company</strong>:<br/> | 
				
			||||
 | 
					                            <span t-field="res_company.name"/> | 
				
			||||
 | 
					                        </div> | 
				
			||||
 | 
					                        <div class="col-xs-3"> | 
				
			||||
 | 
					                            <strong>Print date</strong>:<br/> | 
				
			||||
 | 
					                            <t t-esc="formatLang(time.strftime('%Y-%m-%d'), date=True)"/> | 
				
			||||
 | 
					                        </div> | 
				
			||||
 | 
					                        <div class="col-xs-3"> | 
				
			||||
 | 
					                            <strong>No. Of Articles</strong>:<br/> | 
				
			||||
 | 
					                            <t t-esc="total_quantity(o)"/> | 
				
			||||
 | 
					                        </div> | 
				
			||||
 | 
					                    </div> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                    <table class="table table-condensed"> | 
				
			||||
 | 
					                        <thead> | 
				
			||||
 | 
					                            <tr> | 
				
			||||
 | 
					                                <th><strong>Description</strong></th> | 
				
			||||
 | 
					                                <th><strong>Tax</strong></th> | 
				
			||||
 | 
					                                <th class="text-right"><strong>Quantity</strong></th> | 
				
			||||
 | 
					                                <th class="text-right"><strong>Unit Price</strong></th> | 
				
			||||
 | 
					                                <th class="text-right" groups="sale.group_discount_per_so_line"><strong>Disc. (%)</strong></th> | 
				
			||||
 | 
					                                <th class="text-right" groups="sale.group_discount_per_so_line"><strong>Disc.Fixed</strong></th> | 
				
			||||
 | 
					                                <th class="text-right"><strong>Price</strong></th> | 
				
			||||
 | 
					                            </tr> | 
				
			||||
 | 
					                        </thead> | 
				
			||||
 | 
					                        <tbody> | 
				
			||||
 | 
					                            <tr t-foreach="o.lines" t-as="l"> | 
				
			||||
 | 
					                                <td> | 
				
			||||
 | 
					                                    <t t-if="l.product_id and l.product_id.code"> | 
				
			||||
 | 
					                                        [<span t-field="l.product_id.code"/>] | 
				
			||||
 | 
					                                    </t> | 
				
			||||
 | 
					                                    <span t-field="l.product_id.name"/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td> | 
				
			||||
 | 
					                                    <t t-esc="taxes(l)"/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <span t-field="l.qty"/> | 
				
			||||
 | 
					                                    <span t-field="l.product_id.uom_id.name" groups="product.group_uom"/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <span t-field="l.price_unit"/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-right" groups="sale.group_discount_per_so_line"> | 
				
			||||
 | 
					                                    <span t-field="l.discount"/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-right" groups="sale.group_discount_per_so_line"> | 
				
			||||
 | 
					                                    <span t-field="l.discount_fixed" t-field-options='{"widget": "monetary", "display_currency": "o.pricelist_id.currency_id"}'/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                                <td class="text-right"> | 
				
			||||
 | 
					                                    <span t-field="l.price_subtotal" t-field-options='{"widget": "monetary", "display_currency": "o.pricelist_id.currency_id"}'/> | 
				
			||||
 | 
					                                </td> | 
				
			||||
 | 
					                           </tr> | 
				
			||||
 | 
					                        </tbody> | 
				
			||||
 | 
					                    </table> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					                    <div class="row"> | 
				
			||||
 | 
					                        <div class="col-xs-4 pull-right"> | 
				
			||||
 | 
					                            <table class="table table-condensed"> | 
				
			||||
 | 
					                                <tr class="border-black"> | 
				
			||||
 | 
					                                    <td><strong>Total Without Taxes</strong></td> | 
				
			||||
 | 
					                                    <td class="text-right"> | 
				
			||||
 | 
					                                        <t t-if="o.discount_percent > 0"> | 
				
			||||
 | 
					                                            <span t-esc="(o.amount_total - o.amount_tax)*100/(100 - o.discount_percent)" | 
				
			||||
 | 
					                                            t-esc-options='{"widget": "monetary", "display_currency": "o.pricelist_id.currency_id"}'/> | 
				
			||||
 | 
					                                        </t> | 
				
			||||
 | 
					                                        <t t-if="o.discount_total > 0"> | 
				
			||||
 | 
					                                            <span t-esc="(o.amount_total - o.amount_tax) + o.discount_total" | 
				
			||||
 | 
					                                            t-esc-options='{"widget": "monetary", "display_currency": "o.pricelist_id.currency_id"}'/> | 
				
			||||
 | 
					                                        </t> | 
				
			||||
 | 
					                                        <t t-if="o.discount_total == 0 and o.discount_percent == 0"> | 
				
			||||
 | 
					                                            <span t-esc="(o.amount_total - o.amount_tax)" | 
				
			||||
 | 
					                                            t-esc-options='{"widget": "monetary", "display_currency": "o.pricelist_id.currency_id"}'/> | 
				
			||||
 | 
					                                        </t> | 
				
			||||
 | 
					                                    </td> | 
				
			||||
 | 
					                                </tr> | 
				
			||||
 | 
					                                <tr> | 
				
			||||
 | 
					                                    <td>Taxes</td> | 
				
			||||
 | 
					                                    <td class="text-right"> | 
				
			||||
 | 
					                                        <span t-field="o.amount_tax" | 
				
			||||
 | 
					                                            t-field-options='{"widget": "monetary", "display_currency": "o.pricelist_id.currency_id"}'/> | 
				
			||||
 | 
					                                    </td> | 
				
			||||
 | 
					                                </tr> | 
				
			||||
 | 
					                                <tr groups="sale.group_discount_per_so_line"> | 
				
			||||
 | 
					                                    <td>Discount Fixed(Total)</td> | 
				
			||||
 | 
					                                    <td class="text-right"> | 
				
			||||
 | 
					                                        <span t-field="o.discount_total" | 
				
			||||
 | 
					                                            t-field-options='{"widget": "monetary", "display_currency": "o.pricelist_id.currency_id"}'/> | 
				
			||||
 | 
					                                    </td> | 
				
			||||
 | 
					                                </tr> | 
				
			||||
 | 
					                                <tr groups="sale.group_discount_per_so_line"> | 
				
			||||
 | 
					                                    <td>Discount Percent(Total)</td> | 
				
			||||
 | 
					                                    <td class="text-right"> | 
				
			||||
 | 
					                                        <span t-field="o.discount_percent"/> % | 
				
			||||
 | 
					                                    </td> | 
				
			||||
 | 
					                                </tr> | 
				
			||||
 | 
					                                <tr class="border-black"> | 
				
			||||
 | 
					                                    <td><strong>Total</strong></td> | 
				
			||||
 | 
					                                    <td class="text-right"> | 
				
			||||
 | 
					                                        <span t-field="o.amount_total" | 
				
			||||
 | 
					                                            t-field-options='{"widget": "monetary", "display_currency": "o.pricelist_id.currency_id"}'/> | 
				
			||||
 | 
					                                    </td> | 
				
			||||
 | 
					                                </tr> | 
				
			||||
 | 
					                            </table> | 
				
			||||
 | 
					                        </div> | 
				
			||||
 | 
					                    </div> | 
				
			||||
 | 
					                </div> | 
				
			||||
 | 
					            </t> | 
				
			||||
 | 
					        </t> | 
				
			||||
 | 
					    </t> | 
				
			||||
 | 
					</template> | 
				
			||||
 | 
					</data> | 
				
			||||
 | 
					</openerp> | 
				
			||||
@ -0,0 +1,12 @@ | 
				
			|||||
 | 
					<?xml version="1.0" encoding="utf-8"?> | 
				
			||||
 | 
					<openerp> | 
				
			||||
 | 
					    <data> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        <template id="assets_frontend" inherit_id="web.assets_common"> | 
				
			||||
 | 
					          <xpath expr="." position="inside"> | 
				
			||||
 | 
					              <script type="text/javascript" src="/discounts_in_pos/static/src/js/discount.js"></script> | 
				
			||||
 | 
					          </xpath> | 
				
			||||
 | 
					        </template> | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    </data> | 
				
			||||
 | 
					</openerp> | 
				
			||||