Scan to open on your phone
Point a camera at the QR code - it opens this exact paste, no app needed.
https://codepastes.com/zzgsr4psrjdw2h9wuntitledPlain Text
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Wholesale Ticket Entry</title>
<!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Font Awesome Icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
body {
font-family: Arial, Helvetica, sans-serif;
user-select: none;
background-color: #d4d0c8; /* Classic MS Access / Windows UI feel */
}
.ms-button {
background: linear-gradient(180deg, #ffffff 0%, #ece9d8 100%);
border: 1px solid #7f9db9;
box-shadow: inset -1px -1px 1px rgba(0,0,0,0.2), inset 1px 1px 1px #fff;
}
.ms-button:active {
background: #e3dece;
box-shadow: inset 1px 1px 2px rgba(0,0,0,0.4);
}
.table-header {
background-color: #2e624c; /* Sage green access style header */
color: white;
font-weight: bold;
}
.yellow-input {
background-color: #ffffa0;
}
.yellow-input:focus {
background-color: #ffffff;
outline: 2px solid #2e624c;
}
/* Ribbon menu tabs */
.ribbon-tab {
padding: 3px 12px;
font-size: 12px;
cursor: pointer;
}
.ribbon-tab.active {
background-color: #ece9d8;
border-top: 2px solid #a00000;
border-left: 1px solid #7f9db9;
border-right: 1px solid #7f9db9;
font-weight: bold;
}
</style>
</head>
<body class="p-2 sm:p-3 min-h-screen text-slate-800">
<!-- Access UI Outer Shell -->
<div class="max-w-7xl mx-auto border-2 border-slate-400 bg-[#ece9d8] p-2 rounded shadow-md">
<!-- Access Title Ribbon Header -->
<div class="bg-[#a00000] text-white px-3 py-1 font-bold text-xs flex justify-between items-center rounded-t shadow-sm">
<span class="flex items-center gap-2">
<i class="fa-solid fa-database"></i> Access - Wholesale Entry
</span>
<div class="flex items-center gap-3 text-[11px]">
<i class="fa-solid fa-magnifying-glass-plus"></i>
<i class="fa-solid fa-border-all"></i>
<i class="fa-solid fa-keyboard"></i>
</div>
</div>
<!-- Access Menu Bar -->
<div class="bg-[#d4d0c8] border-b border-slate-400 flex text-xs pt-1 px-1 gap-1">
<div class="ribbon-tab text-red-800 font-bold">File</div>
<div class="ribbon-tab active">Home</div>
<div class="ribbon-tab">Create</div>
<div class="ribbon-tab">External Data</div>
<div class="ribbon-tab">Database Tools</div>
<div class="ribbon-tab">Help</div>
<div class="ml-auto flex items-center pr-2 text-slate-600 text-[11px] gap-1">
<i class="fa-solid fa-magnifying-glass"></i>
<span>Tell me what you want to do</span>
</div>
</div>
<!-- Form Title Header -->
<div class="bg-[#e2dfd5] border border-slate-300 p-2 my-2 rounded flex justify-between items-center">
<div class="text-xs font-bold text-slate-700 flex items-center gap-2">
<i class="fa-solid fa-receipt text-amber-800"></i>
<span>iPad Ticket Entry</span>
</div>
<div class="text-xs font-bold text-slate-600">
Ticket No: <input type="text" id="ticketNo" value="450666" class="border border-slate-400 p-0.5 rounded w-24 text-center yellow-input font-bold">
</div>
</div>
<!-- Top Controls Section (Start Ticket, XFR, LRP & Customer Meta) -->
<div class="grid grid-cols-1 lg:grid-cols-12 gap-3 mb-2 border border-slate-300 p-2 bg-[#f4f2ec] rounded">
<!-- Start Ticket & XFR / LRP Buttons -->
<div class="lg:col-span-5 flex items-center gap-2">
<button onclick="startNewTicket()" class="ms-button p-2.5 rounded text-slate-900 font-bold text-xs flex items-center justify-center gap-2 hover:bg-slate-100 flex-1 border-2 border-slate-400 shadow-sm h-16">
<div class="bg-blue-600 text-white rounded-lg p-1.5 shadow">
<i class="fa-solid fa-file-circle-plus text-xl"></i>
</div>
<span class="text-sm">Start New<br>Ticket</span>
</button>
<button class="ms-button px-4 h-16 rounded text-xs font-bold bg-slate-100 hover:bg-slate-200 border-2 border-slate-400 shadow-sm flex items-center justify-center">
XFR
</button>
<button class="ms-button px-4 h-16 rounded text-xs font-bold bg-slate-100 hover:bg-slate-200 border-2 border-slate-400 shadow-sm flex items-center justify-center">
LRP
</button>
</div>
<!-- Customer & User Header Fields -->
<div class="lg:col-span-7 grid grid-cols-2 sm:grid-cols-3 gap-2 text-xs">
<div class="col-span-2">
<span class="text-[10px] text-red-600 font-bold block">FRANK</span>
<span class="font-bold text-slate-900 text-sm">FRANK H MANN LTD</span>
</div>
<div class="text-right">
<span class="text-red-600 font-bold">DP</span>
</div>
<div>
<label class="block font-bold text-slate-700">REF:</label>
<input type="text" class="w-full border border-slate-400 p-0.5 rounded yellow-input">
</div>
<div>
<label class="block font-bold text-slate-700">Date:</label>
<input type="text" value="20/10/26" class="w-full border border-slate-400 p-0.5 rounded text-center font-bold">
</div>
<div class="col-span-2 sm:col-span-3 text-[11px] text-red-600 font-semibold italic">
If you are not user check before editing or start new ticket
</div>
</div>
</div>
<!-- RESTRUCTURED HERB SECTION (Boxes for Quantities) -->
<div class="mb-2 border-2 border-red-300 bg-red-50 p-2 rounded shadow-sm">
<div class="flex items-center justify-between mb-1.5 border-b border-red-200 pb-1">
<span class="font-bold text-xs text-red-800 uppercase tracking-wide flex items-center gap-1.5">
<i class="fa-solid fa-leaf text-green-600"></i> Herb Quantities & Quality Checklist
</span>
<span class="text-[11px] font-semibold text-red-600">Please use fresh spinach and double check quality</span>
</div>
<div id="herbContainer" class="grid grid-cols-2 sm:grid-cols-4 md:grid-cols-8 gap-2 text-xs">
<!-- Herb input boxes generated via JavaScript -->
</div>
</div>
<!-- Summary Bar (Total Lines & Value with requested £ symbol) -->
<div class="flex justify-end items-center gap-4 my-2 px-2">
<div class="flex items-center gap-2">
<span class="font-bold text-xs">Total Lines</span>
<input type="text" id="totalLines" value="8" readonly class="w-14 p-1 text-center font-bold bg-[#d8f0d8] border border-slate-400 rounded">
</div>
<div class="flex items-center gap-2">
<span class="font-bold text-xs">Value</span>
<!-- Value Input Field -->
<input type="text" id="totalValue" value="3,036.50" readonly class="w-28 p-1 text-right font-bold bg-[#d8f0d8] border border-slate-400 rounded text-slate-900">
<!-- NEW: £ Symbol added immediately after value box -->
<span class="font-bold text-slate-800 text-sm">£</span>
</div>
</div>
<!-- Product Table with NEW Stock Column -->
<div class="overflow-x-auto border border-slate-400 bg-white rounded shadow-inner mb-2">
<table class="w-full text-left border-collapse text-xs">
<thead>
<tr class="table-header divide-x divide-emerald-800 text-center">
<th class="p-1.5 w-20">Code</th>
<th class="p-1.5 min-w-[130px]">Product</th>
<th class="p-1.5 min-w-[120px]">Variety</th>
<th class="p-1.5 min-w-[110px]">Brand</th>
<!-- NEW COLUMN: Stock status before Qty -->
<th class="p-1.5 w-28 bg-emerald-900 text-white">Stock</th>
<th class="p-1.5 w-16">Qty</th>
<th class="p-1.5 w-20">Price (£)</th>
<th class="p-1.5 w-20">Value (£)</th>
<th class="p-1.5 w-24 bg-teal-900 text-white">Guide Price</th>
<th class="p-1.5 w-10">
<i class="fa-solid fa-trash-can"></i>
</th>
</tr>
</thead>
<tbody id="productTableBody" class="divide-y divide-slate-300">
<!-- Dynamic Product Rows generated via JS -->
</tbody>
</table>
</div>
<!-- Bottom Action Toolbar -->
<div class="grid grid-cols-2 sm:grid-cols-5 md:grid-cols-9 gap-1.5 pt-2 border-t border-slate-300">
<button onclick="addProductRow()" class="ms-button py-2 px-1 font-bold rounded flex flex-col items-center justify-center text-slate-800 hover:bg-slate-100 text-xs">
Add Product
</button>
<button class="ms-button py-2 px-1 font-bold rounded flex flex-col items-center justify-center text-slate-800 hover:bg-slate-100 text-xs">
View Open Tickets
</button>
<button onclick="saveTicket()" class="ms-button py-2 px-1 font-bold rounded flex flex-col items-center justify-center text-slate-800 hover:bg-slate-100 text-xs">
Save
</button>
<button class="ms-button py-2 px-1 font-bold rounded flex flex-col items-center justify-center text-slate-800 hover:bg-slate-100 text-xs">
<i class="fa-solid fa-floppy-disk text-slate-500 mb-0.5"></i>
</button>
<button class="ms-button py-2 px-1 font-bold rounded flex flex-col items-center justify-center text-slate-800 hover:bg-slate-100 text-xs">
Print Cash
</button>
<button class="ms-button py-2 px-1 font-bold rounded flex flex-col items-center justify-center text-slate-800 hover:bg-slate-100 text-xs">
Print Del
</button>
<button class="ms-button py-2 px-1 font-bold rounded flex flex-col items-center justify-center text-slate-800 hover:bg-slate-100 text-xs">
Rollback
</button>
<button class="ms-button py-2 px-1 font-bold rounded flex flex-col items-center justify-center text-slate-800 hover:bg-slate-100 text-xs">
Edit
</button>
<button onclick="clearTicket()" class="ms-button py-2 px-1 font-bold rounded flex flex-col items-center justify-center text-red-700 hover:bg-red-50 text-xs">
Cancel Ticket
</button>
</div>
</div>
<!-- JavaScript Logic -->
<script>
// Sample Product Data with Stock status included
let products = [
{ id: 1, code: 'BERR', product: 'BERRIES', variety: 'BLUEBERRY', brand: 'X12 JUMBO', stock: 'in_stock', qty: 3, price: 18.40 },
{ id: 2, code: 'APPL', product: 'APPLES', variety: 'RUSSET', brand: 'pp x14x 1kg', stock: 'in_stock', qty: 10, price: 14.00 },
{ id: 3, code: 'BANA', product: 'BANANA', variety: 'BOX 18KG', brand: 'FYFFES', stock: 'due_in', qty: 20, price: 17.00 },
{ id: 4, code: 'FIGS', product: 'FIGS', variety: 'TURKISH', brand: 'X20', stock: 'in_stock', qty: 8, price: 6.00 },
{ id: 5, code: 'MANG', product: 'MANGO', variety: 'READY TO EAT', brand: 'X9 TROPICAL', stock: 'due_in', qty: 2, price: 11.20 },
{ id: 6, code: 'MELO', product: 'MELON', variety: 'WATER', brand: 'X5', stock: 'in_stock', qty: 6, price: 16.00 },
{ id: 7, code: 'MELO', product: 'MELON', variety: 'CANTALOUPE', brand: 'X6 BRAZIL', stock: 'in_stock', qty: 2, price: 11.80 },
{ id: 8, code: 'MELO', product: 'MELON', variety: 'GALIA', brand: 'X6 BRAZIL', stock: 'due_in', qty: 3, price: 9.00 }
];
// Herb List Data
const herbs = [
{ id: 'basil', label: 'Basil', qty: 5 },
{ id: 'chive', label: 'Chive', qty: 15 },
{ id: 'coriander', label: 'Coriander', qty: 30 },
{ id: 'mint', label: 'Mint', qty: 10 },
{ id: 'rosemary', label: 'Rosemary', qty: 10 },
{ id: 'sage', label: 'Sage', qty: 5 },
{ id: 'thyme', label: 'Thyme', qty: 10 },
{ id: 'spinach', label: 'Spinach', qty: 1 }
];
// Render Herb Quantity Box Layout
function renderHerbs() {
const container = document.getElementById('herbContainer');
container.innerHTML = herbs.map(herb => `
<div class="flex items-center justify-between bg-white border border-red-300 rounded p-1 shadow-sm">
<label for="herb-${herb.id}" class="font-bold text-slate-700 capitalize mr-1 truncate" title="${herb.label}">${herb.label}:</label>
<input type="number" id="herb-${herb.id}" min="0" value="${herb.qty}"
onchange="updateHerbQty('${herb.id}', this.value)"
class="w-10 text-center font-bold yellow-input border border-slate-300 rounded p-0.5 focus:ring-1 focus:ring-red-500">
</div>
`).join('');
}
// Update Herb Quantity
function updateHerbQty(id, val) {
const item = herbs.find(h => h.id === id);
if (item) {
item.qty = parseInt(val) || 0;
}
}
// Toggle stock status when clicked
function toggleStock(index) {
products[index].stock = products[index].stock === 'in_stock' ? 'due_in' : 'in_stock';
renderTable();
}
// Render Product Table Rows
function renderTable() {
const tbody = document.getElementById('productTableBody');
tbody.innerHTML = '';
let grandTotal = 0;
products.forEach((prod, idx) => {
const lineValue = prod.qty * prod.price;
const guidePrice = prod.price * 1.05; // 5% higher than unit price
grandTotal += lineValue;
// Stock Badge Styling (Green for 'In Stock', Red for 'Due In')
const isAvailable = prod.stock === 'in_stock';
const stockBadgeHTML = isAvailable
? `<button onclick="toggleStock(${idx})" class="w-full bg-emerald-600 hover:bg-emerald-700 text-white font-bold py-1 px-2 rounded-full text-[11px] shadow-sm transition flex items-center justify-center gap-1">
<i class="fa-solid fa-circle-check text-[10px]"></i> In Stock
</button>`
: `<button onclick="toggleStock(${idx})" class="w-full bg-red-600 hover:bg-red-700 text-white font-bold py-1 px-2 rounded-full text-[11px] shadow-sm transition flex items-center justify-center gap-1">
<i class="fa-solid fa-clock text-[10px]"></i> Due In
</button>`;
const tr = document.createElement('tr');
tr.className = 'hover:bg-slate-50 border-b border-slate-200';
tr.innerHTML = `
<td class="p-1">
<select onchange="updateRow(${idx}, 'code', this.value)" class="w-full yellow-input border border-slate-300 p-1 rounded font-bold text-center">
<option value="${prod.code}">${prod.code}</option>
<option value="BERR">BERR</option>
<option value="APPL">APPL</option>
<option value="BANA">BANA</option>
<option value="FIGS">FIGS</option>
<option value="MANG">MANG</option>
<option value="MELO">MELO</option>
</select>
</td>
<td class="p-1">
<input type="text" value="${prod.product}" onchange="updateRow(${idx}, 'product', this.value)" class="w-full yellow-input border border-slate-300 p-1 rounded uppercase font-semibold">
</td>
<td class="p-1">
<input type="text" value="${prod.variety}" onchange="updateRow(${idx}, 'variety', this.value)" class="w-full yellow-input border border-slate-300 p-1 rounded uppercase">
</td>
<td class="p-1">
<input type="text" value="${prod.brand}" onchange="updateRow(${idx}, 'brand', this.value)" class="w-full yellow-input border border-slate-300 p-1 rounded uppercase">
</td>
<!-- Stock Column Badge -->
<td class="p-1 text-center">
${stockBadgeHTML}
</td>
<td class="p-1">
<input type="number" value="${prod.qty}" min="1" onchange="updateRow(${idx}, 'qty', this.value)" class="w-full yellow-input border border-slate-300 p-1 rounded text-center font-bold">
</td>
<td class="p-1">
<input type="number" step="0.01" value="${prod.price.toFixed(2)}" onchange="updateRow(${idx}, 'price', this.value)" class="w-full yellow-input border border-slate-300 p-1 rounded text-right font-bold">
</td>
<td class="p-1 text-right font-bold px-2 text-slate-800">
${lineValue.toFixed(2)}
</td>
<td class="p-1 text-right font-bold px-2 bg-teal-50 text-teal-900 border-l border-teal-200">
${guidePrice.toFixed(2)}
</td>
<td class="p-1 text-center">
<button onclick="deleteRow(${idx})" class="text-slate-500 hover:text-red-700 font-bold px-1" title="Delete Row">
<i class="fa-solid fa-trash-can text-xs"></i>
</button>
</td>
`;
tbody.appendChild(tr);
});
// Update Summary Totals
document.getElementById('totalLines').value = products.length;
document.getElementById('totalValue').value = grandTotal.toLocaleString('en-GB', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}
// Row Update Handler
function updateRow(index, field, value) {
if (field === 'qty') {
products[index].qty = parseFloat(value) || 0;
} else if (field === 'price') {
products[index].price = parseFloat(value) || 0;
} else {
products[index][field] = value;
}
renderTable();
}
// Add New Line Item
function addProductRow() {
products.push({
id: Date.now(),
code: 'NEW',
product: 'NEW ITEM',
variety: 'STANDARD',
brand: 'X10',
stock: 'in_stock',
qty: 1,
price: 10.00
});
renderTable();
}
// Delete Row Item
function deleteRow(index) {
products.splice(index, 1);
renderTable();
}
// Start New Ticket Reset
function startNewTicket() {
products = [];
document.getElementById('ticketNo').value = Math.floor(100000 + Math.random() * 900000);
renderTable();
}
// Save Ticket Simulation
function saveTicket() {
alert('Ticket ' + document.getElementById('ticketNo').value + ' saved successfully!');
}
// Clear/Cancel Ticket
function clearTicket() {
if(confirm('Are you sure you want to cancel and clear this ticket?')) {
startNewTicket();
}
}
// Initialize on Load
window.onload = function() {
renderHerbs();
renderTable();
};
</script>
</body>
</html>
```21,250 chars · codepastes.com