fix some bugs from accounting 2
This commit is contained in:
@@ -239,6 +239,13 @@ function inventoryCards() {
|
|||||||
return [...(summary.value.inventory_cards ?? []), ...(summary.value.count_products ?? [])]
|
return [...(summary.value.inventory_cards ?? []), ...(summary.value.count_products ?? [])]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isCountChargeTarget(target: ChargeTarget) {
|
||||||
|
if (target.kind === 'money') return false
|
||||||
|
if (target.allows_decimal === false) return true
|
||||||
|
if (target.unit === 'عدد') return true
|
||||||
|
return target.trade_by_quantity === false && !isMeltedTradeGroup(target.group_type)
|
||||||
|
}
|
||||||
|
|
||||||
function balanceForTarget(target: ChargeTarget) {
|
function balanceForTarget(target: ChargeTarget) {
|
||||||
if (!summary.value) return '—'
|
if (!summary.value) return '—'
|
||||||
if (target.kind === 'money') {
|
if (target.kind === 'money') {
|
||||||
@@ -246,18 +253,15 @@ function balanceForTarget(target: ChargeTarget) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const card = inventoryCards().find((row) => Number(row.product_id) === Number(target.product_id))
|
const card = inventoryCards().find((row) => Number(row.product_id) === Number(target.product_id))
|
||||||
if (card) return formatCard(card)
|
|
||||||
|
|
||||||
// تعدادی: همیشه «عدد» — نه گرم (وزن هر قطعه در فیلد unit محصول است)
|
// اولویت با نوع شارژ (تعدادی) — حتی اگر کارت دارایی اشتباه «گرم» برچسب زده باشد
|
||||||
const isCount =
|
if (isCountChargeTarget(target)) {
|
||||||
target.allows_decimal === false ||
|
const qty = Number(card?.quantity ?? 0)
|
||||||
target.unit === 'عدد' ||
|
return `${qty.toLocaleString('fa-IR', { maximumFractionDigits: 0 })} عدد`
|
||||||
(target.trade_by_quantity === false && !isMeltedTradeGroup(target.group_type))
|
|
||||||
|
|
||||||
if (isCount) {
|
|
||||||
return '۰ عدد'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (card) return formatCard(card)
|
||||||
|
|
||||||
return formatMetalDisplayValue(0, target.metal_id ?? 1)
|
return formatMetalDisplayValue(0, target.metal_id ?? 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,11 +37,12 @@
|
|||||||
v-model:value="modelValue.amountAbs"
|
v-model:value="modelValue.amountAbs"
|
||||||
:addon-before="resolvedUnit"
|
:addon-before="resolvedUnit"
|
||||||
:type="resolvedInputType"
|
:type="resolvedInputType"
|
||||||
:step="integerOnly ? 1 : undefined"
|
:step="requiresInteger ? 1 : undefined"
|
||||||
:place-holder="amountPlaceholder"
|
:place-holder="amountPlaceholder"
|
||||||
|
@onchange="onAmountChange"
|
||||||
/>
|
/>
|
||||||
<div v-if="isMoney && Number(modelValue.amountAbs) > 10" class="wallet-charge-form__hint">
|
<div v-if="isMoney && Number(normalizedAmount) > 10" class="wallet-charge-form__hint">
|
||||||
معادل {{ usePrice(Number(modelValue.amountAbs) / 10, true, 'تومان') }}
|
معادل {{ usePrice(Number(normalizedAmount) / 10, true, 'تومان') }}
|
||||||
</div>
|
</div>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
@@ -84,7 +85,8 @@ const resolvedUnit = computed(
|
|||||||
() => props.unitLabel ?? (props.variant === 'money' ? 'ریال' : 'گرم'),
|
() => props.unitLabel ?? (props.variant === 'money' ? 'ریال' : 'گرم'),
|
||||||
)
|
)
|
||||||
const isMoney = computed(() => props.isMoney ?? props.variant === 'money')
|
const isMoney = computed(() => props.isMoney ?? props.variant === 'money')
|
||||||
const integerOnly = computed(() => props.integerOnly === true)
|
/** نقدی و تعدادی — بدون اعشار */
|
||||||
|
const requiresInteger = computed(() => isMoney.value || props.integerOnly === true)
|
||||||
const resolvedInputType = computed(() => (isMoney.value ? 'price' : 'number'))
|
const resolvedInputType = computed(() => (isMoney.value ? 'price' : 'number'))
|
||||||
const isDischarge = computed(() => props.modelValue.direction === 'discharge')
|
const isDischarge = computed(() => props.modelValue.direction === 'discharge')
|
||||||
|
|
||||||
@@ -114,7 +116,7 @@ const noteLabel = computed(() => (isDischarge.value ? 'علت دشارژ' : 'ع
|
|||||||
|
|
||||||
const amountPlaceholder = computed(() => {
|
const amountPlaceholder = computed(() => {
|
||||||
if (isMoney.value) return 'مثلاً ۱۰۰٬۰۰۰'
|
if (isMoney.value) return 'مثلاً ۱۰۰٬۰۰۰'
|
||||||
if (integerOnly.value) return 'مثلاً ۱'
|
if (requiresInteger.value) return 'مثلاً ۱'
|
||||||
return 'مثلاً ۰.۵'
|
return 'مثلاً ۰.۵'
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -122,16 +124,64 @@ const notePlaceholder = computed(() =>
|
|||||||
isDischarge.value ? 'دلیل کسر موجودی' : 'دلیل افزایش موجودی',
|
isDischarge.value ? 'دلیل کسر موجودی' : 'دلیل افزایش موجودی',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/** ارقام فارسی/عربی → لاتین؛ جداکننده هزار حذف؛ ممیز یکسان */
|
||||||
|
function normalizeAmountRaw(raw: string | number | undefined | null): string {
|
||||||
|
return String(raw ?? '')
|
||||||
|
.trim()
|
||||||
|
.replace(/[۰-۹]/g, (d) => String('۰۱۲۳۴۵۶۷۸۹'.indexOf(d)))
|
||||||
|
.replace(/[٠-٩]/g, (d) => String('٠١٢٣٤٥٦٧٨٩'.indexOf(d)))
|
||||||
|
.replace(/[٬,\s]/g, '')
|
||||||
|
.replace(/٫/g, '.')
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasDecimalSeparator(raw: string): boolean {
|
||||||
|
// بعد از حذف جداکننده هزار، نقطه = اعشار
|
||||||
|
return raw.includes('.')
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseAmount(raw: string | number | undefined | null): number {
|
||||||
|
const normalized = normalizeAmountRaw(raw)
|
||||||
|
if (!normalized) return 0
|
||||||
|
const num = Number(normalized)
|
||||||
|
return Number.isFinite(num) ? Math.abs(num) : NaN
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalizedAmount = computed(() => parseAmount(props.modelValue.amountAbs))
|
||||||
|
|
||||||
|
function onAmountChange(raw: string | number) {
|
||||||
|
if (!requiresInteger.value) return
|
||||||
|
const text = normalizeAmountRaw(raw)
|
||||||
|
if (!hasDecimalSeparator(text)) return
|
||||||
|
// قطع اعشار — فقط بخش صحیح بماند
|
||||||
|
const whole = text.split('.')[0] ?? ''
|
||||||
|
props.modelValue.amountAbs = whole === '' ? undefined : whole
|
||||||
|
}
|
||||||
|
|
||||||
const amountRules = computed(() => [
|
const amountRules = computed(() => [
|
||||||
...inputRules('مقدار'),
|
...inputRules('مقدار'),
|
||||||
{
|
{
|
||||||
validator: (_rule: unknown, value: string | number | undefined) => {
|
validator: (_rule: unknown, value: string | number | undefined) => {
|
||||||
const num = Math.abs(Number(value) || 0)
|
const raw = normalizeAmountRaw(value)
|
||||||
if (!num) {
|
if (!raw) {
|
||||||
return Promise.reject('مقدار باید بیشتر از صفر باشد')
|
return Promise.reject('مقدار باید بیشتر از صفر باشد')
|
||||||
}
|
}
|
||||||
if (integerOnly.value && Math.abs(num - Math.round(num)) > 0.000001) {
|
if (requiresInteger.value && hasDecimalSeparator(raw)) {
|
||||||
return Promise.reject('برای محصول تعدادی فقط عدد صحیح مجاز است')
|
return Promise.reject(
|
||||||
|
isMoney.value
|
||||||
|
? 'برای مبلغ ریالی فقط عدد صحیح مجاز است'
|
||||||
|
: 'برای محصول تعدادی فقط عدد صحیح مجاز است',
|
||||||
|
)
|
||||||
|
}
|
||||||
|
const num = parseAmount(raw)
|
||||||
|
if (!Number.isFinite(num) || !num) {
|
||||||
|
return Promise.reject('مقدار باید بیشتر از صفر باشد')
|
||||||
|
}
|
||||||
|
if (requiresInteger.value && Math.abs(num - Math.round(num)) > 0.000001) {
|
||||||
|
return Promise.reject(
|
||||||
|
isMoney.value
|
||||||
|
? 'برای مبلغ ریالی فقط عدد صحیح مجاز است'
|
||||||
|
: 'برای محصول تعدادی فقط عدد صحیح مجاز است',
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -113,10 +113,11 @@ const targetOptions = computed(() =>
|
|||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
|
|
||||||
/** تعدادی: فقط عدد صحیح — از allows_decimal سرور یا واحد «عدد» */
|
/** تعدادی یا نقدی: فقط عدد صحیح */
|
||||||
const isIntegerOnlyTarget = computed(() => {
|
const isIntegerOnlyTarget = computed(() => {
|
||||||
const target = props.selectedTarget
|
const target = props.selectedTarget
|
||||||
if (!target || target.kind === 'money') return false
|
if (!target) return false
|
||||||
|
if (target.kind === 'money') return true
|
||||||
if (typeof target.allows_decimal === 'boolean') return !target.allows_decimal
|
if (typeof target.allows_decimal === 'boolean') return !target.allows_decimal
|
||||||
if (target.unit === 'عدد') return true
|
if (target.unit === 'عدد') return true
|
||||||
// fallback قبل از آپدیت سرور: تعدادی ≠ آبشده/کاتد
|
// fallback قبل از آپدیت سرور: تعدادی ≠ آبشده/کاتد
|
||||||
|
|||||||
Reference in New Issue
Block a user