UNPKG

ubl2json

Version:

Türkiye e-Belge sistemi için kullanılan UBLTR XML formatındaki belgelerin json objesine dönüştürülmesi için kullanılan paket.

203 lines (181 loc) 7.68 kB
const _ = require('lodash'); const setDefaults = (args) => { return { setBuyerCustomerToReceiverForExportInvoices: args?.setBuyerCustomerToReceiverForExportInvoices || false, }; }; const taxSubtotalNormalizer = (taxTotal) => { const taxSubtotal = _.map(taxTotal.TaxSubtotal, (taxSub) => { return { name: taxSub.TaxCategory?.TaxScheme?.Name?.val, code: taxSub.TaxCategory?.TaxScheme?.TaxTypeCode?.val, percent: taxSub.Percent?.val, taxable: taxSub.TaxableAmount?.val, taxable_currency: taxSub.TaxableAmount?.currencyID, tax_exemption_reason_code: taxSub.TaxCategory?.TaxExemptionReasonCode?.val, amount: taxSub.TaxAmount?.val, amount_currency: taxSub.TaxAmount?.currencyID, }; }); return taxSubtotal; }; const allowanceChargeNormalizer = (allowanceCharge) => { const allowanceChargeArray = _.map(allowanceCharge, (charge) => { return { is_charge: charge.ChargeIndicator?.val, reason: charge.AllowanceChargeReason?.val, multiplier: charge.MultiplierFactorNumeric?.val || 0, amount: charge.Amount?.val || 0, amount_currency: charge.Amount?.currencyID, base_amount: charge.BaseAmount?.val || 0, base_amount_currency: charge.BaseAmount?.currencyID, }; }); return allowanceChargeArray; }; const linesNormalizer = (linesArray) => { const lines = _.map(linesArray, (line) => { let withholding = {}; if (line.WithholdingTaxTotal) { withholding = { withholding_tax_total: line.WithholdingTaxTotal[0]?.TaxAmount?.val, withholding_tax_subtotals: taxSubtotalNormalizer(line.WithholdingTaxTotal[0]), }; } return { id: line.ID?.val, name: line.Item[0]?.Name?.val, note: line.Note?.val, quantity: line.InvoicedQuantity?.val || line.CreditedQuantity?.val || 0, quantity_unit: line.InvoicedQuantity?.unitCode || line.CreditedQuantity?.unitCode, price: line.Price.PriceAmount?.val || 0, price_currency: line.Price?.PriceAmount?.currencyID, extension_amount: line.LineExtensionAmount?.val || 0, extension_amount_currency: line.LineExtensionAmount?.currencyID, allowances: allowanceChargeNormalizer(line.AllowanceCharge), tax_total: line.TaxTotal ? line.TaxTotal[0]?.TaxAmount?.val : 0, tax_subtotals: taxSubtotalNormalizer(line.TaxTotal ? line.TaxTotal[0] : { TaxSubtotal: [] }), ...withholding, additional: { description: line.Item[0]?.Description?.[0]?.val || null, keyword: line.Item[0]?.Keyword?.val || null, brand_name: line.Item[0]?.BrandName?.val || null, model_name: line.Item[0]?.ModelName?.val || null, buyers_item_id: line.Item[0]?.BuyersItemIdentification?.ID?.val || null, sellers_item_id: line.Item[0]?.SellersItemIdentification?.ID?.val || null, manufacturers_item_id: line.Item[0]?.ManufacturersItemIdentification?.ID?.val || null, origin_country: line.Item[0]?.OriginCountry?.val || null, gtip: line.Item[0]?.Delivery?.[0]?.Shipment?.[0]?.GoodsItem?.[0]?.RequiredCustomsID?.val, instance: _.map(line.Item[0]?.ItemInstance, (instance) => { return { trace_id: instance.ProductTraceID?.val || null, manufacture_date: instance.ManufactureDate?.val || null, manufacture_time: instance.ManufactureTime?.val || null, registration_id: instance.RegistrationID?.val || null, serial_id: instance.SerialID?.val || null, lot_id: instance.LotIdentification?.val || null, }; }) || [], }, }; }); return lines; }; const partyNormalizer = (partyJson) => { const party = partyJson.Party; const getVal = (x) => { if (!x) return ''; if (typeof x === 'object') return x.val || x['#text'] || ''; return String(x); }; const parsePartyDetails = (p) => { const matchedIdentity = _.find( p.PartyIdentification, (id) => id?.ID?.schemeID === 'TCKN' || id?.ID?.schemeID === 'VKN' || id?.ID?.schemeID === 'PARTYTYPE', ); const ID = matchedIdentity?.ID || {}; const scheme = ID?.schemeID; let street = p.PostalAddress?.StreetName?.val || ''; let bName = p.PostalAddress?.BuildingName?.val || ''; let bNumber = ''; if (p.PostalAddress?.BuildingNumber) { if (Array.isArray(p.PostalAddress.BuildingNumber)) { bNumber = p.PostalAddress.BuildingNumber[0]?.val || ''; } else { bNumber = p.PostalAddress.BuildingNumber.val || p.PostalAddress.BuildingNumber || ''; } } let room = p.PostalAddress?.Room?.val || ''; let baseAddress = [street, bName, bNumber, room] .map(x => String(x || '').replace(/undefined|null/gi, '').trim()) .filter(Boolean) .join(' '); const city = String(p.PostalAddress?.CityName?.val || '').trim(); const sub = String(p.PostalAddress?.CitySubdivisionName?.val || '').trim(); const extra = [sub, city].filter(Boolean).join('/'); let finalAddress = baseAddress; if (extra) { const baseLower = baseAddress.toLowerCase(); const cityLower = city.toLowerCase(); const subLower = sub.toLowerCase(); const hasCity = city && baseLower.includes(cityLower); const hasSub = sub && baseLower.includes(subLower); const extraParts = []; if (sub && !hasSub) extraParts.push(sub); if (city && !hasCity) extraParts.push(city); if (extraParts.length > 0) { finalAddress = `${baseAddress} ${extraParts.join('/')}`.trim(); } } const additionalIdentifiers = _.map(p.PartyIdentification, (id) => { const schemeId = getVal(id?.ID?.schemeID); if (schemeId !== 'TCKN' && schemeId !== 'VKN') { return { scheme: schemeId, value: getVal(id?.ID), }; } }).filter((id) => id !== undefined) || []; return { name: scheme === 'TCKN' ? `${p.Person?.FirstName?.val}${p.Person?.MiddleName?.val ? ` ${p.Person?.MiddleName?.val}` : ''} ${p.Person?.FamilyName?.val}` : p.PartyName?.Name?.val, vkn_tckn: ['TCKN', 'VKN'].includes(scheme) ? ID?.val : p.PartyLegalEntity?.[0]?.CompanyID?.val, tax_office: p.PartyTaxScheme?.TaxScheme?.Name?.val, address: finalAddress || '', city: p.PostalAddress?.CityName?.val, city_subdivision: p.PostalAddress?.CitySubdivisionName?.val, country: p.PostalAddress?.Country?.Name?.val, postal_zone: p.PostalAddress?.PostalZone?.val, email: p.Contact?.ElectronicMail?.val, phone_number: p.Contact?.Telephone?.val, additional_identifiers: additionalIdentifiers, }; }; const normalized = parsePartyDetails(party); if (party.AgentParty) { const agentNormalized = parsePartyDetails(party.AgentParty); if (agentNormalized.address) normalized.address = agentNormalized.address; if (agentNormalized.city) normalized.city = agentNormalized.city; if (agentNormalized.city_subdivision) normalized.city_subdivision = agentNormalized.city_subdivision; if (agentNormalized.postal_zone) normalized.postal_zone = agentNormalized.postal_zone; agentNormalized.additional_identifiers.forEach((agentId) => { const existing = normalized.additional_identifiers.find(id => id.scheme === agentId.scheme); if (existing) { existing.value = agentId.value; } else { normalized.additional_identifiers.push(agentId); } }); } return normalized; }; module.exports = { setDefaults, taxSubtotalNormalizer, allowanceChargeNormalizer, linesNormalizer, partyNormalizer, };