1+ # © 2026 BITVAX
2+ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
3+ """Bug: account.payment.register wizard's available_journal_ids
4+ includes journals from operating units the invoice does not belong to.
5+
6+ A B2B invoice should only offer journals whose operating_unit_id
7+ matches B2B (or no OU). On upstream/18.0 the wizard pulls journals via
8+ ``account.journal.search()`` without OU context, so it returns every
9+ sale/cash journal of the company regardless of OU.
10+
11+ The fix is to override
12+ ``account.payment.register._get_batch_available_journals`` and filter
13+ the returned set by the operating_unit_id of the invoices in the
14+ batch.
15+ """
16+ from odoo .models import Command
17+ from odoo .tests import tagged
18+
19+ from odoo .addons .account .tests .common import AccountTestInvoicingCommon
20+ from odoo .addons .operating_unit .tests .common import OperatingUnitCommon
21+
22+
23+ @tagged ("post_install" , "-at_install" )
24+ class TestPaymentRegisterJournalOu (
25+ AccountTestInvoicingCommon , OperatingUnitCommon
26+ ):
27+
28+ @classmethod
29+ def setUpClass (cls ):
30+ super ().setUpClass ()
31+
32+ (cls .ou1 | cls .b2b | cls .b2c ).sudo ().write (
33+ {"company_id" : cls .company .id }
34+ )
35+
36+ cls .env .user .sudo ().write (
37+ {
38+ "groups_id" : [
39+ Command .link (
40+ cls .env .ref (
41+ "operating_unit.group_manager_operating_unit"
42+ ).id
43+ ),
44+ ],
45+ "operating_unit_ids" : [
46+ Command .link (cls .ou1 .id ),
47+ Command .link (cls .b2b .id ),
48+ ],
49+ "default_operating_unit_id" : cls .ou1 .id ,
50+ "company_ids" : [Command .link (cls .company .id )],
51+ "company_id" : cls .company .id ,
52+ }
53+ )
54+
55+ cls .user1 .write (
56+ {
57+ "groups_id" : [
58+ (
59+ 3 ,
60+ cls .env .ref (
61+ "operating_unit.group_manager_operating_unit"
62+ ).id ,
63+ ),
64+ Command .link (
65+ cls .env .ref (
66+ "operating_unit.group_multi_operating_unit"
67+ ).id
68+ ),
69+ Command .link (
70+ cls .env .ref ("account.group_account_invoice" ).id
71+ ),
72+ ],
73+ "assigned_operating_unit_ids" : [(6 , 0 , [cls .b2b .id ])],
74+ "default_operating_unit_id" : cls .b2b .id ,
75+ "company_id" : cls .company .id ,
76+ "company_ids" : [Command .link (cls .company .id )],
77+ }
78+ )
79+
80+ Journal = cls .env ["account.journal" ].sudo ()
81+ cls .purchase_journal_b2b = Journal .create (
82+ {
83+ "name" : "Vendor Bills B2B (test_pay_reg)" ,
84+ "code" : "TPRPB" ,
85+ "type" : "purchase" ,
86+ "company_id" : cls .company .id ,
87+ "operating_unit_id" : cls .b2b .id ,
88+ }
89+ )
90+ cls .cash_journal_ou1 = Journal .create (
91+ {
92+ "name" : "Cash OU1 (test_pay_reg)" ,
93+ "code" : "TPRC1" ,
94+ "type" : "cash" ,
95+ "company_id" : cls .company .id ,
96+ "operating_unit_id" : cls .ou1 .id ,
97+ }
98+ )
99+ cls .cash_journal_b2b = Journal .create (
100+ {
101+ "name" : "Cash B2B (test_pay_reg)" ,
102+ "code" : "TPRCB" ,
103+ "type" : "cash" ,
104+ "company_id" : cls .company .id ,
105+ "operating_unit_id" : cls .b2b .id ,
106+ }
107+ )
108+ cls .expense_account = cls .env ["account.account" ].search (
109+ [
110+ ("account_type" , "=" , "expense" ),
111+ ("company_ids" , "in" , cls .company .ids ),
112+ ],
113+ limit = 1 ,
114+ )
115+
116+ def test_payment_register_filters_journals_by_invoice_ou (self ):
117+ invoice = (
118+ self .env ["account.move" ]
119+ .with_context (default_move_type = "in_invoice" )
120+ .create (
121+ {
122+ "partner_id" : self .partner1 .id ,
123+ "operating_unit_id" : self .b2b .id ,
124+ "invoice_date" : "2026-01-01" ,
125+ "journal_id" : self .purchase_journal_b2b .id ,
126+ "invoice_line_ids" : [
127+ (
128+ 0 ,
129+ 0 ,
130+ {
131+ "name" : "Line" ,
132+ "quantity" : 1 ,
133+ "price_unit" : 100.0 ,
134+ "account_id" : self .expense_account .id ,
135+ "tax_ids" : [],
136+ },
137+ )
138+ ],
139+ }
140+ )
141+ )
142+ invoice .action_post ()
143+
144+ wizard = (
145+ self .env ["account.payment.register" ]
146+ .with_user (self .user1 )
147+ .with_context (
148+ active_model = "account.move" ,
149+ active_ids = invoice .ids ,
150+ )
151+ .create ({"journal_id" : self .cash_journal_b2b .id })
152+ )
153+ available = wizard .available_journal_ids
154+ self .assertIn (
155+ self .cash_journal_b2b ,
156+ available ,
157+ "B2B cash journal must be available to pay a B2B invoice." ,
158+ )
159+ self .assertNotIn (
160+ self .cash_journal_ou1 ,
161+ available ,
162+ "OU1 cash journal must NOT be available when paying a "
163+ "B2B invoice." ,
164+ )
0 commit comments