Status values: in-transit, delivered, returned, claimed-return, missing Date format: YYYY-MM-DD (e.g. 2026-05-15) Physical returns: add column physically_received=yes
Default Date (if no Date column in CSV)
Default Status (if no Status column in CSV)
Add SKU Product
Product Name *
SKU Code
Category
Cost Price (Rs.) *
Sell Price (Rs.) *
Current Stock *
Reorder Level *
Supplier
Stock Movement
Quantity *
Note / Reference
Create Deal Pack
Deal Name *
Deal Sell Price (Rs.) *
Items in this Deal
Add Expense
Category *
Amount (Rs.) *
Paid To
Note
Add Supplier
Supplier Name *
Contact Person
Phone *
Address
Opening Balance (Rs.)
Positive = you owe them · Negative = they owe you
Payable / Receivable
Party *
Amount (Rs.) *
Due Date
Note / Invoice
Add Transaction
Amount (Rs.) *
Method
Bank Name
Account Number / IBAN
Note
Add Courier Statement
Courier *
Statement Date *
Total Parcels
Total COD (Rs.)
COD Received (Rs.) *
Note
⚠️
Duplicate Order Detected
Delete Selected
This cannot be undone
Upload Courier CPR / Invoice
Upload a CSV payment report — AI will auto-detect which parcels got paid
Courier *
CPR / Payment File (CSV) *
Note (optional)
🤖 AI Scan Result
🔔 Smart Alerts
Loading...
🚫
Blacklisted Customer
📦 Return Disposition
What happened to the returned product?
📊 Today's Report
// ── NON-SERVICE AREA (NSA) MODULE ───────────────────────────────────────────
// Storage: localStorage key "fl_nsa_v1"
// Data structure: { [courier]: Set }
// We store as: { [courier]: [city1, city2, ...] }
var NSA_KEY="fl_nsa_v1";
var nsaData={}; // { courierName: [{city,note}] }
function nsaLoad(){
try{var raw=localStorage.getItem(NSA_KEY);if(raw)nsaData=JSON.parse(raw);}
catch(e){nsaData={};}
}
function nsaSave(){
try{localStorage.setItem(NSA_KEY,JSON.stringify(nsaData));}catch(e){}
}
function nsaNorm(s){
// Normalize for exact matching: lowercase, trim, collapse spaces
return (s||"").toLowerCase().replace(/\s+/g," ").trim();
}
function checkNSACity(city,courier){
// Returns the matching NSA entry {city,courier,note} or null
if(!city||!courier)return null;
var nc=nsaNorm(city);
// Check against selected courier only (exact match)
var list=nsaData[courier]||[];
for(var i=0;i=0;
if(hasHeader)lines=lines.slice(1);
var added=0,skipped=0;
if(!nsaData[courier])nsaData[courier]=[];
var existing=nsaData[courier].map(function(e){return nsaNorm(e.city);});
lines.forEach(function(line){
var parts=line.split(",");
var city=(parts[0]||"").trim();
var note=(parts[1]||"").trim();
if(!city){skipped++;return;}
var nc=nsaNorm(city);
if(existing.indexOf(nc)>=0){skipped++;return;}
nsaData[courier].push({city:city,note:note});
existing.push(nc);
added++;
});
nsaSave();
return{added:added,skipped:skipped};
}
function nsaDeleteCity(courier,idx){
if(!nsaData[courier])return;
nsaData[courier].splice(idx,1);
nsaSave();
rTab();
}
function nsaDeleteAll(courier){
if(!confirm("Delete ALL non-service cities for "+courier+"?"))return;
nsaData[courier]=[];
nsaSave();
rTab();
}
function nsaHandleCSV(courier){
var fileEl=document.getElementById("nsaCsvInp_"+courier.replace(/\s/g,"_"));
if(!fileEl||!fileEl.files[0]){showT("Select a CSV file first","warn");return;}
var file=fileEl.files[0];
var reader=new FileReader();
reader.onload=function(e){
var result=nsaParseCSV(e.target.result,courier);
showT("✓ Added "+result.added+" cities, "+result.skipped+" skipped/duplicates");
fileEl.value="";
rTab();
};
reader.readAsText(file);
}
function nsaAddManual(courier){
var cityEl=document.getElementById("nsaManCity_"+courier.replace(/\s/g,"_"));
var noteEl=document.getElementById("nsaManNote_"+courier.replace(/\s/g,"_"));
var city=(cityEl?cityEl.value.trim():"");
var note=(noteEl?noteEl.value.trim():"");
if(!city){showT("Enter a city name","error");return;}
if(!nsaData[courier])nsaData[courier]=[];
var nc=nsaNorm(city);
var exists=nsaData[courier].some(function(e){return nsaNorm(e.city)===nc;});
if(exists){showT("City already listed for "+courier,"warn");return;}
nsaData[courier].push({city:city,note:note});
nsaSave();
cityEl.value="";noteEl.value="";
rTab();
showT("✓ Added: "+city);
}
function nsaExportCSV(courier){
var list=nsaData[courier]||[];
if(!list.length){showT("No cities to export","warn");return;}
var rows=["city,note"].concat(list.map(function(e){return'"'+e.city+'","'+(e.note||"")+'"';}));
var a=document.createElement("a");
a.href="data:text/csv;charset=utf-8,"+encodeURIComponent(rows.join("\n"));
a.download="NSA_"+courier.replace(/\s/g,"_")+".csv";
a.click();showT("Downloaded");
}
function nsaSearch(courier){
var q=nsaNorm((document.getElementById("nsaSearch_"+courier.replace(/\s/g,"_"))||{}).value||"");
var list=nsaData[courier]||[];
var tbody=document.getElementById("nsaTbody_"+courier.replace(/\s/g,"_"));
if(!tbody)return;
var rows="";
list.forEach(function(e,i){
if(q&&nsaNorm(e.city).indexOf(q)<0)return;
rows+='
'+e.city+'
'+(e.note||"—")+'
';
});
tbody.innerHTML=rows||'
No cities found
';
}
function rNSA(){
nsaLoad();
var couriers=["Leopards","TCS","Rider","Trax","PostEx","BlueEx","M&P","OCS","Swyft","Bykea","Call Courier","DHL","FedEx","Other"];
var totalNSA=0;
Object.values(nsaData).forEach(function(arr){totalNSA+=arr.length;});
var h='
🚫 Non-Service Area Manager
';
h+='
Upload or manually add cities where couriers do not deliver. The system will warn before dispatching to these areas.
';
// summary strip
h+='
';
var activeCouriers=couriers.filter(function(c){return (nsaData[c]||[]).length>0;});
if(!activeCouriers.length){
h+='
No non-service areas configured yet. Upload a CSV or add cities manually below.
';
} else {
activeCouriers.forEach(function(c){
var cnt=(nsaData[c]||[]).length;
h+='
'+cnt+'
'+c+'
';
});
}
h+='
';
// per-courier sections
couriers.forEach(function(courier){
var safeId=courier.replace(/\s/g,"_").replace(/[^a-zA-Z0-9_]/g,"_");
var list=nsaData[courier]||[];
var isOpen=list.length>0;
h+='
';
// header
h+='
';
h+='
'+courier+' ('+list.length+' cities)
';
h+='
';
if(list.length>0){
h+='';
h+='';
}
h+='
';
// CSV upload row
h+='
';
h+='
📎 Upload CSV (city column, optional note column)
';
h+='
';
h+='';
h+='';
h+='
';
// Manual add row
h+='
';
h+='';
h+='';
h+='';
h+='
';
// City list (show only if any)
if(list.length>0){
h+='';
h+='
';
h+='
City
Note
';
h+='';
list.forEach(function(e,i){
h+='
'+e.city+'
'+(e.note||"—")+'
';
});
h+='
';
}
h+='
';
});
return h;
}
// initialise NSA on page load
nsaLoad();
var _nsaBypass=false;
function nsaForceDispatch(){
document.getElementById("nsaWarnM").style.display="none";
_nsaBypass=true;
subDsp();
_nsaBypass=false;
}
⚠️
Non-Service Area Alert
is listed as a non-service area for
Dispatching here may result in failed delivery and return. Proceed only if you are sure.