CustomsDeclaration.java

package com.tradecloud.domain.shipment.clearing;

import com.tradecloud.domain.common.Incoterm;
import com.tradecloud.domain.configuration.clearing.za.*;
import com.tradecloud.domain.dms.DocumentManagementHardCoding;
import com.tradecloud.domain.exception.DuplicateEntityException;
import com.tradecloud.domain.export.ChangeAcknowledgementIndicator;
import com.tradecloud.domain.export.EdifactStatus;
import com.tradecloud.domain.export.ExportParty;
import com.tradecloud.domain.model.ordermanagement.SalesOrder;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.domain.model.payment.PaymentTerm;
import com.tradecloud.domain.model.shipment.ShippingMode;
import com.tradecloud.domain.party.Bank;
import com.tradecloud.domain.party.Employee;
import com.tradecloud.domain.party.ServiceProvider;
import com.tradecloud.domain.party.base.Company;
import com.tradecloud.domain.place.*;
import com.tradecloud.domain.sars.SARSShipment;
import com.tradecloud.domain.sars.Status;
import com.tradecloud.domain.shipment.AirShipment;
import com.tradecloud.domain.shipment.MultiModalShipment;
import com.tradecloud.domain.shipment.SeaShipment;
import com.tradecloud.domain.useraudit.UserAudit;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.JoinFormula;

import javax.persistence.*;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Entity
@Getter
@Setter
public class CustomsDeclaration extends BaseClearingInstruction implements SARSShipment, Cloneable {

    private static final List<Status> EDITABLE_STATES = Arrays.asList(Status.NEW, Status.REJECTED, Status.REOPENED, Status.OUT_OF_SYNC,
            Status.FAILED);

    @ManyToOne(fetch = FetchType.LAZY)
    private PlaceOfCustom clearingTerminal;
    @Transient
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @Fetch(value = FetchMode.SUBSELECT)
    @XmlElementWrapper(name = "ClearingEvents")
    @XmlElement(name = "ClearingEvent")
    @OrderBy("createDateTime")
    protected List<ClearingEvent> events = new LinkedList<>();

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinFormula("(SELECT MAX(CustomsDeclaration_clearingevent.events_id) " +
            "FROM CustomsDeclaration_clearingevent left join ClearingEvent on CustomsDeclaration_clearingevent.events_id = ClearingEvent.id " +
            "WHERE CustomsDeclaration_clearingevent.customsdeclaration_id = id)")
    //TODO: replace with: @Column(name = "formula_col", insertable = false, updatable = false)
    //@ColumnTransformer(read = "(FORMULA SQL)")
    protected ClearingEvent lastEvent;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @Fetch(value = FetchMode.SUBSELECT)
    @XmlElementWrapper(name = "ClearingEvents")
    @XmlElement(name = "ClearingEvent")
    @OrderBy("createDateTime")
    @JoinTable(name = "customsdeclaration_sarsevent",
            joinColumns = {@JoinColumn(name = "customsdeclaration_id", unique = false)},
            inverseJoinColumns = {@JoinColumn(name = "events_id", unique = true)})
    private List<SarsEvent> sarsEvents = new LinkedList<>();

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinFormula("(SELECT MAX(customsdeclaration_sarsevent.events_id) " +
            "FROM customsdeclaration_sarsevent left join SarsEvent on customsdeclaration_sarsevent.events_id = SarsEvent.id " +
            "WHERE customsdeclaration_sarsevent.customsdeclaration_id = id)")
    private SarsEvent lastSarsEvent;

    @ManyToOne
    private PlaceOfCustom placeOfCustomsEntry;
    @ManyToOne
    private Country warehouseCountryOfDestination;
    @Enumerated(value = EnumType.STRING)
    private ContainerCargoState containerCargoState;
    @Enumerated(EnumType.STRING)
    private EdifactStatus edifactStatus;
    @Enumerated(value = EnumType.STRING)
    protected PurposeCode purposeCode;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @Fetch(value = FetchMode.SUBSELECT)
    @OrderBy("created")
    protected List<CustomsDocument> customsDocuments = new LinkedList<>();

