3 changed files with 147 additions and 1 deletions
@ -0,0 +1,139 @@ |
|||
# -*- coding: utf-8 -*- |
|||
############################################################################# |
|||
# |
|||
# Cybrosys Technologies Pvt. Ltd. |
|||
# |
|||
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
|||
# 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 <http://www.gnu.org/licenses/>. |
|||
# |
|||
############################################################################# |
|||
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']) |
|||
} |
Loading…
Reference in new issue