<!-- Include html2pdf library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
<style>
/* Scoped specifically for Blogger so it doesn't break your theme */
#quote-app-container {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f8fafc;
padding: 20px;
display: flex;
gap: 20px;
max-width: 1400px;
margin: 0 auto;
text-align: left;
line-height: 1.5;
}
#quote-app-container .form-section {
background: white;
padding: 25px;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0,0,0,0.05);
flex: 1;
max-width: 500px;
}
#quote-app-container h2 { margin-top: 0; color: #1e293b; font-size: 20px;}
#quote-app-container .form-group { margin-bottom: 15px; }
#quote-app-container label { display: block; margin-bottom: 5px; font-weight: 600; font-size: 13px; color: #475569; }
#quote-app-container input,
#quote-app-container textarea {
width: 100%; padding: 8px 10px; border: 1px solid #cbd5e1;
border-radius: 4px; box-sizing: border-box; font-family: inherit;
}
#quote-app-container .row { display: flex; gap: 10px; }
#quote-app-container .row > div { flex: 1; }
#quote-app-container button.primary-btn {
background-color: #2563eb; color: white; border: none; padding: 12px;
font-size: 16px; border-radius: 4px; cursor: pointer; width: 100%; font-weight: bold;
margin-top: 15px;
}
#quote-app-container button.primary-btn:hover { background-color: #1d4ed8; }
#quote-app-container button.secondary-btn {
background-color: #e2e8f0; color: #0f172a; border: none; padding: 8px 15px;
font-size: 13px; border-radius: 4px; cursor: pointer; font-weight: bold; margin-bottom: 15px;
}
#quote-app-container button.secondary-btn:hover { background-color: #cbd5e1; }
#quote-app-container .item-row-input {
border: 1px solid #e2e8f0; padding: 10px; border-radius: 4px; margin-bottom: 10px;
position: relative; background: #f8fafc;
}
#quote-app-container .remove-btn {
position: absolute; top: -10px; right: -10px; background: #ef4444; color: white;
border: none; border-radius: 50%; width: 24px; height: 24px; cursor: pointer;
font-weight: bold; line-height: 24px; padding: 0; text-align: center;
}
/* --- PDF TEMPLATE STYLES --- */
#pdfWrapper {
position: absolute;
left: -9999px; /* Hide from screen but keep in DOM for PDF generation */
}
.quote-template {
width: 800px;
padding: 40px 50px;
background: white;
color: #000;
font-family: "Times New Roman", Times, serif;
font-size: 14.5px;
box-sizing: border-box;
line-height: 1.4;
}
.quote-template h1.header-title {
text-align: center;
font-size: 32px;
margin: 0 0 10px 0;
font-weight: normal;
letter-spacing: 1px;
}
.quote-template p.header-address {
text-align: center;
font-size: 12px;
font-style: italic;
margin: 0 0 30px 0;
}
.quote-template .header-address b { font-style: normal; }
.quote-template .mail-text { color: blue; }
.quote-template .ref-date-row { display: flex; justify-content: space-between; margin-bottom: 5px; }
.quote-template .client-address { white-space: pre-wrap; margin-bottom: 25px; line-height: 1.3; }
.quote-template .subject-line { margin-bottom: 25px; text-transform: uppercase; }
.quote-template .subject-line u { text-underline-offset: 3px; }
.quote-template .salutation { margin-bottom: 10px; }
/* Table Styling */
table.quote-table {
width: 100%; border-collapse: collapse; margin-bottom: 30px; margin-top: 5px;
}
table.quote-table th, table.quote-table td {
border: 1px solid #000; padding: 4px 8px; vertical-align: top;
}
table.quote-table th { font-weight: normal; }
.col-sno { width: 6%; text-align: left; }
.col-desc { width: 50%; text-align: left; }
.col-unit { width: 14%; text-align: left; }
.col-price { width: 15%; text-align: right; }
.col-amount { width: 15%; text-align: right; }
.quote-template .terms { margin-top: 30px; }
.quote-template .terms u { text-underline-offset: 3px; }
.quote-template .sign-off { margin-top: 5px; line-height: 1.3; }
/* Responsive Layout for app */
@media (max-width: 1024px) {
#quote-app-container { flex-direction: column; padding: 0; }
#quote-app-container .form-section { max-width: 100%; box-shadow: none; }
}
</style>
<div id="quote-app-container">
<!-- CONTROL PANEL / FORM -->
<div class="form-section">
<h2>Generate MDR Quote</h2>
<form id="quoteForm">
<div class="row">
<div class="form-group">
<label>Ref No.</label>
<input type="text" id="inRef" value="No-58 MDRMC 2026-27" required>
</div>
<div class="form-group">
<label>Date</label>
<input type="date" id="inDate" required>
</div>
</div>
<div class="form-group">
<label>To Address</label>
<textarea id="inAddress" rows="4" required>M/S.MOHAN MEAKIN LTD
UNIT- SPIRIT BOTTLING
PO SOLAN BREWERY
SHIMLA HILLS HP 173212</textarea>
</div>
<div class="form-group">
<label>Kind Attn:</label>
<input type="text" id="inAttn" value="Mr. PARDEEP SINGH JI" required>
</div>
<div class="form-group">
<label>Subject</label>
<input type="text" id="inSubject" value="OFFER FOR THE SUPPLY OF STEEL BRADED PIPE" required>
</div>
<div class="form-group">
<label>Introductory Sentence</label>
<textarea id="inIntroText" rows="2" required>We are pleased to summit our best offer for steel braded pipe as per given here below.</textarea>
</div>
<label style="font-size: 16px; margin-top: 15px; display: block; font-weight: bold;">Line Items</label>
<div id="itemsContainer">
<!-- Dynamic items will be added here -->
</div>
<button type="button" class="secondary-btn" onclick="addItemRow()">+ Add Item Row</button>
<hr style="border: 0; border-top: 1px solid #e2e8f0; margin: 10px 0 20px;">
<div class="row">
<div class="form-group">
<label>GST %</label>
<input type="number" id="inGst" value="18" min="0">
</div>
<div class="form-group">
<label>Packing & Courier</label>
<input type="text" id="inPacking" value="Extra">
</div>
</div>
<button type="submit" class="primary-btn">Generate & Download PDF</button>
</form>
</div>
<!-- HIDDEN PDF TEMPLATE -->
<div id="pdfWrapper">
<div class="quote-template" id="quoteTemplate">
<h1 class="header-title">MDR BOTTLING COMPONENTS</h1>
<p class="header-address">
Plot No 485 Sanjay Colony Near Radha Krishan Mandir Arthla Mohan Nagar Ghaziabad (UP) 201007, India<br>
<b>Mail id:<span class="mail-text">mdrbottling@gmail.com</span></b> Mob No+91-9891743999, <u style="text-underline-offset: 2px;">GSTIN: 09BPZPB5537C1ZN</u>
</p>
<div class="ref-date-row">
<div>REF <span id="outRef"></span></div>
<div>Date <span id="outDate"></span></div>
</div>
<div class="client-address" id="outAddress"></div>
<div class="subject-line">
<u>KIND ATTN:-<span id="outAttn"></span></u><br>
<u>SUBJECT: - <span id="outSubject"></span></u>
</div>
<div class="salutation">
Dear Sir,<br>
<span id="outIntroText"></span>
</div>
<table class="quote-table">
<thead>
<tr>
<th class="col-sno">SNo</th>
<th class="col-desc">DISCRIPTION</th>
<th class="col-unit">PER UNIT</th>
<th class="col-price">PRICE</th>
<th class="col-amount">AMOUNT</th>
</tr>
</thead>
<tbody id="outTableBody">
<!-- JS WILL INJECT ROWS HERE -->
</tbody>
<tfoot>
<tr>
<td colspan="2">GSTIN <span id="outGstPercentLabel">18</span>%</td>
<td></td>
<td></td>
<td id="outGstAmount" style="text-align: right;"></td>
</tr>
<tr>
<td colspan="4">Packing & Courier Charge Extra</td>
<td id="outPackingLabel" style="text-align: right;">Extra</td>
</tr>
<tr>
<td colspan="4">Total Amount After Tax</td>
<td id="outTotalAmount" style="text-align: right;"></td>
</tr>
</tfoot>
</table>
<div class="terms">
<u>TERMS AND CONDITION</u><br>
01-PRICE–All prices quoted are Ex work Ghaziabad.<br>
02-TAXES – GSTIN 18% an applicable.<br>
03-PAYMENT–Payment after delivery within 20 days.<br>
04-DELIVERY- Ready Stock After Receive Purchase Order.<br>
<div class="sign-off">
<u>THANKING YOU</u><br>
FOR-MDR BOTTLING COMPONENTS<br><br>
RAJU BARGALI<br>
+91 9891743999
</div>
</div>
</div>
</div>
</div>
<script>
document.getElementById('inDate').valueAsDate = new Date();
let itemCount = 0;
function addItemRow(desc = '', qty = '', unit = '', price = '') {
itemCount++;
const container = document.getElementById('itemsContainer');
const rowDiv = document.createElement('div');
rowDiv.className = 'item-row-input';
rowDiv.id = `itemRow_${itemCount}`;
rowDiv.innerHTML = `
<button type="button" class="remove-btn" onclick="removeItemRow(${itemCount})">×</button>
<div class="form-group" style="margin-bottom: 8px;">
<label>Description</label>
<input type="text" class="item-desc" value="${desc}" placeholder="e.g. PVC Hose Pipe 80mm ID" required>
</div>
<div class="row">
<div class="form-group" style="margin-bottom: 0;">
<label>Qty</label>
<input type="number" class="item-qty" value="${qty}" placeholder="20" required>
</div>
<div class="form-group" style="margin-bottom: 0;">
<label>Unit</label>
<input type="text" class="item-unit" value="${unit}" placeholder="Mtr" required>
</div>
<div class="form-group" style="margin-bottom: 0;">
<label>Price</label>
<input type="number" step="0.01" class="item-price" value="${price}" placeholder="Leave blank if TBA">
</div>
</div>
`;
container.appendChild(rowDiv);
}
function removeItemRow(id) { document.getElementById(`itemRow_${id}`).remove(); }
window.onload = () => {
addItemRow('PVC Hose Pipe 80mm ID For Air knife', '20', 'Mtr', '');
addItemRow('SS Clamp 1.5"', '20', 'Nos', '');
addItemRow('SS Clamp 1"', '15', 'Nos', '');
addItemRow('PVC Wire Braded Flexible Pipe Size ½"', '50', 'Mtr', '');
addItemRow('PVC Wire Braded Flexible Pipe Size 1"', '25', 'Mtr', '');
addItemRow('PVC Wire Braded Flexible Pipe Size 1.5"', '50', 'Mtr', '');
};
function formatDateMatchImage(dateString) {
const dateObj = new Date(dateString);
return `${dateObj.getDate()} ${dateObj.toLocaleString('default', { month: 'long' }).toUpperCase()} ${dateObj.getFullYear()}`;
}
const currencyFormat = new Intl.NumberFormat('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
document.getElementById('quoteForm').addEventListener('submit', function(e) {
e.preventDefault();
document.getElementById('outRef').innerText = document.getElementById('inRef').value;
document.getElementById('outDate').innerText = formatDateMatchImage(document.getElementById('inDate').value);
document.getElementById('outAddress').innerText = document.getElementById('inAddress').value;
document.getElementById('outAttn').innerText = document.getElementById('inAttn').value;
document.getElementById('outSubject').innerText = document.getElementById('inSubject').value;
document.getElementById('outIntroText').innerText = document.getElementById('inIntroText').value;
const gstPercent = parseFloat(document.getElementById('inGst').value) || 0;
document.getElementById('outGstPercentLabel').innerText = gstPercent;
document.getElementById('outPackingLabel').innerText = document.getElementById('inPacking').value;
const tableBody = document.getElementById('outTableBody');
tableBody.innerHTML = '';
const itemRows = document.querySelectorAll('.item-row-input');
let subTotal = 0;
let index = 1;
itemRows.forEach(row => {
const desc = row.querySelector('.item-desc').value;
const qty = parseFloat(row.querySelector('.item-qty').value) || 0;
const unit = row.querySelector('.item-unit').value;
const priceInput = row.querySelector('.item-price').value;
const price = parseFloat(priceInput);
let amountStr = '';
let priceStr = '';
if (!isNaN(price)) {
const amount = qty * price;
subTotal += amount;
priceStr = currencyFormat.format(price);
amountStr = currencyFormat.format(amount);
}
const tr = document.createElement('tr');
tr.innerHTML = `
<td class="col-sno">${index}-</td>
<td class="col-desc">${desc}</td>
<td class="col-unit">${qty} ${unit}</td>
<td class="col-price">${priceStr}</td>
<td class="col-amount">${amountStr}</td>
`;
tableBody.appendChild(tr);
index++;
});
const gstAmount = subTotal * (gstPercent / 100);
const grandTotal = subTotal + gstAmount;
document.getElementById('outGstAmount').innerText = gstAmount > 0 ? currencyFormat.format(gstAmount) : '';
document.getElementById('outTotalAmount').innerText = grandTotal > 0 ? currencyFormat.format(grandTotal) : '5,900.00';
const element = document.getElementById('quoteTemplate');
const opt = {
margin: 0,
filename: `MDR_Quote_${document.getElementById('inRef').value.replace(/[^a-z0-9]/gi, '_')}.pdf`,
image: { type: 'jpeg', quality: 1.0 },
html2canvas: { scale: 2, useCORS: true },
jsPDF: { unit: 'in', format: 'A4', orientation: 'portrait' }
};
html2pdf().set(opt).from(element).save();
});
</script>