Export.java

package com.tradecloud.domain.export;

import com.tradecloud.authentication.User;
import com.tradecloud.common.base.PersistenceBase;
import com.tradecloud.domain.agent.Agent;
import com.tradecloud.domain.common.Incoterm;
import com.tradecloud.domain.common.IncotermYear;
import com.tradecloud.domain.configuration.clearing.za.*;
import com.tradecloud.domain.costing.clean.CostLineNames;
import com.tradecloud.domain.dms.DocumentManagementHardCoding;
import com.tradecloud.domain.model.DMSLinked;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.domain.model.payment.PaymentMethod;
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.Contact;
import com.tradecloud.domain.place.*;
import com.tradecloud.domain.sars.SARSShipment;
import com.tradecloud.domain.sars.Status;
import com.tradecloud.domain.shipment.clearing.AdditionalClearingInfo;
import com.tradecloud.domain.shipment.clearing.AdvancedPayment;
import com.tradecloud.domain.shipment.clearing.ClearingEvent;
import com.tradecloud.domain.shipment.clearing.DeclarationType;
import com.tradecloud.domain.state.Stateful;
import org.hibernate.annotations.*;
import org.hibernate.annotations.ForeignKey;
import org.springframework.stereotype.Component;

import javax.persistence.*;
import javax.persistence.AccessType;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.*;

@Entity
@Component(value = "Export")
@Table(name = "export")
@Access(AccessType.FIELD)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Export")
public class Export extends PersistenceBase implements Comparable<Export>, SARSShipment, Stateful<Status, ClearingEvent>, DMSLinked {

    private static final Long serialVersionUID = 1L;
    private String trailerRegistration2;
    private String trailerRegistration1;

    private static final List<Status> EDITABLE_STATES = Arrays.asList(Status.NEW, Status.REJECTED, Status.REOPENED, Status.AWAITING_CARTONS,
            Status.AWAITING_TARIFFING, Status.AWAITING_COSTING, Status.IN_TRANSIT, Status.FINALISED);
    @Transient
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @Fetch(value = FetchMode.SUBSELECT)
    @XmlElementWrapper(name = "ExportEvents")
    @XmlElement(name = "ExportEvent")
    @OrderBy("createDateTime")
    @JoinTable(name = "export_exportevent",
            joinColumns = @JoinColumn(name = "export_id"),
            inverseJoinColumns = @JoinColumn(name = "events_id", unique = true))
    protected List<ClearingEvent> events = new LinkedList();

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinFormula("(SELECT MAX(export_exportevent.events_id) " +
            "FROM export_exportevent left join ClearingEvent on export_exportevent.events_id = clearingevent.id " +
            "WHERE export_exportevent.export_id = id)")
    protected ClearingEvent lastEvent;

    @NotNull(message = "")
    @XmlAttribute(required = true)
    private String shipmentNumber;

    @XmlElement
    private String sarsStatus;

    private String carnNo;

    @ManyToOne
    @ForeignKey(name = "export_exporter_fk")
    @XmlElement(name = "Exporter")
    private OrganisationalUnit exporter;

    @ManyToOne
    @ForeignKey(name = "export_exportconsignee_fk")
    @XmlElement(name = "ExportConsignee")
    private ExportParty exportConsignee;

    @ManyToOne
    @ForeignKey(name = "export_agent_fk")
    @XmlElement(name = "ExportAgent")
    private Agent agent;

    @ManyToOne
    @ForeignKey(name = "export_notifyparty_fk")
    @XmlElement(name = "NotifyParty")
    private ExportParty notifyParty;

    @ManyToOne
    @ForeignKey(name = "export_shiptoparty_fk")
    @XmlElement(name = "ShipToParty")
    private ExportParty shipToParty;

    @ManyToOne
    @ForeignKey(name = "export_countryofexport_fk")
    @XmlElement(name = "CountryOfExport")
    private Country countryOfExport;

    @ManyToOne
    @ForeignKey(name = "export_countryoftransit_fk")
    @XmlElement(name = "CountryOfTransit")
    private Country countryOfTransit;

    @ManyToOne
    @ForeignKey(name = "export_countryofdestination_fk")
    @XmlElement(name = "CountryOfDestination")
    private Country countryOfDestination;

    @ManyToOne
    @ForeignKey(name = "export_cityofdestination_fk")
    @XmlElement(name = "CityOfDestination")
    private FinalDestination cityOfDestination;

    @ManyToOne
    @ForeignKey(name = "export_cityofexport_fk")
    @XmlElement(name = "CityofExport")
    private NamedPlace cityOfExport;

    @Column(name = "shipmentcargosummary")
    private String shipmentCargoSummary;

    @ManyToOne
    @ForeignKey(name = "export_shipper_fk")
    @XmlElement(name = "Shipper")
    private OrganisationalUnit shipper;

