Files
web/app/components/modal/InternalEntry.vue
2026-06-06 16:39:26 +07:00

355 lines
10 KiB
Vue

<template>
<div class="container-fluid">
<div
class="mt-0"
v-if="loading"
>
<p>{{ isVietnamese ? "Đang tải dữ liệu..." : "Loading..." }}</p>
</div>
<div
class="mt-0"
v-else-if="entries.length === 0"
>
<p>{{ isVietnamese ? "Không có dữ liệu" : "No data" }}</p>
</div>
<div v-else>
<div
v-for="(entry, index) in entries"
:key="entry.code || index"
class="entry-item mb-5"
>
<h3 class="title is-5 mb-3">{{ isVietnamese ? "Bút toán" : "Entry" }} #{{ index + 1 }}</h3>
<div class="columns is-multiline mx-0">
<!-- bút toán -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Mã bút toán" : "Code" }}</label>
<div class="control">
<span
class="hyperlink"
@click="$copyToClipboard(entry.code)"
>{{ entry.code }}</span
>
</div>
</div>
</div>
<!-- Ngày bút toán -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Ngày bút toán" : "Date" }}</label>
<div class="control">
<span>{{ entry.date ? $dayjs(entry.date).format("L") : "/" }}</span>
</div>
</div>
</div>
<!-- Amount -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Số tiền" : "Amount" }}</label>
<div class="control">
<span>
{{ $numtoString(entry.amount) }}
</span>
</div>
</div>
</div>
<!-- quỹ -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Mã quỹ" : "Account Code" }}</label>
<div class="control">
<span
class="hyperlink"
@click="$copyToClipboard(entry.account__code)"
>
{{ entry.account__code || "/" }}
</span>
</div>
</div>
</div>
<!-- Tên quỹ -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Tên quỹ" : "Account Type" }}</label>
<div class="control">
<span>{{ entry.account__type__name || "/" }}</span>
</div>
</div>
</div>
<!-- Loại bút toán -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Loại bút toán" : "Category" }}</label>
<div class="control">
<span>{{ entry.category__name || "/" }}</span>
</div>
</div>
</div>
<!-- Loại tiền -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Loại tiền" : "Currency" }}</label>
<div class="control">
<span>{{ entry.account__currency__code || "/" }}</span>
</div>
</div>
</div>
<!-- trước -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Dư trước" : "Balance Before" }}</label>
<div class="control">
<span>
{{ $numtoString(entry.balance_before) }}
</span>
</div>
</div>
</div>
<!-- Ghi -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Ghi có" : "Credit" }}</label>
<div class="control">
<span v-if="entry.type === 1">
{{ $numtoString(entry.amount) }}
</span>
</div>
</div>
</div>
<!-- Trích nợ (Ghi nợ) -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Ghi nợ" : "Debit" }}</label>
<div class="control">
<span v-if="entry.type === 2">
{{ $numtoString(entry.amount) }}
</span>
</div>
</div>
</div>
<!-- sau -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Dư sau" : "Balance After" }}</label>
<div class="control">
<span>
{{ $numtoString(entry.balance_after) }}
</span>
</div>
</div>
</div>
<!-- Loại (Ghi /ghi nợ) -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Loại" : "Type" }}</label>
<div class="control">
<span>{{ entry.type__name || "/" }}</span>
</div>
</div>
</div>
<!-- Người nhập -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Người nhập" : "Inputer" }}</label>
<div class="control">
<span
class="hyperlink"
@click="openUser(entry.inputer)"
>
{{ entry.inputer__fullname || "/" }}
</span>
</div>
</div>
</div>
<!-- Người duyệt -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Người duyệt" : "Approver" }}</label>
<div class="control">
<span
class="hyperlink"
@click="openUser(entry.approver)"
>
{{ entry.approver__fullname || "/" }}
</span>
</div>
</div>
</div>
<!-- Ref -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label"> tham chiếu</label>
<div class="control">
<span>{{ entry.ref || "/" }}</span>
</div>
</div>
</div>
<!-- Thời gian -->
<div class="column is-3 pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Thời gian" : "Create Time" }}</label>
<div class="control">
<span>{{ entry.create_time ? $dayjs(entry.create_time).format("L HH:mm") : "/" }}</span>
</div>
</div>
</div>
<!-- Nội dung -->
<div class="column is-full pb-1 px-0">
<div class="field">
<label class="label">{{ isVietnamese ? "Nội dung" : "Content" }}</label>
<div class="control">
<span>{{ entry.content || "/" }}</span>
</div>
</div>
</div>
</div>
<hr
v-if="index < entries.length - 1"
class="my-4"
/>
</div>
</div>
<Modal
@close="showmodal = undefined"
v-bind="showmodal"
v-if="showmodal"
></Modal>
</div>
</template>
<script>
import { useStore } from "~/stores/index";
export default {
setup() {
const store = useStore();
return { store };
},
props: {
entryList: {
type: Array,
default: () => [],
},
},
data() {
return {
entries: [],
loading: false,
showmodal: undefined,
};
},
computed: {
lang() {
return this.store.lang;
},
isVietnamese() {
return this.store.lang === "vi";
},
},
async created() {
await this.fetchEntries();
},
watch: {
entryList: {
handler() {
this.fetchEntries();
},
deep: true,
},
},
methods: {
parseEntryItem(item) {
// Nếu item đã là object thì return luôn
if (typeof item === "object" && item !== null) {
return item;
}
// Nếu item là string thì parse
if (typeof item === "string") {
try {
// Thay thế single quotes bằng double quotes để parse JSON
const jsonString = item.replace(/'/g, '"');
return JSON.parse(jsonString);
} catch (error) {
console.error("Lỗi khi parse string thành JSON:", item, error);
return null;
}
}
return null;
},
async fetchEntries() {
const { $getdata } = useNuxtApp();
if (!this.entryList || this.entryList.length === 0) {
this.entries = [];
return;
}
this.loading = true;
this.entries = [];
try {
// Duyệt qua từng item trong entryList để fetch dữ liệu
for (const item of this.entryList) {
// Parse item từ string sang object nếu cần
const parsedItem = this.parseEntryItem(item);
if (parsedItem && parsedItem.code) {
try {
const entryData = await $getdata("internalentry", {
first: true,
filter: { code: parsedItem.code },
});
if (entryData) {
this.entries.push(entryData);
}
} catch (error) {
console.error(`Lỗi khi load bút toán với code ${parsedItem.code}:`, error);
}
}
}
console.log(`Đã load ${this.entries.length} bút toán thành công`);
} catch (error) {
console.error("Lỗi khi load danh sách bút toán:", error);
} finally {
this.loading = false;
}
},
openUser(userId) {
if (!userId) return;
this.showmodal = {
component: "user/UserInfo",
width: "50%",
height: "200px",
title: "User",
vbind: { userId: userId },
};
},
},
};
</script>