From b252da57c201533643921676aa5bcc9450853088 Mon Sep 17 00:00:00 2001 From: AjmalCybro Date: Wed, 11 Sep 2024 14:58:08 +0530 Subject: [PATCH] Sep 11 [UPDT] Updated 'product_multi_uom_pos' --- product_multi_uom_pos/doc/RELEASE_NOTES.md | 8 +- product_multi_uom_pos/models/__init__.py | 1 + .../models/report_sale_details.py | 139 ++++++++++++++++++ 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 product_multi_uom_pos/models/report_sale_details.py diff --git a/product_multi_uom_pos/doc/RELEASE_NOTES.md b/product_multi_uom_pos/doc/RELEASE_NOTES.md index 861bdcf2e..1635492f3 100644 --- a/product_multi_uom_pos/doc/RELEASE_NOTES.md +++ b/product_multi_uom_pos/doc/RELEASE_NOTES.md @@ -8,4 +8,10 @@ #### 20.02.2024 #### Version 16.0.1.0.0 #### FIX -- Fixed UOM saving issue when POS tables switched. \ No newline at end of file +- Fixed UOM saving issue when POS tables switched. + + +#### 11.09.2024 +#### Version 16.0.1.0.0 +#### FIX +- Added UOM in Sales details report. \ No newline at end of file diff --git a/product_multi_uom_pos/models/__init__.py b/product_multi_uom_pos/models/__init__.py index 3ec6537aa..98c403833 100644 --- a/product_multi_uom_pos/models/__init__.py +++ b/product_multi_uom_pos/models/__init__.py @@ -24,5 +24,6 @@ from . import product_template from . import pos_order_line from . import stock_picking from . import pos_config +from . import report_sale_details from . import res_config_settings from . import pos_multi_uom diff --git a/product_multi_uom_pos/models/report_sale_details.py b/product_multi_uom_pos/models/report_sale_details.py new file mode 100644 index 000000000..0981a917d --- /dev/null +++ b/product_multi_uom_pos/models/report_sale_details.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- +############################################################################# +# +# Cybrosys Technologies Pvt. Ltd. +# +# Copyright (C) 2024-TODAY Cybrosys Technologies() +# Author: Gayathri V (Contact : odoo@cybrosys.com) +# +# You can modify it under the terms of the GNU AFFERO +# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. +# +# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE +# (AGPL v3) along with this program. +# If not, see . +# +############################################################################# +from datetime import timedelta + +import pytz + +from odoo import api, fields, models, _ +from odoo.osv.expression import AND + +class ReportSaleDetails(models.AbstractModel): + + _inherit = 'report.point_of_sale.report_saledetails' + + + @api.model + def get_sale_details(self, date_start=False, date_stop=False, config_ids=False, session_ids=False): + """ Serialise the orders of the requested time period, configs and sessions. + + :param date_start: The dateTime to start, default today 00:00:00. + :type date_start: str. + :param date_stop: The dateTime to stop, default date_start + 23:59:59. + :type date_stop: str. + :param config_ids: Pos Config id's to include. + :type config_ids: list of numbers. + :param session_ids: Pos Config id's to include. + :type session_ids: list of numbers. + + :returns: dict -- Serialised sales. + """ + domain = [('state', 'in', ['paid','invoiced','done'])] + if (session_ids): + domain = AND([domain, [('session_id', 'in', session_ids)]]) + else: + if date_start: + date_start = fields.Datetime.from_string(date_start) + else: + # start by default today 00:00:00 + user_tz = pytz.timezone(self.env.context.get('tz') or self.env.user.tz or 'UTC') + today = user_tz.localize(fields.Datetime.from_string(fields.Date.context_today(self))) + date_start = today.astimezone(pytz.timezone('UTC')) + + if date_stop: + date_stop = fields.Datetime.from_string(date_stop) + # avoid a date_stop smaller than date_start + if (date_stop < date_start): + date_stop = date_start + timedelta(days=1, seconds=-1) + else: + # stop by default today 23:59:59 + date_stop = date_start + timedelta(days=1, seconds=-1) + + domain = AND([domain, + [('date_order', '>=', fields.Datetime.to_string(date_start)), + ('date_order', '<=', fields.Datetime.to_string(date_stop))] + ]) + + if config_ids: + domain = AND([domain, [('config_id', 'in', config_ids)]]) + + orders = self.env['pos.order'].search(domain) + + user_currency = self.env.company.currency_id + + total = 0.0 + products_sold = {} + taxes = {} + for order in orders: + if user_currency != order.pricelist_id.currency_id: + total += order.pricelist_id.currency_id._convert( + order.amount_total, user_currency, order.company_id, order.date_order or fields.Date.today()) + else: + total += order.amount_total + currency = order.session_id.currency_id + + for line in order.lines: + key = (line.product_id, line.price_unit, line.discount,line.product_uom_id.name) + products_sold.setdefault(key, 0.0) + products_sold[key] += line.qty + print(line.product_uom_id.name, 'SDDDDDDDDDDDDDDDDD') + if line.tax_ids_after_fiscal_position: + line_taxes = line.tax_ids_after_fiscal_position.sudo().compute_all(line.price_unit * (1-(line.discount or 0.0)/100.0), currency, line.qty, product=line.product_id, partner=line.order_id.partner_id or False) + for tax in line_taxes['taxes']: + taxes.setdefault(tax['id'], {'name': tax['name'], 'tax_amount':0.0, 'base_amount':0.0}) + taxes[tax['id']]['tax_amount'] += tax['amount'] + taxes[tax['id']]['base_amount'] += tax['base'] + else: + taxes.setdefault(0, {'name': _('No Taxes'), 'tax_amount':0.0, 'base_amount':0.0}) + taxes[0]['base_amount'] += line.price_subtotal_incl + + payment_ids = self.env["pos.payment"].search([('pos_order_id', 'in', orders.ids)]).ids + if payment_ids: + self.env.cr.execute(""" + SELECT COALESCE(method.name->>%s, method.name->>'en_US') as name, sum(amount) total + FROM pos_payment AS payment, + pos_payment_method AS method + WHERE payment.payment_method_id = method.id + AND payment.id IN %s + GROUP BY method.name + """, (self.env.lang, tuple(payment_ids),)) + payments = self.env.cr.dictfetchall() + else: + payments = [] + + return { + 'date_start': date_start, + 'date_stop': date_stop, + 'currency_precision': user_currency.decimal_places, + 'total_paid': user_currency.round(total), + 'payments': payments, + 'company_name': self.env.company.name, + 'taxes': list(taxes.values()), + 'products': sorted([{ + 'product_id': product.id, + 'product_name': product.name, + 'code': product.default_code, + 'quantity': qty, + 'price_unit': price_unit, + 'discount': discount, + 'uom': product_uom_id, + } for (product, price_unit, discount,product_uom_id), qty in products_sold.items()], key=lambda l: l['product_name']) + }