mirror of
https://github.com/frappe/books.git
synced 2024-11-08 14:50:56 +00:00
feat: #151 Add quote object and allow create invoice from it
Also allow changing a print template type, necessary to create a custom print template for this.
This commit is contained in:
parent
b1c94c3246
commit
c10edc7132
@ -21,6 +21,7 @@ const defaultNumberSeriesMap = {
|
||||
[ModelNameEnum.JournalEntry]: 'JV-',
|
||||
[ModelNameEnum.SalesInvoice]: 'SINV-',
|
||||
[ModelNameEnum.PurchaseInvoice]: 'PINV-',
|
||||
[ModelNameEnum.SalesQuote]: 'SQUOT-',
|
||||
} as Record<ModelNameEnum, string>;
|
||||
|
||||
async function execute(dm: DatabaseManager) {
|
||||
@ -209,6 +210,7 @@ async function copyTransactionalTables(
|
||||
ModelNameEnum.Payment,
|
||||
ModelNameEnum.SalesInvoice,
|
||||
ModelNameEnum.PurchaseInvoice,
|
||||
ModelNameEnum.SalesQuote,
|
||||
];
|
||||
|
||||
for (const sn of schemaNames) {
|
||||
|
@ -14,6 +14,7 @@ export class Defaults extends Doc {
|
||||
purchaseReceiptLocation?: string;
|
||||
|
||||
// Number Series
|
||||
salesQuoteNumberSeries?: string;
|
||||
salesInvoiceNumberSeries?: string;
|
||||
purchaseInvoiceNumberSeries?: string;
|
||||
journalEntryNumberSeries?: string;
|
||||
@ -29,6 +30,7 @@ export class Defaults extends Doc {
|
||||
purchaseReceiptTerms?: string;
|
||||
|
||||
// Print Templates
|
||||
salesQuotePrintTemplate?: string;
|
||||
salesInvoicePrintTemplate?: string;
|
||||
purchaseInvoicePrintTemplate?: string;
|
||||
journalEntryPrintTemplate?: string;
|
||||
@ -46,6 +48,9 @@ export class Defaults extends Doc {
|
||||
salesPaymentAccount: () => ({ isGroup: false, accountType: 'Cash' }),
|
||||
purchasePaymentAccount: () => ({ isGroup: false, accountType: 'Cash' }),
|
||||
// Number Series
|
||||
salesQuoteNumberSeries: () => ({
|
||||
referenceType: ModelNameEnum.SalesQuote,
|
||||
}),
|
||||
salesInvoiceNumberSeries: () => ({
|
||||
referenceType: ModelNameEnum.SalesInvoice,
|
||||
}),
|
||||
@ -68,6 +73,7 @@ export class Defaults extends Doc {
|
||||
referenceType: ModelNameEnum.PurchaseReceipt,
|
||||
}),
|
||||
// Print Templates
|
||||
salesQuotePrintTemplate: () => ({ type: ModelNameEnum.SalesQuote }),
|
||||
salesInvoicePrintTemplate: () => ({ type: ModelNameEnum.SalesInvoice }),
|
||||
purchaseInvoicePrintTemplate: () => ({
|
||||
type: ModelNameEnum.PurchaseInvoice,
|
||||
@ -118,4 +124,5 @@ export const numberSeriesDefaultsMap: Record<
|
||||
[ModelNameEnum.StockMovement]: 'stockMovementNumberSeries',
|
||||
[ModelNameEnum.Shipment]: 'shipmentNumberSeries',
|
||||
[ModelNameEnum.PurchaseReceipt]: 'purchaseReceiptNumberSeries',
|
||||
[ModelNameEnum.SalesQuote]: 'salesQuoteNumberSeries',
|
||||
};
|
||||
|
@ -71,7 +71,11 @@ export abstract class Invoice extends Transactional {
|
||||
returnAgainst?: string;
|
||||
|
||||
get isSales() {
|
||||
return this.schemaName === 'SalesInvoice';
|
||||
return this.schemaName === 'SalesInvoice' || this.schemaName == 'SalesQuote';
|
||||
}
|
||||
|
||||
get isQuote() {
|
||||
return this.schemaName == 'SalesQuote';
|
||||
}
|
||||
|
||||
get enableDiscounting() {
|
||||
@ -493,7 +497,7 @@ export abstract class Invoice extends Transactional {
|
||||
}
|
||||
|
||||
async _updateIsItemsReturned() {
|
||||
if (!this.isReturn || !this.returnAgainst) {
|
||||
if (!this.isReturn || !this.returnAgainst || this.isQuote) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -515,7 +519,7 @@ export abstract class Invoice extends Transactional {
|
||||
}
|
||||
|
||||
async _validateHasLinkedReturnInvoices() {
|
||||
if (!this.name || this.isReturn) {
|
||||
if (!this.name || this.isReturn || this.isQuote) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -685,6 +689,7 @@ export abstract class Invoice extends Transactional {
|
||||
attachment: () =>
|
||||
!(this.attachment || !(this.isSubmitted || this.isCancelled)),
|
||||
backReference: () => !this.backReference,
|
||||
quote: () => !this.quote,
|
||||
priceList: () => !this.fyo.singles.AccountingSettings?.enablePriceList,
|
||||
returnAgainst: () =>
|
||||
(this.isSubmitted || this.isCancelled) && !this.returnAgainst,
|
||||
|
@ -47,7 +47,7 @@ export abstract class InvoiceItem extends Doc {
|
||||
itemTaxedTotal?: Money;
|
||||
|
||||
get isSales() {
|
||||
return this.schemaName === 'SalesInvoiceItem';
|
||||
return this.schemaName === 'SalesInvoiceItem' || this.schemaName === 'SalesQuoteItem';
|
||||
}
|
||||
|
||||
get date() {
|
||||
|
@ -55,6 +55,7 @@ export class PrintTemplate extends Doc {
|
||||
|
||||
const models = [
|
||||
ModelNameEnum.SalesInvoice,
|
||||
ModelNameEnum.SalesQuote,
|
||||
ModelNameEnum.PurchaseInvoice,
|
||||
ModelNameEnum.JournalEntry,
|
||||
ModelNameEnum.Payment,
|
||||
|
65
models/baseModels/SalesQuote/SalesQuote.ts
Normal file
65
models/baseModels/SalesQuote/SalesQuote.ts
Normal file
@ -0,0 +1,65 @@
|
||||
import { Fyo } from 'fyo';
|
||||
import { Action, ListViewSettings } from 'fyo/model/types';
|
||||
import { LedgerPosting } from 'models/Transactional/LedgerPosting';
|
||||
import { ModelNameEnum } from 'models/types';
|
||||
import { getQuoteActions, getTransactionStatusColumn } from '../../helpers';
|
||||
import { Invoice } from '../Invoice/Invoice';
|
||||
import { SalesQuoteItem } from '../SalesQuoteItem/SalesQuoteItem';
|
||||
|
||||
export class SalesQuote extends Invoice {
|
||||
items?: SalesQuoteItem[];
|
||||
|
||||
async getPosting() {
|
||||
return null;
|
||||
}
|
||||
|
||||
async getInvoice(): Promise<Invoice | null> {
|
||||
if (!this.isSubmitted) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const schemaName = ModelNameEnum.SalesInvoice;
|
||||
const defaults = (this.fyo.singles.Defaults as Defaults) ?? {};
|
||||
const terms = defaults.salesInvoiceTerms ?? '';
|
||||
const numberSeries = defaults.salesInvoiceNumberSeries ?? undefined;
|
||||
|
||||
const data = {
|
||||
...this,
|
||||
date: new Date().toISOString(),
|
||||
terms,
|
||||
numberSeries,
|
||||
quote: this.name,
|
||||
items: []
|
||||
};
|
||||
|
||||
const invoice = this.fyo.doc.getNewDoc(schemaName, data) as Invoice;
|
||||
for (const row of this.items ?? []) {
|
||||
await invoice.append('items', {
|
||||
...row
|
||||
});
|
||||
}
|
||||
|
||||
if (!invoice.items?.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return invoice;
|
||||
}
|
||||
|
||||
static getListViewSettings(): ListViewSettings {
|
||||
return {
|
||||
columns: [
|
||||
'name',
|
||||
getTransactionStatusColumn(),
|
||||
'party',
|
||||
'date',
|
||||
'baseGrandTotal',
|
||||
'outstandingAmount',
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
static getActions(fyo: Fyo): Action[] {
|
||||
return getQuoteActions(fyo, ModelNameEnum.SalesQuote);
|
||||
}
|
||||
}
|
3
models/baseModels/SalesQuoteItem/SalesQuoteItem.ts
Normal file
3
models/baseModels/SalesQuoteItem/SalesQuoteItem.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { InvoiceItem } from '../InvoiceItem/InvoiceItem';
|
||||
|
||||
export class SalesQuoteItem extends InvoiceItem {}
|
@ -15,6 +15,15 @@ import { StockMovement } from './inventory/StockMovement';
|
||||
import { StockTransfer } from './inventory/StockTransfer';
|
||||
import { InvoiceStatus, ModelNameEnum } from './types';
|
||||
|
||||
export function getQuoteActions(
|
||||
fyo: Fyo,
|
||||
schemaName: ModelNameEnum.SalesQuote
|
||||
): Action[] {
|
||||
return [
|
||||
getMakeInvoiceAction(fyo, schemaName),
|
||||
];
|
||||
}
|
||||
|
||||
export function getInvoiceActions(
|
||||
fyo: Fyo,
|
||||
schemaName: ModelNameEnum.SalesInvoice | ModelNameEnum.PurchaseInvoice
|
||||
@ -67,7 +76,7 @@ export function getMakeStockTransferAction(
|
||||
|
||||
export function getMakeInvoiceAction(
|
||||
fyo: Fyo,
|
||||
schemaName: ModelNameEnum.Shipment | ModelNameEnum.PurchaseReceipt
|
||||
schemaName: ModelNameEnum.Shipment | ModelNameEnum.PurchaseReceipt | ModelNameEnum.SalesQuote
|
||||
): Action {
|
||||
let label = fyo.t`Sales Invoice`;
|
||||
if (schemaName === ModelNameEnum.PurchaseReceipt) {
|
||||
@ -77,9 +86,15 @@ export function getMakeInvoiceAction(
|
||||
return {
|
||||
label,
|
||||
group: fyo.t`Create`,
|
||||
condition: (doc: Doc) => doc.isSubmitted && !doc.backReference,
|
||||
condition: (doc: Doc) => {
|
||||
if (schemaName === ModelNameEnum.SalesQuote) {
|
||||
return doc.isSubmitted
|
||||
} else {
|
||||
return doc.isSubmitted && !doc.backReference
|
||||
}
|
||||
},
|
||||
action: async (doc: Doc) => {
|
||||
const invoice = await (doc as StockTransfer).getInvoice();
|
||||
let invoice = await (doc as SalesQuote | StockTransfer).getInvoice();
|
||||
if (!invoice || !invoice.name) {
|
||||
return;
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ import { PurchaseInvoice } from './baseModels/PurchaseInvoice/PurchaseInvoice';
|
||||
import { PurchaseInvoiceItem } from './baseModels/PurchaseInvoiceItem/PurchaseInvoiceItem';
|
||||
import { SalesInvoice } from './baseModels/SalesInvoice/SalesInvoice';
|
||||
import { SalesInvoiceItem } from './baseModels/SalesInvoiceItem/SalesInvoiceItem';
|
||||
import { SalesQuote } from './baseModels/SalesQuote/SalesQuote';
|
||||
import { SalesQuoteItem } from './baseModels/SalesQuoteItem/SalesQuoteItem';
|
||||
import { SetupWizard } from './baseModels/SetupWizard/SetupWizard';
|
||||
import { Tax } from './baseModels/Tax/Tax';
|
||||
import { TaxSummary } from './baseModels/TaxSummary/TaxSummary';
|
||||
@ -61,6 +63,8 @@ export const models = {
|
||||
PurchaseInvoiceItem,
|
||||
SalesInvoice,
|
||||
SalesInvoiceItem,
|
||||
SalesQuote,
|
||||
SalesQuoteItem,
|
||||
SerialNumber,
|
||||
SetupWizard,
|
||||
PrintTemplate,
|
||||
|
@ -27,6 +27,8 @@ export enum ModelNameEnum {
|
||||
PurchaseInvoiceItem = 'PurchaseInvoiceItem',
|
||||
SalesInvoice = 'SalesInvoice',
|
||||
SalesInvoiceItem = 'SalesInvoiceItem',
|
||||
SalesQuote = 'SalesQuote',
|
||||
SalesQuoteItem = 'SalesQuoteItem',
|
||||
SerialNumber = 'SerialNumber',
|
||||
SetupWizard = 'SetupWizard',
|
||||
Tax = 'Tax',
|
||||
|
@ -92,6 +92,14 @@
|
||||
"create": true,
|
||||
"section": "Number Series"
|
||||
},
|
||||
{
|
||||
"fieldname": "salesQuoteNumberSeries",
|
||||
"label": "Sales Quote Number Series",
|
||||
"fieldtype": "Link",
|
||||
"target": "NumberSeries",
|
||||
"create": true,
|
||||
"section": "Number Series"
|
||||
},
|
||||
{
|
||||
"fieldname": "salesInvoiceTerms",
|
||||
"label": "Sales Invoice Terms",
|
||||
@ -116,6 +124,13 @@
|
||||
"fieldtype": "Text",
|
||||
"section": "Terms"
|
||||
},
|
||||
{
|
||||
"fieldname": "salesQuotePrintTemplate",
|
||||
"label": "Sales Quote Print Template",
|
||||
"fieldtype": "Link",
|
||||
"target": "PrintTemplate",
|
||||
"section": "Print Templates"
|
||||
},
|
||||
{
|
||||
"fieldname": "salesInvoicePrintTemplate",
|
||||
"label": "Sales Invoice Print Template",
|
||||
|
@ -35,6 +35,10 @@
|
||||
"value": "SalesInvoice",
|
||||
"label": "Sales Invoice"
|
||||
},
|
||||
{
|
||||
"value": "SalesQuote",
|
||||
"label": "Sales Quote"
|
||||
},
|
||||
{
|
||||
"value": "PurchaseInvoice",
|
||||
"label": "Purchase Invoice"
|
||||
|
@ -31,6 +31,14 @@
|
||||
"target": "Shipment",
|
||||
"section": "References"
|
||||
},
|
||||
{
|
||||
"fieldname": "quote",
|
||||
"label": "Quote Reference",
|
||||
"fieldtype": "Link",
|
||||
"target": "SalesQuote",
|
||||
"section": "References",
|
||||
"required": false
|
||||
},
|
||||
{
|
||||
"fieldname": "makeAutoStockTransfer",
|
||||
"label": "Make Shipment On Submit",
|
||||
|
58
schemas/app/SalesQuote.json
Normal file
58
schemas/app/SalesQuote.json
Normal file
@ -0,0 +1,58 @@
|
||||
{
|
||||
"name": "SalesQuote",
|
||||
"label": "Quote",
|
||||
"extends": "Invoice",
|
||||
"naming": "numberSeries",
|
||||
"showTitle": true,
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "numberSeries",
|
||||
"label": "Number Series",
|
||||
"fieldtype": "Link",
|
||||
"target": "NumberSeries",
|
||||
"create": true,
|
||||
"required": true,
|
||||
"default": "SQUOT-",
|
||||
"section": "Default"
|
||||
},
|
||||
{
|
||||
"fieldname": "account",
|
||||
"drop": true
|
||||
},
|
||||
{
|
||||
"fieldname": "stockNotTransferred",
|
||||
"drop": true
|
||||
},
|
||||
{
|
||||
"fieldname": "backReference",
|
||||
"drop": true
|
||||
},
|
||||
{
|
||||
"fieldname": "makeAutoStockTransfer",
|
||||
"drop": true
|
||||
},
|
||||
{
|
||||
"fieldname": "returnAgainst",
|
||||
"drop": true
|
||||
},
|
||||
{
|
||||
"fieldname": "party",
|
||||
"label": "Customer",
|
||||
"fieldtype": "Link",
|
||||
"target": "Party",
|
||||
"create": true,
|
||||
"required": true,
|
||||
"section": "Default"
|
||||
},
|
||||
{
|
||||
"fieldname": "items",
|
||||
"label": "Items",
|
||||
"fieldtype": "Table",
|
||||
"target": "SalesQuoteItem",
|
||||
"required": true,
|
||||
"edit": true,
|
||||
"section": "Items"
|
||||
}
|
||||
],
|
||||
"keywordFields": ["name", "party"]
|
||||
}
|
5
schemas/app/SalesQuoteItem.json
Normal file
5
schemas/app/SalesQuoteItem.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "SalesQuoteItem",
|
||||
"label": "Sales Quote Item",
|
||||
"extends": "InvoiceItem"
|
||||
}
|
@ -197,8 +197,12 @@ function getCombined(
|
||||
const combined = Object.assign(abstractSchema, extendingSchema);
|
||||
|
||||
for (const fieldname in extendingFields) {
|
||||
if (extendingFields[fieldname].drop) {
|
||||
delete abstractFields[fieldname]
|
||||
} else {
|
||||
abstractFields[fieldname] = extendingFields[fieldname];
|
||||
}
|
||||
}
|
||||
|
||||
combined.fields = getListFromMap(abstractFields);
|
||||
return combined;
|
||||
|
@ -25,6 +25,8 @@ import PurchaseInvoice from './app/PurchaseInvoice.json';
|
||||
import PurchaseInvoiceItem from './app/PurchaseInvoiceItem.json';
|
||||
import SalesInvoice from './app/SalesInvoice.json';
|
||||
import SalesInvoiceItem from './app/SalesInvoiceItem.json';
|
||||
import SalesQuote from './app/SalesQuote.json';
|
||||
import SalesQuoteItem from './app/SalesQuoteItem.json';
|
||||
import SetupWizard from './app/SetupWizard.json';
|
||||
import Tax from './app/Tax.json';
|
||||
import TaxDetail from './app/TaxDetail.json';
|
||||
@ -108,10 +110,12 @@ export const appSchemas: Schema[] | SchemaStub[] = [
|
||||
Invoice as Schema,
|
||||
SalesInvoice as Schema,
|
||||
PurchaseInvoice as Schema,
|
||||
SalesQuote as Schema,
|
||||
|
||||
InvoiceItem as Schema,
|
||||
SalesInvoiceItem as SchemaStub,
|
||||
PurchaseInvoiceItem as SchemaStub,
|
||||
SalesQuoteItem as SchemaStub,
|
||||
|
||||
PriceList as Schema,
|
||||
PriceListItem as SchemaStub,
|
||||
|
@ -150,6 +150,7 @@
|
||||
v-if="showDevMode"
|
||||
class="text-xs text-gray-500 select-none cursor-pointer"
|
||||
@click="showDevMode = false"
|
||||
title="Open dev tools with Ctrl+Shift+I"
|
||||
>
|
||||
dev mode
|
||||
</p>
|
||||
|
71
src/pages/TemplateBuilder/SetType.vue
Normal file
71
src/pages/TemplateBuilder/SetType.vue
Normal file
@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<div class="w-form">
|
||||
<FormHeader :form-title="t`Set Print Size`" />
|
||||
<hr />
|
||||
<div class="p-4 w-full flex flex-col gap-4">
|
||||
<p class="text-base text-gray-900">
|
||||
{{
|
||||
t`Select the template type.`
|
||||
}}
|
||||
</p>
|
||||
<Select
|
||||
:df="df"
|
||||
:value="type"
|
||||
:border="true"
|
||||
:show-label="true"
|
||||
@change="typeChange"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex border-t p-4">
|
||||
<Button class="ml-auto" type="primary" @click="done">{{
|
||||
t`Done`
|
||||
}}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { PrintTemplate } from 'models/baseModels/PrintTemplate';
|
||||
import { OptionField } from 'schemas/types';
|
||||
import Button from 'src/components/Button.vue';
|
||||
import Float from 'src/components/Controls/Float.vue';
|
||||
import Select from 'src/components/Controls/Select.vue';
|
||||
import FormHeader from 'src/components/FormHeader.vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
type SizeName = typeof printSizes[number];
|
||||
export default defineComponent({
|
||||
components: { FormHeader, Select, Button },
|
||||
props: { doc: { type: PrintTemplate, required: true } },
|
||||
emits: ['done'],
|
||||
data() {
|
||||
return { type: 'SalesInvoice' };
|
||||
},
|
||||
computed: {
|
||||
df(): OptionField {
|
||||
const options = PrintTemplate.lists.type(this.doc)
|
||||
return {
|
||||
...fyo.getField('PrintTemplate', 'type'),
|
||||
options,
|
||||
fieldtype: 'Select',
|
||||
default: options[0].value
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.type = this.doc.type ?? 'SalesInvoice';
|
||||
},
|
||||
methods: {
|
||||
typeChange(v: string) {
|
||||
if (this.type === v) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.type = v;
|
||||
},
|
||||
async done() {
|
||||
await this.doc.set('type', this.type);
|
||||
this.$emit('done');
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
@ -213,6 +213,13 @@
|
||||
>
|
||||
<SetPrintSize :doc="doc" @done="showSizeModal = !showSizeModal" />
|
||||
</Modal>
|
||||
<Modal
|
||||
v-if="doc"
|
||||
:open-modal="showTypeModal"
|
||||
@closemodal="showTypeModal = !showTypeModal"
|
||||
>
|
||||
<SetType :doc="doc" @done="showTypeModal = !showTypeModal" />
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
@ -256,6 +263,7 @@ import { getMapFromList } from 'utils/index';
|
||||
import { computed, defineComponent, inject, ref } from 'vue';
|
||||
import PrintContainer from './PrintContainer.vue';
|
||||
import SetPrintSize from './SetPrintSize.vue';
|
||||
import SetType from './SetType.vue';
|
||||
import TemplateBuilderHint from './TemplateBuilderHint.vue';
|
||||
import TemplateEditor from './TemplateEditor.vue';
|
||||
|
||||
@ -273,6 +281,7 @@ export default defineComponent({
|
||||
Link,
|
||||
Modal,
|
||||
SetPrintSize,
|
||||
SetType,
|
||||
},
|
||||
provide() {
|
||||
return { doc: computed(() => this.doc) };
|
||||
@ -303,6 +312,7 @@ export default defineComponent({
|
||||
scale: 0.6,
|
||||
panelWidth: 22 /** rem */ * 16 /** px */,
|
||||
templateChanged: false,
|
||||
showTypeModal: false,
|
||||
showSizeModal: false,
|
||||
preEditMode: {
|
||||
scale: 0.6,
|
||||
@ -315,6 +325,7 @@ export default defineComponent({
|
||||
hints?: PrintTemplateHint;
|
||||
values: null | PrintValues;
|
||||
displayDoc: PrintTemplate | null;
|
||||
showTypeModal: boolean;
|
||||
showSizeModal: boolean;
|
||||
scale: number;
|
||||
panelWidth: number;
|
||||
@ -367,6 +378,14 @@ export default defineComponent({
|
||||
},
|
||||
});
|
||||
|
||||
if (this.doc.isCustom && !this.showTypeModal) {
|
||||
actions.push({
|
||||
label: this.t`Set Template Type`,
|
||||
group: this.t`Action`,
|
||||
action: () => (this.showTypeModal = true),
|
||||
});
|
||||
}
|
||||
|
||||
if (this.doc.isCustom && !this.showSizeModal) {
|
||||
actions.push({
|
||||
label: this.t`Set Print Size`,
|
||||
|
@ -347,6 +347,7 @@ function getNameAndTypeFromTemplateFile(
|
||||
* If the SchemaName is absent then it is assumed
|
||||
* that the SchemaName is:
|
||||
* - SalesInvoice
|
||||
* - SalesQuote
|
||||
* - PurchaseInvoice
|
||||
*/
|
||||
|
||||
@ -359,7 +360,7 @@ function getNameAndTypeFromTemplateFile(
|
||||
return [{ name: `${name} - ${label}`, type: schemaName }];
|
||||
}
|
||||
|
||||
return [ModelNameEnum.SalesInvoice, ModelNameEnum.PurchaseInvoice].map(
|
||||
return [ModelNameEnum.SalesInvoice, ModelNameEnum.SalesQuote, ModelNameEnum.PurchaseInvoice].map(
|
||||
(schemaName) => {
|
||||
const label = fyo.schemaMap[schemaName]?.label ?? schemaName;
|
||||
return { name: `${name} - ${label}`, type: schemaName };
|
||||
|
@ -169,6 +169,12 @@ function getCompleteSidebar(): SidebarConfig {
|
||||
icon: 'sales',
|
||||
route: '/list/SalesInvoice',
|
||||
items: [
|
||||
{
|
||||
label: t`Sales Quotes`,
|
||||
name: 'sales-quotes',
|
||||
route: '/list/SalesQuote',
|
||||
schemaName: 'SalesQuote',
|
||||
},
|
||||
{
|
||||
label: t`Sales Invoices`,
|
||||
name: 'sales-invoices',
|
||||
|
@ -52,8 +52,8 @@ Accounts,Comptes,
|
||||
"Accounts Payable","Comptes créditeurs",
|
||||
"Accounts Receivable","Comptes débiteurs",
|
||||
"Accumulated Depreciation","Amortissement cumulé",
|
||||
Action,,
|
||||
Active,,
|
||||
Action,Action,
|
||||
Active,Actif,
|
||||
"Add Account","Ajouter un compte",
|
||||
"Add Customers","Ajouter des clients",
|
||||
"Add Group","Ajouter un groupe",
|
||||
@ -689,6 +689,8 @@ Quarterly,Trimestriel,
|
||||
Quarters,Trimestres,
|
||||
"Quick Search",,
|
||||
"Quick edit error: ${0} entry has no name.",,
|
||||
"Quote","Devis",
|
||||
"Quote Reference","Référence du devis",
|
||||
Rate,Tarif,
|
||||
"Rate (${0}) cannot be less zero.","Le Tarif (${0}) ne peut pas être inférieur à zéro.",
|
||||
"Rate (${0}) has to be greater than zero",,
|
||||
@ -739,6 +741,9 @@ Sales,Ventes,
|
||||
"Sales Acc.",,
|
||||
"Sales Expenses","Frais de vente",
|
||||
"Sales Invoice","Facture de vente",
|
||||
"Sales Quote","Devis de vente",
|
||||
"Sales Quote Number Series",,
|
||||
"Sales Quote Print Template",,
|
||||
"Sales Invoice Item","Facture de vente d'article",
|
||||
"Sales Invoice Number Series",,
|
||||
"Sales Invoice Print Template",,
|
||||
@ -792,7 +797,8 @@ September,,
|
||||
Service,,
|
||||
"Set Discount Amount","Définir le montant de la réduction",
|
||||
"Set Period",,
|
||||
"Set Print Size",,
|
||||
"Set Print Size","Définir le format de page",
|
||||
"Set Template Type","Définir le type de modèle",
|
||||
"Set Up",Configurer,
|
||||
"Set Up Your Workspace","Configurez votre espace de travail",
|
||||
"Set a Template value to see the Print Template",,
|
||||
|
|
Loading…
Reference in New Issue
Block a user