HEL-205: 纠正期末余额应收应付方向
翻转 _pair_net_change 符号与全站「转出为正=应收」口径对齐,并补齐甲乙双边与浏览器方向断言。 Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
co-authored by
Cursor
multica-agent
parent
fe6b4e59ec
commit
611b09d57c
@@ -133,6 +133,14 @@ class Hel203BrowserSmokeTests(unittest.TestCase):
|
||||
cls.company_a,
|
||||
must_change_password=False,
|
||||
)
|
||||
auth.create_user(
|
||||
connection,
|
||||
"cashier-b",
|
||||
CASHIER_PASSWORD,
|
||||
"company",
|
||||
cls.company_b,
|
||||
must_change_password=False,
|
||||
)
|
||||
admin = connection.execute(
|
||||
"SELECT * FROM users WHERE username = 'group-admin'"
|
||||
).fetchone()
|
||||
@@ -162,7 +170,7 @@ class Hel203BrowserSmokeTests(unittest.TestCase):
|
||||
start_date="2026-06-01",
|
||||
actor=None,
|
||||
)
|
||||
master_data.review_bank_account(
|
||||
cls.account_b = master_data.review_bank_account(
|
||||
connection,
|
||||
account_b["id"],
|
||||
"approve",
|
||||
@@ -305,7 +313,7 @@ class Hel203BrowserSmokeTests(unittest.TestCase):
|
||||
)
|
||||
row_b = _add_row(
|
||||
cls.company_b,
|
||||
account_b["id"],
|
||||
cls.account_b["id"],
|
||||
"6222000000000002",
|
||||
"6222000000000001",
|
||||
income="100.00",
|
||||
@@ -418,7 +426,7 @@ class Hel203BrowserSmokeTests(unittest.TestCase):
|
||||
timeout=8000,
|
||||
)
|
||||
|
||||
# 公司端看到完整期末口径
|
||||
# 甲公司端:期初 200 + 转出 100 → 期末 300(应收),与净额卡方向一致
|
||||
self._login(
|
||||
page,
|
||||
portal="company",
|
||||
@@ -429,21 +437,73 @@ class Hel203BrowserSmokeTests(unittest.TestCase):
|
||||
page.wait_for_function(
|
||||
"""() => {
|
||||
const data = document.getElementById('transfersData');
|
||||
const empty = document.getElementById('transfersEmpty');
|
||||
const ready = (data && !data.hidden) || (empty && !empty.hidden);
|
||||
const card = document.getElementById('tfStatEndingCard');
|
||||
const title = document.getElementById('tfStatNetTitle');
|
||||
const emptyHtml = document.getElementById('transfersEmptyStats')?.innerHTML || '';
|
||||
return ready && (
|
||||
(card && !card.hidden) ||
|
||||
(title && title.textContent.includes('期末')) ||
|
||||
emptyHtml.includes('期末')
|
||||
);
|
||||
return data && !data.hidden && card && !card.hidden;
|
||||
}""",
|
||||
timeout=15000,
|
||||
)
|
||||
summary_a = page.evaluate(
|
||||
"""async () => {
|
||||
const r = await fetch('/api/company/intercompany/summary');
|
||||
return r.json();
|
||||
}"""
|
||||
)
|
||||
self.assertEqual("ok", summary_a.get("status"))
|
||||
self.assertTrue(summary_a["window"]["has_opening"])
|
||||
self.assertEqual("200.00", summary_a["window"]["opening"])
|
||||
self.assertEqual("300.00", summary_a["window"]["ending"])
|
||||
self.assertEqual("100.00", summary_a["confirmed"]["net_change"])
|
||||
self.assertEqual("receivable", summary_a["confirmed"]["net_direction"])
|
||||
|
||||
opening_text = page.locator("#tfStatOpening").inner_text()
|
||||
ending_text = page.locator("#tfStatEnding").inner_text()
|
||||
net_text = page.locator("#tfStatNet").inner_text()
|
||||
self.assertIn("0.02", opening_text)
|
||||
self.assertIn("0.03", ending_text)
|
||||
self.assertIn("0.01", net_text)
|
||||
self.assertIn("应收", net_text)
|
||||
# 页面不得出现与「正数=应收」矛盾的应付标签套在正净额上
|
||||
self.assertNotRegex(net_text, r"\+.*应付")
|
||||
|
||||
# 乙公司端:期初 −200 + 转入 100 → 期末 −300(应付)
|
||||
self._login(
|
||||
page,
|
||||
portal="company",
|
||||
username="cashier-b",
|
||||
password=CASHIER_PASSWORD,
|
||||
)
|
||||
page.click('a[data-view="transfers"]')
|
||||
page.wait_for_function(
|
||||
"""() => {
|
||||
const data = document.getElementById('transfersData');
|
||||
const card = document.getElementById('tfStatEndingCard');
|
||||
return data && !data.hidden && card && !card.hidden;
|
||||
}""",
|
||||
timeout=15000,
|
||||
)
|
||||
summary_b = page.evaluate(
|
||||
"""async () => {
|
||||
const r = await fetch('/api/company/intercompany/summary');
|
||||
return r.json();
|
||||
}"""
|
||||
)
|
||||
self.assertEqual("ok", summary_b.get("status"))
|
||||
self.assertEqual("-200.00", summary_b["window"]["opening"])
|
||||
self.assertEqual("-300.00", summary_b["window"]["ending"])
|
||||
self.assertEqual("-100.00", summary_b["confirmed"]["net_change"])
|
||||
self.assertEqual("payable", summary_b["confirmed"]["net_direction"])
|
||||
ending_b = page.locator("#tfStatEnding").inner_text()
|
||||
net_b = page.locator("#tfStatNet").inner_text()
|
||||
self.assertIn("0.03", ending_b)
|
||||
self.assertIn("应付", net_b)
|
||||
|
||||
fatal = [e for e in errors if "openModal is not defined" in e
|
||||
or "Cannot read properties of null" in e]
|
||||
or "Cannot read properties of null" in e
|
||||
or e.startswith("pageerror")
|
||||
or "pageerror" in e.lower()]
|
||||
# page.on('pageerror') 已直接 push 字符串,过滤明显运行时错误
|
||||
runtime = [e for e in errors if not e.startswith("console.")]
|
||||
self.assertEqual([], runtime, runtime)
|
||||
self.assertEqual([], fatal, fatal)
|
||||
finally:
|
||||
browser.close()
|
||||
|
||||
Reference in New Issue
Block a user