Initial for #123
This commit is contained in:
@@ -127,6 +127,13 @@
|
||||
"when": 1771704862789,
|
||||
"tag": "0017_slow_the_hood",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 18,
|
||||
"version": "7",
|
||||
"when": 1773000900000,
|
||||
"tag": "0018_account_chart",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -16,6 +16,7 @@ export const accounts = pgTable("accounts", {
|
||||
|
||||
number: text("number").notNull(),
|
||||
label: text("label").notNull(),
|
||||
accountChart: text("accountChart").notNull().default("skr03"),
|
||||
|
||||
description: text("description"),
|
||||
})
|
||||
|
||||
@@ -94,6 +94,7 @@ export const tenants = pgTable(
|
||||
projects: { prefix: "PRJ-", suffix: "", nextNumber: 1000 },
|
||||
costcentres: { prefix: "KST-", suffix: "", nextNumber: 1000 },
|
||||
}),
|
||||
accountChart: text("accountChart").notNull().default("skr03"),
|
||||
|
||||
standardEmailForInvoices: text("standardEmailForInvoices"),
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@ export default async function adminRoutes(server: FastifyInstance) {
|
||||
short: tenants.short,
|
||||
locked: tenants.locked,
|
||||
numberRanges: tenants.numberRanges,
|
||||
accountChart: tenants.accountChart,
|
||||
extraModules: tenants.extraModules,
|
||||
})
|
||||
.from(authTenantUsers)
|
||||
|
||||
@@ -54,6 +54,7 @@ export default async function meRoutes(server: FastifyInstance) {
|
||||
extraModules: tenants.extraModules,
|
||||
businessInfo: tenants.businessInfo,
|
||||
numberRanges: tenants.numberRanges,
|
||||
accountChart: tenants.accountChart,
|
||||
dokuboxkey: tenants.dokuboxkey,
|
||||
standardEmailForInvoices: tenants.standardEmailForInvoices,
|
||||
standardPaymentDays: tenants.standardPaymentDays,
|
||||
|
||||
@@ -586,6 +586,9 @@ export default async function resourceRoutes(server: FastifyInstance) {
|
||||
try {
|
||||
if (!req.user?.tenant_id) return reply.code(400).send({ error: "No tenant selected" });
|
||||
const { resource } = req.params as { resource: string };
|
||||
if (resource === "accounts") {
|
||||
return reply.code(403).send({ error: "Accounts are read-only" })
|
||||
}
|
||||
const body = req.body as Record<string, any>;
|
||||
const config = resourceConfig[resource];
|
||||
const table = config.table;
|
||||
@@ -656,6 +659,9 @@ export default async function resourceRoutes(server: FastifyInstance) {
|
||||
server.put("/resource/:resource/:id", async (req, reply) => {
|
||||
try {
|
||||
const { resource, id } = req.params as { resource: string; id: string }
|
||||
if (resource === "accounts") {
|
||||
return reply.code(403).send({ error: "Accounts are read-only" })
|
||||
}
|
||||
const body = req.body as Record<string, any>
|
||||
const tenantId = req.user?.tenant_id
|
||||
const userId = req.user?.user_id
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { FastifyInstance } from "fastify"
|
||||
import { asc, desc } from "drizzle-orm"
|
||||
import { asc, desc, eq } from "drizzle-orm"
|
||||
import { sortData } from "../utils/sort"
|
||||
|
||||
// Schema imports
|
||||
import { accounts, units,countrys } from "../../db/schema"
|
||||
import { accounts, units, countrys, tenants } from "../../db/schema"
|
||||
|
||||
const TABLE_MAP: Record<string, any> = {
|
||||
accounts,
|
||||
@@ -40,6 +40,44 @@ export default async function resourceRoutesSpecial(server: FastifyInstance) {
|
||||
// Wir geben IMMER alle Spalten zurück → kompatibel zum Frontend
|
||||
// ---------------------------------------
|
||||
|
||||
if (resource === "accounts") {
|
||||
const [tenant] = await server.db
|
||||
.select({
|
||||
accountChart: tenants.accountChart,
|
||||
})
|
||||
.from(tenants)
|
||||
.where(eq(tenants.id, Number(req.user.tenant_id)))
|
||||
.limit(1)
|
||||
|
||||
const activeAccountChart = tenant?.accountChart || "skr03"
|
||||
let data
|
||||
if (sort && (accounts as any)[sort]) {
|
||||
const col = (accounts as any)[sort]
|
||||
data = ascQuery === "true"
|
||||
? await server.db
|
||||
.select()
|
||||
.from(accounts)
|
||||
.where(eq(accounts.accountChart, activeAccountChart))
|
||||
.orderBy(asc(col))
|
||||
: await server.db
|
||||
.select()
|
||||
.from(accounts)
|
||||
.where(eq(accounts.accountChart, activeAccountChart))
|
||||
.orderBy(desc(col))
|
||||
} else {
|
||||
data = await server.db
|
||||
.select()
|
||||
.from(accounts)
|
||||
.where(eq(accounts.accountChart, activeAccountChart))
|
||||
}
|
||||
|
||||
return sortData(
|
||||
data,
|
||||
sort as any,
|
||||
ascQuery === "true"
|
||||
)
|
||||
}
|
||||
|
||||
let query = server.db.select().from(table)
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
@@ -11,7 +11,7 @@ import { s3 } from "./s3";
|
||||
import { secrets } from "./secrets";
|
||||
|
||||
// Drizzle schema
|
||||
import { vendors, accounts } from "../../db/schema";
|
||||
import { vendors, accounts, tenants } from "../../db/schema";
|
||||
import {eq} from "drizzle-orm";
|
||||
|
||||
let openai: OpenAI | null = null;
|
||||
@@ -163,13 +163,22 @@ export const getInvoiceDataFromGPT = async function (
|
||||
.from(vendors)
|
||||
.where(eq(vendors.tenant,tenantId));
|
||||
|
||||
const [tenant] = await server.db
|
||||
.select({ accountChart: tenants.accountChart })
|
||||
.from(tenants)
|
||||
.where(eq(tenants.id, tenantId))
|
||||
.limit(1)
|
||||
|
||||
const activeAccountChart = tenant?.accountChart || "skr03"
|
||||
|
||||
const accountList = await server.db
|
||||
.select({
|
||||
id: accounts.id,
|
||||
label: accounts.label,
|
||||
number: accounts.number,
|
||||
})
|
||||
.from(accounts);
|
||||
.from(accounts)
|
||||
.where(eq(accounts.accountChart, activeAccountChart));
|
||||
|
||||
// ---------------------------------------------------------
|
||||
// 4) GPT ANALYSIS
|
||||
|
||||
@@ -15,6 +15,11 @@ const setupPage = async () => {
|
||||
|
||||
const features = ref(auth.activeTenantData.features)
|
||||
const businessInfo = ref(auth.activeTenantData.businessInfo)
|
||||
const accountChart = ref(auth.activeTenantData.accountChart || "skr03")
|
||||
const accountChartOptions = [
|
||||
{ label: "SKR 03", value: "skr03" },
|
||||
{ label: "Verein", value: "verein" }
|
||||
]
|
||||
|
||||
const updateTenant = async (newData) => {
|
||||
|
||||
@@ -24,6 +29,11 @@ const updateTenant = async (newData) => {
|
||||
data: newData,
|
||||
}
|
||||
})
|
||||
|
||||
if (res) {
|
||||
itemInfo.value = res
|
||||
auth.activeTenantData = res
|
||||
}
|
||||
}
|
||||
|
||||
setupPage()
|
||||
@@ -90,6 +100,23 @@ setupPage()
|
||||
>
|
||||
Speichern
|
||||
</UButton>
|
||||
<UFormGroup
|
||||
label="Kontenrahmen:"
|
||||
class="mt-6"
|
||||
>
|
||||
<USelectMenu
|
||||
v-model="accountChart"
|
||||
:options="accountChartOptions"
|
||||
option-attribute="label"
|
||||
value-attribute="value"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<UButton
|
||||
class="mt-3"
|
||||
@click="updateTenant({accountChart: accountChart})"
|
||||
>
|
||||
Kontenrahmen speichern
|
||||
</UButton>
|
||||
</UForm>
|
||||
</UCard>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user