public void closeOrder(final StateChangeContext stateChangeContext) {
    final Entity productionTracking = stateChangeContext.getOwner();
    final Entity order = productionTracking.getBelongsToField(ORDER);

    if (!orderClosingHelper.orderShouldBeClosed(productionTracking)) {
      return;
    }
    if (order.getStringField(STATE).equals(COMPLETED.getStringValue())) {
      stateChangeContext.addMessage(
          "productionCounting.order.orderIsAlreadyClosed", StateMessageType.INFO, false);
      return;
    }
    final StateChangeContext orderStateChangeContext =
        stateChangeContextBuilder.build(
            orderStateChangeAspect.getChangeEntityDescriber(),
            order,
            OrderState.COMPLETED.getStringValue());
    orderStateChangeAspect.changeState(orderStateChangeContext);
    Entity orderFromDB = order.getDataDefinition().get(orderStateChangeContext.getOwner().getId());
    if (orderFromDB.getStringField(STATE).equals(COMPLETED.getStringValue())) {
      stateChangeContext.addMessage(
          "productionCounting.order.orderClosed", StateMessageType.INFO, false);
    } else if (StateChangeStatus.PAUSED.equals(orderStateChangeContext.getStatus())) {
      stateChangeContext.addMessage(
          "productionCounting.order.orderWillBeClosedAfterExtSync", StateMessageType.INFO, false);
    } else {
      stateChangeContext.addMessage(
          "productionCounting.order.orderCannotBeClosed", StateMessageType.FAILURE, false);

      List<ErrorMessage> errors = Lists.newArrayList();

      if (!orderFromDB.getErrors().isEmpty()) {
        errors.addAll(order.getErrors().values());
      }
      if (!orderFromDB.getGlobalErrors().isEmpty()) {
        errors.addAll(order.getGlobalErrors());
      }

      if (!errors.isEmpty()) {
        StringBuilder errorMessages = new StringBuilder();

        for (ErrorMessage errorMessage : errors) {
          String translatedErrorMessage =
              translationService.translate(
                  errorMessage.getMessage(), Locale.getDefault(), errorMessage.getVars());
          errorMessages.append(translatedErrorMessage);
          errorMessages.append(", ");
        }

        stateChangeContext.addValidationError(
            "orders.order.orderStates.error", errorMessages.toString());
      }
    }
  }
  @Test
  public final void shouldSaveButNotSetJustInvalidateOwnerEntity() {
    // given
    given(owner.isValid()).willReturn(true);
    given(ownerDD.save(owner)).willReturn(savedOwner);
    given(savedOwner.isValid()).willReturn(false);

    final Map<String, ErrorMessage> fieldErrorsMap = Maps.newHashMap();
    final ErrorMessage fieldErrorMessage = buildErrorMessage(FIELD_1_MESSAGE_1);
    fieldErrorsMap.put(FIELD_1_NAME, fieldErrorMessage);
    given(savedOwner.getErrors()).willReturn(fieldErrorsMap);

    final List<ErrorMessage> globalErrors = Lists.newArrayList();
    final ErrorMessage globalErrorMessage = buildErrorMessage(GLOBAL_MESSAGE_1);
    globalErrors.add(globalErrorMessage);
    given(savedOwner.getGlobalErrors()).willReturn(globalErrors);

    // when
    stateChangeContext.setOwner(owner);

    // then
    verify(ownerDD).save(owner);
    verify(stateChangeEntity, never()).setField(describer.getOwnerFieldName(), owner);
    verify(stateChangeEntity, never()).setField(describer.getOwnerFieldName(), savedOwner);
    verify(messageService)
        .addValidationError(
            stateChangeContext, FIELD_1_NAME, FIELD_1_MESSAGE_1, EMPTY_STRING_ARRAY);
    verify(messageService)
        .addValidationError(stateChangeContext, null, GLOBAL_MESSAGE_1, EMPTY_STRING_ARRAY);
    verify(stateChangeEntity)
        .setField(describer.getStatusFieldName(), StateChangeStatus.FAILURE.getStringValue());
  }
  @Test
  public final void
      shouldMarkEntityAsInvalidAndSetStateToFailureIfStateChangeEntityIsInvalidAfterSave() {
    // given
    final Entity savedStateChangeEntity = mock(Entity.class);
    given(stateChangeEntity.isValid()).willReturn(true);
    given(savedStateChangeEntity.isValid()).willReturn(true, false);
    given(stateChangeDD.save(stateChangeEntity)).willReturn(savedStateChangeEntity);

    final Map<String, ErrorMessage> fieldErrorsMap = Maps.newHashMap();
    final ErrorMessage fieldErrorMessage = buildErrorMessage(FIELD_1_MESSAGE_1);
    fieldErrorsMap.put(FIELD_1_NAME, fieldErrorMessage);
    given(savedStateChangeEntity.getErrors()).willReturn(fieldErrorsMap);

    final List<ErrorMessage> globalErrors = Lists.newArrayList();
    final ErrorMessage globalErrorMessage = buildErrorMessage(GLOBAL_MESSAGE_1);
    globalErrors.add(globalErrorMessage);
    given(savedStateChangeEntity.getGlobalErrors()).willReturn(globalErrors);

    // when
    stateChangeContext.save();

    // then
    verify(messageService)
        .addValidationError(
            stateChangeContext, FIELD_1_NAME, FIELD_1_MESSAGE_1, EMPTY_STRING_ARRAY);
    verify(messageService)
        .addValidationError(stateChangeContext, null, GLOBAL_MESSAGE_1, EMPTY_STRING_ARRAY);
    verify(stateChangeEntity).setField(describer.getStatusFieldName(), FAILURE.getStringValue());
  }