139 lines
4.4 KiB
Python
139 lines
4.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from odoo import models, api
|
|
|
|
|
|
class PosSession(models.Model):
|
|
_inherit = 'pos.session'
|
|
|
|
def action_reprint_closing_summary(self):
|
|
"""Open the closing summary report for this session (backend reprint)."""
|
|
self.ensure_one()
|
|
return self.env.ref(
|
|
'pos_closing_receipt.action_report_pos_closing_summary'
|
|
).report_action(self)
|
|
|
|
def get_closing_summary_data(self):
|
|
"""
|
|
Return structured data consumed by the QWeb report template.
|
|
Aggregates payments grouped by payment method for all orders
|
|
in this session.
|
|
"""
|
|
self.ensure_one()
|
|
session = self
|
|
|
|
payments = self.env['pos.payment'].search([
|
|
('session_id', '=', session.id),
|
|
])
|
|
|
|
method_totals = {}
|
|
for payment in payments:
|
|
pm = payment.payment_method_id
|
|
if pm.id not in method_totals:
|
|
method_totals[pm.id] = {
|
|
'name': pm.name,
|
|
'is_cash': pm.type == 'cash',
|
|
'amount': 0.0,
|
|
}
|
|
method_totals[pm.id]['amount'] += payment.amount
|
|
|
|
sorted_methods = sorted(
|
|
method_totals.values(),
|
|
key=lambda m: (0 if m['is_cash'] else 1, m['name'])
|
|
)
|
|
|
|
cash_payment = None
|
|
non_cash_payments = []
|
|
for m in sorted_methods:
|
|
if m['is_cash']:
|
|
cash_payment = m
|
|
else:
|
|
non_cash_payments.append(m)
|
|
|
|
grand_total = sum(m['amount'] for m in sorted_methods)
|
|
|
|
cashier_name = session.user_id.name or ''
|
|
closing_time = ''
|
|
if session.stop_at:
|
|
tz = self.env.user.tz or 'UTC'
|
|
try:
|
|
import pytz
|
|
utc_dt = session.stop_at.replace(tzinfo=pytz.utc)
|
|
local_dt = utc_dt.astimezone(pytz.timezone(tz))
|
|
closing_time = local_dt.strftime('%Y-%m-%d %H:%M:%S')
|
|
except Exception:
|
|
closing_time = session.stop_at.strftime('%Y-%m-%d %H:%M:%S')
|
|
|
|
return {
|
|
'session': session,
|
|
'session_name': session.name,
|
|
'cashier_name': cashier_name,
|
|
'closing_time': closing_time,
|
|
'cash_payment': cash_payment,
|
|
'non_cash_payments': non_cash_payments,
|
|
'grand_total': grand_total,
|
|
}
|
|
|
|
@api.model
|
|
def get_last_closed_session_summary(self, config_id):
|
|
"""
|
|
Called from the POS frontend (Navbar) to reprint the last closed
|
|
session summary for the given config.
|
|
|
|
Returns a dict with:
|
|
- session_name
|
|
- cashier_name
|
|
- closing_time (localized to current user's timezone)
|
|
- payment_methods: [{id, name, is_cash, amount}]
|
|
|
|
Returns False if no closed session exists for this config.
|
|
"""
|
|
session = self.search(
|
|
[('config_id', '=', config_id), ('state', '=', 'closed')],
|
|
order='stop_at desc',
|
|
limit=1,
|
|
)
|
|
if not session:
|
|
return False
|
|
|
|
payments = self.env['pos.payment'].search([
|
|
('session_id', '=', session.id),
|
|
])
|
|
|
|
method_totals = {}
|
|
for payment in payments:
|
|
pm = payment.payment_method_id
|
|
if pm.id not in method_totals:
|
|
method_totals[pm.id] = {
|
|
'id': pm.id,
|
|
'name': pm.name,
|
|
'is_cash': pm.type == 'cash',
|
|
'amount': 0.0,
|
|
}
|
|
method_totals[pm.id]['amount'] += payment.amount
|
|
|
|
# Sort: cash first, then alphabetically
|
|
payment_methods = sorted(
|
|
method_totals.values(),
|
|
key=lambda m: (0 if m['is_cash'] else 1, m['name'])
|
|
)
|
|
|
|
cashier_name = session.user_id.name or ''
|
|
closing_time = ''
|
|
if session.stop_at:
|
|
tz = self.env.user.tz or 'UTC'
|
|
try:
|
|
import pytz
|
|
utc_dt = session.stop_at.replace(tzinfo=pytz.utc)
|
|
local_dt = utc_dt.astimezone(pytz.timezone(tz))
|
|
closing_time = local_dt.strftime('%Y-%m-%d %H:%M:%S')
|
|
except Exception:
|
|
closing_time = session.stop_at.strftime('%Y-%m-%d %H:%M:%S')
|
|
|
|
return {
|
|
'session_name': session.name,
|
|
'cashier_name': cashier_name,
|
|
'closing_time': closing_time,
|
|
'payment_methods': payment_methods,
|
|
}
|