diff --git a/apps/api/src/pipelines/deals.service.ts b/apps/api/src/pipelines/deals.service.ts index 0328ec2..d153853 100644 --- a/apps/api/src/pipelines/deals.service.ts +++ b/apps/api/src/pipelines/deals.service.ts @@ -225,14 +225,15 @@ export class DealsService { } const data: Prisma.DealUncheckedUpdateInput = {}; + const pricedFromLines = (dto.lineItems?.length ?? 0) > 0; if (dto.title !== undefined) data.title = dto.title.trim(); - if ('amount' in dto && dto.lineItems === undefined) { + if ('amount' in dto && !pricedFromLines) { data.amount = dto.amount == null || Number.isNaN(Number(dto.amount)) ? null : new Prisma.Decimal(dto.amount); } - if (dto.currency !== undefined && dto.lineItems === undefined) { + if (dto.currency !== undefined && !pricedFromLines) { data.currency = dto.currency.trim() || 'IRR'; } if ('source' in dto) data.source = emptyToNull(dto.source); @@ -270,7 +271,7 @@ export class DealsService { assigneeConnect = assigneeIds.map((uid) => ({ id: uid })); } - if (dto.lineItems !== undefined) { + if (pricedFromLines && dto.lineItems) { const total = sumLineItems(dto.lineItems); data.amount = total == null ? null : new Prisma.Decimal(total); diff --git a/apps/web/src/components/gamification/ClubLeaderboard.vue b/apps/web/src/components/gamification/ClubLeaderboard.vue index 723686f..3d3e700 100644 --- a/apps/web/src/components/gamification/ClubLeaderboard.vue +++ b/apps/web/src/components/gamification/ClubLeaderboard.vue @@ -97,26 +97,26 @@ const meOutside = computed(() => {
  1. + {{ toFaDigits(e.rank) }} + + {{ e.isMe ? 'شما' : e.fullName }} + {{ faNum(e.score) }} - {{ faNum(e.score) }} - {{ e.isMe ? 'شما' : e.fullName }} - - {{ toFaDigits(e.rank) }}
  2. هنوز کسی در این بازه امتیاز نگرفته است.
  3. @@ -315,7 +315,7 @@ const meOutside = computed(() => { .who { flex: 1; min-width: 0; - text-align: end; + text-align: start; font-size: 0.84rem; font-weight: 600; color: #0f172a; diff --git a/apps/web/src/views/DealFormView.vue b/apps/web/src/views/DealFormView.vue index 3fa93f8..8579c23 100644 --- a/apps/web/src/views/DealFormView.vue +++ b/apps/web/src/views/DealFormView.vue @@ -116,6 +116,8 @@ const sourceRef = ref(''); const status = ref(''); const customFields = ref>({}); const lines = ref([]); +/** تعداد اقلام ذخیره‌شده؛ برای حذف همهٔ اقلام باید آرایهٔ خالی فرستاده شود */ +const savedLineCount = ref(0); const nextDueDate = ref(''); const nextDueTime = ref('10:30'); @@ -364,7 +366,11 @@ async function load() { quantity: String(item.quantity), unitPrice: String(item.unitPrice), })); + savedLineCount.value = lines.value.length; productsOpen.value = lines.value.length > 0; + if (data.company && !companies.value.some((c) => c.id === data.company!.id)) { + companies.value = [{ id: data.company.id, name: data.company.name } as CompanyDto, ...companies.value]; + } if (data.pipelineId !== pipelineId.value) { await loadBoard(data.pipelineId); stageId.value = data.stageId; @@ -397,6 +403,7 @@ async function load() { function payload(): CreateDealRequest { const lineItems = toLineInputs(); + const sendLineItems = lineItems.length > 0 || savedLineCount.value > 0; return { title: title.value, amount: @@ -423,12 +430,12 @@ function payload(): CreateDealRequest { stageId: stageId.value || undefined, customFields: customFields.value, currency: currency.value || 'IRR', - lineItems, + ...(sendLineItems ? { lineItems } : {}), }; } async function createFollowUp(dealId: string) { - if (!isNew.value || !nextDueDate.value) return; + if (!nextDueDate.value) return; const due = new Date(`${nextDueDate.value}T${nextDueTime.value || '10:30'}:00`); if (Number.isNaN(due.getTime())) return; await api.post('/activities', { @@ -488,6 +495,11 @@ async function submit() { if (moveStageId) { await api.patch(`/deals/${id.value}/move`, { stageId: moveStageId }); } + try { + await createFollowUp(id.value); + } catch { + /* deal saved; follow-up is optional */ + } if (props.embedded) { emit('saved'); return;