# -*- coding: utf-8 -*- from odoo import api, fields, models 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): 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) 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: if session.currency_id.is_zero(session_amount + opening_float): continue if session.currency_id.compare_amounts(session.cash_register_balance_end_real or 0.0, opening_float) <= 0: session_amount += opening_float if session.currency_id.is_zero(session_amount): continue elif session.currency_id.is_zero(session_amount): 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