negative amount validation added

This commit is contained in:
laxmanhalaki 2026-03-19 16:25:15 +05:30
parent 41b8b57efe
commit bf7574734e
6 changed files with 127 additions and 81 deletions

View File

@ -1 +1 @@
import{a as s}from"./index-BACqZT24.js";import"./radix-vendor-CYvDqP9X.js";import"./charts-vendor-BVfwAPj-.js";import"./utils-vendor-BTBPSQfW.js";import"./ui-vendor-BrA5VgBk.js";import"./socket-vendor-TjCxX7sJ.js";import"./redux-vendor-tbZCm13o.js";import"./router-vendor-BATWUvr6.js";async function m(n){return(await s.post(`/conclusions/${n}/generate`)).data.data}async function f(n,t){return(await s.post(`/conclusions/${n}/finalize`,{finalRemark:t})).data.data}async function d(n){var t;try{return(await s.get(`/conclusions/${n}`)).data.data}catch(o){if(((t=o.response)==null?void 0:t.status)===404)return null;throw o}}export{f as finalizeConclusion,m as generateConclusion,d as getConclusion};
import{a as s}from"./index-FNvbaKic.js";import"./radix-vendor-CYvDqP9X.js";import"./charts-vendor-BVfwAPj-.js";import"./utils-vendor-BTBPSQfW.js";import"./ui-vendor-BrA5VgBk.js";import"./socket-vendor-TjCxX7sJ.js";import"./redux-vendor-tbZCm13o.js";import"./router-vendor-BATWUvr6.js";async function m(n){return(await s.post(`/conclusions/${n}/generate`)).data.data}async function f(n,t){return(await s.post(`/conclusions/${n}/finalize`,{finalRemark:t})).data.data}async function d(n){var t;try{return(await s.get(`/conclusions/${n}`)).data.data}catch(o){if(((t=o.response)==null?void 0:t.status)===404)return null;throw o}}export{f as finalizeConclusion,m as generateConclusion,d as getConclusion};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -13,7 +13,7 @@
<!-- Preload essential fonts and icons -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<script type="module" crossorigin src="/assets/index-BACqZT24.js"></script>
<script type="module" crossorigin src="/assets/index-FNvbaKic.js"></script>
<link rel="modulepreload" crossorigin href="/assets/charts-vendor-BVfwAPj-.js">
<link rel="modulepreload" crossorigin href="/assets/radix-vendor-CYvDqP9X.js">
<link rel="modulepreload" crossorigin href="/assets/utils-vendor-BTBPSQfW.js">

View File

