Last active
January 15, 2026 01:32
-
-
Save robsonkades/029444862fd7cdeab515069e879a881e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| record StatusTransition(InvoiceStatus current) { | |
| public void validate(InvoiceStatus next, String invoiceId) { | |
| if (!current.canTransitionTo(next)) { | |
| throw DomainException.with(Message.INVOICE_TRANSITION_NOT_ALLOWED, invoiceId, current, next); | |
| } | |
| } | |
| } | |
| static { | |
| // Definição clara da Máquina de Estados | |
| PENDING.nextPossibleStates = EnumSet.of(PENDING, AUTHORIZED, REJECTED, CANCELED, NUMBER_INVALIDED); | |
| REJECTED.nextPossibleStates = EnumSet.of(PENDING, AUTHORIZED, REJECTED, CANCELED, NUMBER_INVALIDED); | |
| AUTHORIZED.nextPossibleStates = EnumSet.of(AUTHORIZED, CANCELED); | |
| CANCELED.nextPossibleStates = EnumSet.of(CANCELED); | |
| NUMBER_INVALIDED.nextPossibleStates = EnumSet.of(NUMBER_INVALIDED); | |
| } | |
| private final String description; | |
| private Set<InvoiceStatus> nextPossibleStates; | |
| InvoiceStatus(final String description) { | |
| this.description = description; | |
| } | |
| public String getDescription() { | |
| return description; | |
| } | |
| public boolean canTransitionTo(InvoiceStatus next) { | |
| return nextPossibleStates.contains(next); | |
| } | |
| public void markAsPending() { | |
| new StatusTransition(this.status).validate(InvoiceStatus.PENDING, id.getValue()); | |
| if (isPending()) { | |
| LOGGER.debug("Invoice {} already authorized", id.getValue()); | |
| return; | |
| } | |
| this.clearStatusFields(); | |
| this.changeStatus(InvoiceStatus.PENDING); | |
| this.registerEvent(InvoicePending.from(this)); | |
| } | |
| public void markAsAuthorized() { | |
| new StatusTransition(this.status).validate(InvoiceStatus.AUTHORIZED, id.getValue()); | |
| if (isAuthorized()) { | |
| LOGGER.debug("Invoice {} already authorized", id.getValue()); | |
| return; | |
| } | |
| this.changeStatus(InvoiceStatus.AUTHORIZED); | |
| this.registerEvent(InvoiceAuthorized.from(this)); | |
| } | |
| public void markAsCanceled() { | |
| new StatusTransition(this.status).validate(InvoiceStatus.CANCELED, id.getValue()); | |
| if (isCanceled()) return; | |
| this.changeStatus(InvoiceStatus.CANCELED); | |
| this.registerEvent(InvoiceCanceled.from(this)); | |
| } | |
| public void markAsRejected() { | |
| new StatusTransition(this.status).validate(InvoiceStatus.REJECTED, id.getValue()); | |
| if (isRejected()) return; | |
| this.changeStatus(InvoiceStatus.REJECTED); | |
| this.registerEvent(InvoiceRejected.from(this)); | |
| } | |
| public void markAsNumberInvalided() { | |
| new StatusTransition(this.status).validate(InvoiceStatus.NUMBER_INVALIDED, id.getValue()); | |
| if (isRejected()) return; | |
| this.changeStatus(InvoiceStatus.NUMBER_INVALIDED); | |
| } | |
| /** | |
| * Extrai substring de forma segura, retornando null se houver erro | |
| */ | |
| private String safeSubstring(String value, int start, int end) { | |
| try { | |
| if (value == null || start < 0 || end > value.length() || start >= end) { | |
| return null; | |
| } | |
| String substring = value.substring(start, end); | |
| return substring.trim().isEmpty() ? null : substring; | |
| } catch (Exception e) { | |
| return null; | |
| } | |
| } | |
| /** | |
| * Parse seguro de Integer, retornando null se houver erro | |
| */ | |
| private Integer safeParseInt(String value, int start, int end) { | |
| try { | |
| String substring = safeSubstring(value, start, end); | |
| if (substring == null) { | |
| return null; | |
| } | |
| return Integer.parseInt(substring); | |
| } catch (NumberFormatException e) { | |
| return null; | |
| } | |
| } | |
| /** | |
| * Parse seguro de Long, retornando null se houver erro | |
| */ | |
| private Long safeParseLong(String value, int start, int end) { | |
| try { | |
| String substring = safeSubstring(value, start, end); | |
| if (substring == null) { | |
| return null; | |
| } | |
| return Long.parseLong(substring); | |
| } catch (NumberFormatException e) { | |
| return null; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment