Skip to content
This repository was archived by the owner on Nov 7, 2023. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import lombok.*;

import jakarta.persistence.*;
import org.dcsa.edocumentation.domain.validations.AsyncShipperProvidedDataValidation;
import org.dcsa.edocumentation.domain.validations.PartyValidation;

import java.util.List;
import java.util.Set;
import java.util.UUID;

Expand All @@ -14,6 +18,7 @@
@Setter(AccessLevel.PRIVATE)
@Entity
@Table(name = "party")
@PartyValidation(groups = AsyncShipperProvidedDataValidation.class)
public class Party {
@Id
@GeneratedValue
Expand All @@ -23,15 +28,6 @@ public class Party {
@Column(name = "party_name", length = 100)
private String partyName;

@Column(name = "tax_reference_1", length = 20)
private String taxReference1;

@Column(name = "tax_reference_2", length = 20)
private String taxReference2;

@Column(name = "public_key", length = 100)
private String publicKey;

@ToString.Exclude
@EqualsAndHashCode.Exclude
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
Expand All @@ -43,6 +39,12 @@ public class Party {
@OneToMany(mappedBy = "party")
private Set<@Valid PartyContactDetails> partyContactDetails;

@ToString.Exclude
@EqualsAndHashCode.Exclude
@OrderColumn(name = "list_order")
@OneToMany(mappedBy = "party")
private Set<@Valid TaxAndLegalReference> taxAndLegalReferences;

@ToString.Exclude
@EqualsAndHashCode.Exclude
@OneToMany(mappedBy = "party")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.dcsa.edocumentation.domain.persistence.entity;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.*;
import org.dcsa.edocumentation.domain.validations.AsyncShipperProvidedDataValidation;
import org.dcsa.edocumentation.domain.validations.TaxAndLegalReferenceValidation;

import java.util.UUID;

@Data
@Builder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
@Setter(AccessLevel.PRIVATE)
@Entity
@Table(name = "tax_and_legal_reference")
@TaxAndLegalReferenceValidation(groups = AsyncShipperProvidedDataValidation.class)
public class TaxAndLegalReference {

@Id
@GeneratedValue
private UUID id;

@Column(name = "type_code")
@Size(max = 50)
@NotBlank
private String type;

@Column(name = "country_code")
@Size(max = 2)
@NotBlank
private String countryCode;

@Column(name = "value")
@Size(max = 100)
@NotBlank
private String value;

@ToString.Exclude
@EqualsAndHashCode.Exclude
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "party_id")
private Party party;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.dcsa.edocumentation.domain.persistence.repository;

import org.dcsa.edocumentation.domain.persistence.entity.TaxAndLegalReference;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.UUID;

@Repository
public interface TaxAndLegalReferenceRepository extends JpaRepository<TaxAndLegalReference, UUID> { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.dcsa.edocumentation.domain.validations;

import jakarta.validation.Constraint;
import jakarta.validation.Payload;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = PartyValidator.class)
public @interface PartyValidation {

LocationSubType[] allowedSubtypes() default {};

String message() default "Illegal party specification";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.dcsa.edocumentation.domain.validations;


import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import org.dcsa.edocumentation.domain.persistence.entity.Party;
import org.dcsa.edocumentation.domain.persistence.entity.TaxAndLegalReference;

import java.util.List;
import java.util.Set;

public class PartyValidator implements ConstraintValidator<PartyValidation, Party> {

@Override
public boolean isValid(Party value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}

var state = ValidationState.of(value, context);
validateTaxAndLegalReferences(state);
return state.isValid();
}

private void validateTaxAndLegalReferences(ValidationState<Party> state) {
Set<TaxAndLegalReference> taxAndLegalReferenceSet = state.getValue().getTaxAndLegalReferences();

// return customsReferences.stream()
// .collect(Collectors.groupingBy(p -> p.getType() + "-" + p.getCountryCode(), Collectors.toList()))
// .values()
// .stream()
// .filter(i -> i.size() > 1)
// .flatMap(Collection::stream)
// .toList();


for (TaxAndLegalReference taxAndLegalReference : taxAndLegalReferenceSet) {
List<TaxAndLegalReference> matched = taxAndLegalReferenceSet.stream()
.filter(inner -> inner.getType().equals(taxAndLegalReference.getType())
&& inner.getCountryCode().equals(taxAndLegalReference.getCountryCode()))
.toList();

if (matched.size() > 1) {
TaxAndLegalReference illegalTaxAndLegalReference = matched.get(0);
state.getContext().buildConstraintViolationWithTemplate(
"Tax and Legal Reference Type = " + illegalTaxAndLegalReference.getType() + " and country code = " + illegalTaxAndLegalReference.getCountryCode() +
" can only appear once for a Party. Please correct party: " + state.getValue().toString())
.addConstraintViolation();
state.invalidate();
return;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.dcsa.edocumentation.domain.validations;

import jakarta.validation.Constraint;
import jakarta.validation.Payload;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = TaxAndLegalReferenceValidator.class)
public @interface TaxAndLegalReferenceValidation {

LocationSubType[] allowedSubtypes() default {};

String message() default "Illegal referenceType and countryCode combination in Tax and Legal Reference";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.dcsa.edocumentation.domain.validations;


import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import org.dcsa.edocumentation.domain.persistence.entity.TaxAndLegalReference;

public class TaxAndLegalReferenceValidator implements ConstraintValidator<TaxAndLegalReferenceValidation, TaxAndLegalReference> {

private static final CodeCache VALID_TAX_AND_LEGAL_CODES =
CodeCache.of("taxandlegalreferences.csv", "Tax and Legal Reference Type", "Country Code");

@Override
public boolean isValid(TaxAndLegalReference value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}

boolean valid = VALID_TAX_AND_LEGAL_CODES.isValid(value.getType(),value.getCountryCode());
if (!valid) {
var state = ValidationState.of(value, context);
state.getContext().buildConstraintViolationWithTemplate(
"Illegal combination of Tax and Legal Reference Type = " + value.getType() + " and country code = " + value.getCountryCode())
.addConstraintViolation();
state.invalidate();
return false;
}
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,6 @@ CREATE TABLE carrier (
CREATE TABLE party (
id uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
party_name varchar(100) NULL,
tax_reference_1 varchar(20) NULL,
tax_reference_2 varchar(20) NULL,
public_key varchar(500) NULL,
address_id uuid NULL REFERENCES address (id)
);

Expand All @@ -87,6 +84,14 @@ CREATE TABLE party_identifying_code (
party_code varchar(100) NOT NULL
);

CREATE TABLE tax_and_legal_reference (
id uuid DEFAULT uuid_generate_v4() PRIMARY KEY,
party_id uuid NOT NULL REFERENCES party(id),
type_code varchar(50) NOT NULL,
country_code varchar(2) NOT NULL,
value varchar(100) NOT NULL,
list_order int NOT NULL default 0
);

CREATE TABLE transport_document_type (
transport_document_type_code varchar(3) PRIMARY KEY,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,4 @@ INSERT INTO hs_code_item (
'bf93f6fb-98b8-4268-a4dc-23a40eab95a8'::uuid,
'720711'
);

Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
import org.dcsa.edocumentation.domain.persistence.repository.PartyContactDetailsRepository;
import org.dcsa.edocumentation.domain.persistence.repository.PartyIdentifyingCodeRepository;
import org.dcsa.edocumentation.domain.persistence.repository.PartyRepository;
import org.dcsa.edocumentation.domain.persistence.repository.TaxAndLegalReferenceRepository;
import org.dcsa.edocumentation.service.mapping.PartyMapper;
import org.dcsa.edocumentation.transferobjects.PartyContactDetailsTO;
import org.dcsa.edocumentation.transferobjects.PartyIdentifyingCodeTO;
import org.dcsa.edocumentation.transferobjects.PartyTO;
import org.dcsa.edocumentation.transferobjects.TaxAndLegalReferenceTO;
import org.springframework.stereotype.Service;

@RequiredArgsConstructor
Expand All @@ -20,6 +22,7 @@ public class PartyService {
private final PartyRepository partyRepository;
private final PartyMapper partyMapper;
private final PartyContactDetailsRepository partyContactDetailsRepository;
private final TaxAndLegalReferenceRepository taxAndLegalReferenceRepository;
private final PartyIdentifyingCodeRepository partyIdentifyingCodeRepository;

@Transactional
Expand All @@ -35,6 +38,14 @@ public Party createParty(PartyTO partyTO) {
.toList());
}

List<TaxAndLegalReferenceTO> taxAndLegalReferences = partyTO.taxAndLegalReferences();
if (taxAndLegalReferences != null && !taxAndLegalReferences.isEmpty()) {
taxAndLegalReferenceRepository.saveAll(
taxAndLegalReferences.stream()
.map(taxAndLegalReferenceTO -> partyMapper.toDAO(taxAndLegalReferenceTO, party))
.toList());
}

List<PartyIdentifyingCodeTO> identifyingCodes = partyTO.identifyingCodes();
if (identifyingCodes != null && !identifyingCodes.isEmpty()) {
partyIdentifyingCodeRepository.saveAll(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import org.dcsa.edocumentation.domain.persistence.entity.Party;
import org.dcsa.edocumentation.domain.persistence.entity.PartyContactDetails;
import org.dcsa.edocumentation.domain.persistence.entity.PartyIdentifyingCode;
import org.dcsa.edocumentation.domain.persistence.entity.TaxAndLegalReference;
import org.dcsa.edocumentation.transferobjects.PartyContactDetailsTO;
import org.dcsa.edocumentation.transferobjects.PartyIdentifyingCodeTO;
import org.dcsa.edocumentation.transferobjects.PartyTO;
import org.dcsa.edocumentation.transferobjects.TaxAndLegalReferenceTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

Expand All @@ -15,15 +17,21 @@
AddressMapper.class,
PartyContactDetailsMapper.class,
PartyIdentifyingCodeMapper.class,
TaxAndLegalReferenceMapper.class
})
public interface PartyMapper {
@Mapping(source = "taxAndLegalReferences", target = "taxAndLegalReferences", ignore = true)
@Mapping(source = "partyContactDetails", target = "partyContactDetails", ignore = true)
@Mapping(source = "identifyingCodes", target = "identifyingCodes", ignore = true)
@Mapping(target = "id", ignore = true)
Party toDAO(PartyTO partyTo);
PartyTO toTO(Party party);


@Mapping(source = "party", target = "party")
@Mapping(source = "party.id", target = "id", ignore = true)
TaxAndLegalReference toDAO(TaxAndLegalReferenceTO taxAndLegalReferenceTO, Party party);

@Mapping(source = "party", target = "party")
@Mapping(source = "party.id", target = "id", ignore = true)
PartyContactDetails toDAO(PartyContactDetailsTO partyContactDetailsTO, Party party);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.dcsa.edocumentation.service.mapping;

import org.dcsa.edocumentation.domain.persistence.entity.PartyIdentifyingCode;
import org.dcsa.edocumentation.domain.persistence.entity.TaxAndLegalReference;
import org.dcsa.edocumentation.transferobjects.PartyIdentifyingCodeTO;
import org.dcsa.edocumentation.transferobjects.TaxAndLegalReferenceTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper(
componentModel = "spring",
config = EDocumentationMappingConfig.class
)
public interface TaxAndLegalReferenceMapper {
@Mapping(target = "id", ignore = true)
@Mapping(target = "party", ignore = true)
TaxAndLegalReference toDAO(TaxAndLegalReferenceTO taxAndLegalReferenceTO);

TaxAndLegalReferenceTO toTO(TaxAndLegalReference taxAndLegalReference);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,7 @@ public Party singleParty() {
return Party.builder()
.id(UUID.randomUUID())
.partyName("DCSA")
.taxReference1("1234567890")
.publicKey("""
-----BEGIN RSA PUBLIC KEY-----
MEgCQQCo9+BpMRYQ/dL3DS2CyJxRF+j6ctbT3/Qp84+KeFhnii7NT7fELilKUSnx
S30WAvQCCo2yU1orfgqr41mM70MBAgMBAAE=
-----END RSA PUBLIC KEY-----
""")
.taxAndLegalReferences(Set.of(TaxAndLegalReferencesDataFactory.singleTaxAndLegalReference()))
.address(AddressDataFactory.getSingleAddress())
.partyContactDetails(Set.of(PartyContactDetails.builder()
.id(UUID.randomUUID())
Expand Down
Loading