    @ManyToOne
    @ForeignKey(name = "export_localshippingagent_fk")
    @XmlElement(name = "LocalShippingAgent")
    private ServiceProvider localShippingAgent;

    @ManyToOne
    @ForeignKey(name = "export_freightforwarder_fk")
    @XmlElement(name = "FreightForwarder")
    private ServiceProvider freightForwarder;

    @OneToMany(mappedBy = "export", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    private Set<ExportCostLine> exportCostLines = new HashSet<>();

    @OneToOne
    private Contact reportContact;
    @OneToOne
    private Employee driver;
    @OneToOne
    private Employee coDriver;

    private String exportersReference;
    private String buyersReference;
    private String bookingReference;
    private String freightForwardersReference;
    private String inspectionNumber;
    private String cleanReportInspectionNo;
    private String containerType;
    private String containerQuantity;
    private String wayBillNumber;
    private String footer;
    private Boolean distributeLineItemsByWeight;
    private BigDecimal capturedShipmentGrossWeight;
    private Long previousCuscarId;
    private boolean produceExportManifest;
    private boolean integrated;
    private boolean cartonBased;
//    @OneToMany(orphanRemoval = false)
//    private Set<ExportInvoice> exportInvoices = new LinkedHashSet<ExportInvoice>();

    @Basic(fetch = FetchType.LAZY)
    @Formula(value = "(select count(*) from exportinvoice e join costsinvoice inv on (inv.id=e.id) join export s on (s.id=e.export_id)" +
            " where  s.id=id and inv.state<>'DELETED' and e.ignored ='t' ) ")
    private long numberOfCartons;

    public String getWayBillNumber() {
        return wayBillNumber;
    }

    public void setWayBillNumber(String wayBillNumber) {
        this.wayBillNumber = wayBillNumber;
    }

    @XmlElementWrapper(name = "ExportContainers")
    @XmlElement(name = "ExportContainer")
    @ForeignKey(name = "export_fk")
    @OneToMany(mappedBy = "export", fetch = FetchType.LAZY, cascade = {CascadeType.ALL}, orphanRemoval = true)
    private Set<ExportContainer> exportContainers = new LinkedHashSet<>();
    // SAD500
    @Column(name = "customsprocedurecategory")
    private String customsProcedureCategory;

    // @Column(name = "portofexit_code")
    // private String portOfExit;
    @ManyToOne
    @ForeignKey(name = "fk_portofexit_code")
    private PlaceOfCustom portOfExit;

    @Column(name = "cargostatus")
    private String cargoStatus;

    @ManyToOne
    @ForeignKey(name = "declarant_id")
    private User declarant;
    private String declarantNumber;

    @ManyToOne
    @ForeignKey(name = "receivingbank_id")
    private Bank receivingBank;

    private String marksAndNumbers;
    private Integer numberOfPackages;
    private String extendedCustomsProcedureRequested;
    private String extendedCustomsProcedurePrevious;

    @Temporal(TemporalType.TIMESTAMP)
    private Date sad500DateOfIssue;
    // Transport
    @Enumerated(value = EnumType.STRING)
    private ShippingMode modeOfTransport;
    private String vehicleRegistration;

    @ManyToOne
    @ForeignKey(name = "export_placeofloading_fk")
    @XmlElement(name = "PlaceOfLoading")
    private PlaceOfLoading placeOfLoading;

    @ManyToOne
    @ForeignKey(name = "export_placeofdischarge_fk")
    @XmlElement(name = "PlaceOfDischarge")
    private PlaceOfDischarge placeOfDischarge;

    @Temporal(TemporalType.TIMESTAMP)
    private Date actualDepartureDate;
    private Date estimateDepartureDate;

    @Temporal(TemporalType.TIMESTAMP)
    private Date estimatedArrivalDate;

    private Integer sarsApprovalDispatchExtension;
    private String transportDocumentNumber;

    @ManyToOne
    @ForeignKey(name = "fk_transportdocumentplaceofissue_code")
    private PlaceOfCustom transportdocumentplaceofissue;

    @Temporal(TemporalType.TIMESTAMP)
    private Date transportDocumentDateOfIssue;

    private String billOfEntryNumber;
    @Temporal(TemporalType.TIMESTAMP)
    private Date billOfEntryDate;

    private String lrnNumber;

    private String mrnNumber;

    @Enumerated(value = EnumType.STRING)
    private ChangeAcknowledgementIndicator changeAcknowledgementIndicator;

    @ManyToOne
    @ForeignKey(name = "fk_placeofcustomsentry")
    private PlaceOfCustom placeOfCustomsEntry;

    @ManyToOne
    @ForeignKey(name = "fk_placeofcustomtransitsentry")
    private PlaceOfCustom placeOfCustomsTransitEntry;

    @ManyToOne
    @ForeignKey(name = "fk_placeofcustomtransitsexit")
    private PlaceOfCustom placeOfCustomsTransitExit;

    private String comments;
    private String specialInstructions;
    private String packageMarkings;
    @ManyToOne
    @ForeignKey(name = "export_transporter_fk")
    @XmlElement(name = "Transporter")
    private ServiceProvider transporter;

    private Double insuranceFactor;
    private Double insuranceRate;
    private boolean vatInvoice;

    @ManyToOne
    @ForeignKey(name = "export_paymentmethod_fk")
    @XmlElement(name = "PaymentMethod")
    private PaymentMethod paymentMethod;

    @ManyToOne
    @ForeignKey(name = "export_paymentterm_fk")
    @XmlElement(name = "PaymentTerm")
    private PaymentTerm paymentTerm;

    @Column(name = "currency_code")
    private String currency;
    private Double exchangeRate;
    private String ucrNumber;

    @ManyToOne
    @ForeignKey(name = "export_incotermyear_fk")
    @XmlElement(name = "IncoTermYear")
    private IncotermYear incotermYear;

    @ManyToOne
    @ForeignKey(name = "export_invoicedparty_fk")
    @XmlElement(name = "InvoicedParty")
    private ExportParty invoicedParty;

    @ManyToOne
    @ForeignKey(name = "export_authorisedbankdealer_id_fkey")
    private Bank authorisedBankDealer;

    @Column(name = "contractterms_code")
    private String contractTerm;

    @ManyToOne
    @ForeignKey(name = "invoiceapprover_id")
    private User invoiceApprover;

    @Temporal(TemporalType.TIMESTAMP)
    private Date invoiceCreatedDate;

    // costs
    @ManyToOne
    @ForeignKey(name = "export_incoterm_fk")
    @XmlElement(name = "IncoTerm")
    private Incoterm incoterm;

    private Integer documentBatch;
    private Integer lastLineCount;
    private String caseNumber;
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastSubmissionDate;
    private String lastAcceptedCode;
    private Double lastTransactionValue;
    private String changeReason;
    private String cancelReason;
    private Long cusdecId;
    private Long cuscarId;
    private String vesselName;
    private String voyageNumber;
    private String flightNumber;
    private String shipmentType;
    private boolean cusdecProceedToBorderReceived;

    @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true)
    private ExportCosting exportCosting = new ExportCosting();
    @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 String getVesselName() {
        return vesselName;
    }

