diff --git a/README.md b/README.md
index b7628fe..a849e65 100644
--- a/README.md
+++ b/README.md
@@ -43,6 +43,7 @@ TOTAL Rp 850.000,00
|---------------|----------------------------------------|
| `point_of_sale` | Core Odoo 19 POS module |
| `pos_hr` | Required for cashier name lookup via `pos.getCashier()` |
+| `pos_cash_opening_adjustment` | Required for cash difference tracking fields (`closing_cash_expected`, `closing_cash_counted`, etc.) |
---
diff --git a/__manifest__.py b/__manifest__.py
index ee9e03c..b246b58 100644
--- a/__manifest__.py
+++ b/__manifest__.py
@@ -15,7 +15,7 @@
form view in the Odoo backend for easy reprinting.
""",
'author': 'Suherdy Yacob',
- 'depends': ['point_of_sale', 'pos_hr'],
+ 'depends': ['point_of_sale', 'pos_hr', 'pos_cash_opening_adjustment'],
'data': [
'report/pos_closing_summary_report.xml',
'views/pos_session_views.xml',
diff --git a/models/pos_session.py b/models/pos_session.py
index f35a562..aee2ba0 100644
--- a/models/pos_session.py
+++ b/models/pos_session.py
@@ -99,6 +99,10 @@ class PosSession(models.Model):
'cash_payment': cash_payment,
'non_cash_payments': non_cash_payments,
'grand_total': grand_total,
+ 'has_cash_control': session.config_id.cash_control,
+ 'closing_cash_expected': session.closing_cash_expected,
+ 'closing_cash_counted': session.closing_cash_counted,
+ 'closing_cash_difference': session.closing_cash_difference,
}
@api.model
@@ -162,4 +166,8 @@ class PosSession(models.Model):
'cashier_name': cashier_name,
'closing_time': closing_time,
'payment_methods': payment_methods,
+ 'has_cash_control': session.config_id.cash_control,
+ 'closing_cash_expected': session.closing_cash_expected,
+ 'closing_cash_counted': session.closing_cash_counted,
+ 'closing_cash_difference': session.closing_cash_difference,
}
diff --git a/report/pos_closing_summary_report.xml b/report/pos_closing_summary_report.xml
index 6e00050..c6d5046 100644
--- a/report/pos_closing_summary_report.xml
+++ b/report/pos_closing_summary_report.xml
@@ -127,6 +127,34 @@
+
+
+
+
+
+ | Expected Cash |
+
+
+ |
+
+
+ | Counted Cash |
+
+
+ |
+
+
+ | Cash Difference |
+
+
+ |
+
+
+
+
diff --git a/static/src/app/closing_receipt.xml b/static/src/app/closing_receipt.xml
index c74feb0..0863f6d 100644
--- a/static/src/app/closing_receipt.xml
+++ b/static/src/app/closing_receipt.xml
@@ -79,6 +79,31 @@
+
+
+
+
+
+ | Expected Cash |
+
+
+ |
+
+
+ | Counted Cash |
+
+
+ |
+
+
+ | Cash Difference |
+
+
+ |
+
+
+
+
diff --git a/static/src/app/closing_receipt_patch.js b/static/src/app/closing_receipt_patch.js
index f13409f..ff4299d 100644
--- a/static/src/app/closing_receipt_patch.js
+++ b/static/src/app/closing_receipt_patch.js
@@ -348,6 +348,18 @@ patch(ClosePosPopup.prototype, {
const nonCashTotal = nonCashPayments.reduce((sum, pm) => sum + pm.amount, 0);
const grandTotal = formatCurrency(cashAmount + nonCashTotal);
+ let expectedCash = 0;
+ let countedCash = 0;
+ let cashDifference = 0;
+ let hasCashControl = false;
+ if (this.props.default_cash_details) {
+ hasCashControl = true;
+ expectedCash = this.props.default_cash_details.amount || 0;
+ const countedStr = this.state.payments[this.props.default_cash_details.id]?.counted || "0";
+ countedCash = parseFloat(countedStr) || 0;
+ cashDifference = countedCash - expectedCash;
+ }
+
return {
sessionName,
cashierName,
@@ -355,6 +367,11 @@ patch(ClosePosPopup.prototype, {
cashPayment,
nonCashPayments,
grandTotal,
+ hasCashControl,
+ expectedCash: formatCurrency(expectedCash),
+ countedCash: formatCurrency(countedCash),
+ cashDifference: formatCurrency(cashDifference),
+ rawCashDifference: cashDifference,
};
},
});
@@ -414,6 +431,26 @@ patch(Navbar.prototype, {
.reduce((s, p) => s + p.amount, 0);
const grandTotal = formatCurrency(cashAmount + nonCashTotal);
+ let cashControlBlock = "";
+ if (sessionData.has_cash_control) {
+ cashControlBlock = `
+
+
+
+ | Expected Cash |
+ ${formatCurrency(sessionData.closing_cash_expected)} |
+
+
+ | Counted Cash |
+ ${formatCurrency(sessionData.closing_cash_counted)} |
+
+
+ | Cash Difference |
+ ${formatCurrency(sessionData.closing_cash_difference)} |
+
+
`;
+ }
+
// ── 3. Build standalone HTML receipt and open print window ───────────
const html = `
@@ -500,6 +537,7 @@ patch(Navbar.prototype, {
${grandTotal} |
+ ${cashControlBlock}