{"version":3,"sources":["../src/services/padron.ts"],"sourcesContent":["import type { ReceiverCondition } from \"../constants\";\nimport { ArcaSoapFaultError } from \"../errors\";\nimport type {\n  ArcaClientConfig,\n  ArcaPadronServiceName,\n} from \"../internal/types\";\nimport type { SoapTransport } from \"../soap\";\nimport type { WsaaAuthModule } from \"../wsaa\";\n\n/** One tax registration reported by the constancia de inscripción. */\nexport type PadronTax = {\n  id: number;\n  description?: string;\n  /** ARCA's state code; `AC` is active. Absent when ARCA omits it. */\n  state?: string;\n  regime: \"general\" | \"monotributo\";\n};\n\n/** Result of a taxpayer lookup via Padron A5. */\nexport type PadronTaxpayerResult = {\n  taxId: string;\n  personType?: string;\n  name?: string;\n  /**\n   * The receiver condition to invoice this taxpayer under, derived from its\n   * active IVA registrations: 30 is responsable inscripto, 20 monotributo, 32\n   * exento and 34 no alcanzado. A taxpayer with none of them is a consumidor\n   * final. Absent when the registrations contradict each other or when the\n   * constancia reports an error, because then they may be missing.\n   */\n  condition?: ReceiverCondition;\n  taxes: PadronTax[];\n  raw: Record<string, unknown>;\n};\n\n/** Result of a tax ID lookup by document number via Padron A13. */\nexport type PadronTaxIdLookupResult = {\n  taxIds: string[];\n  raw: Record<string, unknown>;\n};\n\n/** Padron taxpayer registry service. */\nexport type PadronService = {\n  /** Looks up taxpayer details by CUIT. Returns `null` if the taxpayer does not exist. */\n  getTaxpayerDetails(\n    taxId: number | string\n  ): Promise<PadronTaxpayerResult | null>;\n  /** Looks up CUITs associated with a document number. Returns `null` if not found. */\n  getTaxIdByDocument(\n    documentNumber: number | string\n  ): Promise<PadronTaxIdLookupResult | null>;\n};\n\nexport type CreatePadronServiceOptions = {\n  config: ArcaClientConfig;\n  auth: WsaaAuthModule;\n  soap: SoapTransport;\n};\n\n/** Creates a Padron service instance wired with authentication and SOAP transport. */\nexport function createPadronService(\n  options: CreatePadronServiceOptions\n): PadronService {\n  return {\n    async getTaxpayerDetails(taxId) {\n      const raw = await executePadronOperation(\n        options,\n        \"padron-a5\",\n        \"getPersona_v2\",\n        {\n          idPersona: Number.parseInt(String(taxId), 10),\n        }\n      );\n      if (!raw) {\n        return null;\n      }\n      const record = raw as Record<string, unknown>;\n      if (isPadronNotFound(record)) {\n        return null;\n      }\n      const datosGenerales = record.datosGenerales as\n        | Record<string, unknown>\n        | undefined;\n      const idPersona = record.idPersona ?? datosGenerales?.idPersona;\n      const tipoPersona = record.tipoPersona ?? datosGenerales?.tipoPersona;\n      const taxes = extractPadronTaxes(record);\n      // A constancia with an unresolved error may be missing registrations, so\n      // their absence proves nothing about the receiver's condition.\n      const condition = hasConstanciaError(record)\n        ? undefined\n        : deriveReceiverCondition(taxes);\n      return {\n        taxId: String(idPersona ?? taxId),\n        ...(tipoPersona === undefined\n          ? {}\n          : { personType: String(tipoPersona) }),\n        ...(datosGenerales ? { name: extractPadronName(datosGenerales) } : {}),\n        ...(condition === undefined ? {} : { condition }),\n        taxes,\n        raw: record,\n      };\n    },\n    async getTaxIdByDocument(documentNumber) {\n      const raw = await executePadronOperation(\n        options,\n        \"padron-a13\",\n        \"getIdPersonaListByDocumento\",\n        {\n          documento: String(documentNumber),\n        }\n      );\n      if (!raw) {\n        return null;\n      }\n      const record = raw as Record<string, unknown>;\n      const idPersona = record.idPersona;\n      const taxIds = Array.isArray(idPersona)\n        ? idPersona.map(String)\n        : idPersona === undefined\n          ? []\n          : [String(idPersona)];\n      return {\n        taxIds,\n        raw: record,\n      };\n    },\n  };\n}\n\nconst IVA_TAX_CONDITIONS: Readonly<Record<number, ReceiverCondition>> = {\n  20: \"monotributo\",\n  30: \"responsable_inscripto\",\n  32: \"exento\",\n  34: \"no_alcanzado\",\n};\n\n// The constancia answers a missing CUIT inside errorConstancia, not as a fault.\nconst NOT_FOUND_PHRASES = [\n  \"la clave solicitada no existe\",\n  \"no existe persona con ese id\",\n  \"no existe persona con esa clave\",\n  \"persona no encontrada\",\n  \"no se encontro informacion para la clave\",\n];\n\nfunction constanciaErrors(record: Record<string, unknown>): string[] {\n  const errorConstancia = record.errorConstancia as\n    | { error?: unknown }\n    | undefined;\n  const errors = errorConstancia?.error;\n  return (Array.isArray(errors) ? errors : [errors]).filter(\n    (message): message is string =>\n      typeof message === \"string\" && message.trim() !== \"\"\n  );\n}\n\nfunction hasConstanciaError(record: Record<string, unknown>): boolean {\n  return constanciaErrors(record).length > 0;\n}\n\nfunction isPadronNotFound(record: Record<string, unknown>): boolean {\n  return constanciaErrors(record).some((message) =>\n    NOT_FOUND_PHRASES.some((phrase) => plainText(message).includes(phrase))\n  );\n}\n\nfunction plainText(value: string): string {\n  return value\n    .normalize(\"NFD\")\n    .replace(/\\p{Diacritic}/gu, \"\")\n    .toLowerCase();\n}\n\nfunction extractPadronTaxes(record: Record<string, unknown>): PadronTax[] {\n  const taxes: PadronTax[] = [];\n  for (const [regime, field] of [\n    [\"general\", \"datosRegimenGeneral\"],\n    [\"monotributo\", \"datosMonotributo\"],\n  ] as const) {\n    const bucket = record[field] as { impuesto?: unknown } | undefined;\n    const rows = bucket?.impuesto;\n    for (const row of Array.isArray(rows) ? rows : rows ? [rows] : []) {\n      const tax = row as Record<string, unknown>;\n      const id = Number(tax.idImpuesto);\n      if (!Number.isSafeInteger(id)) {\n        continue;\n      }\n      taxes.push({\n        id,\n        ...(typeof tax.descripcionImpuesto === \"string\"\n          ? { description: tax.descripcionImpuesto }\n          : {}),\n        ...(typeof tax.estadoImpuesto === \"string\"\n          ? { state: tax.estadoImpuesto.trim().toUpperCase() }\n          : {}),\n        regime,\n      });\n    }\n  }\n  return taxes;\n}\n\n/** One active IVA registration decides; none is a consumidor final; two is nobody's call. */\nfunction deriveReceiverCondition(\n  taxes: readonly PadronTax[]\n): ReceiverCondition | undefined {\n  const conditions = new Set<ReceiverCondition>();\n  for (const tax of taxes) {\n    const condition = IVA_TAX_CONDITIONS[tax.id];\n    if (condition && (tax.state === undefined || tax.state === \"AC\")) {\n      conditions.add(condition);\n    }\n  }\n  if (conditions.size === 0) {\n    return \"consumidor_final\";\n  }\n  return conditions.size === 1 ? [...conditions][0] : undefined;\n}\n\nfunction extractPadronName(\n  datosGenerales: Record<string, unknown>\n): string | undefined {\n  if (typeof datosGenerales.razonSocial === \"string\") {\n    return datosGenerales.razonSocial;\n  }\n  const nombre = datosGenerales.nombre;\n  const apellido = datosGenerales.apellido;\n  if (typeof apellido === \"string\" && typeof nombre === \"string\") {\n    return `${apellido} ${nombre}`.trim();\n  }\n  if (typeof apellido === \"string\") {\n    return apellido;\n  }\n  if (typeof nombre === \"string\") {\n    return nombre;\n  }\n  return undefined;\n}\n\nasync function executePadronOperation(\n  options: CreatePadronServiceOptions,\n  service: ArcaPadronServiceName,\n  operation: string,\n  body: Record<string, unknown>\n) {\n  const auth = await options.auth.login(\n    service === \"padron-a5\"\n      ? \"ws_sr_constancia_inscripcion\"\n      : \"ws_sr_padron_a13\"\n  );\n\n  try {\n    const response = await options.soap.execute<\n      Record<string, unknown>,\n      Record<string, unknown>\n    >({\n      service,\n      operation,\n      bodyElementNamespaceMode: \"prefix\",\n      body: {\n        token: auth.token,\n        sign: auth.sign,\n        cuitRepresentada: Number.parseInt(options.config.taxId, 10),\n        ...body,\n      },\n    });\n\n    const operationResponse = response.result as Record<string, unknown>;\n\n    if (operation === \"getPersona_v2\") {\n      return operationResponse.personaReturn ?? null;\n    }\n\n    if (operation === \"getIdPersonaListByDocumento\") {\n      return operationResponse.idPersonaListReturn ?? null;\n    }\n\n    return operationResponse.return ?? null;\n  } catch (error) {\n    if (\n      error instanceof ArcaSoapFaultError &&\n      // Public Padron A5/A13 WSDLs expose only a generic validation fault, so\n      // there is no documented not-found-specific fault code to match here.\n      // Keep the current message fallback, but treat it as fragile.\n      error.message.toLowerCase().includes(\"no existe\")\n    ) {\n      return null;\n    }\n\n    throw error;\n  }\n}\n"],"mappings":"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","names":[]}