add date barcode
This commit is contained in:
parent
8fccefd923
commit
d52dfbe9df
62
index.php
62
index.php
@ -7277,11 +7277,20 @@ runtime_debug_mark('page:rendering', ['page' => (string)$page]);
|
||||
</td>
|
||||
<td><?= !empty($item['expiry_date']) ? htmlspecialchars((string)$item['expiry_date']) : '---' ?></td>
|
||||
<td><?= number_format((float)$item['vat_rate'], 2) ?>%</td>
|
||||
<?php
|
||||
$itemBarcodePrice = number_format((float)$item['sale_price'] * (1 + (float)($item['vat_rate'] ?? 0) / 100), 3);
|
||||
$itemSkuJs = htmlspecialchars(json_encode((string)($item['sku'] ?? ''), JSON_UNESCAPED_UNICODE), ENT_QUOTES, 'UTF-8');
|
||||
$itemNameArJs = htmlspecialchars(json_encode((string)($item['name_ar'] ?? ''), JSON_UNESCAPED_UNICODE), ENT_QUOTES, 'UTF-8');
|
||||
$itemNameEnJs = htmlspecialchars(json_encode((string)($item['name_en'] ?? ''), JSON_UNESCAPED_UNICODE), ENT_QUOTES, 'UTF-8');
|
||||
$itemBarcodePriceJs = htmlspecialchars(json_encode((string)$itemBarcodePrice, JSON_UNESCAPED_UNICODE), ENT_QUOTES, 'UTF-8');
|
||||
$itemExpiryDateJs = htmlspecialchars(json_encode(!empty($item['expiry_date']) ? (string)$item['expiry_date'] : '', JSON_UNESCAPED_UNICODE), ENT_QUOTES, 'UTF-8');
|
||||
?>
|
||||
<td>
|
||||
<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-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_ar']) ?>', '<?= htmlspecialchars($item['name_en']) ?>', '<?= number_format((float)$item['sale_price'] * (1 + (float)($item['vat_rate'] ?? 0) / 100), 3) ?>')"><i class="bi bi-upc"></i></button>
|
||||
<button class="btn btn-outline-dark" title="Barcode" onclick="printItemBarcode(<?= $itemSkuJs ?>, <?= $itemNameArJs ?>, <?= $itemNameEnJs ?>, <?= $itemBarcodePriceJs ?>)"><i class="bi bi-upc"></i></button>
|
||||
<button class="btn btn-outline-secondary" title="Barcode + Dates" onclick="printItemBarcodeWithDates(<?= $itemSkuJs ?>, <?= $itemNameArJs ?>, <?= $itemNameEnJs ?>, <?= $itemExpiryDateJs ?>)"><i class="bi bi-calendar-date"></i></button>
|
||||
<form method="POST" class="d-inline" onsubmit="return confirm('Are you sure?')">
|
||||
<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>
|
||||
@ -7318,7 +7327,8 @@ runtime_debug_mark('page:rendering', ['page' => (string)$page]);
|
||||
|
||||
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-outline-dark" onclick="printItemBarcode('<?= htmlspecialchars($item['sku']) ?>', '<?= htmlspecialchars($item['name_ar']) ?>', '<?= htmlspecialchars($item['name_en']) ?>', '<?= number_format((float)$item['sale_price'] * (1 + (float)($item['vat_rate'] ?? 0) / 100), 3) ?>')"><i class="bi bi-printer"></i> Print Barcode</button>
|
||||
<button class="btn btn-outline-dark" onclick="printItemBarcode(<?= $itemSkuJs ?>, <?= $itemNameArJs ?>, <?= $itemNameEnJs ?>, <?= $itemBarcodePriceJs ?>)"><i class="bi bi-printer"></i> Print Barcode</button>
|
||||
<button class="btn btn-outline-secondary" onclick="printItemBarcodeWithDates(<?= $itemSkuJs ?>, <?= $itemNameArJs ?>, <?= $itemNameEnJs ?>, <?= $itemExpiryDateJs ?>)"><i class="bi bi-calendar-date"></i> Barcode + Dates</button>
|
||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal" data-en="Close" data-ar="إغلاق">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -12223,6 +12233,54 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Barcode + Dates Print Modal -->
|
||||
<div class="modal fade" id="datedBarcodePrintModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content border-0 shadow">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Print Barcode + Dates Label</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body text-center">
|
||||
<div id="datedBarcodeContainer" class="p-3 bg-white border mb-3 mx-auto" style="width: fit-content; max-width: 100%;">
|
||||
<div id="datedBarcodeLabelName" class="fw-bold small mb-1"></div>
|
||||
<svg id="datedBarcodeSvg" style="max-width: 100%; height: auto;"></svg>
|
||||
<div id="datedBarcodeLabelDates" class="small mt-2 text-start mx-auto" style="width: fit-content; min-width: 145px;"></div>
|
||||
</div>
|
||||
<div class="row g-2 mb-3 text-start">
|
||||
<div class="col-6">
|
||||
<label class="form-label small" data-en="Production Date" data-ar="تاريخ الإنتاج">Production Date</label>
|
||||
<input type="date" id="datedBarcodeProductionDate" class="form-control form-control-sm">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label small" data-en="Expiry Date" data-ar="تاريخ الانتهاء">Expiry Date</label>
|
||||
<input type="date" id="datedBarcodeExpiryDate" class="form-control form-control-sm">
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label small">Number of Labels</label>
|
||||
<input type="number" id="datedBarcodeQty" class="form-control form-control-sm mx-auto" value="1" min="1" style="width: 80px;">
|
||||
</div>
|
||||
<div class="row mb-2 mx-auto" style="max-width: 200px;">
|
||||
<div class="col-6">
|
||||
<label class="form-label small">Width (mm)</label>
|
||||
<input type="number" id="datedBarcodeWidth" class="form-control form-control-sm" value="50" min="10">
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<label class="form-label small">Height (mm)</label>
|
||||
<input type="number" id="datedBarcodeHeight" class="form-control form-control-sm" value="35" min="10">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-text text-center mb-1">For barcode labels with P / E dates, 50 × 35 mm or larger is recommended.</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-light" data-bs-dismiss="modal" data-en="Close" data-ar="إغلاق">Close</button>
|
||||
<button type="button" class="btn btn-primary" onclick="executeDatedBarcodePrint()"><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">
|
||||
|
||||
@ -18,6 +18,19 @@
|
||||
};
|
||||
}
|
||||
|
||||
function getSingleBarcodeScale(labelWidthMm, labelHeightMm) {
|
||||
if (labelWidthMm <= 32 || labelHeightMm <= 20) {
|
||||
return 0.96;
|
||||
}
|
||||
if (labelWidthMm <= 40 || labelHeightMm <= 25) {
|
||||
return 0.92;
|
||||
}
|
||||
if (labelWidthMm <= 50 || labelHeightMm <= 30) {
|
||||
return 0.88;
|
||||
}
|
||||
return 0.84;
|
||||
}
|
||||
|
||||
function getSingleBarcodeOptions(sku, labelWidthMm, labelHeightMm) {
|
||||
const skuText = String(sku || '');
|
||||
const skuLength = skuText.length;
|
||||
@ -77,10 +90,14 @@
|
||||
|
||||
function buildSingleBarcodeSvgMarkup(sku, labelWidthMm, labelHeightMm) {
|
||||
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
const scale = getSingleBarcodeScale(labelWidthMm, labelHeightMm);
|
||||
JsBarcode(svg, sku, getSingleBarcodeOptions(sku, labelWidthMm, labelHeightMm));
|
||||
svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
|
||||
svg.style.width = '100%';
|
||||
svg.style.width = Math.round(scale * 100) + '%';
|
||||
svg.style.maxWidth = '100%';
|
||||
svg.style.height = 'auto';
|
||||
svg.style.display = 'block';
|
||||
svg.style.margin = '0 auto';
|
||||
return svg.outerHTML;
|
||||
}
|
||||
|
||||
@ -93,6 +110,7 @@
|
||||
const dimensions = getSingleBarcodePrintDimensions();
|
||||
const width = dimensions.width;
|
||||
const height = dimensions.height;
|
||||
const scale = getSingleBarcodeScale(width, height);
|
||||
const nameContainer = document.getElementById('barcodeLabelName');
|
||||
const priceContainer = document.getElementById('barcodeLabelPrice');
|
||||
const previewContainer = document.getElementById('barcodeContainer');
|
||||
@ -104,15 +122,18 @@
|
||||
|
||||
nameContainer.innerHTML = buildSingleBarcodeNameHtml(label.nameAr, label.nameEn);
|
||||
priceContainer.textContent = label.price ? 'OMR ' + label.price : '';
|
||||
previewContainer.style.width = Math.min(Math.max(width * 4, 180), 320) + 'px';
|
||||
previewContainer.style.width = Math.min(Math.max(width * 3.6, 170), 280) + 'px';
|
||||
previewContainer.style.maxWidth = '100%';
|
||||
previewContainer.style.padding = height <= 25 ? '12px' : '16px';
|
||||
|
||||
svg.innerHTML = '';
|
||||
JsBarcode(svg, label.sku, getSingleBarcodeOptions(label.sku, width, height));
|
||||
svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
|
||||
svg.style.width = '100%';
|
||||
svg.style.width = Math.round(scale * 100) + '%';
|
||||
svg.style.maxWidth = '100%';
|
||||
svg.style.height = 'auto';
|
||||
svg.style.display = 'block';
|
||||
svg.style.margin = '0 auto';
|
||||
}
|
||||
|
||||
function initSingleBarcodePreviewControls() {
|
||||
@ -272,6 +293,309 @@
|
||||
}, 500);
|
||||
};
|
||||
|
||||
function formatBarcodeLabelDate(value) {
|
||||
const dateText = String(value || '').trim();
|
||||
const match = dateText.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
||||
if (match) {
|
||||
return `${match[3]}/${match[2]}/${match[1]}`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function buildDatedBarcodeDateRowsHtml(productionDate, expiryDate) {
|
||||
const productionText = formatBarcodeLabelDate(productionDate) || '--/--/----';
|
||||
const expiryText = formatBarcodeLabelDate(expiryDate) || '--/--/----';
|
||||
|
||||
return `
|
||||
<div class="label-date-row"><span class="label-date-key">P:</span><span class="label-date-value">${escapeBarcodeLabelHtml(productionText)}</span></div>
|
||||
<div class="label-date-row"><span class="label-date-key">E:</span><span class="label-date-value">${escapeBarcodeLabelHtml(expiryText)}</span></div>
|
||||
`;
|
||||
}
|
||||
|
||||
function getDatedBarcodeLabelData() {
|
||||
return window.currentDatedBarcodeLabel || null;
|
||||
}
|
||||
|
||||
function getDatedBarcodePrintDimensions() {
|
||||
return {
|
||||
width: Math.max(parseInt(document.getElementById('datedBarcodeWidth').value, 10) || 50, 10),
|
||||
height: Math.max(parseInt(document.getElementById('datedBarcodeHeight').value, 10) || 35, 10)
|
||||
};
|
||||
}
|
||||
|
||||
function getDatedBarcodeScale(labelWidthMm, labelHeightMm) {
|
||||
if (labelWidthMm <= 32 || labelHeightMm <= 24) {
|
||||
return 0.88;
|
||||
}
|
||||
if (labelWidthMm <= 40 || labelHeightMm <= 30) {
|
||||
return 0.84;
|
||||
}
|
||||
if (labelWidthMm <= 50 || labelHeightMm <= 35) {
|
||||
return 0.80;
|
||||
}
|
||||
return 0.76;
|
||||
}
|
||||
|
||||
function getDatedBarcodeOptions(sku, labelWidthMm, labelHeightMm) {
|
||||
const baseOptions = getSingleBarcodeOptions(sku, labelWidthMm, labelHeightMm);
|
||||
const skuLength = String(sku || '').length;
|
||||
const showValue = labelHeightMm >= 42 && labelWidthMm >= 50 && skuLength <= 16;
|
||||
|
||||
return {
|
||||
...baseOptions,
|
||||
displayValue: showValue,
|
||||
fontSize: showValue ? 9 : 8,
|
||||
textMargin: showValue ? 2 : 0,
|
||||
height: Math.max(Math.round(baseOptions.height * (showValue ? 0.78 : 0.86)), 24),
|
||||
margin: Math.max(baseOptions.margin, 6),
|
||||
marginBottom: showValue ? 1 : 0
|
||||
};
|
||||
}
|
||||
|
||||
function buildDatedBarcodeSvgMarkup(sku, labelWidthMm, labelHeightMm) {
|
||||
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
const scale = getDatedBarcodeScale(labelWidthMm, labelHeightMm);
|
||||
JsBarcode(svg, sku, getDatedBarcodeOptions(sku, labelWidthMm, labelHeightMm));
|
||||
svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
|
||||
svg.style.width = Math.round(scale * 100) + '%';
|
||||
svg.style.maxWidth = '100%';
|
||||
svg.style.height = 'auto';
|
||||
svg.style.display = 'block';
|
||||
svg.style.margin = '0 auto';
|
||||
return svg.outerHTML;
|
||||
}
|
||||
|
||||
function renderDatedBarcodePreview() {
|
||||
const label = getDatedBarcodeLabelData();
|
||||
if (!label) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dimensions = getDatedBarcodePrintDimensions();
|
||||
const width = dimensions.width;
|
||||
const height = dimensions.height;
|
||||
const scale = getDatedBarcodeScale(width, height);
|
||||
const nameContainer = document.getElementById('datedBarcodeLabelName');
|
||||
const datesContainer = document.getElementById('datedBarcodeLabelDates');
|
||||
const previewContainer = document.getElementById('datedBarcodeContainer');
|
||||
const svg = document.getElementById('datedBarcodeSvg');
|
||||
const productionInput = document.getElementById('datedBarcodeProductionDate');
|
||||
const expiryInput = document.getElementById('datedBarcodeExpiryDate');
|
||||
|
||||
if (!nameContainer || !datesContainer || !previewContainer || !svg) {
|
||||
return;
|
||||
}
|
||||
|
||||
nameContainer.innerHTML = buildSingleBarcodeNameHtml(label.nameAr, label.nameEn);
|
||||
datesContainer.innerHTML = buildDatedBarcodeDateRowsHtml(
|
||||
productionInput ? productionInput.value : '',
|
||||
expiryInput ? expiryInput.value : ''
|
||||
);
|
||||
previewContainer.style.width = Math.min(Math.max(width * 3.8, 180), 300) + 'px';
|
||||
previewContainer.style.maxWidth = '100%';
|
||||
previewContainer.style.padding = height <= 30 ? '10px 12px' : '12px 14px';
|
||||
|
||||
svg.innerHTML = '';
|
||||
JsBarcode(svg, label.sku, getDatedBarcodeOptions(label.sku, width, height));
|
||||
svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');
|
||||
svg.style.width = Math.round(scale * 100) + '%';
|
||||
svg.style.maxWidth = '100%';
|
||||
svg.style.height = 'auto';
|
||||
svg.style.display = 'block';
|
||||
svg.style.margin = '0 auto';
|
||||
}
|
||||
|
||||
function initDatedBarcodePreviewControls() {
|
||||
['datedBarcodeWidth', 'datedBarcodeHeight', 'datedBarcodeProductionDate', 'datedBarcodeExpiryDate'].forEach((id) => {
|
||||
const input = document.getElementById(id);
|
||||
if (!input || input.dataset.barcodePreviewBound === '1') {
|
||||
return;
|
||||
}
|
||||
|
||||
input.dataset.barcodePreviewBound = '1';
|
||||
input.addEventListener('input', renderDatedBarcodePreview);
|
||||
input.addEventListener('change', renderDatedBarcodePreview);
|
||||
});
|
||||
}
|
||||
|
||||
initDatedBarcodePreviewControls();
|
||||
|
||||
window.printItemBarcodeWithDates = function(sku, nameAr, nameEn, defaultExpiryDate) {
|
||||
if (!sku) {
|
||||
Swal.fire('Error', 'This item has no SKU/Barcode assigned.', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
window.currentDatedBarcodeLabel = {
|
||||
sku: String(sku),
|
||||
nameAr: nameAr || '',
|
||||
nameEn: nameEn || ''
|
||||
};
|
||||
|
||||
const productionInput = document.getElementById('datedBarcodeProductionDate');
|
||||
const expiryInput = document.getElementById('datedBarcodeExpiryDate');
|
||||
if (productionInput) {
|
||||
productionInput.value = '';
|
||||
}
|
||||
if (expiryInput) {
|
||||
expiryInput.value = defaultExpiryDate || '';
|
||||
}
|
||||
|
||||
renderDatedBarcodePreview();
|
||||
|
||||
const modal = new bootstrap.Modal(document.getElementById('datedBarcodePrintModal'));
|
||||
modal.show();
|
||||
};
|
||||
|
||||
window.executeDatedBarcodePrint = function() {
|
||||
const qty = Math.max(parseInt(document.getElementById('datedBarcodeQty').value, 10) || 1, 1);
|
||||
const dimensions = getDatedBarcodePrintDimensions();
|
||||
const width = dimensions.width;
|
||||
const height = dimensions.height;
|
||||
const label = getDatedBarcodeLabelData();
|
||||
const productionDate = document.getElementById('datedBarcodeProductionDate').value || '';
|
||||
const expiryDate = document.getElementById('datedBarcodeExpiryDate').value || '';
|
||||
|
||||
if (!label) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!productionDate || !expiryDate) {
|
||||
Swal.fire('Missing dates', 'Please select both production and expiry dates before printing.', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
if (expiryDate < productionDate) {
|
||||
Swal.fire('Invalid dates', 'Expiry date must be the same as or later than the production date.', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
const nameHtml = buildSingleBarcodeNameHtml(label.nameAr, label.nameEn);
|
||||
const dateHtml = buildDatedBarcodeDateRowsHtml(productionDate, expiryDate);
|
||||
const svg = buildDatedBarcodeSvgMarkup(label.sku, width, height);
|
||||
const compactClass = width <= 40 || height <= 30 ? 'label-compact' : '';
|
||||
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.style.position = 'absolute';
|
||||
iframe.style.width = '0px';
|
||||
iframe.style.height = '0px';
|
||||
iframe.style.border = 'none';
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
const doc = iframe.contentWindow.document;
|
||||
|
||||
let labelsHtml = '';
|
||||
for (let i = 0; i < qty; i++) {
|
||||
labelsHtml += `
|
||||
<div class="label-container dated-label ${compactClass}">
|
||||
${nameHtml ? `<div class="label-name">${nameHtml}</div>` : ''}
|
||||
<div class="barcode-wrap">${svg}</div>
|
||||
<div class="label-dates">${dateHtml}</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
doc.open();
|
||||
doc.write(`
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
@page { size: ${width}mm ${height}mm; margin: 0; }
|
||||
body { margin: 0; padding: 0; font-family: sans-serif; }
|
||||
.label-container {
|
||||
width: ${width}mm;
|
||||
height: ${height}mm;
|
||||
page-break-after: always;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.label-container:last-child { page-break-after: avoid; }
|
||||
.dated-label {
|
||||
padding: 1.2mm 2mm;
|
||||
gap: 0.6mm;
|
||||
}
|
||||
.label-name {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
line-height: 1.05;
|
||||
}
|
||||
.label-name-ar,
|
||||
.label-name-en {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.label-name-ar {
|
||||
font-weight: 700;
|
||||
font-size: 10px;
|
||||
direction: rtl;
|
||||
}
|
||||
.label-name-en { font-size: 8px; }
|
||||
.label-dates {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 0.35mm;
|
||||
font-size: 8px;
|
||||
line-height: 1.05;
|
||||
}
|
||||
.label-date-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1mm;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.label-date-key {
|
||||
font-weight: 700;
|
||||
}
|
||||
.label-compact {
|
||||
padding: 0.9mm 1.4mm;
|
||||
gap: 0.45mm;
|
||||
}
|
||||
.label-compact .label-name-ar { font-size: 9px; }
|
||||
.label-compact .label-name-en { font-size: 7px; }
|
||||
.label-compact .label-dates { font-size: 7px; }
|
||||
.barcode-wrap {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 1.2mm;
|
||||
overflow: hidden;
|
||||
}
|
||||
.barcode-wrap svg {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
overflow: visible;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
${labelsHtml}
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
doc.close();
|
||||
|
||||
iframe.contentWindow.focus();
|
||||
setTimeout(() => {
|
||||
iframe.contentWindow.print();
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(iframe);
|
||||
}, 2000);
|
||||
}, 500);
|
||||
};
|
||||
|
||||
<?php require 'pages/sales_purchases_print_script.php'; ?>
|
||||
|
||||
window.printPosReceiptFromInvoice = function(inv) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user