    private int numberOfPackages;
    private int totalNumberOfPackages;
    @Size(max = 350)
    private String marksAndNumbers;
    private Date declarationDate;
    protected BigInteger number;
    private String caseNumber;
    private String mrnNumber;
    private String lrnNumber;
    private Date assessmentDate;
    private String billOfEntryNumber;
    private Long originalDeclarationID;
    private boolean pendingOutOfSync;
    private boolean pendingCancellation;
    private boolean vatInvoice;
    private boolean vatRefundRequired;
    private BigDecimal expectedPayment;
    private Date reopenedTime;
    private int reopenedCount;
    private String ucrNumber;
    private String documentsProduced;
    private BigDecimal customsOverriddenTotal;

    private String customsFinancialAccountNumber;
    @Enumerated(EnumType.STRING)
    private CustomsFinancialAccountOwner customsFinancialAccountOwner;

    @Size(max = 255)
    private String amendReason;
    @Enumerated(value = EnumType.STRING)
    private DeclarationType declarationType = DeclarationType.RDC_REGULAR_COMPLETE;

    @OneToMany(fetch = FetchType.LAZY)
    @Fetch(value = FetchMode.SUBSELECT)
    @OrderBy("created")
    protected List<UserAudit> userAudits = new LinkedList<>();

    @Enumerated(value = EnumType.STRING)
    private ChangeAcknowledgementIndicator changeAcknowledgementIndicator;
    @ManyToOne
    @org.hibernate.annotations.ForeignKey(name = "receivingbank_id")
    private Bank receivingBank;
    @ManyToOne
    @org.hibernate.annotations.ForeignKey(name = "export_paymentterm_fk")
    @XmlElement(name = "PaymentTerm")
    private PaymentTerm paymentTerm;

    //refund fields
    @Enumerated(value = EnumType.STRING)
    private VOCCostResponsible vocCostResponsible;
    @Enumerated(value = EnumType.STRING)
    private RefundType refundType;
    @Size(max = 255)
    private String refundAdditional;
    @ManyToOne(fetch = FetchType.LAZY)
    private ServiceProvider refundApplicant;
    @ManyToOne(fetch = FetchType.EAGER)
    private Employee refundApplicantRepresentative;
    @ManyToOne(fetch = FetchType.LAZY)
    private City refundPlace;
    private Date refundDate;
    @Size(max = 255)
    private String refundReason;
    private BigDecimal refundAmount = BigDecimal.ZERO;
    private BigDecimal currentAmountDue = BigDecimal.ZERO;

    protected BigInteger positionInShipment;
    private String extendedCustomsProcedurePrevious;
    private int lastBillOfEntryLineNumber = 0;
    private transient List<String> comments;
    private boolean noHouseBill;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @Fetch(value = FetchMode.SUBSELECT)
    @OrderBy("created")
    private List<CustomsDeclarationCostedValues> costedValues;
    @Enumerated(EnumType.STRING)
    private ClearingPaymentTerm clearingPaymentTerm;
    private String printIndicator;

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<AdditionalClearingInfo> additionalClearingInfo;
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
    private Set<AdvancedPayment> advancedPayments;

    public ContainerCargoState getContainerCargoState() {
        return containerCargoState;
    }

    public void setContainerCargoState(ContainerCargoState containerCargoState) {
        this.containerCargoState = containerCargoState;
    }

    public SarsEvent getLastSarsEvent() {
        return lastSarsEvent;
    }

    public void setPlaceOfCustomsEntry(PlaceOfCustom placeOfCustomsEntry) {
        this.placeOfCustomsEntry = placeOfCustomsEntry;
    }

    @Override
    public PlaceOfCustom getPlaceOfCustomsEntry() {
        return placeOfCustomsEntry;
    }

    @Override
    public Country getCountryOfDestination() {
        return warehouseCountryOfDestination;
    }

    public List<SarsEvent> getSarsEvents() {
        return sarsEvents;
    }

    public void setSarsEvents(List<SarsEvent> sarsEvents) {
        this.sarsEvents = sarsEvents;
    }

