Fixed extensions bugs
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
* Deadline: 25th of the month following the reporting period
|
||||
*/
|
||||
|
||||
import { isEUCountry } from '@/extensions/export/shared/eu-countries'
|
||||
import { isEUCountry, toCountryCode } from '@/extensions/export/shared/eu-countries'
|
||||
|
||||
// ── Types ────────────────────────────────────────────────────
|
||||
|
||||
@@ -231,6 +231,9 @@ export function generateECSalesListReport(options: GenerateReportOptions): ECSal
|
||||
// Classify: goods (box 35) or services (box 39)
|
||||
const classification = classifyInvoice(invoice)
|
||||
|
||||
// Normalize country to ISO code for consistent output
|
||||
const countryCode = toCountryCode(customer.country)
|
||||
|
||||
// Get or create aggregation line
|
||||
const vatNumber = customer.vat_number
|
||||
const key = vatNumber
|
||||
@@ -238,7 +241,7 @@ export function generateECSalesListReport(options: GenerateReportOptions): ECSal
|
||||
aggregation.set(key, {
|
||||
customerVatNumber: vatNumber,
|
||||
customerName: customer.name,
|
||||
customerCountry: customer.country,
|
||||
customerCountry: countryCode,
|
||||
customerId: customer.id,
|
||||
goodsAmount: 0,
|
||||
servicesAmount: 0,
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* Reference: SCB Intrastat guidelines, Combined Nomenclature (CN)
|
||||
*/
|
||||
|
||||
import { isEUCountry } from '@/extensions/export/shared/eu-countries'
|
||||
import { isEUCountry, toCountryCode } from '@/extensions/export/shared/eu-countries'
|
||||
|
||||
// ── Types ────────────────────────────────────────────────────
|
||||
|
||||
@@ -192,6 +192,7 @@ export function generateIntrastatReport(options: IntrastatOptions): IntrastatRep
|
||||
|
||||
for (const invoice of relevantInvoices) {
|
||||
const customer = customerMap.get(invoice.customer_id)!
|
||||
const partnerCountryCode = toCountryCode(customer.country)
|
||||
const isCreditNote = invoice.credited_invoice_id !== null
|
||||
const items = itemsByInvoice.get(invoice.id) ?? []
|
||||
|
||||
@@ -208,10 +209,10 @@ export function generateIntrastatReport(options: IntrastatOptions): IntrastatRep
|
||||
message: `Faktura ${invoice.invoice_number} saknar fakturarader — kan inte tilldela CN-kod.`,
|
||||
})
|
||||
|
||||
const key = buildAggKey('00000000', customer.country, 'SE', defaultTransactionNature, defaultDeliveryTerms)
|
||||
const key = buildAggKey('00000000', partnerCountryCode, 'SE', defaultTransactionNature, defaultDeliveryTerms)
|
||||
addToAggregation(aggregation, key, {
|
||||
cnCode: '00000000',
|
||||
partnerCountry: customer.country,
|
||||
partnerCountry: partnerCountryCode,
|
||||
countryOfOrigin: 'SE',
|
||||
transactionNature: defaultTransactionNature,
|
||||
deliveryTerms: defaultDeliveryTerms,
|
||||
@@ -240,10 +241,10 @@ export function generateIntrastatReport(options: IntrastatOptions): IntrastatRep
|
||||
message: `Faktura ${invoice.invoice_number}, rad "${item.description}" — ingen matchande produkt med CN-kod hittad.`,
|
||||
})
|
||||
|
||||
const key = buildAggKey('00000000', customer.country, 'SE', defaultTransactionNature, defaultDeliveryTerms)
|
||||
const key = buildAggKey('00000000', partnerCountryCode, 'SE', defaultTransactionNature, defaultDeliveryTerms)
|
||||
addToAggregation(aggregation, key, {
|
||||
cnCode: '00000000',
|
||||
partnerCountry: customer.country,
|
||||
partnerCountry: partnerCountryCode,
|
||||
countryOfOrigin: 'SE',
|
||||
transactionNature: defaultTransactionNature,
|
||||
deliveryTerms: defaultDeliveryTerms,
|
||||
@@ -286,10 +287,10 @@ export function generateIntrastatReport(options: IntrastatOptions): IntrastatRep
|
||||
? product.supplementaryUnit * item.quantity
|
||||
: null
|
||||
|
||||
const key = buildAggKey(cnCode, customer.country, origin, defaultTransactionNature, defaultDeliveryTerms)
|
||||
const key = buildAggKey(cnCode, partnerCountryCode, origin, defaultTransactionNature, defaultDeliveryTerms)
|
||||
addToAggregation(aggregation, key, {
|
||||
cnCode,
|
||||
partnerCountry: customer.country,
|
||||
partnerCountry: partnerCountryCode,
|
||||
countryOfOrigin: origin,
|
||||
transactionNature: defaultTransactionNature,
|
||||
deliveryTerms: defaultDeliveryTerms,
|
||||
|
||||
@@ -58,22 +58,56 @@ export const EU_COUNTRY_CODES_EXCL_SE = EU_COUNTRIES
|
||||
/** All EU country codes including Sweden */
|
||||
export const EU_COUNTRY_CODES = EU_COUNTRIES.map(c => c.code)
|
||||
|
||||
/** Check if a country code is an EU member state (excluding Sweden) */
|
||||
export function isEUCountry(countryCode: string): boolean {
|
||||
return EU_COUNTRY_CODES_EXCL_SE.includes(countryCode.toUpperCase())
|
||||
/**
|
||||
* Build a lookup set of all known names/codes for EU countries (excluding Sweden).
|
||||
* Handles ISO codes, English names, and Swedish names — all uppercased for matching.
|
||||
*/
|
||||
const EU_LOOKUP_EXCL_SE = new Set(
|
||||
EU_COUNTRIES
|
||||
.filter(c => c.code !== 'SE')
|
||||
.flatMap(c => [c.code, c.name, c.nameEn].map(s => s.toUpperCase()))
|
||||
)
|
||||
|
||||
const EU_LOOKUP_INCL_SE = new Set(
|
||||
EU_COUNTRIES
|
||||
.flatMap(c => [c.code, c.name, c.nameEn].map(s => s.toUpperCase()))
|
||||
)
|
||||
|
||||
/**
|
||||
* Check if a country value is an EU member state (excluding Sweden).
|
||||
* Accepts ISO codes ("DE"), English names ("Germany"), or Swedish names ("Tyskland").
|
||||
*/
|
||||
export function isEUCountry(country: string): boolean {
|
||||
return EU_LOOKUP_EXCL_SE.has(country.trim().toUpperCase())
|
||||
}
|
||||
|
||||
/** Check if a country code is an EU member state (including Sweden) */
|
||||
export function isEUCountryIncludingSE(countryCode: string): boolean {
|
||||
return EU_COUNTRY_CODES.includes(countryCode.toUpperCase())
|
||||
/**
|
||||
* Check if a country value is an EU member state (including Sweden).
|
||||
* Accepts ISO codes, English names, or Swedish names.
|
||||
*/
|
||||
export function isEUCountryIncludingSE(country: string): boolean {
|
||||
return EU_LOOKUP_INCL_SE.has(country.trim().toUpperCase())
|
||||
}
|
||||
|
||||
/** Get EU country data by ISO code */
|
||||
export function getEUCountry(countryCode: string): EUCountry | undefined {
|
||||
return EU_COUNTRIES.find(c => c.code === countryCode.toUpperCase())
|
||||
/** Get EU country data by ISO code, English name, or Swedish name */
|
||||
export function getEUCountry(country: string): EUCountry | undefined {
|
||||
const upper = country.trim().toUpperCase()
|
||||
return EU_COUNTRIES.find(
|
||||
c => c.code === upper || c.name.toUpperCase() === upper || c.nameEn.toUpperCase() === upper
|
||||
)
|
||||
}
|
||||
|
||||
/** Get the VIES VAT prefix for a country (note: Greece uses 'EL' not 'GR') */
|
||||
export function getVatPrefix(countryCode: string): string | undefined {
|
||||
return getEUCountry(countryCode)?.vatPrefix
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a country value to its ISO 3166-1 alpha-2 code.
|
||||
* Accepts ISO codes, English names, or Swedish names.
|
||||
* Returns the input uppercased if no match is found.
|
||||
*/
|
||||
export function toCountryCode(country: string): string {
|
||||
const found = getEUCountry(country)
|
||||
return found ? found.code : country.trim().toUpperCase()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user