Exemple #1
0
        /// <summary>
        /// Issue an order
        /// </summary>
        public void IssueDespatchAdvice(DespatchAdviceMessageType advice)
        {
            String boundary = String.Format("------{0:N}", Guid.NewGuid());

            if (this.m_configuration.UseAS2MimeEncoding)
            {
                this.Client.Post <MultipartAttachment, object>("despatchAdvice", String.Format("multipart/form-data; boundary={0}", boundary), this.CreateAttachment(advice));
            }
            else
            {
                this.Client.Post <DespatchAdviceMessageType, object>("despatchAdvice", "application/xml", advice);
            }
        }
        /// <summary>
        /// The issue despactch advice message will insert a new shipped order into the TImR system.
        /// </summary>
        public void IssueDespatchAdvice(DespatchAdviceMessageType advice)
        {
            if (advice == null || advice.despatchAdvice == null)
            {
                throw new InvalidOperationException("Invalid message sent");
            }
            // TODO: Validate the standard header
            // Loop
            Bundle orderTransaction = new Bundle();

            foreach (var adv in advice.despatchAdvice)
            {
                // Has this already been created?
                Place sourceLocation         = this.m_gs1Util.GetLocation(adv.shipper),
                         destinationLocation = this.m_gs1Util.GetLocation(adv.receiver);
                if (sourceLocation == null)
                {
                    throw new KeyNotFoundException($"Shipper location not found");
                }
                else if (destinationLocation == null)
                {
                    throw new KeyNotFoundException($"Receiver location not found");
                }

                // Find the original order which this despatch advice is fulfilling
                Act orderRequestAct = null;
                if (adv.orderResponse != null || adv.purchaseOrder != null)
                {
                    orderRequestAct = this.m_gs1Util.GetOrder(adv.orderResponse ?? adv.purchaseOrder, ActMoodKeys.Request);
                    if (orderRequestAct != null) // Orderless despatch!
                    {
                        // If the original order request is not comlete, then complete it
                        orderRequestAct.StatusConceptKey = StatusKeys.Completed;
                        orderTransaction.Add(orderRequestAct);
                    }
                }

                // Find the author of the shipment

                var oidService       = ApplicationContext.Current.GetService <IOidRegistrarService>();
                var gln              = oidService.GetOid("GLN");
                var issuingAuthority = oidService.FindData($"{gln.Oid}.{adv.despatchAdviceIdentification.contentOwner?.gln}");
                if (issuingAuthority == null)
                {
                    issuingAuthority = oidService.GetOid(this.m_configuration.DefaultContentOwnerAssigningAuthority);
                }

                if (issuingAuthority == null)
                {
                    throw new KeyNotFoundException("Cannot find default issuing authority for advice identification. Please configure a valid OID");
                }

                int tr       = 0;
                var existing = this.m_actRepository.Find <Act>(o => o.Identifiers.Any(i => i.Authority.DomainName == issuingAuthority.Mnemonic && i.Value == adv.despatchAdviceIdentification.entityIdentification), 0, 1, out tr);
                if (existing.Any())
                {
                    this.m_tracer.TraceWarning("Duplicate despatch {0} will be ignored", adv.despatchAdviceIdentification.entityIdentification);
                    continue;
                }

                // Now we want to create a new Supply act which that fulfills the old act
                Act fulfillAct = new Act()
                {
                    CreationTime     = DateTimeOffset.Now,
                    MoodConceptKey   = ActMoodKeys.Eventoccurrence,
                    ClassConceptKey  = ActClassKeys.Supply,
                    StatusConceptKey = StatusKeys.Active,
                    TypeConceptKey   = Guid.Parse("14d69b32-f6c4-4a49-a527-a74893dbcf4a"), // Order
                    ActTime          = adv.despatchInformation.despatchDateTimeSpecified ? adv.despatchInformation.despatchDateTime : DateTime.Now,
                    Extensions       = new List <ActExtension>()
                    {
                        new ActExtension(Gs1ModelExtensions.ActualShipmentDate, typeof(DateExtensionHandler), adv.despatchInformation.actualShipDateTime),
                        new ActExtension(Gs1ModelExtensions.ExpectedDeliveryDate, typeof(DateExtensionHandler), adv.despatchInformation.estimatedDeliveryDateTime)
                    },
                    Tags = new List <ActTag>()
                    {
                        new ActTag("orderNumber", adv.despatchAdviceIdentification.entityIdentification),
                        new ActTag("orderStatus", "shipped"),
                        new ActTag("http://openiz.org/tags/contrib/importedData", "true")
                    },
                    Identifiers = new List <ActIdentifier>()
                    {
                        new ActIdentifier(new AssigningAuthority(issuingAuthority.Mnemonic, issuingAuthority.Name, issuingAuthority.Oid), adv.despatchAdviceIdentification.entityIdentification)
                    },
                    Participations = new List <ActParticipation>()
                    {
                        // TODO: Author
                        // TODO: Performer
                        new ActParticipation(ActParticipationKey.Location, sourceLocation.Key),
                        new ActParticipation(ActParticipationKey.Destination, destinationLocation.Key)
                    }
                };
                orderTransaction.Add(fulfillAct);

                // Fullfillment
                if (orderRequestAct != null)
                {
                    fulfillAct.Relationships = new List <ActRelationship>()
                    {
                        new ActRelationship(ActRelationshipTypeKeys.Fulfills, orderRequestAct.Key)
                    }
                }
                ;


                // Now add participations for each material in the despatch
                foreach (var dal in adv.despatchAdviceLogisticUnit)
                {
                    foreach (var line in dal.despatchAdviceLineItem)
                    {
                        if (line.despatchedQuantity.measurementUnitCode != "dose" &&
                            line.despatchedQuantity.measurementUnitCode != "unit")
                        {
                            throw new InvalidOperationException("Despatched quantity must be reported in units or doses");
                        }

                        var material = this.m_gs1Util.GetManufacturedMaterial(line.transactionalTradeItem, this.m_configuration.AutoCreateMaterials);

                        // Add a participation
                        fulfillAct.Participations.Add(new ActParticipation(ActParticipationKey.Consumable, material.Key)
                        {
                            Quantity = (int)line.despatchedQuantity.Value
                        });
                    }
                }
            }

            // insert transaction
            if (orderTransaction.Item.Count > 0)
            {
                try
                {
                    ApplicationContext.Current.GetService <IBatchRepositoryService>().Insert(orderTransaction);
                }
                catch (Exception e)
                {
                    this.m_tracer.TraceError("Error issuing despatch advice: {0}", e);
                    throw new Exception($"Error issuing despatch advice: {e.Message}", e);
                }
            }
        }