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>
189 lines
5.6 KiB
Vue
189 lines
5.6 KiB
Vue
<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>
|