    public void setVesselName(String vesselName) {
        this.vesselName = vesselName;
    }

    public String getVoyageNumber() {
        return voyageNumber;
    }

    public void setVoyageNumber(String voyageNumber) {
        this.voyageNumber = voyageNumber;
    }

    public String getShipmentType() {
        return shipmentType;
    }

    public void setShipmentType(String shipmentType) {
        this.shipmentType = shipmentType;
    }

    public String getFlightNumber() {
        return flightNumber;
    }

    public void setFlightNumber(String flightNumber) {
        this.flightNumber = flightNumber;
    }

    @Enumerated(value = EnumType.STRING)
    private EdifactStatus edifactStatus;

    @Enumerated(value = EnumType.STRING)
    private Status exportStatus;

    @ManyToOne
    @ForeignKey(name = "depot")
    @XmlElement(name = "Depot")
    private Depot depot;

    @ManyToOne
    @XmlElement(name = "ServiceProvider")
    @ForeignKey(name = "fk_carrier_id")
    private ServiceProvider carrier;

    public ServiceProvider getCarrier() {
        return carrier;
    }

    public void setCarrier(ServiceProvider carrier) {
        this.carrier = carrier;
    }

    public Export() {
    }

    public Status getStatus() {
        return exportStatus;
    }

    public void setExportStatus(Status exportStatus) {
        this.exportStatus = exportStatus;
    }

    public Status getExportStatus() {
        return exportStatus;
    }

    public String getShipmentNumber() {
        return shipmentNumber;
    }

    public void setShipmentNumber(String shipmentNumber) {
        this.shipmentNumber = shipmentNumber;
    }

    public String getSarsStatus() {
        return sarsStatus;
    }

    public void setSarsStatus(String sarsStatus) {
        this.sarsStatus = sarsStatus;
    }

    public OrganisationalUnit getExporter() {
        return exporter;
    }

    public void setExporter(OrganisationalUnit exporter) {
        this.exporter = exporter;
    }

    public ExportParty getExportConsignee() {
        return exportConsignee;
    }

    public void setExportConsignee(ExportParty exportConsignee) {
        this.exportConsignee = exportConsignee;
    }

    public Agent getAgent() {
        return agent;
    }

    public void setAgent(Agent agent) {
        this.agent = agent;
    }

    public ExportParty getNotifyParty() {
        return notifyParty;
    }

    public void setNotifyParty(ExportParty notifyParty) {
        this.notifyParty = notifyParty;
    }

    public ExportParty getShipToParty() {
        return shipToParty;
    }

    public void setShipToParty(ExportParty shipToParty) {
        this.shipToParty = shipToParty;
    }

    public Country getCountryOfExport() {
        return countryOfExport;
    }