    public Country getWarehouseCountryOfDestination() {
        return warehouseCountryOfDestination;
    }

    public void setWarehouseCountryOfDestination(Country warehouseCountryOfDestination) {
        this.warehouseCountryOfDestination = warehouseCountryOfDestination;
    }

    public int getNumberOfPackages() {
        return numberOfPackages;
    }

    public void setNumberOfPackages(int numberOfPackages) {
        this.numberOfPackages = numberOfPackages;
    }

    public int getTotalNumberOfPackages() {
        return totalNumberOfPackages;
    }

    public void setTotalNumberOfPackages(int totalNumberOfPackages) {
        this.totalNumberOfPackages = totalNumberOfPackages;
    }

    public Date getActualDepartureDate() {
        return getShipment().getArrivalDateAtPlaceOfDischarge() != null ? getShipment().getArrivalDateAtPlaceOfDischarge() :
                getShipment().getEstimatedArrivalDateAtPlaceOfDischarge();
    }

    @Override
    public PlaceOfCustom getPortOfExit() {
        return null;
    }

    @Override
    public OrganisationalUnit getParty() {
        return getImporter();
    }

    @Override
    public String findChangeAcknowledgementIndicatorNumberStr(String s) {
        ChangeAcknowledgementIndicator ack = getChangeAcknowledgementIndicator();
        return (ack != null && ack.getStatusNumber() != 0) ? ack.getStatusNumber().toString() : s;
    }

    public ChangeAcknowledgementIndicator getChangeAcknowledgementIndicator() {
        return changeAcknowledgementIndicator;
    }

    public void setChangeAcknowledgementIndicator(ChangeAcknowledgementIndicator changeAcknowledgementIndicator) {
        this.changeAcknowledgementIndicator = changeAcknowledgementIndicator;
    }

    @Override
    public boolean isVatInvoice() {
        return vatInvoice;
    }

    public void setVatInvoice(boolean vatInvoice) {
        this.vatInvoice = vatInvoice;
    }

    @Override
    public String getTransportDocumentNumber() {
        return switch (shipment.getShippingMode()) {
            case SEA -> ((SeaShipment) shipment).getMasterBillOfLadingReference();
            case AIR -> ((AirShipment) shipment).getMasterAirwayBillNumber();
            default -> null;
        };
    }

    @Override
    public Date getTransportDocumentDate() {
        return switch (shipment.getShippingMode()) {
            case SEA -> ((SeaShipment) shipment).getMasterBillOfLadingDate();
            case AIR -> ((AirShipment) shipment).getMasterAirwayBillIssueDate();
            default -> null;
        };
    }

    @Override
    public EdifactStatus getEdifactStatus() {
        if (edifactStatus == null) {
            edifactStatus = EdifactStatus.BLANK;
        }
        return edifactStatus;
    }

    public PlaceOfLoading getPlaceOfLoading() {
        return getShipment().getShippingInfo().getPlaceOfLoading();
    }

    public PlaceOfDischarge getPlaceOfDischarge() {
        return getShipment().getShippingInfo().getPlaceOfDischarge();
    }

    @Override
    public PaymentTerm getPaymentTerm() {
        return paymentTerm;
    }

    @Override
    public void setPaymentTerm(PaymentTerm paymentTerm) {
        this.paymentTerm = paymentTerm;
    }

    @Override
    public void setEdifactStatus(EdifactStatus edifactStatus) {
        this.edifactStatus = edifactStatus;
    }

