changes
This commit is contained in:
@@ -256,7 +256,10 @@ async function update() {
|
||||
if (checkError()) return;
|
||||
if (!record.value.id) {
|
||||
if (record.value.phone) record.value.phone = record.value.phone.trim();
|
||||
let obj = await $getdata("company", { phone: record.value.phone }, undefined, true);
|
||||
const obj = await $getdata("company", {
|
||||
first: true,
|
||||
filter: { phone: record.value.phone },
|
||||
});
|
||||
if (obj) {
|
||||
existedCustomer = obj;
|
||||
errors.phone = "Số điện thoại đã tồn tại trong hệ thống.";
|
||||
@@ -271,7 +274,10 @@ async function update() {
|
||||
if (rs === "error") return;
|
||||
if (!record.value.id) $snackbar(`Khách hàng đã được khởi tạo với mã <b>${rs.code}</b>`, "Success");
|
||||
record.value.id = rs.id;
|
||||
let ele = await $getdata("company", { id: rs.id }, null, true);
|
||||
let ele = await $getdata("company", {
|
||||
first: true,
|
||||
filter: { id: rs.id },
|
||||
});
|
||||
emit("update", ele);
|
||||
emit("modalevent", { name: "dataevent", data: ele });
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,699 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
v-if="!selectedCustomerType && isNewCustomer && !props.customerType"
|
||||
class="p-5"
|
||||
>
|
||||
<h3 class="title is-4 mb-5 has-text-centered">
|
||||
{{ isVietnamese ? "Chọn loại khách hàng" : "Select Customer Type" }}
|
||||
</h3>
|
||||
<div class="columns is-multiline">
|
||||
<div class="column is-6">
|
||||
<button
|
||||
:disabled="!$getEditRights('edit', { code: 'individual', category: 'submenu' })"
|
||||
class="button is-large is-fullwidth"
|
||||
style="height: 120px"
|
||||
@click="selectCustomerType(1)"
|
||||
>
|
||||
<div class="has-text-centered">
|
||||
<div>
|
||||
<SvgIcon v-bind="{ name: 'user.svg', type: 'black', size: 40 }"></SvgIcon>
|
||||
</div>
|
||||
<div class="title is-5 mb-0">
|
||||
{{ isVietnamese ? "Cá nhân" : "Individual" }}
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="column is-6">
|
||||
<button
|
||||
:disabled="!$getEditRights('edit', { code: 'org', category: 'submenu' })"
|
||||
class="button is-large is-fullwidth"
|
||||
style="height: 120px"
|
||||
@click="selectCustomerType(2)"
|
||||
>
|
||||
<div class="has-text-centered">
|
||||
<div>
|
||||
<SvgIcon v-bind="{ name: 'building.svg', type: 'black', size: 40 }"></SvgIcon>
|
||||
</div>
|
||||
<div class="title is-5 mb-0">
|
||||
{{ isVietnamese ? "Tổ chức" : "Organization" }}
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template v-else-if="isLoaded">
|
||||
<div v-if="record && isLoaded">
|
||||
<div class="columns is-multiline">
|
||||
<div class="column is-4">
|
||||
<div class="field">
|
||||
<label class="label"
|
||||
>{{ isIndividual ? "Họ và tên" : "Tên tổ chức" }}<b class="ml-1 has-text-danger">*</b></label
|
||||
>
|
||||
<div class="control">
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
v-model="record.fullname"
|
||||
/>
|
||||
</div>
|
||||
<p
|
||||
class="help is-danger"
|
||||
v-if="errors.fullname"
|
||||
>
|
||||
{{ errors.fullname }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-4">
|
||||
<div class="field">
|
||||
<label class="label"
|
||||
>{{ dataLang && findFieldName("phone_number")[lang] }}<b class="ml-1 has-text-danger">*</b></label
|
||||
>
|
||||
<InputPhone
|
||||
v-bind="{ record: record, attr: 'phone' }"
|
||||
@phone="selected('phone', $event)"
|
||||
></InputPhone>
|
||||
<p
|
||||
class="help is-danger"
|
||||
v-if="errors.phone"
|
||||
>
|
||||
{{ errors.phone }}
|
||||
<a
|
||||
class="has-text-primary"
|
||||
v-if="existedCustomer"
|
||||
@click="showCustomer()"
|
||||
>Chi tiết</a
|
||||
>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-4">
|
||||
<div class="field">
|
||||
<label class="label">Email</label>
|
||||
<InputEmail
|
||||
v-bind="{ record: record, attr: 'email' }"
|
||||
@email="selected('email', $event)"
|
||||
></InputEmail>
|
||||
<p
|
||||
class="help is-danger"
|
||||
v-if="errors.email"
|
||||
>
|
||||
{{ errors.email }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns is-multiline">
|
||||
<div class="column is-6">
|
||||
<div class="field">
|
||||
<label class="label">Địa chỉ liên hệ</label>
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
v-model="record.contact_address"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-6">
|
||||
<div class="field">
|
||||
<label class="label">{{ isIndividual ? "Địa chỉ thường trú" : "Địa chỉ đăng ký" }}</label>
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
v-model="record.address"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="isOrganization"
|
||||
class="columns is-multiline"
|
||||
>
|
||||
<div class="column is-6">
|
||||
<div class="field">
|
||||
<label class="label">Tài khoản ngân hàng</label>
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
v-model="organizationData.bank_account"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-6">
|
||||
<div class="field">
|
||||
<label class="label">Tên ngân hàng</label>
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
v-model="organizationData.bank_name"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="columns is-multiline">
|
||||
<div class="column is-3">
|
||||
<div class="field">
|
||||
<label class="label"
|
||||
>{{ isIndividual ? "Giấy tờ tùy thân" : "Giấy tờ" }}<b class="ml-1 has-text-danger">*</b></label
|
||||
>
|
||||
<SearchBox
|
||||
v-bind="{
|
||||
vdata: filteredLegalTypes,
|
||||
api: 'legaltype',
|
||||
field: isVietnamese ? 'name' : 'en',
|
||||
column: ['name', 'en'],
|
||||
first: true,
|
||||
optionid: record.legal_type,
|
||||
}"
|
||||
@option="selected('legal_type', $event)"
|
||||
></SearchBox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-3">
|
||||
<div class="field">
|
||||
<label class="label"
|
||||
>{{ dataLang && findFieldName("idnum")[lang] }}<b class="ml-1 has-text-danger">*</b></label
|
||||
>
|
||||
<input
|
||||
class="input"
|
||||
type="text"
|
||||
v-model="record.legal_code"
|
||||
/>
|
||||
<p
|
||||
class="help is-danger"
|
||||
v-if="errors.legal_code"
|
||||
>
|
||||
{{ errors.legal_code }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-3">
|
||||
<div class="field">
|
||||
<label class="label"
|
||||
>{{ dataLang && findFieldName("issued_date")[lang] }}<b class="ml-1 has-text-danger">*</b></label
|
||||
>
|
||||
<Datepicker
|
||||
v-bind="{
|
||||
record: record,
|
||||
attr: 'issued_date',
|
||||
maxdate: new Date(),
|
||||
}"
|
||||
@date="selected('issued_date', $event)"
|
||||
></Datepicker>
|
||||
<p
|
||||
class="help is-danger"
|
||||
v-if="errors.issued_date"
|
||||
>
|
||||
{{ errors.issued_date }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-3">
|
||||
<div class="field">
|
||||
<label class="label">{{ dataLang && findFieldName("issued_place")[lang] }}</label>
|
||||
<SearchBox
|
||||
v-bind="{
|
||||
api: 'issuedplace',
|
||||
field: 'name',
|
||||
column: ['name'],
|
||||
first: true,
|
||||
position: 'is-bottom-right',
|
||||
optionid: record.issued_place,
|
||||
filter: { id__in: isIndividual ? [2, 3] : [4, 5] },
|
||||
}"
|
||||
@option="selected('issued_place', $event)"
|
||||
></SearchBox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="columns is-multiline"
|
||||
v-if="isIndividual"
|
||||
>
|
||||
<div class="column is-3">
|
||||
<div class="field">
|
||||
<label class="label">{{ dataLang && findFieldName("gender")[lang] }}</label>
|
||||
<SearchBox
|
||||
v-bind="{
|
||||
vdata: store.sex,
|
||||
api: 'sex',
|
||||
field: isVietnamese ? 'name' : 'en',
|
||||
column: ['name', 'en'],
|
||||
first: true,
|
||||
optionid: individualData.sex,
|
||||
}"
|
||||
@option="selectedIndividual('sex', $event)"
|
||||
></SearchBox>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-3">
|
||||
<div class="field">
|
||||
<label class="label">{{ dataLang && findFieldName("birth_date")[lang] }}</label>
|
||||
<Datepicker
|
||||
v-bind="{
|
||||
record: individualData,
|
||||
attr: 'dob',
|
||||
maxdate: new Date(),
|
||||
}"
|
||||
@date="selectedIndividual('dob', $event)"
|
||||
></Datepicker>
|
||||
<p
|
||||
class="help is-danger"
|
||||
v-if="errors.dob"
|
||||
>
|
||||
{{ errors.dob }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="columns is-multiline">
|
||||
<div class="column is-12">
|
||||
<div class="field">
|
||||
<label class="label">{{ dataLang && findFieldName("note")[lang] }}</label>
|
||||
<textarea
|
||||
class="textarea"
|
||||
v-model="record.note"
|
||||
rows="2"
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-5 mb-4">
|
||||
<h4 class="title is-6 has-text-warning">
|
||||
{{ isIndividual ? "Người liên quan" : "Người đại diện pháp luật" }}
|
||||
</h4>
|
||||
</div>
|
||||
<div
|
||||
class="columns is-multiline mb-0 is-2"
|
||||
v-for="(v, i) in localPeople"
|
||||
:key="i"
|
||||
>
|
||||
<div class="column">
|
||||
<label
|
||||
class="label"
|
||||
v-if="i === 0"
|
||||
>{{ findFieldName("select")[lang] }}</label
|
||||
>
|
||||
<SearchBox
|
||||
v-bind="{
|
||||
api: 'people',
|
||||
field: 'label',
|
||||
column: ['code', 'fullname', 'phone'],
|
||||
first: true,
|
||||
optionid: v.people,
|
||||
position: 'is-top-left',
|
||||
addon: peopleAddon,
|
||||
viewaddon: peopleviewAddon,
|
||||
}"
|
||||
@option="selectPeople($event, v, i)"
|
||||
></SearchBox>
|
||||
</div>
|
||||
<div class="column is-4">
|
||||
<label
|
||||
class="label"
|
||||
v-if="i === 0"
|
||||
>{{ isIndividual ? "Quan hệ" : "Chức vụ" }}</label
|
||||
>
|
||||
<SearchBox
|
||||
v-bind="{
|
||||
api: 'relation',
|
||||
field: store.lang === 'en' ? 'en' : 'name',
|
||||
column: ['code', 'name', 'en'],
|
||||
first: true,
|
||||
optionid: v.relation,
|
||||
position: 'is-top-left',
|
||||
filter: {
|
||||
id__in: isIndividual ? [1, 2, 3, 4, 5, 6, 7, 8] : [9, 10, 11, 12],
|
||||
},
|
||||
}"
|
||||
@option="selectRelation($event, v, i)"
|
||||
/>
|
||||
</div>
|
||||
<div class="column is-narrow">
|
||||
<label
|
||||
class="label"
|
||||
v-if="i === 0"
|
||||
> </label
|
||||
>
|
||||
<div
|
||||
class="buttons is-gap-0.5 is-flex-wrap-nowrap are-small"
|
||||
style="height: 40px"
|
||||
>
|
||||
<button
|
||||
class="button is-dark"
|
||||
@click="add()"
|
||||
>
|
||||
<span class="icon">
|
||||
<SvgIcon v-bind="{ name: 'add4.svg', type: 'white', size: 20 }"></SvgIcon>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="button is-dark"
|
||||
@click="remove(v, i)"
|
||||
>
|
||||
<span class="icon">
|
||||
<SvgIcon v-bind="{ name: 'bin1.svg', type: 'white', size: 20 }"></SvgIcon>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-5 buttons is-right">
|
||||
<button
|
||||
class="button"
|
||||
@click="emit('close')"
|
||||
>
|
||||
{{ isVietnamese ? "Hủy" : "Cancel" }}
|
||||
</button>
|
||||
<button
|
||||
class="button is-primary"
|
||||
@click="update()"
|
||||
>
|
||||
{{ isVietnamese ? "Lưu lại" : "Save" }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<Modal
|
||||
@close="showmodal = undefined"
|
||||
v-bind="showmodal"
|
||||
v-if="showmodal"
|
||||
></Modal>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, watch } from "vue";
|
||||
import { useNuxtApp } from "#app";
|
||||
import InputPhone from "~/components/common/InputPhone";
|
||||
import InputEmail from "~/components/common/InputEmail";
|
||||
import SearchBox from "~/components/SearchBox";
|
||||
import Datepicker from "~/components/datepicker/Datepicker";
|
||||
import { useStore } from "~/stores/index";
|
||||
import { isEqual, pick } from "es-toolkit";
|
||||
|
||||
const emit = defineEmits(["close", "update", "modalevent"]);
|
||||
const { $getdata, $patchapi, $insertapi, $deleteapi, $empty, $errPhone, $resetNull, $snackbar, $copy } = useNuxtApp();
|
||||
|
||||
const props = defineProps({
|
||||
pagename: String,
|
||||
row: Object,
|
||||
application: Object,
|
||||
customerType: Number,
|
||||
});
|
||||
|
||||
const store = useStore();
|
||||
const lang = computed(() => store.lang);
|
||||
const isVietnamese = computed(() => lang.value === "vi");
|
||||
const dataLang = ref(store.common);
|
||||
|
||||
const errors = ref({});
|
||||
const record = ref({});
|
||||
const individualData = ref({});
|
||||
const organizationData = ref({});
|
||||
const isLoaded = ref(false);
|
||||
const isNewCustomer = ref(true);
|
||||
const selectedCustomerType = ref(null);
|
||||
const showmodal = ref();
|
||||
const existedCustomer = ref(undefined);
|
||||
const people = ref([]);
|
||||
const localPeople = ref([]); // { id?: number; people: number; relation: number }[]
|
||||
|
||||
const isIndividual = computed(() => selectedCustomerType.value === 1);
|
||||
const isOrganization = computed(() => selectedCustomerType.value === 2);
|
||||
|
||||
const filteredLegalTypes = computed(() => {
|
||||
if (!store.legaltype) return [];
|
||||
return isOrganization.value
|
||||
? store.legaltype.filter((lt) => lt.id === 4)
|
||||
: store.legaltype.filter((lt) => lt.id !== 4);
|
||||
});
|
||||
|
||||
const peopleAddon = {
|
||||
component: "people/People",
|
||||
width: "65%",
|
||||
height: "500px",
|
||||
title: store.lang === "en" ? "Related person" : "Người liên quan",
|
||||
};
|
||||
const peopleviewAddon = { ...peopleAddon };
|
||||
|
||||
function selectCustomerType(type) {
|
||||
const typeNum = Number(type);
|
||||
selectedCustomerType.value = typeNum;
|
||||
record.value = {
|
||||
fullname: "",
|
||||
phone: "",
|
||||
email: "",
|
||||
country: 1,
|
||||
type: typeNum,
|
||||
legal_type: typeNum === 2 ? 4 : null,
|
||||
creator: store.login.id,
|
||||
updater: store.login.id,
|
||||
};
|
||||
if (typeNum === 1) {
|
||||
individualData.value = { dob: null, sex: 1 };
|
||||
organizationData.value = {};
|
||||
} else {
|
||||
individualData.value = {};
|
||||
organizationData.value = { established_date: null };
|
||||
}
|
||||
people.value = [{}];
|
||||
isLoaded.value = true;
|
||||
}
|
||||
|
||||
function findFieldName(code) {
|
||||
return dataLang.value.find((item) => item.code === code) || { vi: code, en: code };
|
||||
}
|
||||
|
||||
function showCustomer() {
|
||||
showmodal.value = {
|
||||
component: "customer/CustomerView",
|
||||
width: "60%",
|
||||
height: "600px",
|
||||
title: "Khách hàng",
|
||||
vbind: { row: existedCustomer.value },
|
||||
};
|
||||
}
|
||||
|
||||
const selected = (f, v) => {
|
||||
record.value[f] = v && typeof v === "object" ? v.id : v;
|
||||
if (errors.value[f]) delete errors.value[f];
|
||||
};
|
||||
const selectedIndividual = (f, v) => {
|
||||
individualData.value[f] = v && typeof v === "object" ? v.id : v;
|
||||
};
|
||||
const selectedOrg = (f, v) => {
|
||||
organizationData.value[f] = v && typeof v === "object" ? v.id : v;
|
||||
};
|
||||
const selectPeople = (opt, _v, i) => {
|
||||
localPeople.value[i].people = opt.id;
|
||||
};
|
||||
const selectRelation = (opt, _v, i) => {
|
||||
localPeople.value[i].relation = opt ? opt.id : null;
|
||||
};
|
||||
const add = () => localPeople.value.push({});
|
||||
const remove = (_v, i) => {
|
||||
localPeople.value.splice(i, 1);
|
||||
if (localPeople.value.length === 0) localPeople.value = [{}];
|
||||
};
|
||||
|
||||
watch(
|
||||
people,
|
||||
(val) => {
|
||||
localPeople.value = val.map((cp) => pick(cp, ["id", "people", "relation"]));
|
||||
},
|
||||
{ deep: true },
|
||||
);
|
||||
|
||||
function checkError() {
|
||||
errors.value = {};
|
||||
if ($empty(record.value.fullname))
|
||||
errors.value.fullname = isVietnamese.value ? "Họ tên không được bỏ trống" : "Full name is required";
|
||||
if ($empty(record.value.phone)) {
|
||||
errors.value.phone = isVietnamese.value ? "Số điện thoại không được bỏ trống" : "Phone is required";
|
||||
} else {
|
||||
const text = $errPhone(record.value.phone);
|
||||
if (text) errors.value.phone = text;
|
||||
}
|
||||
if ($empty(record.value.legal_code))
|
||||
errors.value.legal_code = isVietnamese.value ? "Mã số không được bỏ trống" : "Legal code is required";
|
||||
if ($empty(record.value.issued_date)) errors.value.issued_date = "Ngày cấp không được bỏ trống";
|
||||
|
||||
return Object.keys(errors.value).length > 0;
|
||||
}
|
||||
|
||||
async function update() {
|
||||
try {
|
||||
if (checkError()) return;
|
||||
|
||||
if (isNewCustomer.value) {
|
||||
if (record.value.phone) {
|
||||
const phoneCheck = await $getdata("customer", { phone: record.value.phone.trim() }, undefined, true);
|
||||
if (phoneCheck) {
|
||||
existedCustomer.value = phoneCheck;
|
||||
errors.value.phone = isVietnamese.value ? "Số điện thoại đã tồn tại." : "Phone already exists.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (record.value.email) {
|
||||
const emailCheck = await $getdata("customer", { email: record.value.email.trim() }, undefined, true);
|
||||
if (emailCheck) {
|
||||
existedCustomer.value = emailCheck;
|
||||
errors.value.email = isVietnamese.value ? "Email đã tồn tại." : "Email already exists.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (record.value.legal_code) {
|
||||
const legalCheck = await $getdata("customer", { legal_code: record.value.legal_code }, undefined, true);
|
||||
if (legalCheck) {
|
||||
errors.value.legal_code = "Số CMND/CCCD đã tồn tại.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let customerData = $resetNull({ ...record.value });
|
||||
customerData.type = selectedCustomerType.value;
|
||||
customerData.updater = store.login.id;
|
||||
customerData.update_time = new Date();
|
||||
|
||||
let res = isNewCustomer.value
|
||||
? await $insertapi("customer", customerData, undefined, false)
|
||||
: await $patchapi("customer", customerData, undefined, false);
|
||||
if (!res || res === "error") return;
|
||||
|
||||
const customerId = res.id;
|
||||
let organizationId = organizationData.value?.id;
|
||||
|
||||
if (isIndividual.value) {
|
||||
let indPayload = $resetNull({ ...individualData.value });
|
||||
indPayload.customer = customerId;
|
||||
if (individualData.value.id)
|
||||
await $patchapi("individual", { ...indPayload, id: individualData.value.id }, undefined, false);
|
||||
else await $insertapi("individual", indPayload, undefined, false);
|
||||
} else if (isOrganization.value) {
|
||||
let orgPayload = $resetNull({ ...organizationData.value });
|
||||
orgPayload.customer = customerId;
|
||||
let orgRes;
|
||||
if (organizationData.value.id) {
|
||||
orgRes = await $patchapi("organization", { ...orgPayload, id: organizationData.value.id }, undefined, false);
|
||||
} else {
|
||||
orgRes = await $insertapi("organization", orgPayload, undefined, false);
|
||||
}
|
||||
if (orgRes && orgRes.id) {
|
||||
organizationId = orgRes.id;
|
||||
}
|
||||
}
|
||||
|
||||
// Người liên quan / Người đại diện
|
||||
const apiName = isIndividual.value ? "customerpeople" : "legalrep";
|
||||
let commonPayload = {};
|
||||
if (isIndividual.value) {
|
||||
commonPayload = { customer: customerId };
|
||||
}
|
||||
if (isOrganization.value && organizationId) {
|
||||
commonPayload = { organization: organizationId };
|
||||
}
|
||||
|
||||
const validLocalPeople = localPeople.value.filter((lp) => lp.people && lp.relation).map((lp) => toRaw(lp));
|
||||
const peopleKeys = people.value.map((p) => pick(p, ["id", "people", "relation"]));
|
||||
|
||||
// 1. check existing ids, if people or relation changes -> patch
|
||||
const existingLocalPeople = validLocalPeople.filter((cp) => Boolean(cp.id));
|
||||
existingLocalPeople.forEach((lp) => {
|
||||
const match = peopleKeys.find((p) => isEqual(p, lp));
|
||||
const payload = { ...lp, ...commonPayload };
|
||||
|
||||
if (!match) {
|
||||
$patchapi(apiName, payload);
|
||||
}
|
||||
});
|
||||
|
||||
// 2. if localPeople has and people doesn't -> insert
|
||||
validLocalPeople.forEach((lp) => {
|
||||
if (!lp.id) {
|
||||
const payload = { ...lp, ...commonPayload };
|
||||
$insertapi(apiName, payload);
|
||||
}
|
||||
});
|
||||
|
||||
// 3. if people has and localPeople doesn't -> delete
|
||||
if (peopleKeys.length !== 0 && validLocalPeople.length !== 0) {
|
||||
peopleKeys.forEach((cp) => {
|
||||
const match = validLocalPeople.find((lp) => cp.id === lp.id);
|
||||
if (!match) {
|
||||
$deleteapi(apiName, cp.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Ảnh
|
||||
if (record.value.image && record.value.image.length > 0) {
|
||||
await $insertapi(
|
||||
"customerfile",
|
||||
record.value.image.map((v) => ({ ref: customerId, file: v })),
|
||||
undefined,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
const completeData = await $getdata("customer", { id: customerId }, undefined, true);
|
||||
|
||||
$snackbar(`Khách hàng đã được ${isNewCustomer.value ? "khởi tạo" : "cập nhật"} thành công`, "Thành công");
|
||||
|
||||
emit("modalevent", { name: "dataevent", data: completeData });
|
||||
emit("update", completeData);
|
||||
setTimeout(() => emit("close"), 100);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
async function initData() {
|
||||
if (props.row && props.row.id) {
|
||||
isNewCustomer.value = false;
|
||||
selectedCustomerType.value = Number(props.row.type);
|
||||
record.value = { ...props.row };
|
||||
if (isIndividual.value) {
|
||||
const ind = await $getdata("individual", { customer: props.row.id }, undefined, true);
|
||||
individualData.value = ind || { dob: null, sex: 1 };
|
||||
const rows = await $getdata("customerpeople", { customer: props.row.id });
|
||||
people.value = rows.length > 0 ? rows : [{}];
|
||||
} else {
|
||||
const org = await $getdata("organization", { customer: props.row.id }, undefined, true);
|
||||
organizationData.value = org || { established_date: null };
|
||||
if (org && org.id) {
|
||||
const rows = await $getdata("legalrep", { organization: org.id });
|
||||
people.value = rows.length > 0 ? rows : [{}];
|
||||
} else {
|
||||
people.value = [{}];
|
||||
}
|
||||
}
|
||||
isLoaded.value = true;
|
||||
} else if (props.application && props.application.id) {
|
||||
const copyData = $copy(props.application);
|
||||
const type = props.customerType || copyData.type || 1;
|
||||
selectCustomerType(type);
|
||||
record.value = {
|
||||
...record.value,
|
||||
...copyData,
|
||||
id: undefined,
|
||||
code: undefined,
|
||||
};
|
||||
individualData.value = { ...individualData.value, ...copyData };
|
||||
} else if (props.customerType) {
|
||||
selectCustomerType(props.customerType);
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => initData());
|
||||
</script>
|
||||
@@ -326,15 +326,22 @@ export default {
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
this.record = await this.$getdata("customer", { id: this.row.customer || this.row.id }, undefined, true);
|
||||
this.record = await this.$getdata("customer", { first: true, filter: { id: this.row.customer || this.row.id } });
|
||||
if (this.isIndividual) {
|
||||
this.relatedPeople = await this.$getdata("customerpeople", {
|
||||
customer: this.row.customer || this.row.id,
|
||||
filter: {
|
||||
customer: this.row.customer || this.row.id,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const org = await this.$getdata("organization", { customer: this.row.customer || this.row.id }, undefined, true);
|
||||
const org = await this.$getdata("organization", {
|
||||
first: true,
|
||||
filter: { customer: this.row.customer || this.row.id },
|
||||
});
|
||||
this.relatedPeople = await this.$getdata("legalrep", {
|
||||
organization: org.id,
|
||||
filter: {
|
||||
organization: org.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -373,17 +380,19 @@ export default {
|
||||
// refetch relatedPeople
|
||||
if (this.isIndividual) {
|
||||
this.relatedPeople = await this.$getdata("customerpeople", {
|
||||
customer: this.row.customer || this.row.id,
|
||||
filter: {
|
||||
customer: this.row.customer || this.row.id,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
const org = await this.$getdata(
|
||||
"organization",
|
||||
{ customer: this.row.customer || this.row.id },
|
||||
undefined,
|
||||
true,
|
||||
);
|
||||
const org = await this.$getdata("organization", {
|
||||
first: true,
|
||||
filter: { customer: this.row.customer || this.row.id },
|
||||
});
|
||||
this.relatedPeople = await this.$getdata("legalrep", {
|
||||
organization: org.id,
|
||||
filter: {
|
||||
organization: org.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -398,7 +407,10 @@ export default {
|
||||
};
|
||||
},
|
||||
async openRelatedPerson(peopleId) {
|
||||
const peopleRow = await this.$getdata("people", { id: peopleId }, undefined, true);
|
||||
const peopleRow = await this.$getdata("people", {
|
||||
first: true,
|
||||
filter: { id: peopleId },
|
||||
});
|
||||
this.showmodal = {
|
||||
component: "people/PeopleView",
|
||||
vbind: { row: peopleRow },
|
||||
|
||||
Reference in New Issue
Block a user