@ -19,6 +19,7 @@ import { ActivityType } from '../models/ActivityType';
import { Participant } from '../models/Participant';
import { sanitizeObject, sanitizePermissive } from '../utils/sanitizer';
import { padDealerCode } from '../utils/helpers';
import { costBreakupSchema, closedExpensesSchema, updateEInvoiceSchema, updateIOSchema } from '../validators/dealerClaim.validator';
export class DealerClaimController {
private dealerClaimService = new DealerClaimService();
@ -213,17 +214,15 @@ export class DealerClaimController {
}
}
// Validate costBreakup is an array
if (!Array.isArray(parsedCostBreakup)) {
logger.error('[DealerClaimController] costBreakup is not an array after parsing:', parsedCostBreakup);
return ResponseHandler.error(res, 'costBreakup must be an array of cost items', 400);
}
// Validate each cost item has required fields
for (const item of parsedCostBreakup) {
if (!item.description || item.amount === undefined || item.amount === null) {
return ResponseHandler.error(res, 'Each cost item must have description and amount', 400);
}
// Validate costBreakup array using Zod schema
const costValidation = costBreakupSchema.safeParse(parsedCostBreakup);
if (!costValidation.success) {
return ResponseHandler.error(
res,
`Invalid cost breakup data: ${costValidation.error.errors.map((e: any) => e.message).join(', ')}`,
400
);
}
// Handle file upload if present
@ -300,6 +299,16 @@ export class DealerClaimController {
}
}
// Validate closed expenses using Zod schema
const expenseValidation = closedExpensesSchema.safeParse(parsedClosedExpenses);
if (!expenseValidation.success) {
return ResponseHandler.error(
res,
`Invalid closed expenses: ${expenseValidation.error.errors.map((e: any) => e.message).join(', ')}`,
400
);
}
// Get files from multer
const files = req.files as { [fieldname: string]: Express.Multer.File[] } | undefined;
const completionDocumentsFiles = files?.completionDocuments || [];
@ -654,8 +663,14 @@ export class DealerClaimController {
return ResponseHandler.error(res, 'Invalid workflow request', 400);
}
if (!ioNumber) {
return ResponseHandler.error(res, 'IO number is required', 400);
// Validate request body using Zod schema
const ioValidation = updateIOSchema.safeParse(req.body);
if (!ioValidation.success) {
return ResponseHandler.error(
res,
`Invalid IO details: ${ioValidation.error.errors.map((e: any) => e.message).join(', ')}`,
400
);
}
const blockAmount = blockedAmount ? parseFloat(blockedAmount) : 0;
@ -760,6 +775,16 @@ export class DealerClaimController {
description,
} = req.body;
// Validate request body using Zod schema
const einvoiceValidation = updateEInvoiceSchema.safeParse(req.body);
if (!einvoiceValidation.success) {
return ResponseHandler.error(
res,
`Invalid e-invoice details: ${einvoiceValidation.error.errors.map((e: any) => e.message).join(', ')}`,
400
);
}
// Find workflow to get actual UUID
const workflow = await this.findWorkflowByIdentifier(identifier);
if (!workflow) {

View File

@ -28,7 +28,7 @@ export const createClaimSchema = z.object({
export const updateIOSchema = z.object({
ioNumber: z.string().min(1, 'IO number is required').max(50, 'IO number too long'),
amount: z.number().positive('Amount must be positive').optional(),
amount: z.number().min(0, 'Amount cannot be negative').optional(),
requestNumber: z.string().max(50).optional(),
}).passthrough();
@ -39,6 +39,7 @@ export const updateEInvoiceSchema = z.object({
ackNumber: z.string().max(100, 'Acknowledgement number too long').optional(),
invoiceNumber: z.string().max(100, 'Invoice number too long').optional(),
invoiceDate: z.string().optional(),
amount: z.number().min(0, 'Amount cannot be negative').optional(),
}).passthrough();
// ── Credit Note Schema ──
@ -46,13 +47,33 @@ export const updateEInvoiceSchema = z.object({
export const sendCreditNoteSchema = z.object({
creditNoteNumber: z.string().max(100, 'Credit note number too long').optional(),
creditNoteDate: z.string().optional(),
creditNoteAmount: z.number().positive('Amount must be positive').optional(),
creditNoteAmount: z.number().min(0, 'Amount cannot be negative').optional(),
}).passthrough();
// ── SAP Test Schema ──
export const testSapBlockSchema = z.object({
ioNumber: z.string().min(1, 'IO number is required'),
amount: z.number().positive('Amount must be positive'),
amount: z.number().min(0, 'Amount cannot be negative'),
requestNumber: z.string().optional(),
});
// ── Proposal & Completion Schemas ──
export const costItemSchema = z.object({
description: z.string().min(1, 'Description is required'),
amount: z.number().min(0, 'Amount cannot be negative'),
quantity: z.number().min(1, 'Quantity must be at least 1').optional(),
totalAmt: z.number().min(0, 'Total amount cannot be negative').optional(),
}).passthrough();
export const costBreakupSchema = z.array(costItemSchema);
export const expenseItemSchema = z.object({
description: z.string().min(1, 'Description is required'),
amount: z.number().min(0, 'Amount cannot be negative'),
quantity: z.number().min(1, 'Quantity must be at least 1').optional(),
totalAmt: z.number().min(0, 'Total amount cannot be negative').optional(),
}).passthrough();
export const closedExpensesSchema = z.array(expenseItemSchema);