more bug fix in cost mod

This commit is contained in:
Hesabix 2025-04-04 20:07:58 +00:00
parent 77977b54a5
commit 2ac59fa0c7
4 changed files with 97 additions and 132 deletions

View file

@ -1,115 +1,83 @@
<template> <template>
<v-text-field <v-text-field
v-model="formattedValue" v-model="inputValue"
v-bind="$attrs" v-bind="$attrs"
type="text" type="text"
:rules="combinedRules" :rules="combinedRules"
@keypress="handleKeypress" @keypress="restrictToNumbers"
@input="syncValue" dir="ltr"
dir="ltr" dense
dense />
/> </template>
</template>
<script>
<script> export default {
export default { name: 'HNumberInput',
name: 'Hnumberinput', inheritAttrs: false,
inheritAttrs: false,
props: {
props: { modelValue: {
modelValue: { type: [Number, String],
type: [Number, String], default: null
default: null
},
rules: {
type: Array,
default: () => []
}
}, },
rules: {
data() { type: Array,
return { default: () => []
internalValue: '' // مقدار خام به صورت رشته }
} },
},
data() {
computed: { return {
formattedValue() { inputValue: ''
if (!this.internalValue) return '' }
return Number(this.internalValue).toLocaleString('fa-IR') },
},
combinedRules() { computed: {
return [ combinedRules() {
v => !v || !isNaN(this.normalizeNumber(v)) || 'فقط عدد مجاز است', return [
...this.rules v => !v || /^\d+$/.test(v.replace(/[^0-9]/g, '')) || 'فقط عدد انگلیسی مجاز است',
] ...this.rules
} ]
}, }
},
watch: {
modelValue(newVal) { watch: {
this.internalValue = newVal !== null && newVal !== undefined ? String(newVal) : '' modelValue: {
} immediate: true,
}, handler(newVal) {
if (newVal !== null && newVal !== undefined) {
mounted() { const cleaned = String(newVal).replace(/[^0-9]/g, '')
this.internalValue = this.modelValue !== null && this.modelValue !== undefined ? String(this.modelValue) : '' this.inputValue = cleaned ? Number(cleaned).toLocaleString('en-US') : ''
}, } else {
this.inputValue = ''
methods: {
normalizeNumber(value) {
if (!value) return ''
let result = value.toString()
const persianNumbers = [/۰/g, /۱/g, /۲/g, /۳/g, /۴/g, /۵/g, /۶/g, /۷/g, /۸/g, /۹/g]
const arabicNumbers = [/٠/g, /١/g, /٢/g, /٣/g, /٤/g, /٥/g, /٦/g, /٧/g, /٨/g, /٩/g]
for (let i = 0; i < 10; i++) {
result = result.replace(persianNumbers[i], i).replace(arabicNumbers[i], i)
} }
return result.replace(/[^0-9]/g, '') }
}, },
inputValue(newVal) {
handleKeypress(event) { if (newVal === '' || newVal === null || newVal === undefined) {
event.preventDefault() // جلوگیری از رفتار پیشفرض برای کنترل کامل this.$emit('update:modelValue', 0) // وقتی خالی است، صفر ارسال شود
const charCode = event.charCode } else {
const char = String.fromCharCode(charCode) const cleaned = String(newVal).replace(/[^0-9]/g, '')
const numericValue = cleaned ? Number(cleaned) : 0
// فقط اعداد رو قبول کن this.$emit('update:modelValue', numericValue)
if (charCode >= 48 && charCode <= 57) { // اعداد انگلیسی }
const newValue = this.internalValue + char }
const normalized = this.normalizeNumber(newValue) },
this.internalValue = normalized
this.$emit('update:modelValue', normalized ? Number(normalized) : null) methods: {
} else if (charCode >= 1632 && charCode <= 1641) { // اعداد عربی restrictToNumbers(event) {
const arabicToEnglish = String.fromCharCode(charCode - 1584) const charCode = event.charCode
const newValue = this.internalValue + arabicToEnglish if (charCode < 48 || charCode > 57) {
const normalized = this.normalizeNumber(newValue) event.preventDefault()
this.internalValue = normalized
this.$emit('update:modelValue', normalized ? Number(normalized) : null)
} else if (charCode >= 1776 && charCode <= 1785) { // اعداد فارسی
const persianToEnglish = String.fromCharCode(charCode - 1728)
const newValue = this.internalValue + persianToEnglish
const normalized = this.normalizeNumber(newValue)
this.internalValue = normalized
this.$emit('update:modelValue', normalized ? Number(normalized) : null)
}
},
syncValue(event) {
const rawInput = event.target.value
const normalized = this.normalizeNumber(rawInput)
this.internalValue = normalized
this.$emit('update:modelValue', normalized ? Number(normalized) : null)
this.$nextTick(() => {
event.target.value = this.formattedValue
})
} }
} }
} }
</script> }
</script>
<style scoped>
:deep(.v-text-field input) { <style scoped>
direction: ltr; :deep(.v-text-field input) {
text-align: left; direction: ltr;
} text-align: left;
</style> }
</style>

View file

@ -496,7 +496,6 @@ export default {
this.totalItems = 0; this.totalItems = 0;
} }
console.log('آیتم‌های ذخیره شده:', this.items);
if (this.modelValue) { if (this.modelValue) {
if (this.returnObject) { if (this.returnObject) {
@ -506,7 +505,6 @@ export default {
} }
} }
} catch (error) { } catch (error) {
console.error('خطا در دریافت داده‌ها:', error);
this.showMessage('خطا در بارگذاری داده‌ها', 'error'); this.showMessage('خطا در بارگذاری داده‌ها', 'error');
this.items = []; this.items = [];
this.totalItems = 0; this.totalItems = 0;

View file

@ -146,12 +146,11 @@
<template #expanded-row="{ columns, item }"> <template #expanded-row="{ columns, item }">
<tr> <tr>
<td :colspan="columns.length" class="expanded-row"> <td :colspan="columns.length" class="expanded-row">
<v-container> <v-container class="pa-0 ma-0">
<v-row> <v-row>
<v-col cols="12"> <v-col cols="12">
<h4>مراکز هزینه</h4> <v-list density="compact" class="pa-0 ma-0">
<v-list dense> <v-list-item :border="true" v-for="(center, index) in item.costCenters" :key="index">
<v-list-item v-for="(center, index) in item.costCenters" :key="index">
<v-list-item-title> <v-list-item-title>
{{ center.name }} {{ center.name }}
{{ $t('dialog.acc_price') }} : {{ $filters.formatNumber(center.amount) }} {{ $t('dialog.acc_price') }} : {{ $filters.formatNumber(center.amount) }}

View file

@ -88,7 +88,7 @@
<!-- مرکز هزینه --> <!-- مرکز هزینه -->
<template v-for="(item, index) in costs" :key="'cost'+index"> <template v-for="(item, index) in costs" :key="'cost'+index">
<v-card class="mb-4"> <v-card class="mb-4">
<v-toolbar color="grey-darken-3" density="compact"> <v-toolbar color="primary" density="compact">
<v-toolbar-title class="text-white text--secondary"> <v-toolbar-title class="text-white text--secondary">
<span class="text-error me-2">{{ index + 1 }}</span> <span class="text-error me-2">{{ index + 1 }}</span>
<v-icon color="white">mdi-ticket</v-icon> <v-icon color="white">mdi-ticket</v-icon>
@ -130,7 +130,7 @@
<!-- حساب بانکی --> <!-- حساب بانکی -->
<template v-for="(item, index) in banks" :key="'bank'+index"> <template v-for="(item, index) in banks" :key="'bank'+index">
<v-card class="mb-4"> <v-card class="mb-4">
<v-toolbar color="grey-lighten-3" density="compact"> <v-toolbar color="grey-lighten-2" density="compact">
<v-toolbar-title> <v-toolbar-title>
<span class="me-2">{{ index + 1 }}</span> <span class="me-2">{{ index + 1 }}</span>
<v-icon>mdi-bank</v-icon> <v-icon>mdi-bank</v-icon>
@ -408,20 +408,20 @@ export default {
calc() { calc() {
this.sum = 0; this.sum = 0;
this.costs.forEach((item) => { this.costs.forEach((item) => {
this.sum = parseInt(this.sum) + parseInt(item.amount); this.sum = parseInt(this.sum) + (parseInt(item.amount) || 0);
}); });
let side = 0; let side = 0;
this.banks.forEach((item) => { this.banks.forEach((item) => {
side = parseInt(side) + parseInt(item.amount); side = parseInt(side) + (parseInt(item.amount) || 0);
}); });
this.salarys.forEach((item) => { this.salarys.forEach((item) => {
side = parseInt(side) + parseInt(item.amount); side = parseInt(side) + (parseInt(item.amount) || 0);
}); });
this.cashdesks.forEach((item) => { this.cashdesks.forEach((item) => {
side = parseInt(side) + parseInt(item.amount); side = parseInt(side) + (parseInt(item.amount) || 0);
}); });
this.persons.forEach((item) => { this.persons.forEach((item) => {
side = parseInt(side) + parseInt(item.amount); side = parseInt(side) + (parseInt(item.amount) || 0);
}); });
this.balance = parseInt(this.sum) - parseInt(side); this.balance = parseInt(this.sum) - parseInt(side);
@ -471,7 +471,6 @@ export default {
addSalary() { addSalary() {
this.salarys.push({ this.salarys.push({
id: '', id: '',
salary: null,
amount: '', amount: '',
des: '' des: ''
}) })
@ -513,14 +512,14 @@ export default {
} }
else if (item.type == 'bank') { else if (item.type == 'bank') {
this.banks.push({ this.banks.push({
id: item.bank, id: item.bank.id,
amount: item.bs, amount: item.bs,
des: item.des des: item.des
}); });
} }
else if (item.type == 'cashdesk') { else if (item.type == 'cashdesk') {
this.cashdesks.push({ this.cashdesks.push({
id: item.cashdesk, person: item.cashdesk.id,
amount: item.bs, amount: item.bs,
des: item.des des: item.des
}); });
@ -528,7 +527,6 @@ export default {
else if (item.type == 'salary') { else if (item.type == 'salary') {
this.salarys.push({ this.salarys.push({
id: item.salary.id, id: item.salary.id,
salary: item.salary,
amount: item.bs, amount: item.bs,
des: item.des des: item.des
}); });
@ -542,6 +540,7 @@ export default {
}); });
} }
}) })
this.calc();
}); });
} }
else { else {
@ -601,20 +600,20 @@ export default {
} }
}); });
this.salarys.forEach((item) => { this.salarys.forEach((item) => {
if (item.person == null || item.person == '') { if (item.id == null || item.id == '') {
sideOK = false; sideOK = false;
} }
}) });
this.cashdesks.forEach((item) => { this.cashdesks.forEach((item) => {
if (item.person == null || item.person == '') { if (item.person == null || item.person == '') {
sideOK = false; sideOK = false;
} }
}) });
this.persons.forEach((item) => { this.persons.forEach((item) => {
if (item.id == null || item.id == '') { if (item.id == null || item.id == '') {
sideOK = false; sideOK = false;
} }
}) });
if (sideOK == false) { if (sideOK == false) {
Swal.fire({ Swal.fire({
text: 'یکی از طرف‌های حساب انتخاب نشده است.', text: 'یکی از طرف‌های حساب انتخاب نشده است.',
@ -666,12 +665,13 @@ export default {
this.salarys.forEach((item) => { this.salarys.forEach((item) => {
if (item.des == '') item.des = 'هزینه' if (item.des == '') item.des = 'هزینه'
rows.push({ rows.push({
id: item.person, id: item.id,
bs: parseInt(item.amount), bs: parseInt(item.amount),
bd: 0, bd: 0,
des: item.des, des: item.des,
type: 'salary', type: 'salary',
table: 124 table: 124,
salary: this.listSalarys.find(s => s.id === item.id)
}); });
}) })