    @Override
    public Date getBillOfEntryDate() {
        //JSA202107265191106
        if (mrnNumber != null) {
            try {
                return sdf.parse(getMrnNumber().substring(3, 11));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public String getUcrNumber() {
        return ucrNumber;
    }

    @Override
    public String getVehicleRegistration() {
        return null;
    }

    @Override
    public Company getAgent() {
        if (shipment.isImports())
            return shipment.getOrders().get(0).getSupplier().getCompany();
        else
            return ((SalesOrder) shipment.getOrders().get(0)).getExportParty();
    }

    @Override
    public String getExtendedCustomsProcedurePrevious() {
        return extendedCustomsProcedurePrevious != null ? extendedCustomsProcedurePrevious : "00";
    }

    public void setExtendedCustomsProcedurePrevious(String code) {
        extendedCustomsProcedurePrevious = code;
    }

    @Override
    public String getExtendedCustomsProcedureRequested() {
        return "" + getPurposeCode().getCpcCode();
    }

    @Override
    public Long getPreviousCuscarId() {
        return null;
    }

    @Override
    public ServiceProvider getTransporterServiceProvider() {
        return null;
    }

    @Override
    public ExportParty getExportConsignee() {
        if (!shipment.isImports()) {
            if (shipment.getShippingInfo().getShipToParty() == null)
                return ((SalesOrder) shipment.getOrders().get(0)).getExportParty();
            else
                return shipment.getShippingInfo().getShipToParty();
        }
        return null;
    }

    @Override
    public Country getCountryOfExport() {
        return shipment.getShippingInfo().getCountryOfExport();
    }

    @Override
    public String getLrnNumber() {
        if (lrnNumber == null) {
            StringBuilder sb = new StringBuilder();
            String customsCode = getClearingAgent() != null ? getClearingAgent().getCustomsCode() : null;
            sb.append(customsCode);
            String code = getPlaceOfCustomsEntry() != null ? getPlaceOfCustomsEntry().getCode() : null;
            sb.append(code);
            sb.append(getDeclarationDate() != null ? sdf.format(getDeclarationDate()) : "");
            sb.append(ObjectUtils.firstNonNull(StringUtils.leftPad("" + number, 6, "0"), "000000"));

            //If any of the required fields are null, do not return genrated lrn
            if (ObjectUtils.anyNull(customsCode, code, getDeclarationDate(), number))
                return null;

            return sb.toString();
        }

        return lrnNumber;
    }

    @Override
    public Employee getDriver() {
        return null;
    }

    @Override
    public Employee getCoDriver() {
        return null;
    }

    @Override
    public String getTrailerRegistration2() {
        return null;
    }

    @Override
    public String getTrailerRegistration1() {
        return null;
    }

    @Override
    public void setCusdecId(Long id) {
    }

    @Override
    public void setUcrNumber(String ucrNumber) {
        this.ucrNumber = ucrNumber;
    }

    @Override
    public String getExportersReference() {
        return null;
    }

    @Override
    public Long getCusdecId() {
        return null;
    }

    @Override
    public String getManifestNumber() {
        StringBuilder sb = new StringBuilder();

        switch (shipment.getShippingMode()) {
            case SEA:
                sb.append(((SeaShipment) shipment).getMasterBillOfLadingReference());
                sb.append(sdf.format(((SeaShipment) shipment).getMasterBillOfLadingDate()));
                sb.append(shipment.getBillPlaceOfIssue().getCode());
                break;
            case AIR:
                sb = new StringBuilder();
                sb.append(((AirShipment) shipment).getMasterAirwayBillNumber());
                sb.append(sdf.format(((AirShipment) shipment).getMasterAirwayBillIssueDate()));
                sb.append(shipment.getBillPlaceOfIssue().getCode());
                break;
        }
        return sb.toString();
    }

    public City getPlaceOfIssue() {
        return switch (shipment.getShippingMode()) {
            case SEA -> shipment.getBillPlaceOfIssue();
            case AIR -> shipment.getBillPlaceOfIssue();
            default -> null;
        };
    }

    public String getMarksAndNumbers() {
        return marksAndNumbers;
    }

    public void setMarksAndNumbers(String marksAndNumbers) {
        this.marksAndNumbers = marksAndNumbers;
    }

    @Override
    public PlaceOfCustom getClearingTerminal() {
        return clearingTerminal;
    }

    public void setClearingTerminal(PlaceOfCustom clearingTerminal) {
        this.clearingTerminal = clearingTerminal;
    }

    public Date getDeclarationDate() {
        return declarationDate;
    }

    public void setDeclarationDate(Date declarationDate) {
        this.declarationDate = declarationDate;
    }

    @Override
    public Date getEstimatedArrivalDate() {
        return shipment.getEstimatedArrivalDateAtPlaceOfDischarge();
    }

    @Override
    public Date getPresentationOfGoodsDate() {
        return assessmentDate != null ? assessmentDate : declarationDate;
        //return declarationDate;
    }

    @Override
    public String getShipmentNumber() {
        return getShipment().getReference();
    }

    @Override
    public Bank getReceivingBank() {
        return receivingBank;
    }

    public void setReceivingBank(Bank receivingBank) {
        this.receivingBank = receivingBank;
    }

    public BigInteger getNumber() {
        return number;
    }

    public void setNumber(BigInteger number) {
        this.number = number;
    }

    public ClearingEvent getLastStatus() {
        return lastEvent;
    }

    public List<ClearingEvent> getEvents() {
        if (events == null) {
            events = new LinkedList<>();
        }
        return events;
    }

    @Override
    public ClearingEvent getLastEvent() {
        return lastEvent;
    }

    public void setEvents(List<ClearingEvent> events) {
        this.events = events;
    }

    public void addClearingEvent(ClearingEvent clearingEvent) {
        this.getEvents().add(clearingEvent);
    }

    public void setCaseNumber(String caseNumber) {
        this.caseNumber = caseNumber;
    }

    @Override
    public String getCaseNumber() {
        return caseNumber;
    }

    @Override
    public String getMrnNumber() {
        return mrnNumber;
    }

    public void setMrnNumber(String mrnNumber) {
        this.mrnNumber = mrnNumber;
    }

    public List<CustomsDocument> getCustomsDocuments() {
        if (customsDocuments == null) {
            customsDocuments = new ArrayList<>();
        }
        return customsDocuments;
    }

    public void addCustomsDocument(CustomsDocument customsDocument) {
        customsDocument.setCustomsDeclaration(this);
        getCustomsDocuments().add(customsDocument);
    }

    @Override
    public boolean inNonEditableState() {
        return !EDITABLE_STATES.contains(this.status);
    }

    public List<UserAudit> getUserAudits() {
        if (userAudits == null) {
            userAudits = new ArrayList<>();
        }
        return userAudits;
    }

    public void setPositionInShipment(BigInteger positionInShipment) {
        this.positionInShipment = positionInShipment;
    }

    public void setLrnNumber(String lrnNumber) {
        //only set it once, no changes allowed. the getLrn will generate new until mrn is received from sars
        if (this.lrnNumber == null) {
            this.lrnNumber = lrnNumber;
        }
    }

    /*This allows the LRN to be set for a manual declaration*/
    public void allowManualLrnUpdate(String lrnNumber) {
        this.lrnNumber = lrnNumber;
    }

    public BigDecimal getRefundAmount() {
        CustomsDeclarationCostedValues before = getCostedValues(CustomsDeclarationCostedValues.Type.BEFORE_CORRECTION, 0);
        //YFG-242: if this is a second or greater number VOC, use the after values
        if (reopenedCount > 1)
            before = getCostedValues(CustomsDeclarationCostedValues.Type.AFTER_CORRECTION, getReopenedCount());
        if (before != null && before.getAmountDue() != null && currentAmountDue != null) {
            refundAmount = before.getAmountDue().subtract(currentAmountDue);
        }
        if (refundAmount == null)
            refundAmount = BigDecimal.ZERO;

        return refundAmount;
    }

    public void setRefundAmount(BigDecimal refundAmount) {
        //this.refundAmount = refundAmount;
    }

    public boolean isCustomsDeclaration() {
        return true;
    }

    @Override
    public String getDocumentGroupName() {
        return DocumentManagementHardCoding.CUSTOMS_DECLARATION.getDocumentManagementHardCodedName();
    }

    public SarsEvent getSarsEvent(EdifactStatus edifactStatus) {
        List<SarsEvent> events = getSarsEvents();

        if (events == null)
            return null;

        for (SarsEvent event : events) {
            if (event.getEventType() == edifactStatus) {
                return event;
            }
        }
        return null;
    }

    public boolean getSarsEventNewerThan(EdifactStatus newer, EdifactStatus older) {
        List<SarsEvent> events = getSarsEvents();

        if (events == null)
            return false;

        Collections.reverse(events);

        boolean foundNewer = false;
        for (SarsEvent event : events) {
            if (event.getEventType() == newer) {
                foundNewer = true;
            }
            if (foundNewer && event.getEventType() == older)
                return true;
        }
        return false;
    }

    public SarsEvent getSarsEventBefore(EdifactStatus eventFrom) {
        List<SarsEvent> events = getSarsEvents();

        if (events == null)
            return null;

        Collections.reverse(events);

        int index = 0;
        for (SarsEvent event : events) {
            if (event.getEventType() == eventFrom) {
                if (index <= events.size() - 2)
                    return events.get(index + 1);
            }
            index++;

        }
        return null;
    }

    public List<CustomsDeclarationCostedValues> getCostedValues() {
        if (costedValues == null)
            costedValues = new ArrayList<>();
        return costedValues;
    }

    public void setCostedValues(List<CustomsDeclarationCostedValues> costedValues) {
        this.costedValues = costedValues;
    }

    public void addCostedValues(CustomsDeclarationCostedValues costedValues) {
        if (getCostedValues(costedValues.getType(), getReopenedCount()) != null) {
            throw new DuplicateEntityException("Values for type already exist: " + costedValues.getType().name());
        }
        getCostedValues().add(costedValues);
    }

    public CustomsDeclarationCostedValues getCostedValues(CustomsDeclarationCostedValues.Type type, Integer version) {
        return getCostedValues().stream().filter(p -> p.getType().equals(type) && (p.getVersion() == null ||
                (p.getVersion() != null && version != null &&
                        p.getVersion().intValue() == version.intValue()))).findFirst().orElse(null);
    }

    @Override
    public ShippingMode getShippingMode() {
        return getShipment().getShippingMode();
    }

    @Override
    public String getInvoiceNumber() {
        return getShipment().getActiveCommercialInvoices().get(0).getReference();
    }

    @Override
    public Incoterm getIncoterm() {
        return getShipment().getIncoterm();
    }

    public Set<AdditionalClearingInfo> getAdditionalClearingInfo() {
        return additionalClearingInfo;
    }

    public void setAdditionalClearingInfo(Set<AdditionalClearingInfo> additionalClearingInfo) {
        if (this.additionalClearingInfo == null)
            this.additionalClearingInfo = new HashSet<>();
        if (additionalClearingInfo != null) {
            this.additionalClearingInfo.clear();
            this.additionalClearingInfo.addAll(additionalClearingInfo);
        }
    }

    public Set<AdvancedPayment> getAdvancedPayments() {
        return advancedPayments;
    }

    public void setAdvancedPayments(Set<AdvancedPayment> advancedPayments) {
        if (this.advancedPayments == null)
            this.advancedPayments = new HashSet<>();
        if (advancedPayments != null) {
            this.advancedPayments.clear();
            this.advancedPayments.addAll(advancedPayments.stream().limit(5).collect(Collectors.toSet()));
        }
    }

    public void addAdvancedPaymentDTO(AdvancedPayment dto) {
        if (getAdvancedPayments() == null)
            advancedPayments = new HashSet<>();
        advancedPayments.add(dto);
    }

    public void addAdditionalClearingInfoDTO(AdditionalClearingInfo dto) {
        if (additionalClearingInfo == null)
            additionalClearingInfo = new HashSet<>();
        additionalClearingInfo.add(dto);
    }

    public void setDocumentsProduced(String documentsProduced) {
        this.documentsProduced = documentsProduced;
    }

    public MultiModalShipment getMultiModalShipment() {
        return null; //TODO implement
    }

    public void setCustomsOverriddenTotal(BigDecimal customsOverriddenTotal) {
        if (customsOverriddenTotal != null)
            this.customsOverriddenTotal = customsOverriddenTotal;
    }
}