You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

264 lines
13 KiB

# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Afra MP (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/>.
#
###############################################################################
import pytz
from twilio.rest import Client
from odoo import api, fields, models
class PosOrder(models.Model):
"""Inherited the pos_order class to add filed and function to calculate pos
order details in the dashboard menu"""
_inherit = 'pos.order'
exchange = fields.Boolean(string='Exchange',
help='Enable if the order contain is exchange '
'product')
sale_barcode = fields.Char(string='Barcode',
help='Barcode associated with the pos order.')
def get_pos_exchange_order(self):
"""Mark order a exchanged"""
self.exchange = True
return
@api.model
def get_department(self, option):
"""Function to filter the POs sales report chart"""
company_id = self.env.company.id
if option == 'pos_hourly_sales':
query = '''select EXTRACT(hour FROM date_order at time zone 'utc' at time zone '{}')
as date_month,sum(amount_total) from pos_order where
EXTRACT(month FROM date_order::date) = EXTRACT(month FROM CURRENT_DATE)
AND pos_order.company_id = ''' + str(
company_id) + ''' group by date_month '''
query = query.format(
self.env.user.tz if self.env.user.tz else pytz.UTC)
label = 'HOURS'
elif option == 'pos_monthly_sales':
query = '''select date_order::date as date_month,sum(amount_total) from pos_order where
EXTRACT(month FROM date_order::date) = EXTRACT(month FROM CURRENT_DATE) AND pos_order.company_id = ''' + str(
company_id) + ''' group by date_month '''
label = 'DAYS'
else:
query = '''select TO_CHAR(date_order,'MON')date_month,sum(amount_total) from pos_order where
EXTRACT(year FROM date_order::date) = EXTRACT(year FROM CURRENT_DATE) AND pos_order.company_id = ''' + str(
company_id) + ''' group by date_month'''
label = 'MONTHS'
self._cr.execute(query)
docs = self._cr.dictfetchall()
order = []
today = []
for record in docs:
order.append(record.get('sum'))
today.append(record.get('date_month'))
return [order, today, label]
@api.model
def get_details(self):
"""Function to get payment details,session details and sales person
details"""
company_id = self.env.company
self._cr.execute('''select pos_payment_method.name ->>'en_US',sum(amount)
from pos_payment inner join pos_payment_method on
pos_payment_method.id=pos_payment.payment_method_id
where pos_payment.company_id = ''' + str(company_id.id) + " " + '''
group by pos_payment_method.name ORDER
BY sum(amount) DESC; ''')
payment_details = self._cr.fetchall()
self._cr.execute('''select hr_employee.name,sum(pos_order.amount_paid)
as total,count(pos_order.amount_paid) as orders from
pos_order inner join hr_employee on pos_order.user_id =
hr_employee.user_id where pos_order.company_id =''' + str(
company_id.id) + " " + '''GROUP BY hr_employee.name order by total DESC;''')
salesperson = self._cr.fetchall()
payments = []
for rec in payment_details:
rec = list(rec)
if company_id.currency_id.position == 'after':
rec[1] = "%s %s" % (rec[1], company_id.currency_id.symbol)
else:
rec[1] = "%s %s" % (company_id.currency_id.symbol, rec[1])
payments.append(tuple(rec))
total_sales = []
for rec in salesperson:
rec = list(rec)
if company_id.currency_id.position == 'after':
rec[1] = "%s %s" % (rec[1], company_id.currency_id.symbol)
else:
rec[1] = "%s %s" % (company_id.currency_id.symbol, rec[1])
total_sales.append(tuple(rec))
sessions_list = []
session = {'opened': 'Opened', 'opening_control': "Opening Control"}
for session_id in self.env['pos.config'].search([]):
if session.get(session_id.pos_session_state) is None:
sessions_list.append({'session': session_id.name,
'status': 'Closed'})
else:
sessions_list.append({'session': session_id.name,
'status': session.get(
session_id.pos_session_state)})
return {'payment_details': payments, 'salesperson': total_sales,
'selling_product': sessions_list}
@api.model
def get_refund_details(self):
"""Function to get total count of orders,session and refund orders"""
total = sum(self.env['pos.order'].search([]).mapped('amount_total'))
today_refund_total = 0
today_sale = 0
for pos_order_id in self.env['pos.order'].search([]):
if pos_order_id.date_order.date() == fields.date.today():
today_sale = today_sale + 1
if pos_order_id.amount_total < 0.0:
today_refund_total = today_refund_total + 1
magnitude = 0
while abs(total) >= 1000:
magnitude += 1
total /= 1000.0
# add more suffixes if you need them
val = '%.2f%s' % (total, ['', 'K', 'M', 'G', 'T', 'P'][magnitude])
return {
'total_sale': val,
'total_order_count': self.env['pos.order'].search_count([]),
'total_refund_count': self.env['pos.order'].search_count(
[('amount_total', '<', 0.0)]),
'total_session': self.env['pos.session'].search_count([]),
'today_refund_total': today_refund_total,
'today_sale': today_sale,
}
@api.model
def get_the_top_customer(self):
"""Function to get top 10 customer in pos"""
self._cr.execute('''select res_partner.name as customer,pos_order.partner_id,sum(pos_order.amount_paid) as amount_total from pos_order
inner join res_partner on res_partner.id = pos_order.partner_id where pos_order.company_id = ''' + str(
self.env.company.id) + ''' GROUP BY pos_order.partner_id,
res_partner.name ORDER BY amount_total DESC LIMIT 10;''')
top_customer = self._cr.dictfetchall()
order = []
day = []
for record in top_customer:
order.append(record.get('amount_total'))
day.append(record.get('customer'))
return [order, day]
@api.model
def get_the_top_products(self):
"""Function to get top 10 product in """
self._cr.execute('''select DISTINCT(product_template.name)->>'en_US' as product_name,sum(qty) as total_quantity from
pos_order_line inner join product_product on product_product.id=pos_order_line.product_id inner join
product_template on product_product.product_tmpl_id = product_template.id where pos_order_line.company_id = ''' + str(
self.env.company.id) + ''' group by product_template.id ORDER
BY total_quantity DESC Limit 10 ''')
top_product = self._cr.dictfetchall()
total_quantity = []
product_name = []
for record in top_product:
total_quantity.append(record.get('total_quantity'))
product_name.append(record.get('product_name'))
return [total_quantity, product_name]
@api.model
def get_the_top_categories(self):
"""Function to get top categories in pos"""
query = '''select DISTINCT(product_category.complete_name) as product_category,sum(qty) as total_quantity
from pos_order_line inner join product_product on product_product.id=pos_order_line.product_id inner join
product_template on product_product.product_tmpl_id = product_template.id inner join product_category on
product_category.id =product_template.categ_id where pos_order_line.company_id = ''' + str(
self.env.company.id) + ''' group by product_category ORDER BY total_quantity DESC '''
self._cr.execute(query)
top_categories = self._cr.dictfetchall()
total_quantity = []
product_categ = []
for record in top_categories:
total_quantity.append(record.get('total_quantity'))
product_categ.append(record.get('product_category'))
return [total_quantity, product_categ]
@api.model
def get_invoice(self, id):
"""Retrieve invoice information based on a POS reference ID.
This method searches for a POS record with the specified reference ID. It
then retrieves the associated invoice based on the name matching the
reference. The invoice details, including ID, name, base URL, and account
barcode, are returned as a dictionary.
:param id: The POS reference ID to search for.
:return: A dictionary containing the invoice details.
:rtype: dict"""
invoice_id = self.env['account.move'].search(
[('ref', '=', self.search([('pos_reference', '=', id)]).name)])
return {'invoice_id': invoice_id.id, 'invoice_name': invoice_id.name,
'base_url': self.env['ir.config_parameter'].get_param(
'web.base.url'), 'barcode': invoice_id.account_barcode}
@api.model
def create_from_ui(self, orders, draft=False):
"""Create POS orders from the user interface.
This method is called to create POS orders based on the provided
data from the user interface.
:param orders: A list of dictionaries representing the POS orders.
:param draft: Set to True if the orders should be created in the
draft state.
:returns: A list of dictionaries containing the created order
details.
"""
res = super(PosOrder, self).create_from_ui(orders)
id = [line['id'] for line in res if line['id']]
if backend_order := self.search([('id', 'in', id)]):
for pos_order in backend_order:
params = self.env['ir.config_parameter'].sudo()
if params.get_param(
'pos.customer_msg') and pos_order.partner_id.phone:
try:
# Download the helper library from https://www.twilio.com/docs/python/install
Client(params.get_param('pos.account_sid'),
params.get_param(
'pos.auth_token')).messages.create(
body=params.get_param('pos.sms_body'),
from_=params.get_param('pos.twilio_number'),
to=str(pos_order.partner_id.phone))
self.env['pos.greetings'].create({
'partner_id': pos_order.partner_id.id,
'order_id': pos_order.id,
'auth_token': params.get_param('pos.auth_token'),
'twilio_number': params.get_param(
'pos.twilio_number'),
'to_number': str(pos_order.partner_id.phone),
'session_id': pos_order.session_id.id,
'sms_body': params.get_param('pos.sms_body'),
'send_sms': True,
})
except Exception:
pass
return res
class PosOrderLine(models.Model):
"""Inherit the class pos_order_line"""
_inherit = "pos.order.line"
def get_product_details(self, ids):
"""Function to get the product details"""
return [{'product_id': rec.product_id.id, 'name': rec.product_id.name,
'qty': rec.qty}
for rec in self.env['pos.order.line'].browse(ids)]