feat(tahesab): three-way mande decision UI including push to Tahesab

Clarify overwrite vs keep vs push-to-tahesab, warn when app balance is zero, and update colleague wait-callback help text.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-05 22:30:58 +03:30
co-authored by Cursor
parent e0b89223ac
commit 9ef381f00e
6 changed files with 208 additions and 42 deletions
@@ -7,7 +7,7 @@
<AdminFieldHelp :text="accountingTahesabBalanceSyncIntro" size="sm" />
</div>
<p class="tw-bulk__hint">
همگام تکی: اول سندها و اختلاف را می‌بینید، بعد تأیید می‌کنید. دو مانده جمع نمی‌شوند.
همگام تکی: اول سندها و اختلاف را می‌بینید، بعد یکی از سه مسیر را تأیید می‌کنید (ته‌حساب→اپ، اپ→ته‌حساب حتی اگر اپ صفر باشد، یا نگه داشتن). دو مانده جمع نمی‌شوند.
همگام همه فقط کیف خالی را می‌نشاند؛ تداخل برای تصمیم دستی می‌ماند.
</p>
</div>
@@ -154,6 +154,7 @@
<TahesabMandeDecisionModal
v-model:visible="decisionVisible"
source-label="ته‌حساب"
:allow-push="true"
:app-gold="decisionResult?.app_gold"
:app-cash="decisionResult?.app_cash"
:tahesab-gold="decisionResult?.tahesab_gold"
@@ -200,7 +201,7 @@ const failed = ref(0)
const errors = ref<TahesabBulkWalletSyncChunk['errors']>([])
const decisions = ref<TahesabBulkWalletSyncChunk['decisions']>([])
const decidingId = ref<number | null>(null)
const decidingMode = ref<'overwrite' | 'keep' | null>(null)
const decidingMode = ref<'overwrite' | 'keep' | 'push' | null>(null)
const search = ref('')
const page = ref(1)
@@ -209,7 +210,7 @@ const listTotal = ref(0)
const listLoading = ref(false)
const rows = ref<TahesabWalletLinkedRow[]>([])
const syncingId = ref<number | null>(null)
const syncingMode = ref<'ask' | 'overwrite' | 'keep' | null>(null)
const syncingMode = ref<'ask' | 'overwrite' | 'keep' | 'push' | null>(null)
const decisionVisible = ref(false)
const decisionCustomerId = ref<number | null>(null)
const decisionResult = ref<TahesabWalletSyncResult['result'] | null>(null)
@@ -321,7 +322,7 @@ async function openReview(customerId: number) {
}
}
async function onReviewDecide(mode: 'overwrite' | 'keep') {
async function onReviewDecide(mode: 'overwrite' | 'keep' | 'push') {
const customerId = decisionCustomerId.value
decisionVisible.value = false
if (!customerId) return
@@ -337,22 +338,25 @@ function dismissResult() {
showDetails.value = false
}
async function applyDecision(customerId: number, mode: 'overwrite' | 'keep') {
async function applyDecision(customerId: number, mode: 'overwrite' | 'keep' | 'push') {
decidingId.value = customerId
decidingMode.value = mode
try {
const res = await syncCustomerWalletFromTahesab(customerId, {
overwrite: mode === 'overwrite',
keep: mode === 'keep',
push_to_tahesab: mode === 'push',
ask_if_conflict: false,
})
decisions.value = decisions.value.filter(d => d.id !== customerId)
needsDecision.value = Math.max(0, decisions.value.length)
if (mode === 'keep') message.info(res.message || 'موجودی اپ حفظ شد')
else if (mode === 'push') message.success(res.message || 'مانده اپ روی ته‌حساب اعمال شد')
else message.success(res.message || 'مانده ته‌حساب اعمال شد')
await loadList()
} catch {
message.error('اعمال تصمیم ناموفق بود')
} catch (e: unknown) {
const data = (e as { response?: { data?: { message?: string } } })?.response?.data
message.error(data?.message || 'اعمال تصمیم ناموفق بود')
} finally {
decidingId.value = null
decidingMode.value = null