pos_cash_opening_adjustment/models/pos_session.py

153 lines
6.7 KiB
Python

# -*- coding: utf-8 -*-
import logging
from odoo import api, fields, models
_logger = logging.getLogger(__name__)
class PosSession(models.Model):
_inherit = "pos.session"
opening_cash_expected = fields.Monetary(
string="Expected Opening Cash",
currency_field="currency_id",
readonly=True,
help="Forecasted cash amount in the drawer when the session is opened.",
)
opening_cash_counted = fields.Monetary(
string="Counted Opening Cash",
currency_field="currency_id",
readonly=True,
help="Actual cash amount counted by the cashier when the session is opened.",
)
opening_cash_difference = fields.Monetary(
string="Opening Cash Difference",
currency_field="currency_id",
compute="_compute_opening_cash_difference",
store=True,
help="Difference between the expected and the counted cash at session opening.",
)
@api.depends("opening_cash_expected", "opening_cash_counted")
def _compute_opening_cash_difference(self):
for session in self:
expected = session.opening_cash_expected or 0.0
counted = session.opening_cash_counted or 0.0
session.opening_cash_difference = counted - expected
def action_pos_session_open(self):
res = super().action_pos_session_open()
for session in self:
if session.config_id.cash_control:
session.write({
"opening_cash_expected": session.cash_register_balance_start or 0.0,
"opening_cash_counted": 0.0,
})
else:
session.write({
"opening_cash_expected": 0.0,
"opening_cash_counted": 0.0,
})
return res
def set_cashbox_pos(self, cashbox_value: int, notes: str):
_logger.debug(
"POS cash opening adjustment: set_cashbox_pos called for session_ids=%s, cashbox_value=%s, notes=%s",
self.ids,
cashbox_value,
notes,
)
for session in self:
expected = session.opening_cash_expected if session.config_id.cash_control else 0.0
if not session.config_id.cash_control:
expected = session.cash_register_balance_start or 0.0
difference = cashbox_value - (expected or 0.0)
_logger.debug(
"POS cash opening adjustment: session=%s expected=%s counted=%s difference=%s cash_control=%s",
session.id,
expected,
cashbox_value,
difference,
session.config_id.cash_control,
)
session.write({
"state": "opened",
"opening_notes": notes,
"cash_register_balance_start": cashbox_value,
"opening_cash_expected": expected,
"opening_cash_counted": cashbox_value if session.config_id.cash_control else 0.0,
})
session._post_cash_details_message("Opening", difference, notes)
return True
def _get_opening_float_amount(self):
self.ensure_one()
if not self.config_id.cash_control:
return 0.0
opening_amount = self.opening_cash_counted
if self.currency_id.is_zero(opening_amount or 0.0):
opening_amount = self.opening_cash_expected
return opening_amount or 0.0
def _post_statement_difference(self, amount, is_opening):
for session in self:
session_amount = amount
if not is_opening and session.config_id.cash_control:
opening_float = session._get_opening_float_amount()
if opening_float and session.currency_id.is_zero(session_amount + opening_float):
_logger.debug(
"POS cash opening adjustment: skipping difference posting for session %s "
"because it solely matches the opening float (amount=%s, opening_float=%s).",
session.id,
session_amount,
opening_float,
)
continue
super(PosSession, session)._post_statement_difference(session_amount, is_opening)
@api.depends("payment_method_ids", "order_ids", "cash_register_balance_start", "cash_real_transaction", "statement_line_ids")
def _compute_cash_balance(self):
for session in self:
cash_payment_method = session.payment_method_ids.filtered("is_cash_count")[:1]
if cash_payment_method:
result = self.env["pos.payment"]._read_group(
[
("session_id", "=", session.id),
("payment_method_id", "=", cash_payment_method.id),
],
aggregates=["amount:sum"],
)
total_cash_payment = result[0][0] or 0.0
if session.state == "closed":
manual_cash_total = session.cash_real_transaction or 0.0
else:
manual_cash_total = sum(session.statement_line_ids.mapped("amount"))
session.cash_register_total_entry_encoding = manual_cash_total + total_cash_payment
session.cash_register_balance_end = session.cash_register_balance_start + session.cash_register_total_entry_encoding
session.cash_register_difference = session.cash_register_balance_end_real - session.cash_register_balance_end
else:
session.cash_register_total_entry_encoding = 0.0
session.cash_register_balance_end = 0.0
session.cash_register_difference = 0.0
def get_closing_control_data(self):
data = super().get_closing_control_data()
default_cash_details = data.get("default_cash_details")
if default_cash_details:
manual_moves_total = sum(move.get("amount", 0.0) for move in default_cash_details.get("moves", []))
payments_amount = default_cash_details.get("payment_amount") or 0.0
opening_expected = self.opening_cash_expected or 0.0
expected_total = opening_expected + payments_amount + manual_moves_total
session_cash_amount = payments_amount + manual_moves_total
default_cash_details.update({
"opening": opening_expected,
"opening_cash_expected": opening_expected,
"opening_cash_counted": self.opening_cash_counted or 0.0,
"opening_cash_difference": self.opening_cash_difference or 0.0,
"session_cash_amount": session_cash_amount,
"expected_amount": expected_total,
"amount": expected_total,
})
return data