    public Country getCountryOfTransit() {
        return countryOfTransit;
    }

    public void setCountryOfExport(Country countryOfExport) {
        this.countryOfExport = countryOfExport;
    }

    public void setCountryOfTransit(Country countryOfTransit) {
        this.countryOfTransit = countryOfTransit;
    }

    public Country getCountryOfDestination() {
        return countryOfDestination;
    }

    public void setCountryOfDestination(Country countryOfDestination) {
        this.countryOfDestination = countryOfDestination;
    }

    public FinalDestination getCityOfDestination() {
        return cityOfDestination;
    }

    public void setCityOfDestination(FinalDestination cityOfDestination) {
        this.cityOfDestination = cityOfDestination;
    }

    public NamedPlace getCityOfExport() {
        return cityOfExport;
    }

    public void setCityOfExport(NamedPlace cityOfExport) {
        this.cityOfExport = cityOfExport;
    }

    public String getShipmentCargoSummary() {
        return shipmentCargoSummary;
    }

    public void setShipmentCargoSummary(String shipmentCargoSummary) {
        this.shipmentCargoSummary = shipmentCargoSummary;
    }

    public OrganisationalUnit getShipper() {
        return shipper;
    }

    public void setShipper(OrganisationalUnit shipper) {
        this.shipper = shipper;
    }

    public String getContainertype() {
        return containerType;
    }

    public void setContainertype(String containertype) {
        this.containerType = containertype;
    }

    public String getContainerquantity() {
        return containerQuantity;
    }

    public void setContainerquantity(String containerquantity) {
        this.containerQuantity = containerquantity;
    }

    public Set<ExportContainer> getExportcontainers() {
        return exportContainers;
    }

    public void setExportcontainers(Set<ExportContainer> exportcontainers) {
        this.exportContainers = exportcontainers;
    }

    public void addExportcontainer(ExportContainer exportcontainer) {
        exportContainers.add(exportcontainer);
        exportcontainer.setExport(this);
    }

    public List<ExportContainer> getExportcontainerList() {
        return new ArrayList<ExportContainer>(exportContainers);
    }

    public ServiceProvider getLocalShippingAgent() {
        return localShippingAgent;
    }

    public void setLocalShippingAgent(ServiceProvider localShippingAgent) {
        this.localShippingAgent = localShippingAgent;
    }

    public ServiceProvider getFreightForwarder() {
        return freightForwarder;
    }

    public void setFreightForwarder(ServiceProvider freightForwarder) {
        this.freightForwarder = freightForwarder;
    }

    public String getExportersReference() {
        return exportersReference;
    }

    public void setExportersReference(String exportersreference) {
        this.exportersReference = exportersreference;
    }

    public String getBuyersReference() {
        return buyersReference;
    }

    public void setBuyersReference(String buyersReference) {
        this.buyersReference = buyersReference;
    }

    public String getBookingReference() {
        return bookingReference;
    }

    public void setBookingreference(String bookingreference) {
        this.bookingReference = bookingreference;
    }

    public String getFreightforwardersreference() {
        return freightForwardersReference;
    }

    public void setFreightforwardersreference(String freightforwardersreference) {
        this.freightForwardersReference = freightforwardersreference;
    }

    public String getInspectionnumber() {
        return inspectionNumber;
    }

    public void setInspectionnumber(String inspectionnumber) {
        this.inspectionNumber = inspectionnumber;
    }

    public String getCleanreportinspectionno() {
        return cleanReportInspectionNo;
    }

    public void setCleanreportinspectionno(String cleanreportinspectionno) {
        this.cleanReportInspectionNo = cleanreportinspectionno;
    }

    public String getCustomsprocedurecategory() {
        return customsProcedureCategory;
    }

    public void setCustomsprocedurecategory(String customsprocedurecategory) {
        this.customsProcedureCategory = customsprocedurecategory;
    }

    /*
     * public String getPortofexit() { return portOfExit; } public void
     * setPortofexit(String portofexit) { this.portOfExit = portofexit; }
     */

    public String getCargoStatus() {
        return cargoStatus;
    }

    public void setCargoStatus(String cargoStatus) {
        this.cargoStatus = cargoStatus;
    }

    public User getDeclarant() {
        return declarant;
    }

    public void setDeclarant(User declarant) {
        this.declarant = declarant;
    }

    public Date getSad500DateOfIssue() {
        return sad500DateOfIssue;
    }

    public void setSad500DateOfIssue(Date sad500DateOfIssue) {
        this.sad500DateOfIssue = sad500DateOfIssue;
    }

    public String getDeclarantnumber() {
        return declarantNumber;
    }

    public void setDeclarantnumber(String declarantnumber) {
        this.declarantNumber = declarantnumber;
    }

    public Bank getReceivingBank() {
        return receivingBank;
    }

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

    public String getMarksAndNumbers() {
        return marksAndNumbers;
    }

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

