arcli 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -1
- package/README.md +6 -0
- package/dist/cli/arca-runtime.js +0 -1
- package/dist/cli/commands/billing-family.command.js +36 -9
- package/dist/cli/commands/billing-shortcuts.command.js +8 -2
- package/dist/cli/commands/billing.command.batch.js +0 -1
- package/dist/cli/commands/billing.command.interactive-preview.js +9 -13
- package/dist/cli/commands/billing.command.options.js +83 -39
- package/dist/cli/commands/billing.command.output.js +0 -1
- package/dist/cli/commands/billing.command.parser.js +18 -17
- package/dist/cli/commands/billing.command.pdf.js +9 -6
- package/dist/cli/commands/billing.command.shared.js +2 -2
- package/dist/cli/commands/billing.command.shortcuts.js +3 -4
- package/dist/cli/commands/completion.command.js +140 -0
- package/dist/cli/commands/config.command.js +9 -10
- package/dist/cli/commands/cuit-argument.js +6 -6
- package/dist/cli/commands/examples.command.js +0 -1
- package/dist/cli/commands/export-shortcut.command.js +19 -0
- package/dist/cli/commands/export.command.js +106 -0
- package/dist/cli/commands/export.command.options.js +140 -0
- package/dist/cli/commands/export.command.parser.js +84 -0
- package/dist/cli/commands/export.command.pdf.js +61 -0
- package/dist/cli/commands/fce-obligation.command.js +2 -3
- package/dist/cli/commands/interactive.command.js +2 -3
- package/dist/cli/commands/padron.command.js +5 -6
- package/dist/cli/commands/parameters.command.js +5 -6
- package/dist/cli/commands/pdf.command.js +1 -2
- package/dist/cli/commands/storybook.command.js +4 -4
- package/dist/cli/commands/vouchers.command.js +9 -9
- package/dist/cli/error-output.js +21 -3
- package/dist/cli/global-options.js +2 -3
- package/dist/cli/help-argv.js +0 -1
- package/dist/cli/help.js +186 -380
- package/dist/cli/ignored-global-options.js +1 -2
- package/dist/cli/index.js +5 -3
- package/dist/cli/interactive/advanced-options.js +13 -14
- package/dist/cli/interactive/config.flow.js +55 -17
- package/dist/cli/interactive/export.flow.js +263 -0
- package/dist/cli/interactive/history.flow.js +2 -3
- package/dist/cli/interactive/interactive-mode.js +16 -17
- package/dist/cli/interactive/invoice-picker.js +7 -7
- package/dist/cli/interactive/invoice.flow.js +32 -11
- package/dist/cli/interactive/note.flow.js +12 -13
- package/dist/cli/interactive/pdf.flow.js +9 -7
- package/dist/cli/interactive/prompts.js +0 -1
- package/dist/cli/interactive/receiver-padron.js +3 -4
- package/dist/cli/interactive/repeat.flow.js +7 -8
- package/dist/cli/interactive/session.js +9 -7
- package/dist/cli/interactive/status.flow.js +0 -1
- package/dist/cli/interactive/update.flow.js +0 -1
- package/dist/cli/interactive/validators.js +7 -6
- package/dist/cli/option-parsers.js +14 -4
- package/dist/cli/program.js +6 -3
- package/dist/cli/skipped-options.js +14 -0
- package/dist/cli/spinner.js +0 -1
- package/dist/cli/types.js +0 -1
- package/dist/cli/version.js +1 -2
- package/dist/index.js +0 -1
- package/dist/lib/dates/arca-date.js +3 -4
- package/dist/lib/errors/app-error.js +0 -1
- package/dist/lib/files/read-json-file.js +2 -3
- package/dist/lib/files/restrict-to-owner.js +0 -1
- package/dist/lib/files/write-new-file.js +0 -1
- package/dist/lib/identity/cuit.js +26 -0
- package/dist/lib/identity/format-cuit.js +1 -2
- package/dist/lib/links.js +0 -1
- package/dist/lib/numbers/argentine-amount.js +3 -4
- package/dist/lib/numbers/strict-integer.js +0 -1
- package/dist/lib/paths/mask-path.js +0 -1
- package/dist/lib/security/certificate.js +0 -1
- package/dist/lib/security/pem.js +2 -3
- package/dist/modules/billing/billing-response.js +6 -7
- package/dist/modules/billing/billing.amounts.js +3 -4
- package/dist/modules/billing/billing.associated-period.js +7 -8
- package/dist/modules/billing/billing.associated-vouchers.js +5 -6
- package/dist/modules/billing/billing.batch.js +7 -6
- package/dist/modules/billing/billing.constants.js +0 -1
- package/dist/modules/billing/billing.currency.js +4 -5
- package/dist/modules/billing/billing.date-range.js +1 -2
- package/dist/modules/billing/billing.display.js +10 -8
- package/dist/modules/billing/billing.errors.js +2 -3
- package/dist/modules/billing/billing.fce.js +3 -4
- package/dist/modules/billing/billing.iva-receptor.js +2 -3
- package/dist/modules/billing/billing.json-format.js +0 -1
- package/dist/modules/billing/billing.json-input.js +5 -6
- package/dist/modules/billing/billing.labels.js +1 -2
- package/dist/modules/billing/billing.mappers.js +0 -1
- package/dist/modules/billing/billing.padron.js +9 -5
- package/dist/modules/billing/billing.presenter.js +0 -1
- package/dist/modules/billing/billing.schemas.js +14 -6
- package/dist/modules/billing/billing.serialize.js +6 -3
- package/dist/modules/billing/billing.service.js +4 -4
- package/dist/modules/billing/billing.text.js +0 -1
- package/dist/modules/billing/billing.types.internal.js +0 -1
- package/dist/modules/billing/billing.types.js +0 -1
- package/dist/modules/billing/billing.validation.js +13 -11
- package/dist/modules/billing/voucher-kind-map.js +15 -16
- package/dist/modules/completion/completion.js +53 -0
- package/dist/modules/completion/completion.presenter.js +35 -0
- package/dist/modules/completion/installer.js +92 -0
- package/dist/modules/completion/shell-scripts.js +46 -0
- package/dist/modules/config/certificate-expiry.js +3 -4
- package/dist/modules/config/config-doctor.js +36 -14
- package/dist/modules/config/config-value-parser.js +29 -16
- package/dist/modules/config/config.export-credentials.js +23 -0
- package/dist/modules/config/config.presenter.js +22 -6
- package/dist/modules/config/config.schemas.js +24 -12
- package/dist/modules/config/config.sections.js +26 -11
- package/dist/modules/config/config.service.js +6 -2
- package/dist/modules/examples/examples.js +44 -10
- package/dist/modules/export/export.items.js +149 -0
- package/dist/modules/export/export.json-input.js +91 -0
- package/dist/modules/export/export.mappers.js +293 -0
- package/dist/modules/export/export.presenter.js +2 -0
- package/dist/modules/export/export.response.js +86 -0
- package/dist/modules/export/export.serialize.js +70 -0
- package/dist/modules/export/export.service.js +146 -0
- package/dist/modules/export/export.text.js +177 -0
- package/dist/modules/export/export.types.js +36 -0
- package/dist/modules/fce/fce-obligation.js +3 -4
- package/dist/modules/fce/fce-obligation.presenter.js +2 -3
- package/dist/modules/interactive/amount-input.js +0 -1
- package/dist/modules/interactive/choices.js +10 -2
- package/dist/modules/interactive/config-fields.js +11 -3
- package/dist/modules/interactive/equivalent-command.js +4 -1
- package/dist/modules/interactive/export-equivalent-command.js +40 -0
- package/dist/modules/interactive/invoice-copy.js +1 -2
- package/dist/modules/interactive/periods.js +0 -1
- package/dist/modules/interactive/wizard.js +0 -1
- package/dist/modules/padron/padron.js +0 -1
- package/dist/modules/padron/padron.presenter.js +6 -7
- package/dist/modules/parameters/health.js +0 -1
- package/dist/modules/parameters/parameters.js +2 -3
- package/dist/modules/parameters/parameters.presenter.js +12 -13
- package/dist/modules/parameters/status.js +0 -1
- package/dist/modules/pdf/pdf-data.mapper.js +94 -3
- package/dist/modules/pdf/pdf-decision.js +0 -1
- package/dist/modules/pdf/pdf-file-name.js +0 -1
- package/dist/modules/pdf/pdf-issuer.js +3 -3
- package/dist/modules/pdf/pdf-legends.js +35 -0
- package/dist/modules/pdf/pdf.errors.js +0 -1
- package/dist/modules/pdf/pdf.types.js +0 -1
- package/dist/modules/storybook/showcase-theme.js +0 -1
- package/dist/modules/storybook/showcase.js +20 -21
- package/dist/modules/update-check/changelog.js +0 -1
- package/dist/modules/update-check/update-check.presenter.js +6 -7
- package/dist/modules/update-check/update-check.service.js +0 -1
- package/dist/modules/vouchers/voucher-history.js +0 -1
- package/dist/modules/vouchers/voucher-history.presenter.js +3 -4
- package/dist/services/arca/arca-billing.gateway.js +4 -5
- package/dist/services/arca/arca-client.factory.js +23 -2
- package/dist/services/arca/arca-context.resolver.js +5 -6
- package/dist/services/arca/arca-export.gateway.js +146 -0
- package/dist/services/arca/arca-fce-obligation.gateway.js +2 -3
- package/dist/services/arca/arca-padron.gateway.js +1 -2
- package/dist/services/arca/arca-parameters.gateway.js +2 -3
- package/dist/services/arca/arca-voucher-history.gateway.js +2 -3
- package/dist/services/arca/last-voucher.js +26 -0
- package/dist/services/clipboard/clipboard.js +0 -1
- package/dist/services/pdf/escape-html.js +0 -1
- package/dist/services/pdf/pdf-browser.js +0 -1
- package/dist/services/pdf/pdf-exporter.js +15 -2
- package/dist/services/pdf/pdf-plugin.js +41 -14
- package/dist/ui/components/certificateBanner.js +0 -1
- package/dist/ui/components/contentPanel.js +0 -1
- package/dist/ui/components/errorPanel.js +0 -1
- package/dist/ui/components/index.js +0 -1
- package/dist/ui/components/keyValuePanel.js +0 -1
- package/dist/ui/components/noticePanel.js +0 -1
- package/dist/ui/components/rawPanel.js +0 -1
- package/dist/ui/components/sectionHeading.js +0 -1
- package/dist/ui/components/statusBar.js +0 -1
- package/dist/ui/components/statusPanel.js +0 -1
- package/dist/ui/components/testingBanner.js +0 -1
- package/dist/ui/index.js +0 -1
- package/dist/ui/presenters/billing.presenter.js +0 -1
- package/dist/ui/presenters/config.presenter.js +0 -1
- package/dist/ui/presenters/errors.presenter.js +10 -11
- package/dist/ui/presenters/errors.zod-presenter.js +8 -9
- package/dist/ui/presenters/export.presenter.js +1 -0
- package/dist/ui/presenters/index.js +1 -1
- package/dist/ui/presenters/pdf.presenter.js +1 -2
- package/dist/ui/presenters/showcase.presenter.js +0 -1
- package/dist/ui/primitives/index.js +0 -1
- package/dist/ui/primitives/renderDivider.js +0 -1
- package/dist/ui/primitives/renderFooter.js +0 -1
- package/dist/ui/primitives/renderJson.js +0 -1
- package/dist/ui/primitives/renderKeyValue.js +0 -1
- package/dist/ui/primitives/renderLogo.js +0 -1
- package/dist/ui/primitives/renderObject.js +0 -1
- package/dist/ui/primitives/renderPanel.js +0 -1
- package/dist/ui/primitives/renderSubtitle.js +0 -1
- package/dist/ui/primitives/renderTable.js +0 -1
- package/dist/ui/primitives/terminalWidth.js +0 -1
- package/dist/ui/primitives/text.js +0 -1
- package/dist/ui/stream/index.js +0 -1
- package/dist/ui/stream/terminal-stream.js +0 -1
- package/dist/ui/theme/index.js +0 -1
- package/dist/ui/theme/theme.js +0 -1
- package/llms.txt +64 -5
- package/package.json +1 -2
- package/dist/cli/arca-runtime.d.ts +0 -20
- package/dist/cli/arca-runtime.js.map +0 -1
- package/dist/cli/commands/billing-family.command.d.ts +0 -2
- package/dist/cli/commands/billing-family.command.js.map +0 -1
- package/dist/cli/commands/billing-shortcuts.command.d.ts +0 -2
- package/dist/cli/commands/billing-shortcuts.command.js.map +0 -1
- package/dist/cli/commands/billing.command.batch.d.ts +0 -32
- package/dist/cli/commands/billing.command.batch.js.map +0 -1
- package/dist/cli/commands/billing.command.interactive-preview.d.ts +0 -18
- package/dist/cli/commands/billing.command.interactive-preview.js.map +0 -1
- package/dist/cli/commands/billing.command.options.d.ts +0 -2
- package/dist/cli/commands/billing.command.options.js.map +0 -1
- package/dist/cli/commands/billing.command.output.d.ts +0 -18
- package/dist/cli/commands/billing.command.output.js.map +0 -1
- package/dist/cli/commands/billing.command.parser.d.ts +0 -35
- package/dist/cli/commands/billing.command.parser.js.map +0 -1
- package/dist/cli/commands/billing.command.pdf.d.ts +0 -24
- package/dist/cli/commands/billing.command.pdf.js.map +0 -1
- package/dist/cli/commands/billing.command.shared.d.ts +0 -26
- package/dist/cli/commands/billing.command.shared.js.map +0 -1
- package/dist/cli/commands/billing.command.shortcuts.d.ts +0 -7
- package/dist/cli/commands/billing.command.shortcuts.js.map +0 -1
- package/dist/cli/commands/config.command.d.ts +0 -6
- package/dist/cli/commands/config.command.js.map +0 -1
- package/dist/cli/commands/cuit-argument.d.ts +0 -2
- package/dist/cli/commands/cuit-argument.js.map +0 -1
- package/dist/cli/commands/examples.command.d.ts +0 -2
- package/dist/cli/commands/examples.command.js.map +0 -1
- package/dist/cli/commands/fce-obligation.command.d.ts +0 -2
- package/dist/cli/commands/fce-obligation.command.js.map +0 -1
- package/dist/cli/commands/interactive.command.d.ts +0 -3
- package/dist/cli/commands/interactive.command.js.map +0 -1
- package/dist/cli/commands/padron.command.d.ts +0 -2
- package/dist/cli/commands/padron.command.js.map +0 -1
- package/dist/cli/commands/parameters.command.d.ts +0 -2
- package/dist/cli/commands/parameters.command.js.map +0 -1
- package/dist/cli/commands/pdf.command.d.ts +0 -2
- package/dist/cli/commands/pdf.command.js.map +0 -1
- package/dist/cli/commands/storybook.command.d.ts +0 -2
- package/dist/cli/commands/storybook.command.js.map +0 -1
- package/dist/cli/commands/vouchers.command.d.ts +0 -2
- package/dist/cli/commands/vouchers.command.js.map +0 -1
- package/dist/cli/error-output.d.ts +0 -25
- package/dist/cli/error-output.js.map +0 -1
- package/dist/cli/global-options.d.ts +0 -26
- package/dist/cli/global-options.js.map +0 -1
- package/dist/cli/help-argv.d.ts +0 -5
- package/dist/cli/help-argv.js.map +0 -1
- package/dist/cli/help.d.ts +0 -14
- package/dist/cli/help.js.map +0 -1
- package/dist/cli/ignored-global-options.d.ts +0 -6
- package/dist/cli/ignored-global-options.js.map +0 -1
- package/dist/cli/index.d.ts +0 -2
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/interactive/advanced-options.d.ts +0 -21
- package/dist/cli/interactive/advanced-options.js.map +0 -1
- package/dist/cli/interactive/config.flow.d.ts +0 -4
- package/dist/cli/interactive/config.flow.js.map +0 -1
- package/dist/cli/interactive/history.flow.d.ts +0 -6
- package/dist/cli/interactive/history.flow.js.map +0 -1
- package/dist/cli/interactive/interactive-mode.d.ts +0 -3
- package/dist/cli/interactive/interactive-mode.js.map +0 -1
- package/dist/cli/interactive/invoice-picker.d.ts +0 -25
- package/dist/cli/interactive/invoice-picker.js.map +0 -1
- package/dist/cli/interactive/invoice.flow.d.ts +0 -22
- package/dist/cli/interactive/invoice.flow.js.map +0 -1
- package/dist/cli/interactive/note.flow.d.ts +0 -34
- package/dist/cli/interactive/note.flow.js.map +0 -1
- package/dist/cli/interactive/pdf.flow.d.ts +0 -5
- package/dist/cli/interactive/pdf.flow.js.map +0 -1
- package/dist/cli/interactive/prompts.d.ts +0 -57
- package/dist/cli/interactive/prompts.js.map +0 -1
- package/dist/cli/interactive/receiver-padron.d.ts +0 -29
- package/dist/cli/interactive/receiver-padron.js.map +0 -1
- package/dist/cli/interactive/repeat.flow.d.ts +0 -13
- package/dist/cli/interactive/repeat.flow.js.map +0 -1
- package/dist/cli/interactive/session.d.ts +0 -22
- package/dist/cli/interactive/session.js.map +0 -1
- package/dist/cli/interactive/status.flow.d.ts +0 -3
- package/dist/cli/interactive/status.flow.js.map +0 -1
- package/dist/cli/interactive/update.flow.d.ts +0 -6
- package/dist/cli/interactive/update.flow.js.map +0 -1
- package/dist/cli/interactive/validators.d.ts +0 -9
- package/dist/cli/interactive/validators.js.map +0 -1
- package/dist/cli/option-parsers.d.ts +0 -6
- package/dist/cli/option-parsers.js.map +0 -1
- package/dist/cli/program.d.ts +0 -6
- package/dist/cli/program.js.map +0 -1
- package/dist/cli/spinner.d.ts +0 -8
- package/dist/cli/spinner.js.map +0 -1
- package/dist/cli/types.d.ts +0 -6
- package/dist/cli/types.js.map +0 -1
- package/dist/cli/version.d.ts +0 -1
- package/dist/cli/version.js.map +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/dates/arca-date.d.ts +0 -19
- package/dist/lib/dates/arca-date.js.map +0 -1
- package/dist/lib/errors/app-error.d.ts +0 -17
- package/dist/lib/errors/app-error.js.map +0 -1
- package/dist/lib/files/read-json-file.d.ts +0 -1
- package/dist/lib/files/read-json-file.js.map +0 -1
- package/dist/lib/files/restrict-to-owner.d.ts +0 -7
- package/dist/lib/files/restrict-to-owner.js.map +0 -1
- package/dist/lib/files/write-new-file.d.ts +0 -5
- package/dist/lib/files/write-new-file.js.map +0 -1
- package/dist/lib/identity/format-cuit.d.ts +0 -2
- package/dist/lib/identity/format-cuit.js.map +0 -1
- package/dist/lib/links.d.ts +0 -4
- package/dist/lib/links.js.map +0 -1
- package/dist/lib/numbers/argentine-amount.d.ts +0 -23
- package/dist/lib/numbers/argentine-amount.js.map +0 -1
- package/dist/lib/numbers/strict-integer.d.ts +0 -4
- package/dist/lib/numbers/strict-integer.js.map +0 -1
- package/dist/lib/paths/mask-path.d.ts +0 -1
- package/dist/lib/paths/mask-path.js.map +0 -1
- package/dist/lib/security/certificate.d.ts +0 -11
- package/dist/lib/security/certificate.js.map +0 -1
- package/dist/lib/security/pem.d.ts +0 -5
- package/dist/lib/security/pem.js.map +0 -1
- package/dist/modules/billing/billing-response.d.ts +0 -4
- package/dist/modules/billing/billing-response.js.map +0 -1
- package/dist/modules/billing/billing.amounts.d.ts +0 -21
- package/dist/modules/billing/billing.amounts.js.map +0 -1
- package/dist/modules/billing/billing.associated-period.d.ts +0 -8
- package/dist/modules/billing/billing.associated-period.js.map +0 -1
- package/dist/modules/billing/billing.associated-vouchers.d.ts +0 -12
- package/dist/modules/billing/billing.associated-vouchers.js.map +0 -1
- package/dist/modules/billing/billing.batch.d.ts +0 -23
- package/dist/modules/billing/billing.batch.js.map +0 -1
- package/dist/modules/billing/billing.constants.d.ts +0 -2
- package/dist/modules/billing/billing.constants.js.map +0 -1
- package/dist/modules/billing/billing.currency.d.ts +0 -18
- package/dist/modules/billing/billing.currency.js.map +0 -1
- package/dist/modules/billing/billing.date-range.d.ts +0 -9
- package/dist/modules/billing/billing.date-range.js.map +0 -1
- package/dist/modules/billing/billing.display.d.ts +0 -13
- package/dist/modules/billing/billing.display.js.map +0 -1
- package/dist/modules/billing/billing.errors.d.ts +0 -12
- package/dist/modules/billing/billing.errors.js.map +0 -1
- package/dist/modules/billing/billing.fce.d.ts +0 -21
- package/dist/modules/billing/billing.fce.js.map +0 -1
- package/dist/modules/billing/billing.iva-receptor.d.ts +0 -8
- package/dist/modules/billing/billing.iva-receptor.js.map +0 -1
- package/dist/modules/billing/billing.json-format.d.ts +0 -6
- package/dist/modules/billing/billing.json-format.js.map +0 -1
- package/dist/modules/billing/billing.json-input.d.ts +0 -58
- package/dist/modules/billing/billing.json-input.js.map +0 -1
- package/dist/modules/billing/billing.labels.d.ts +0 -9
- package/dist/modules/billing/billing.labels.js.map +0 -1
- package/dist/modules/billing/billing.mappers.d.ts +0 -8
- package/dist/modules/billing/billing.mappers.js.map +0 -1
- package/dist/modules/billing/billing.padron.d.ts +0 -14
- package/dist/modules/billing/billing.padron.js.map +0 -1
- package/dist/modules/billing/billing.presenter.d.ts +0 -7
- package/dist/modules/billing/billing.presenter.js.map +0 -1
- package/dist/modules/billing/billing.schemas.d.ts +0 -147
- package/dist/modules/billing/billing.schemas.js.map +0 -1
- package/dist/modules/billing/billing.serialize.d.ts +0 -9
- package/dist/modules/billing/billing.serialize.js.map +0 -1
- package/dist/modules/billing/billing.service.d.ts +0 -30
- package/dist/modules/billing/billing.service.js.map +0 -1
- package/dist/modules/billing/billing.text.d.ts +0 -8
- package/dist/modules/billing/billing.text.js.map +0 -1
- package/dist/modules/billing/billing.types.d.ts +0 -13
- package/dist/modules/billing/billing.types.internal.d.ts +0 -38
- package/dist/modules/billing/billing.types.internal.js.map +0 -1
- package/dist/modules/billing/billing.types.js.map +0 -1
- package/dist/modules/billing/billing.validation.d.ts +0 -7
- package/dist/modules/billing/billing.validation.js.map +0 -1
- package/dist/modules/billing/voucher-kind-map.d.ts +0 -9
- package/dist/modules/billing/voucher-kind-map.js.map +0 -1
- package/dist/modules/config/certificate-expiry.d.ts +0 -42
- package/dist/modules/config/certificate-expiry.js.map +0 -1
- package/dist/modules/config/config-doctor.d.ts +0 -16
- package/dist/modules/config/config-doctor.js.map +0 -1
- package/dist/modules/config/config-value-parser.d.ts +0 -2
- package/dist/modules/config/config-value-parser.js.map +0 -1
- package/dist/modules/config/config.presenter.d.ts +0 -17
- package/dist/modules/config/config.presenter.js.map +0 -1
- package/dist/modules/config/config.schemas.d.ts +0 -156
- package/dist/modules/config/config.schemas.js.map +0 -1
- package/dist/modules/config/config.sections.d.ts +0 -14
- package/dist/modules/config/config.sections.js.map +0 -1
- package/dist/modules/config/config.service.d.ts +0 -35
- package/dist/modules/config/config.service.js.map +0 -1
- package/dist/modules/examples/examples.d.ts +0 -6
- package/dist/modules/examples/examples.js.map +0 -1
- package/dist/modules/fce/fce-obligation.d.ts +0 -20
- package/dist/modules/fce/fce-obligation.js.map +0 -1
- package/dist/modules/fce/fce-obligation.presenter.d.ts +0 -9
- package/dist/modules/fce/fce-obligation.presenter.js.map +0 -1
- package/dist/modules/interactive/amount-input.d.ts +0 -4
- package/dist/modules/interactive/amount-input.js.map +0 -1
- package/dist/modules/interactive/choices.d.ts +0 -13
- package/dist/modules/interactive/choices.js.map +0 -1
- package/dist/modules/interactive/config-fields.d.ts +0 -20
- package/dist/modules/interactive/config-fields.js.map +0 -1
- package/dist/modules/interactive/equivalent-command.d.ts +0 -8
- package/dist/modules/interactive/equivalent-command.js.map +0 -1
- package/dist/modules/interactive/invoice-copy.d.ts +0 -19
- package/dist/modules/interactive/invoice-copy.js.map +0 -1
- package/dist/modules/interactive/periods.d.ts +0 -7
- package/dist/modules/interactive/periods.js.map +0 -1
- package/dist/modules/interactive/wizard.d.ts +0 -16
- package/dist/modules/interactive/wizard.js.map +0 -1
- package/dist/modules/padron/padron.d.ts +0 -46
- package/dist/modules/padron/padron.js.map +0 -1
- package/dist/modules/padron/padron.presenter.d.ts +0 -7
- package/dist/modules/padron/padron.presenter.js.map +0 -1
- package/dist/modules/parameters/health.d.ts +0 -17
- package/dist/modules/parameters/health.js.map +0 -1
- package/dist/modules/parameters/parameters.d.ts +0 -50
- package/dist/modules/parameters/parameters.js.map +0 -1
- package/dist/modules/parameters/parameters.presenter.d.ts +0 -12
- package/dist/modules/parameters/parameters.presenter.js.map +0 -1
- package/dist/modules/parameters/status.d.ts +0 -31
- package/dist/modules/parameters/status.js.map +0 -1
- package/dist/modules/pdf/pdf-data.mapper.d.ts +0 -4
- package/dist/modules/pdf/pdf-data.mapper.js.map +0 -1
- package/dist/modules/pdf/pdf-decision.d.ts +0 -14
- package/dist/modules/pdf/pdf-decision.js.map +0 -1
- package/dist/modules/pdf/pdf-file-name.d.ts +0 -3
- package/dist/modules/pdf/pdf-file-name.js.map +0 -1
- package/dist/modules/pdf/pdf-issuer.d.ts +0 -8
- package/dist/modules/pdf/pdf-issuer.js.map +0 -1
- package/dist/modules/pdf/pdf.errors.d.ts +0 -9
- package/dist/modules/pdf/pdf.errors.js.map +0 -1
- package/dist/modules/pdf/pdf.types.d.ts +0 -91
- package/dist/modules/pdf/pdf.types.js.map +0 -1
- package/dist/modules/storybook/showcase-theme.d.ts +0 -7
- package/dist/modules/storybook/showcase-theme.js.map +0 -1
- package/dist/modules/storybook/showcase.d.ts +0 -2
- package/dist/modules/storybook/showcase.js.map +0 -1
- package/dist/modules/update-check/changelog.d.ts +0 -23
- package/dist/modules/update-check/changelog.js.map +0 -1
- package/dist/modules/update-check/update-check.presenter.d.ts +0 -6
- package/dist/modules/update-check/update-check.presenter.js.map +0 -1
- package/dist/modules/update-check/update-check.service.d.ts +0 -11
- package/dist/modules/update-check/update-check.service.js.map +0 -1
- package/dist/modules/vouchers/voucher-history.d.ts +0 -39
- package/dist/modules/vouchers/voucher-history.js.map +0 -1
- package/dist/modules/vouchers/voucher-history.presenter.d.ts +0 -29
- package/dist/modules/vouchers/voucher-history.presenter.js.map +0 -1
- package/dist/services/arca/arca-billing.gateway.d.ts +0 -16
- package/dist/services/arca/arca-billing.gateway.js.map +0 -1
- package/dist/services/arca/arca-client.factory.d.ts +0 -6
- package/dist/services/arca/arca-client.factory.js.map +0 -1
- package/dist/services/arca/arca-context.resolver.d.ts +0 -55
- package/dist/services/arca/arca-context.resolver.js.map +0 -1
- package/dist/services/arca/arca-fce-obligation.gateway.d.ts +0 -7
- package/dist/services/arca/arca-fce-obligation.gateway.js.map +0 -1
- package/dist/services/arca/arca-padron.gateway.d.ts +0 -9
- package/dist/services/arca/arca-padron.gateway.js.map +0 -1
- package/dist/services/arca/arca-parameters.gateway.d.ts +0 -10
- package/dist/services/arca/arca-parameters.gateway.js.map +0 -1
- package/dist/services/arca/arca-voucher-history.gateway.d.ts +0 -8
- package/dist/services/arca/arca-voucher-history.gateway.js.map +0 -1
- package/dist/services/clipboard/clipboard.d.ts +0 -2
- package/dist/services/clipboard/clipboard.js.map +0 -1
- package/dist/services/pdf/escape-html.d.ts +0 -6
- package/dist/services/pdf/escape-html.js.map +0 -1
- package/dist/services/pdf/pdf-browser.d.ts +0 -5
- package/dist/services/pdf/pdf-browser.js.map +0 -1
- package/dist/services/pdf/pdf-exporter.d.ts +0 -22
- package/dist/services/pdf/pdf-exporter.js.map +0 -1
- package/dist/services/pdf/pdf-plugin.d.ts +0 -50
- package/dist/services/pdf/pdf-plugin.js.map +0 -1
- package/dist/ui/components/certificateBanner.d.ts +0 -11
- package/dist/ui/components/certificateBanner.js.map +0 -1
- package/dist/ui/components/contentPanel.d.ts +0 -5
- package/dist/ui/components/contentPanel.js.map +0 -1
- package/dist/ui/components/errorPanel.d.ts +0 -1
- package/dist/ui/components/errorPanel.js.map +0 -1
- package/dist/ui/components/index.d.ts +0 -10
- package/dist/ui/components/index.js.map +0 -1
- package/dist/ui/components/keyValuePanel.d.ts +0 -3
- package/dist/ui/components/keyValuePanel.js.map +0 -1
- package/dist/ui/components/noticePanel.d.ts +0 -3
- package/dist/ui/components/noticePanel.js.map +0 -1
- package/dist/ui/components/rawPanel.d.ts +0 -1
- package/dist/ui/components/rawPanel.js.map +0 -1
- package/dist/ui/components/sectionHeading.d.ts +0 -3
- package/dist/ui/components/sectionHeading.js.map +0 -1
- package/dist/ui/components/statusBar.d.ts +0 -19
- package/dist/ui/components/statusBar.js.map +0 -1
- package/dist/ui/components/statusPanel.d.ts +0 -3
- package/dist/ui/components/statusPanel.js.map +0 -1
- package/dist/ui/components/testingBanner.d.ts +0 -2
- package/dist/ui/components/testingBanner.js.map +0 -1
- package/dist/ui/index.d.ts +0 -5
- package/dist/ui/index.js.map +0 -1
- package/dist/ui/presenters/billing.presenter.d.ts +0 -2
- package/dist/ui/presenters/billing.presenter.js.map +0 -1
- package/dist/ui/presenters/config.presenter.d.ts +0 -1
- package/dist/ui/presenters/config.presenter.js.map +0 -1
- package/dist/ui/presenters/errors.presenter.d.ts +0 -1
- package/dist/ui/presenters/errors.presenter.js.map +0 -1
- package/dist/ui/presenters/errors.zod-presenter.d.ts +0 -4
- package/dist/ui/presenters/errors.zod-presenter.js.map +0 -1
- package/dist/ui/presenters/index.d.ts +0 -6
- package/dist/ui/presenters/index.js.map +0 -1
- package/dist/ui/presenters/pdf.presenter.d.ts +0 -13
- package/dist/ui/presenters/pdf.presenter.js.map +0 -1
- package/dist/ui/presenters/showcase.presenter.d.ts +0 -1
- package/dist/ui/presenters/showcase.presenter.js.map +0 -1
- package/dist/ui/primitives/index.d.ts +0 -10
- package/dist/ui/primitives/index.js.map +0 -1
- package/dist/ui/primitives/renderDivider.d.ts +0 -5
- package/dist/ui/primitives/renderDivider.js.map +0 -1
- package/dist/ui/primitives/renderFooter.d.ts +0 -7
- package/dist/ui/primitives/renderFooter.js.map +0 -1
- package/dist/ui/primitives/renderJson.d.ts +0 -3
- package/dist/ui/primitives/renderJson.js.map +0 -1
- package/dist/ui/primitives/renderKeyValue.d.ts +0 -14
- package/dist/ui/primitives/renderKeyValue.js.map +0 -1
- package/dist/ui/primitives/renderLogo.d.ts +0 -3
- package/dist/ui/primitives/renderLogo.js.map +0 -1
- package/dist/ui/primitives/renderObject.d.ts +0 -1
- package/dist/ui/primitives/renderObject.js.map +0 -1
- package/dist/ui/primitives/renderPanel.d.ts +0 -27
- package/dist/ui/primitives/renderPanel.js.map +0 -1
- package/dist/ui/primitives/renderSubtitle.d.ts +0 -7
- package/dist/ui/primitives/renderSubtitle.js.map +0 -1
- package/dist/ui/primitives/renderTable.d.ts +0 -6
- package/dist/ui/primitives/renderTable.js.map +0 -1
- package/dist/ui/primitives/terminalWidth.d.ts +0 -4
- package/dist/ui/primitives/terminalWidth.js.map +0 -1
- package/dist/ui/primitives/text.d.ts +0 -28
- package/dist/ui/primitives/text.js.map +0 -1
- package/dist/ui/stream/index.d.ts +0 -1
- package/dist/ui/stream/index.js.map +0 -1
- package/dist/ui/stream/terminal-stream.d.ts +0 -21
- package/dist/ui/stream/terminal-stream.js.map +0 -1
- package/dist/ui/theme/index.d.ts +0 -1
- package/dist/ui/theme/index.js.map +0 -1
- package/dist/ui/theme/theme.d.ts +0 -68
- package/dist/ui/theme/theme.js.map +0 -1
|
@@ -18,7 +18,7 @@ export function formatReceiver(voucher) {
|
|
|
18
18
|
}
|
|
19
19
|
/** Titulo del listado de ultimos comprobantes, tambien usado por el selector del modo interactivo. */
|
|
20
20
|
export function formatVoucherListTitle(report) {
|
|
21
|
-
return
|
|
21
|
+
return `Últimas ${report.voucherKind.displayName} · PV ${report.pointOfSale} · ${report.environment}`;
|
|
22
22
|
}
|
|
23
23
|
/** Una fila del listado: numero, fecha, receptor, total y CAE, en columnas alineadas. */
|
|
24
24
|
export function formatVoucherListRow(pointOfSale, voucher) {
|
|
@@ -121,14 +121,14 @@ export function formatVoucherDetailAsJson(report) {
|
|
|
121
121
|
export function formatVoucherDetailAsText(report) {
|
|
122
122
|
const { pointOfSale, voucher, voucherKind } = report;
|
|
123
123
|
const rows = [
|
|
124
|
-
['
|
|
124
|
+
['Número', formatVoucherNumber(pointOfSale, voucher.number)],
|
|
125
125
|
['Fecha', formatArcaDateAsArgentineDate(voucher.date)],
|
|
126
126
|
['Receptor', formatReceiver(voucher)],
|
|
127
127
|
['Concepto', formatConceptLabel(voucher.concept)],
|
|
128
128
|
['Moneda', formatCurrencyLabel(voucher.currency)],
|
|
129
129
|
];
|
|
130
130
|
if (voucher.currency && voucher.currency !== 'PES') {
|
|
131
|
-
rows.push(['
|
|
131
|
+
rows.push(['Cotización', String(voucher.exchangeRate ?? 1)]);
|
|
132
132
|
}
|
|
133
133
|
rows.push(['Importe neto', formatMoneyLabel(voucher.netAmount)], ['Importe IVA', formatMoneyLabel(voucher.ivaAmount)]);
|
|
134
134
|
if (voucher.exemptAmount)
|
|
@@ -143,4 +143,3 @@ export function formatVoucherDetailAsText(report) {
|
|
|
143
143
|
}
|
|
144
144
|
return keyValuePanel(voucherKind.displayName, renderKeyValueRows(rows, { labelWidth: resolveKeyValueLabelWidth('ticket', rows) }), voucher.result === 'A' ? 'APROBADO' : voucher.result === 'R' ? 'RECHAZADO' : undefined, 'ticket', voucher.result === 'R' ? 'danger' : 'success', 'ticket');
|
|
145
145
|
}
|
|
146
|
-
//# sourceMappingURL=voucher-history.presenter.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AppError } from '../../lib/errors/app-error.js';
|
|
2
|
+
import { getLastAuthorizedNumber } from './last-voucher.js';
|
|
2
3
|
/** Tope de numeracion de ARCA; el SDK lo valida igual en `createNextVoucher`. */
|
|
3
4
|
const MAX_VOUCHER_NUMBER = 99_999_999;
|
|
4
5
|
export class ArcaBillingGateway {
|
|
@@ -11,10 +12,9 @@ export class ArcaBillingGateway {
|
|
|
11
12
|
* Si falla, no se envio nada a ARCA. Como el SDK, sin comprobantes previos arranca en 1.
|
|
12
13
|
*/
|
|
13
14
|
async getNextVoucherNumber(pointOfSale, voucherType) {
|
|
14
|
-
const
|
|
15
|
-
const nextNumber = (lastVoucher.cbteNro || 0) + 1;
|
|
15
|
+
const nextNumber = (await getLastAuthorizedNumber(this.arca, pointOfSale, voucherType)) + 1;
|
|
16
16
|
if (nextNumber > MAX_VOUCHER_NUMBER) {
|
|
17
|
-
throw new Error(`
|
|
17
|
+
throw new Error(`Número de comprobante no puede ser mayor a ${MAX_VOUCHER_NUMBER}`);
|
|
18
18
|
}
|
|
19
19
|
return nextNumber;
|
|
20
20
|
}
|
|
@@ -26,7 +26,7 @@ export class ArcaBillingGateway {
|
|
|
26
26
|
const result = await this.arca.electronicBillingService.getQuotation(currencyCode);
|
|
27
27
|
const exchangeRate = result.resultGet?.monCotiz;
|
|
28
28
|
if (typeof exchangeRate !== 'number' || exchangeRate <= 0) {
|
|
29
|
-
throw new AppError(`ARCA no
|
|
29
|
+
throw new AppError(`ARCA no devolvió una cotización válida para ${currencyCode}.`, {
|
|
30
30
|
code: 'ARCA_QUOTATION_ERROR',
|
|
31
31
|
details: { errors: result.errors },
|
|
32
32
|
});
|
|
@@ -34,4 +34,3 @@ export class ArcaBillingGateway {
|
|
|
34
34
|
return exchangeRate;
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
|
-
//# sourceMappingURL=arca-billing.gateway.js.map
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Arca } from '@arcasdk/core';
|
|
2
|
-
import {
|
|
2
|
+
import { readPemFile } from '../../lib/security/pem.js';
|
|
3
|
+
import { CertificateExpiredError, inspectCertificateExpiry } from '../../modules/config/certificate-expiry.js';
|
|
4
|
+
import { resolveExportCredentials } from '../../modules/config/config.export-credentials.js';
|
|
3
5
|
export class ArcaClientFactory {
|
|
4
6
|
/** Todo cliente de ARCA sale de aca: con el certificado vencido se corta antes de pedir el ticket a WSAA. */
|
|
5
7
|
create(runtime) {
|
|
@@ -8,5 +10,24 @@ export class ArcaClientFactory {
|
|
|
8
10
|
}
|
|
9
11
|
return new Arca(runtime.context);
|
|
10
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* WSFEX se autentica con el certificado autorizado al servicio wsfex. Si `exportacion.cert`/`exportacion.key`
|
|
15
|
+
* estan configurados usa esos archivos (y su propio vencimiento); si no, los mismos de facturacion.
|
|
16
|
+
*/
|
|
17
|
+
createForExport(runtime) {
|
|
18
|
+
const credentials = resolveExportCredentials(runtime.config, runtime.environment);
|
|
19
|
+
if (!credentials.dedicated) {
|
|
20
|
+
return this.create(runtime);
|
|
21
|
+
}
|
|
22
|
+
const cert = readPemFile(credentials.cert, 'certificado');
|
|
23
|
+
const notice = inspectCertificateExpiry(cert, runtime.environment);
|
|
24
|
+
if (notice?.expired) {
|
|
25
|
+
throw new CertificateExpiredError(notice);
|
|
26
|
+
}
|
|
27
|
+
return new Arca({
|
|
28
|
+
...runtime.context,
|
|
29
|
+
cert,
|
|
30
|
+
key: readPemFile(credentials.key, 'clave privada'),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
11
33
|
}
|
|
12
|
-
//# sourceMappingURL=arca-client.factory.js.map
|
|
@@ -83,17 +83,17 @@ export class ArcaContextResolver {
|
|
|
83
83
|
resolveCuit(config) {
|
|
84
84
|
const rawValue = config.cuit;
|
|
85
85
|
if (!rawValue) {
|
|
86
|
-
throw new ConfigurationError('Falta el CUIT.
|
|
86
|
+
throw new ConfigurationError('Falta el CUIT. Configuralo con "arcli config establecer cuit <valor>". Si querés una guía rápida, usá "arcli config revisar".');
|
|
87
87
|
}
|
|
88
88
|
const parsedValue = Number.parseInt(rawValue, 10);
|
|
89
89
|
if (!Number.isInteger(parsedValue) || rawValue.length !== 11) {
|
|
90
|
-
throw new ConfigurationError(`El CUIT "${rawValue}" no es
|
|
90
|
+
throw new ConfigurationError(`El CUIT "${rawValue}" no es válido. Debe tener 11 digitos.`);
|
|
91
91
|
}
|
|
92
92
|
return parsedValue;
|
|
93
93
|
}
|
|
94
94
|
resolveEnvironment(config) {
|
|
95
95
|
if (this.options.testing && this.options.produccion) {
|
|
96
|
-
throw new ConfigurationError('
|
|
96
|
+
throw new ConfigurationError('Usá --testing o --produccion, pero no ambos a la vez.');
|
|
97
97
|
}
|
|
98
98
|
if (this.options.testing) {
|
|
99
99
|
return 'testing';
|
|
@@ -121,16 +121,15 @@ export class ArcaContextResolver {
|
|
|
121
121
|
resolveCertificatePath(config, environment) {
|
|
122
122
|
const filePath = config.cert[environment];
|
|
123
123
|
if (!filePath) {
|
|
124
|
-
throw new ConfigurationError(`Falta la ruta del certificado para ${environment}.
|
|
124
|
+
throw new ConfigurationError(`Falta la ruta del certificado para ${environment}. Configurá "cert.${environment}". Si necesitás ayuda, probá "arcli config revisar".`);
|
|
125
125
|
}
|
|
126
126
|
return filePath;
|
|
127
127
|
}
|
|
128
128
|
resolveKeyPath(config, environment) {
|
|
129
129
|
const filePath = config.key[environment];
|
|
130
130
|
if (!filePath) {
|
|
131
|
-
throw new ConfigurationError(`Falta la ruta de la clave privada para ${environment}.
|
|
131
|
+
throw new ConfigurationError(`Falta la ruta de la clave privada para ${environment}. Configurá "key.${environment}". Si necesitás ayuda, probá "arcli config revisar".`);
|
|
132
132
|
}
|
|
133
133
|
return filePath;
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
-
//# sourceMappingURL=arca-context.resolver.js.map
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { formatArcaDateAsArgentineDate } from '../../lib/dates/arca-date.js';
|
|
2
|
+
import { AppError } from '../../lib/errors/app-error.js';
|
|
3
|
+
const NOT_AUTHORIZED_MESSAGE = 'El certificado no está autorizado para el servicio wsfex (factura de exportación). Autorizalo igual que wsfe: en testing desde WSASS ("Crear autorización a servicio") y en producción desde el Administrador de Relaciones.';
|
|
4
|
+
/** El XML de ARCA a veces trae un solo elemento donde el WSDL promete un array. */
|
|
5
|
+
function asArray(value) {
|
|
6
|
+
if (value === undefined || value === null) {
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
return Array.isArray(value) ? value : [value];
|
|
10
|
+
}
|
|
11
|
+
function readText(value) {
|
|
12
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* La fecha de la cotizacion viene como `dd/mm/yyyy`; el resto del modulo trabaja con fechas ARCA (`yyyymmdd`).
|
|
16
|
+
* Si ARCA no la informa se descarta: la cotizacion igual sirve.
|
|
17
|
+
*/
|
|
18
|
+
function parseWsfexQuotationDate(value) {
|
|
19
|
+
const match = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/.exec(value);
|
|
20
|
+
return match ? `${match[3]}${match[2].padStart(2, '0')}${match[1].padStart(2, '0')}` : undefined;
|
|
21
|
+
}
|
|
22
|
+
/** WSFEX no lanza: devuelve `FEXErr` con codigo 0 cuando salio todo bien. */
|
|
23
|
+
function assertNoError(result, operation) {
|
|
24
|
+
const error = result?.FEXErr;
|
|
25
|
+
if (error?.ErrCode) {
|
|
26
|
+
throw new AppError(`ARCA devolvió un error al consultar ${operation}: ${readText(error.ErrMsg) || error.ErrCode}`, {
|
|
27
|
+
code: 'ARCA_EXPORT_ERROR',
|
|
28
|
+
details: { errores: [{ codigo: error.ErrCode, mensaje: readText(error.ErrMsg) }] },
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export class ArcaExportGateway {
|
|
33
|
+
arca;
|
|
34
|
+
constructor(arca) {
|
|
35
|
+
this.arca = arca;
|
|
36
|
+
}
|
|
37
|
+
/** Todas las llamadas autentican en WSAA: si el certificado no esta autorizado a wsfex, el error lo dice. */
|
|
38
|
+
async call(request) {
|
|
39
|
+
try {
|
|
40
|
+
return await request(this.arca.wsfexService);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error instanceof Error && error.message.includes('notAuthorized')) {
|
|
44
|
+
throw new AppError(NOT_AUTHORIZED_MESSAGE, { code: 'WSFEX_SERVICE_NOT_AUTHORIZED' });
|
|
45
|
+
}
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* La unica llamada que emite. Un rechazo viene en `FEXResultAuth`, no como excepcion.
|
|
51
|
+
*
|
|
52
|
+
* El WSDL tipa `Permisos` como obligatorio, pero ARCA lo rechaza cuando `Permiso_existente` es `N` (error
|
|
53
|
+
* 1720) y en los tipos de exportacion 2 y 4 pide ese campo vacio (error 1550): sin permisos el `Cmp` no trae la
|
|
54
|
+
* clave y el serializador de SOAP omite los campos ausentes.
|
|
55
|
+
*/
|
|
56
|
+
async authorize(payload) {
|
|
57
|
+
return this.call((service) => service.authorize({ Cmp: payload }));
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* La tabla de actividades de WSFEX es propia: tiene menos codigos que la del padron y el `Cmp` solo acepta los
|
|
61
|
+
* suyos. El WSDL no la tipa (devuelve `ClsFEXResponse_ActividadTipo`), asi que se lee como array tolerante.
|
|
62
|
+
*/
|
|
63
|
+
async getActivities() {
|
|
64
|
+
const data = (await this.call((service) => service.getParamActividades({}))).FEXGetPARAM_ActividadesResult;
|
|
65
|
+
assertNoError(data, 'las actividades');
|
|
66
|
+
const rows = data?.FEXResultGet
|
|
67
|
+
?.ClsFEXResponse_ActividadTipo;
|
|
68
|
+
return asArray(rows).flatMap((row) => {
|
|
69
|
+
const id = Number(row?.Id);
|
|
70
|
+
const name = readText(row?.Desc);
|
|
71
|
+
return Number.isInteger(id) && id > 0 ? [{ id, name }] : [];
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async getCurrencies() {
|
|
75
|
+
const data = (await this.call((service) => service.getParamMon({}))).FEXGetPARAM_MONResult;
|
|
76
|
+
assertNoError(data, 'las monedas');
|
|
77
|
+
return asArray(data?.FEXResultGet?.ClsFEXResponse_Mon).flatMap((row) => {
|
|
78
|
+
const code = readText(row.Mon_Id);
|
|
79
|
+
return code ? [{ code, name: readText(row.Mon_Ds) }] : [];
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async getDestinationCountries() {
|
|
83
|
+
const data = (await this.call((service) => service.getParamDstPais({}))).FEXGetPARAM_DST_paisResult;
|
|
84
|
+
assertNoError(data, 'los países de destino');
|
|
85
|
+
return asArray(data?.FEXResultGet?.ClsFEXResponse_DST_pais).flatMap((row) => {
|
|
86
|
+
const code = Number(row.DST_Codigo);
|
|
87
|
+
const name = readText(row.DST_Ds);
|
|
88
|
+
return Number.isInteger(code) && name ? [{ code, name }] : [];
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
async getDestinationCountryCuits() {
|
|
92
|
+
const data = (await this.call((service) => service.getParamDstCuit({}))).FEXGetPARAM_DST_CUITResult;
|
|
93
|
+
assertNoError(data, 'los CUIT de países');
|
|
94
|
+
return asArray(data?.FEXResultGet?.ClsFEXResponse_DST_cuit).flatMap((row) => {
|
|
95
|
+
const cuit = Number(row.DST_CUIT);
|
|
96
|
+
const countryName = readText(row.DST_Ds);
|
|
97
|
+
return Number.isInteger(cuit) && countryName ? [{ countryName, cuit }] : [];
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
async getIncoterms() {
|
|
101
|
+
const data = (await this.call((service) => service.getParamIncoterms({}))).FEXGetPARAM_IncotermsResult;
|
|
102
|
+
assertNoError(data, 'los incoterms');
|
|
103
|
+
return asArray(data?.FEXResultGet?.ClsFEXResponse_Inc).flatMap((row) => {
|
|
104
|
+
const code = readText(row.Inc_Id);
|
|
105
|
+
return code ? [{ code, name: readText(row.Inc_Ds) }] : [];
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
async getLanguages() {
|
|
109
|
+
const data = (await this.call((service) => service.getParamIdiomas({}))).FEXGetPARAM_IdiomasResult;
|
|
110
|
+
assertNoError(data, 'los idiomas');
|
|
111
|
+
return asArray(data?.FEXResultGet?.ClsFEXResponse_Idi).flatMap((row) => {
|
|
112
|
+
const id = Number(row.Idi_Id);
|
|
113
|
+
return Number.isInteger(id) ? [{ id, name: readText(row.Idi_Ds) }] : [];
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
async getUnits() {
|
|
117
|
+
const data = (await this.call((service) => service.getParamUMed({}))).FEXGetPARAM_UMedResult;
|
|
118
|
+
assertNoError(data, 'las unidades de medida');
|
|
119
|
+
return asArray(data?.FEXResultGet?.ClsFEXResponse_UMed).flatMap((row) => {
|
|
120
|
+
const id = Number(row.Umed_Id);
|
|
121
|
+
return Number.isInteger(id) ? [{ id, name: readText(row.Umed_Ds) }] : [];
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
async getLastRequestId() {
|
|
125
|
+
const data = (await this.call((service) => service.getLastId({}))).FEXGetLast_IDResult;
|
|
126
|
+
assertNoError(data, 'el último ID de solicitud');
|
|
127
|
+
return Number(data?.FEXResultGet?.Id) || 0;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* La cotizacion de la `E` es la de aduana, que WSFEX publica una vez por dia: `FEXGetPARAM_MON_CON_COTIZACION`
|
|
131
|
+
* devuelve por moneda la ultima publicada hasta `arcaDate`, con el dia al que corresponde. `Fecha_CTZ` va en
|
|
132
|
+
* `yyyymmdd`: con guiones ARCA contesta el error 2054.
|
|
133
|
+
*/
|
|
134
|
+
async getQuotations(arcaDate) {
|
|
135
|
+
const data = (await this.call((service) => service.getParamMonConCotizacion({ Fecha_CTZ: arcaDate })))
|
|
136
|
+
.FEXGetPARAM_MON_CON_COTIZACIONResult;
|
|
137
|
+
assertNoError(data, `las cotizaciones al ${formatArcaDateAsArgentineDate(arcaDate)}`);
|
|
138
|
+
return asArray(data?.FEXResultGet?.ClsFEXResponse_Mon_CON_Cotizacion).flatMap((row) => {
|
|
139
|
+
const code = readText(row.Mon_Id);
|
|
140
|
+
const rate = Number(row.Mon_ctz);
|
|
141
|
+
return code && Number.isFinite(rate) && rate > 0
|
|
142
|
+
? [{ code, date: parseWsfexQuotationDate(readText(row.Fecha_ctz)), rate }]
|
|
143
|
+
: [];
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AppError } from '../../lib/errors/app-error.js';
|
|
2
|
-
const NOT_AUTHORIZED_MESSAGE = 'El certificado no
|
|
2
|
+
const NOT_AUTHORIZED_MESSAGE = 'El certificado no está autorizado para el servicio wsfecred (Factura de Crédito Electrónica). Autorizalo igual que wsfe: en testing desde WSASS ("Crear autorizacion a servicio") y en producción desde el Administrador de Relaciones.';
|
|
3
3
|
function toIsoDate(arcaDate) {
|
|
4
4
|
return `${arcaDate.slice(0, 4)}-${arcaDate.slice(4, 6)}-${arcaDate.slice(6, 8)}`;
|
|
5
5
|
}
|
|
@@ -25,7 +25,7 @@ export class ArcaFceObligationGateway {
|
|
|
25
25
|
const result = output.consultarMontoObligadoRecepcionReturn;
|
|
26
26
|
const errors = result.arrayErrores?.codigoDescripcion ?? [];
|
|
27
27
|
if (errors.length > 0) {
|
|
28
|
-
throw new AppError(`ARCA no pudo informar si el receptor
|
|
28
|
+
throw new AppError(`ARCA no pudo informar si el receptor está obligado a FCE: ${errors.map((item) => `${item.codigo} ${item.descripcion}`).join('; ')}`, { code: 'FCE_OBLIGATION_ERROR', details: { errors } });
|
|
29
29
|
}
|
|
30
30
|
return {
|
|
31
31
|
minimumAmount: Number(result.montoDesde ?? 0),
|
|
@@ -33,4 +33,3 @@ export class ArcaFceObligationGateway {
|
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
//# sourceMappingURL=arca-fce-obligation.gateway.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AppError } from '../../lib/errors/app-error.js';
|
|
2
2
|
import { deriveIvaCondition, } from '../../modules/padron/padron.js';
|
|
3
|
-
const NOT_AUTHORIZED_MESSAGE = 'El certificado no
|
|
3
|
+
const NOT_AUTHORIZED_MESSAGE = 'El certificado no está autorizado para el servicio ws_sr_constancia_inscripcion (padrón). Autorizalo igual que wsfe: en testing desde WSASS ("Crear autorizacion a servicio") y en producción desde el Administrador de Relaciones.';
|
|
4
4
|
function asRecord(value) {
|
|
5
5
|
return value && typeof value === 'object' && !Array.isArray(value) ? value : undefined;
|
|
6
6
|
}
|
|
@@ -101,4 +101,3 @@ export class ArcaPadronGateway {
|
|
|
101
101
|
return details ? mapTaxpayerDetails(cuit, details) : null;
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
-
//# sourceMappingURL=arca-padron.gateway.js.map
|
|
@@ -5,7 +5,7 @@ const NO_RESULTS_CODE = 602;
|
|
|
5
5
|
function readRows(result, key, operation) {
|
|
6
6
|
const errors = result.errors?.err ?? [];
|
|
7
7
|
if (errors.some((error) => error.code !== NO_RESULTS_CODE)) {
|
|
8
|
-
throw new AppError(`ARCA
|
|
8
|
+
throw new AppError(`ARCA devolvió un error al consultar ${operation}: ${errors.map((e) => e.msg).join('; ')}`, {
|
|
9
9
|
code: 'ARCA_PARAMETERS_ERROR',
|
|
10
10
|
details: { errores: errors },
|
|
11
11
|
});
|
|
@@ -45,7 +45,7 @@ export class ArcaParametersGateway {
|
|
|
45
45
|
const result = await this.arca.electronicBillingService.getQuotation(code);
|
|
46
46
|
const rate = result.resultGet?.monCotiz;
|
|
47
47
|
if (typeof rate !== 'number' || rate <= 0) {
|
|
48
|
-
throw new AppError(`ARCA no
|
|
48
|
+
throw new AppError(`ARCA no devolvió una cotización para ${currency}.`, {
|
|
49
49
|
code: 'ARCA_QUOTATION_ERROR',
|
|
50
50
|
details: { errors: result.errors },
|
|
51
51
|
});
|
|
@@ -68,4 +68,3 @@ export class ArcaParametersGateway {
|
|
|
68
68
|
return readRows(result, key, table).map(toEntry);
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
-
//# sourceMappingURL=arca-parameters.gateway.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { getLastAuthorizedNumber } from './last-voucher.js';
|
|
1
2
|
export class ArcaVoucherHistoryGateway {
|
|
2
3
|
arca;
|
|
3
4
|
constructor(arca) {
|
|
4
5
|
this.arca = arca;
|
|
5
6
|
}
|
|
6
7
|
async getLastNumber(pointOfSale, voucherType) {
|
|
7
|
-
|
|
8
|
-
return result.cbteNro ?? 0;
|
|
8
|
+
return getLastAuthorizedNumber(this.arca, pointOfSale, voucherType);
|
|
9
9
|
}
|
|
10
10
|
async getVoucher(number, pointOfSale, voucherType) {
|
|
11
11
|
const info = await this.arca.electronicBillingService.getVoucherInfo(number, pointOfSale, voucherType);
|
|
@@ -33,4 +33,3 @@ export class ArcaVoucherHistoryGateway {
|
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
//# sourceMappingURL=arca-voucher-history.gateway.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { AppError } from '../../lib/errors/app-error.js';
|
|
2
|
+
import { POINT_OF_SALE_GUIDE_URL } from '../../lib/links.js';
|
|
3
|
+
/**
|
|
4
|
+
* WSFEv1 11002: el punto de venta no esta habilitado para el web service.
|
|
5
|
+
* 10005 es el mismo problema cuando ARCA lo informa al emitir.
|
|
6
|
+
*/
|
|
7
|
+
const POINT_OF_SALE_ERROR_CODES = new Set([10005, 11002]);
|
|
8
|
+
/**
|
|
9
|
+
* Pide el ultimo numero autorizado y corta si ARCA devolvio errores.
|
|
10
|
+
* El SDK los deja en `errors` y no lanza: sin este chequeo, un punto de venta invalido parece no tener comprobantes.
|
|
11
|
+
*/
|
|
12
|
+
export async function getLastAuthorizedNumber(arca, pointOfSale, voucherType) {
|
|
13
|
+
const result = await arca.electronicBillingService.getLastVoucher(pointOfSale, voucherType);
|
|
14
|
+
const errors = result.errors?.err ?? [];
|
|
15
|
+
if (errors.length > 0) {
|
|
16
|
+
const pointOfSaleProblem = errors.some((error) => POINT_OF_SALE_ERROR_CODES.has(error.code));
|
|
17
|
+
throw new AppError(`ARCA devolvió un error al pedir el último comprobante del punto de venta ${pointOfSale}: ${errors.map((error) => `${error.code} ${error.msg}`).join('; ')}`, {
|
|
18
|
+
code: 'ARCA_LAST_VOUCHER_ERROR',
|
|
19
|
+
details: { errores: errors },
|
|
20
|
+
suggestion: pointOfSaleProblem
|
|
21
|
+
? `El punto de venta no está habilitado para web service (los de "Factura en línea" no sirven). Revisá los habilitados con arcli parametros puntos-venta o creá uno para web service: ${POINT_OF_SALE_GUIDE_URL}`
|
|
22
|
+
: 'No se emitió nada. Revisá el mensaje de ARCA y reintentá.',
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
return result.cbteNro ?? 0;
|
|
26
|
+
}
|
|
@@ -3,7 +3,7 @@ import { extname, join } from 'node:path';
|
|
|
3
3
|
import { AppError } from '../../lib/errors/app-error.js';
|
|
4
4
|
import { writeNewFile } from '../../lib/files/write-new-file.js';
|
|
5
5
|
import { PdfError } from '../../modules/pdf/pdf.errors.js';
|
|
6
|
-
import { mapBillingResultToPdfData } from '../../modules/pdf/pdf-data.mapper.js';
|
|
6
|
+
import { mapBillingResultToPdfData, mapExportResultToPdfData } from '../../modules/pdf/pdf-data.mapper.js';
|
|
7
7
|
import { buildPdfFileName } from '../../modules/pdf/pdf-file-name.js';
|
|
8
8
|
import { resolvePdfIssuer } from '../../modules/pdf/pdf-issuer.js';
|
|
9
9
|
import { escapeHtmlStrings } from './escape-html.js';
|
|
@@ -47,4 +47,17 @@ export async function exportBillingPdf(input) {
|
|
|
47
47
|
mkdirSync(folder, { recursive: true });
|
|
48
48
|
return writeNewFile(join(folder, buildPdfFileName(result.voucherKind, data.puntoVenta, data.cbteDesde)), bytes);
|
|
49
49
|
}
|
|
50
|
-
|
|
50
|
+
/** Igual que `exportBillingPdf`, con el detalle real de WSFEX y el CUIT del pais del cliente. */
|
|
51
|
+
export async function exportExportacionPdf(input) {
|
|
52
|
+
const { result } = input;
|
|
53
|
+
const issuer = resolvePdfIssuer(input.config, result.voucherKind.letter);
|
|
54
|
+
const data = mapExportResultToPdfData(result, issuer, input.extras);
|
|
55
|
+
const options = {
|
|
56
|
+
footerText: result.environment === 'testing' ? TESTING_FOOTER : undefined,
|
|
57
|
+
logo: readLogoAsDataUrl(input.config.emisor.logo),
|
|
58
|
+
};
|
|
59
|
+
const bytes = await input.renderer.render(escapeHtmlStrings(data), options);
|
|
60
|
+
const folder = resolvePdfTargetFolder(input.folder, result.environment, issuer.cuit);
|
|
61
|
+
mkdirSync(folder, { recursive: true });
|
|
62
|
+
return writeNewFile(join(folder, buildPdfFileName(result.voucherKind, data.puntoVenta, data.cbteDesde)), bytes);
|
|
63
|
+
}
|
|
@@ -7,15 +7,33 @@ import { findDownloadedBrowser, findSystemBrowser } from './pdf-browser.js';
|
|
|
7
7
|
export const PDF_PLUGIN_PACKAGE = '@arcasdk/pdf';
|
|
8
8
|
/** Version probada con arcli. Se sube a mano despues de revisar los PDFs que genera. */
|
|
9
9
|
export const PDF_PLUGIN_VERSION = '0.2.1';
|
|
10
|
-
|
|
10
|
+
/** Limites de la instalacion: con un proxy colgado, npm o la descarga no terminan nunca. */
|
|
11
|
+
export const NPM_INSTALL_TIMEOUT_MS = 5 * 60_000;
|
|
12
|
+
export const BROWSER_DOWNLOAD_TIMEOUT_MS = 15 * 60_000;
|
|
13
|
+
export const runProcessWithSpawn = (command, args, options) => new Promise((resolve) => {
|
|
11
14
|
// En Windows npm es un .cmd y necesita shell.
|
|
12
15
|
const child = spawn(command, args, { cwd: options.cwd, env: options.env, shell: process.platform === 'win32' });
|
|
13
16
|
let output = '';
|
|
17
|
+
const timer = setTimeout(() => {
|
|
18
|
+
child.kill();
|
|
19
|
+
// Con shell, el kill no llega a los nietos y sus pipes mantendrian vivo el proceso: se sueltan.
|
|
20
|
+
child.stdout.destroy();
|
|
21
|
+
child.stderr.destroy();
|
|
22
|
+
child.unref();
|
|
23
|
+
resolve({ code: null, output, timedOut: true });
|
|
24
|
+
}, options.timeoutMs);
|
|
25
|
+
const finish = (result) => {
|
|
26
|
+
clearTimeout(timer);
|
|
27
|
+
resolve(result);
|
|
28
|
+
};
|
|
14
29
|
child.stdout.on('data', (chunk) => (output += chunk.toString()));
|
|
15
30
|
child.stderr.on('data', (chunk) => (output += chunk.toString()));
|
|
16
|
-
child.on('error', (error) =>
|
|
17
|
-
child.on('close', (code) =>
|
|
31
|
+
child.on('error', (error) => finish({ code: 1, output: `${output}${error.message}` }));
|
|
32
|
+
child.on('close', (code) => finish({ code, output }));
|
|
18
33
|
});
|
|
34
|
+
function describeTimeout(timeoutMs) {
|
|
35
|
+
return `no termino en ${timeoutMs / 60_000} minutos y se corto`;
|
|
36
|
+
}
|
|
19
37
|
function lastLines(output, count = 5) {
|
|
20
38
|
return output.trim().split('\n').slice(-count).join('\n');
|
|
21
39
|
}
|
|
@@ -86,11 +104,14 @@ export class PdfPlugin {
|
|
|
86
104
|
'--no-audit',
|
|
87
105
|
'--no-fund',
|
|
88
106
|
'--save-exact',
|
|
89
|
-
], { cwd: this.options.path, env: this.env });
|
|
107
|
+
], { cwd: this.options.path, env: this.env, timeoutMs: NPM_INSTALL_TIMEOUT_MS });
|
|
90
108
|
if (result.code !== 0) {
|
|
91
|
-
|
|
109
|
+
const message = result.timedOut
|
|
110
|
+
? `La instalación de ${PDF_PLUGIN_PACKAGE} ${describeTimeout(NPM_INSTALL_TIMEOUT_MS)}.`
|
|
111
|
+
: `npm no pudo instalar ${PDF_PLUGIN_PACKAGE}.`;
|
|
112
|
+
throw new PdfError('PDF_PLUGIN_INSTALL_ERROR', message, {
|
|
92
113
|
details: { salida: lastLines(result.output) },
|
|
93
|
-
suggestion: '
|
|
114
|
+
suggestion: 'Revisá la conexión a internet o el proxy de npm y volvé a correr `arcli pdf instalar`.',
|
|
94
115
|
});
|
|
95
116
|
}
|
|
96
117
|
}
|
|
@@ -98,11 +119,18 @@ export class PdfPlugin {
|
|
|
98
119
|
onStep('Descargando el navegador para generar PDFs (unos 200 MB)...');
|
|
99
120
|
const require = createRequire(join(this.options.path, 'package.json'));
|
|
100
121
|
const puppeteerCli = join(require.resolve('puppeteer/package.json'), '..', 'lib', 'puppeteer', 'node', 'cli.js');
|
|
101
|
-
const result = await this.runProcess(process.execPath, [puppeteerCli, 'browsers', 'install', 'chrome-headless-shell'], {
|
|
122
|
+
const result = await this.runProcess(process.execPath, [puppeteerCli, 'browsers', 'install', 'chrome-headless-shell'], {
|
|
123
|
+
cwd: this.options.path,
|
|
124
|
+
env: { ...this.env, PUPPETEER_CACHE_DIR: this.browsersPath },
|
|
125
|
+
timeoutMs: BROWSER_DOWNLOAD_TIMEOUT_MS,
|
|
126
|
+
});
|
|
102
127
|
if (result.code !== 0 || !findDownloadedBrowser(this.browsersPath)) {
|
|
103
|
-
|
|
128
|
+
const message = result.timedOut
|
|
129
|
+
? `La descarga del navegador para generar PDFs ${describeTimeout(BROWSER_DOWNLOAD_TIMEOUT_MS)}.`
|
|
130
|
+
: 'No se pudo descargar el navegador para generar PDFs.';
|
|
131
|
+
throw new PdfError('PDF_PLUGIN_INSTALL_ERROR', message, {
|
|
104
132
|
details: { salida: lastLines(result.output) },
|
|
105
|
-
suggestion: 'Si ya tiene Chrome, Chromium o Edge,
|
|
133
|
+
suggestion: 'Si ya tiene Chrome, Chromium o Edge, indicá su ruta con `arcli config establecer pdfNavegador <ruta>`.',
|
|
106
134
|
});
|
|
107
135
|
}
|
|
108
136
|
}
|
|
@@ -115,13 +143,13 @@ export class PdfPlugin {
|
|
|
115
143
|
const installedVersion = this.readInstalledVersion();
|
|
116
144
|
if (installedVersion !== PDF_PLUGIN_VERSION) {
|
|
117
145
|
throw new PdfError('PDF_PLUGIN_MISSING', installedVersion
|
|
118
|
-
? `El plugin de PDF
|
|
146
|
+
? `El plugin de PDF está en la versión ${installedVersion} y arcli usa la ${PDF_PLUGIN_VERSION}.`
|
|
119
147
|
: 'Para generar PDFs falta instalar el plugin de PDF.', { suggestion: PDF_INSTALL_SUGGESTION });
|
|
120
148
|
}
|
|
121
149
|
const browser = this.resolveBrowser();
|
|
122
150
|
if (!browser) {
|
|
123
|
-
throw new PdfError('PDF_PLUGIN_MISSING', 'No se
|
|
124
|
-
suggestion: `${PDF_INSTALL_SUGGESTION} Descarga uno, o
|
|
151
|
+
throw new PdfError('PDF_PLUGIN_MISSING', 'No se encontró un navegador para generar PDFs.', {
|
|
152
|
+
suggestion: `${PDF_INSTALL_SUGGESTION} Descarga uno, o indicá Chrome con \`arcli config establecer pdfNavegador <ruta>\`.`,
|
|
125
153
|
});
|
|
126
154
|
}
|
|
127
155
|
// El SDK no deja elegir el ejecutable; Puppeteer lo toma de esta variable.
|
|
@@ -134,10 +162,9 @@ export class PdfPlugin {
|
|
|
134
162
|
return await new sdk.InvoicePdfGenerator(options).generate(data);
|
|
135
163
|
}
|
|
136
164
|
catch (error) {
|
|
137
|
-
throw new PdfError('PDF_GENERATION_ERROR', `No se pudo generar el PDF: ${error instanceof Error ? error.message : String(error)}`, { suggestion: 'Si el navegador falla,
|
|
165
|
+
throw new PdfError('PDF_GENERATION_ERROR', `No se pudo generar el PDF: ${error instanceof Error ? error.message : String(error)}`, { suggestion: 'Si el navegador falla, probá con otro: `arcli config establecer pdfNavegador <ruta>`.' });
|
|
138
166
|
}
|
|
139
167
|
},
|
|
140
168
|
};
|
|
141
169
|
}
|
|
142
170
|
}
|
|
143
|
-
//# sourceMappingURL=pdf-plugin.js.map
|
package/dist/ui/index.js
CHANGED