Files
boursecu_admin/src/pages/menuPages/colleagueOrders/components/ColleagueAccountingAccounts.vue
T
mohmdsdgandCursor 1c4b2d4435 Require review before Tahesab wallet sync and harden accounting admin UX.
Single-customer and row sync preview balances with documents before overwrite/keep; bulk sync keeps confirm. Also ship Zarin wallet sync actions, field help, and get_user cache improvements.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-30 21:18:26 +03:30

189 lines
5.6 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<section
v-if="visible"
class="colleague-accounts w-full flex flex-col gap-2.5 rounded-lg border border-base p-2.5 sm:grid sm:grid-cols-2 sm:items-end sm:gap-3"
>
<div class="min-w-0">
<h3 class="m-0 inline-flex items-center gap-1.5 text-sm font-600" style="color: var(--admin-text)">
کد حسابداری معامله با همکار
<AdminFieldHelp :text="colleagueAccountingCodeHelp" size="sm" />
</h3>
<p class="m-0 mt-0.5 text-xs leading-5" style="color: var(--admin-text-secondary)">
سند خرید/فروش پوشش‌شده روی این کد در حسابداری فعال ثبت می‌شود.
</p>
</div>
<label v-if="activeField" class="m-0 flex w-full min-w-0 flex-col gap-1">
<span class="inline-flex items-center gap-1.5 text-xs font-600" style="color: var(--admin-text)">
{{ activeField.label }}
<span class="colleague-accounts__badge">فعال</span>
</span>
<div class="flex w-full min-w-0 items-center gap-2">
<a-input
v-model:value="values[activeField.key]"
:placeholder="activeField.placeholder"
allow-clear
size="small"
class="min-w-0 flex-1"
/>
<BaseButton type="primary" size="small" class="shrink-0" :loading="saving" @click="save">
ذخیره
</BaseButton>
</div>
</label>
</section>
</template>
<script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue'
import { message } from 'ant-design-vue'
import { getConfiguration, setConfiguration } from '@/api/configuration'
import type { Const } from '@/model/configuration'
import { colleagueAccountingCodeHelp } from '@/utils/adminHelpCopy'
import AdminFieldHelp from '@/components/AdminFieldHelp.vue'
import {
accountingProviderSetting,
initWalletSettingsFromApi,
priceProviderSetting,
type AccountingProvider,
} from '@/utils/config'
const props = withDefaults(
defineProps<{
/**
* اگر ست شود فقط وقتی provider فعال همین باشد نشان بده
* (مثلاً روی صفحهٔ همگام‌سازی ته‌حساب: provider-only="tahesab")
*/
providerOnly?: AccountingProvider | null
/** پیش‌فرض: فقط وقتی منبع قیمت Montzar است */
requireMontzar?: boolean
}>(),
{
providerOnly: null,
requireMontzar: true,
},
)
const KEYS = {
zarin: 'montzar_account_zarin',
tahesab: 'montzar_account_tahesab',
pargar: 'montzar_account_pargar',
} as const
const META: Record<
Exclude<AccountingProvider, 'none'>,
{ key: string; label: string; placeholder: string; titleFa: string }
> = {
zarin: {
key: KEYS.zarin,
label: 'کد حساب زرین',
placeholder: 'کد حساب همکار در زرین',
titleFa: 'کد حساب همکار در زرین',
},
tahesab: {
key: KEYS.tahesab,
label: 'کد حساب ته‌حساب',
placeholder: 'کد حساب همکار در ته‌حساب',
titleFa: 'کد حساب همکار در ته‌حساب',
},
pargar: {
key: KEYS.pargar,
label: 'کد حساب پرگار',
placeholder: 'کد حساب همکار در پرگار',
titleFa: 'کد حساب همکار در پرگار',
},
}
const values = reactive<Record<string, string>>({
[KEYS.zarin]: '',
[KEYS.tahesab]: '',
[KEYS.pargar]: '',
})
const rowIds = reactive<Record<string, number | null>>({
[KEYS.zarin]: null,
[KEYS.tahesab]: null,
[KEYS.pargar]: null,
})
const saving = ref(false)
const activeProvider = computed(() => accountingProviderSetting.value as AccountingProvider)
const activeField = computed(() => {
const provider = activeProvider.value
if (provider === 'none') return null
return META[provider] ?? null
})
const visible = computed(() => {
if (props.requireMontzar && priceProviderSetting.value !== 'montzar') {
return false
}
if (!activeField.value) {
return false
}
if (props.providerOnly && activeProvider.value !== props.providerOnly) {
return false
}
return true
})
async function load() {
await initWalletSettingsFromApi()
const rows = await getConfiguration()
const list = Array.isArray(rows) ? rows : []
for (const key of Object.values(KEYS)) {
const row = list.find((item) => item?.key === key)
values[key] = row?.value != null ? String(row.value) : ''
rowIds[key] = row?.id != null ? Number(row.id) : null
}
}
async function save() {
const field = activeField.value
if (!field) {
message.warning('سیستم حسابداری فعالی انتخاب نشده است')
return
}
saving.value = true
try {
await setConfiguration({
id: rowIds[field.key] ?? undefined,
key: field.key,
value: (values[field.key] ?? '').trim(),
title_fa: field.titleFa,
is_active: true,
can_edit: true,
type: 'text',
description:
'کد حساب طرف حساب همکار؛ سند خرید/فروش پوشش‌شده روی Montzar روی این حساب ثبت می‌شود.',
} satisfies Const)
message.success('کد حساب همکار ذخیره شد')
await load()
} catch (error) {
console.error(error)
message.error('ذخیره کد حساب همکار ناموفق بود')
} finally {
saving.value = false
}
}
onMounted(() => {
void load()
})
</script>
<style scoped>
.colleague-accounts {
background: var(--admin-bg-surface, var(--admin-bg-elevated, rgba(28, 28, 34, 0.92)));
}
.colleague-accounts__badge {
@apply inline-flex items-center rounded-full px-1.5 text-10px font-700;
background: rgba(212, 175, 55, 0.18);
color: #d4af37;
}
</style>