    public Integer getNumberOfPackages() {
        return numberOfPackages;
    }

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

    public String getExtendedCustomsProcedureRequested() {
        return extendedCustomsProcedureRequested;
    }

    public void setExtendedCustomsProcedureRequested(String extendedCustomsProcedureRequested) {
        this.extendedCustomsProcedureRequested = extendedCustomsProcedureRequested;
    }

    public String getExtendedCustomsProcedurePrevious() {
        return extendedCustomsProcedurePrevious;
    }

    public void setExtendedCustomsProcedurePrevious(String extendedCustomsProcedurePrevious) {
        this.extendedCustomsProcedurePrevious = extendedCustomsProcedurePrevious;
    }

    public ShippingMode getModeOfTransport() {
        return modeOfTransport;
    }

    public void setModeOfTransport(ShippingMode modeOfTransport) {
        this.modeOfTransport = modeOfTransport;
    }

    public String getVehicleRegistration() {
        return vehicleRegistration;
    }

    public void setVehicleRegistration(String vehicleRegistration) {
        this.vehicleRegistration = vehicleRegistration;
    }

    @Override
    public PlaceOfLoading getPlaceOfLoading() {
        return placeOfLoading;
    }

    public void setPlaceOfLoading(PlaceOfLoading placeOfLoading) {
        this.placeOfLoading = placeOfLoading;
    }

    @Override
    public PlaceOfDischarge getPlaceOfDischarge() {
        return placeOfDischarge;
    }

    public void setPlaceOfDischarge(PlaceOfDischarge placeOfDischarge) {
        this.placeOfDischarge = placeOfDischarge;
    }

    @Override
    public Date getActualDepartureDate() {
        return actualDepartureDate;
    }

    public void setActualDepartureDate(Date actualDepartureDate) {
        this.actualDepartureDate = actualDepartureDate;
    }

    public Date getEstimatedArrivalDate() {
        return estimatedArrivalDate;
    }

    public void setEstimatedArrivalDate(Date estimatedArrivalDate) {
        this.estimatedArrivalDate = estimatedArrivalDate;
    }

    public Integer getSarsApprovalDispatchExtension() {
        return sarsApprovalDispatchExtension;
    }

    public void setSarsApprovalDispatchExtension(Integer sarsApprovalDispatchExtension) {
        this.sarsApprovalDispatchExtension = sarsApprovalDispatchExtension;
    }

    public String getTransportDocumentNumber() {
        return transportDocumentNumber;
    }

    public void setTransportDocumentNumber(String transportDocumentNumber) {
        this.transportDocumentNumber = transportDocumentNumber;
    }

    public Date getTransportDocumentDateOfIssue() {
        return transportDocumentDateOfIssue;
    }

    public void setTransportDocumentDateOfIssue(Date transportDocumentDateOfIssue) {
        this.transportDocumentDateOfIssue = transportDocumentDateOfIssue;
    }

    public String getBillOfEntryNumber() {
        return billOfEntryNumber;
    }

    public void setBillOfEntryNumber(String billOfEntryNumber) {
        this.billOfEntryNumber = billOfEntryNumber;
    }

    public Date getBillOfEntryDate() {
        return billOfEntryDate;
    }

    public void setBillOfEntryDate(Date billOfEntryDate) {
        this.billOfEntryDate = billOfEntryDate;
    }

    public String getComments() {
        return comments;
    }

    public void setComments(String comments) {
        this.comments = comments;
    }

    public String getSpecialinstructions() {
        return specialInstructions;
    }

    public void setSpecialinstructions(String specialinstructions) {
        this.specialInstructions = specialinstructions;
    }

    public String getPackagemarkings() {
        return packageMarkings;
    }

    public void setPackagemarkings(String packagemarkings) {
        this.packageMarkings = packagemarkings;
    }

    @Column(name = "transporter")
    public ServiceProvider getTransporterServiceProvider() {
        return transporter;
    }

    public ServiceProvider getTransporter() {
        return transporter;
    }

    public void setTransporter(ServiceProvider transporter) {
        this.transporter = transporter;
    }

    public Double getInsurancefactor() {
        return insuranceFactor;
    }

    public void setInsurancefactor(Double insurancefactor) {
        this.insuranceFactor = insurancefactor;
    }

    public Double getInsurancerate() {
        return insuranceRate;
    }

    public void setInsurancerate(Double insurancerate) {
        this.insuranceRate = insurancerate;
    }

    public boolean isVatInvoice() {
        return vatInvoice;
    }

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

    public PaymentMethod getPaymentmethod() {
        return paymentMethod;
    }

    public void setPaymentmethod(PaymentMethod paymentmethod) {
        this.paymentMethod = paymentmethod;
    }

    public String getContractTerm() {
        return contractTerm;
    }

    public void setContractTerm(String contractTerm) {
        this.contractTerm = contractTerm;
    }

    public PaymentTerm getPaymentTerm() {
        return paymentTerm;
    }

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

