public TransferShippingOrder MapToModel(TransferShippingOrderViewModel viewModel)
        {
            TransferShippingOrder model = new TransferShippingOrder();

            PropertyCopier <TransferShippingOrderViewModel, TransferShippingOrder> .Copy(viewModel, model);

            model.SupplierId   = viewModel.Supplier._id;
            model.SupplierCode = viewModel.Supplier.code;
            model.SupplierName = viewModel.Supplier.name;

            model.TransferShippingOrderItems = new List <TransferShippingOrderItem>();
            foreach (TransferShippingOrderItemViewModel shippingOrderItemViewModel in viewModel.TransferShippingOrderItems)
            {
                TransferShippingOrderItem shippingOrderItem = new TransferShippingOrderItem();
                PropertyCopier <TransferShippingOrderItemViewModel, TransferShippingOrderItem> .Copy(shippingOrderItemViewModel, shippingOrderItem);

                shippingOrderItem.TransferShippingOrderDetails = new List <TransferShippingOrderDetail>();
                foreach (TransferShippingOrderDetailViewModel shippingOrderDetailViewModel in shippingOrderItemViewModel.TransferShippingOrderDetails)
                {
                    TransferShippingOrderDetail shippingOrderDetail = new TransferShippingOrderDetail();
                    PropertyCopier <TransferShippingOrderDetailViewModel, TransferShippingOrderDetail> .Copy(shippingOrderDetailViewModel, shippingOrderDetail);

                    shippingOrderDetail.ProductId   = shippingOrderDetailViewModel.Product._id;
                    shippingOrderDetail.ProductCode = shippingOrderDetailViewModel.Product.code;
                    shippingOrderDetail.ProductName = shippingOrderDetailViewModel.Product.name;
                    shippingOrderDetail.UomId       = shippingOrderDetailViewModel.Uom._id;
                    shippingOrderDetail.UomUnit     = shippingOrderDetailViewModel.Uom.unit;

                    shippingOrderItem.TransferShippingOrderDetails.Add(shippingOrderDetail);
                }

                model.TransferShippingOrderItems.Add(shippingOrderItem);
            }

            return(model);
        }
        public override async Task <int> UpdateModel(int Id, TransferShippingOrder Model)
        {
            int Updated = 0;

            using (var Transaction = this.DbContext.Database.BeginTransaction())
            {
                try
                {
                    TransferShippingOrderItemService shippingOrderItemService = ServiceProvider.GetService <TransferShippingOrderItemService>();
                    shippingOrderItemService.Username = this.Username;
                    TransferShippingOrderDetailService shippingOrderDetailService = ServiceProvider.GetService <TransferShippingOrderDetailService>();
                    shippingOrderDetailService.Username = this.Username;

                    HashSet <int> ShippingOrderItemIds = new HashSet <int>(
                        this.DbContext.TransferShippingOrderItems
                        .Where(p => p.SOId.Equals(Id))
                        .Select(p => p.Id)
                        );

                    foreach (int itemId in ShippingOrderItemIds)
                    {
                        HashSet <int> ShippingOrderDetailIds = new HashSet <int>(
                            this.DbContext.TransferShippingOrderDetails
                            .Where(p => p.SOItemId.Equals(itemId))
                            .Select(p => p.Id)
                            );

                        TransferShippingOrderItem shippingOrderItemNew = Model.TransferShippingOrderItems.FirstOrDefault(p => p.Id.Equals(itemId));

                        if (shippingOrderItemNew == null)
                        {
                            TransferShippingOrderItem item = this.DbContext.TransferShippingOrderItems
                                                             .Include(d => d.TransferShippingOrderDetails)
                                                             .FirstOrDefault(p => p.Id.Equals(itemId));

                            if (item != null)
                            {
                                foreach (var detail in item.TransferShippingOrderDetails)
                                {
                                    TransferDeliveryOrderDetail transferDeliveryOrderDetail = this.DbContext.TransferDeliveryOrderDetails.FirstOrDefault(s => s.Id == detail.DODetailId);
                                    transferDeliveryOrderDetail.ShippingOrderQuantity -= (int)detail.DeliveryQuantity;
                                    transferDeliveryOrderDetail.RemainingQuantity     += (int)detail.DeliveryQuantity;

                                    TransferRequestDetail transferRequestDetail = this.DbContext.TransferRequestDetails.FirstOrDefault(s => s.Id == detail.TRDetailId);
                                    transferRequestDetail._LastModifiedUtc   = DateTime.UtcNow;
                                    transferRequestDetail._LastModifiedAgent = "Service";
                                    transferRequestDetail._LastModifiedBy    = this.Username;

                                    InternalTransferOrderDetail internalTransferOrderDetail = this.DbContext.InternalTransferOrderDetails.FirstOrDefault(s => s.Id == detail.ITODetailId);
                                    internalTransferOrderDetail._LastModifiedUtc   = DateTime.UtcNow;
                                    internalTransferOrderDetail._LastModifiedAgent = "Service";
                                    internalTransferOrderDetail._LastModifiedBy    = this.Username;

                                    if (transferDeliveryOrderDetail.RemainingQuantity == transferDeliveryOrderDetail.DOQuantity)
                                    {
                                        ExternalTransferOrderDetail externalTransferOrderDetail = this.DbContext.ExternalTransferOrderDetails.FirstOrDefault(s => s.Id == detail.ETODetailId);

                                        transferRequestDetail.Status       = externalTransferOrderDetail.RemainingQuantity > 0 ? "Barang Sudah dikirim sebagian ke Unit Pengirim" : "Barang Sudah dikirim semua ke Unit Pengirim";
                                        internalTransferOrderDetail.Status = externalTransferOrderDetail.RemainingQuantity > 0 ? "Barang Sudah dikirim sebagian ke Unit Pengirim" : "Barang Sudah dikirim semua ke Unit Pengirim";
                                    }
                                    else
                                    {
                                        transferRequestDetail.Status       = transferDeliveryOrderDetail.RemainingQuantity > 0 ? "Barang Sudah dikirim sebagian" : "Barang Sudah dikirim semua";
                                        internalTransferOrderDetail.Status = transferDeliveryOrderDetail.RemainingQuantity > 0 ? "Barang Sudah dikirim sebagian" : "Barang Sudah dikirim semua";
                                    }
                                }
                            }

                            foreach (int detailId in ShippingOrderDetailIds)
                            {
                                await shippingOrderDetailService.DeleteModel(detailId);
                            }

                            await shippingOrderItemService.DeleteModel(itemId);
                        }
                        else
                        {
                            await shippingOrderItemService.UpdateModel(itemId, shippingOrderItemNew);

                            foreach (int detailId in ShippingOrderDetailIds)
                            {
                                TransferShippingOrderDetail shippingOrderDetailNew = shippingOrderItemNew.TransferShippingOrderDetails.FirstOrDefault(p => p.Id.Equals(detailId));

                                if (shippingOrderDetailNew == null)
                                {
                                    await shippingOrderDetailService.DeleteModel(detailId);
                                }
                                else
                                {
                                    await shippingOrderDetailService.UpdateModel(detailId, shippingOrderDetailNew);

                                    TransferShippingOrderDetail shippingOrderDetailOld = this.DbContext.TransferShippingOrderDetails.FirstOrDefault(p => p.Id.Equals(detailId));

                                    TransferDeliveryOrderDetail transferDeliveryOrderDetail = this.DbContext.TransferDeliveryOrderDetails.FirstOrDefault(s => s.Id == shippingOrderDetailNew.DODetailId);
                                    transferDeliveryOrderDetail.ShippingOrderQuantity = transferDeliveryOrderDetail.ShippingOrderQuantity - (int)shippingOrderDetailOld.DeliveryQuantity + (int)shippingOrderDetailNew.DeliveryQuantity;
                                    transferDeliveryOrderDetail.RemainingQuantity     = transferDeliveryOrderDetail.RemainingQuantity + (int)shippingOrderDetailOld.DeliveryQuantity - (int)shippingOrderDetailNew.DeliveryQuantity;

                                    TransferRequestDetail transferRequestDetail = this.DbContext.TransferRequestDetails.FirstOrDefault(s => s.Id == shippingOrderDetailNew.TRDetailId);
                                    transferRequestDetail._LastModifiedUtc   = DateTime.UtcNow;
                                    transferRequestDetail._LastModifiedAgent = "Service";
                                    transferRequestDetail._LastModifiedBy    = this.Username;

                                    InternalTransferOrderDetail internalTransferOrderDetail = this.DbContext.InternalTransferOrderDetails.FirstOrDefault(s => s.Id == shippingOrderDetailNew.ITODetailId);
                                    internalTransferOrderDetail._LastModifiedUtc   = DateTime.UtcNow;
                                    internalTransferOrderDetail._LastModifiedAgent = "Service";
                                    internalTransferOrderDetail._LastModifiedBy    = this.Username;

                                    if (transferDeliveryOrderDetail.RemainingQuantity == transferDeliveryOrderDetail.DOQuantity)
                                    {
                                        ExternalTransferOrderDetail externalTransferOrderDetail = this.DbContext.ExternalTransferOrderDetails.FirstOrDefault(s => s.Id == shippingOrderDetailNew.ETODetailId);

                                        transferRequestDetail.Status       = externalTransferOrderDetail.RemainingQuantity > 0 ? "Barang Sudah dikirim sebagian ke Unit Pengirim" : "Barang Sudah dikirim semua ke Unit Pengirim";
                                        internalTransferOrderDetail.Status = externalTransferOrderDetail.RemainingQuantity > 0 ? "Barang Sudah dikirim sebagian ke Unit Pengirim" : "Barang Sudah dikirim semua ke Unit Pengirim";
                                    }
                                    else
                                    {
                                        transferRequestDetail.Status       = transferDeliveryOrderDetail.RemainingQuantity > 0 ? "Barang Sudah dikirim sebagian" : "Barang Sudah dikirim semua";
                                        internalTransferOrderDetail.Status = transferDeliveryOrderDetail.RemainingQuantity > 0 ? "Barang Sudah dikirim sebagian" : "Barang Sudah dikirim semua";
                                    }
                                }
                            }
                        }
                    }

                    Updated = await this.UpdateAsync(Id, Model);

                    foreach (TransferShippingOrderItem item in Model.TransferShippingOrderItems)
                    {
                        if (item.Id == 0)
                        {
                            await shippingOrderItemService.CreateModel(item);

                            foreach (var detail in item.TransferShippingOrderDetails)
                            {
                                TransferDeliveryOrderDetail transferDeliveryOrderDetail = this.DbContext.TransferDeliveryOrderDetails.FirstOrDefault(s => s.Id == detail.DODetailId);
                                transferDeliveryOrderDetail.ShippingOrderQuantity += (int)detail.DeliveryQuantity;
                                transferDeliveryOrderDetail.RemainingQuantity     -= (int)detail.DeliveryQuantity;

                                TransferRequestDetail transferRequestDetail = this.DbContext.TransferRequestDetails.FirstOrDefault(s => s.Id == detail.TRDetailId);
                                transferRequestDetail._LastModifiedUtc   = DateTime.UtcNow;
                                transferRequestDetail._LastModifiedAgent = "Service";
                                transferRequestDetail._LastModifiedBy    = this.Username;

                                InternalTransferOrderDetail internalTransferOrderDetail = this.DbContext.InternalTransferOrderDetails.FirstOrDefault(s => s.Id == detail.ITODetailId);
                                internalTransferOrderDetail._LastModifiedUtc   = DateTime.UtcNow;
                                internalTransferOrderDetail._LastModifiedAgent = "Service";
                                internalTransferOrderDetail._LastModifiedBy    = this.Username;

                                if (transferDeliveryOrderDetail.RemainingQuantity == transferDeliveryOrderDetail.DOQuantity)
                                {
                                    ExternalTransferOrderDetail externalTransferOrderDetail = this.DbContext.ExternalTransferOrderDetails.FirstOrDefault(s => s.Id == detail.ETODetailId);

                                    transferRequestDetail.Status       = externalTransferOrderDetail.RemainingQuantity > 0 ? "Barang Sudah dikirim sebagian ke Unit Pengirim" : "Barang Sudah dikirim semua ke Unit Pengirim";
                                    internalTransferOrderDetail.Status = externalTransferOrderDetail.RemainingQuantity > 0 ? "Barang Sudah dikirim sebagian ke Unit Pengirim" : "Barang Sudah dikirim semua ke Unit Pengirim";
                                }
                                else
                                {
                                    transferRequestDetail.Status       = transferDeliveryOrderDetail.RemainingQuantity > 0 ? "Barang Sudah dikirim sebagian" : "Barang Sudah dikirim semua";
                                    internalTransferOrderDetail.Status = transferDeliveryOrderDetail.RemainingQuantity > 0 ? "Barang Sudah dikirim sebagian" : "Barang Sudah dikirim semua";
                                }
                            }
                        }
                    }

                    this.DbContext.SaveChanges();

                    Transaction.Commit();
                }
                catch (Exception)
                {
                    Transaction.Rollback();
                }
            }

            return(Updated);
        }