Compare commits
No commits in common. "1d4ec78360ea3afda7466adfc83feafd37d37393" and "eff824a4adbd635e8abc3bc2fe8b24ebb2a16b87" have entirely different histories.
1d4ec78360
...
eff824a4ad
16
fix_lower.cjs
Normal file
16
fix_lower.cjs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const files = [
|
||||||
|
'f:/WorkPlace/dev/krishnasales_mobile/src/components/forms/fields/SmartGridField.tsx',
|
||||||
|
'f:/WorkPlace/dev/krishnasales_mobile/src/components/forms/DynamicForm.tsx'
|
||||||
|
];
|
||||||
|
files.forEach(file => {
|
||||||
|
let content = fs.readFileSync(file, 'utf8');
|
||||||
|
content = content.replace(/col\.name\.toLowerCase/g, "(col.name || '').toLowerCase");
|
||||||
|
content = content.replace(/col\.id\.toLowerCase/g, "(col.id || '').toLowerCase");
|
||||||
|
content = content.replace(/c\.name\.toLowerCase/g, "(c.name || '').toLowerCase");
|
||||||
|
content = content.replace(/f\.id\.toLowerCase/g, "(f.id || '').toLowerCase");
|
||||||
|
content = content.replace(/f\.name\.toLowerCase/g, "(f.name || '').toLowerCase");
|
||||||
|
content = content.replace(/col\.mapped_workflow_field\?\.toLowerCase/g, "(col.mapped_workflow_field || '').toLowerCase");
|
||||||
|
fs.writeFileSync(file, content, 'utf8');
|
||||||
|
console.log('Fixed', file);
|
||||||
|
});
|
||||||
@ -253,7 +253,7 @@ export const SALES_REPORT_SO_NAMES = [
|
|||||||
// --- Pipeline Endpoints ---
|
// --- Pipeline Endpoints ---
|
||||||
export const PIPELINE = {
|
export const PIPELINE = {
|
||||||
endpoints: {
|
endpoints: {
|
||||||
nearestStores: '/api/p/krishna-group/v1/nearest-stores',
|
nearestStores: '/api/papi2/nearest-stores',
|
||||||
dailySalesReport: '/api/papi2/daily-sales-report',
|
dailySalesReport: '/api/papi2/daily-sales-report',
|
||||||
productiveCallSummary: '/api/papi2/productive-call-summary',
|
productiveCallSummary: '/api/papi2/productive-call-summary',
|
||||||
salesOfficers: '/api/papi2/sales-officers'
|
salesOfficers: '/api/papi2/sales-officers'
|
||||||
@ -263,7 +263,3 @@ export const PIPELINE = {
|
|||||||
export const HIDDEN_FORM_FIELDS = [
|
export const HIDDEN_FORM_FIELDS = [
|
||||||
'store_code_3',
|
'store_code_3',
|
||||||
];
|
];
|
||||||
|
|
||||||
export const SELECT_OPTION_LIMIT = 500;
|
|
||||||
export const PDF_MAX_SKUS_PER_CHUNK = 20;
|
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ import {
|
|||||||
WfLookupField,
|
WfLookupField,
|
||||||
RadioField,
|
RadioField,
|
||||||
} from './fields';
|
} from './fields';
|
||||||
import { ORDER_BOOKING, STORE, DAILY_REPORTS, HIDDEN_FORM_FIELDS, SELECT_OPTION_LIMIT } from '../../api/config';
|
import { ORDER_BOOKING, STORE, DAILY_REPORTS, HIDDEN_FORM_FIELDS } from '../../api/config';
|
||||||
|
|
||||||
export interface DynamicFormProps {
|
export interface DynamicFormProps {
|
||||||
client: ZinoClient;
|
client: ZinoClient;
|
||||||
@ -457,7 +457,7 @@ export function DynamicForm({ client, activityId: initialActivityId, instanceId:
|
|||||||
activityId: ORDER_BOOKING.activities.LOG_VISIT.uid,
|
activityId: ORDER_BOOKING.activities.LOG_VISIT.uid,
|
||||||
fieldId: ORDER_BOOKING.activities.LOG_VISIT.fields.selectStore,
|
fieldId: ORDER_BOOKING.activities.LOG_VISIT.fields.selectStore,
|
||||||
formData: { ...(chainedPrefillData as any || {}), ...values, ...(schema?.prefill_data as any || {}) },
|
formData: { ...(chainedPrefillData as any || {}), ...values, ...(schema?.prefill_data as any || {}) },
|
||||||
limit: SELECT_OPTION_LIMIT
|
limit: 500
|
||||||
});
|
});
|
||||||
const arr = Array.isArray(lookupRes) ? lookupRes : (lookupRes.data || lookupRes.records || []);
|
const arr = Array.isArray(lookupRes) ? lookupRes : (lookupRes.data || lookupRes.records || []);
|
||||||
const row = arr.find((r: any) => String(r.instance_id || r.id) === String(storeId));
|
const row = arr.find((r: any) => String(r.instance_id || r.id) === String(storeId));
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useState, useEffect, useCallback, useRef } from 'react';
|
import { useState, useEffect, useCallback, useRef } from 'react';
|
||||||
import type { ZinoClient } from '../../api/client';
|
import type { ZinoClient } from '../../api/client';
|
||||||
import type { FormScreenResponse } from '../../api/types';
|
import type { FormScreenResponse } from '../../api/types';
|
||||||
import { ORDER_BOOKING, HIDDEN_FORM_FIELDS, SELECT_OPTION_LIMIT } from '../../api/config';
|
import { ORDER_BOOKING, HIDDEN_FORM_FIELDS } from '../../api/config';
|
||||||
import { Button } from '../buttons/Button';
|
import { Button } from '../buttons/Button';
|
||||||
import { Select } from '../reusable/Select';
|
import { Select } from '../reusable/Select';
|
||||||
import { DateField, TimeField, FileInput, TextField } from './fields';
|
import { DateField, TimeField, FileInput, TextField } from './fields';
|
||||||
@ -148,7 +148,7 @@ export function LogVisitForm({ client, onSuccess, onCancel, onActivityChange }:
|
|||||||
activityId,
|
activityId,
|
||||||
fieldId: 'select_store',
|
fieldId: 'select_store',
|
||||||
formData: formDataToSend,
|
formData: formDataToSend,
|
||||||
limit: SELECT_OPTION_LIMIT,
|
limit: 200,
|
||||||
});
|
});
|
||||||
|
|
||||||
const arr = Array.isArray(lookupRes)
|
const arr = Array.isArray(lookupRes)
|
||||||
@ -215,7 +215,7 @@ export function LogVisitForm({ client, onSuccess, onCancel, onActivityChange }:
|
|||||||
activityId,
|
activityId,
|
||||||
fieldId: 'daily_log',
|
fieldId: 'daily_log',
|
||||||
formData: payload,
|
formData: payload,
|
||||||
limit: SELECT_OPTION_LIMIT,
|
limit: 200,
|
||||||
});
|
});
|
||||||
|
|
||||||
const arr = Array.isArray(dailyLogLookupRes)
|
const arr = Array.isArray(dailyLogLookupRes)
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import type { ZinoClient } from '../../../api/client';
|
import type { ZinoClient } from '../../../api/client';
|
||||||
import { SELECT_OPTION_LIMIT } from '../../../api/config';
|
|
||||||
import { SelectField } from './SelectField';
|
import { SelectField } from './SelectField';
|
||||||
|
|
||||||
export interface WfLookupFieldProps {
|
export interface WfLookupFieldProps {
|
||||||
@ -39,7 +38,7 @@ export function WfLookupField({ label, required, value, onChange, client, config
|
|||||||
activityId,
|
activityId,
|
||||||
fieldId,
|
fieldId,
|
||||||
formData,
|
formData,
|
||||||
limit: SELECT_OPTION_LIMIT
|
limit: 200
|
||||||
})
|
})
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|||||||
@ -64,7 +64,11 @@ export function NearestStoresMap() {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'accept': 'application/json, text/plain, */*',
|
'accept': 'application/json, text/plain, */*',
|
||||||
'content-type': 'application/json'
|
'content-type': 'application/json',
|
||||||
|
'groupid': '25',
|
||||||
|
'orgid': '57',
|
||||||
|
'templateid': '189',
|
||||||
|
'x-pipeline-version': 'latest'
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
latitude: lat,
|
latitude: lat,
|
||||||
|
|||||||
@ -5,8 +5,7 @@ import {
|
|||||||
SALES_REPORT_ROUTES,
|
SALES_REPORT_ROUTES,
|
||||||
ROUTE_WISE_DISTRIBUTORS,
|
ROUTE_WISE_DISTRIBUTORS,
|
||||||
BASE_URL,
|
BASE_URL,
|
||||||
PIPELINE,
|
PIPELINE
|
||||||
PDF_MAX_SKUS_PER_CHUNK
|
|
||||||
} from '../api/config';
|
} from '../api/config';
|
||||||
import { Download, Printer } from 'lucide-react';
|
import { Download, Printer } from 'lucide-react';
|
||||||
import jsPDF from 'jspdf';
|
import jsPDF from 'jspdf';
|
||||||
@ -74,56 +73,28 @@ export function DailySalesReportPage() {
|
|||||||
|
|
||||||
// Meta Info
|
// Meta Info
|
||||||
doc.setFontSize(10);
|
doc.setFontSize(10);
|
||||||
|
doc.text(`Distributor Name : ${distributor}`, 14, 40);
|
||||||
let leftY = 40;
|
doc.text(`Date : ${date}`, rightMargin, 40, { align: 'right' });
|
||||||
if (distributor) {
|
const selectedSo = soOptions.find(o => o.value === soEmail);
|
||||||
doc.text(`Distributor Name : ${distributor}`, 14, leftY);
|
doc.text(`SO Name : ${selectedSo ? selectedSo.label : soEmail}`, rightMargin, 45, { align: 'right' });
|
||||||
leftY += 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
let rightY = 40;
|
|
||||||
if (date) {
|
|
||||||
doc.text(`Date : ${date}`, rightMargin, rightY, { align: 'right' });
|
|
||||||
rightY += 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (soEmail) {
|
|
||||||
const selectedSo = soOptions.find(o => o.value === soEmail);
|
|
||||||
doc.text(`SO Name : ${selectedSo ? selectedSo.label : soEmail}`, rightMargin, rightY, { align: 'right' });
|
|
||||||
rightY += 5;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Split headers into chunks of exactly PDF_MAX_SKUS_PER_CHUNK, even if it means splitting a brand.
|
// Split headers into chunks to avoid jspdf-autotable's horizontal page break bugs
|
||||||
|
// This allows us to keep the 2-tier header perfectly intact and break at heading boundaries.
|
||||||
|
const MAX_SKUS_PER_CHUNK = 14;
|
||||||
const headerChunks: any[][] = [];
|
const headerChunks: any[][] = [];
|
||||||
let currentChunk: any[] = [];
|
let currentChunk: any[] = [];
|
||||||
let currentSkuCount = 0;
|
let currentSkuCount = 0;
|
||||||
|
|
||||||
reportData?.response?.headers?.forEach((h: any) => {
|
reportData?.response?.headers?.forEach((h: any) => {
|
||||||
const allSkus = h.skus || [];
|
const skus = h.skus || [];
|
||||||
if (allSkus.length === 0) return;
|
if (currentSkuCount + skus.length > MAX_SKUS_PER_CHUNK && currentSkuCount > 0) {
|
||||||
|
headerChunks.push(currentChunk);
|
||||||
let remainingSkus = [...allSkus];
|
currentChunk = [];
|
||||||
|
currentSkuCount = 0;
|
||||||
while (remainingSkus.length > 0) {
|
|
||||||
const availableSpace = PDF_MAX_SKUS_PER_CHUNK - currentSkuCount;
|
|
||||||
|
|
||||||
// Take as many SKUs as we can fit in the current chunk
|
|
||||||
const skusToTake = remainingSkus.splice(0, availableSpace);
|
|
||||||
|
|
||||||
currentChunk.push({
|
|
||||||
...h,
|
|
||||||
skus: skusToTake
|
|
||||||
});
|
|
||||||
|
|
||||||
currentSkuCount += skusToTake.length;
|
|
||||||
|
|
||||||
if (currentSkuCount >= PDF_MAX_SKUS_PER_CHUNK) {
|
|
||||||
headerChunks.push(currentChunk);
|
|
||||||
currentChunk = [];
|
|
||||||
currentSkuCount = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
currentChunk.push(h);
|
||||||
|
currentSkuCount += skus.length;
|
||||||
});
|
});
|
||||||
if (currentChunk.length > 0) {
|
if (currentChunk.length > 0) {
|
||||||
headerChunks.push(currentChunk);
|
headerChunks.push(currentChunk);
|
||||||
@ -328,12 +299,10 @@ export function DailySalesReportPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex justify-between items-start text-sm font-bold text-strong mb-2">
|
<div className="flex justify-between items-start text-sm font-bold text-strong mb-2">
|
||||||
<div className="flex flex-col gap-1.5">
|
<div>Distributor Name : {distributor}</div>
|
||||||
{distributor && <div>Distributor Name : {distributor}</div>}
|
|
||||||
</div>
|
|
||||||
<div className="text-right flex flex-col gap-1.5">
|
<div className="text-right flex flex-col gap-1.5">
|
||||||
{date && <div>Date : {date}</div>}
|
<div>Date : {date}</div>
|
||||||
{soEmail && <div>SO Name : {soOptions.find(o => o.value === soEmail)?.label || soEmail}</div>}
|
<div>SO Name : {soOptions.find(o => o.value === soEmail)?.label || soEmail}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user