    public String getCurrency() {
        return currency;
    }

    public void setCurrency(String currency) {
        this.currency = currency;
    }

    public Double getExchangeRate() {
        return exchangeRate;
    }

    public void setExchangeRate(Double exchangeRate) {
        this.exchangeRate = exchangeRate;
    }

    public String getUcrNumber() {
        return ucrNumber;
    }

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

    public IncotermYear getIncotermYear() {
        return incotermYear;
    }

    public void setIncotermYear(IncotermYear incotermYear) {
        this.incotermYear = incotermYear;
    }

    public ExportParty getInvoicedParty() {
        return invoicedParty;
    }

    public void setInvoicedParty(ExportParty invoicedParty) {
        this.invoicedParty = invoicedParty;
    }

    public Bank getAuthorisedBankDealer() {
        return authorisedBankDealer;
    }

    public void setAuthorisedBankDealer(Bank authorisedBankDealer) {
        this.authorisedBankDealer = authorisedBankDealer;
    }

    public User getInvoiceApprover() {
        return invoiceApprover;
    }

    public void setInvoiceApprover(User invoiceApprover) {
        this.invoiceApprover = invoiceApprover;
    }

    public Date getInvoiceCreatedDate() {
        return invoiceCreatedDate;
    }

    public void setInvoiceCreatedDate(Date invoiceCreatedDate) {
        this.invoiceCreatedDate = invoiceCreatedDate;
    }

    public Incoterm getIncoterm() {
        return incoterm;
    }

    public void setIncoterm(Incoterm incoterm) {
        this.incoterm = incoterm;
    }

    public Double getFactoryValue() {
        return getValueAsDouble(getExportCosting().getFactoryValue());
    }

    public void setFactoryValue(Double factoryValue) {
        getExportCosting().setFactoryValue(getValueAsBD(factoryValue));
    }

    public Double getTransactionValue() {
        return getValueAsDouble(getExportCosting().getTransactionValue());
    }

    public void setTransactionValue(Double transactionValue) {
        getExportCosting().setTransactionValue(getValueAsBD(transactionValue));
    }

    public Double getFreightAmount() {
        return getValueAsDouble(getExportCosting().getFreightAmount());
    }

    public void setFreightAmount(Double freightAmount) {
        ExportCostLine freight = getExportCostLine(CostLineNames.FREIGHT_FREIGHT);
        if (freight != null) {
            freight.setValue(new BigDecimal(freightAmount));
        }
        getExportCosting().setFreightAmount(getValueAsBD(freightAmount));
    }

    public Double getInsurancePercentage() {
        return getValueAsDouble(getExportCosting().getInsurancePercentage());
    }

    public void setInsurancePercentage(Double insurancePercentage) {
        if (insurancePercentage != null) {
            getExportCosting().setInsurancePercentage(BigDecimal.valueOf(insurancePercentage));
        } else {
            getExportCosting().setInsurancePercentage(null);
        }
    }

    public Double getInsuranceAmount() {
        return getValueAsDouble(getExportCosting().getInsuranceAmount());
    }

    private Double getValueAsDouble(BigDecimal insuranceamount) {
        return insuranceamount != null ? insuranceamount.doubleValue() : null;
    }

    private BigDecimal getValueAsBD(Double aDouble) {
        return aDouble != null ? BigDecimal.valueOf(aDouble) : null;
    }

    public void setInsuranceAmount(Double insuranceAmount) {
        ExportCostLine insurance = getExportCostLine(CostLineNames.FINANCE_INSURANCE);
        if (insurance != null) {
            insurance.setValue(new BigDecimal(insuranceAmount));
        }

        getExportCosting().setInsuranceAmount(getValueAsBD(insuranceAmount));
    }

    public Integer getDocumentBatch() {
        return documentBatch;
    }

    public void setDocumentBatch(Integer documentBatch) {
        this.documentBatch = documentBatch;
    }

    public Integer getLastLineCount() {
        return lastLineCount;
    }

    public void setLastLineCount(Integer lastLineCount) {
        this.lastLineCount = lastLineCount;
    }

    public String getCaseNumber() {
        return caseNumber;
    }

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

    public String getLastAcceptedCode() {
        return lastAcceptedCode;
    }

    public void setLastAcceptedCode(String lastAcceptedCode) {
        this.lastAcceptedCode = lastAcceptedCode;
    }

    public Date getLastSubmissionDate() {
        return lastSubmissionDate;
    }

    public void setLastSubmissionDate(Date lastSubmissionDate) {
        this.lastSubmissionDate = lastSubmissionDate;
    }

    public Double getLastTransactionValue() {
        return lastTransactionValue;
    }

    public void setLastTransactionValue(Double lastTransactionValue) {
        this.lastTransactionValue = lastTransactionValue;
    }

    public String getChangeReason() {
        return changeReason;
    }

