feat: customer groups for people and companies with tahesab group sync and bulk register
Multiple groups per contact, legacy group text migrated, excel import/export, contacts filter and column, richer create-in-tahesab, match-first bulk export
This commit is contained in:
@@ -38,6 +38,7 @@ import type { CompanyDto, CreatePersonRequest, PersonDto, PersonMood } from '@me
|
||||
import { PERSON_MOOD_LABELS, PERSON_MOODS } from '@/lib/person-mood';
|
||||
import { formatLocalDateInput, toFaDigits } from '@/lib/jalali';
|
||||
import JalaliDateInput from '@/components/JalaliDateInput.vue';
|
||||
import { useCustomerGroups } from '@/lib/customer-groups';
|
||||
import {
|
||||
filterPhoneContacts,
|
||||
isContactPickerSupported,
|
||||
@@ -97,7 +98,13 @@ const notes = ref('');
|
||||
const tagsRaw = ref('');
|
||||
const companyId = ref('');
|
||||
const mood = ref<PersonMood>('newcomer');
|
||||
const groupIds = ref<string[]>([]);
|
||||
const customFields = ref<Record<string, unknown>>({});
|
||||
const { groups: customerGroups, loaded: groupsLoaded, load: loadCustomerGroups } =
|
||||
useCustomerGroups();
|
||||
const groupOptions = computed(() =>
|
||||
customerGroups.value.map((g) => ({ value: g.id, label: g.name })),
|
||||
);
|
||||
const loyaltyPoints = ref(0);
|
||||
const loyaltyTierName = ref('');
|
||||
|
||||
@@ -257,6 +264,7 @@ function fill(p: PersonDto) {
|
||||
tagsRaw.value = (p.tags ?? []).join('، ');
|
||||
companyId.value = p.company?.id ?? '';
|
||||
mood.value = p.mood || 'newcomer';
|
||||
groupIds.value = (p.groups ?? []).map((g) => g.id);
|
||||
customFields.value = { ...(p.customFields ?? {}) };
|
||||
loyaltyPoints.value = p.loyaltyPoints ?? 0;
|
||||
loyaltyTierName.value = p.loyaltyTier?.name ?? '';
|
||||
@@ -277,6 +285,7 @@ function removeAddress(index: number) {
|
||||
async function load() {
|
||||
loading.value = true;
|
||||
error.value = '';
|
||||
void loadCustomerGroups().catch(() => undefined);
|
||||
try {
|
||||
const companiesRes = await api.get<{ items: CompanyDto[] }>('/companies', {
|
||||
params: { limit: 100 },
|
||||
@@ -334,6 +343,7 @@ function payload(): CreatePersonRequest {
|
||||
tags: parseTags(tagsRaw.value),
|
||||
companyId: companyId.value || null,
|
||||
mood: mood.value,
|
||||
groupIds: groupIds.value,
|
||||
customFields: customFields.value,
|
||||
};
|
||||
}
|
||||
@@ -558,6 +568,20 @@ onMounted(load);
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :xs="24" :md="12">
|
||||
<a-form-item label="گروهها">
|
||||
<a-select
|
||||
v-model:value="groupIds"
|
||||
mode="multiple"
|
||||
allow-clear
|
||||
option-filter-prop="label"
|
||||
placeholder="بدون گروه"
|
||||
:options="groupOptions"
|
||||
:not-found-content="groupsLoaded ? 'گروهی تعریف نشده' : undefined"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
<a-col :xs="24" :md="12">
|
||||
<a-form-item label="برچسبها">
|
||||
<a-input
|
||||
|
||||
Reference in New Issue
Block a user