public async Task <int> Create(PurchasingDisposition m, string user, int clientTimeZoneOffset)
        {
            int Created = 0;

            using (var transaction = this.dbContext.Database.BeginTransaction())
            {
                try
                {
                    EntityExtension.FlagForCreate(m, user, "Facade");
                    m.DispositionNo = await GenerateNo(m, clientTimeZoneOffset);

                    m.Position = 1;
                    if (m.IncomeTaxBy == "Supplier")
                    {
                        m.Amount = m.DPP + m.VatValue + m.PaymentCorrection;
                    }
                    else
                    {
                        m.Amount = m.DPP + m.VatValue - m.IncomeTaxValue + m.PaymentCorrection;
                    }

                    foreach (var item in m.Items)
                    {
                        EntityExtension.FlagForCreate(item, user, "Facade");
                        foreach (var detail in item.Details)
                        {
                            ExternalPurchaseOrderDetail epoDetail = this.dbContext.ExternalPurchaseOrderDetails.Where(s => s.Id.ToString() == detail.EPODetailId && s.IsDeleted == false).FirstOrDefault();
                            epoDetail.DispositionQuantity += detail.PaidQuantity;
                            EntityExtension.FlagForCreate(detail, user, "Facade");
                        }
                    }

                    this.dbSet.Add(m);
                    Created = await dbContext.SaveChangesAsync();

                    transaction.Commit();
                }
                catch (Exception e)
                {
                    transaction.Rollback();
                    throw new Exception(e.Message);
                }
            }

            return(Created);
        }
        public async Task <int> UpdatePosition(PurchasingDispositionUpdatePositionPostedViewModel data, string user)
        {
            int updated = 0;

            using (var transaction = dbContext.Database.BeginTransaction())
            {
                foreach (var dispositionNo in data.PurchasingDispositionNoes)
                {
                    PurchasingDisposition purchasingDisposition = dbSet.FirstOrDefault(x => x.DispositionNo == dispositionNo);

                    purchasingDisposition.Position = (int)data.Position;
                    EntityExtension.FlagForUpdate(purchasingDisposition, user, "Facade");
                }
                updated = await dbContext.SaveChangesAsync();

                transaction.Commit();
            }
            return(updated);
        }
        public IActionResult GetPDF(int id)
        {
            try
            {
                var indexAcceptPdf = Request.Headers["Accept"].ToList().IndexOf("application/pdf");
                identityService.Username = User.Claims.Single(p => p.Type.Equals("username")).Value;
                PurchasingDisposition model = facade.ReadModelById(id);

                PurchasingDispositionViewModel viewModel = mapper.Map <PurchasingDispositionViewModel>(model);

                if (indexAcceptPdf < 0)
                {
                    return(Ok(new
                    {
                        apiVersion = ApiVersion,
                        statusCode = General.OK_STATUS_CODE,
                        message = General.OK_MESSAGE,
                        data = viewModel,
                    }));
                }
                else
                {
                    int clientTimeZoneOffset = int.Parse(Request.Headers["x-timezone-offset"].First());

                    PurchasingDispositionPDFTemplate PdfTemplate = new PurchasingDispositionPDFTemplate();
                    MemoryStream stream = PdfTemplate.GeneratePdfTemplate(viewModel, clientTimeZoneOffset);

                    return(new FileStreamResult(stream, "application/pdf")
                    {
                        FileDownloadName = $"{model.DispositionNo}.pdf"
                    });
                }
            }
            catch (Exception e)
            {
                Dictionary <string, object> Result =
                    new ResultFormatter(ApiVersion, General.INTERNAL_ERROR_STATUS_CODE, e.Message)
                    .Fail();
                return(StatusCode(General.INTERNAL_ERROR_STATUS_CODE, Result));
            }
        }
        public void Should_Success_Get_Data_DispositionMemoLoader()
        {
            var dbContext = _dbContext(GetCurrentMethod());
            var facade    = new PurchasingDispositionFacade(ServiceProvider, dbContext);

            var Response = facade.GetDispositionMemoLoader(0);

            Assert.Null(Response);

            var purhcasingDisposition = new PurchasingDisposition()
            {
                Id = 1, CurrencyCode = "IDR"
            };
            var purchasingDispositionItem = new PurchasingDispositionItem()
            {
                PurchasingDispositionId = 1, UseVat = true, UseIncomeTax = true, EPONo = "1"
            };
            var unitPaymentOrder = new UnitPaymentOrder()
            {
                Id = 1
            };
            var unitPaymentOrderItem = new UnitPaymentOrderItem()
            {
                Id = 1, UPOId = 1
            };
            var unitPaymentOrderDetail = new UnitPaymentOrderDetail()
            {
                EPONo = "1", UPOItemId = 1
            };

            dbContext.PurchasingDispositions.Add(purhcasingDisposition);
            dbContext.PurchasingDispositionItems.Add(purchasingDispositionItem);
            dbContext.UnitPaymentOrders.Add(unitPaymentOrder);
            dbContext.UnitPaymentOrderItems.Add(unitPaymentOrderItem);
            dbContext.UnitPaymentOrderDetails.Add(unitPaymentOrderDetail);
            dbContext.SaveChanges();

            var Response2 = facade.GetDispositionMemoLoader(1);

            Assert.NotNull(Response2);
        }
        async Task <string> GenerateNo(PurchasingDisposition model, int clientTimeZoneOffset)
        {
            DateTimeOffset Now   = DateTime.UtcNow;
            string         Year  = Now.ToOffset(new TimeSpan(clientTimeZoneOffset, 0, 0)).ToString("yy");
            string         Month = Now.ToOffset(new TimeSpan(clientTimeZoneOffset, 0, 0)).ToString("MM");

            string no      = model.DivisionName == "GARMENT" ? $"{Year}-{Month}-G" : $"{Year}-{Month}-T";
            int    Padding = 3;

            var lastNo = await this.dbSet.Where(w => w.DispositionNo.StartsWith(no) && !w.IsDeleted).OrderByDescending(o => o.DispositionNo).FirstOrDefaultAsync();

            no = $"{no}";

            if (lastNo == null)
            {
                return(no + "1".PadLeft(Padding, '0'));
            }
            else
            {
                int lastNoNumber = Int32.Parse(lastNo.DispositionNo.Replace(no, "")) + 1;
                return(no + lastNoNumber.ToString().PadLeft(Padding, '0'));
            }
        }
        public async Task <int> Update(int id, PurchasingDisposition purchasingDisposition, string user)
        {
            int Updated = 0;

            using (var transaction = this.dbContext.Database.BeginTransaction())
            {
                try
                {
                    var existingModel = this.dbSet.AsNoTracking()
                                        .Include(d => d.Items)
                                        .ThenInclude(d => d.Details)
                                        .Single(epo => epo.Id == id && !epo.IsDeleted);

                    foreach (var oldIem in existingModel.Items)
                    {
                        foreach (var oldDetail in oldIem.Details)
                        {
                            ExternalPurchaseOrderDetail epoDetail = this.dbContext.ExternalPurchaseOrderDetails.Where(s => s.Id.ToString() == oldDetail.EPODetailId && s.IsDeleted == false).FirstOrDefault();
                            epoDetail.DispositionQuantity -= oldDetail.PaidQuantity;
                        }
                    }

                    if (existingModel != null && id == purchasingDisposition.Id)
                    {
                        if (purchasingDisposition.IncomeTaxBy == "Supplier")
                        {
                            purchasingDisposition.Amount = purchasingDisposition.DPP + purchasingDisposition.VatValue + purchasingDisposition.PaymentCorrection;
                        }
                        else
                        {
                            purchasingDisposition.Amount = purchasingDisposition.DPP + purchasingDisposition.VatValue - purchasingDisposition.IncomeTaxValue + purchasingDisposition.PaymentCorrection;
                        }

                        EntityExtension.FlagForUpdate(purchasingDisposition, user, "Facade");

                        foreach (var item in purchasingDisposition.Items.ToList())
                        {
                            var existingItem = existingModel.Items.SingleOrDefault(m => m.Id == item.Id);
                            List <PurchasingDispositionItem> duplicateDispositionItems = purchasingDisposition.Items.Where(i => i.EPOId == item.EPOId && i.Id != item.Id).ToList();

                            if (item.Id == 0)
                            {
                                if (duplicateDispositionItems.Count <= 0)
                                {
                                    EntityExtension.FlagForCreate(item, user, "Facade");

                                    foreach (var detail in item.Details)
                                    {
                                        ExternalPurchaseOrderDetail epoDetail = this.dbContext.ExternalPurchaseOrderDetails.Where(s => s.Id.ToString() == detail.EPODetailId && s.IsDeleted == false).FirstOrDefault();
                                        epoDetail.DispositionQuantity += detail.PaidQuantity;
                                        EntityExtension.FlagForCreate(detail, user, "Facade");
                                    }
                                }
                            }
                            else
                            {
                                EntityExtension.FlagForUpdate(item, user, "Facade");

                                if (duplicateDispositionItems.Count > 0)
                                {
                                    //foreach (var detail in item.Details.ToList())
                                    //{
                                    //    if (detail.Id != 0)
                                    //    {

                                    //        EntityExtension.FlagForUpdate(detail, user, "Facade");

                                    //        foreach (var duplicateItem in duplicateDispositionItems.ToList())
                                    //        {
                                    //            foreach (var duplicateDetail in duplicateItem.Details.ToList())
                                    //            {
                                    //                if (item.Details.Count(d => d.EPODetailId.Equals(duplicateDetail.EPODetailId)) < 1)
                                    //                {
                                    //                    ExternalPurchaseOrderDetail epoDetail = this.dbContext.ExternalPurchaseOrderDetails.Where(s => s.Id == detail.EPODetailId && s.IsDeleted == false).FirstOrDefault();
                                    //                    epoDetail.DispositionQuantity += detail.PaidQuantity;
                                    //                    EntityExtension.FlagForCreate(duplicateDetail, user, "Facade");
                                    //                    item.Details.Add(duplicateDetail);

                                    //                }
                                    //            }
                                    //            purchasingDisposition.Items.Remove(duplicateItem);
                                    //        }
                                    //    }
                                    //}
                                }
                                else
                                {
                                    foreach (var detail in item.Details)
                                    {
                                        if (detail.Id != 0)
                                        {
                                            ExternalPurchaseOrderDetail epoDetail = this.dbContext.ExternalPurchaseOrderDetails.Where(s => s.Id.ToString() == detail.EPODetailId && s.IsDeleted == false).FirstOrDefault();
                                            epoDetail.DispositionQuantity += detail.PaidQuantity;
                                            EntityExtension.FlagForUpdate(detail, user, "Facade");
                                        }
                                    }
                                }
                            }
                        }

                        this.dbContext.Update(purchasingDisposition);

                        foreach (var existingItem in existingModel.Items)
                        {
                            var newItem = purchasingDisposition.Items.FirstOrDefault(i => i.Id == existingItem.Id);
                            if (newItem == null)
                            {
                                EntityExtension.FlagForDelete(existingItem, user, "Facade");

                                this.dbContext.PurchasingDispositionItems.Update(existingItem);
                                foreach (var existingDetail in existingItem.Details)
                                {
                                    EntityExtension.FlagForDelete(existingDetail, user, "Facade");

                                    this.dbContext.PurchasingDispositionDetails.Update(existingDetail);
                                }
                            }
                            else
                            {
                                foreach (var existingDetail in existingItem.Details)
                                {
                                    var newDetail = newItem.Details.FirstOrDefault(d => d.Id == existingDetail.Id);
                                    if (newDetail == null)
                                    {
                                        EntityExtension.FlagForDelete(existingDetail, user, "Facade");

                                        this.dbContext.PurchasingDispositionDetails.Update(existingDetail);
                                    }
                                }
                            }
                        }

                        Updated = await dbContext.SaveChangesAsync();

                        transaction.Commit();
                    }
                    else
                    {
                        throw new Exception("Error");
                    }
                }
                catch (Exception e)
                {
                    transaction.Rollback();
                    throw new Exception(e.Message);
                }
            }

            return(Updated);
        }