adding labels
This commit is contained in:
parent
5efe80f7c5
commit
d6e5b04b82
423
index.php
423
index.php
@ -1085,6 +1085,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
|||||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/jsbarcode@3.11.5/dist/JsBarcode.all.min.js"></script>
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||||
<style>
|
<style>
|
||||||
@ -1546,7 +1547,10 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
|||||||
<div class="card p-4">
|
<div class="card p-4">
|
||||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
<h5 class="m-0" data-en="Stock Items" data-ar="أصناف المخزون">Stock Items</h5>
|
<h5 class="m-0" data-en="Stock Items" data-ar="أصناف المخزون">Stock Items</h5>
|
||||||
<div>
|
<div class="d-flex align-items-center">
|
||||||
|
<button class="btn btn-dark me-2" id="bulkBarcodeBtn" style="display:none;" onclick="openAveryModal()">
|
||||||
|
<i class="bi bi-printer"></i> <span data-en="Avery Labels" data-ar="ملصقات إيفري">Avery Labels</span>
|
||||||
|
</button>
|
||||||
<button class="btn btn-outline-success me-2" data-bs-toggle="modal" data-bs-target="#importItemsModal">
|
<button class="btn btn-outline-success me-2" data-bs-toggle="modal" data-bs-target="#importItemsModal">
|
||||||
<i class="bi bi-file-earmark-excel"></i> <span data-en="Import Excel" data-ar="استيراد من اكسل">Import Excel</span>
|
<i class="bi bi-file-earmark-excel"></i> <span data-en="Import Excel" data-ar="استيراد من اكسل">Import Excel</span>
|
||||||
</button>
|
</button>
|
||||||
@ -1583,6 +1587,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
|||||||
<table class="table table-hover align-middle">
|
<table class="table table-hover align-middle">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
<th style="width: 40px;"><input type="checkbox" id="selectAllItems" class="form-check-input"></th>
|
||||||
<th data-en="Image" data-ar="الصورة">Image</th>
|
<th data-en="Image" data-ar="الصورة">Image</th>
|
||||||
<th data-en="SKU" data-ar="الباركود">SKU</th>
|
<th data-en="SKU" data-ar="الباركود">SKU</th>
|
||||||
<th data-en="Name" data-ar="الاسم">Name</th>
|
<th data-en="Name" data-ar="الاسم">Name</th>
|
||||||
@ -1597,6 +1602,7 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
|||||||
<tbody>
|
<tbody>
|
||||||
<?php foreach ($data['items'] as $item): ?>
|
<?php foreach ($data['items'] as $item): ?>
|
||||||
<tr>
|
<tr>
|
||||||
|
<td><input type="checkbox" class="form-check-input item-checkbox" data-id="<?= $item['id'] ?>" data-sku="<?= htmlspecialchars($item['sku']) ?>" data-name="<?= htmlspecialchars($item['name_en']) ?>" data-price="<?= number_format((float)$item['sale_price'], 3) ?>"></td>
|
||||||
<td>
|
<td>
|
||||||
<?php if ($item['image_path']): ?>
|
<?php if ($item['image_path']): ?>
|
||||||
<img src="<?= htmlspecialchars($item['image_path']) ?>" alt="item" style="width: 40px; height: 40px; object-fit: cover;" class="rounded">
|
<img src="<?= htmlspecialchars($item['image_path']) ?>" alt="item" style="width: 40px; height: 40px; object-fit: cover;" class="rounded">
|
||||||
@ -1628,11 +1634,133 @@ $projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? 'Accounting System';
|
|||||||
<div class="btn-group btn-group-sm">
|
<div class="btn-group btn-group-sm">
|
||||||
<button class="btn btn-outline-info" title="View" data-bs-toggle="modal" data-bs-target="#viewItemModal<?= $item['id'] ?>"><i class="bi bi-eye"></i></button>
|
<button class="btn btn-outline-info" title="View" data-bs-toggle="modal" data-bs-target="#viewItemModal<?= $item['id'] ?>"><i class="bi bi-eye"></i></button>
|
||||||
<button class="btn btn-outline-primary" title="Edit" data-bs-toggle="modal" data-bs-target="#editItemModal<?= $item['id'] ?>"><i class="bi bi-pencil"></i></button>
|
<button class="btn btn-outline-primary" title="Edit" data-bs-toggle="modal" data-bs-target="#editItemModal<?= $item['id'] ?>"><i class="bi bi-pencil"></i></button>
|
||||||
|
<button class="btn btn-outline-dark" title="Barcode" onclick="printItemBarcode('<?= htmlspecialchars($item['sku']) ?>', '<?= htmlspecialchars($item['name_en']) ?>', '<?= number_format((float)$item['sale_price'], 3) ?>')"><i class="bi bi-upc"></i></button>
|
||||||
<form method="POST" class="d-inline" onsubmit="return confirm('Are you sure?')">
|
<form method="POST" class="d-inline" onsubmit="return confirm('Are you sure?')">
|
||||||
<input type="hidden" name="id" value="<?= $item['id'] ?>">
|
<input type="hidden" name="id" value="<?= $item['id'] ?>">
|
||||||
<button type="submit" name="delete_item" class="btn btn-outline-danger" title="Delete"><i class="bi bi-trash"></i></button>
|
<button type="submit" name="delete_item" class="btn btn-outline-danger" title="Delete"><i class="bi bi-trash"></i></button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- View Item Modal -->
|
||||||
|
<div class="modal fade" id="viewItemModal<?= $item['id'] ?>" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content border-0 shadow">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title"><?= htmlspecialchars($item['name_en']) ?></h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="text-center mb-3">
|
||||||
|
<?php if ($item['image_path']): ?>
|
||||||
|
<img src="<?= htmlspecialchars($item['image_path']) ?>" class="img-fluid rounded shadow-sm" style="max-height: 200px;">
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="bg-light rounded d-flex align-items-center justify-content-center mx-auto" style="width: 150px; height: 150px;">
|
||||||
|
<i class="bi bi-image text-muted" style="font-size: 3rem;"></i>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
<table class="table table-sm">
|
||||||
|
<tr><th class="text-muted">SKU</th><td><?= htmlspecialchars($item['sku']) ?></td></tr>
|
||||||
|
<tr><th class="text-muted">Category</th><td><?= htmlspecialchars($item['cat_en'] ?? '---') ?></td></tr>
|
||||||
|
<tr><th class="text-muted">Supplier</th><td><?= htmlspecialchars($item['supplier_name'] ?? '---') ?></td></tr>
|
||||||
|
<tr><th class="text-muted">Sale Price</th><td>OMR <?= number_format((float)$item['sale_price'], 3) ?></td></tr>
|
||||||
|
<tr><th class="text-muted">Stock Level</th><td><?= number_format((float)$item['stock_quantity'], 3) ?></td></tr>
|
||||||
|
<tr><th class="text-muted">VAT Rate</th><td><?= number_format((float)$item['vat_rate'], 3) ?>%</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-outline-dark" onclick="printItemBarcode('<?= htmlspecialchars($item['sku']) ?>', '<?= htmlspecialchars($item['name_en']) ?>', '<?= number_format((float)$item['sale_price'], 3) ?>')"><i class="bi bi-printer"></i> Print Barcode</button>
|
||||||
|
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Close</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Edit Item Modal -->
|
||||||
|
<div class="modal fade" id="editItemModal<?= $item['id'] ?>" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-lg">
|
||||||
|
<div class="modal-content border-0 shadow">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" data-en="Edit Item" data-ar="تعديل صنف">Edit Item</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<form method="POST" enctype="multipart/form-data">
|
||||||
|
<input type="hidden" name="id" value="<?= $item['id'] ?>">
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="row g-3">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label">Name (EN)</label>
|
||||||
|
<input type="text" name="name_en" class="form-control" value="<?= htmlspecialchars($item['name_en']) ?>" required>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label">Name (AR)</label>
|
||||||
|
<input type="text" name="name_ar" class="form-control" value="<?= htmlspecialchars($item['name_ar']) ?>" required>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label">Category</label>
|
||||||
|
<select name="category_id" class="form-select">
|
||||||
|
<option value="">---</option>
|
||||||
|
<?php foreach ($data['categories'] ?? [] as $c): ?>
|
||||||
|
<option value="<?= $c['id'] ?>" <?= $c['id'] == $item['category_id'] ? 'selected' : '' ?>><?= htmlspecialchars($c['name_en']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label">Unit</label>
|
||||||
|
<select name="unit_id" class="form-select">
|
||||||
|
<option value="">---</option>
|
||||||
|
<?php foreach ($data['units'] ?? [] as $u): ?>
|
||||||
|
<option value="<?= $u['id'] ?>" <?= $u['id'] == $item['unit_id'] ? 'selected' : '' ?>><?= htmlspecialchars($u['short_name_en']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label">Supplier</label>
|
||||||
|
<select name="supplier_id" class="form-select">
|
||||||
|
<option value="">---</option>
|
||||||
|
<?php foreach ($data['suppliers'] ?? [] as $s): ?>
|
||||||
|
<option value="<?= $s['id'] ?>" <?= $s['id'] == $item['supplier_id'] ? 'selected' : '' ?>><?= htmlspecialchars($s['name']) ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label">Sale Price</label>
|
||||||
|
<input type="number" step="0.001" name="sale_price" class="form-control" value="<?= (float)$item['sale_price'] ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label">Purchase Price</label>
|
||||||
|
<input type="number" step="0.001" name="purchase_price" class="form-control" value="<?= (float)$item['purchase_price'] ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label">Stock Qty</label>
|
||||||
|
<input type="number" step="0.001" name="stock_quantity" class="form-control" value="<?= (float)$item['stock_quantity'] ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<label class="form-label">Min Level</label>
|
||||||
|
<input type="number" step="0.001" name="min_stock_level" class="form-control" value="<?= (float)$item['min_stock_level'] ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label">SKU</label>
|
||||||
|
<input type="text" name="sku" class="form-control" value="<?= htmlspecialchars($item['sku']) ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label">VAT Rate (%)</label>
|
||||||
|
<input type="number" step="0.001" name="vat_rate" class="form-control" value="<?= (float)$item['vat_rate'] ?>">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<label class="form-label">Item Picture</label>
|
||||||
|
<input type="file" name="image" class="form-control" accept="image/*">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Cancel</button>
|
||||||
|
<button type="submit" name="edit_item" class="btn btn-primary">Update Item</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
@ -3039,6 +3167,13 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
const suggestSkuBtn = document.getElementById('suggestSkuBtn');
|
const suggestSkuBtn = document.getElementById('suggestSkuBtn');
|
||||||
const skuInput = document.getElementById('skuInput');
|
const skuInput = document.getElementById('skuInput');
|
||||||
|
|
||||||
|
if (suggestSkuBtn && skuInput) {
|
||||||
|
suggestSkuBtn.addEventListener('click', function() {
|
||||||
|
const sku = Math.floor(100000000000 + Math.random() * 900000000000).toString();
|
||||||
|
skuInput.value = sku;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Toggle Expiry Date visibility
|
// Toggle Expiry Date visibility
|
||||||
if (hasExpiryToggle && expiryDateContainer) {
|
if (hasExpiryToggle && expiryDateContainer) {
|
||||||
hasExpiryToggle.addEventListener('change', function() {
|
hasExpiryToggle.addEventListener('change', function() {
|
||||||
@ -4033,7 +4168,293 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
|
|
||||||
<div id="posPrintArea" class="d-none d-print-block"></div>
|
<div id="posPrintArea" class="d-none d-print-block"></div>
|
||||||
|
|
||||||
|
<!-- Barcode Print Modal -->
|
||||||
|
<div class="modal fade" id="barcodePrintModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content border-0 shadow">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Print Barcode Label</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body text-center">
|
||||||
|
<div id="barcodeContainer" class="p-4 bg-white border mb-3 mx-auto" style="width: fit-content;">
|
||||||
|
<div id="barcodeLabelName" class="fw-bold small mb-1"></div>
|
||||||
|
<svg id="barcodeSvg"></svg>
|
||||||
|
<div id="barcodeLabelPrice" class="fw-bold mt-1"></div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label class="form-label small">Number of Labels</label>
|
||||||
|
<input type="number" id="barcodeQty" class="form-control form-control-sm mx-auto" value="1" min="1" style="width: 80px;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="button" class="btn btn-primary" onclick="executeBarcodePrint()"><i class="bi bi-printer me-2"></i>Print Now</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Avery Labels Modal -->
|
||||||
|
<div class="modal fade" id="averyLabelsModal" tabindex="-1">
|
||||||
|
<div class="modal-dialog modal-xl">
|
||||||
|
<div class="modal-content border-0 shadow">
|
||||||
|
<div class="modal-header d-print-none">
|
||||||
|
<h5 class="modal-title">Avery Barcode Labels (A4)</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="row mb-4 d-print-none">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label small">Label Layout</label>
|
||||||
|
<select id="averyLayout" class="form-select form-select-sm" onchange="updateAveryPreview()">
|
||||||
|
<option value="3x7">3 x 7 (21 Labels per sheet)</option>
|
||||||
|
<option value="3x8">3 x 8 (24 Labels per sheet)</option>
|
||||||
|
<option value="4x10">4 x 10 (40 Labels per sheet)</option>
|
||||||
|
<option value="L7651">L7651 (5 x 13 - 65 Labels)</option>
|
||||||
|
<option value="L4736">L4736 (2 x 7 - 14 Labels)</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<label class="form-label small">Copies per Item</label>
|
||||||
|
<input type="number" id="averyCopies" class="form-control form-control-sm" value="1" min="1" oninput="updateAveryPreview()">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4 d-flex align-items-end">
|
||||||
|
<button class="btn btn-primary btn-sm w-100" onclick="window.print()"><i class="bi bi-printer me-2"></i>Print A4 Sheet</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="averyPrintArea" class="avery-container">
|
||||||
|
<!-- Labels will be generated here -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Avery Label Printing */
|
||||||
|
.avery-container {
|
||||||
|
background: white;
|
||||||
|
width: 210mm; /* A4 Width */
|
||||||
|
min-height: 297mm; /* A4 Height */
|
||||||
|
padding: 10mm 5mm;
|
||||||
|
margin: 0 auto;
|
||||||
|
display: grid;
|
||||||
|
gap: 2mm;
|
||||||
|
box-shadow: 0 0 10px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
.avery-layout-3x7 { grid-template-columns: repeat(3, 1fr); grid-auto-rows: 38mm; }
|
||||||
|
.avery-layout-3x8 { grid-template-columns: repeat(3, 1fr); grid-auto-rows: 34mm; }
|
||||||
|
.avery-layout-4x10 { grid-template-columns: repeat(4, 1fr); grid-auto-rows: 27mm; }
|
||||||
|
.avery-layout-L7651 { grid-template-columns: repeat(5, 1fr); grid-auto-rows: 21mm; }
|
||||||
|
.avery-layout-L4736 { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 38mm; }
|
||||||
|
|
||||||
|
.avery-layout-L7651 .avery-label { padding: 2mm; }
|
||||||
|
.avery-layout-L7651 .avery-label svg { height: 25px; }
|
||||||
|
.avery-layout-L7651 .avery-label div { font-size: 8px !important; }
|
||||||
|
|
||||||
|
.avery-label {
|
||||||
|
border: 1px dashed #eee;
|
||||||
|
padding: 5mm;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
overflow: hidden;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avery-label svg {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
body.printing-avery .sidebar,
|
||||||
|
body.printing-avery .topbar,
|
||||||
|
body.printing-avery .modal-header,
|
||||||
|
body.printing-avery .d-print-none,
|
||||||
|
body.printing-avery .modal-backdrop {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
body.printing-avery .modal {
|
||||||
|
position: absolute !important;
|
||||||
|
left: 0 !important;
|
||||||
|
top: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
display: block !important;
|
||||||
|
visibility: visible !important;
|
||||||
|
background: white !important;
|
||||||
|
}
|
||||||
|
body.printing-avery .modal-dialog {
|
||||||
|
max-width: 100% !important;
|
||||||
|
width: 100% !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
body.printing-avery .modal-content {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
body.printing-avery .avery-label {
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
.avery-container {
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 10mm 5mm !important;
|
||||||
|
box-shadow: none !important;
|
||||||
|
border: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// Avery Label Logic
|
||||||
|
const selectAllItems = document.getElementById('selectAllItems');
|
||||||
|
const bulkBarcodeBtn = document.getElementById('bulkBarcodeBtn');
|
||||||
|
|
||||||
|
if (selectAllItems) {
|
||||||
|
selectAllItems.addEventListener('change', function() {
|
||||||
|
document.querySelectorAll('.item-checkbox').forEach(cb => {
|
||||||
|
cb.checked = this.checked;
|
||||||
|
});
|
||||||
|
toggleBulkBtn();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('change', function(e) {
|
||||||
|
if (e.target.classList.contains('item-checkbox')) {
|
||||||
|
toggleBulkBtn();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function toggleBulkBtn() {
|
||||||
|
const checked = document.querySelectorAll('.item-checkbox:checked').length;
|
||||||
|
if (bulkBarcodeBtn) {
|
||||||
|
bulkBarcodeBtn.style.display = checked > 0 ? 'inline-block' : 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.openAveryModal = function() {
|
||||||
|
const modal = new bootstrap.Modal(document.getElementById('averyLabelsModal'));
|
||||||
|
modal.show();
|
||||||
|
updateAveryPreview();
|
||||||
|
};
|
||||||
|
|
||||||
|
window.updateAveryPreview = function() {
|
||||||
|
const layout = document.getElementById('averyLayout').value;
|
||||||
|
const copies = parseInt(document.getElementById('averyCopies').value) || 1;
|
||||||
|
const container = document.getElementById('averyPrintArea');
|
||||||
|
const checkedItems = document.querySelectorAll('.item-checkbox:checked');
|
||||||
|
|
||||||
|
container.className = 'avery-container avery-layout-' + layout;
|
||||||
|
container.innerHTML = '';
|
||||||
|
|
||||||
|
checkedItems.forEach(cb => {
|
||||||
|
const sku = cb.dataset.sku;
|
||||||
|
const name = cb.dataset.name;
|
||||||
|
const price = cb.dataset.price;
|
||||||
|
|
||||||
|
for (let i = 0; i < copies; i++) {
|
||||||
|
const label = document.createElement('div');
|
||||||
|
label.className = 'avery-label';
|
||||||
|
const svgId = `bc-${sku}-${i}`;
|
||||||
|
label.innerHTML = `
|
||||||
|
<div style="font-size: 10px; font-weight: bold; margin-bottom: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 100%;">${name}</div>
|
||||||
|
<svg id="${svgId}"></svg>
|
||||||
|
<div style="font-size: 11px; font-weight: bold; margin-top: 2px;">OMR ${price}</div>
|
||||||
|
`;
|
||||||
|
container.appendChild(label);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
const bcHeight = layout === 'L7651' ? 20 : 35;
|
||||||
|
JsBarcode(`#${svgId}`, sku, {
|
||||||
|
format: "CODE128",
|
||||||
|
width: layout === 'L7651' ? 1.0 : 1.2,
|
||||||
|
height: bcHeight,
|
||||||
|
displayValue: true,
|
||||||
|
fontSize: layout === 'L7651' ? 8 : 10,
|
||||||
|
margin: 0
|
||||||
|
});
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('beforeprint', () => {
|
||||||
|
if (document.getElementById('averyLabelsModal') && document.getElementById('averyLabelsModal').classList.contains('show')) {
|
||||||
|
document.body.classList.add('printing-avery');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
window.addEventListener('afterprint', () => {
|
||||||
|
document.body.classList.remove('printing-avery');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@media print {
|
||||||
|
.barcode-print-view {
|
||||||
|
display: block !important;
|
||||||
|
width: 40mm !important; /* Standard label size */
|
||||||
|
padding: 5mm !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
text-align: center !important;
|
||||||
|
}
|
||||||
|
body.printing-barcode * {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
body.printing-barcode #posPrintArea,
|
||||||
|
body.printing-barcode #posPrintArea * {
|
||||||
|
visibility: visible !important;
|
||||||
|
}
|
||||||
|
body.printing-barcode #posPrintArea {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.printItemBarcode = function(sku, name, price) {
|
||||||
|
if (!sku) {
|
||||||
|
Swal.fire('Error', 'This item has no SKU/Barcode assigned.', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
document.getElementById('barcodeLabelName').textContent = name;
|
||||||
|
document.getElementById('barcodeLabelPrice').textContent = 'OMR ' + price;
|
||||||
|
|
||||||
|
JsBarcode("#barcodeSvg", sku, {
|
||||||
|
format: "CODE128",
|
||||||
|
lineColor: "#000",
|
||||||
|
width: 2,
|
||||||
|
height: 50,
|
||||||
|
displayValue: true
|
||||||
|
});
|
||||||
|
|
||||||
|
const modal = new bootstrap.Modal(document.getElementById('barcodePrintModal'));
|
||||||
|
modal.show();
|
||||||
|
};
|
||||||
|
|
||||||
|
window.executeBarcodePrint = function() {
|
||||||
|
const qty = parseInt(document.getElementById('barcodeQty').value) || 1;
|
||||||
|
const content = document.getElementById('barcodeContainer').innerHTML;
|
||||||
|
const printArea = document.getElementById('posPrintArea');
|
||||||
|
|
||||||
|
let printHtml = '';
|
||||||
|
for (let i = 0; i < qty; i++) {
|
||||||
|
printHtml += `<div class="barcode-print-view" style="page-break-after: always; text-align: center; margin-bottom: 20px;">${content}</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
printArea.innerHTML = printHtml;
|
||||||
|
document.body.classList.add('printing-barcode');
|
||||||
|
window.print();
|
||||||
|
document.body.classList.remove('printing-barcode');
|
||||||
|
};
|
||||||
|
|
||||||
window.viewAndPrintA4Invoice = function(data, autoPrint = true) {
|
window.viewAndPrintA4Invoice = function(data, autoPrint = true) {
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
// Reuse view logic
|
// Reuse view logic
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user