// Custom object hydration
        /// <summary>
        /// Customs the shipment fill.
        /// </summary>
        /// <param name="shipment">The shipment.</param>
        /// <param name="dataReader">The data reader.</param>
        /// <param name="fullyPopulate">if set to <c>true</c> [fully populate].</param>
        private static void CustomShipmentFill(OpCoShipment shipment, IDataReader dataReader, bool fullyPopulate)
        {
            // See if we fully populate this entity
            if (fullyPopulate)
            {
                // Populate shipment lines
                List <OpCoShipmentLine> opCoLines = OpCoShipmentLineController.GetLines(shipment.Id);
                // The total number of lines
                int TotalLines = opCoLines.Count;
                // Clear existing lines
                shipment.ShipmentLines.Clear();
                // Add new lines
                foreach (OpCoShipmentLine opCoLine in opCoLines)
                {
                    // Specify any derived columns that we need
                    opCoLine.TotalLines = TotalLines;
                    // Add the line
                    shipment.ShipmentLines.Add(opCoLine);
                }
            }

            // Populate opco contact
            shipment.OpCoContact.Email = dataReader["OpCoContactEmail"].ToString();
            shipment.OpCoContact.Name  = dataReader["OpCoContactName"].ToString();

            // Populate shipment contact
            shipment.ShipmentContact.Email           = dataReader["ShipmentContactEmail"].ToString();
            shipment.ShipmentContact.Name            = dataReader["ShipmentContactName"].ToString();
            shipment.ShipmentContact.TelephoneNumber = dataReader["ShipmentContactTel"].ToString();

            // Populate shipment address
            shipment.ShipmentAddress.Line1    = dataReader["ShipmentAddress1"].ToString();
            shipment.ShipmentAddress.Line2    = dataReader["ShipmentAddress2"].ToString();
            shipment.ShipmentAddress.Line3    = dataReader["ShipmentAddress3"].ToString();
            shipment.ShipmentAddress.Line4    = dataReader["ShipmentAddress4"].ToString();
            shipment.ShipmentAddress.Line5    = dataReader["ShipmentAddress5"].ToString();
            shipment.ShipmentAddress.PostCode = dataReader["ShipmentPostCode"].ToString();

            // Populate customer address
            shipment.CustomerAddress.Line1    = dataReader["CustomerAddress1"].ToString();
            shipment.CustomerAddress.Line2    = dataReader["CustomerAddress2"].ToString();
            shipment.CustomerAddress.Line3    = dataReader["CustomerAddress3"].ToString();
            shipment.CustomerAddress.Line4    = dataReader["CustomerAddress4"].ToString();
            shipment.CustomerAddress.Line5    = dataReader["CustomerAddress5"].ToString();
            shipment.CustomerAddress.PostCode = dataReader["CustomerPostCode"].ToString();
        }
        /// <summary>
        /// Saves the shipment.
        /// </summary>
        /// <param name="shipment">The shipment.</param>
        /// <returns></returns>
        public static int SaveShipment(OpCoShipment shipment)
        {
            try
            {
                // Make sure the shipment is valid
                if (shipment.IsValid)
                {
                    // Save the shipment to the db and update the id, this will update the shipment lines if required
                    shipment.Id = DataAccessProvider.Instance().SaveOpCoShipment(shipment);

                    // Get the checksum for the entity
                    FrameworkController.GetChecksum(shipment);

                    // Save the shipment lines to the db
                    foreach (OpCoShipmentLine opCoShipmentLine in shipment.ShipmentLines)
                    {
                        // Save the shipment line and update the shipment line id if required
                        opCoShipmentLine.Id = OpCoShipmentLineController.SaveLine(opCoShipmentLine);
                    }
                }
                else
                {
                    // Entity is not valid
                    throw new InValidBusinessObjectException(shipment);
                }
            }
            catch (Exception ex)
            {
                // Generate a new exception
                ex = new Exception(string.Format("Failed to save OpCo shipment {0} - {1} for OpCo {2}.  {3}", shipment.ShipmentNumber, shipment.DespatchNumber, shipment.OpCoCode, ex.Message));

                // Log an throw if configured to do so
                if (ExceptionPolicy.HandleException(ex, "Business Logic"))
                {
                    throw ex;
                }

                // We failed to save the shipment
                return(-1);
            }

            // Done
            return(shipment.Id);
        }