    public void setChangeReason(String changeReason) {
        this.changeReason = changeReason;
    }

    public String getCancelReason() {
        return cancelReason;
    }

    public void setCancelReason(String cancelReason) {
        this.cancelReason = cancelReason;
    }

    public Long getCusdecId() {
        return cusdecId;
    }

    @Override
    public void setCusdecId(Long cusdecId) {
        this.cusdecId = cusdecId;
    }

    public Long getCuscarId() {
        return cuscarId;
    }

    public void setCuscarId(Long cuscarId) {
        if (cuscarId != null)
            this.cuscarId = cuscarId;
    }

    public void updateCuscarId(Long cuscarId) {
        this.cuscarId = cuscarId;
    }

    public EdifactStatus getEdifactStatus() {
        return edifactStatus;
    }

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

    public Depot getDepot() {
        return depot;
    }

    public void setDepot(Depot depot) {
        this.depot = depot;
    }

    public boolean inEditableState() {
        return EDITABLE_STATES.contains(getStatus());
    }

    @Override
    public int compareTo(Export e) {
        if (created != null && e.created != null) {
            if (created.compareTo(e.getCreated()) != 0) {
                return created.compareTo(e.getCreated());
            } else {
                return shipmentNumber.compareTo(e.getShipmentNumber());
            }
        }
        return 0;
    }

    public PlaceOfCustom getPlaceOfCustomsEntry() {
        return placeOfCustomsEntry;
    }

    public PlaceOfCustom getPlaceOfCustomsTransitEntry() {
        return placeOfCustomsTransitEntry;
    }

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

    public void setPlaceOfCustomsTransitEntry(PlaceOfCustom placeOfCustomsTransitEntry) {
        this.placeOfCustomsTransitEntry = placeOfCustomsTransitEntry;
    }

    public PlaceOfCustom getPlaceOfCustomsTransitExit() {
        return placeOfCustomsTransitExit;
    }

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

    public void setPortOfExit(PlaceOfCustom portOfExit) {
        this.portOfExit = portOfExit;
    }

    public void setPlaceOfCustomsTransitExit(PlaceOfCustom placeOfCustomsTransitExit) {
        this.placeOfCustomsTransitExit = placeOfCustomsTransitExit;
    }

    public PlaceOfCustom getTransportdocumentplaceofissue() {
        return transportdocumentplaceofissue;
    }

    public void setTransportdocumentplaceofissue(PlaceOfCustom transportdocumentplaceofissue) {
        this.transportdocumentplaceofissue = transportdocumentplaceofissue;
    }

    public String getLrnNumber() {
        return lrnNumber;
    }

    public void setLrnNumber(String lrnNumber) {
        this.lrnNumber = lrnNumber;
    }

    public String getMrnNumber() {
        return mrnNumber;
    }

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

    public ChangeAcknowledgementIndicator getChangeAcknowledgementIndicator() {
        return changeAcknowledgementIndicator;
    }

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

    public String findChangeAcknowledgementIndicatorNumberStr(String stringIfNull) {
        ChangeAcknowledgementIndicator ack = getChangeAcknowledgementIndicator();
        return ack != null ? ack.getStatusNumber().toString() : stringIfNull;
    }

    public Set<ExportCostLine> getExportCostLines() {
        if (exportCostLines == null) {
            exportCostLines = new LinkedHashSet<ExportCostLine>();
        }
        return exportCostLines;
    }

    public void setExportCostLines(Set<ExportCostLine> exportCostLines) {
        this.exportCostLines = exportCostLines;
    }

    public ExportCostLine getExportCostLine(String costlineCode) {
        for (ExportCostLine costLine : getExportCostLines()) {
            if (costLine.getCostLine().getCostLineTemplate().getCode().equals(costlineCode)) {
                return costLine;
            }
        }
        return null;
    }

    public String getFooter() {
        return footer;
    }

    public void setFooter(String footer) {
        this.footer = footer;
    }

    public BigDecimal getCapturedShipmentGrossWeight() {
        return capturedShipmentGrossWeight;
    }

    public void setCapturedShipmentGrossWeight(BigDecimal capturedShipmentGrossWeight) {
        this.capturedShipmentGrossWeight = capturedShipmentGrossWeight;
    }

    public Boolean getDistributeLineItemsByWeight() {
        return distributeLineItemsByWeight;
    }

    public void setDistributeLineItemsByWeight(Boolean distributeLineItemsByWeight) {
        this.distributeLineItemsByWeight = distributeLineItemsByWeight;
    }

    public Employee getDriver() {
        return driver;
    }

    public void setDriver(Employee driver) {
        this.driver = driver;
    }

    public Employee getCoDriver() {
        return coDriver;
    }

    public void setCoDriver(Employee coDriver) {
        this.coDriver = coDriver;
    }

    public void setCarnNo(String carnNo) {
        this.carnNo = carnNo;
    }

    public String getCarnNo() {
        return carnNo;
    }

