let costChart = null; let products = []; let currentProductIndex = 1; // مقادیر پیش‌فرض const defaultValues = { dollar: [ { id: 'dollar-rate', value: '810,000' }, { id: 'official-rate', value: '693,160' }, { id: 'container-20-cost', value: '2,500' }, { id: 'container-40-cost', value: '4,500' }, { id: 'ltc-sea-cost-per-cbm', value: '200' }, { id: 'customs-rate', value: '5' }, { id: 'ltc-air-cost-per-kg', value: '7' } ], yuan: [ { id: 'yuan-rate', value: '111,500' }, { id: 'official-rate', value: '94,805' }, { id: 'container-20-cost', value: '18175.00' }, { id: 'container-40-cost', value: '32715.00' }, { id: 'ltc-sea-cost-per-cbm', value: '1454.00' }, { id: 'ltc-air-cost-per-kg', value: '50.89' } ], euro: [ { id: 'euro-rate', value: '928,000' }, { id: 'official-rate', value: '794,830' }, { id: 'container-20-cost', value: '2150.00' }, { id: 'container-40-cost', value: '3870.00' }, { id: 'ltc-sea-cost-per-cbm', value: '172.00' }, { id: 'ltc-air-cost-per-kg', value: '6.02' } ], aed: [ { id: 'aed-rate', value: '222,000' }, { id: 'official-rate', value: '188,750' }, { id: 'container-20-cost', value: '9175.00' }, { id: 'container-40-cost', value: '16515.00' }, { id: 'ltc-sea-cost-per-cbm', value: '734.00' }, { id: 'ltc-air-cost-per-kg', value: '25.69' } ], standardCost: 150000000, bankingCost: { low: 100000000, mid: 150000000, high: 200000000 }, shippingClearanceCost: { container: 300000000, ltc: 150000000 }, agentFeeCost: { low: 120000000, mid: 150000000, high: 200000000 }, miscellaneousCostFactor: 5000, orderRegistrationMin: 100 }; function initializeChart() { const ctx = document.getElementById('cost-chart')?.getContext('2d'); if (!ctx) { console.error('Canvas element not found'); return; } costChart = new Chart(ctx, { type: 'pie', data: { labels: [ 'ارزش فوب', 'هزینه حمل', 'حقوق ورودی', 'مالیات ارزش افزوده', 'مالیات علی‌الحساب', 'عوارض هلال احمر', 'هزینه انبارداری', 'هزینه استاندارد', 'هزینه مجوزهای سازمانی', 'هزینه ثبت سفارش', 'هزینه بانکی', 'هزینه ترخیصیه کشتیرانی', 'هزینه کارت بازرگانی', 'کارمزد کارگزار گمرکی', 'هزینه حمل داخل ایران', 'هزینه‌های متفرقه' ], datasets: [{ data: Array(16).fill(0), backgroundColor: [ '#007bff', '#28a745', '#dc3545', '#ffc107', '#6c757d', '#17a2b8', '#fd7e14', '#6610f2', '#e83e8c', '#20c997', '#343a40', '#007bff80', '#28a74580', '#dc354580', '#ffc10780', '#6c757d80' ], }] }, options: { responsive: true, plugins: { datalabels: { color: '#fff', formatter: (value, context) => { const total = context.chart.data.datasets[0].data.reduce((sum, val) => sum + val, 0); const percentage = total ? ((value / total) * 100).toFixed(1) : 0; return value && percentage ? `${percentage}%` : ''; }, font: { size: 12 }, display: (context) => context.dataset.data[context.dataIndex] > 0 } } }, plugins: [ChartDataLabels] }); } function updateChart() { if (!costChart) return; const currencyType = document.getElementById('currency-type-main').value; const defaults = defaultValues[currencyType] || defaultValues.dollar; const officialRate = parseNumber(document.getElementById('official-rate').value) || parseNumber(defaults.find(d => d.id === 'official-rate').value); const costs = [ parseNumber(document.getElementById('product-price-rial').value) || 0, parseNumber(document.getElementById('shipping-cost-rial').value) || 0, parseNumber(document.getElementById('customs-duty-rial').value) || 0, parseNumber(document.getElementById('vat-amount').value) || 0, parseNumber(document.getElementById('prepayment-tax').value) || 0, parseNumber(document.getElementById('red-crescent-fee').value) || 0, parseNumber(document.getElementById('storage-fee').value) || 0, document.getElementById('standard-required-yes')?.checked ? parseNumber(document.getElementById('standard-cost').value) || defaultValues.standardCost : 0, parseNumber(document.getElementById('org-permits-cost').value) || 0, parseNumber(document.getElementById('order-registration-cost').value) || 0, parseNumber(document.getElementById('banking-cost').value) || 0, parseNumber(document.getElementById('shipping-clearance-cost').value) || 0, document.getElementById('commerce-card-cost').value || 0, parseNumber(document.getElementById('agent-fee-cost').value) || 0, parseNumber(document.getElementById('inland-shipping-cost').value) || 0, parseNumber(document.getElementById('miscellaneous-cost').value) || 0 ]; costChart.data.datasets[0].data = costs; costChart.update(); updateTotalCost(); } function parseNumber(value) { return parseFloat(value?.toString().replace(/,/g, '')) || 0; } function formatNumber(value) { return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); } function formatInputNumber(inputId) { const input = document.getElementById(inputId); if (!input) return; input.value = formatNumber(input.value.replace(/,/g, '')) || ''; if (inputId.includes('yuan') || inputId.includes('dollar') || inputId.includes('euro') || inputId.includes('aed')) { updateFobPrice(); } else if (inputId.includes('modal-site-price') || inputId.includes('modal-quantity')) { updateChinaProduct(); } else if (inputId.includes('container')) { updateContainerShippingCost(); } else if (inputId.includes('ltc-sea')) { updateLtcSeaCost(); } else if (inputId.includes('ltc-air')) { updateLtcAirCost(); } else if (inputId.includes('customs') || inputId.includes('official-rate')) { updateCustomsCost(); } else if (inputId.includes('standard') || inputId.includes('org-permits')) { updatePermitsCost(); } else if (inputId.includes('order-registration') || inputId.includes('banking') || inputId.includes('shipping-clearance') || inputId.includes('commerce-card') || inputId.includes('agent-fee') || inputId.includes('inland-shipping') || inputId.includes('miscellaneous')) { updateOtherCosts(); } updateChart(); } function openModal(modalId) { const modal = document.getElementById(modalId); if (!modal) return; modal.classList.add('active'); if (modalId === 'product-price-modal') { setDefaultValuesForFobModal(); toggleFobModalFields(); updateFobPrice(); resetChinaInquiry(); } else if (modalId === 'container-shipping-cost-modal') { setDefaultValuesForContainerModal(); updateContainerShippingCost(); } else if (modalId === 'less-than-container-modal') { setDefaultValuesForLtcModal(); updateLtcCost(); } else if (modalId === 'customs-cost-modal') { setDefaultValuesForCustomsModal(); updateCustomsCost(); } else if (modalId === 'permits-cost-modal') { setDefaultValuesForPermitsModal(); updatePermitsCost(); } else if (modalId === 'other-costs-modal') { setDefaultValuesForOtherCostsModal(); updateOtherCosts(); } } function closeModal(modalId) { const modal = document.getElementById(modalId); if (!modal) return; modal.classList.remove('active'); } function setDefaultValuesForFobModal() { const currencyType = document.getElementById('currency-type-main').value; const defaults = defaultValues[currencyType] || defaultValues.dollar; defaults.forEach(({ id, value }) => { const input = document.getElementById(id); if (input && !input.value) { input.value = formatNumber(value); } }); updateFobPrice(); } function toggleFobModalFields() { const fobType = document.querySelector('input[name="fob-type"]:checked')?.value; if (!fobType) return; document.getElementById('fob-dollar-field').style.display = fobType === 'fob-dollar' ? 'block' : 'none'; document.getElementById('china-inquiry-field').style.display = fobType === 'china-inquiry' ? 'block' : 'none'; if (fobType === 'china-inquiry') { resetChinaInquiry(); } else { updateFobPrice(); } } function setDefaultValuesForContainerModal() { const currencyType = document.getElementById('currency-type-main').value; const defaults = defaultValues[currencyType] || defaultValues.dollar; defaults.forEach(({ id, value }) => { if (id.includes('container') && !document.getElementById(id).value) { document.getElementById(id).value = formatNumber(value); } }); updateContainerShippingCost(); } function setDefaultValuesForLtcModal() { const currencyType = document.getElementById('currency-type-main').value; const defaults = defaultValues[currencyType] || defaultValues.dollar; defaults.forEach(({ id, value }) => { if ((id.includes('ltc-sea') || id.includes('ltc-air')) && !document.getElementById(id).value) { document.getElementById(id).value = formatNumber(value); } }); updateLtcCost(); } function setDefaultValuesForCustomsModal() { const currencyType = document.getElementById('currency-type-main').value; const defaults = defaultValues[currencyType] || defaultValues.dollar; defaults.forEach(({ id, value }) => { if (id.includes('official-rate') || id.includes('customs-rate')) { if (!document.getElementById(id).value) { document.getElementById(id).value = formatNumber(value); } } }); updateCustomsCost(); } function setDefaultValuesForPermitsModal() { if (document.getElementById('standard-required-yes')?.checked && !document.getElementById('standard-cost').value) { document.getElementById('standard-cost').value = formatNumber(defaultValues.standardCost.toString()); } updatePermitsCost(); } function setDefaultValuesForOtherCostsModal() { const cifDollar = parseNumber(document.getElementById('product-price-rial-modal').value); if (!document.getElementById('order-registration-cost').value) { const orderRegistrationCost = Math.max( defaultValues.orderRegistrationMin * parseNumber(defaultValues.euro.find(d => d.id === 'official-rate').value), (cifDollar * parseNumber(defaultValues.dollar.find(d => d.id === 'official-rate').value)) / 2000 ); document.getElementById('order-registration-cost').value = formatNumber(orderRegistrationCost.toFixed(0)); } if (!document.getElementById('banking-cost').value) { let bankingCost = cifDollar <= 10000 ? defaultValues.bankingCost.low : cifDollar <= 20000 ? defaultValues.bankingCost.mid : defaultValues.bankingCost.high; document.getElementById('banking-cost').value = formatNumber(bankingCost.toFixed(0)); } if (!document.getElementById('shipping-clearance-cost').value) { const container20 = parseNumber(document.getElementById('container-20-foot').value); const container40 = parseNumber(document.getElementById('container-40-foot').value); const shippingClearanceCost = (container20 + container40) ? (container20 + container40) * defaultValues.shippingClearanceCost.container : defaultValues.shippingClearanceCost.ltc; document.getElementById('shipping-clearance-cost').value = formatNumber(shippingClearanceCost.toFixed(0)); } if (!document.getElementById('agent-fee-cost').value) { let agentFeeCost = cifDollar <= 10000 ? defaultValues.agentFeeCost.low : cifDollar <= 20000 ? defaultValues.agentFeeCost.mid : defaultValues.bankingCost.high; document.getElementById('agent-fee-cost').value = formatNumber(agentFeeCost.toFixed(0)); } if (!document.getElementById('miscellaneous-cost').value) { const miscellaneousCost = cifDollar * defaultValues.miscellaneousCostFactor; document.getElementById('miscellaneous-cost').value = formatNumber(miscellaneousCost.toFixed(0)); } updateOtherCosts(); } function toggleFormFields() { const currencyType = document.getElementById('currency-type-main').value; document.getElementById('yuan-field').style.display = currencyType === 'yuan' ? 'block' : 'none'; document.getElementById('dollar-field').style.display = currencyType === 'dollar' ? 'block' : 'none'; document.getElementById('euro-field').style.display = currencyType === 'euro' ? 'block' : 'none'; document.getElementById('aed-field').style.display = currencyType === 'aed' ? 'block' : 'none'; updateFobPrice(); } function updateTransportLabels() { const currencyType = document.getElementById('currency-type-main').value; const currencyLabels = { dollar: 'دلار', yuan: 'یوآن', euro: 'یورو', aed: 'درهم' }; const currencyLabel = currencyLabels[currencyType] || 'دلار'; document.getElementById('container-20-cost-label').textContent = `هزینه هر کانتینر (${currencyLabel}):`; document.getElementById('container-40-cost-label').textContent = `هزینه هر کانتینر (${currencyLabel}):`; document.getElementById('ltc-sea-cost-per-cbm-label').textContent = `هزینه حمل یک مترمکعب (${currencyLabel}):`; document.getElementById('ltc-sea-shipping-cost-label').textContent = `هزینه حمل (${currencyLabel}):`; document.getElementById('ltc-air-cost-per-kg-label').textContent = `هزینه حمل یک کیلوگرم (${currencyLabel}):`; document.getElementById('ltc-air-shipping-cost-label').textContent = `هزینه حمل (${currencyLabel}):`; } function updateDynamicTitle() { const productName = document.getElementById('product-name').value.trim() || document.getElementById('modal-product-nameFa')?.value.trim() || products[0]?.nameEn || 'کالای'; const currencyType = document.getElementById('currency-type-main').value; const currencyLabels = { dollar: 'دلار', yuan: 'یوآن', euro: 'یورو', aed: 'درهم' }; const currencyLabel = currencyLabels[currencyType] || 'دلار'; let fobValue = 0; if (currencyType === 'yuan') { fobValue = parseNumber(document.getElementById('yuan-to-rial').value); } else if (currencyType === 'dollar') { fobValue = parseNumber(document.getElementById('dollar-to-rial').value); } else if (currencyType === 'euro') { fobValue = parseNumber(document.getElementById('euro-to-rial').value); } else if (currencyType === 'aed') { fobValue = parseNumber(document.getElementById('aed-to-rial').value); } const title = fobValue ? `قیمت تمام شده ${productName} وارداتی از چین به ارزش ${formatNumber(fobValue.toFixed(2))} ${currencyLabel}` : `قیمت تمام شده ${productName} وارداتی از چین`; document.getElementById('dynamic-title').textContent = title; } function updateFobPrice() { const currencyType = document.getElementById('currency-type-main').value; const fobType = document.querySelector('input[name="fob-type"]:checked')?.value; let amount = 0; let rate = 0; const defaults = defaultValues[currencyType] || defaultValues.dollar; if (currencyType === 'yuan') { amount = parseNumber(document.getElementById('yuan-to-rial').value); rate = parseNumber(document.getElementById('yuan-rate').value) || parseNumber(defaults.find(d => d.id === 'yuan-rate').value); } else if (currencyType === 'dollar') { amount = fobType === 'china-inquiry' ? parseNumber(document.getElementById('modal-total-price').value) : parseNumber(document.getElementById('dollar-to-rial').value); rate = parseNumber(document.getElementById('dollar-rate').value) || parseNumber(defaults.find(d => d.id === 'dollar-rate').value); } else if (currencyType === 'euro') { amount = parseNumber(document.getElementById('euro-to-rial').value); rate = parseNumber(document.getElementById('euro-rate').value) || parseNumber(defaults.find(d => d.id === 'euro-rate').value); } else if (currencyType === 'aed') { amount = parseNumber(document.getElementById('aed-to-rial').value); rate = parseNumber(document.getElementById('aed-rate').value) || parseNumber(defaults.find(d => d.id === 'aed-rate').value); } const fobPrice = amount * rate; document.getElementById('fob-price').value = formatNumber(fobPrice.toFixed(0)); document.getElementById('product-price-rial').value = formatNumber(fobPrice.toFixed(0)); // خالی کردن فیلد نام کالا (انگلیسی) و تغییر placeholder if (fobType === 'china-inquiry' && amount > 0) { const nameEnInput = document.getElementById('modal-product-name-en'); if (nameEnInput && products.length < 10) { nameEnInput.value = ''; nameEnInput.placeholder = `نام کالای ${products.length + 1}`; updateChinaModal(); } } updateDynamicTitle(); updateChart(); } function updateChinaModal() { const productNameFa = document.getElementById('modal-product-name-fa')?.value.trim(); const productNameEn = document.getElementById('modal-product-name-en')?.value.trim(); const googleTranslateEnLink = document.getElementById('google-translate-en-link'); const alibabaLink = document.getElementById('alibaba-search-link'); if (!googleTranslateEnLink || !alibabaLink) return; googleTranslateEnLink.style.display = 'none'; alibabaLink.style.display = 'none'; if (productNameFa) { googleTranslateEnLink.textContent = `معادل انگلیسی کلمه ${productNameFa}`; googleTranslateEnLink.href = `https://translate.google.com/?sl=fa&tl=en&text=${encodeURIComponent(productNameFa)}&op=translate`; googleTranslateEnLink.style.display = 'block'; } // فعال‌سازی لینک Alibaba فقط وقتی نام کالا (انگلیسی) وارد شده if (productNameEn) { alibabaLink.textContent = `استعلام قیمت ${productNameEn} از Alibaba`; alibabaLink.href = `https://www.alibaba.com/trade/search?keywords=${encodeURIComponent(productNameEn)}`; alibabaLink.style.display = 'block'; document.getElementById('modal-site-price-label').textContent = `قیمت ${productNameEn} از سایت (دلار):`; document.getElementById('modal-quantity-label').textContent = `تعداد ${productNameEn} موردنیاز:`; } else { alibabaLink.style.display = 'none'; document.getElementById('modal-site-price-label').textContent = `قیمت کالا از سایت (دلار):`; document.getElementById('modal-quantity-label').textContent = `تعداد موردنیاز:`; } document.getElementById('product-name').value = productNameFa || productNameEn || products[0]?.nameFa || products[0]?.nameEn || ''; updateDynamicTitle(); } function updateChinaProduct() { const productNameEn = document.getElementById('modal-product-name-en')?.value.trim(); const productNameFa = document.getElementById('modal-product-name-fa')?.value.trim(); const sitePriceInput = document.getElementById('modal-site-price'); const quantityInput = document.getElementById('modal-quantity'); if (!sitePriceInput || !quantityInput || !productNameEn) return; let sitePrice = parseNumber(sitePriceInput.value); let quantity = parseNumber(quantityInput.value); // فقط وقتی هر دو فیلد پر باشن محصول اضافه می‌شه if (sitePrice && quantity && productNameEn && products.length < 10) { const totalPrice = sitePrice * quantity; products.push({ id: Date.now() + Math.random(), nameEn: productNameEn, nameFa: productNameFa || '', unitPrice: sitePrice, quantity: quantity, totalPrice: totalPrice }); renderProductList(); // خالی کردن تمام فیلدها برای کالای بعدی sitePriceInput.value = ''; quantityInput.value = ''; document.getElementById('modal-product-name-en').value = ''; document.getElementById('modal-product-name-fa').value = ''; document.getElementById('modal-product-name-en').placeholder = `نام کالای ${products.length + 1}`; updateChinaModal(); updateChinaTotalPrice(); } } function resetChinaInquiry() { if (products.length < 10) { document.getElementById('modal-product-name-en').value = ''; document.getElementById('modal-product-name-fa').value = ''; document.getElementById('modal-site-price').value = ''; document.getElementById('modal-quantity').value = ''; document.getElementById('modal-product-name-en').placeholder = `نام کالای ${products.length + 1}`; document.getElementById('modal-product-name-en').disabled = false; document.getElementById('modal-product-name-fa').disabled = false; document.getElementById('modal-site-price').disabled = false; document.getElementById('modal-quantity').disabled = false; updateChinaModal(); } else { document.getElementById('modal-product-name-en').disabled = true; document.getElementById('modal-product-name-fa').disabled = true; document.getElementById('modal-site-price').disabled = true; document.getElementById('modal-quantity').disabled = true; } currentProductIndex = products.length + 1; } function renderProductList() { const productList = document.getElementById('product-list'); if (!productList) { console.error('Product list element not found'); return; } productList.innerHTML = ` ${products.map((product, index) => ` `).join('')}
ردیف نام کالا قیمت واحد (دلار) تعداد قیمت کل (دلار) عملیات
${index + 1} ${product.nameEn} ${formatNumber(product.unitPrice.toFixed(2))} ${formatNumber(product.quantity.toFixed(0))} ${formatNumber((product.unitPrice * product.quantity).toFixed(2))}
`; updateChinaTotalPrice(); } function editProduct(id) { const product = products.find(p => p.id === id); if (!product) return; // پر کردن فیلدها const nameEnInput = document.getElementById('modal-product-name-en'); const nameFaInput = document.getElementById('modal-product-name-fa'); const sitePriceInput = document.getElementById('modal-site-price'); const quantityInput = document.getElementById('modal-quantity'); if (nameEnInput && nameFaInput && sitePriceInput && quantityInput) { nameEnInput.value = product.nameEn; nameFaInput.value = product.nameFa; sitePriceInput.value = formatNumber(product.unitPrice.toFixed(2)); quantityInput.value = formatNumber(product.quantity.toFixed(0)); } // حذف محصول برای ویرایش products = products.filter(p => p.id !== id); renderProductList(); updateChinaModal(); } function deleteProduct(id) { products = products.filter(p => p.id !== id); renderProductList(); resetChinaInquiry(); } function updateChinaTotalPrice() { const totalPrice = products.reduce((sum, product) => sum + (product.unitPrice * product.quantity), 0); const totalPriceInput = document.getElementById('modal-total-price'); if (totalPriceInput) { totalPriceInput.value = formatNumber(totalPrice.toFixed(2)); } if (document.querySelector('input[name="fob-type"]:checked')?.value === 'china-inquiry') { const dollarInput = document.getElementById('dollar-to-rial'); if (dollarInput) { dollarInput.value = formatNumber(totalPrice.toFixed(2)); } document.getElementById('product-name').value = products[0]?.nameFa || products[0]?.nameEn || ''; updateFobPrice(); updateDynamicTitle(); updateChart(); } } function showSellerBuyerInfo() { const sellerBuyerInfo = document.getElementById('seller-buyer-info'); if (sellerBuyerInfo) { sellerBuyerInfo.classList.add('active'); } } function printProformaInvoice(includeInfo) { if (!window.jspdf) { console.error('jsPDF not loaded'); alert('کتابخانه jsPDF لود نشده است. لطفاً اتصال اینترنت را بررسی کنید.'); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF(); // اطلاعات پیش‌فاکتور const sellerInfo = includeInfo ? document.getElementById('seller-info')?.value.trim() || 'نامشخص' : '___________________________'; const buyerInfo = includeInfo ? document.getElementById('buyer-info')?.value.trim() || 'نامشخص' : '___________________________'; const date = new Date().toLocaleDateString('fa-IR'); const invoiceNumber = `PI-${Math.floor(Math.random() * 100000)}`; const totalPrice = products.reduce((sum, product) => sum + (product.unitPrice * product.quantity), 0); // تنظیم فونت doc.setFont("Helvetica", "normal"); doc.setFontSize(12); // صفحه اول: پیش‌فاکتور فارسی doc.text('پیش‌فاکتور', 105, 20, { align: 'center' }); doc.text(`شماره فاکتور: ${invoiceNumber}`, 190, 30, { align: 'right' }); doc.text(`تاریخ: ${date}`, 190, 40, { align: 'right' }); doc.text('فروشنده:', 190, 50, { align: 'right' }); doc.text(sellerInfo, 190, 60, { align: 'right', maxWidth: 100 }); doc.text('خریدار:', 190, 80, { align: 'right' }); doc.text(buyerInfo, 190, 90, { align: 'right', maxWidth: 100 }); // جدول کالاها doc.text('شرح کالا', 190, 110, { align: 'right' }); doc.text('قیمت واحد (دلار)', 100, 110, { align: 'center' }); doc.text('تعداد', 60, 110, { align: 'center' }); doc.text('قیمت کل (دلار)', 20, 110, { align: 'center' }); let y = 120; products.forEach((product, index) => { doc.text(`${index + 1}- ${product.nameFa || product.nameEn || 'کالا'}`, 190, y, { align: 'right', maxWidth: 80 }); doc.text(formatNumber(product.unitPrice.toFixed(2)), 100, y, { align: 'center' }); doc.text(formatNumber(product.quantity.toFixed(0)), 60, y, { align: 'center' }); doc.text(formatNumber((product.unitPrice * product.quantity).toFixed(2)), 20, y, { align: 'center' }); y += 10; }); doc.text(`مجموع کل: ${formatNumber(totalPrice.toFixed(2))} دلار`, 190, y + 10, { align: 'right' }); doc.text('تهیه‌شده توسط: irantd.com', 105, 280, { align: 'center' }); // صفحه دوم: Proforma Invoice انگلیسی doc.addPage(); doc.setFont("Helvetica", "normal"); doc.setFontSize(12); doc.text('Proforma Invoice', 105, 20, { align: 'center' }); doc.text(`Invoice Number: ${invoiceNumber}`, 190, 30, { align: 'right' }); doc.text(`Date: ${new Date().toLocaleDateString('en-US')}`, 190, 40, { align: 'right' }); doc.text('Seller:', 190, 50, { align: 'right' }); doc.text(sellerInfo, 190, 60, { align: 'right', maxWidth: 100 }); doc.text('Buyer:', 190, 80, { align: 'right' }); doc.text(buyerInfo, 190, 90, { align: 'right', maxWidth: 100 }); // جدول کالاها doc.text('Description', 190, 110, { align: 'right' }); doc.text('Unit Price (USD)', 100, 110, { align: 'center' }); doc.text('Quantity', 60, 110, { align: 'center' }); doc.text('Total Price (USD)', 20, 110, { align: 'center' }); y = 120; products.forEach((product, index) => { doc.text(`${index + 1}- ${product.nameEn || 'Item'}`, 190, y, { align: 'right', maxWidth: 80 }); doc.text(formatNumber(product.unitPrice.toFixed(2)), 100, y, { align: 'center' }); doc.text(formatNumber(product.quantity.toFixed(0)), 60, y, { align: 'center' }); doc.text(formatNumber((product.unitPrice * product.quantity).toFixed(2)), 20, y, { align: 'center' }); y += 10; }); doc.text(`Total: ${formatNumber(totalPrice.toFixed(2))} USD`, 190, y + 10, { align: 'right' }); doc.text('Prepared by: irantd.com', 105, 280, { align: 'center' }); // ذخیره PDF try { doc.save(`proforma_invoice_${invoiceNumber}.pdf`); } catch (error) { console.error('Error saving PDF:', error); alert('خطا در تولید PDF. لطفاً کنسول مرورگر را بررسی کنید.'); } } function toggleLtcFields() { const transportType = document.querySelector('input[name="ltc-transport-type"]:checked')?.value; if (!transportType) return; document.getElementById('ltc-sea-fields').style.display = transportType === 'sea' ? 'block' : 'none'; document.getElementById('ltc-air-fields').style.display = transportType === 'air' ? 'block' : 'none'; updateLtcCost(); } function updateLtcSeaCost() { const volume = parseNumber(document.getElementById('ltc-sea-volume').value); const currencyType = document.getElementById('currency-type-main').value; const defaults = defaultValues[currencyType] || defaultValues.dollar; const costPerCbm = parseNumber(document.getElementById('ltc-sea-cost-per-cbm').value) || parseNumber(defaults.find(d => d.id === 'ltc-sea-cost-per-cbm').value); const shippingCost = volume * costPerCbm; document.getElementById('ltc-sea-shipping-cost').value = formatNumber(shippingCost.toFixed(2)); updateLtcCost(); } function updateLtcAirCost() { const weight = parseNumber(document.getElementById('ltc-air-weight').value); const length = parseNumber(document.getElementById('ltc-air-length').value); const width = parseNumber(document.getElementById('ltc-air-width').value); const height = parseNumber(document.getElementById('ltc-air-height').value); const volumetricWeight = (length * width * height) / 6000; const chargeableWeight = Math.max(weight, volumetricWeight); document.getElementById('ltc-air-chargeable-weight').value = formatNumber(chargeableWeight.toFixed(2)); const currencyType = document.getElementById('currency-type-main').value; const defaults = defaultValues[currencyType] || defaultValues.dollar; const costPerKg = parseNumber(document.getElementById('ltc-air-cost-per-kg').value) || parseNumber(defaults.find(d => d.id === 'ltc-air-cost-per-kg').value); const shippingCost = chargeableWeight * costPerKg; document.getElementById('ltc-air-shipping-cost').value = formatNumber(shippingCost.toFixed(2)); updateLtcCost(); } function updateLtcCost() { const transportType = document.querySelector('input[name="ltc-transport-type"]:checked')?.value; const currencyType = document.getElementById('currency-type-main').value; const defaults = defaultValues[currencyType] || defaultValues.dollar; let shippingCost = 0; if (transportType === 'sea') { shippingCost = parseNumber(document.getElementById('ltc-sea-shipping-cost').value); } else if (transportType === 'air') { shippingCost = parseNumber(document.getElementById('ltc-air-shipping-cost').value); } const rate = parseNumber(document.getElementById(`${currencyType}-rate`).value) || parseNumber(defaults.find(d => d.id === `${currencyType}-rate`).value); const totalCostRial = shippingCost * rate; document.getElementById('ltc-total-cost-rial').value = formatNumber(totalCostRial.toFixed(0)); document.getElementById('shipping-cost-rial').value = formatNumber(totalCostRial.toFixed(0)); updateChart(); } function updateContainerShippingCost() { const container20 = parseNumber(document.getElementById('container-20-foot').value); const container40 = parseNumber(document.getElementById('container-40-foot').value); const currencyType = document.getElementById('currency-type-main').value; const defaults = defaultValues[currencyType] || defaultValues.dollar; const cost20 = parseNumber(document.getElementById('container-20-cost').value) || parseNumber(defaults.find(d => d.id === 'container-20-cost').value); const cost40 = parseNumber(document.getElementById('container-40-cost').value) || parseNumber(defaults.find(d => d.id === 'container-40-cost').value); const rate = parseNumber(document.getElementById(`${currencyType}-rate`).value) || parseNumber(defaults.find(d => d.id === `${currencyType}-rate`).value); const totalCost = (container20 * cost20 + container40 * cost40) * rate; document.getElementById('total-shipping-cost-rial').value = formatNumber(totalCost.toFixed(0)); document.getElementById('shipping-cost-rial').value = formatNumber(totalCost.toFixed(0)); updateChart(); } function updateCustomsCost() { const officialRate = parseNumber(document.getElementById('official-rate').value) || parseNumber(defaultValues.dollar.find(d => d.id === 'official-rate').value); const fobRial = parseNumber(document.getElementById('product-price-rial').value); const shippingRial = parseNumber(document.getElementById('shipping-cost-rial').value); const cifDollar = (fobRial + shippingRial) / officialRate; document.getElementById('product-price-rial-modal').value = formatNumber(cifDollar.toFixed(2)); const customsRate = parseNumber(document.getElementById('customs-rate').value) || parseNumber(defaults.find(d => d.id === 'customs-rate').value); const customsDuty = cifDollar * (customsRate / 100) * officialRate; document.getElementById('customs-duty-rial').value = formatNumber(customsDuty.toFixed(0)); const vat = (cifDollar + (cifDollar * customsRate / 100)) * 0.10 * officialRate; document.getElementById('vat-amount').value = formatNumber(vat.toFixed(0)); const prepaymentTax = cifDollar * 0.02 * officialRate; document.getElementById('prepayment-tax').value = formatNumber(prepaymentTax.toFixed(0)); const redCrescentFee = cifDollar * 0.015 * officialRate; document.getElementById('red-crescent-fee').value = formatNumber(redCrescentFee.toFixed(0)); let storageFee = 0; const container20 = parseNumber(document.getElementById('container-20-foot').value); const container40 = parseNumber(document.getElementById('container-40-foot').value); const ltcSeaVolume = parseNumber(document.getElementById('ltc-sea-volume').value); const ltcAirWeight = parseNumber(document.getElementById('ltc-air-chargeable-weight').value); if (container20 || container40) { storageFee = (container20 * 200000000) + (container40 * 300000000); } else if (ltcSeaVolume) { storageFee = ltcSeaVolume * 20000000; } else if (ltcAirWeight) { storageFee = ltcAirWeight * 250000; } document.getElementById('storage-fee').value = formatNumber(storageFee.toFixed(0)); const totalCustomsCost = customsDuty + vat + prepaymentTax + redCrescentFee + storageFee; document.getElementById('customs-cost-rial-modal').value = formatNumber(totalCustomsCost.toFixed(0)); document.getElementById('customs-cost-rial').value = formatNumber(totalCustomsCost.toFixed(0)); updateChart(); } function updatePermitsCost() { const standardCost = document.getElementById('standard-required-yes')?.checked ? parseNumber(document.getElementById('standard-cost').value) || defaultValues.standardCost : 0; const orgPermitsCost = parseNumber(document.getElementById('org-permits-cost').value); const totalPermitsCost = standardCost + orgPermitsCost; document.getElementById('permits-cost-total').value = formatNumber(totalPermitsCost.toFixed(0)); document.getElementById('permits-cost-rial').value = formatNumber(totalPermitsCost.toFixed(0)); updateChart(); } function updateOtherCosts() { const orderRegistrationCost = parseNumber(document.getElementById('order-registration-cost').value); const bankingCost = parseNumber(document.getElementById('banking-cost').value); const shippingClearanceCost = parseNumber(document.getElementById('shipping-clearance-cost').value); const commerceCardCost = parseNumber(document.getElementById('commerce-card-cost').value); const agentFeeCost = parseNumber(document.getElementById('agent-fee-cost').value); const inlandShippingCost = parseNumber(document.getElementById('inland-shipping-cost').value); const miscellaneousCost = parseNumber(document.getElementById('miscellaneous-cost').value); const totalOtherCosts = orderRegistrationCost + bankingCost + shippingClearanceCost + commerceCardCost + agentFeeCost + inlandShippingCost + miscellaneousCost; document.getElementById('other-costs-total').value = formatNumber(totalOtherCosts.toFixed(0)); document.getElementById('other-costs-rial').value = formatNumber(totalOtherCosts.toFixed(0)); updateChart(); } function updateTotalCost() { const productPrice = parseNumber(document.getElementById('product-price-rial').value); const shippingCost = parseNumber(document.getElementById('shipping-cost-rial').value); const customsCost = parseNumber(document.getElementById('customs-cost-rial').value); const permitsCost = parseNumber(document.getElementById('permits-cost-rial').value); const otherCosts = parseNumber(document.getElementById('other-costs-rial').value); const totalCost = productPrice + shippingCost + customsCost + permitsCost + otherCosts; document.getElementById('total-cost-rial').value = formatNumber(totalCost.toFixed(0)); } function resetForm() { document.querySelectorAll('input[type="text"]').forEach(input => input.value = ''); document.querySelectorAll('select').forEach(select => select.selectedIndex = 0); document.querySelectorAll('input[type="radio"]').forEach(radio => radio.checked = radio.defaultChecked); toggleFormFields(); toggleFobModalFields(); toggleLtcFields(); products = []; currentProductIndex = 1; renderProductList(); updateChart(); updateDynamicTitle(); } function updateStandardCost() { const standardRequired = document.getElementById('standard-required-yes')?.checked; document.getElementById('standard-cost').value = standardRequired ? formatNumber(defaultValues.standardCost.toString()) : '0'; updatePermitsCost(); } function updateCommerceCardCost() { const commerceCardType = document.querySelector('input[name="commerce-card-type"]:checked')?.value; const cifDollar = parseNumber(document.getElementById('product-price-rial-modal').value); const cost = commerceCardType === 'own' ? 0 : cifDollar * 1000; document.getElementById('commerce-card-cost').value = formatNumber(cost.toFixed(0)); updateOtherCosts(); } document.addEventListener('DOMContentLoaded', () => { initializeChart(); toggleFormFields(); toggleFobModalFields(); toggleLtcFields(); updateDynamicTitle(); updateChart(); // اضافه کردن event listener برای به‌روزرسانی خودکار const sitePriceInput = document.getElementById('modal-site-price'); const quantityInput = document.getElementById('modal-quantity'); if (sitePriceInput && quantityInput) { sitePriceInput.addEventListener('input', updateChinaProduct); quantityInput.addEventListener('input', updateChinaProduct); } });