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

fix: PrintTemplate list view

- type ListCell
- improve ListViewConfig types, update where required
This commit is contained in:
18alantom 2023-03-07 12:39:49 +05:30
parent f9fbefad0e
commit dabcbcd2ce
10 changed files with 91 additions and 83 deletions

View File

@ -13,7 +13,7 @@ import { TelemetryManager } from './telemetry/telemetry';
import {
DEFAULT_CURRENCY,
DEFAULT_DISPLAY_PRECISION,
DEFAULT_INTERNAL_PRECISION
DEFAULT_INTERNAL_PRECISION,
} from './utils/consts';
import * as errors from './utils/errors';
import { format } from './utils/format';
@ -88,7 +88,7 @@ export class Fyo {
return this.db.fieldMap;
}
format(value: DocValue, field: string | Field, doc?: Doc) {
format(value: unknown, field: string | Field, doc?: Doc) {
return format(value, field, doc ?? null, this);
}

View File

@ -1,3 +1,4 @@
import { Fyo } from 'fyo';
import { DocValue, DocValueMap } from 'fyo/core/types';
import SystemSettings from 'fyo/models/SystemSettings';
import { FieldType, Schema, SelectOption } from 'schemas/types';
@ -76,13 +77,12 @@ export interface RenderData {
[key: string]: DocValue | Schema
}
export interface ColumnConfig {
export type ColumnConfig = {
label: string;
fieldtype: FieldType;
fieldname?: string;
size?: string;
fieldname: string;
render?: (doc: RenderData) => { template: string };
getValue?: (doc: Doc) => string;
display?: (value: unknown, fyo: Fyo) => string;
}
export type ListViewColumn = string | ColumnConfig;

View File

@ -1,10 +1,9 @@
import { Fyo } from 'fyo';
import { DocValue } from 'fyo/core/types';
import { Doc } from 'fyo/model/doc';
import { DateTime } from 'luxon';
import { Money } from 'pesa';
import { Field, FieldType, FieldTypeEnum } from 'schemas/types';
import { getIsNullOrUndef, safeParseFloat } from 'utils';
import { getIsNullOrUndef, safeParseFloat, titleCase } from 'utils';
import {
DEFAULT_CURRENCY,
DEFAULT_DATE_FORMAT,
@ -13,7 +12,7 @@ import {
} from './consts';
export function format(
value: DocValue,
value: unknown,
df: string | Field | null,
doc: Doc | null,
fyo: Fyo
@ -45,7 +44,7 @@ export function format(
}
if (field.fieldtype === FieldTypeEnum.Check) {
return Boolean(value).toString();
return titleCase(Boolean(value).toString());
}
if (getIsNullOrUndef(value)) {
@ -55,26 +54,31 @@ export function format(
return String(value);
}
function toDatetime(value: DocValue) {
function toDatetime(value: unknown): DateTime | null {
if (typeof value === 'string') {
return DateTime.fromISO(value);
} else if (value instanceof Date) {
return DateTime.fromJSDate(value);
} else {
} else if (typeof value === 'number') {
return DateTime.fromSeconds(value as number);
}
return null;
}
function formatDatetime(value: DocValue, fyo: Fyo): string {
function formatDatetime(value: unknown, fyo: Fyo): string {
if (value == null) {
return '';
}
const dateFormat =
(fyo.singles.SystemSettings?.dateFormat as string) ?? DEFAULT_DATE_FORMAT;
const formattedDatetime = toDatetime(value).toFormat(
`${dateFormat} HH:mm:ss`
);
const dateTime = toDatetime(value);
if (!dateTime) {
return '';
}
const formattedDatetime = dateTime.toFormat(`${dateFormat} HH:mm:ss`);
if (value === 'Invalid DateTime') {
return '';
@ -83,7 +87,7 @@ function formatDatetime(value: DocValue, fyo: Fyo): string {
return formattedDatetime;
}
function formatDate(value: DocValue, fyo: Fyo): string {
function formatDate(value: unknown, fyo: Fyo): string {
if (value == null) {
return '';
}
@ -91,9 +95,12 @@ function formatDate(value: DocValue, fyo: Fyo): string {
const dateFormat =
(fyo.singles.SystemSettings?.dateFormat as string) ?? DEFAULT_DATE_FORMAT;
const dateValue: DateTime = toDatetime(value);
const dateTime = toDatetime(value);
if (!dateTime) {
return '';
}
const formattedDate = dateValue.toFormat(dateFormat);
const formattedDate = dateTime.toFormat(dateFormat);
if (value === 'Invalid DateTime') {
return '';
}
@ -102,7 +109,7 @@ function formatDate(value: DocValue, fyo: Fyo): string {
}
function formatCurrency(
value: DocValue,
value: unknown,
field: Field,
doc: Doc | null,
fyo: Fyo
@ -125,7 +132,7 @@ function formatCurrency(
return valueString;
}
function formatNumber(value: DocValue, fyo: Fyo): string {
function formatNumber(value: unknown, fyo: Fyo): string {
const numberFormatter = getNumberFormatter(fyo);
if (typeof value === 'number') {
value = fyo.pesa(value.toFixed(20));

View File

@ -70,8 +70,8 @@ export class JournalEntry extends Transactional {
'name',
{
label: t`Status`,
fieldname: 'status',
fieldtype: 'Select',
size: 'small',
render(doc) {
const status = getDocStatus(doc);
const color = statusColor[status] ?? 'gray';

View File

@ -2,6 +2,7 @@ import { Doc } from 'fyo/model/doc';
import { SchemaMap } from 'schemas/types';
import { ListsMap, ListViewSettings, ReadOnlyMap } from 'fyo/model/types';
import { ModelNameEnum } from 'models/types';
import { Fyo } from 'fyo';
export class PrintTemplate extends Doc {
name?: string;
@ -17,10 +18,21 @@ export class PrintTemplate extends Doc {
return super.canDelete;
}
static getListViewSettings(): ListViewSettings {
static getListViewSettings(fyo: Fyo): ListViewSettings {
return {
formRoute: (name) => `/template-builder/${name}`,
columns: ['name', 'type', 'isCustom'],
columns: [
'name',
{
label: fyo.t`Type`,
fieldtype: 'AutoComplete',
fieldname: 'type',
display(value) {
return fyo.schemaMap[value as string]?.label ?? '';
},
},
'isCustom',
],
};
}

View File

@ -311,7 +311,6 @@ export function getDocStatusListColumn(): ColumnConfig {
label: t`Status`,
fieldname: 'status',
fieldtype: 'Select',
size: 'small',
render(doc) {
const status = getDocStatus(doc);
const color = statusColor[status] ?? 'gray';

View File

@ -80,6 +80,13 @@ export class StockMovement extends Transfer {
};
static getListViewSettings(fyo: Fyo): ListViewSettings {
const movementTypeMap = {
[MovementType.MaterialIssue]: fyo.t`Material Issue`,
[MovementType.MaterialReceipt]: fyo.t`Material Receipt`,
[MovementType.MaterialTransfer]: fyo.t`Material Transfer`,
[MovementType.Manufacture]: fyo.t`Manufacture`,
};
return {
formRoute: (name) => `/edit/StockMovement/${name}`,
columns: [
@ -90,20 +97,8 @@ export class StockMovement extends Transfer {
label: fyo.t`Movement Type`,
fieldname: 'movementType',
fieldtype: 'Select',
size: 'small',
render(doc) {
const movementType = doc.movementType as MovementType;
const label =
{
[MovementType.MaterialIssue]: fyo.t`Material Issue`,
[MovementType.MaterialReceipt]: fyo.t`Material Receipt`,
[MovementType.MaterialTransfer]: fyo.t`Material Transfer`,
[MovementType.Manufacture]: fyo.t`Manufacture`,
}[movementType] ?? '';
return {
template: `<span>${label}</span>`,
};
display(value): string {
return movementTypeMap[value as MovementType] ?? '';
},
},
],

View File

@ -37,7 +37,7 @@
<!-- Data Rows -->
<div class="overflow-y-auto custom-scroll" v-if="dataSlice.length !== 0">
<div v-for="(doc, i) in dataSlice" :key="doc.name">
<div v-for="(row, i) in dataSlice" :key="row.name">
<!-- Row Content -->
<div class="flex hover:bg-gray-50 items-center">
<p class="w-8 text-end me-4 text-gray-900">
@ -46,7 +46,7 @@
<Row
gap="1rem"
class="cursor-pointer text-gray-900 flex-1 h-row-mid"
@click="$emit('openDoc', doc.name)"
@click="$emit('openDoc', row.name)"
:columnCount="columns.length"
>
<ListCell
@ -56,7 +56,7 @@
'text-end': isNumeric(column.fieldtype),
'pe-4': c === columns.length - 1,
}"
:doc="doc"
:row="row"
:column="column"
/>
</Row>
@ -95,7 +95,6 @@ import Paginator from 'src/components/Paginator.vue';
import Row from 'src/components/Row';
import { fyo } from 'src/initFyo';
import { isNumeric } from 'src/utils';
import { openQuickEdit, routeTo } from 'src/utils/ui';
import { objectForEach } from 'utils/index';
import { defineComponent, toRaw } from 'vue';
import ListCell from './ListCell';

View File

@ -4,26 +4,52 @@
<component v-else :is="customRenderer" />
</div>
</template>
<script>
<script lang="ts">
import { ColumnConfig, RenderData } from 'fyo/model/types';
import { Field } from 'schemas/types';
import { fyo } from 'src/initFyo';
import { isNumeric } from 'src/utils';
import { defineComponent, PropType } from 'vue';
export default {
type Column = ColumnConfig | Field;
function isField(column: ColumnConfig | Field): column is Field {
if ((column as ColumnConfig).display || (column as ColumnConfig).render) {
return false;
}
return true;
}
export default defineComponent({
name: 'ListCell',
props: ['doc', 'column'],
props: {
row: { type: Object as PropType<RenderData>, required: true },
column: { type: Object as PropType<Column>, required: true },
},
computed: {
columnValue() {
let { column, doc } = this;
let value = doc[column.fieldname];
return fyo.format(value, column, doc);
columnValue(): string {
const column = this.column;
const value = this.row[this.column.fieldname];
if (isField(column)) {
return fyo.format(value, column);
}
return column.display?.(value, fyo) ?? '';
},
customRenderer() {
if (!this.column.render) return;
return this.column.render(this.doc);
const { render } = this.column as ColumnConfig;
if (!render) {
return;
}
return render(this.row);
},
cellClass() {
return isNumeric(this.column.fieldtype) ? 'justify-end' : '';
},
},
};
});
</script>

View File

@ -344,36 +344,6 @@ async function openEdit({ name, schemaName }: Doc) {
const route = getFormRoute(schemaName, name);
return await routeTo(route);
/*
const listConfig = fyo.models[doc.schemaName]?.getListViewSettings?.(fyo);
const formRoute = listConfig?.formRoute;
if (!doc.name) {
return;
}
if (formRoute) {
const route = formRoute(doc.name);
return await routeTo(route);
}
const isFormEdit = [
ModelNameEnum.SalesInvoice,
ModelNameEnum.PurchaseInvoice,
ModelNameEnum.JournalEntry,
ModelNameEnum.Shipment,
ModelNameEnum.PurchaseReceipt,
ModelNameEnum.StockMovement,
ModelNameEnum.Payment,
ModelNameEnum.Item,
].includes(doc.schemaName as ModelNameEnum);
if (isFormEdit) {
return await routeTo(`/edit/${doc.schemaName}/${doc.name}`);
}
await openQuickEdit({ schemaName: doc.schemaName, name: doc.name });
*/
}
function getDuplicateAction(doc: Doc): Action {