Add invoice verification system using NocoDB for automated data checks

Integrates NocoDB to verify invoice references and supplier matches, and allows searching by BL number to auto-populate delivery details, enhancing reconciliation accuracy and efficiency.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: c52a701b-4841-4d00-b8cf-5a41c12abdf3
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/c52a701b-4841-4d00-b8cf-5a41c12abdf3/3uCfEKb
This commit is contained in:
michaelschal committed 2025-08-13 09:11:48 +00:00
1 parent d418fda3c9
commit bc85434858
5 files changed
+528 -25

No files matched your search

+74
View File
@@ -37,6 +37,7 @@ import {
} from "@shared/schema";
import { hasPermission } from "@shared/permissions";
import { z } from "zod";
import { nocodbVerificationService } from "./services/nocodbVerification";
export async function registerRoutes(app: Express): Promise<Server> {
// Health check endpoint for Docker
@@ -889,6 +890,79 @@ export async function registerRoutes(app: Express): Promise<Server> {
}
});
// Routes de vérification NocoDB pour les factures
app.post('/api/deliveries/verify-invoice', isAuthenticated, async (req: any, res) => {
try {
const user = await storage.getUserWithGroups(req.user.claims ? req.user.claims.sub : req.user.id);
if (!user) {
return res.status(404).json({ message: "User not found" });
}
const { groupId, invoiceReference, supplierName } = req.body;
if (!groupId || !invoiceReference || !supplierName) {
return res.status(400).json({
message: "groupId, invoiceReference et supplierName sont requis"
});
}
// Vérifier les permissions d'accès au groupe
if (user.role !== 'admin') {
const userGroupIds = user.userGroups?.map((ug: any) => ug.groupId) || [];
if (!userGroupIds.includes(parseInt(groupId))) {
return res.status(403).json({ message: "Access denied to this group" });
}
}
const result = await nocodbVerificationService.verifyInvoiceReference(
parseInt(groupId),
invoiceReference,
supplierName
);
res.json(result);
} catch (error) {
console.error("Error verifying invoice:", error);
res.status(500).json({ message: "Failed to verify invoice" });
}
});
app.post('/api/deliveries/search-by-bl', isAuthenticated, async (req: any, res) => {
try {
const user = await storage.getUserWithGroups(req.user.claims ? req.user.claims.sub : req.user.id);
if (!user) {
return res.status(404).json({ message: "User not found" });
}
const { groupId, blNumber, supplierName } = req.body;
if (!groupId || !blNumber || !supplierName) {
return res.status(400).json({
message: "groupId, blNumber et supplierName sont requis"
});
}
// Vérifier les permissions d'accès au groupe
if (user.role !== 'admin') {
const userGroupIds = user.userGroups?.map((ug: any) => ug.groupId) || [];
if (!userGroupIds.includes(parseInt(groupId))) {
return res.status(403).json({ message: "Access denied to this group" });
}
}
const result = await nocodbVerificationService.searchByBLNumber(
parseInt(groupId),
blNumber,
supplierName
);
res.json(result);
} catch (error) {
console.error("Error searching by BL:", error);
res.status(500).json({ message: "Failed to search by BL number" });
}
});
// Statistics routes
app.get('/api/stats/monthly', isAuthenticated, async (req: any, res) => {
try {