Commit 2532684f authored by Enriko Käsper's avatar Enriko Käsper
Browse files

Merge branch 'develop' into 'master'

Release: merge 'develop' into 'master' created by Enriko Käsper

See merge request teis/payments-service!41
parents 657799f2 8561aee5
theGroup=ee.sm.ti.teis
theVersion=1.4.0
theVersion=1.5.0
pluginVersion=1.0.1
commonsVersion=1.6.0
officeApiGatewayVersion=1.6.0
commonsVersion=1.7.0
officeApiGatewayVersion=1.7.0
mapstructVersion=1.3.0.Final
querydslVersion=4.1.3
package ee.sm.ti.teis.payments.claim.listener;
import ee.sm.ti.teis.PaymentsAppTestBase;
import ee.sm.ti.teis.commongateway.payments.claim.dto.ClaimDefinitionDto;
import ee.sm.ti.teis.officegateway.payments.payment.request.ClaimDefinitionsRequest;
import ee.sm.ti.teis.officegateway.payments.payment.request.UpdateClaimDefinitionRequest;
import ee.sm.ti.teis.officegateway.payments.payment.response.ClaimDefinitionsResponse;
import ee.sm.ti.teis.officegateway.payments.payment.response.UpdateClaimDefinitionResponse;
import ee.sm.ti.teis.payments.claim.definition.ClaimDefinitionEntity;
import ee.sm.ti.teis.payments.claim.definition.ClaimDefinitionOfficeGwListener;
import ee.sm.ti.teis.payments.claim.definition.ClaimDefinitionRepository;
import ee.sm.ti.teis.servicerequest.RequestMetaDTO;
import ee.sm.ti.teis.types.enums.ObjectStatus;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Optional;
import java.util.UUID;
import static ee.sm.ti.teis.servicerequest.UserType.OFFICIAL_USER;
import static ee.sm.ti.teis.types.enums.RolePrivilegeCode.*;
import static ee.sm.ti.teis.utils.TestUtils.assertResponseForbidden;
import static ee.sm.ti.teis.utils.TestUtils.createRequestMeta;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.UUID.randomUUID;
import static org.assertj.core.api.Assertions.assertThat;
public class ClaimOfficeGwListenerTest extends PaymentsAppTestBase {
private static final String COMPANY_ID = "6b68de81-37be-4613-b7c4-f226107978e5";
private static final UUID CLAIM_ID = UUID.fromString("e63b9fd5-ea40-49de-b233-1563bd5d44aa");
@Autowired
ClaimDefinitionOfficeGwListener listener;
@Autowired
ClaimDefinitionRepository claimDefinitionRepository;
private ClaimDefinitionsRequest request;
private UpdateClaimDefinitionRequest updateRequest;
private RequestMetaDTO requestMetaDTO;
@BeforeEach
void setUp() {
requestMetaDTO = createRequestMeta(UUID.randomUUID().toString(), OFFICIAL_USER, randomUUID().toString(),
emptyList());
updateRequest = new UpdateClaimDefinitionRequest();
request = new ClaimDefinitionsRequest();
request.setRequestMetaDTO(requestMetaDTO);
updateRequest.setRequestMetaDTO(requestMetaDTO);
}
@Test
public void getClaimDefinitions_invalid_privilege() {
requestMetaDTO.setPrivileges(singletonList(EX_VIEW_PAYMENTS.name()));
request.setRequestMetaDTO(requestMetaDTO);
ClaimDefinitionsResponse response = listener.getClaimDefinitions(request);
assertResponseForbidden(response.getError());
}
@Test
public void getClaimDefinitions_success() {
requestMetaDTO.setPrivileges(singletonList(TI_MANAGE_PAYMENTS_DEFINITIONS.name()));
request.setRequestMetaDTO(requestMetaDTO);
ClaimDefinitionsResponse response = listener.getClaimDefinitions(request);
assertThat(response.getError()).isNull();
assertThat(response.getPayload()).isNotEmpty();
}
@Test
public void updateClaimDefinitions_success() {
requestMetaDTO.setPrivileges(singletonList(TI_MANAGE_PAYMENTS_DEFINITIONS.name()));
ClaimDefinitionDto dto = ClaimDefinitionDto.builder()
.id(UUID.fromString("13c32867-b082-48a3-907a-b930f0164d2c"))
.title("Kingitus")
.build();
Optional<ClaimDefinitionEntity> currentDefinition = claimDefinitionRepository.findByIdAndObjectStatus(UUID.fromString("13c32867-b082-48a3-907a-b930f0164d2c"), ObjectStatus.CURRENT);
assertThat(currentDefinition).isNotEmpty();
assertThat(currentDefinition.get().getTitle()).isEqualTo("Sunniraha");
updateRequest.setPayload(dto, requestMetaDTO);
UpdateClaimDefinitionResponse response = listener.updateClaimDefinitions(updateRequest);
assertThat(response.getError()).isNull();
assertThat(response.getPayload().getTitle()).isEqualTo("Kingitus");
}
@Test
public void updateClaimDefinitions_invalid_privilege() {
requestMetaDTO.setPrivileges(singletonList(TI_MANAGE_PAYMENTS.name()));
ClaimDefinitionDto dto = ClaimDefinitionDto.builder()
.id(UUID.fromString("13c32867-b082-48a3-907a-b930f0164d2c"))
.title("Kingitus")
.build();
updateRequest.setPayload(dto, requestMetaDTO);
UpdateClaimDefinitionResponse response = listener.updateClaimDefinitions(updateRequest);
assertResponseForbidden(response.getError());
}
}
package ee.sm.ti.teis.payments.claim.config;
import ee.sm.ti.teis.configuration.QueueList;
import ee.sm.ti.teis.configuration.TeisQueue;
import ee.sm.ti.teis.officegateway.payments.payment.request.ClaimDefinitionsRequest;
import ee.sm.ti.teis.officegateway.payments.payment.request.UpdateClaimDefinitionRequest;
import java.util.ArrayList;
public class ClaimDefinitionQueueConfig implements QueueList {
public static final String GW_CLAIM_DEFINITIONS_QUEUE = "payments-service.gw.claimDefinitionsRequests";
public static final String GW_UPDATE_CLAIM_DEFINITION_QUEUE = "payments-service.gw.updateClaimDefinitionRequests";
@Override
public void updateQueues(ArrayList<TeisQueue> queues) {
addGwQueue(queues, "gwGetClaimDefinitionsQueue", ClaimDefinitionsRequest.ROUTING_KEY, GW_CLAIM_DEFINITIONS_QUEUE);
addGwQueue(queues, "gwUpdateClaimDefinitionQueue", UpdateClaimDefinitionRequest.ROUTING_KEY, GW_UPDATE_CLAIM_DEFINITION_QUEUE);
}
}
package ee.sm.ti.teis.payments.claim.entity;
package ee.sm.ti.teis.payments.claim.definition;
import ee.sm.ti.teis.servicecommon.common.AuditedEntity;
import ee.sm.ti.teis.types.enums.ObjectStatus;
......
package ee.sm.ti.teis.payments.claim.definition;
import ee.sm.ti.teis.commongateway.payments.claim.dto.ClaimDefinitionDto;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.ReportingPolicy;
import org.springframework.stereotype.Component;
import java.util.List;
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
@Component
public interface ClaimDefinitionMapper {
@Mapping(target = "dataObjectType.id", source = "dataObjectType")
ClaimDefinitionDto toDto(ClaimDefinitionEntity definitionEntity);
List<ClaimDefinitionDto> toDtoList(List<ClaimDefinitionEntity> definitionEntity);
}
package ee.sm.ti.teis.payments.claim.definition;
import ee.sm.ti.teis.commongateway.payments.claim.dto.ClaimDefinitionDto;
import ee.sm.ti.teis.officegateway.payments.payment.request.ClaimDefinitionsRequest;
import ee.sm.ti.teis.officegateway.payments.payment.request.UpdateClaimDefinitionRequest;
import ee.sm.ti.teis.officegateway.payments.payment.response.ClaimDefinitionsResponse;
import ee.sm.ti.teis.officegateway.payments.payment.response.UpdateClaimDefinitionResponse;
import ee.sm.ti.teis.payments.claim.definition.service.ClaimDefinitionBusinessGwService;
import ee.sm.ti.teis.servicerequest.RequestMetaDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import java.util.List;
import static ee.sm.ti.teis.payments.claim.config.ClaimDefinitionQueueConfig.GW_CLAIM_DEFINITIONS_QUEUE;
import static ee.sm.ti.teis.payments.claim.config.ClaimDefinitionQueueConfig.GW_UPDATE_CLAIM_DEFINITION_QUEUE;
@Component
@RequiredArgsConstructor
public class ClaimDefinitionOfficeGwListener {
private final ClaimDefinitionBusinessGwService service;
@RabbitListener(queues = {GW_CLAIM_DEFINITIONS_QUEUE})
@PreAuthorize("@accessController.hasOfficialPrivilege({'TI_MANAGE_PAYMENTS_DEFINITIONS'})")
public ClaimDefinitionsResponse getClaimDefinitions(ClaimDefinitionsRequest request) {
RequestMetaDTO requestMetaDTO = request.getRequestMetaDTO();
List<ClaimDefinitionDto> claimDefinitions = service.getAll(requestMetaDTO);
ClaimDefinitionsResponse response = new ClaimDefinitionsResponse();
response.setPayload(claimDefinitions, requestMetaDTO);
return response;
}
@RabbitListener(queues = {GW_UPDATE_CLAIM_DEFINITION_QUEUE})
@PreAuthorize("@accessController.hasOfficialPrivilege({'TI_MANAGE_PAYMENTS_DEFINITIONS'})")
public UpdateClaimDefinitionResponse updateClaimDefinitions(UpdateClaimDefinitionRequest request) {
RequestMetaDTO requestMetaDTO = request.getRequestMetaDTO();
ClaimDefinitionDto claimDefinition = service.update(request.getPayload(), requestMetaDTO);
UpdateClaimDefinitionResponse response = new UpdateClaimDefinitionResponse();
response.setPayload(claimDefinition, requestMetaDTO);
return response;
}
}
package ee.sm.ti.teis.payments.claim.repository;
package ee.sm.ti.teis.payments.claim.definition;
import ee.sm.ti.teis.payments.claim.entity.ClaimDefinitionEntity;
import ee.sm.ti.teis.types.enums.ObjectStatus;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
......@@ -13,7 +13,12 @@ public interface ClaimDefinitionRepository extends CrudRepository<ClaimDefinitio
Optional<ClaimDefinitionEntity> findByCodeAndObjectStatus(String code, ObjectStatus objectStatus);
Optional<ClaimDefinitionEntity> findByIdAndObjectStatus(UUID id, ObjectStatus objectStatus);
default Optional<ClaimDefinitionEntity> findCurrentByCode(String code) {
return findByCodeAndObjectStatus(code, CURRENT);
}
List<ClaimDefinitionEntity> findAllByObjectStatus(ObjectStatus objectStatus);
}
package ee.sm.ti.teis.payments.claim.definition;
import ee.sm.ti.teis.commongateway.payments.claim.dto.ClaimDefinitionDto;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class UpdateClaimDefinitionValidator implements ConstraintValidator<ValidClaimDefinitionDto, ClaimDefinitionDto> {
@Override
public boolean isValid(ClaimDefinitionDto dto, ConstraintValidatorContext context) {
return dto.getId() != null && dto.getTitle() != null && !dto.getTitle().isBlank();
}
}
package ee.sm.ti.teis.payments.claim.definition;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Constraint(validatedBy = UpdateClaimDefinitionValidator.class)
@Target({PARAMETER})
@Retention(RUNTIME)
@Documented
public @interface ValidClaimDefinitionDto {
String message() default "Field validation error";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
package ee.sm.ti.teis.payments.claim.definition.service;
import ee.sm.ti.teis.commongateway.payments.claim.dto.ClaimDefinitionDto;
import ee.sm.ti.teis.payments.claim.definition.ClaimDefinitionEntity;
import ee.sm.ti.teis.payments.claim.definition.ValidClaimDefinitionDto;
import ee.sm.ti.teis.servicerequest.RequestMetaDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.util.List;
@Service
@Validated
@RequiredArgsConstructor
public class ClaimDefinitionBusinessGwService {
private final ClaimDefinitionDataService dataService;
private final ClaimDefinitionComposeService composeService;
private final ClaimDefinitionNotifyService notifyService;
@Transactional(readOnly = true)
public List<ClaimDefinitionDto> getAll(RequestMetaDTO requestMetaDTO) {
List<ClaimDefinitionEntity> claimDefinitions = dataService.getCurrentClaimDefinitions();
return composeService.composeDtoList(claimDefinitions, requestMetaDTO);
}
@Transactional
public ClaimDefinitionDto update(@ValidClaimDefinitionDto ClaimDefinitionDto dto, RequestMetaDTO requestMetaDTO) {
ClaimDefinitionEntity claimDefinition = dataService.getCurrentById(dto.getId());
ClaimDefinitionDto auditLogDto = composeService.composeDto(claimDefinition, requestMetaDTO);
ClaimDefinitionEntity updatedEntity = updateDefinitionValues(claimDefinition, dto);
notifyService.update(auditLogDto, requestMetaDTO);
return composeService.composeDto(updatedEntity, requestMetaDTO);
}
private ClaimDefinitionEntity updateDefinitionValues(ClaimDefinitionEntity claimDefinition, ClaimDefinitionDto dto) {
claimDefinition.setTitle(dto.getTitle());
claimDefinition.setBankAccounts(dto.getBankAccounts());
claimDefinition.setReceiverName(dto.getReceiverName());
claimDefinition.setPaymentReference(dto.getPaymentReference());
claimDefinition.setPaymentDescription(dto.getPaymentDescription());
return dataService.save(claimDefinition);
}
}
package ee.sm.ti.teis.payments.claim.definition.service;
import ee.sm.ti.teis.cache.classifier.ClassifierService;
import ee.sm.ti.teis.commongateway.payments.claim.dto.ClaimDefinitionDto;
import ee.sm.ti.teis.domain.ClassifierItem;
import ee.sm.ti.teis.payments.claim.definition.ClaimDefinitionEntity;
import ee.sm.ti.teis.payments.claim.definition.ClaimDefinitionMapper;
import ee.sm.ti.teis.payments.claim.mapper.ClassifierMapper;
import ee.sm.ti.teis.servicerequest.RequestMetaDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class ClaimDefinitionComposeService {
private final ClassifierService classifierService;
private final ClassifierMapper classifierMapper;
private final ClaimDefinitionMapper claimDefinitionMapper;
public List<ClaimDefinitionDto> composeDtoList(List<ClaimDefinitionEntity> claimDefinitions, RequestMetaDTO requestMetaDTO) {
List<ClaimDefinitionDto> claimDefinitionDtos = claimDefinitionMapper.toDtoList(claimDefinitions);
claimDefinitionDtos.forEach(def -> {
ClassifierItem dataObjectTypeClassifier = classifierService.getClassifierItem(def.getDataObjectType().getId(), requestMetaDTO);
def.setDataObjectType(classifierMapper.toGwLightDto(dataObjectTypeClassifier));
});
return claimDefinitionDtos;
}
public ClaimDefinitionDto composeDto(ClaimDefinitionEntity claimDefinition, RequestMetaDTO requestMetaDTO) {
ClaimDefinitionDto definitionDto = claimDefinitionMapper.toDto(claimDefinition);
ClassifierItem dataObjectTypeClassifier = classifierService.getClassifierItem(definitionDto.getDataObjectType().getId(), requestMetaDTO);
definitionDto.setDataObjectType(classifierMapper.toGwLightDto(dataObjectTypeClassifier));
return definitionDto;
}
}
package ee.sm.ti.teis.payments.claim.service;
package ee.sm.ti.teis.payments.claim.definition.service;
import ee.sm.ti.teis.exceptions.TeisResourceNotFoundException;
import ee.sm.ti.teis.payments.claim.entity.ClaimDefinitionEntity;
import ee.sm.ti.teis.payments.claim.repository.ClaimDefinitionRepository;
import ee.sm.ti.teis.payments.claim.definition.ClaimDefinitionEntity;
import ee.sm.ti.teis.payments.claim.definition.ClaimDefinitionRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.UUID;
import static ee.sm.ti.teis.types.enums.ObjectStatus.CURRENT;
@Service
@RequiredArgsConstructor
......@@ -14,8 +17,21 @@ public class ClaimDefinitionDataService {
private final ClaimDefinitionRepository repository;
ClaimDefinitionEntity getCurrentByCode(String code) {
public ClaimDefinitionEntity getCurrentByCode(String code) {
return repository.findCurrentByCode(code)
.orElseThrow(() -> new TeisResourceNotFoundException("Claim definition not found", List.of(code)));
}
public ClaimDefinitionEntity getCurrentById(UUID id) {
return repository.findByIdAndObjectStatus(id, CURRENT)
.orElseThrow(() -> new TeisResourceNotFoundException("Claim definition not found", List.of(id)));
}
public List<ClaimDefinitionEntity> getCurrentClaimDefinitions() {
return repository.findAllByObjectStatus(CURRENT);
}
public ClaimDefinitionEntity save(ClaimDefinitionEntity definitionEntity) {
return repository.save(definitionEntity);
}
}
package ee.sm.ti.teis.payments.claim.definition.service;
import ee.sm.ti.teis.ErrorDTO;
import ee.sm.ti.teis.commongateway.payments.claim.dto.ClaimDefinitionDto;
import ee.sm.ti.teis.domain.auditlog.AuditLogItem;
import ee.sm.ti.teis.domain.common.SimpleMessageSource;
import ee.sm.ti.teis.domainrequest.DomainCreatedEventDto;
import ee.sm.ti.teis.domainrequest.rabbit.SendDomainMessageEvent;
import ee.sm.ti.teis.servicerequest.RequestMetaDTO;
import ee.sm.ti.teis.types.enums.ActivityType;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import static ee.sm.ti.teis.types.enums.ActivityType.UPDATE;
import static ee.sm.ti.teis.types.enums.DataObjectType.CLAIMDEFINITIONS;
@Service
@RequiredArgsConstructor
public class ClaimDefinitionNotifyService {
private final ApplicationEventPublisher eventPublisher;
private final SimpleMessageSource messageSource;
public void update(ClaimDefinitionDto claimDefinition, RequestMetaDTO requestMetaDTO) {
notifyAuditEvent(claimDefinition, requestMetaDTO, UPDATE);
}
private void notifyAuditEvent(ClaimDefinitionDto claimDefinition, RequestMetaDTO requestMetaDTO, ActivityType activityType) {
CreateAuditLogDomainRequest request = new CreateAuditLogDomainRequest();
AuditLogItem auditLogItem = AuditLogItem.builder()
.activityType(activityType)
.dataObjectType(CLAIMDEFINITIONS.name())
.parentDataObjectId(claimDefinition.getId().toString())
.dataObjectId(claimDefinition.getId().toString())
.build();
auditLogItem.setActivityDescription(messageSource.getAuditlogMessage(auditLogItem, claimDefinition.getCode(),
claimDefinition.getTitle(), claimDefinition.getBankAccounts(), claimDefinition.getReceiverName(),
claimDefinition.getPaymentReference(), claimDefinition.getPaymentDescription()));
request.setPayload(auditLogItem, requestMetaDTO);
eventPublisher.publishEvent(new SendDomainMessageEvent(request));
}
public class CreateAuditLogDomainRequest extends DomainCreatedEventDto<AuditLogItem, ErrorDTO> {
}
}
package ee.sm.ti.teis.payments.claim.entity;
import ee.sm.ti.teis.payments.claim.definition.ClaimDefinitionEntity;
import ee.sm.ti.teis.payments.reconciliation.ReconciliationEntity;
import ee.sm.ti.teis.servicecommon.common.AuditedEntity;
import ee.sm.ti.teis.types.enums.ClaimStatusType;
......
......@@ -5,7 +5,8 @@ import ee.sm.ti.teis.cache.person.PersonService;
import ee.sm.ti.teis.domain.ClassifierItem;
import ee.sm.ti.teis.domain.payments.claim.Claim;
import ee.sm.ti.teis.domain.payments.claim.DataObjectReference;
import ee.sm.ti.teis.payments.claim.entity.ClaimDefinitionEntity;
import ee.sm.ti.teis.payments.claim.definition.ClaimDefinitionEntity;
import ee.sm.ti.teis.payments.claim.definition.service.ClaimDefinitionDataService;
import ee.sm.ti.teis.payments.claim.entity.ClaimEntity;
import ee.sm.ti.teis.payments.claim.entity.DataObjectReferenceEntity;
import ee.sm.ti.teis.payments.serviceclient.PathServiceClient;
......
......@@ -15,6 +15,7 @@ DELETE FROM claim_definition WHERE created_by = 'test';
INSERT INTO claim_definition (id, code, title, bank_accounts, receiver_name, payment_reference, payment_description, data_object_type, path_end, object_status, created_by)
VALUES ('20bffead-a063-467e-a4b1-d55bf53944b5', 'CREATE_PAYMENT', 'Create payment', 'EE123123213453543', 'TEHIK', 'Create payment reference', 'payment description 123', 'OBJECT_TYPE__CLAIM_PAYMENT', null, 'CURRENT', 'test'),
('500dacdc-dbff-47bd-a5fe-ba61537b08f9', 'CREATE_ANOTHER_PAYMENT', 'Create another payment definition', 'EE123123213453543', 'TEHIK', 'Ref 123456789', 'payment another description', 'OBJECT_TYPE__CLAIM_PAYMENT', null, 'CURRENT', 'test'),
('4d614265-a00b-426a-8b9e-dc93ac75a63d', 'CLAIM_DEFINITION_FOR_TESTS', 'Claim definition for tests', 'EE123123213453543', 'TEHIK', 'Ref 123456789', 'Test description', 'OBJECT_TYPE__CLAIM_PAYMENT', null, 'CURRENT', 'test'),
('4cf07228-fdd9-4a76-a8a2-a2dffa97bd3e', 'CREATE_THIRD_PAYMENT', 'Create payment', 'EE123123213453543', 'TEHIK', 'Ref 987654321', 'payment description 123', 'OBJECT_TYPE__CLAIM_PAYMENT', null, 'DELETED', 'test');
INSERT INTO claim (id, claim_definition_id, employer_id, issued_date, amount, deadline_date, reference, payment_reference, path, status, balance, object_status, payment_description)
......
......@@ -5,4 +5,5 @@ auditlog.reconciliations.delete=Kustutati seos laekumisega nõudelt toimingu num
auditlog.payments.update=Muudeti laekumist {0} summas {1} maksjalt {2}
auditlog.payments.refund.true=Laekumine {0} summas {1} maksjalt {2} märgitud tagastatuks summas {3}
auditlog.payments.refund.false=Laekumise {0} summas {1} maksjalt {2} tagastamine märgitud tühistatuks
auditlog.payments.delete=Kustutati laekumine {0} summas {1} maksjalt {2}
\ No newline at end of file
auditlog.payments.delete=Kustutati laekumine {0} summas {1} maksjalt {2}
auditlog.claimdefinitions.update=Muudeti nõude definitsiooni {0}. Vana nimetus {1}, arveldusarved: {2}, saaja nimi {3}, makseviide {4}, makse selgitus: {5}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment