Net Balance (Due/Advance)
₹0.00
Total Cost
₹0.00
Total Paid
₹0.00
Total Pages
0
Total Jobs
0
The definitive Print Expense Manager for cyber cafés, xerox shops, and students. Track costs, manage credits, and sync across devices instantly.
In the busy environment of a photocopy shop or a university project center, tracking every single page is difficult. Notebooks get lost, and mental math leads to financial leakage.
Designed for the Indian market context (₹), but works globally.
To enable syncing between your Phone and Laptop, you need to create your own "Backend" using a free Google Sheet.
Jobs (Case sensitive).Payments (Case sensitive).id, documentName, pages, costPerPage, totalCost, dateid, amount, date
Go to Extensions > Apps Script. Delete existing code and paste this.
IMPORTANT: Paste your Spreadsheet ID in the first line.
// ==========================================
// PRINT TRACKER BACKEND (FINAL)
// ==========================================
// 👇 PASTE YOUR SPREADSHEET ID HERE 👇
const SHEET_ID = "PASTE_YOUR_SHEET_ID_HERE";
function doGet(e) {
const ss = SpreadsheetApp.openById(SHEET_ID);
const jobsSheet = ss.getSheetByName("Jobs");
const paySheet = ss.getSheetByName("Payments");
const jobsData = getSheetData(jobsSheet);
const payData = getSheetData(paySheet);
return ContentService.createTextOutput(JSON.stringify({
jobs: jobsData,
payments: payData
})).setMimeType(ContentService.MimeType.JSON);
}
function doPost(e) {
const ss = SpreadsheetApp.openById(SHEET_ID);
try {
const data = JSON.parse(e.postData.contents);
const action = data.action;
const lock = LockService.getScriptLock();
lock.tryLock(10000);
try {
// CONVERT TIMESTAMP TO DATE OBJECT
const rowDate = new Date(data.date);
if (action === "addJob") {
const sheet = ss.getSheetByName("Jobs");
const id = data.id;
sheet.appendRow([id, data.documentName, data.pages, data.costPerPage, data.totalCost, rowDate]);
}
else if (action === "addPayment") {
const sheet = ss.getSheetByName("Payments");
const id = data.id;
sheet.appendRow([id, data.amount, rowDate]);
}
else if (action === "editJob") {
updateRow(ss.getSheetByName("Jobs"), data.id, [data.id, data.documentName, data.pages, data.costPerPage, data.totalCost, rowDate]);
}
else if (action === "delete") {
const sheetName = data.type === 'job' ? "Jobs" : "Payments";
deleteRow(ss.getSheetByName(sheetName), data.id);
}
return ContentService.createTextOutput(JSON.stringify({status: "success"}));
} catch (innerError) {
return ContentService.createTextOutput(JSON.stringify({status: "error", message: innerError.toString()}));
} finally {
lock.releaseLock();
}
} catch (e) {
return ContentService.createTextOutput(JSON.stringify({status: "fatal_error", message: e.toString()}));
}
}
// --- HELPER FUNCTIONS ---
function getSheetData(sheet) {
if (!sheet) return [];
const lastRow = sheet.getLastRow();
if (lastRow < 2) return [];
const rows = sheet.getRange(2, 1, lastRow - 1, sheet.getLastColumn()).getValues();
const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
return rows.map(row => {
let obj = {};
headers.forEach((h, i) => {
if (row[i] instanceof Date) {
obj[h] = row[i].getTime();
} else {
obj[h] = row[i];
}
});
return obj;
});
}
function deleteRow(sheet, id) {
const data = sheet.getDataRange().getValues();
for (let i = data.length - 1; i >= 1; i--) {
if (String(data[i][0]) === String(id)) {
sheet.deleteRow(i + 1);
return;
}
}
}
function updateRow(sheet, id, newValues) {
const data = sheet.getDataRange().getValues();
for (let i = 1; i < data.length; i++) {
if (String(data[i][0]) === String(id)) {
sheet.getRange(i + 1, 1, 1, newValues.length).setValues([newValues]);
return;
}
}
}
Yes. It uses your browser's storage and your Google Drive. There is no middleman and no subscription.
If you are using Local Mode, your data will be deleted. We strongly recommend setting up the Cloud Sync so your data is permanently safe in Google Sheets.
Yes! While it says "Pages", you can use the quantity field for anything (e.g., hours of service, 3D printing grams) and set the cost per unit accordingly.
Ensure your Google Deployment is set to "Anyone" and that you are not using extensions like "Video Downloaders" that block background requests.
Start recording your jobs now and take control of your expenses! Efficiently track dues, advances, and total earnings in one streamlined dashboard.