2
0
mirror of https://github.com/frappe/books.git synced 2024-12-22 10:58:59 +00:00

fix: support option field value or label

- remove address placeholder
- allow more types of entries to be imported
This commit is contained in:
18alantom 2023-02-15 19:19:17 +05:30
parent aa04e1493c
commit 48797dff62
7 changed files with 74 additions and 20 deletions

View File

@ -73,7 +73,6 @@
"label": "Address",
"fieldtype": "Link",
"target": "Address",
"placeholder": "Click to create",
"inline": true
},
{

View File

@ -40,7 +40,6 @@
"label": "Address",
"fieldtype": "Link",
"target": "Address",
"placeholder": "Click to create",
"inline": true
},
{

View File

@ -16,7 +16,6 @@
"label": "Address",
"fieldtype": "Link",
"target": "Address",
"placeholder": "Click to create",
"inline": true
}
],

View File

@ -73,7 +73,6 @@
"label": "Address",
"fieldtype": "Link",
"target": "Address",
"placeholder": "Click to create",
"inline": true
}
],

View File

@ -8,13 +8,17 @@ import {
Field,
FieldType,
FieldTypeEnum,
OptionField,
RawValue,
Schema,
TargetField,
} from 'schemas/types';
import { generateCSV, parseCSV } from 'utils/csvParser';
import { getValueMapFromList } from 'utils/index';
export type TemplateField = Field & {
export type TemplateField = Field & TemplateFieldProps;
type TemplateFieldProps = {
schemaName: string;
schemaLabel: string;
fieldKey: string;
@ -82,6 +86,15 @@ export class Importer {
*/
docs: Doc[];
/**
* Used if an options field is imported where the import data
* provided maybe the label and not the value
*/
optionsMap: {
values: Record<string, Set<string>>;
labelValueMap: Record<string, Record<string, string>>;
};
constructor(schemaName: string, fyo: Fyo) {
if (!fyo.schemaMap[schemaName]) {
throw new ValidationError(
@ -94,6 +107,10 @@ export class Importer {
this.fyo = fyo;
this.docs = [];
this.valueMatrix = [];
this.optionsMap = {
values: {},
labelValueMap: {},
};
const templateFields = getTemplateFields(schemaName, fyo, this);
this.assignedTemplateFields = templateFields.map((f) => f.fieldKey);
@ -423,6 +440,10 @@ export class Importer {
return vmi;
}
if ('options' in tf && typeof vmi.rawValue === 'string') {
return this.getOptionFieldVmi(vmi, tf);
}
try {
vmi.value = Converter.toDocValue(rawValue, tf, this.fyo);
} catch {
@ -432,6 +453,39 @@ export class Importer {
return vmi;
}
getOptionFieldVmi(
{ rawValue }: ValueMatrixItem,
tf: OptionField & TemplateFieldProps
): ValueMatrixItem {
if (typeof rawValue !== 'string') {
return { error: true, value: null, rawValue };
}
if (!tf?.options.length) {
return { value: null, rawValue };
}
if (!this.optionsMap.labelValueMap[tf.fieldKey]) {
const values = new Set(tf.options.map(({ value }) => value));
const labelValueMap = getValueMapFromList(tf.options, 'label', 'value');
this.optionsMap.labelValueMap[tf.fieldKey] = labelValueMap;
this.optionsMap.values[tf.fieldKey] = values;
}
const hasValue = this.optionsMap.values[tf.fieldKey].has(rawValue);
if (hasValue) {
return { value: rawValue, rawValue };
}
const value = this.optionsMap.labelValueMap[tf.fieldKey][rawValue];
if (value) {
return { value, rawValue };
}
return { error: true, value: null, rawValue };
}
assignTemplateFieldsFromParsedRow(row: string[]): boolean {
const isKeyRow = row.some((key) => this.templateFieldsMap.has(key));
if (!isKeyRow) {
@ -550,6 +604,10 @@ function getTemplateFields(
tf.readOnly = false;
}
if (schema.isChild && tf.fieldname === 'name') {
tf.required = false;
}
const schemaName = schema.name;
const schemaLabel = schema.label;
const fieldKey = `${schema.name}.${field.fieldname}`;

View File

@ -4,12 +4,12 @@
<PageHeader :title="t`Import Wizard`">
<DropdownWithActions
:actions="actions"
v-if="hasImporter && !complete"
v-if="hasImporter"
:disabled="isMakingEntries"
:title="t`More`"
/>
<Button
v-if="hasImporter && !complete"
v-if="hasImporter"
:title="t`Add Row`"
@click="() => importer.addRow()"
:disabled="isMakingEntries"
@ -18,7 +18,7 @@
<feather-icon name="plus" class="w-4 h-4" />
</Button>
<Button
v-if="hasImporter && !complete"
v-if="hasImporter"
:title="t`Save Template`"
@click="saveTemplate"
:icon="true"
@ -45,7 +45,7 @@
</PageHeader>
<!-- Main Body of the Wizard -->
<div class="flex text-base w-full flex-col" v-if="!complete">
<div class="flex text-base w-full flex-col">
<!-- Select Import Type -->
<div
class="
@ -367,16 +367,16 @@
</template>
<script lang="ts">
import { DocValue } from 'fyo/core/types';
import { RawValue } from 'schemas/types';
import { Action as BaseAction } from 'fyo/model/types';
import { ValidationError } from 'fyo/utils/errors';
import { ModelNameEnum } from 'models/types';
import { OptionField, SelectOption } from 'schemas/types';
import { OptionField, RawValue, SelectOption } from 'schemas/types';
import Button from 'src/components/Button.vue';
import AutoComplete from 'src/components/Controls/AutoComplete.vue';
import Check from 'src/components/Controls/Check.vue';
import Data from 'src/components/Controls/Data.vue';
import FormControl from 'src/components/Controls/FormControl.vue';
import Select from 'src/components/Controls/Select.vue';
import DropdownWithActions from 'src/components/DropdownWithActions.vue';
import FormHeader from 'src/components/FormHeader.vue';
import Modal from 'src/components/Modal.vue';
@ -389,8 +389,6 @@ import { docsPathRef } from 'src/utils/refs';
import { showMessageDialog } from 'src/utils/ui';
import { defineComponent } from 'vue';
import Loading from '../components/Loading.vue';
import Select from 'src/components/Controls/Select.vue';
import { isWeakMap } from 'lodash';
type Action = Pick<BaseAction, 'condition' | 'component'> & {
action: Function;
@ -443,7 +441,6 @@ export default defineComponent({
if (fyo.store.isDevelopment) {
// @ts-ignore
window.iw = this;
this.setImportType('Item');
}
},
watch: {
@ -532,14 +529,13 @@ export default defineComponent({
return this.numColumnsPicked;
}
let vmColumnCount = 0;
if (this.importer.valueMatrix.length) {
vmColumnCount = this.importer.valueMatrix[0].length;
if (!this.importer.valueMatrix.length) {
return this.importer.assignedTemplateFields.length;
}
return Math.min(
this.importer.assignedTemplateFields.length,
vmColumnCount
this.importer.valueMatrix[0].length
);
},
columnIterator(): number[] {
@ -587,6 +583,10 @@ export default defineComponent({
ModelNameEnum.Party,
ModelNameEnum.Item,
ModelNameEnum.JournalEntry,
ModelNameEnum.Tax,
ModelNameEnum.Account,
ModelNameEnum.Address,
ModelNameEnum.NumberSeries,
];
const hasInventory = fyo.doc.singles.AccountingSettings?.enableInventory;

View File

@ -6,7 +6,7 @@ export function getValueMapFromList<T, K extends keyof T, V extends keyof T>(
key: K,
valueKey: V,
filterUndefined: boolean = true
): Record<string, unknown> {
): Record<string, T[V]> {
if (filterUndefined) {
list = list.filter(
(f) =>
@ -20,7 +20,7 @@ export function getValueMapFromList<T, K extends keyof T, V extends keyof T>(
const value = f[valueKey];
acc[keyValue] = value;
return acc;
}, {} as Record<string, unknown>);
}, {} as Record<string, T[V]>);
}
export function getRandomString(): string {