mirror of
https://github.com/frappe/books.git
synced 2024-11-09 23:30:56 +00:00
incr: add inventory settings
This commit is contained in:
parent
b5f8e49299
commit
14138967c1
@ -43,16 +43,16 @@ export class Defaults extends Doc {
|
||||
static filters: FiltersMap = this.commonFilters;
|
||||
static createFilters: FiltersMap = this.commonFilters;
|
||||
|
||||
hideInventoryDefaults(): boolean {
|
||||
return !this.fyo.store.appFlags.getIsInventoryEnabled;
|
||||
getInventoryHidden() {
|
||||
return () => !this.fyo.store.appFlags.isInventoryEnabled;
|
||||
}
|
||||
|
||||
hidden: HiddenMap = {
|
||||
stockMovementNumberSeries: this.hideInventoryDefaults.bind(this),
|
||||
shipmentNumberSeries: this.hideInventoryDefaults.bind(this),
|
||||
purchaseReceiptNumberSeries: this.hideInventoryDefaults.bind(this),
|
||||
shipmentTerms: this.hideInventoryDefaults.bind(this),
|
||||
purchaseReceiptTerms: this.hideInventoryDefaults.bind(this),
|
||||
stockMovementNumberSeries: this.getInventoryHidden(),
|
||||
shipmentNumberSeries: this.getInventoryHidden(),
|
||||
purchaseReceiptNumberSeries: this.getInventoryHidden(),
|
||||
shipmentTerms: this.getInventoryHidden(),
|
||||
purchaseReceiptTerms: this.getInventoryHidden(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ import { SalesInvoiceItem } from './baseModels/SalesInvoiceItem/SalesInvoiceItem
|
||||
import { SetupWizard } from './baseModels/SetupWizard/SetupWizard';
|
||||
import { Tax } from './baseModels/Tax/Tax';
|
||||
import { TaxSummary } from './baseModels/TaxSummary/TaxSummary';
|
||||
import { InventorySettings } from './inventory/InventorySettings';
|
||||
import { Location } from './inventory/Location';
|
||||
import { PurchaseReceipt } from './inventory/PurchaseReceipt';
|
||||
import { PurchaseReceiptItem } from './inventory/PurchaseReceiptItem';
|
||||
@ -46,6 +47,7 @@ export const models = {
|
||||
Tax,
|
||||
TaxSummary,
|
||||
// Inventory Models
|
||||
InventorySettings,
|
||||
StockMovement,
|
||||
StockMovementItem,
|
||||
StockLedgerEntry,
|
||||
|
21
models/inventory/InventorySettings.ts
Normal file
21
models/inventory/InventorySettings.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { Doc } from 'fyo/model/doc';
|
||||
import { FiltersMap } from 'fyo/model/types';
|
||||
import { AccountTypeEnum } from 'models/baseModels/Account/types';
|
||||
import { valuationMethod } from './types';
|
||||
|
||||
export class InventorySettings extends Doc {
|
||||
stockInHand?: string;
|
||||
valuationMethod?: valuationMethod;
|
||||
stockInReceivedButNotBilled?: string;
|
||||
|
||||
static filters: FiltersMap = {
|
||||
stockInHand: () => ({
|
||||
isGroup: false,
|
||||
accountType: AccountTypeEnum.Stock,
|
||||
}),
|
||||
stockReceivedButNotBilled: () => ({
|
||||
isGroup: false,
|
||||
accountType: AccountTypeEnum['Stock Received But Not Billed'],
|
||||
}),
|
||||
};
|
||||
}
|
@ -29,6 +29,7 @@ export enum ModelNameEnum {
|
||||
TaxSummary = 'TaxSummary',
|
||||
PatchRun = 'PatchRun',
|
||||
SingleValue = 'SingleValue',
|
||||
InventorySettings = 'InventorySettings',
|
||||
SystemSettings = 'SystemSettings',
|
||||
StockMovement = 'StockMovement',
|
||||
StockMovementItem = 'StockMovementItem',
|
||||
|
39
schemas/app/inventory/InventorySettings.json
Normal file
39
schemas/app/inventory/InventorySettings.json
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "InventorySettings",
|
||||
"label": "Inventory Settings",
|
||||
"isSingle": true,
|
||||
"isChild": false,
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "valuationMethod",
|
||||
"label": "Valuation Method",
|
||||
"fieldtype": "Select",
|
||||
"options": [
|
||||
{
|
||||
"value": "FIFO",
|
||||
"label": "FIFO"
|
||||
},
|
||||
{
|
||||
"value": "MovingAverage",
|
||||
"label": "Moving Average"
|
||||
}
|
||||
],
|
||||
"default": "FIFO",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"fieldname": "stockInHand",
|
||||
"label": "Stock In Hand Acc.",
|
||||
"fieldtype": "Link",
|
||||
"target": "Account",
|
||||
"create": true
|
||||
},
|
||||
{
|
||||
"fieldname": "stockReceivedButNotBilled",
|
||||
"label": "Stock Received But Not Billed Acc.",
|
||||
"fieldtype": "Link",
|
||||
"target": "Account",
|
||||
"create": true
|
||||
}
|
||||
]
|
||||
}
|
@ -45,6 +45,7 @@ import child from './meta/child.json';
|
||||
import submittable from './meta/submittable.json';
|
||||
import tree from './meta/tree.json';
|
||||
import { Schema, SchemaStub } from './types';
|
||||
import InventorySettings from './app/inventory/InventorySettings.json';
|
||||
|
||||
export const coreSchemas: Schema[] = [
|
||||
PatchRun as Schema,
|
||||
@ -99,6 +100,7 @@ export const appSchemas: Schema[] | SchemaStub[] = [
|
||||
TaxDetail as Schema,
|
||||
TaxSummary as Schema,
|
||||
|
||||
InventorySettings as Schema,
|
||||
Location as Schema,
|
||||
StockLedgerEntry as Schema,
|
||||
StockMovement as Schema,
|
||||
|
@ -125,6 +125,11 @@ export default {
|
||||
focusFirstInput: Boolean,
|
||||
readOnly: { type: [null, Boolean], default: null },
|
||||
},
|
||||
watch: {
|
||||
doc() {
|
||||
this.setFormFields();
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
inlineEditDoc: null,
|
||||
@ -268,7 +273,7 @@ export default {
|
||||
try {
|
||||
await this.inlineEditDoc.sync();
|
||||
} catch (error) {
|
||||
return await handleErrorWithDialog(error, this.inlineEditDoc)
|
||||
return await handleErrorWithDialog(error, this.inlineEditDoc);
|
||||
}
|
||||
|
||||
await this.onChangeCommon(df, this.inlineEditDoc.name);
|
||||
|
@ -301,7 +301,9 @@ export default {
|
||||
this.creatingDemo = false;
|
||||
},
|
||||
async setFiles() {
|
||||
this.files = await ipcRenderer.invoke(IPC_ACTIONS.GET_DB_LIST);
|
||||
this.files = (await ipcRenderer.invoke(IPC_ACTIONS.GET_DB_LIST))?.sort(
|
||||
(a, b) => Date.parse(b.modified) - Date.parse(a.modified)
|
||||
);
|
||||
},
|
||||
async newDatabase() {
|
||||
if (this.creatingDemo) {
|
||||
|
@ -29,7 +29,11 @@
|
||||
|
||||
<!-- Component -->
|
||||
<div class="flex-1 overflow-y-auto custom-scroll">
|
||||
<component :is="activeTabComponent" @change="handleChange" />
|
||||
<component
|
||||
:is="tabs[activeTab].component"
|
||||
:schema-name="tabs[activeTab].schemaName"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</FormContainer>
|
||||
@ -47,11 +51,10 @@ import { docsPathMap } from 'src/utils/misc';
|
||||
import { docsPath, showToast } from 'src/utils/ui';
|
||||
import { IPC_MESSAGES } from 'utils/messages';
|
||||
import { h, markRaw } from 'vue';
|
||||
import TabDefaults from './TabDefaults.vue';
|
||||
import TabBase from './TabBase.vue';
|
||||
import TabGeneral from './TabGeneral.vue';
|
||||
import TabInvoice from './TabInvoice.vue';
|
||||
import TabSystem from './TabSystem.vue';
|
||||
|
||||
export default {
|
||||
name: 'Settings',
|
||||
components: {
|
||||
@ -70,21 +73,31 @@ export default {
|
||||
{
|
||||
key: 'Invoice',
|
||||
label: t`Invoice`,
|
||||
schemaName: 'PrintSettings',
|
||||
component: markRaw(TabInvoice),
|
||||
},
|
||||
{
|
||||
key: 'General',
|
||||
label: t`General`,
|
||||
schemaName: 'AccountingSettings',
|
||||
component: markRaw(TabGeneral),
|
||||
},
|
||||
{
|
||||
key: 'Defaults',
|
||||
label: t`Defaults`,
|
||||
component: markRaw(TabDefaults),
|
||||
schemaName: 'Defaults',
|
||||
component: markRaw(TabBase),
|
||||
},
|
||||
{
|
||||
key: 'Inventory',
|
||||
label: t`Inventory`,
|
||||
schemaName: 'InventorySettings',
|
||||
component: markRaw(TabBase),
|
||||
},
|
||||
{
|
||||
key: 'System',
|
||||
label: t`System`,
|
||||
schemaName: 'SystemSettings',
|
||||
component: markRaw(TabSystem),
|
||||
},
|
||||
],
|
||||
@ -154,10 +167,5 @@ export default {
|
||||
};
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
activeTabComponent() {
|
||||
return this.tabs[this.activeTab].component;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -12,15 +12,39 @@
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { Doc } from 'fyo/model/doc';
|
||||
import { Field } from 'schemas/types';
|
||||
import TwoColumnForm from 'src/components/TwoColumnForm.vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'TabGeneral',
|
||||
emits: ['change'],
|
||||
props: { schemaName: String },
|
||||
components: {
|
||||
TwoColumnForm,
|
||||
},
|
||||
async mounted() {
|
||||
await this.setDoc();
|
||||
},
|
||||
watch: {
|
||||
async schemaName() {
|
||||
await this.setDoc();
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async setDoc() {
|
||||
if (this.doc && this.schemaName === this.doc.schemaName) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.schemaName) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.doc = await this.fyo.doc.getDoc(this.schemaName, this.schemaName, {
|
||||
skipDocumentCache: true,
|
||||
});
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
doc: undefined,
|
||||
@ -28,8 +52,12 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
fields() {
|
||||
return [] as Field[];
|
||||
console.log(
|
||||
'changed',
|
||||
this.doc?.schema.fields.map(({ fieldname }) => fieldname).join(',')
|
||||
);
|
||||
return this.doc?.schema.fields;
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
@ -1,20 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { defineComponent } from 'vue';
|
||||
import TabBase from './TabBase.vue';
|
||||
|
||||
export default defineComponent({
|
||||
extends: TabBase,
|
||||
name: 'TabDefaults',
|
||||
async mounted() {
|
||||
this.doc = await fyo.doc.getDoc('Defaults', 'Defaults', {
|
||||
skipDocumentCache: true,
|
||||
});
|
||||
},
|
||||
computed: {
|
||||
fields() {
|
||||
return this.doc?.schema.fields;
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
@ -23,7 +23,6 @@ import { ModelNameEnum } from 'models/types';
|
||||
import LanguageSelector from 'src/components/Controls/LanguageSelector.vue';
|
||||
import TwoColumnForm from 'src/components/TwoColumnForm';
|
||||
import { fyo } from 'src/initFyo';
|
||||
import { getCountryInfo } from 'utils/misc';
|
||||
|
||||
export default {
|
||||
name: 'TabSystem',
|
||||
@ -42,7 +41,6 @@ export default {
|
||||
this.doc = fyo.singles.SystemSettings;
|
||||
this.companyName = fyo.singles.AccountingSettings.companyName;
|
||||
this.telemetry = fyo.config.get(ConfigKeys.Telemetry);
|
||||
window.gci = getCountryInfo;
|
||||
},
|
||||
computed: {
|
||||
fields() {
|
||||
|
@ -5,14 +5,23 @@ import { createNumberSeries } from 'fyo/model/naming';
|
||||
import {
|
||||
DEFAULT_CURRENCY,
|
||||
DEFAULT_LOCALE,
|
||||
DEFAULT_SERIES_START
|
||||
DEFAULT_SERIES_START,
|
||||
} from 'fyo/utils/consts';
|
||||
import { AccountRootTypeEnum } from 'models/baseModels/Account/types';
|
||||
import { ValueError } from 'fyo/utils/errors';
|
||||
import {
|
||||
AccountRootTypeEnum,
|
||||
AccountTypeEnum,
|
||||
} from 'models/baseModels/Account/types';
|
||||
import { AccountingSettings } from 'models/baseModels/AccountingSettings/AccountingSettings';
|
||||
import { numberSeriesDefaultsMap } from 'models/baseModels/Defaults/Defaults';
|
||||
import { InventorySettings } from 'models/inventory/InventorySettings';
|
||||
import { valuationMethod } from 'models/inventory/types';
|
||||
import { ModelNameEnum } from 'models/types';
|
||||
import { createRegionalRecords } from 'src/regional';
|
||||
import { initializeInstance, setCurrencySymbols } from 'src/utils/initialization';
|
||||
import {
|
||||
initializeInstance,
|
||||
setCurrencySymbols,
|
||||
} from 'src/utils/initialization';
|
||||
import { getRandomString } from 'utils';
|
||||
import { defaultUOMs } from 'utils/defaults';
|
||||
import { getCountryCodeFromCountry, getCountryInfo } from 'utils/misc';
|
||||
@ -39,6 +48,7 @@ export default async function setupInstance(
|
||||
await createRegionalRecords(country, fyo);
|
||||
await createDefaultEntries(fyo);
|
||||
await createDefaultNumberSeries(fyo);
|
||||
await updateInventorySettings(fyo);
|
||||
|
||||
await completeSetup(companyName, fyo);
|
||||
if (!Object.keys(fyo.currencySymbols).length) {
|
||||
@ -329,3 +339,40 @@ async function createDefaultNumberSeries(fyo: Fyo) {
|
||||
await fyo.singles.Defaults?.setAndSync(defaultKey as string, defaultValue);
|
||||
}
|
||||
}
|
||||
|
||||
async function updateInventorySettings(fyo: Fyo) {
|
||||
const inventorySettings = (await fyo.doc.getDoc(
|
||||
ModelNameEnum.InventorySettings
|
||||
)) as InventorySettings;
|
||||
|
||||
if (!inventorySettings.valuationMethod) {
|
||||
await inventorySettings.set('valuationMethod', valuationMethod.FIFO);
|
||||
}
|
||||
|
||||
const stockAccounts = (await fyo.db.getAllRaw('Account', {
|
||||
filters: { accountType: AccountTypeEnum.Stock, isGroup: false },
|
||||
})) as { name: string }[];
|
||||
|
||||
if (stockAccounts.length && !inventorySettings.stockInHand) {
|
||||
await inventorySettings.set('stockInHand', stockAccounts[0].name);
|
||||
}
|
||||
|
||||
const stockReceivedButNotBilled = (await fyo.db.getAllRaw('Account', {
|
||||
filters: {
|
||||
accountType: AccountTypeEnum['Stock Received But Not Billed'],
|
||||
isGroup: false,
|
||||
},
|
||||
})) as { name: string }[];
|
||||
|
||||
if (
|
||||
stockReceivedButNotBilled.length &&
|
||||
!inventorySettings.stockInReceivedButNotBilled
|
||||
) {
|
||||
await inventorySettings.set(
|
||||
'stockInReceivedButNotBilled',
|
||||
stockAccounts[0].name
|
||||
);
|
||||
}
|
||||
|
||||
await inventorySettings.sync();
|
||||
}
|
||||
|
@ -44,10 +44,13 @@ async function closeDbIfConnected(fyo: Fyo) {
|
||||
}
|
||||
|
||||
async function setSingles(fyo: Fyo) {
|
||||
await fyo.doc.getDoc(ModelNameEnum.AccountingSettings);
|
||||
await fyo.doc.getDoc(ModelNameEnum.GetStarted);
|
||||
await fyo.doc.getDoc(ModelNameEnum.Defaults);
|
||||
await fyo.doc.getDoc(ModelNameEnum.Misc);
|
||||
for (const schema of Object.values(fyo.schemaMap)) {
|
||||
if (!schema?.isSingle || schema.name === ModelNameEnum.SetupWizard) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await fyo.doc.getDoc(schema.name);
|
||||
}
|
||||
}
|
||||
|
||||
async function setCreds(fyo: Fyo) {
|
||||
|
Loading…
Reference in New Issue
Block a user