Files
citrus-cms/resources/views/components/modals/surface-area-modal.blade.php
T
2026-04-28 21:15:09 +03:00

1110 lines
48 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- Surface Area Calculation Modal -->
<div class="modal fade" id="surfaceAreaModal" tabindex="-1" role="dialog" aria-labelledby="surfaceAreaModalLabel" aria-hidden="true">
<div class="modal-dialog modal-xl" role="document" style="max-width: 85%; margin: 1.5rem auto;">
<div class="modal-content">
<div class="modal-header" style="background-color: #fff; border-bottom: 1px solid #ddd;">
<h5 class="modal-title text-dark" id="surfaceAreaModalLabel">
<i class="fa fa-calculator"></i> {{e2("Surface Area Calculation")}}
</h5>
<button type="button" class="close text-dark" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<!-- Spool Info Header -->
<div class="alert alert-info mb-3">
<strong>{{e2("Spool")}}:</strong> <span id="surfaceAreaSpoolName">-</span> |
<strong>{{e2("ISO Drawing")}}:</strong> <a href="#" id="surfaceAreaIsoDrawingLink" target="_blank" class="text-primary" style="text-decoration: underline; cursor: pointer;"><span id="surfaceAreaIsoDrawing">-</span> <i class="fa fa-external-link-alt fa-sm"></i></a> |
<strong>{{e2("Line")}}:</strong> <span id="surfaceAreaLine">-</span>
</div>
<!-- Hidden Dimensions Fields (automatically populated, not visible to user) -->
<input type="hidden" id="surfaceAreaDn1">
<input type="hidden" id="surfaceAreaDn2">
<input type="hidden" id="surfaceAreaLinePipeMm1">
<input type="hidden" id="surfaceAreaLinePipeMm2">
<!-- Standard Selection Tabs (visual only) -->
<div class="btn-group mb-3" role="group" id="standardTabButtons">
<button type="button" class="btn btn-outline-primary active" data-standard="GOST">GOST</button>
<button type="button" class="btn btn-outline-primary" data-standard="EN">EN/ISO</button>
<button type="button" class="btn btn-outline-primary" data-standard="ASME">ASME/API</button>
</div>
<!-- Info message -->
<div class="alert alert-info py-2 mb-2">
<i class="fa fa-info-circle"></i> {{e2("This section allows adding materials. Calculation updates as you add items.")}}
</div>
<!-- Single Unified Table -->
<div class="table-responsive">
<table class="table table-sm table-bordered table-hover mb-0" id="surfaceAreaMainTable">
<thead class="thead-light">
<tr>
<th style="width: 8%">{{e2("Standard")}}</th>
<th style="width: 12%">{{e2("General Name")}}</th>
<th style="width: 12%">{{e2("Element EN")}}</th>
<th style="width: 12%">{{e2("Element RU")}}</th>
<th style="width: 10%">{{e2("Mfg. Standard")}}</th>
<th style="width: 6%">{{e2("Quantity")}}</th>
<th style="width: 10%">{{e2("DIA (mm)")}}</th>
<th style="width: 8%">{{e2("Cutting (mm)")}}</th>
<th style="width: 8%">{{e2("Unit (m²)")}}</th>
<th style="width: 8%">{{e2("Total")}}</th>
<th style="width: 5%">{{e2("Action")}}</th>
</tr>
</thead>
<tbody id="surfaceAreaTableBody">
<!-- Dynamic rows will be added here -->
</tbody>
</table>
</div>
<!-- Add Row Button -->
<button type="button" class="btn btn-success btn-sm mt-2" id="addSurfaceAreaRowBtn">
<i class="fa fa-plus"></i> {{e2("Add Row")}}
</button>
<!-- Summary Section - Horizontal Layout -->
<div class="row mt-4 pt-3" style="border-top: 2px solid #17a2b8;">
<div class="col-md-3 text-left">
<strong>{{e2("Fittings")}}:</strong>
<span class="text-primary font-weight-bold ml-2" id="fittingsTotalDisplay">0</span>
</div>
<div class="col-md-3 text-left">
<strong>{{e2("Pipe")}}:</strong>
<span class="text-info font-weight-bold ml-2" id="pipeTotalDisplay">0</span>
</div>
<div class="col-md-3 text-left">
<strong>{{e2("Grand Total")}}:</strong>
<span class="text-success font-weight-bold ml-2" id="grandTotalDisplay">0</span>
</div>
<div class="col-md-3 text-left">
<strong>{{e2("MTO Grand Total MM2")}}:</strong>
<span class="text-danger font-weight-bold ml-2" id="mtoGrandTotalDisplay">0</span>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">
<i class="fa fa-times"></i> {{e2("Close")}}
</button>
<button type="button" class="btn btn-success" id="saveSurfaceAreaBtn">
<i class="fa fa-save"></i> {{e2("Save")}}
</button>
</div>
</div>
</div>
</div>
<script>
var surfaceAreaData = {};
var currentRowId = null;
var currentRowIndex = null;
var surfaceAreaDrafts = {}; // Global object to store drafts by row ID
var surfaceAreaInitialItemCount = 0; // Used to avoid wiping items when user saves only dimensions
function initSurfaceAreaElementSelect(selectEl) {
if (!selectEl || !selectEl.length) return;
if (!$.fn || typeof $.fn.select2 !== 'function') return;
if (selectEl.data('select2')) return;
selectEl.select2({
tags: true,
width: '100%',
dropdownParent: $('#surfaceAreaModal')
});
}
function initSurfaceAreaDiameterSelect(selectEl) {
if (!selectEl || !selectEl.length) return;
if (!$.fn || typeof $.fn.select2 !== 'function') return;
if (selectEl.data('select2')) return;
selectEl.select2({
tags: true,
width: '100%',
dropdownParent: $('#surfaceAreaModal')
});
}
function openSurfaceAreaModal(rowData, rowIndex) {
try {
currentRowId = rowData.id;
currentRowIndex = rowIndex;
surfaceAreaInitialItemCount = 0;
// Store rowData globally for pipe calculations
window.currentSurfaceAreaRowData = rowData;
$('#surfaceAreaSpoolName').text(rowData.spool || '-');
$('#surfaceAreaIsoDrawing').text(rowData.iso_drawings || '-');
$('#surfaceAreaLine').text(rowData.line || '-');
// Load pipe dimensions
$('#surfaceAreaDn1').val(rowData.dn_1 || '');
$('#surfaceAreaDn2').val(rowData.dn_2 || '');
$('#surfaceAreaLinePipeMm1').val(rowData.line_pipe_mm_1 || '');
$('#surfaceAreaLinePipeMm2').val(rowData.line_pipe_mm_2 || '');
var isoDrawing = rowData.iso_drawings || '';
if(isoDrawing) {
var drawingUrl = '{{url("storage/documents/001_Drawings/002_Iso")}}/' + isoDrawing + '.pdf';
$('#surfaceAreaIsoDrawingLink').attr('href', drawingUrl).show();
} else {
$('#surfaceAreaIsoDrawingLink').removeAttr('href').hide();
}
surfaceAreaData = {
items: [],
fittingsTotal: 0,
pipeTotal: 0,
grandTotal: 0,
mtoGrandTotal: 0
};
if(isoDrawing) {
$.getJSON('/api/surface-area/mto-total?iso_drawings=' + encodeURIComponent(isoDrawing), function(response) {
if(response && response.mto_total !== undefined) {
var mtoTotal = parseFloat(response.mto_total) || 0;
surfaceAreaData.mtoGrandTotal = mtoTotal;
$('#mtoGrandTotalDisplay').text(mtoTotal.toFixed(6));
}
}).fail(function() {
console.log('MTO total could not be loaded');
});
}
// Check for draft and load if exists, otherwise load from server
if (surfaceAreaDrafts[currentRowId]) {
// Restore draft
restoreSurfaceAreaDraft(surfaceAreaDrafts[currentRowId]);
surfaceAreaInitialItemCount = (surfaceAreaDrafts[currentRowId].items || []).length;
} else {
$('#surfaceAreaTableBody').empty();
// Load from server
$.getJSON('/api/surface-area/get-saved-items?construction_paint_log_id=' + currentRowId, function(response) {
surfaceAreaInitialItemCount = (response && response.items) ? response.items.length : 0;
if(response && response.items && response.items.length > 0) {
response.items.forEach(function(item) {
loadSavedItemRow(item);
});
updateSurfaceAreaSummary();
}
}).fail(function() {
console.log('Saved items could not be loaded');
});
}
} catch (e) {
console.error('Error opening Surface Area modal:', e);
}
$('#surfaceAreaModal').modal('show');
}
function restoreSurfaceAreaDraft(draft) {
if (!draft) return;
// Restore inputs
$('#surfaceAreaDn1').val(draft.dn1 || '');
$('#surfaceAreaDn2').val(draft.dn2 || '');
$('#surfaceAreaLinePipeMm1').val(draft.linePipeMm1 || '');
$('#surfaceAreaLinePipeMm2').val(draft.linePipeMm2 || '');
$('#surfaceAreaTableBody').empty();
if (draft.items && draft.items.length > 0) {
draft.items.forEach(function(item) {
loadSavedItemRow(item);
});
}
updateSurfaceAreaSummary();
}
// Kaydedilmiş item'ı tabloya ekle
function loadSavedItemRow(item) {
var selectedStandard = item.standard || 'GOST';
var tbody = $('#surfaceAreaTableBody');
var rowHtml = `
<tr class="surface-area-row">
<td>
<select class="form-control form-control-sm standard-select">
<option value="GOST" ${selectedStandard === 'GOST' ? 'selected' : ''}>GOST</option>
<option value="EN" ${selectedStandard === 'EN' ? 'selected' : ''}>EN/ISO</option>
<option value="ASME" ${selectedStandard === 'ASME' ? 'selected' : ''}>ASME/API</option>
</select>
</td>
<td><input type="text" class="form-control form-control-sm general-name" readonly value="${item.general_name || ''}" data-was-pipe="${(item.general_name || '').toLowerCase().indexOf('pipe') !== -1}"></td>
<td>
<select class="form-control form-control-sm element-en-select">
<option value="${item.element_en || ''}" selected>${item.element_en || '{{e2("Select")}}'}</option>
</select>
</td>
<td>
<select class="form-control form-control-sm element-ru-select">
<option value="${item.element_ru || ''}" selected>${item.element_ru || '{{e2("Select")}}'}</option>
</select>
</td>
<td><input type="text" class="form-control form-control-sm mfg-standard" readonly value="${item.mfg_standard || ''}"></td>
<td><input type="number" class="form-control form-control-sm quantity" value="${item.quantity || 1}" min="1" step="1"></td>
<td>
<select class="form-control form-control-sm diameter-select">
<option value="${item.diameter || ''}" selected>${item.diameter ? item.diameter + 'mm' : '{{e2("Select")}}'}</option>
</select>
</td>
<td><input type="number" class="form-control form-control-sm cutting-mm" step="0.01" placeholder="mm" value="${item.cutting_mm || ''}" ${(item.general_name || '').toLowerCase().indexOf('pipe') !== -1 ? '' : 'disabled'}></td>
<td><input type="number" class="form-control form-control-sm unit-area" readonly step="0.000001" value="${item.unit_area || ''}"></td>
<td><input type="number" class="form-control form-control-sm row-total" readonly step="0.000001" value="${item.total || ''}"></td>
<td>
<button type="button" class="btn btn-danger btn-sm remove-row-btn">
<i class="fa fa-times"></i>
</button>
</td>
</tr>
`;
tbody.append(rowHtml);
}
function calculateRowTotal(row) {
var quantity = parseFloat(row.find('.quantity').val()) || 0;
var unitArea = parseFloat(row.find('.unit-area').val()) || 0;
var total = quantity * unitArea;
row.find('.row-total').val(total.toFixed(6));
updateSurfaceAreaSummary();
}
// Pipe için diameter mm ve inch'ten DN değerini hesapla/eşleştir
// Predefined diameter_inch değerini kullanarak DN hesapla
function updatePipeDimensions(diameterMm, diameterInch, row) {
// Bu fonksiyon artık sadece DN hesaplamak için kullanılıyor
// DN1 ve DN2 değerleri tüm pipe satırlarına bakılarak güncelleniyor
updateAllPipeDimensions();
}
// Tüm pipe satırlarını tarayarak DN1 ve DN2 değerlerini güncelle (inch olarak)
// 4 inch seçildiğinde DN1'e, diğerleri DN2'ye yazılacak
// Eğer hiç pipe seçimi yoksa veya diameter seçilmemişse, DN1 ve DN2 temizlenir
function updateAllPipeDimensions() {
var dn1Value = '';
var dn2Values = [];
var hasAnyPipe = false;
// Tüm pipe satırlarını sırayla tarayarak inch değerlerini kontrol et
$('.surface-area-row').each(function() {
var row = $(this);
var generalName = (row.find('.general-name').val() || '').toLowerCase();
// Sadece pipe satırlarını işle
if (generalName.indexOf('pipe') !== -1) {
hasAnyPipe = true;
var diameterSelect = row.find('.diameter-select');
var selected = diameterSelect.find(':selected');
var diameterInch = selected.data('diameter-inch') || '';
var diameterMm = diameterSelect.val() || '';
// Diameter seçilmişse işle
if (diameterInch && diameterMm) {
// Inch değerini parse et ve temizle (örn: "2"" → "2", "1/2"" → "0.5")
var inchValue = parseInchValue(diameterInch);
if (inchValue !== null) {
var inchNum = parseFloat(inchValue);
// 4 inch kontrolü (tam olarak 4 inch olmalı)
if (inchNum === 4) {
// 4 inch ise DN1'e yaz (sadece ilk 4 inch değeri)
if (!dn1Value) {
dn1Value = inchValue;
}
} else {
// 4 inch değilse DN2'ye ekle
dn2Values.push(inchValue);
}
}
}
}
});
// Eğer hiç pipe yoksa veya hiçbirinde diameter seçilmemişse, DN1 ve DN2'yi temizle
if (!hasAnyPipe || (dn1Value === '' && dn2Values.length === 0)) {
$('#surfaceAreaDn1').val('');
$('#surfaceAreaDn2').val('');
} else {
// DN1'e 4 inch değerini yaz (varsa)
$('#surfaceAreaDn1').val(dn1Value);
// DN2'ye diğer değerleri yaz (ilk değer varsa, yoksa boş)
if (dn2Values.length > 0) {
$('#surfaceAreaDn2').val(dn2Values[0]);
} else {
$('#surfaceAreaDn2').val('');
}
}
}
// Inch değerini parse et (örn: "2"" → "2", "1/2"" → "0.5", "3/4"" → "0.75")
function parseInchValue(diameterInch) {
if (!diameterInch) return null;
var inchValue = diameterInch.toString().replace(/"/g, '').trim();
// Kesirli inch değerlerini handle et (örn: "1/2", "3/4")
if (inchValue.indexOf('/') !== -1) {
var parts = inchValue.split('/');
var numerator = parseFloat(parts[0]) || 0;
var denominator = parseFloat(parts[1]) || 1;
if (denominator === 0) return null;
return (numerator / denominator).toString();
} else {
// Tam sayı inch değeri
var inchNum = parseFloat(inchValue);
if (isNaN(inchNum)) return null;
return inchNum.toString();
}
}
// Diameter mm ve inch'ten DN değerini hesapla
function calculateDnFromDiameter(diameterMm, diameterInch) {
var dnValue = '';
// diameter_inch değerini parse et (örn: "2"", "4"", "1/2"" gibi)
if (diameterInch) {
var inchValue = diameterInch.toString().replace(/"/g, '').trim();
// Kesirli inch değerlerini handle et (örn: "1/2", "3/4")
if (inchValue.indexOf('/') !== -1) {
var parts = inchValue.split('/');
var numerator = parseFloat(parts[0]) || 0;
var denominator = parseFloat(parts[1]) || 1;
var inchDecimal = numerator / denominator;
// Standart inch -> DN mapping
dnValue = calculateDnFromInch(inchDecimal);
} else {
// Tam sayı inch değeri
var inchNum = parseFloat(inchValue) || 0;
if (inchNum > 0) {
dnValue = calculateDnFromInch(inchNum);
} else {
// Eğer parse edilemezse, mm'den hesapla
dnValue = calculateDnFromMm(parseFloat(diameterMm) || 0);
}
}
} else {
// Sadece mm varsa, mm'den hesapla
dnValue = calculateDnFromMm(parseFloat(diameterMm) || 0);
}
return dnValue;
}
// Inch değerinden DN hesapla (standart nominal diameter mapping)
function calculateDnFromInch(inchValue) {
// Standart inch -> DN mapping (nominal diameter)
// DN değeri genellikle inch * 25'e yakındır ama standart değerler kullanılır
var standardDnValues = [15, 20, 25, 32, 40, 50, 65, 80, 100, 125, 150, 200, 250, 300, 350, 400, 450, 500, 600];
// Inch değerinden yaklaşık DN hesapla (DN ≈ inch * 25)
var approximateDn = Math.round(inchValue * 25);
// En yakın standart DN değerini bul
var closestDn = standardDnValues[0];
var minDiff = Math.abs(approximateDn - standardDnValues[0]);
for (var i = 1; i < standardDnValues.length; i++) {
var diff = Math.abs(approximateDn - standardDnValues[i]);
if (diff < minDiff) {
minDiff = diff;
closestDn = standardDnValues[i];
}
}
return closestDn;
}
// MM değerinden DN hesapla (diameter_mm'den yaklaşık DN bul)
function calculateDnFromMm(diameterMmNum) {
if (!diameterMmNum || diameterMmNum === 0) return '';
// Standart DN değerleri ve yaklaşık mm karşılıkları
var standardDnValues = [15, 20, 25, 32, 40, 50, 65, 80, 100, 125, 150, 200, 250, 300, 350, 400, 450, 500, 600];
// MM'den yaklaşık DN hesapla (DN ≈ mm / 25)
var approximateDn = Math.round(diameterMmNum / 25);
// En yakın standart DN değerini bul
var closestDn = standardDnValues[0];
var minDiff = Math.abs(approximateDn - standardDnValues[0]);
for (var i = 1; i < standardDnValues.length; i++) {
var diff = Math.abs(approximateDn - standardDnValues[i]);
if (diff < minDiff) {
minDiff = diff;
closestDn = standardDnValues[i];
}
}
return closestDn;
}
// Pipe için quantity değerini line pipe mm alanlarına yaz
// Tüm pipe satırlarını tarayarak quantity değerlerini line pipe mm alanlarına yaz
function updateLinePipeMmFromQuantity(quantity, row) {
// Tüm pipe satırlarını tarayarak quantity değerlerini topla
updateAllLinePipeMm();
}
// Tüm pipe satırlarını tarayarak line pipe mm değerlerini güncelle
function updateAllLinePipeMm() {
var pipeQuantities = [];
// Tüm pipe satırlarını sırayla tarayarak quantity değerlerini topla
$('.surface-area-row').each(function() {
var row = $(this);
var generalName = (row.find('.general-name').val() || '').toLowerCase();
// Sadece pipe satırlarını işle
if (generalName.indexOf('pipe') !== -1) {
var quantity = parseFloat(row.find('.quantity').val()) || 0;
if (quantity > 0) {
pipeQuantities.push(quantity);
}
}
});
// İlk pipe satırının quantity değeri → Line Pipe 1
if (pipeQuantities.length > 0) {
$('#surfaceAreaLinePipeMm1').val(pipeQuantities[0]);
} else {
$('#surfaceAreaLinePipeMm1').val('');
}
// İkinci pipe satırının quantity değeri → Line Pipe 2
if (pipeQuantities.length > 1) {
$('#surfaceAreaLinePipeMm2').val(pipeQuantities[1]);
} else {
$('#surfaceAreaLinePipeMm2').val('');
}
}
function updateSurfaceAreaSummary() {
var fittingsTotal = 0;
var pipeTotal = 0;
// Tablodaki satırlardan topla
$('.surface-area-row').each(function() {
var total = parseFloat($(this).find('.row-total').val()) || 0;
var generalName = ($(this).find('.general-name').val() || '').toLowerCase();
if (total > 0) {
if (generalName === 'pipe') {
pipeTotal += total;
} else {
fittingsTotal += total;
}
}
});
var grandTotal = fittingsTotal + pipeTotal;
var mtoGrandTotal = grandTotal * 1000000;
surfaceAreaData.fittingsTotal = fittingsTotal;
surfaceAreaData.pipeTotal = pipeTotal;
surfaceAreaData.grandTotal = grandTotal;
surfaceAreaData.mtoGrandTotal = mtoGrandTotal;
$('#fittingsTotalDisplay').text(fittingsTotal.toFixed(2));
$('#pipeTotalDisplay').text(pipeTotal.toFixed(6));
$('#grandTotalDisplay').text(grandTotal.toFixed(6));
$('#mtoGrandTotalDisplay').text(Math.round(mtoGrandTotal).toLocaleString());
}
function getSelectedStandard() {
return $('#standardTabButtons .btn.active').data('standard') || 'GOST';
}
function addSurfaceAreaRow() {
var selectedStandard = getSelectedStandard();
var tbody = $('#surfaceAreaTableBody');
var rowHtml = `
<tr class="surface-area-row">
<td>
<select class="form-control form-control-sm standard-select">
<option value="GOST" ${selectedStandard === 'GOST' ? 'selected' : ''}>GOST</option>
<option value="EN" ${selectedStandard === 'EN' ? 'selected' : ''}>EN/ISO</option>
<option value="ASME" ${selectedStandard === 'ASME' ? 'selected' : ''}>ASME/API</option>
</select>
</td>
<td><input type="text" class="form-control form-control-sm general-name" readonly data-was-pipe="false"></td>
<td>
<select class="form-control form-control-sm element-en-select">
<option value="">{{e2("Select")}}</option>
</select>
</td>
<td>
<select class="form-control form-control-sm element-ru-select">
<option value="">{{e2("Select")}}</option>
</select>
</td>
<td><input type="text" class="form-control form-control-sm mfg-standard" readonly></td>
<td><input type="number" class="form-control form-control-sm quantity" value="1" min="1" step="1"></td>
<td>
<select class="form-control form-control-sm diameter-select">
<option value="">{{e2("Select")}}</option>
</select>
</td>
<td><input type="number" class="form-control form-control-sm cutting-mm" step="0.01" placeholder="mm" disabled></td>
<td><input type="number" class="form-control form-control-sm unit-area" readonly step="0.000001"></td>
<td><input type="number" class="form-control form-control-sm row-total" readonly step="0.000001"></td>
<td>
<button type="button" class="btn btn-danger btn-sm remove-row-btn">
<i class="fa fa-times"></i>
</button>
</td>
</tr>
`;
tbody.append(rowHtml);
var newRow = tbody.find('tr:last');
initSurfaceAreaElementSelect(newRow.find('.element-en-select'));
initSurfaceAreaElementSelect(newRow.find('.element-ru-select'));
initSurfaceAreaDiameterSelect(newRow.find('.diameter-select'));
loadElementEnOptions(newRow.find('.element-en-select'), selectedStandard);
loadElementRuOptions(newRow.find('.element-ru-select'), selectedStandard);
}
function loadElementEnOptions(selectElement, standard) {
$.getJSON('/api/surface-area/elements?standard=' + standard, function(data) {
var options = '<option value="">{{e2("Select")}}</option>';
var addedElements = {}; // Track added elements to avoid duplicates
$.each(data, function(i, item) {
var elementEn = item.element_type_en || '';
var elementRu = item.element_type_ru || '';
// Add only EN options with RU mapping in data attribute
if (elementEn && !addedElements[elementEn]) {
options += '<option value="' + elementEn + '" data-element-ru="' + (elementRu || '') + '">' + elementEn + '</option>';
addedElements[elementEn] = true;
}
});
selectElement.html(options);
if (selectElement.data('select2')) {
selectElement.trigger('change.select2');
}
});
}
function loadElementRuOptions(selectElement, standard) {
$.getJSON('/api/surface-area/elements?standard=' + standard, function(data) {
var options = '<option value="">{{e2("Select")}}</option>';
var addedElements = {}; // Track added elements to avoid duplicates
$.each(data, function(i, item) {
var elementEn = item.element_type_en || '';
var elementRu = item.element_type_ru || '';
// Add only RU options (if exists and different from EN)
if (elementRu && elementRu !== elementEn && !addedElements[elementRu]) {
options += '<option value="' + elementRu + '" data-element-en="' + elementEn + '">' + elementRu + '</option>';
addedElements[elementRu] = true;
}
});
selectElement.html(options);
if (selectElement.data('select2')) {
selectElement.trigger('change.select2');
}
});
}
function loadDiameterOptions(row, standard, elementName) {
var diameterSelect = row.find('.diameter-select');
$.getJSON('/api/surface-area/diameters?standard=' + standard + '&element=' + encodeURIComponent(elementName), function(data) {
var options = '<option value="">{{e2("Select")}}</option>';
$.each(data, function(i, item) {
options += '<option value="' + item.diameter_mm + '" data-area="' + item.surface_area_m2 + '" data-mfg-standard="' + (item.manufacturing_standard || '') + '" data-element-ru="' + (item.element_type_ru || '') + '" data-general-name="' + (item.general_name || '') + '" data-diameter-inch="' + (item.diameter_inch || '') + '">' +
item.diameter_inch + '" (' + item.diameter_mm + 'mm)</option>';
});
diameterSelect.html(options);
initSurfaceAreaDiameterSelect(diameterSelect);
if (diameterSelect.data('select2')) {
diameterSelect.trigger('change.select2');
}
});
}
$(document).ready(function() {
// Standard tab button click
$('#standardTabButtons .btn').on('click', function() {
$('#standardTabButtons .btn').removeClass('active');
$(this).addClass('active');
});
// Add row button
$('#addSurfaceAreaRowBtn').on('click', function() {
addSurfaceAreaRow();
});
// Standard selection change in row
$(document).on('change', '.standard-select', function() {
var row = $(this).closest('tr');
var standard = $(this).val();
row.find('.element-en-select').html('<option value="">{{e2("Select")}}</option>');
row.find('.element-ru-select').html('<option value="">{{e2("Select")}}</option>');
row.find('.diameter-select').html('<option value="">{{e2("Select")}}</option>');
row.find('.general-name').val('');
row.find('.mfg-standard').val('');
row.find('.unit-area').val('');
row.find('.row-total').val('');
initSurfaceAreaElementSelect(row.find('.element-en-select'));
initSurfaceAreaElementSelect(row.find('.element-ru-select'));
initSurfaceAreaDiameterSelect(row.find('.diameter-select'));
loadElementEnOptions(row.find('.element-en-select'), standard);
loadElementRuOptions(row.find('.element-ru-select'), standard);
updateSurfaceAreaSummary();
});
$(document).on('change', '.element-en-select', function() {
var row = $(this).closest('tr');
if (row.data('saSyncing')) return;
var standard = row.find('.standard-select').val();
var selectedOption = $(this).find(':selected');
var elementName = $(this).val();
var wasPipe = (row.find('.general-name').val() || '').toLowerCase().indexOf('pipe') !== -1;
if (elementName) {
// Get the corresponding RU value from data attribute
var elementRu = selectedOption.data('element-ru');
if (elementRu) {
// Set RU select value to show the Russian equivalent
row.data('saSyncing', true);
row.find('.element-ru-select').val(elementRu).trigger('change');
row.data('saSyncing', false);
}
loadDiameterOptions(row, standard, elementName);
} else {
// Clear RU select when EN is cleared
row.data('saSyncing', true);
row.find('.element-ru-select').val('').trigger('change');
row.data('saSyncing', false);
row.find('.diameter-select').html('<option value="">{{e2("Select")}}</option>');
row.find('.general-name').val('').data('was-pipe', false);
row.find('.mfg-standard').val('');
row.find('.unit-area').val('');
row.find('.row-total').val('');
// Eğer pipe satırıydı ve element seçimi kaldırıldıysa, DN değerlerini güncelle
if (wasPipe) {
updateAllPipeDimensions();
updateAllLinePipeMm();
}
}
});
$(document).on('change', '.element-ru-select', function() {
var row = $(this).closest('tr');
if (row.data('saSyncing')) return;
var standard = row.find('.standard-select').val();
var selectedOption = $(this).find(':selected');
var elementRu = $(this).val();
var wasPipe = (row.find('.general-name').val() || '').toLowerCase().indexOf('pipe') !== -1;
if (elementRu) {
// Get the corresponding EN value from data attribute
var elementEn = selectedOption.data('element-en');
if (elementEn) {
// Set EN select value to show the English equivalent
row.data('saSyncing', true);
row.find('.element-en-select').val(elementEn).trigger('change');
row.data('saSyncing', false);
// Load diameters using EN value
loadDiameterOptions(row, standard, elementEn);
} else {
// If no EN mapping, try with RU value
loadDiameterOptions(row, standard, elementRu);
}
} else {
// Clear EN select when RU is cleared
row.data('saSyncing', true);
row.find('.element-en-select').val('').trigger('change');
row.data('saSyncing', false);
row.find('.diameter-select').html('<option value="">{{e2("Select")}}</option>');
row.find('.general-name').val('').data('was-pipe', false);
row.find('.mfg-standard').val('');
row.find('.unit-area').val('');
row.find('.row-total').val('');
// Eğer pipe satırıydı ve element seçimi kaldırıldıysa, DN değerlerini güncelle
if (wasPipe) {
updateAllPipeDimensions();
updateAllLinePipeMm();
}
}
});
$(document).on('change', '.diameter-select', function() {
var row = $(this).closest('tr');
var selected = $(this).find(':selected');
var unitAreaAttr = selected.data('area');
var hasPresetArea = (typeof unitAreaAttr !== 'undefined' && unitAreaAttr !== null && unitAreaAttr !== '');
var unitArea = hasPresetArea ? unitAreaAttr : '';
var mfgStandard = selected.data('mfg-standard') || '';
var generalName = selected.data('general-name') || '';
var elementRu = selected.data('element-ru') || '';
var diameterMm = $(this).val() || '';
var diameterInch = selected.data('diameter-inch') || '';
var wasPipe = (row.find('.general-name').data('was-pipe') === true || (row.find('.general-name').val() || '').toLowerCase().indexOf('pipe') !== -1);
// General name'i her durumda set et
row.find('.general-name').val(generalName);
row.find('.mfg-standard').val(mfgStandard);
if (hasPresetArea) {
row.find('.unit-area').prop('readonly', true).val(unitArea);
} else {
// Custom diameter entered via tags -> allow manual unit area entry
row.find('.unit-area').prop('readonly', false);
if (!row.find('.unit-area').val()) {
row.find('.unit-area').val('');
}
}
// Pipe seçildiğinde cutting alanını aktif et ve dimensions'ı otomatik doldur
var isPipe = generalName.toLowerCase().indexOf('pipe') !== -1;
if (isPipe) {
row.find('.general-name').data('was-pipe', true);
row.find('.cutting-mm').prop('disabled', false);
// Pipe için quantity alanını mm uzunluk olarak işaretle
var quantityInput = row.find('.quantity');
quantityInput.attr('data-is-pipe-length', 'true');
quantityInput.attr('placeholder', '{{e2("Length (mm)")}}');
// Diameter mm ve inch'ten DN değerini hesapla/eşleştir
if (diameterMm && diameterInch) {
updatePipeDimensions(diameterMm, diameterInch, row);
} else {
// Diameter seçimi kaldırıldıysa veya boşsa, DN değerlerini güncelle
updateAllPipeDimensions();
}
// Pipe için quantity varsa line pipe mm'yi güncelle
updateAllLinePipeMm();
} else {
// Pipe değilse veya pipe'dan başka bir şeye değiştirildiyse
if (wasPipe) {
// Eğer önceden pipe idi ve şimdi değilse, DN değerlerini güncelle
updateAllPipeDimensions();
updateAllLinePipeMm();
}
row.find('.general-name').data('was-pipe', false);
row.find('.cutting-mm').prop('disabled', true).val('');
var quantityInput = row.find('.quantity');
quantityInput.removeAttr('data-is-pipe-length');
quantityInput.attr('placeholder', '');
}
// Update RU select if API returned RU value and it's not already set
if (elementRu && !row.find('.element-ru-select').val()) {
row.find('.element-ru-select').val(elementRu);
}
calculateRowTotal(row);
});
$(document).on('change keyup', '.unit-area', function() {
var row = $(this).closest('tr');
calculateRowTotal(row);
});
$(document).on('change keyup', '.quantity', function() {
var row = $(this).closest('tr');
var quantity = parseFloat($(this).val()) || 0;
var isPipeLength = $(this).attr('data-is-pipe-length') === 'true';
// Pipe için quantity değeri line pipe mm'ye yazılmalı
if (isPipeLength) {
updateAllLinePipeMm();
}
calculateRowTotal(row);
});
$(document).on('click', '.remove-row-btn', function() {
var row = $(this).closest('tr');
var generalName = (row.find('.general-name').val() || '').toLowerCase();
$(this).closest('tr').remove();
// Eğer pipe satırı silindiyse, DN ve line pipe mm değerlerini güncelle
if (generalName.indexOf('pipe') !== -1) {
updateAllPipeDimensions();
updateAllLinePipeMm();
}
updateSurfaceAreaSummary();
});
$('#saveSurfaceAreaBtn').on('click', function() {
if (!currentRowId) {
Swal.fire('{{e2("Warning")}}', '{{e2("No row selected")}}', 'warning');
return;
}
var itemsData = [];
$('.surface-area-row').each(function() {
var row = $(this);
itemsData.push({
standard: row.find('.standard-select').val(),
element_en: row.find('.element-en-select').val(),
element_ru: row.find('.element-ru-select').val(),
mfg_standard: row.find('.mfg-standard').val(),
general_name: row.find('.general-name').val(),
diameter: row.find('.diameter-select').val(),
quantity: row.find('.quantity').val(),
cutting_mm: row.find('.cutting-mm').val() || 0,
unit_area: row.find('.unit-area').val(),
total: row.find('.row-total').val()
});
});
var btn = $(this);
btn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> {{e2("Saving...")}}');
// Pipe satırlarından cutting toplamını hesapla
var totalCuttingMm = 0;
itemsData.forEach(function(item) {
var generalName = (item.general_name || '').toLowerCase();
var cuttingVal = parseFloat(item.cutting_mm) || 0;
console.log('Item general_name:', item.general_name, 'cutting_mm:', item.cutting_mm, 'parsed:', cuttingVal);
// Pipe veya pipe içeren tüm değerleri kabul et
if (generalName.indexOf('pipe') !== -1) {
totalCuttingMm += cuttingVal;
}
});
console.log('Total Cutting MM:', totalCuttingMm);
// Get pipe dimensions from modal inputs
var dn1 = $('#surfaceAreaDn1').val() || '';
var dn2 = $('#surfaceAreaDn2').val() || '';
var linePipeMm1 = parseFloat($('#surfaceAreaLinePipeMm1').val()) || 0;
var linePipeMm2 = parseFloat($('#surfaceAreaLinePipeMm2').val()) || 0;
// Calculate total_line_mm as sum of line_pipe_mm_1 and line_pipe_mm_2
var totalLineMm = linePipeMm1 + linePipeMm2;
$.post('/api/surface-area/save-calculation', {
'_token': '{{csrf_token()}}',
'construction_paint_log_id': currentRowId,
'fittings_total': surfaceAreaData.fittingsTotal,
'pipe_total': surfaceAreaData.pipeTotal,
'grand_total': surfaceAreaData.grandTotal,
'cutting_mm': totalCuttingMm,
'items': JSON.stringify(itemsData),
'dn_1': dn1,
'dn_2': dn2,
'line_pipe_mm_1': linePipeMm1,
'line_pipe_mm_2': linePipeMm2,
'total_line_mm': totalLineMm
}, function(response) {
// Also update DataGrid visually
var dataGrid = $('#dataGrid').dxDataGrid('instance');
if (currentRowIndex !== null) {
// Calculate fitting quantities and areas from items
var elbowPcs = 0;
var elbow45Pcs = 0;
var elbowM2 = 0;
var teePcs = 0;
var teeM2 = 0;
var reductionsPcs = 0;
var reductionsM2 = 0;
var flangePcs = 0;
var flangeM2 = 0;
var ventPcs = 0;
var ventM2 = 0;
var capPcs = 0;
var capM2 = 0;
itemsData.forEach(function(item) {
var elementEn = (item.element_en || '').trim();
var elementRu = (item.element_ru || '').trim();
var quantity = parseInt(item.quantity) || 0;
var total = parseFloat(item.total) || 0;
var elementName = (elementEn || elementRu).toLowerCase();
// Elbow 90° 1.5D
if (elementName.indexOf('elbow') !== -1 &&
(elementName.indexOf('90') !== -1 || elementEn.indexOf('90°') !== -1)) {
elbowPcs += quantity;
elbowM2 += total;
}
// Elbow 45° 1.5D
else if (elementName.indexOf('elbow') !== -1 &&
(elementName.indexOf('45') !== -1 || elementEn.indexOf('45°') !== -1)) {
elbow45Pcs += quantity;
elbowM2 += total;
}
// Reductions (Concentric, Eccentric, any reducer)
else if (elementName.indexOf('reducer') !== -1 ||
elementName.indexOf('reduction') !== -1) {
reductionsPcs += quantity;
reductionsM2 += total;
}
// Slip On Flange (Class 150)
else if (elementName.indexOf('slip on flange') !== -1 ||
(elementName.indexOf('slip') !== -1 && elementName.indexOf('flange') !== -1)) {
flangePcs += quantity;
flangeM2 += total;
}
// Weldneck Flange (Class 150)
else if (elementName.indexOf('weldneck flange') !== -1 ||
(elementName.indexOf('weldneck') !== -1 && elementName.indexOf('flange') !== -1)) {
flangePcs += quantity;
flangeM2 += total;
}
// Tee (Equal Tee, Reducing Tee, Cross Tee - all types)
else if (elementName.indexOf('tee') !== -1 ||
elementName.indexOf('cross') !== -1) {
teePcs += quantity;
teeM2 += total;
}
// Nipple/Olet (replaces Vent)
else if (elementName.indexOf('nipple') !== -1 ||
elementName.indexOf('olet') !== -1 ||
elementName.indexOf('nipel') !== -1 ||
elementName.indexOf('nippel') !== -1) {
ventPcs += quantity;
ventM2 += total;
}
// Cap
else if (elementName.indexOf('cap') !== -1) {
capPcs += quantity;
capM2 += total;
}
});
// Update DataGrid cells
dataGrid.cellValue(currentRowIndex, 'fittings_m2', surfaceAreaData.fittingsTotal.toFixed(2));
dataGrid.cellValue(currentRowIndex, 'pipe_m2', surfaceAreaData.pipeTotal.toFixed(2));
dataGrid.cellValue(currentRowIndex, 'total_m2', surfaceAreaData.grandTotal.toFixed(2));
dataGrid.cellValue(currentRowIndex, 'elbow_pcs', elbowPcs);
dataGrid.cellValue(currentRowIndex, 'elbow_45_pcs', elbow45Pcs);
dataGrid.cellValue(currentRowIndex, 'elbow_m2', elbowM2.toFixed(2));
dataGrid.cellValue(currentRowIndex, 'tee_pcs', teePcs);
dataGrid.cellValue(currentRowIndex, 'tee_m2', teeM2.toFixed(2));
dataGrid.cellValue(currentRowIndex, 'reductions_pcs', reductionsPcs);
dataGrid.cellValue(currentRowIndex, 'reductions_m2', reductionsM2.toFixed(2));
dataGrid.cellValue(currentRowIndex, 'flange_pcs', flangePcs);
dataGrid.cellValue(currentRowIndex, 'flange_m2', flangeM2.toFixed(2));
dataGrid.cellValue(currentRowIndex, 'vent_pcs', ventPcs);
dataGrid.cellValue(currentRowIndex, 'vent_m2', ventM2.toFixed(2));
dataGrid.cellValue(currentRowIndex, 'cap_pcs', capPcs);
dataGrid.cellValue(currentRowIndex, 'cap_m2', capM2.toFixed(2));
// Pipe dimensions değerlerini de güncelle
dataGrid.cellValue(currentRowIndex, 'cutting_mm', totalCuttingMm);
if (dn1 !== '') {
dataGrid.cellValue(currentRowIndex, 'dn_1', dn1);
}
if (dn2 !== '') {
dataGrid.cellValue(currentRowIndex, 'dn_2', dn2);
}
if (linePipeMm1 !== 0) {
dataGrid.cellValue(currentRowIndex, 'line_pipe_mm_1', linePipeMm1);
}
if (linePipeMm2 !== 0) {
dataGrid.cellValue(currentRowIndex, 'line_pipe_mm_2', linePipeMm2);
}
// Update total_line_mm as sum of line_pipe_mm_1 and line_pipe_mm_2
if (totalLineMm > 0) {
dataGrid.cellValue(currentRowIndex, 'total_line_mm', totalLineMm.toFixed(2));
}
dataGrid.saveEditData();
// Automatically show fittings columns after calculation
if (typeof window.toggleFittingsVisibility === 'function') {
window.toggleFittingsVisibility(true);
}
}
Swal.fire('{{e2("Success")}}', '{{e2("Surface area saved successfully")}}', 'success');
// Clear draft after successful save
if (currentRowId && surfaceAreaDrafts[currentRowId]) {
delete surfaceAreaDrafts[currentRowId];
}
$('#surfaceAreaModal').modal('hide');
}).fail(function(error) {
console.error('Save error:', error);
Swal.fire('{{e2("Error")}}', '{{e2("Failed to save data")}}', 'error');
}).always(function() {
btn.prop('disabled', false).html('<i class="fa fa-save"></i> {{e2("Save")}}');
});
});
// Save draft when modal is closed
$('#surfaceAreaModal').on('hide.bs.modal', function () {
if (currentRowId) {
// Gather current data
var itemsData = [];
$('.surface-area-row').each(function() {
var row = $(this);
itemsData.push({
standard: row.find('.standard-select').val(),
element_en: row.find('.element-en-select').val(),
element_ru: row.find('.element-ru-select').val(),
mfg_standard: row.find('.mfg-standard').val(),
general_name: row.find('.general-name').val(),
diameter: row.find('.diameter-select').val(),
quantity: row.find('.quantity').val(),
cutting_mm: row.find('.cutting-mm').val(),
unit_area: row.find('.unit-area').val(),
total: row.find('.row-total').val()
});
});
var draft = {
dn1: $('#surfaceAreaDn1').val(),
dn2: $('#surfaceAreaDn2').val(),
linePipeMm1: $('#surfaceAreaLinePipeMm1').val(),
linePipeMm2: $('#surfaceAreaLinePipeMm2').val(),
items: itemsData
};
surfaceAreaDrafts[currentRowId] = draft;
console.log('Draft saved for row', currentRowId);
}
});
});
</script>
<style>
#surfaceAreaModal .nav-tabs .nav-link.active {
font-weight: bold;
border-bottom: 3px solid #007bff;
}
#surfaceAreaModal .card-header {
font-weight: bold;
}
.surface-area-row input[readonly] {
background-color: #f8f9fa;
}
</style>