public SPKViewModel GetSPKById(int spkId)
        {
            SPK result = _SPKRepository.GetById(spkId);

            SPKViewModel mappedResult = new SPKViewModel();

            return Map(result, mappedResult);
        }
        public void PrintSPK(SPKViewModel spk, int userId)
        {
            DateTime serverTime = DateTime.Now;
            SPK entity = _SPKRepository.GetById(spk.Id);
            entity.StatusPrintId = (int)DbConstant.SPKPrintStatus.Printed;
            entity.ModifyDate = serverTime;
            entity.ModifyUserId = userId;

            _SPKRepository.Update(entity);

            _unitOfWork.SaveChanges();
        }
        public void AbortSPK(SPKViewModel spk, List<SPKDetailSparepartViewModel> spkSparepartList, List<SPKDetailSparepartDetailViewModel> spkSparepartDetailList, int userId)
        {
            DateTime serverTime = DateTime.Now;

            SPK entity = _SPKRepository.GetById(spk.Id);
            entity.Status = (int)DbConstant.DefaultDataStatus.Deleted;
            entity.ModifyDate = serverTime;
            entity.ModifyUserId = userId;

            _SPKRepository.Update(entity);

            foreach (var item in spkSparepartList)
            {
                Sparepart sparepart = _sparepartRepository.GetById(item.Sparepart.Id);
                sparepart.StockQty = sparepart.StockQty + item.TotalQuantity;
                sparepart.ModifyDate = serverTime;
                sparepart.ModifyUserId = userId;

                _sparepartRepository.Update(sparepart);
            }

            foreach (var item in spkSparepartDetailList)
            {
                SparepartDetail sparepartDetail = _sparepartDetailRepository.GetById(item.SparepartDetail.Id);
                sparepartDetail.ModifyDate = serverTime;
                sparepartDetail.ModifyUserId = userId;
                sparepartDetail.Status = (int)DbConstant.SparepartDetailDataStatus.Active;

                _sparepartDetailRepository.Update(sparepartDetail);
            }

            List<SPKSchedule> scheduleList = _SPKScheduleRepository.GetMany(sched => sched.SPKId == spk.Id).ToList();

            foreach (SPKSchedule schedule in scheduleList)
            {
                _SPKScheduleRepository.Delete(schedule);
            }

            List<WheelExchangeHistory> wehList = _wheelExchangeHistoryRepository.GetMany(weh => weh.SPKId == spk.Id).ToList();

            foreach (var item in wehList)
            {
                _wheelExchangeHistoryRepository.Delete(item);
            }

            _unitOfWork.SaveChanges();
        }
        public void SetAsCompletedSPK(SPKViewModel spk, int userId)
        {
            DateTime serverTime = DateTime.Now;

            SPK entity = _SPKRepository.GetById(spk.Id);
            entity.StatusCompletedId = (int)DbConstant.SPKCompletionStatus.Completed;
            entity.ModifyDate = serverTime;
            entity.ModifyUserId = userId;

            _SPKRepository.Update(entity);

            Invoice invc = new Invoice();
            invc.CreateDate = serverTime;
            invc.ModifyDate = serverTime;
            invc.ModifyUserId = userId;
            invc.CreateUserId = userId;

            invc.Code = spk.Code.Replace("SPK", "INVC");

            invc.TotalSparepart = spk.TotalSparepartPrice;
            invc.TotalFeeSparepart = 0;
            invc.TotalSparepartPlusFee = invc.TotalSparepart + invc.TotalFeeSparepart;

            invc.PaymentStatus = (int)DbConstant.PaymentStatus.NotSettled;
            invc.Status = (int)DbConstant.InvoiceStatus.FeeNotFixed;
            invc.PaymentMethod = _referenceRepository.GetMany(r => r.Code == DbConstant.REF_INVOICE_PAYMENTMETHOD_PIUTANG).FirstOrDefault();
            invc.TotalHasPaid = 0;
            invc.SPKId = spk.Id;

            if (spk.isContractWork)
            {
                invc.TotalService = spk.ContractWorkFee;
                invc.TotalFeeService = (spk.ContractWorkFee * (0.2).AsDecimal());
            }
            else
            {
                decimal ServiceFee = 0;

                TimeSpan SPKTimeSpan = serverTime - spk.CreateDate;
                int SPKWorkingDays = Math.Ceiling(SPKTimeSpan.TotalDays).AsInteger();

                for (int i = 0; i < SPKWorkingDays; i++)
                {
                    List<Mechanic> involvedMechanic = (from sched in _SPKScheduleRepository.GetMany(sc => sc.CreateDate.Day == spk.CreateDate.Day + i && sc.SPKId == spk.Id).ToList()
                                                       select sched.Mechanic).ToList();

                    foreach (Mechanic mechanic in involvedMechanic)
                    {
                        int mechanicJobForToday = _SPKScheduleRepository.GetMany(sc => sc.CreateDate.Day == spk.CreateDate.Day + i && sc.MechanicId == mechanic.Id).Count();

                        decimal mechanicFeeForToday = mechanic.BaseFee / mechanicJobForToday;

                        ServiceFee = ServiceFee + mechanicFeeForToday;
                    }
                }

                invc.TotalService = ServiceFee;
                invc.TotalFeeService = 0;
            }
            invc.TotalServicePlusFee = invc.TotalService + invc.TotalFeeService;
            invc.TotalSparepartAndService = invc.TotalSparepartPlusFee + invc.TotalServicePlusFee;
            invc.TotalValueAdded = (invc.TotalSparepartAndService * (0.1).AsDecimal());
            invc.TotalPrice = invc.TotalValueAdded + invc.TotalSparepartAndService;

            _invoiceRepository.AttachNavigation<SPK>(invc.SPK);
            _invoiceRepository.AttachNavigation<Reference>(invc.PaymentMethod);
            Invoice insertedInvoice = _invoiceRepository.Add(invc);

            List<SPKDetailSparepart> SPKSpList = _SPKDetailSparepartRepository.GetMany(sp => sp.SPKId == spk.Id).ToList();
            List<SPKDetailSparepartDetail> SPKSpDetailList = _SPKDetailSparepartDetailRepository.GetMany(spdt => spdt.SPKDetailSparepart.SPKId == spk.Id).ToList();

            foreach (SPKDetailSparepart spkSp in SPKSpList)
            {
                UsedGood foundUsedGood = _usedGoodRepository.GetMany(ug => ug.SparepartId == spkSp.SparepartId && ug.Status == (int)DbConstant.DefaultDataStatus.Active).FirstOrDefault();
                if (foundUsedGood != null)
                {
                    int usedGoodQty = SPKSpDetailList.Where(sp => sp.SparepartDetail.SparepartId == foundUsedGood.SparepartId).ToList().Count;
                    foundUsedGood.Stock = foundUsedGood.Stock + usedGoodQty;
                    _usedGoodRepository.Update(foundUsedGood);
                    _unitOfWork.SaveChanges();

                    UsedGoodTransaction usedGoodTrans = new UsedGoodTransaction();
                    usedGoodTrans.CreateDate = usedGoodTrans.ModifyDate = serverTime;
                    usedGoodTrans.CreateUserId = usedGoodTrans.ModifyUserId = userId;
                    usedGoodTrans.UsedGoodId = foundUsedGood.Id;
                    usedGoodTrans.TransactionDate = spk.CreateDate;
                    usedGoodTrans.Qty = usedGoodQty;
                    usedGoodTrans.ItemPrice = 0;
                    usedGoodTrans.TotalPrice = 0;
                    usedGoodTrans.TypeReferenceId = _referenceRepository.GetMany(r => r.Code == DbConstant.REF_USEDGOOD_TRANSACTION_TYPE_SPK).FirstOrDefault().Id;
                    usedGoodTrans.Remark = string.Format("SPK Code: {0}", spk.Code);
                    _usedGoodTransactionRepository.Add(usedGoodTrans);
                    _unitOfWork.SaveChanges();
                }

                //Replace Vehicle Wheel
                foreach (var item in getCurrentVehicleWheel(spk.Id, spk.VehicleId).Where(w => w.ReplaceWithWheelDetailId > 0))
                {
                    VehicleWheel vw = _vehicleWheelRepository.GetById(item.Id);

                    vw.WheelDetailId = item.ReplaceWithWheelDetailId;
                    vw.ModifyDate = serverTime;
                    vw.ModifyUserId = userId;

                    _vehicleWheelRepository.Update(vw);

                    UsedGood usedWHeel = _usedGoodRepository.GetMany(ug => ug.SparepartId == item.WheelDetail.SparepartDetail.SparepartId).FirstOrDefault();
                    if (usedWHeel != null)
                    {
                        usedWHeel.Stock++;

                        _usedGoodRepository.Update(usedWHeel);
                    }
                }
                _unitOfWork.SaveChanges();

                //Remove Wheel Exchange
                List<WheelExchangeHistory> wehList = _wheelExchangeHistoryRepository.GetMany(weh => weh.SPKId == spk.Id).ToList();

                foreach (var item in wehList)
                {
                    _wheelExchangeHistoryRepository.Delete(item);
                }
                _unitOfWork.SaveChanges();

                //Update Stock Card
                SparepartStockCard stockCard = new SparepartStockCard();
                Reference transactionReferenceTable = _referenceRepository.GetById(spk.CategoryReferenceId);

                stockCard.CreateUserId = userId;
                stockCard.CreateDate = serverTime;
                stockCard.PrimaryKeyValue = spk.Id;
                stockCard.ReferenceTableId = transactionReferenceTable.Id;
                stockCard.SparepartId = spkSp.SparepartId;
                stockCard.Description = "SPK Complete";
                stockCard.QtyOut = SPKSpDetailList.Count;
                SparepartStockCard lastStockCard = _sparepartStokCardRepository.RetrieveLastCard(spkSp.SparepartId);
                double lastStock = 0;
                if (lastStockCard != null)
                {
                    lastStock = lastStockCard.QtyLast;
                }
                stockCard.QtyFirst = lastStock;
                stockCard.QtyLast = lastStock - stockCard.QtyOut;
                _sparepartStokCardRepository.AttachNavigation(stockCard.CreateUser);
                _sparepartStokCardRepository.AttachNavigation(stockCard.Sparepart);
                _sparepartStokCardRepository.AttachNavigation(stockCard.ReferenceTable);
                _sparepartStokCardRepository.Add(stockCard);
            }

            foreach (SPKDetailSparepartDetail spkSpDtl in SPKSpDetailList)
            {
                InvoiceDetail invcDtl = new InvoiceDetail();

                invcDtl.Invoice = insertedInvoice;
                invcDtl.SPKDetailSparepartDetail = spkSpDtl;

                if (spkSpDtl.SparepartDetail.PurchasingDetailId > 0)
                {
                    invcDtl.SubTotalPrice = spkSpDtl.SparepartDetail.PurchasingDetail.Price.AsDouble();
                }
                else if (spkSpDtl.SparepartDetail.SparepartManualTransactionId > 0)
                {
                    invcDtl.SubTotalPrice = spkSpDtl.SparepartDetail.SparepartManualTransaction.Price.AsDouble();
                }

                invcDtl.Status = (int)DbConstant.DefaultDataStatus.Active;

                invcDtl.CreateDate = serverTime;
                invcDtl.ModifyDate = serverTime;
                invcDtl.ModifyUserId = userId;
                invcDtl.CreateUserId = userId;

                _invoiceDetailRepository.Add(invcDtl);
            }

            _unitOfWork.SaveChanges();
        }
        public bool ApproveSPK(SPKViewModel spk, List<SPKDetailSparepartViewModel> spkSparepartList, List<SPKDetailSparepartDetailViewModel> spkSparepartDetailList, int userId, bool isApproved, out List<SparepartViewModel> warningList)
        {
            bool result = false;
            bool hasParent = false;

            warningList = new List<SparepartViewModel>();

            DateTime serverTime = DateTime.Now;
            SPK spkParent = _SPKRepository.GetById(spk.SPKParentId);

            if (spkParent != null)
            {
                hasParent = true;
            }

            if (isApproved)
            {
                SPK entity = _SPKRepository.GetById(spk.Id);
                entity.StatusApprovalId = (int)DbConstant.ApprovalStatus.Approved;
                entity.StatusPrintId = (int)DbConstant.SPKPrintStatus.Ready;
                entity.ModifyDate = serverTime;
                entity.ModifyUserId = userId;

                _SPKRepository.Update(entity);
                _unitOfWork.SaveChanges();

                foreach (var item in spkSparepartList)
                {
                    Sparepart sparepart = _sparepartRepository.GetById(item.Sparepart.Id);
                    sparepart.StockQty = sparepart.StockQty - item.TotalQuantity;
                    sparepart.ModifyDate = serverTime;
                    sparepart.ModifyUserId = userId;

                    _sparepartRepository.Update(sparepart);

                    if (sparepart.StockQty <= GetStockThreshold())
                    {
                        SparepartViewModel viewModel = new SparepartViewModel();
                        Map(sparepart, viewModel);
                        warningList.Add(viewModel);
                    }
                }

                _unitOfWork.SaveChanges();

                foreach (var item in spkSparepartDetailList)
                {
                    SparepartDetail sparepartDetail = _sparepartDetailRepository.GetById(item.SparepartDetail.Id);
                    sparepartDetail.ModifyDate = serverTime;
                    sparepartDetail.ModifyUserId = userId;
                    if (item.SPKDetailSparepart.SPK.CategoryReference.Id == 22)
                    {
                        sparepartDetail.Status = (int)DbConstant.SparepartDetailDataStatus.OutPurchase;
                    }
                    else
                    {
                        sparepartDetail.Status = (int)DbConstant.SparepartDetailDataStatus.OutService;
                    }

                    _sparepartDetailRepository.Update(sparepartDetail);
                }

                _unitOfWork.SaveChanges();

                result = true;
            }
            else
            {

                SPK entity = _SPKRepository.GetById(spk.Id);
                entity.StatusApprovalId = (int)DbConstant.ApprovalStatus.Approved;
                entity.StatusPrintId = (int)DbConstant.SPKPrintStatus.Ready;
                entity.ModifyDate = serverTime;
                entity.ModifyUserId = userId;

                if (spk.SPKParent == null)
                {
                    entity.SPKParent = null;
                }
                _SPKRepository.Update(entity);

                _unitOfWork.SaveChanges();

                if (hasParent)
                {
                    spkParent.StatusApprovalId = (int)DbConstant.ApprovalStatus.Approved;
                    spkParent.StatusCompletedId = (int)DbConstant.SPKCompletionStatus.InProgress;
                    spkParent.Status = (int)DbConstant.DefaultDataStatus.Active;

                    spkParent.ModifyDate = serverTime;
                    spkParent.ModifyUserId = userId;

                    _SPKRepository.Update(spkParent);

                    _unitOfWork.SaveChanges();
                }
                result = true;
            }

            return result;
        }
        public void AbortParentSPK(SPKViewModel spk, int userId)
        {
            #region Abort Endorsed SPK
            DateTime serverTime = DateTime.Now;

            SPK entity = _SPKRepository.GetById(spk.Id);
            entity.StatusCompletedId = (int)DbConstant.SPKCompletionStatus.Completed;
            entity.StatusApprovalId = (int)DbConstant.ApprovalStatus.Endorsed;
            entity.Status = (int)DbConstant.DefaultDataStatus.Deleted;
            entity.ModifyDate = serverTime;
            entity.ModifyUserId = userId;

            //_SPKRepository.AttachNavigation<Vehicle>(entity.Vehicle);
            //_SPKRepository.AttachNavigation<User>(entity.ModifyUser);
            //_SPKRepository.AttachNavigation<User>(entity.CreateUser);
            //_SPKRepository.AttachNavigation<Reference>(entity.CategoryReference);
            _SPKRepository.Update(entity);

            foreach (var spkSp in _SPKDetailSparepartRepository.GetMany(sds => sds.SPKId == entity.Id))
            {
                Sparepart sparepart = _sparepartRepository.GetById(spkSp.Sparepart.Id);
                sparepart.StockQty = sparepart.StockQty + spkSp.TotalQuantity;
                sparepart.ModifyDate = serverTime;
                sparepart.ModifyUserId = userId;

                SparepartStockCard stockCard = new SparepartStockCard();
                Reference transactionReferenceTable = _referenceRepository.GetById(spk.CategoryReferenceId);

                stockCard.CreateUserId = userId;
                stockCard.CreateDate = serverTime;
                stockCard.PrimaryKeyValue = spk.Id;
                stockCard.ReferenceTableId = transactionReferenceTable.Id;
                stockCard.SparepartId = spkSp.SparepartId;
                stockCard.Description = "Pembatalan SPK";
                stockCard.QtyIn = spkSp.TotalQuantity;

                SparepartStockCard lastStockCard = _sparepartStokCardRepository.RetrieveLastCard(spkSp.SparepartId);
                double lastStock = 0;
                if (lastStockCard != null)
                {
                    lastStock = lastStockCard.QtyLast;
                }
                stockCard.QtyFirst = lastStock;
                stockCard.QtyLast = lastStock + stockCard.QtyIn;
                _sparepartStokCardRepository.AttachNavigation(stockCard.CreateUser);
                _sparepartStokCardRepository.AttachNavigation(stockCard.Sparepart);
                _sparepartStokCardRepository.AttachNavigation(stockCard.ReferenceTable);
                _sparepartStokCardRepository.Add(stockCard);

                //_sparepartRepository.AttachNavigation<User>(sparepart.ModifyUser);
                //_sparepartRepository.AttachNavigation<User>(sparepart.CreateUser);
                //_sparepartRepository.AttachNavigation<Reference>(sparepart.CategoryReference);
                //_sparepartRepository.AttachNavigation<Reference>(sparepart.UnitReference);
                _sparepartRepository.Update(sparepart);
            }

            foreach (var item in _SPKDetailSparepartDetailRepository.GetMany(sdsd => sdsd.SPKDetailSparepart.SPK.Id == entity.Id))
            {
                SparepartDetail sparepartDetail = _sparepartDetailRepository.GetById(item.SparepartDetail.Id);
                sparepartDetail.ModifyDate = serverTime;
                sparepartDetail.ModifyUserId = userId;
                sparepartDetail.Status = (int)DbConstant.SparepartDetailDataStatus.Active;

                //_sparepartDetailRepository.AttachNavigation<User>(sparepartDetail.ModifyUser);
                //_sparepartDetailRepository.AttachNavigation<User>(sparepartDetail.CreateUser);
                //_sparepartDetailRepository.AttachNavigation<Sparepart>(sparepartDetail.Sparepart);
                //_sparepartDetailRepository.AttachNavigation<PurchasingDetail>(sparepartDetail.PurchasingDetail);
                //_sparepartDetailRepository.AttachNavigation<SparepartManualTransaction>(sparepartDetail.SparepartManualTransaction);
                _sparepartDetailRepository.Update(sparepartDetail);
            }

            List<WheelExchangeHistory> wehList = _wheelExchangeHistoryRepository.GetMany(weh => weh.SPKId == spk.Id).ToList();

            foreach (var item in wehList)
            {
                _wheelExchangeHistoryRepository.Delete(item);
            }

            List<SPKSchedule> scheduleList = _SPKScheduleRepository.GetMany(sched => sched.SPKId == spk.Id).ToList();

            foreach (SPKSchedule schedule in scheduleList)
            {
                _SPKScheduleRepository.Delete(schedule);
            }

            _unitOfWork.SaveChanges();
            #endregion
        }
        public SPKViewModel InsertSPK(SPKViewModel spk,
            List<SPKDetailSparepartViewModel> spkSparepartList,
            List<SPKDetailSparepartDetailViewModel> spkSparepartDetailList,
            List<VehicleWheelViewModel> vehicleWheelList,
            int userId,
            bool isNeedApproval)
        {
            DateTime serverTime = DateTime.Now;
            Invoice insertedInvoice = new Invoice();
            Reference spkReference = _referenceRepository.GetById(spk.CategoryReferenceId);
            bool isSPKSales = spkReference.Code == DbConstant.REF_SPK_CATEGORY_SALE;

            string code = "SPK-";

            switch (spkReference.Code)
            {
                case DbConstant.REF_SPK_CATEGORY_SERVICE: code = code + "S";
                    break;
                case DbConstant.REF_SPK_CATEGORY_REPAIR: code = code + "P";
                    break;
                case DbConstant.REF_SPK_CATEGORY_SALE: code = code + "L";
                    break;
                case DbConstant.REF_SPK_CATEGORY_INVENTORY: code = code + "I";
                    break;
            }

            code = code + "-" + spk.Vehicle.ActiveLicenseNumber + "-" + serverTime.Month.ToString() + serverTime.Day.ToString() + "-";

            //get total SPK created today
            List<SPK> todaySPK = _SPKRepository.GetMany(s => s.Code.ToString().Contains(code) && s.CreateDate.Year == serverTime.Year).ToList();

            code = code + (todaySPK.Count + 1);

            spk.Code = code;
            spk.CreateDate = serverTime;
            spk.ModifyDate = serverTime;
            spk.ModifyUserId = userId;
            spk.CreateUserId = userId;

            spk.Status = (int)DbConstant.DefaultDataStatus.Active;
            if (isNeedApproval)
            {
                spk.StatusApprovalId = (int)DbConstant.ApprovalStatus.Pending;
                spk.StatusOverLimit = 1;
                spk.StatusPrintId = (int)DbConstant.SPKPrintStatus.Pending;
            }
            else
            {
                spk.StatusApprovalId = (int)DbConstant.ApprovalStatus.Approved;
                spk.StatusOverLimit = 0;
                spk.StatusPrintId = (int)DbConstant.SPKPrintStatus.Printed;
            }

            spk.StatusCompletedId = isSPKSales ? (int)DbConstant.SPKCompletionStatus.Completed : (int)DbConstant.SPKCompletionStatus.InProgress;
            SPK entityChild = new SPK();
            Map(spk, entityChild);

            SPK insertedSPK = _SPKRepository.Add(entityChild);

            if (isSPKSales)
            {
                //insert invoice

                Invoice invc = new Invoice();
                invc.Code = spk.Code.Replace("SPK", "INVC");
                invc.TotalSparepart = spk.TotalSparepartPrice;
                invc.TotalFeeSparepart = 0;
                invc.TotalSparepartPlusFee = invc.TotalSparepart + invc.TotalFeeSparepart;
                invc.TotalService = 0;
                invc.TotalFeeService = 0;
                invc.TotalServicePlusFee = invc.TotalService + invc.TotalFeeService;
                invc.TotalSparepartAndService = invc.TotalSparepartPlusFee + invc.TotalServicePlusFee;
                invc.TotalValueAdded = (invc.TotalSparepartAndService * (0.1).AsDecimal());
                invc.TotalPrice = invc.TotalValueAdded + invc.TotalSparepartAndService;
                invc.PaymentStatus = (int)DbConstant.PaymentStatus.NotSettled;
                invc.Status = (int)DbConstant.InvoiceStatus.FeeNotFixed;
                invc.TotalHasPaid = 0;
                invc.SPK = insertedSPK;
                invc.PaymentMethod = invc.PaymentMethod = _referenceRepository.GetMany(r => r.Code == DbConstant.REF_INVOICE_PAYMENTMETHOD_PIUTANG).FirstOrDefault();

                invc.CreateDate = serverTime;
                invc.ModifyDate = serverTime;
                invc.ModifyUserId = userId;
                invc.CreateUserId = userId;

                insertedInvoice = _invoiceRepository.Add(invc);
            }

            foreach (var spkSparepart in spkSparepartList)
            {
                SPKDetailSparepart entitySPKDetailSparepart = new SPKDetailSparepart();
                Sparepart sparepart = _sparepartRepository.GetById(spkSparepart.Sparepart.Id);

                entitySPKDetailSparepart.SparepartId = spkSparepart.SparepartId;
                entitySPKDetailSparepart.TotalPrice = spkSparepart.TotalPrice;
                entitySPKDetailSparepart.TotalQuantity = spkSparepart.TotalQuantity;
                entitySPKDetailSparepart.Sparepart = sparepart;
                entitySPKDetailSparepart.SPK = insertedSPK;

                entitySPKDetailSparepart.CreateDate = serverTime;
                entitySPKDetailSparepart.CreateUserId = userId;
                entitySPKDetailSparepart.ModifyDate = serverTime;
                entitySPKDetailSparepart.ModifyUserId = userId;
                entitySPKDetailSparepart.Status = (int)DbConstant.DefaultDataStatus.Active;

                if (!isNeedApproval)
                {
                    sparepart.StockQty = sparepart.StockQty - spkSparepart.TotalQuantity;
                    sparepart.ModifyDate = serverTime;
                    sparepart.ModifyUserId = userId;

                    _sparepartRepository.Update(sparepart);

                    SparepartStockCard stockCard = new SparepartStockCard();
                    Reference transactionReferenceTable = _referenceRepository.GetById(spk.CategoryReferenceId);

                    stockCard.CreateUserId = userId;
                    stockCard.CreateDate = serverTime;
                    stockCard.PrimaryKeyValue = spk.Id;
                    stockCard.ReferenceTableId = transactionReferenceTable.Id;
                    stockCard.SparepartId = sparepart.Id;
                    stockCard.Description = "SPK";
                    stockCard.QtyOut = spkSparepart.TotalQuantity;

                    SparepartStockCard lastStockCard = _sparepartStokCardRepository.RetrieveLastCard(sparepart.Id);
                    double lastStock = 0;
                    if (lastStockCard != null)
                    {
                        lastStock = lastStockCard.QtyLast;
                    }
                    stockCard.QtyFirst = lastStock;
                    stockCard.QtyLast = lastStock - stockCard.QtyOut;
                    _sparepartStokCardRepository.AttachNavigation(stockCard.CreateUser);
                    _sparepartStokCardRepository.AttachNavigation(stockCard.Sparepart);
                    _sparepartStokCardRepository.AttachNavigation(stockCard.ReferenceTable);
                    _sparepartStokCardRepository.Add(stockCard);
                }

                if (isSPKSales)
                {
                    UsedGood foundUsedGood = _usedGoodRepository.GetMany(ug => ug.SparepartId == spkSparepart.SparepartId && ug.Status == (int)DbConstant.DefaultDataStatus.Active).FirstOrDefault();
                    if (foundUsedGood != null)
                    {
                        foundUsedGood.Stock = foundUsedGood.Stock + spkSparepartList.Count;
                        _usedGoodRepository.Update(foundUsedGood);
                    }
                }

                SPKDetailSparepart insertedSPkDetailSparepart = _SPKDetailSparepartRepository.Add(entitySPKDetailSparepart);

                var detailList = spkSparepartDetailList.Where(spd => spd.SparepartDetail.SparepartId == spkSparepart.SparepartId);

                foreach (var spkSparepartDetail in detailList)
                {
                    SPKDetailSparepartDetail entityNewSparepartDetail = new SPKDetailSparepartDetail();

                    entityNewSparepartDetail.CreateDate = serverTime;
                    entityNewSparepartDetail.CreateUserId = userId;
                    entityNewSparepartDetail.ModifyDate = serverTime;
                    entityNewSparepartDetail.ModifyUserId = userId;
                    entityNewSparepartDetail.Status = (int)DbConstant.DefaultDataStatus.Active;

                    entityNewSparepartDetail.SPKDetailSparepart = insertedSPkDetailSparepart;
                    entityNewSparepartDetail.SparepartDetailId = spkSparepartDetail.SparepartDetailId;

                    SPKDetailSparepartDetail insertedSPKSpDtl = _SPKDetailSparepartDetailRepository.Add(entityNewSparepartDetail);

                    if (!isNeedApproval)
                    {
                        SparepartDetail sparepartDetail = _sparepartDetailRepository.GetById(spkSparepartDetail.SparepartDetail.Id);
                        sparepartDetail.ModifyDate = serverTime;
                        sparepartDetail.ModifyUserId = userId;

                        if (spkReference.Code == DbConstant.REF_SPK_CATEGORY_SALE)
                        {
                            sparepartDetail.Status = (int)DbConstant.SparepartDetailDataStatus.OutPurchase;
                        }
                        else
                        {
                            sparepartDetail.Status = (int)DbConstant.SparepartDetailDataStatus.OutService;
                        }

                        _sparepartDetailRepository.Update(sparepartDetail);
                    }

                    //insert invoice detail

                    if (isSPKSales)
                    {
                        InvoiceDetail invcDtl = new InvoiceDetail();

                        invcDtl.Invoice = insertedInvoice;
                        invcDtl.SPKDetailSparepartDetail = insertedSPKSpDtl;

                        if (insertedSPKSpDtl.SparepartDetail.PurchasingDetailId > 0)
                        {
                            invcDtl.SubTotalPrice = insertedSPKSpDtl.SparepartDetail.PurchasingDetail.Price.AsDouble();
                        }
                        else
                        {
                            invcDtl.SubTotalPrice = insertedSPKSpDtl.SparepartDetail.SparepartManualTransaction.Price.AsDouble();
                        }

                        invcDtl.Status = (int)DbConstant.DefaultDataStatus.Active;
                        invcDtl.FeePctg = 0;

                        invcDtl.CreateDate = serverTime;
                        invcDtl.ModifyDate = serverTime;
                        invcDtl.ModifyUserId = userId;
                        invcDtl.CreateUserId = userId;

                        _invoiceDetailRepository.Add(invcDtl);
                    }
                }
            }

            //Wheel Change Handler
            foreach (var item in vehicleWheelList.Where(vw => vw.ReplaceWithWheelDetailId > 0))
            {
                WheelExchangeHistory weh = new WheelExchangeHistory();
                weh.SPK = insertedSPK;
                weh.OriginalWheelId = item.WheelDetailId;
                weh.ReplaceWheelId = item.ReplaceWithWheelDetailId;

                weh.CreateDate = serverTime;
                weh.ModifyDate = serverTime;
                weh.ModifyUserId = userId;
                weh.CreateUserId = userId;

                _wheelExchangeHistoryRepository.Add(weh);

                SpecialSparepartDetail wheel = _specialSparepartDetailRepository.GetById(item.WheelDetailId);
                wheel.Kilometers = spk.Kilometers;
                wheel.ModifyDate = serverTime;
                wheel.ModifyUserId = userId;

                _specialSparepartDetailRepository.Update(wheel);
            }

            // Update Vehicle Kilometers
            Vehicle vehicle = _vehicleRepository.GetById(spk.VehicleId);

            vehicle.Kilometers = spk.Kilometers;
            vehicle.ModifyDate = serverTime;
            vehicle.ModifyUserId = userId;

            _vehicleRepository.Update(vehicle);

            _unitOfWork.SaveChanges();

            SPKViewModel mappedResult = new SPKViewModel();

            return Map(insertedSPK, mappedResult);
        }