2
0
mirror of https://github.com/frappe/books.git synced 2024-11-08 14:50:56 +00:00

incr: get Invoice form to render

This commit is contained in:
18alantom 2022-05-01 10:15:47 +05:30
parent e6b8c8a1b6
commit d99591d058
16 changed files with 132 additions and 108 deletions

View File

@ -224,7 +224,7 @@ export default class DatabaseCore extends DatabaseBase {
}
if (tableFields.length) {
await this.#loadChildren(fieldValueMap, tableFields);
await this.#loadChildren(name, fieldValueMap, tableFields);
}
return fieldValueMap;
}
@ -711,13 +711,14 @@ export default class DatabaseCore extends DatabaseBase {
}
async #loadChildren(
parentName: string,
fieldValueMap: FieldValueMap,
tableFields: TargetField[]
) {
for (const field of tableFields) {
fieldValueMap[field.fieldname] = await this.getAll(field.target, {
fields: ['*'],
filters: { parent: fieldValueMap.name as string },
filters: { parent: parentName },
orderBy: 'idx',
order: 'asc',
});

View File

@ -48,9 +48,9 @@ export async function setName(doc: Doc, fyo: Fyo) {
return;
}
// name === doctype for Single
// name === schemaName for Single
if (doc.schema.isSingle) {
doc.name = doc.schema.name;
doc.name = doc.schemaName;
return;
}

View File

@ -122,7 +122,7 @@ export class Party extends Doc {
router.push({
path: `/edit/PurchaseInvoice/${doc.name}`,
query: {
doctype: 'PurchaseInvoice',
schemaName: 'PurchaseInvoice',
values: {
// @ts-ignore
party: partyDoc.name!,
@ -139,7 +139,7 @@ export class Party extends Doc {
router.push({
name: 'ListView',
params: {
doctype: 'PurchaseInvoice',
schemaName: 'PurchaseInvoice',
filters: {
// @ts-ignore
party: partyDoc.name!,
@ -157,7 +157,7 @@ export class Party extends Doc {
router.push({
path: `/edit/SalesInvoice/${doc.name}`,
query: {
doctype: 'SalesInvoice',
schemaName: 'SalesInvoice',
values: {
// @ts-ignore
party: partyDoc.name!,
@ -174,7 +174,7 @@ export class Party extends Doc {
router.push({
name: 'ListView',
params: {
doctype: 'SalesInvoice',
schemaName: 'SalesInvoice',
filters: {
// @ts-ignore
party: partyDoc.name!,

View File

@ -55,7 +55,7 @@ export function getTransactionActions(schemaName: string, fyo: Fyo): Action[] {
paymentType,
for: [
{
referenceType: doc.doctype,
referenceType: doc.schemaName,
referenceName: doc.name,
amount: doc.outstandingAmount,
},
@ -68,7 +68,7 @@ export function getTransactionActions(schemaName: string, fyo: Fyo): Action[] {
label: fyo.t`Print`,
condition: (doc: Doc) => doc.submitted as boolean,
action: async (doc: Doc, router: Router) => {
router.push({ path: `/print/${doc.doctype}/${doc.name}` });
router.push({ path: `/print/${doc.schemaName}/${doc.name}` });
},
},
getLedgerLinkAction(fyo),

View File

@ -30,7 +30,7 @@
<!-- Error Display -->
<div
class="text-sm text-red-600 mb-2 pl-2 col-span-full"
v-if="Object.values(errors).length"
v-if="Object.values(errors).filter(Boolean).length"
>
{{ getErrorString() }}
</div>
@ -79,7 +79,7 @@ export default {
});
},
getErrorString() {
return Object.values(this.errors).join(' ');
return Object.values(this.errors).filter(Boolean).join(' ');
},
},
};

View File

@ -11,17 +11,14 @@ export default {
}
},
async mounted() {
await this.doc.loadLink(this.partyField);
this.party = this.doc.getLink(this.partyField);
await this.doc.loadLink('party');
this.party = this.doc.getLink('party');
await this.printSettings.loadLink('address');
this.companyAddress = this.printSettings.getLink('address');
},
computed: {
partyField() {
return this.doc.doctype === 'SalesInvoice' ? 'customer' : 'supplier';
},
isSalesInvoice() {
return this.doc.doctype === 'SalesInvoice';
return this.doc.schemaName === 'SalesInvoice';
}
}
};

View File

@ -30,7 +30,7 @@
class="font-semibold text-xl"
:style="{ color: printSettings.color }"
>
{{ doc.doctype === 'SalesInvoice' ? 'Invoice' : 'Bill' }}
{{ doc.schemaName === 'SalesInvoice' ? t`Sales Invoie` : t`Purchase Invoice` }}
</div>
<div>
{{ doc.name }}

View File

@ -178,8 +178,8 @@ export default {
itemActiveClass(item) {
let { path: currentRoute, params } = this.$route;
let routeMatch = currentRoute === item.route;
let doctypeMatch = item.doctype && params.doctype === item.doctype;
return routeMatch || doctypeMatch ? 'bg-white text-blue-500' : '';
let schemaNameMatch = item.schemaName && params.schemaName === item.schemaName;
return routeMatch || schemaNameMatch ? 'bg-white text-blue-500' : '';
},
isActiveGroup(group) {
return this.activeGroup && group.label === this.activeGroup.label;

View File

@ -249,7 +249,7 @@ export default {
// open quick edit
openQuickEdit({
doctype: 'Account',
schemaName: 'Account',
name: account.name,
});
// unfreeze input
@ -261,8 +261,8 @@ export default {
}
},
isQuickEditOpen(account) {
let { edit, doctype, name } = this.$route.query;
if (edit && doctype === 'Account' && name === account.name) {
let { edit, schemaName, name } = this.$route.query;
if (edit && schemaName === 'Account' && name === account.name) {
return true;
}
return false;

View File

@ -87,7 +87,7 @@ export default {
invoices: [
{
title: t`Sales Invoices`,
doctype: 'SalesInvoice',
schemaName: 'SalesInvoice',
total: 0,
unpaid: 0,
paid: 0,
@ -98,7 +98,7 @@ export default {
},
{
title: t`Purchase Invoices`,
doctype: 'PurchaseInvoice',
schemaName: 'PurchaseInvoice',
total: 0,
unpaid: 0,
paid: 0,
@ -126,7 +126,7 @@ export default {
);
let result = await fyo.db.getTotalOutstanding(
d.doctype,
d.schemaName,
fromDate,
toDate
);
@ -143,8 +143,8 @@ export default {
this.invoices = await Promise.all(promises);
},
async newInvoice(invoice) {
let doc = await fyo.doc.getNewDoc(invoice.doctype);
routeTo(`/edit/${invoice.doctype}/${doc.name}`);
let doc = await fyo.doc.getNewDoc(invoice.schemaName);
routeTo(`/edit/${invoice.schemaName}/${doc.name}`);
},
},
};

View File

@ -426,9 +426,9 @@ export default {
return this.file ? this.t`Import Data` : this.t`Select File`;
},
isSubmittable() {
const doctype = this.importer?.doctype;
if (doctype) {
return fyo.models[doctype].isSubmittable ?? false;
const schemaName = this.importer?.schemaName;
if (schemaName) {
return fyo.schemaMap[schemaName].isSubmittable ?? false;
}
return false;
},
@ -441,7 +441,7 @@ export default {
getList: () => importable.map((i) => fyo.models[i].label),
};
},
labelDoctypeMap() {
labelSchemaNameMap() {
return importable
.map((i) => ({
name: i,
@ -465,9 +465,9 @@ export default {
},
methods: {
showMe() {
const doctype = this.importer.doctype;
const schemaName = this.importer.schemaName;
this.clear();
this.$router.push(`/list/${doctype}`);
this.$router.push(`/list/${schemaName}`);
},
clear() {
this.file = null;
@ -573,7 +573,7 @@ export default {
this.clear();
}
this.importType = importType;
this.importer = new Importer(this.labelDoctypeMap[this.importType], fyo);
this.importer = new Importer(this.labelSchemaNameMap[this.importType], fyo);
},
setLoadingStatus(isMakingEntries, entriesMade, totalEntries) {
this.isMakingEntries = isMakingEntries;

View File

@ -7,7 +7,7 @@
v-if="doc.submitted"
class="text-gray-900 text-xs ml-2"
:icon="true"
@click="routeTo(`/print/${doc.doctype}/${doc.name}`)"
@click="routeTo(`/print/${doc.schemaName}/${doc.name}`)"
>
Print
</Button>
@ -21,7 +21,7 @@
{{ t`Save` }}
</Button>
<Button
v-if="!doc._dirty && !doc._notInserted && !doc.submitted"
v-if="!doc.dirty && !doc.notInserted && !doc.submitted"
type="primary"
class="text-white text-xs ml-2"
@click="onSubmitClick"
@ -29,7 +29,7 @@
>
</template>
</PageHeader>
<div class="flex justify-center flex-1 mb-8 mt-2" v-if="meta">
<div class="flex justify-center flex-1 mb-8 mt-2" v-if="doc">
<div
class="border rounded-lg shadow h-full flex flex-col justify-between"
style="width: 600px"
@ -60,31 +60,29 @@
<div class="mt-8 px-6">
<h1 class="text-2xl font-semibold">
{{
doc._notInserted
? doc.doctype === 'SalesInvoice'
? t`New Invoice`
: t`New Bill`
doc.notInserted
? doc.schemaName === 'SalesInvoice'
? t`New Sales Invoice`
: t`New Purchase Invoice`
: doc.name
}}
</h1>
<div class="flex justify-between mt-2">
<div class="w-1/3">
<FormControl
class="text-base"
input-class="bg-gray-100 p-2 text-lg font-semibold"
:df="meta.getField(partyField.fieldname)"
:value="doc[partyField.fieldname]"
:placeholder="partyField.label"
@change="(value) => doc.set(partyField.fieldname, value)"
@new-doc="
(party) => doc.set(partyField.fieldname, party.name)
"
class="bg-gray-100 rounded text-base"
input-class="p-2 text-lg font-semibold bg-transparent"
:df="getField('party')"
:value="doc.party"
:placeholder="getField('party').label"
@change="(value) => doc.set('party', value)"
@new-doc="(party) => doc.set('party', party.name)"
:read-only="doc.submitted"
/>
<FormControl
class="mt-2 text-base"
input-class="bg-gray-100 px-3 py-2 text-base"
:df="meta.getField('account')"
class="mt-2 text-base bg-gray-100 rounded"
input-class="px-3 py-2 text-base bg-transparent"
:df="getField('account')"
:value="doc.account"
:placeholder="'Account'"
@change="(value) => doc.set('account', value)"
@ -94,26 +92,26 @@
<div class="w-1/3">
<FormControl
input-class="bg-gray-100 px-3 py-2 text-base text-right"
:df="meta.getField('date')"
:df="getField('date')"
:value="doc.date"
:placeholder="'Date'"
@change="(value) => doc.set('date', value)"
:read-only="doc.submitted"
/>
<FormControl
class="mt-2 text-base"
input-class="bg-gray-100 px-3 py-2 text-base text-right"
:df="meta.getField('numberSeries')"
class="mt-2 text-base bg-gray-100 rounded"
input-class="bg-transparent px-3 py-2 text-base text-right"
:df="getField('numberSeries')"
:value="doc.numberSeries"
@change="(value) => doc.set('numberSeries', value)"
:read-only="!doc._notInserted || doc.submitted"
:read-only="!doc.notInserted || doc.submitted"
/>
</div>
</div>
</div>
<div class="px-6 text-base">
<FormControl
:df="meta.getField('items')"
:df="getField('items')"
:value="doc.items"
:showHeader="true"
:max-rows-before-overflow="4"
@ -129,7 +127,7 @@
<div class="flex-1 mr-10">
<FormControl
v-if="!doc.submitted || doc.terms"
:df="meta.getField('terms')"
:df="getField('terms')"
:value="doc.terms"
:show-label="true"
input-class="bg-gray-100"
@ -195,24 +193,26 @@
</div>
</template>
<script>
import { computed } from '@vue/reactivity';
import { getInvoiceStatus } from 'models/helpers';
import Button from 'src/components/Button';
import { ModelNameEnum } from 'models/types';
import Button from 'src/components/Button.vue';
import FormControl from 'src/components/Controls/FormControl.vue';
import DropdownWithActions from 'src/components/DropdownWithActions';
import PageHeader from 'src/components/PageHeader';
import StatusBadge from 'src/components/StatusBadge';
import DropdownWithActions from 'src/components/DropdownWithActions.vue';
import PageHeader from 'src/components/PageHeader.vue';
import StatusBadge from 'src/components/StatusBadge.vue';
import { fyo } from 'src/initFyo';
import {
getActionsForDocument,
openSettings,
routeTo,
showMessageDialog
} from 'src/utils';
getActionsForDocument,
openSettings,
routeTo,
showMessageDialog,
} from 'src/utils/ui';
import { handleErrorWithDialog } from '../errorHandling';
export default {
name: 'InvoiceForm',
props: ['doctype', 'name'],
props: { schemaName: String, name: String },
components: {
PageHeader,
StatusBadge,
@ -222,8 +222,9 @@ export default {
},
provide() {
return {
doctype: this.doctype,
schemaName: this.schemaName,
name: this.name,
doc: computed(() => this.doc),
};
},
data() {
@ -236,21 +237,11 @@ export default {
};
},
computed: {
meta() {
return fyo.getMeta(this.doctype);
},
partyField() {
let fieldname = {
SalesInvoice: 'customer',
PurchaseInvoice: 'supplier',
}[this.doctype];
return this.meta.getField(fieldname);
},
address() {
return this.printSettings && this.printSettings.getLink('address');
},
showSave() {
return this.doc && (this.doc._notInserted || this.doc._dirty);
return this.doc && (this.doc.notInserted || this.doc.dirty);
},
actions() {
return getActionsForDocument(this.doc);
@ -258,29 +249,37 @@ export default {
},
async mounted() {
try {
this.doc = await fyo.doc.getDoc(this.doctype, this.name);
window.d = this.doc;
this.doc = await fyo.doc.getDoc(this.schemaName, this.name);
} catch (error) {
if (error instanceof fyo.errors.NotFoundError) {
routeTo(`/list/${this.doctype}`);
routeTo(`/list/${this.schemaName}`);
return;
}
this.handleError(error);
}
this.printSettings = await fyo.getSingle('PrintSettings');
this.companyName = (await fyo.getSingle('AccountingSettings')).companyName;
this.printSettings = await fyo.doc.getSingle('PrintSettings');
this.companyName = (
await fyo.doc.getSingle('AccountingSettings')
).companyName;
let query = this.$route.query;
if (query.values && query.doctype === this.doctype) {
if (query.values && query.schemaName === this.schemaName) {
this.doc.set(this.$router.currentRoute.value.query.values);
}
this.status = getInvoiceStatus(this.doc);
if (fyo.store.isDevelopment) {
window.inv = this;
}
},
updated() {
this.status = getInvoiceStatus(this.doc);
},
methods: {
routeTo,
getField(fieldname) {
return fyo.getField(this.schemaName, fieldname);
},
async onSaveClick() {
await this.doc.set(
'items',
@ -290,9 +289,9 @@ export default {
},
onSubmitClick() {
let message =
this.doctype === 'SalesInvoice'
? this.t`Are you sure you want to submit this Invoice?`
: this.t`Are you sure you want to submit this Bill?`;
this.schemaName === ModelNameEnum.SalesInvoice
? this.t`Are you sure you want to submit this Sales Invoice?`
: this.t`Are you sure you want to submit this Purchase Invoice?`;
showMessageDialog({
message,
buttons: [
@ -319,7 +318,8 @@ export default {
if (!doc) {
doc = this.doc;
}
let df = doc.meta.getField(fieldname);
const df = this.getField(fieldname);
return fyo.format(doc[fieldname], df, doc);
},
},

View File

@ -59,7 +59,7 @@ import { IPC_ACTIONS } from 'utils/messages';
export default {
name: 'PrintView',
props: ['doctype', 'name'],
props: { schemaName: String, name: String },
components: {
PageHeader,
SearchBar,
@ -74,12 +74,12 @@ export default {
};
},
async mounted() {
this.doc = await fyo.doc.getDoc(this.doctype, this.name);
this.doc = await fyo.doc.getDoc(this.schemaName, this.name);
this.printSettings = await fyo.getSingle('PrintSettings');
},
computed: {
meta() {
return fyo.getMeta(this.doctype);
return fyo.getMeta(this.schemaName);
},
printTemplate() {
return this.meta.printTemplate;

View File

@ -59,7 +59,7 @@ export default {
emits: ['change'],
provide() {
return {
doctype: 'PrintSettings',
schemaName: 'PrintSettings',
name: 'PrintSettings',
};
},

View File

@ -3,7 +3,7 @@ import ChartOfAccounts from 'src/pages/ChartOfAccounts.vue';
import Dashboard from 'src/pages/Dashboard/Dashboard.vue';
import GetStarted from 'src/pages/GetStarted.vue';
// import DataImport from 'src/pages/DataImport.vue';
// import InvoiceForm from 'src/pages/InvoiceForm.vue';
import InvoiceForm from 'src/pages/InvoiceForm.vue';
import JournalEntryForm from 'src/pages/JournalEntryForm.vue';
import ListView from 'src/pages/ListView/ListView.vue';
// import PrintView from 'src/pages/PrintView/PrintView.vue';
@ -34,16 +34,15 @@ const routes: RouteRecordRaw[] = [
// for sidebar item active state
route.params.schemaName = 'JournalEntry';
return {
doctype: 'JournalEntry',
schemaName: 'JournalEntry',
name: route.params.name,
};
},
edit: (route) => route.query,
},
},
/*
{
path: '/edit/:doctype/:name',
path: '/edit/:schemaName/:name',
name: 'InvoiceForm',
components: {
default: InvoiceForm,
@ -54,7 +53,6 @@ const routes: RouteRecordRaw[] = [
edit: (route) => route.query,
},
},
*/
{
path: '/list/:schemaName/:fieldname?/:value?',
name: 'ListView',
@ -84,7 +82,7 @@ const routes: RouteRecordRaw[] = [
},
/*
{
path: '/print/:doctype/:name',
path: '/print/:schemaName/:name',
name: 'PrintView',
component: PrintView,
props: true,

View File

@ -19,7 +19,7 @@ interface SearchItem {
action?: () => void;
}
async function openNewDoc(schemaName: string) {
async function openQuickEditDoc(schemaName: string) {
await routeTo(`/list/${schemaName}`);
const doc = await fyo.doc.getNewDoc(schemaName);
const { openQuickEdit } = await import('src/utils/ui');
@ -30,27 +30,55 @@ async function openNewDoc(schemaName: string) {
});
}
async function openFormEditDoc(schemaName: string) {
const doc = fyo.doc.getNewDoc(schemaName);
const name = doc.name;
routeTo(`/edit/${schemaName}/${name}`);
}
function getCreateList(): SearchItem[] {
return [
{
label: t`Create Item`,
group: 'Create',
action() {
openNewDoc(ModelNameEnum.Item);
openQuickEditDoc(ModelNameEnum.Item);
},
},
{
label: t`Create Party`,
group: 'Create',
action() {
openNewDoc(ModelNameEnum.Party);
openQuickEditDoc(ModelNameEnum.Party);
},
},
{
label: t`Create Payment`,
group: 'Create',
action() {
openNewDoc(ModelNameEnum.Payment);
openQuickEditDoc(ModelNameEnum.Payment);
},
},
{
label: t`Create Sales Invoice`,
group: 'Create',
action() {
openFormEditDoc(ModelNameEnum.SalesInvoice);
},
},
{
label: t`Create Purchase Invoice`,
group: 'Create',
action() {
openFormEditDoc(ModelNameEnum.PurchaseInvoice);
},
},
{
label: t`Create Journal Entry`,
group: 'Create',
action() {
openFormEditDoc(ModelNameEnum.JournalEntry);
},
},
];