mirror of
https://github.com/frappe/books.git
synced 2025-01-23 07:08:36 +00:00
feat: Use InvoiceForm for PurchaseInvoice as well
- Button with icon prop
This commit is contained in:
parent
1537ea4609
commit
bd5d812d77
@ -26,7 +26,7 @@ module.exports = {
|
||||
getFilters: (query, doc) => {
|
||||
return {
|
||||
isGroup: 0,
|
||||
accountType: doc.customer === 1 ? 'Receivable' : 'Payable'
|
||||
accountType: doc.customer ? 'Receivable' : 'Payable'
|
||||
};
|
||||
}
|
||||
},
|
||||
|
@ -17,7 +17,7 @@ module.exports = {
|
||||
fieldname: 'date',
|
||||
label: 'Date',
|
||||
fieldtype: 'Date',
|
||||
defaultValue: new Date().toISOString()
|
||||
default: new Date().toISOString().slice(0, 10)
|
||||
},
|
||||
{
|
||||
fieldname: 'supplier',
|
||||
|
@ -4,6 +4,7 @@ import indicators from 'frappejs/ui/constants/indicators';
|
||||
export default {
|
||||
doctype: 'PurchaseInvoice',
|
||||
title: _('Purchase Invoice'),
|
||||
formRoute: name => `/edit/PurchaseInvoice/${name}`,
|
||||
columns: [
|
||||
'supplier',
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ module.exports = class PurchaseInvoiceServer extends PurchaseInvoice {
|
||||
await entries.validateEntries();
|
||||
}
|
||||
|
||||
async afterSubmit() {
|
||||
async beforeSubmit() {
|
||||
const entries = await this.getPosting();
|
||||
await entries.post();
|
||||
await frappe.db.setValue(
|
||||
|
@ -6,6 +6,13 @@ module.exports = {
|
||||
isChild: 1,
|
||||
keywordFields: [],
|
||||
layout: 'ratio',
|
||||
tableFields: [
|
||||
'item',
|
||||
'tax',
|
||||
'quantity',
|
||||
'rate',
|
||||
'amount'
|
||||
],
|
||||
fields: [
|
||||
{
|
||||
fieldname: 'item',
|
||||
|
@ -20,7 +20,7 @@ module.exports = {
|
||||
fieldname: 'date',
|
||||
label: 'Date',
|
||||
fieldtype: 'Date',
|
||||
defaultValue: new Date().toISOString()
|
||||
default: new Date().toISOString().slice(0, 10)
|
||||
},
|
||||
{
|
||||
fieldname: 'customer',
|
||||
|
@ -57,7 +57,7 @@ module.exports = class SalesInvoiceServer extends SalesInvoice {
|
||||
await entries.validateEntries();
|
||||
}
|
||||
|
||||
async afterSubmit() {
|
||||
async beforeSubmit() {
|
||||
const entries = await this.getPosting();
|
||||
await entries.post();
|
||||
await frappe.db.setValue(
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<button
|
||||
class="px-4 py-2 focus:outline-none rounded-6px"
|
||||
class="focus:outline-none rounded-6px"
|
||||
:style="style"
|
||||
v-bind="$attrs"
|
||||
v-on="$listeners"
|
||||
@ -15,11 +15,16 @@ export default {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'secondary'
|
||||
},
|
||||
icon: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
return {
|
||||
padding: this.icon ? '9px 15px' : '6px 24px',
|
||||
'background-image':
|
||||
this.type === 'primary'
|
||||
? 'linear-gradient(180deg, #4AC3F8 0%, #2490EF 100%)'
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="flex">
|
||||
<Sidebar class="w-56" />
|
||||
<div class="flex flex-1 overflow-y-hidden bg-white">
|
||||
<keep-alive exclude="ListView">
|
||||
<keep-alive include="InvoiceForm">
|
||||
<router-view class="flex-1" :key="$route.fullPath" />
|
||||
</keep-alive>
|
||||
<div class="flex" v-if="$route.query.edit && $route.query.doctype && $route.query.name">
|
||||
|
@ -3,11 +3,26 @@
|
||||
<PageHeader>
|
||||
<a class="cursor-pointer font-semibold" slot="title" @click="$router.go(-1)">{{ _('Back') }}</a>
|
||||
<template slot="actions">
|
||||
<Button class="text-gray-900 text-xs">Customise</Button>
|
||||
<Button v-if="doc._notInserted || doc._dirty" type="primary" class="text-white text-xs ml-2" @click="onSaveClick">{{ _('Save') }}</Button>
|
||||
<Button class="text-gray-900 text-xs">{{ _('Customise') }}</Button>
|
||||
<Button
|
||||
v-if="doc._notInserted || doc._dirty"
|
||||
type="primary"
|
||||
class="text-white text-xs ml-2"
|
||||
@click="onSaveClick"
|
||||
>{{ _('Save') }}</Button>
|
||||
<Button
|
||||
v-if="!doc._dirty && !doc._notInserted && !doc.submitted"
|
||||
type="primary"
|
||||
class="text-white text-xs ml-2"
|
||||
@click="onSubmitClick"
|
||||
>{{ _('Submit') }}</Button>
|
||||
</template>
|
||||
</PageHeader>
|
||||
<div class="flex justify-center flex-1 mb-8 mt-6" v-if="meta">
|
||||
<div
|
||||
class="flex justify-center flex-1 mb-8 mt-6"
|
||||
v-if="meta"
|
||||
:class="doc.submitted && 'pointer-events-none'"
|
||||
>
|
||||
<div class="border rounded shadow h-full flex flex-col justify-between" style="width: 600px">
|
||||
<div>
|
||||
<div class="px-6 pt-6">
|
||||
@ -53,11 +68,11 @@
|
||||
</div>
|
||||
<div class="w-1/3">
|
||||
<FormControl
|
||||
:df="meta.getField('customer')"
|
||||
:value="doc.customer"
|
||||
:placeholder="'Customer'"
|
||||
@change="value => doc.set('customer', value)"
|
||||
@new-doc="doc => doc.set('customer', doc.name)"
|
||||
:df="meta.getField(partyField.fieldname)"
|
||||
:value="doc[partyField.fieldname]"
|
||||
:placeholder="partyField.label"
|
||||
@change="value => doc.set(partyField.fieldname, value)"
|
||||
@new-doc="doc => doc.set(partyField.fieldname, doc.name)"
|
||||
input-class="bg-gray-100 rounded-lg p-2 text-right"
|
||||
/>
|
||||
<div
|
||||
@ -86,7 +101,9 @@
|
||||
<div>{{ tax.account }} ({{ tax.rate }}%)</div>
|
||||
<div>{{ tax.amount }}</div>
|
||||
</div>
|
||||
<div class="flex pl-2 justify-between py-3 border-t text-green-600 font-semibold text-base">
|
||||
<div
|
||||
class="flex pl-2 justify-between py-3 border-t text-green-600 font-semibold text-base"
|
||||
>
|
||||
<div>Grand Total</div>
|
||||
<div>{{ doc.grandTotal }}</div>
|
||||
</div>
|
||||
@ -105,7 +122,7 @@ import AddIcon from '@/components/Icons/Add';
|
||||
|
||||
export default {
|
||||
name: 'InvoiceForm',
|
||||
props: ['name'],
|
||||
props: ['doctype', 'name'],
|
||||
components: {
|
||||
PageHeader,
|
||||
Button,
|
||||
@ -115,7 +132,7 @@ export default {
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
doctype: 'SalesInvoice',
|
||||
doctype: this.doctype,
|
||||
name: this.name
|
||||
};
|
||||
},
|
||||
@ -134,12 +151,19 @@ export default {
|
||||
},
|
||||
itemTableColumnRatio() {
|
||||
return [0.3].concat(this.itemTableFields.map(_ => 1));
|
||||
}
|
||||
},
|
||||
partyField() {
|
||||
let fieldname = {
|
||||
SalesInvoice: 'customer',
|
||||
PurchaseInvoice: 'supplier'
|
||||
}[this.doctype];
|
||||
return this.meta.getField(fieldname);
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
this.meta = frappe.getMeta('SalesInvoice');
|
||||
this.itemsMeta = frappe.getMeta('SalesInvoiceItem');
|
||||
this.doc = await frappe.getDoc('SalesInvoice', this.name);
|
||||
this.meta = frappe.getMeta(this.doctype);
|
||||
this.itemsMeta = frappe.getMeta(`${this.doctype}Item`);
|
||||
this.doc = await frappe.getDoc(this.doctype, this.name);
|
||||
window.si = this.doc;
|
||||
},
|
||||
methods: {
|
||||
@ -154,6 +178,9 @@ export default {
|
||||
} else {
|
||||
this.doc.update();
|
||||
}
|
||||
},
|
||||
async onSubmitClick() {
|
||||
await this.doc.submit();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -26,7 +26,7 @@
|
||||
</Row>
|
||||
</div>
|
||||
<div class="flex items-center justify-center">
|
||||
<Button :class="start == 0 && 'text-gray-600'" :disabled="start == 0" @click="prevPage">
|
||||
<Button :icon="true" :class="start == 0 && 'text-gray-600'" :disabled="start == 0" @click="prevPage">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
@ -45,7 +45,7 @@
|
||||
<span class="text-gray-600">of</span>
|
||||
<span class="font-medium">{{ totalCount }}</span>
|
||||
</div>
|
||||
<Button :class="start + pageLength >= totalCount && 'text-gray-600'" :disabled="start + pageLength >= totalCount" @click="nextPage">
|
||||
<Button :icon="true" :class="start + pageLength >= totalCount && 'text-gray-600'" :disabled="start + pageLength >= totalCount" @click="nextPage">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
|
@ -1,18 +1,16 @@
|
||||
<template>
|
||||
<div class="flex">
|
||||
<div class="flex flex-col flex-1">
|
||||
<PageHeader>
|
||||
<h1 slot="title" class="text-xl font-bold" v-if="title">{{ title }}</h1>
|
||||
<template slot="actions">
|
||||
<Button type="primary" @click="makeNewDoc">
|
||||
<Add class="w-3 h-3 stroke-current text-white" />
|
||||
</Button>
|
||||
<SearchBar class="ml-2" />
|
||||
</template>
|
||||
</PageHeader>
|
||||
<div class="flex-1 flex">
|
||||
<List :listConfig="listConfig" :filters="filters" class="flex-1" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<PageHeader>
|
||||
<h1 slot="title" class="text-xl font-bold" v-if="title">{{ title }}</h1>
|
||||
<template slot="actions">
|
||||
<Button :icon="true" type="primary" @click="makeNewDoc">
|
||||
<Add class="w-3 h-3 stroke-current text-white" />
|
||||
</Button>
|
||||
<SearchBar class="ml-2" />
|
||||
</template>
|
||||
</PageHeader>
|
||||
<div class="flex-1 flex">
|
||||
<List :listConfig="listConfig" :filters="filters" class="flex-1" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -80,7 +78,7 @@ export default {
|
||||
title: this.doctype,
|
||||
doctype: this.doctype,
|
||||
columns: frappe.getMeta(this.doctype).getKeywordFields()
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
title() {
|
||||
|
@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<div class="border-l h-full">
|
||||
<div class="flex justify-end px-4 pt-4">
|
||||
<Button @click="routeToList">
|
||||
<Button :icon="true" @click="routeToList">
|
||||
<XIcon class="w-3 h-3 stroke-current text-gray-700" />
|
||||
</Button>
|
||||
<Button @click="insertDoc" type="primary" v-if="doc._notInserted" class="ml-2 flex">
|
||||
<Button :icon="true" @click="insertDoc" type="primary" v-if="doc._notInserted" class="ml-2 flex">
|
||||
<feather-icon name="check" class="text-white" />
|
||||
</Button>
|
||||
</div>
|
||||
<div class="px-1 pt-2 pb-4 border-b flex items-center justify-between">
|
||||
<div class="pl-1 pr-4 pt-2 pb-4 border-b flex items-center justify-between">
|
||||
<FormControl
|
||||
ref="titleControl"
|
||||
v-if="titleDocField"
|
||||
|
Loading…
x
Reference in New Issue
Block a user