Merge branch 'ASTRA-48' into 'master'

WIP Исправлены проверки

See merge request andrusyakka/urban-couscous!326
This commit is contained in:
Daria Golova
2023-04-20 18:33:25 +00:00
5 changed files with 144 additions and 133 deletions

View File

@@ -1,9 +1,10 @@
<template lang="pug"> <template lang="pug">
base-input-container.gap-y-2(:label="label") base-input-container.gap-y-2(:label="label", :style="{width: width + 'px' }")
q-input( q-input(
v-model="value", v-model="value",
:name="name",
:class="{'circle': circle, 'font-input': true}", :class="{'circle': circle, 'font-input': true}",
:input-style="{ color: textColor, width: width + 'px' , borderColor: borderColor}", :input-style="{ color: textColor, borderColor: borderColor}",
:borderless="borderless", :borderless="borderless",
:placeholder="placeholder", :placeholder="placeholder",
:outlined="outlined", :outlined="outlined",
@@ -11,7 +12,6 @@
:type="type", :type="type",
:readonly="readonly", :readonly="readonly",
:disable="disabled", :disable="disabled",
:name="name"
:filled="filled", :filled="filled",
:bg-color="filled || standout ? '' : 'white'", :bg-color="filled || standout ? '' : 'white'",
:rules="rule", :rules="rule",

View File

@@ -7,7 +7,7 @@
:open-edit="openEdit", :open-edit="openEdit",
:save="saveChange" :save="saveChange"
) )
.form-wrap.gap-24.w-full q-form.form-wrap.gap-24.w-full(ref="documentForm", :no-error-focus="true")
.data-section.flex.flex-col.gap-4(v-for="data in configData", :key="data.dataLabel") .data-section.flex.flex-col.gap-4(v-for="data in configData", :key="data.dataLabel")
.font-semibold.text-sm.whitespace-nowrap {{data.dataLabel}} .font-semibold.text-sm.whitespace-nowrap {{data.dataLabel}}
.flex.w-full.justify-between.items-center.gap-4( .flex.w-full.justify-between.items-center.gap-4(
@@ -16,11 +16,22 @@
) )
.label-field.font-sm.text-sm.whitespace-nowrap {{`${field.label} :`}} .label-field.font-sm.text-sm.whitespace-nowrap {{`${field.label} :`}}
.photo-field.flex.gap-3.items-center(v-if="field.type === 'photo'") .photo-field.flex.gap-3.items-center(v-if="field.type === 'photo'")
img.h-10.w-10.object-cover( q-avatar(
v-if="docData[data.dataKey][field.key]?.photo", square,
:src="docData[data.dataKey][field.key]?.photo", size="40px",
:alt="docData[data.dataKey][field.label]", v-if="docData[data.dataKey][field.key]?.photo"
) )
img.h-10.w-10.object-cover(
:src="docData[data.dataKey][field.key]?.photo",
:alt="docData[data.dataKey][field.label]"
)
q-badge.delete(
floating,
v-if="isEdit",
rounded,
@click="removeImage(data?.dataKey, field?.key)"
)
q-icon(name="app:icon-cancel", size="8px")
.replace-photo.font-medium.text-base.cursor-pointer( .replace-photo.font-medium.text-base.cursor-pointer(
v-if="isEdit", v-if="isEdit",
@click="openModal(data.dataKey)", @click="openModal(data.dataKey)",
@@ -33,15 +44,17 @@
base-input( base-input(
v-else, v-else,
v-model="docData[data.dataKey][field.key]", v-model="docData[data.dataKey][field.key]",
@update:model-value="checkChangeDocData" :name="field.key",
@update:model-value="checkChangeDocData",
:readonly="!isEdit", :readonly="!isEdit",
:type="field.type", :type="field.type",
textColor="var(--font-dark-blue-color)" textColor="var(--font-dark-blue-color)",
:width="checkCopiedFields(field.key) ? 260 : 278", :width="302",
:standout="!isEdit", :standout="!isEdit",
:outlined="isEdit", :outlined="isEdit",
:mask="field?.inputMask",
:rule="field.rules", :rule="field.rules",
:mask="field?.inputMask" :autogrow="field.key === 'issued_by_org'"
) )
.icon-copy.my-auto.text-lg.label-field( .icon-copy.my-auto.text-lg.label-field(
v-if="checkCopiedFields(field.key)", v-if="checkCopiedFields(field.key)",
@@ -56,9 +69,11 @@ import BaseInput from "@/components/base/BaseInput.vue";
import BaseAvatar from "@/components/base/BaseAvatar.vue"; import BaseAvatar from "@/components/base/BaseAvatar.vue";
import BaseModal from "@/components/base/BaseModal.vue"; import BaseModal from "@/components/base/BaseModal.vue";
import BaseUploadPhoto from "@/components/base/BaseUploadPhoto.vue"; import BaseUploadPhoto from "@/components/base/BaseUploadPhoto.vue";
import { checkChangeData } from "@/shared/utils/changesObjects.js"; import {
checkChangeData,
getFieldsNameUnvalidated,
} from "@/shared/utils/changesObjects.js";
import { fetchWrapper } from "@/shared/fetchWrapper.js"; import { fetchWrapper } from "@/shared/fetchWrapper.js";
import * as moment from "moment/moment";
import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider"; import TheNotificationProvider from "@/components/Notifications/TheNotificationProvider";
import { addNotification } from "@/components/Notifications/notificationContext"; import { addNotification } from "@/components/Notifications/notificationContext";
export default { export default {
@@ -103,6 +118,7 @@ export default {
photo_tax_identification_number: null, photo_tax_identification_number: null,
}, },
}, },
personDataField: ["insurance_number", "tax_identification_number"],
showModal: false, showModal: false,
photoId: "", photoId: "",
}; };
@@ -113,6 +129,10 @@ export default {
}, },
}, },
methods: { methods: {
removeImage(docKey, field) {
this.docData[docKey][field] = {};
this.isCheckChange = true;
},
copyValue(text) { copyValue(text) {
navigator.clipboard.writeText(text); navigator.clipboard.writeText(text);
}, },
@@ -141,103 +161,74 @@ export default {
this.isCheckChange = true; this.isCheckChange = true;
}, },
saveChange() { saveChange() {
this.updateDocData(); const form = this.$refs.documentForm;
}, form.validate().then((validate) => {
updateDocData() { if (!validate) {
let { insurance_number: insurance, tax_identification_number: tax } = getFieldsNameUnvalidated(form).forEach((elem) => {
this.docData; let error = {};
let passport = JSON.parse(JSON.stringify(this.docData.passport)); this.configData.forEach(({ fields }) => {
passport.issued_by_date = moment(passport.issued_by_date).format( let findedElem = fields.find((el) => el.key === elem);
"YYYY-MM-DD" if (findedElem) error = findedElem?.errorMessage;
); });
passport.photo = this.docData.passport.photo; this.addErrorNotification(error?.title, error?.message);
let initData = JSON.parse(JSON.stringify(this.initialDocData)); });
initData.passport.issued_by_date = moment( this.cancelEdit();
initData.passport.issued_by_date } else {
).format("YYYY-MM-DD"); let passportFormData = new FormData();
let documentsFormData = new FormData(); let documentsFormData = new FormData();
let passportFormData = new FormData(); form.getValidationComponents().forEach((elem) => {
this.fillResultData(initData, passport, "passport", passportFormData); if (!this.personDataField.includes(elem.name))
this.fillResultData( passportFormData.append(elem.name, elem.modelValue ?? "");
initData, else documentsFormData.append(elem.name, elem.modelValue ?? "");
insurance, });
"insurance_number", this.checkChengePhoto("passport", "photo", passportFormData);
documentsFormData this.checkChengePhoto(
); "insurance_number",
this.fillResultData( "photo_insurance_number",
initData, documentsFormData
tax, );
"tax_identification_number", this.checkChengePhoto(
documentsFormData "tax_identification_number",
); "photo_tax_identification_number",
let request = []; documentsFormData
if (!passport.id) );
request.push( let request = [];
this.sendData("general/identity_document/create/", passportFormData) if (!this.initialDocData.passport?.id) {
); passportFormData.append("kind", "PASSPORT");
else passportFormData.append(
request.push( "person",
this.sendData( this.$store.state.medical?.basicData?.personalData?.id
`general/identity_document/${passport.id}/update/`,
passportFormData
)
);
request.push(
this.sendData(
`general/person/${this.$store.state.medical?.basicData?.personalData?.id}/update/`,
documentsFormData
)
);
Promise.allSettled(request).then(() => {
this.$store.dispatch("getMedicalCardData");
this.isEdit = false;
this.isCheckChange = false;
});
},
fillResultData(initObj, updateObj, id, formData) {
Object.keys(updateObj).forEach((key) => {
let config = this.configData
.find(({ dataKey }) => dataKey === id)
?.fields.find((el) => el.key === key);
if (
config?.type === "photo" &&
this.checkChengePhoto(initObj[id], updateObj, key)
) {
if (config.inputMask && !config.checkField(updateObj[key])) {
this.addErrorNotification(
config.errorMessage.title,
config.errorMessage.message
); );
return; request.push(
} this.sendData(
formData.append(key, updateObj[key]?.file[0]); "general/identity_document/create/",
return; passportFormData
} )
if (
config?.type !== "photo" &&
this.checkChangeField(initObj[id], updateObj, key)
) {
if (config.inputMask && !config.checkField(updateObj[key])) {
this.addErrorNotification(
config.errorMessage.title,
config.errorMessage.message
); );
return; } else
} request.push(
formData.append(key, updateObj[key]); this.sendData(
return; `general/identity_document/${this.initialDocData.passport?.id}/update/`,
passportFormData
)
);
request.push(
this.sendData(
`general/person/${this.$store.state.medical?.basicData?.personalData?.id}/update/`,
documentsFormData
)
);
Promise.allSettled(request).then(() => {
this.$store.dispatch("getMedicalCardData");
this.isEdit = false;
this.isCheckChange = false;
});
} }
}); });
return;
}, },
checkChangeField(initObj, updatedObj, field) { checkChengePhoto(updatedObjId, field, formData) {
return updatedObj[field] && initObj[field] !== updatedObj[field]; if (this.docData[updatedObjId][field]?.file)
}, formData.append(field, this.docData[updatedObjId][field]?.file[0]);
checkChengePhoto(initObj, updatedObj, field) {
return (
updatedObj[field]?.file &&
initObj[field]?.photo !== updatedObj[field]?.photo
);
}, },
async sendData(url, body) { async sendData(url, body) {
return await fetchWrapper.post(url, body, "formData"); return await fetchWrapper.post(url, body, "formData");
@@ -280,4 +271,9 @@ export default {
min-width: 302px min-width: 302px
.icon-copy .cursor .icon-copy .cursor
cursor: pointer !important cursor: pointer !important
.q-badge
padding: 4px
cursor: pointer
.delete
background-color: var(--btn-red-color)
</style> </style>

View File

@@ -3,6 +3,8 @@ import {
ruleEmailValue, ruleEmailValue,
ruleMaxLength, ruleMaxLength,
ruleNotValue, ruleNotValue,
ruleDateValue,
ruleOptionalFields,
} from "@/shared/utils/rulesInputs"; } from "@/shared/utils/rulesInputs";
export const baseDataForm = [ export const baseDataForm = [
@@ -369,49 +371,53 @@ export const documentForm = [
label: "Серия", label: "Серия",
type: "text", type: "text",
inputMask: "####", inputMask: "####",
checkField: (field) => {
return field.length === 4;
},
errorMessage: { errorMessage: {
title: "Ошибка валидации", title: "Ошибка валидации",
message: "Серия паспорта заполнена неправильно", message: "Серия паспорта менее 4 цифр или не заполнена",
}, },
rules: [(val) => ruleLengthValue(val, 4)],
}, },
{ {
key: "number", key: "number",
label: "Номер", label: "Номер",
type: "text", type: "text",
inputMask: "######", inputMask: "######",
checkField: (field) => {
return field.length === 6;
},
errorMessage: { errorMessage: {
title: "Ошибка валидации", title: "Ошибка валидации",
message: "Номер паспорта заполнен неправильно", message: "Номер паспорта менее 6 цифр или не заполнен",
}, },
rules: [(val) => ruleLengthValue(val, 6)],
}, },
{ {
key: "issued_by_org", key: "issued_by_org",
label: "Кем выдан", label: "Кем выдан",
type: "text", type: "text",
errorMessage: {
title: "Ошибка валидации",
message: "Поле 'Кем выдан' не заполнено",
},
rules: [(val) => ruleNotValue(val)],
}, },
{ {
key: "issued_by_org_code", key: "issued_by_org_code",
label: "Код подраздел.", label: "Код подраздел.",
type: "text", type: "text",
inputMask: "###-###", inputMask: "###-###",
checkField: (field) => {
return field.length === 7;
},
errorMessage: { errorMessage: {
title: "Ошибка валидации", title: "Ошибка валидации",
message: "Код подразделения заполнен неправильно", message: "Код подразделения менее 6 цифр или не заполнен",
}, },
rules: [(val) => ruleLengthValue(val, 7)],
}, },
{ {
key: "issued_by_date", key: "issued_by_date",
label: "Дата выдачи", label: "Дата выдачи",
type: "date", type: "date",
rules: [(val) => ruleDateValue(val)],
errorMessage: {
title: "Ошибка валидации",
message: "Дата выдачи паспорта позднее текущего дня",
},
}, },
{ {
key: "photo", key: "photo",
@@ -429,13 +435,11 @@ export const documentForm = [
label: "Номер СНИЛС", label: "Номер СНИЛС",
type: "text", type: "text",
inputMask: "###-###-### ##", inputMask: "###-###-### ##",
checkField: (field) => {
return field.length === 14;
},
errorMessage: { errorMessage: {
title: "Ошибка валидации", title: "Ошибка валидации",
message: "СНИЛС заполнен неправильно", message: "СНИЛС содержит менее 11 цифр",
}, },
rules: [(val) => ruleOptionalFields(val, 14)],
}, },
{ {
key: "photo_insurance_number", key: "photo_insurance_number",
@@ -453,13 +457,11 @@ export const documentForm = [
label: "Номер ИНН", label: "Номер ИНН",
type: "text", type: "text",
inputMask: "############", inputMask: "############",
checkField: (field) => {
return field.length === 12;
},
errorMessage: { errorMessage: {
title: "Ошибка валидации", title: "Ошибка валидации",
message: "ИНН заполнен неправильно", message: "ИНН содержит менее 12 цифр",
}, },
rules: [(val) => ruleOptionalFields(val, 12)],
}, },
{ {
key: "photo_tax_identification_number", key: "photo_tax_identification_number",

View File

@@ -1,3 +1,4 @@
import * as moment from "moment/moment";
export function ruleNotValue(val, text) { export function ruleNotValue(val, text) {
return !!val || text || false; return !!val || text || false;
} }
@@ -6,6 +7,10 @@ export function ruleLengthValue(val, minLength, text) {
return (val && val.length === minLength) || text || false; return (val && val.length === minLength) || text || false;
} }
export function ruleOptionalFields(val, minLength, text) {
return !val || val.length === minLength || text || false;
}
export function ruleEmailValue(val, text) { export function ruleEmailValue(val, text) {
return ( return (
(val && (val &&
@@ -21,3 +26,11 @@ export function ruleEmailValue(val, text) {
export function ruleMaxLength(val, maxLength, text) { export function ruleMaxLength(val, maxLength, text) {
return (!!val && val.length <= maxLength) || text || false; return (!!val && val.length <= maxLength) || text || false;
} }
export function ruleDateValue(val, text) {
return (
(val && !moment(val).isAfter(moment().format("YYYY-MM-DD"))) ||
text ||
false
);
}

View File

@@ -147,11 +147,11 @@ const getters = {
); );
return { return {
passport: { passport: {
id: passport?.id, id: passport?.id ?? "",
series: passport?.series, series: passport?.series ?? "",
number: passport?.number, number: passport?.number ?? "",
issued_by_org: passport?.issued_by_org, issued_by_org: passport?.issued_by_org ?? "",
issued_by_org_code: passport?.issued_by_org_code, issued_by_org_code: passport?.issued_by_org_code ?? "",
issued_by_date: passport?.issued_by_date issued_by_date: passport?.issued_by_date
? new Date(passport?.issued_by_date) ? new Date(passport?.issued_by_date)
: null, : null,
@@ -163,7 +163,7 @@ const getters = {
: {}, : {},
}, },
insurance_number: { insurance_number: {
insurance_number: person?.insurance_number, insurance_number: person?.insurance_number ?? "",
photo_insurance_number: person?.photo_insurance_number photo_insurance_number: person?.photo_insurance_number
? { ? {
photo: rootState.getUrl + person.photo_insurance_number, photo: rootState.getUrl + person.photo_insurance_number,
@@ -172,7 +172,7 @@ const getters = {
: {}, : {},
}, },
tax_identification_number: { tax_identification_number: {
tax_identification_number: person?.tax_identification_number, tax_identification_number: person?.tax_identification_number ?? "",
photo_tax_identification_number: person?.photo_tax_identification_number photo_tax_identification_number: person?.photo_tax_identification_number
? { ? {
photo: rootState.getUrl + person?.photo_tax_identification_number, photo: rootState.getUrl + person?.photo_tax_identification_number,