    public Contact getReportContact() {
        return reportContact;
    }

    public void setReportContact(Contact reportContact) {
        this.reportContact = reportContact;
    }

    public Long getPreviousCuscarId() {
        return previousCuscarId;
    }

    public void setPreviousCuscarId(Long previousCuscarId) {
        this.previousCuscarId = previousCuscarId;
    }

    public boolean isCusdecProceedToBorderReceived() {
        return cusdecProceedToBorderReceived;
    }

    public void setCusdecProceedToBorderReceived(boolean cusdecProceedToBorderReceived) {
        this.cusdecProceedToBorderReceived = cusdecProceedToBorderReceived;
    }

    public String getTrailerRegistration1() {
        return trailerRegistration1;
    }

    public String getTrailerRegistration2() {
        return trailerRegistration2;
    }

    public void setTrailerRegistration2(String trailerRegistration2) {
        this.trailerRegistration2 = trailerRegistration2;
    }

    public void setTrailerRegistration1(String trailerRegistration1) {
        this.trailerRegistration1 = trailerRegistration1;
    }

    public boolean isProduceExportManifest() {
        return produceExportManifest;
    }

    public void setProduceExportManifest(boolean produceExportManifest) {
        this.produceExportManifest = produceExportManifest;
    }

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

    @Override
    public PurposeCode getPurposeCode() {
        return PurposeCode.EXPORT_FREE_CIRCULATION;
    }

    @Override
    public TypeOfGoods getTypeOfGoods() {
        return TypeOfGoods.NEW_GOODS;
    }

    @Override
    public ValuationMethod getValuationMethod() {
        return null;
    }

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

        sb.append(this.getTransportDocumentNumber());
        sb.append(this.getPortOfExit().getCode());
        return sb.toString();
    }

    @Override
    public BigInteger getNumber() {
        return BigInteger.valueOf(getCusdecId().intValue());
    }

    @Override
    public Date getPresentationOfGoodsDate() {
        return null;
    }

    @Override
    public CustomsValuation getCustomsValuation() {
        return null;
    }

    @Override
    public com.tradecloud.domain.configuration.clearing.za.PaymentMethod getPaymentMethod() {
        return null;
    }

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

    @Override
    public Date getTransportDocumentDate() {
        return null;
    }

    public boolean isIntegrated() {
        return integrated;
    }

    public void setIntegrated(boolean integrated) {
        this.integrated = integrated;
    }

    @Override
    public Status getState() {
        return getExportStatus();
    }

    @Override
    public void setState(Status state) {
        exportStatus = state;
    }

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

    public void setLastEvent(ClearingEvent lastEvent) {
        this.lastEvent = lastEvent;
    }

    @Override
    public List<ClearingEvent> getEvents() {
        return events;
    }

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

    @Override
    public boolean inNonEditableState() {
        return false;
    }

    public Date getEstimateDepartureDate() {
        return estimateDepartureDate;
    }

    public void setEstimateDepartureDate(Date estimateDepartureDate) {
        this.estimateDepartureDate = estimateDepartureDate;
    }

    public ExportCosting getExportCosting() {
        if (exportCosting == null) {
            exportCosting = new ExportCosting();
        }
        return exportCosting;
    }

    public void setExportCosting(ExportCosting exportCosting) {
        this.exportCosting = exportCosting;
    }

    @Override
    public String getDocumentGroupName() {
        return DocumentManagementHardCoding.EXPORT_SHIPMENT.name();
    }

    @Override
    public String getDMSKey() {
        return getId().toString();
    }

    @Override
    public String getReference() {
        return shipmentNumber;
    }

    public boolean isCartonBased() {
        return cartonBased;
    }

    public void setCartonBased(boolean cartonBased) {
        this.cartonBased = cartonBased;
    }

    public String getInvoiceNumbers() {
        return getShipmentNumber();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        if (!super.equals(o)) return false;
        Export export = (Export) o;
        return Objects.equals(shipmentNumber, export.shipmentNumber);
    }

    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), shipmentNumber);
    }

    public long getNumberOfCartons() {
        return numberOfCartons;
    }

    @Override
    public ShippingMode getShippingMode() {
        return getModeOfTransport();
    }

    @Override
    public ClearingPaymentTerm getClearingPaymentTerm() {
        return null;
    }

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

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

    public void setAdvancedPayments(Set<AdvancedPayment> advancedPayments) {
        this.advancedPayments = advancedPayments;
    }

    @Override
    public DeclarationType getDeclarationType() {
        //TODO: add db column
        return DeclarationType.RDC_REGULAR_COMPLETE;
    }

    public void setAdditionalClearingInfo(Set<AdditionalClearingInfo> additionalClearingInfo) {
        this.additionalClearingInfo = additionalClearingInfo;
    }

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

    @Override
    public boolean isImports() {
        return false;
    }

    public Date getShippedOnBoardDate() {
        return getActualDepartureDate();
    }
}