namespace Hims.Infrastructure.Services
{
    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Linq;
    using System.Threading.Tasks;
    using Dapper;
    using Domain.Entities;
    using Domain.Entities.Pharmacy;
    using Domain.Repositories.UnitOfWork;
    using Domain.Services;
    using Hims.Shared.UserModels.OperationTheater;
    using Shared.EntityModels;
    using Shared.UserModels;
    using Shared.UserModels.PharmacyIndent;

    /// <inheritdoc />
    public class IndentServices : IIndentService
    {
        /// <summary>
        /// The unit of work.
        /// </summary>
        private readonly IUnitOfWork unitOfWork;

        /// <summary>
        /// Initializes a new instance of the <see cref="IndentServices"/> class.
        /// </summary>
        /// <param name="unitOfWork">
        /// The unit of work.
        /// </param>
        public IndentServices(IUnitOfWork unitOfWork) => this.unitOfWork = unitOfWork;

        /// <inheritdoc/>
        public async Task<int> CreateIndentRequestAsync(IndentRequestModel model)
        {
            int departmentId;

            var department = await this.unitOfWork.Departments.FindAsync(m => m.DepartmentName == "Inventory");
            if (department == null)
            {
                departmentId = await this.CreateDepartment("Inventory", model.CreatedBy);
            }
            else
            {
                departmentId = department.DepartmentId;
            }

            using (var transaction = this.unitOfWork.BeginTransaction())
            {
                var indentHeader = new IndentHeader
                {
                    ApprovedBy = null,
                    CreatedBy = model.CreatedBy,
                    CreatedDate = DateTime.Now,
                    DepartmentId = departmentId,
                    IndentTo = model.IndentTo,
                    ReasonForRequirement = model.Reason,
                    RequiredDate = model.RequiredDate,
                    RetailPharmacyId = (int?)null,
                    PharmacyDepartmentId = (int?)null,
                    InventoryDepartmentId = model.InventoryDepartmentId,
                    LocationId = (int)model.LocationId
                };
                indentHeader.IndentHeaderId = await this.unitOfWork.IndentHeaders.InsertAsync(indentHeader, transaction);
                if (indentHeader.IndentHeaderId == 0)
                {
                    transaction.Rollback();
                    return -1;
                }

                var details = model.Products.Select(d => new IndentDetail
                {
                    IndentHeaderId = indentHeader.IndentHeaderId,
                    ProductId = d.ProductId,
                    Quantity = d.Quantity
                });

                var detailResponse = await this.unitOfWork.IndentDetails.BulkInsertAsync(details, transaction);
                if (detailResponse == 0)
                {
                    transaction.Rollback();
                    return -2;
                }
                transaction.Commit();
                return indentHeader.IndentHeaderId;
            }
        }
        /// <inheritdoc/>
        public async Task<IndentFetchModel> FindProductNameAsyn(int indentHeaderId)
        {
            var query = $@"select distinct coalesce(ip.""ProductName"" ,pp.""ProductName"" ) as  ""ProductName"" ,a.""FullName"" as ""ApprovedByName""
                        from ""IndentDetail"" ID
                      join ""IndentHeader"" IH on IH.""IndentHeaderId"" = ID.""IndentHeaderId""
                     left join ""InventoryProduct"" ip on ip.""InventoryProductId"" = ID.""ProductId"" and IH.""IndentTo"" = 'I'
                      left join ""PharmacyProduct"" pp on pp.""PharmacyProductId"" = ID.""ProductId""  and IH.""IndentTo"" = 'P' 
                        left join ""Account"" a on a.""AccountId""=IH.""ApprovedBy""
                     where IH.""IndentHeaderId"" ={indentHeaderId}";
            return await this.unitOfWork.Current.QueryFirstOrDefaultAsync<IndentFetchModel>(query);
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<OTIndentModel>> FetchInventoryIndentAsync(OTIndentModel model)
        {
            var where = $@"where 1=1 and IH.""IndentTo"" = 'I'";

            if (!string.IsNullOrEmpty(model.Type))
            {
                switch (model.Type)
                {
                    case "Pending":
                        where += $@" and IH.""ApprovedBy"" is null";
                        break;
                    case "Approved":
                        where += $@" and IH.""ApprovedBy"" is not null";
                        break;
                }
            }
            if (model.CreatedBy > 0)
            {
                where += $@" and IH.""CreatedBy"" = {model.CreatedBy}";
            }

            if (model.FromDate != null)
            {
                where += $@" AND IH.""CreatedDate""::DATE >= '{model.FromDate}'::timestamp without time zone ";
            }
            if (model.ToDate != null)
            {
                where += $@" AND IH.""CreatedDate""::DATE <= '{model.ToDate}'::timestamp without time zone ";
            }

            if (model.LocationId != null)
            {
                where += $@" and IH.""LocationId"" = {model.LocationId} ";
            }
            if (model.InventoryDepartmentId != null)
            {
                where += $@" and  IH.""InventoryDepartmentId""={model.InventoryDepartmentId}";
            }

            if (model.ProductId != null)
            {
                if (model.Type == "Approved")
                {
                    var qry2 = $@"select ""IssueHeaderId"" from ""IssueDetail"" where ""ProductId"" = {model.ProductId}";
                    var issues = await this.unitOfWork.Current.QueryAsync<OTIndentModel>(qry2);
                    var rec = issues.ToList();
                    if (rec.Count > 0)
                    {
                        var id = string.Join(",", rec.Select(x => x.IssueHeaderId));
                        where += $@" AND ISH.""IssueHeaderId"" in ({id})";
                    }
                    else
                    {
                        return null;
                    }
                }
                else
                {
                    var qry1 = $@"select ""IndentHeaderId"" from ""IndentDetail"" where ""ProductId"" = {model.ProductId}";
                    var indents = await this.unitOfWork.Current.QueryAsync<OTIndentModel>(qry1);
                    var records = indents.ToList();
                    if (records.Count > 0)
                    {
                        var ids = string.Join(",", records.Select(x => x.IndentHeaderId));
                        where += $@" AND IH.""IndentHeaderId"" in ({ids})";
                    }
                    else
                    {
                        return null;
                    }
                }
            }

            var query = $@"SELECT count(IH.""IndentHeaderId"") over() as ""TotalItems"", IH.""IndentHeaderId"", IH.""DepartmentId"",
                            IH.""RequiredDate"", IH.""ReasonForRequirement"" as ""Reason"", IH.""IndentTo"", IH.""ApprovedBy"", 
		                    IH.""CreatedBy"", IH.""CreatedDate"", IH.""ModifiedBy"", IH.""ModifiedDate"", IH.""ApprovedDate"", IH.""InventoryDepartmentId"",
		                    CA.""FullName"" as ""CreatedByName"",CR.""RoleName"" as ""CreatedByRole"",ISH.""IssueHeaderId"",
		                    APP.""FullName"" as ""ApprovedByName"",APPR.""RoleName"" as ""ApprovedByRole"",
		                    MA.""FullName"" as ""ModifiedByName"",MR.""RoleName"" as ""ModifiedByRole"",
		                    ID.""Name"" as ""InventoryDepartmentName"",IWH.""Name"" as ""ApprovedWareHouse""
							FROM ""IndentHeader"" IH	                   
	                    join ""Account"" CA on CA.""AccountId"" = IH.""CreatedBy""
	                    join ""Role"" CR on CR.""RoleId"" = CA.""RoleId""
	                    join ""InventoryDepartment"" ID ON ID.""InventoryDepartmentId"" = IH.""InventoryDepartmentId"" 
	                    left join ""Account"" APP on APP.""AccountId"" = IH.""ApprovedBy""
	                    left join ""Role"" APPR on APPR.""RoleId"" = APP.""RoleId""
	                    left join ""Account"" MA on MA.""AccountId"" = IH.""ModifiedBy""
	                    left join ""Role"" MR on MR.""RoleId"" = MA.""RoleId""
	                    left join ""IssueHeader"" ISH on ISH.""IndentHeaderId"" = IH.""IndentHeaderId"" 
	                    left join ""InventoryWareHouse"" IWH on IWH.""InventoryWareHouseId"" = ISH.""InventoryWareHouseId"" 
                        {where}						
	                    order by IH.""CreatedDate"" desc";

            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex > 0 ? model.PageIndex - 1 : model.PageSize;
                query += $@" limit {model.PageSize} offset {model.PageIndex * model.PageSize}";
            }

            return await this.unitOfWork.Current.QueryAsync<OTIndentModel>(query);
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<ProductModel>> FetchInventoryIndentDetailAsync(OTIndentModel model)
        {
            var where = "where 1=1";

            if (model.IndentHeaderId != 0 && model.Type != "Approved")
            {
                where += $@" AND OID.""IndentHeaderId"" ={model.IndentHeaderId}";
            }
            else if (model.IndentHeaderId != 0 && model.Type == "Approved")
            {
                where += $@" and IH.""IndentHeaderId"" = {model.IndentHeaderId}";
            }

            if (model.IssueHeaderId != 0)
            {
                where += $@" AND IH.""IssueHeaderId"" ={model.IssueHeaderId}";
            }

            if ((!string.IsNullOrEmpty(model.Product)) && (model.Product != "null"))
            {
                where += $@" AND IP.""ProductName"" ILIKE '%{model.Product}%'";
            }

            string query;
            if (model.Type != "Approved")
            {
                query = $@"SELECT IP.""InventoryProductId"", OID.""IndentDetailId"",IP.""ProductName"",IP.""PurchaseUnitQuantity"",IP.""CategoryId"", IP.""CompanyId"", 
		                            IP.""PurchaseUnit"",IP.""TaxId"",IP.""IsExpiry"" as ""IsProductExpire"", IP.""CreatedBy"", IP.""CreatedDate"",
                                    C.""Name"" as ""CompanyName"",Cat.""Name"" as ""CategoryName"",Tax.""Name"" as ""Tax"",                                    
                                    PurchaseUnit.""Name"" as ""PurchaseUnitName"",
									OID.""Quantity"" from ""IndentDetail"" OID								 
	                                    join ""InventoryProduct"" IP on IP.""InventoryProductId"" = OID.""ProductId""
										join ""Company"" C on C.""CompanyId"" = IP.""CompanyId""
	                                    join ""LookupValue"" Cat on Cat.""LookupValueId"" = IP.""CategoryId""
	                                    join ""LookupValue"" Tax on Tax.""LookupValueId"" = IP.""TaxId""
	                                    join ""LookupValue"" PurchaseUnit on PurchaseUnit.""LookupValueId"" = IP.""PurchaseUnit""	 
                                        {where}";
                return await this.unitOfWork.Current.QueryAsync<ProductModel>(query);
            }
            else
            { // incomplete section
                query = $@"SELECT IP.""InventoryProductId"", IP.""ProductName"",IP.""PurchaseUnitQuantity"", IP.""CategoryId"", IP.""CompanyId"",IP.""PurchaseUnit"",
                                        IP.""TaxId"", IP.""IsExpiry"" as ""IsProductExpire"",IP.""CreatedBy"", IP.""CreatedDate"",
                                        C.""Name"" as ""CompanyName"",Cat.""Name"" as ""CategoryName"",Tax.""Name"" as ""Tax"",
                                        PurchaseUnit.""Name"" as ""PurchaseUnitName"",OID.""Quantity"",InS.""BatchNumber"",
                                        (select ""Quantity"" from ""IndentDetail"" where ""IndentHeaderId"" = IH.""IndentHeaderId"" and ""ProductId""= IP.""InventoryProductId"") as ""RequestedQuantity""
                                        from ""IssueDetail"" OID
                                        join ""InventoryProduct"" IP on IP.""InventoryProductId"" = OID.""ProductId""
                                        join ""Company"" C on C.""CompanyId"" = IP.""CompanyId""
                                        join ""LookupValue"" Cat on Cat.""LookupValueId"" = IP.""CategoryId""
                                        join ""LookupValue"" Tax on Tax.""LookupValueId"" = IP.""TaxId""
                                        join ""LookupValue"" PurchaseUnit on PurchaseUnit.""LookupValueId"" = IP.""PurchaseUnit""
                                        join ""IssueHeader"" IH on IH.""IssueHeaderId"" = OID.""IssueHeaderId""
                                        join ""InventoryStock"" InS on InS.""InventoryStockId"" = OID.""StockId""
                                        {where}";
                var data = (await this.unitOfWork.Current.QueryAsync<ProductModel>(query)).ToList();
                if (data.Count > 0)
                {
                    var approvedProductIds = string.Join(",", data.Select(p => p.InventoryProductId));
                    var notApprovedProductQuery = $@"select IP.""InventoryProductId"", IP.""ProductName"",ID.""Quantity"" as ""RequestedQuantity""
		                                        from ""IndentDetail"" ID  
		                                        join ""InventoryProduct"" IP on IP.""InventoryProductId"" = ID.""ProductId""
		                                        where 1=1 and ID.""IndentHeaderId"" = {model.IndentHeaderId} 
                                                and IP.""InventoryProductId"" not in ({approvedProductIds})";
                    var notApprovedProducts = (await this.unitOfWork.Current.QueryAsync<ProductModel>(notApprovedProductQuery)).ToList();
                    if (notApprovedProducts.Count > 0)
                    {
                        data.AddRange(notApprovedProducts);
                    }
                }

                return data;
                // incomplete section
            }
        }

        /// <inheritdoc/>
        public async Task<int> DeleteIndentRequestAsync(int indentHeaderId)
        {
            using (var transaction = this.unitOfWork.BeginTransaction())
            {
                var detailQuery = $@"DELETE FROM ""IndentDetail"" WHERE ""IndentHeaderId"" = {indentHeaderId}";
                var detailResponse = await this.unitOfWork.Current.ExecuteAsync(detailQuery, transaction);
                if (detailResponse <= 0)
                {
                    transaction.Rollback();
                    return -1;
                }

                var headerQuery = $@"DELETE FROM ""IndentHeader"" WHERE ""IndentHeaderId"" = {indentHeaderId}";
                var headerResponse = await this.unitOfWork.Current.ExecuteAsync(headerQuery, transaction);
                if (headerResponse <= 0)
                {
                    transaction.Rollback();
                    return -2;
                }

                transaction.Commit();
                return headerResponse;
            }
        }

        /// <inheritdoc/>
        public async Task<long> AddPharmacyDepartmentIndentAsync(PharmacyDepartmentIndentHeaderModel model)
        {
            using var transaction = this.unitOfWork.BeginTransaction();
            var header = new PharmacyDepartmentIndentHeader
            {
                Active = true,
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.Now,
                PharmacyDepartmentId = model.PharmacyDepartmentId,
                Reason = model.Reason,
                RequiredDate = model.RequiredDate
            };

            header.PharmacyDepartmentIndentHeaderId = await this.unitOfWork.PharmacyDepartmentIndentHeaders.InsertAsync(header, transaction);

            if (header.PharmacyDepartmentIndentHeaderId == 0)
            {
                transaction.Rollback();
                return -1;
            }

            var products = model.Products.Select(s => new PharmacyDepartmentIndentDetail
            {
                PharmacyDepartmentIndentHeaderId = header.PharmacyDepartmentIndentHeaderId,
                IsReplaced = false,
                PharmacyProductId = s.PharmacyProductId,
                RequestedQuantity = s.RequestedQuantity
            });

            var data = await this.unitOfWork.PharmacyDepartmentIndentDetails.BulkInsertAsync(products, transaction);
            if (data == 0)
            {
                transaction.Rollback();
                return -1;
            }

            transaction.Commit();
            return header.PharmacyDepartmentIndentHeaderId;

        }

        /// <inheritdoc/>
        public async Task<IEnumerable<PharmacyDepartmentIndentHeaderModel>> FetchPharmacyDepartmentIndentAsync(PharmacyDepartmentIndentHeaderModel model)
        {
            var where = $@" where 1=1";
            if (!string.IsNullOrEmpty(model.Type))
            {
                switch (model.Type)
                {
                    case "Pending":
                        where += $@" and pd.""ApprovedRetailStoreId"" is null";
                        break;
                    case "Approved":
                        where += $@" and pd.""ApprovedRetailStoreId"" is not null";
                        break;
                }
            }

          

            if (model.FromDate !=null)
            {
                where += $@" AND pd.""RequiredDate""::DATE >= '{model.FromDate}'::timestamp without time zone ";
            }
            if (model.ToDate != null)
            {
                where += $@" AND pd.""RequiredDate""::DATE <= '{model.ToDate}'::timestamp without time zone ";
            }
            if (model.LocationId != null)
            {
                where += $@" and pd2.""LocationId"" = {model.LocationId} ";
            }
            if (model.PharmacyDepartmentId != null)
            {
                where += $@" and pd.""PharmacyDepartmentId"" = {model.PharmacyDepartmentId} ";
            }
           

            var query = $@"SELECT count(pd.*) over() as ""TotalItems"", pd.""PharmacyDepartmentIndentHeaderId"", pd.""RequiredDate"", pd.""CreatedBy"", pd.""CreatedDate"", pd.""Active"", pd.""PharmacyDepartmentId"", 
		                            pd.""ApprovedWareHouseId"", pd.""ApprovedRetailStoreId"", pd.""Reason"", pd2.""Name""  as ""DepartmentName"", c.""FullName"" as ""CreatedByName""
	                           ,a.""FullName"" as ""ApprovedByName"", pdih.""CreatedDate"" as ""ApprovedDate"", rp.""RetailName"" as ""ApprovedRetailName""
		                            FROM ""PharmacyDepartmentIndentHeader"" pd
	                            join ""PharmacyDepartment"" pd2 on pd2.""PharmacyDepartmentId""  = pd.""PharmacyDepartmentId""  
	                            join ""Account"" c on c.""AccountId""  = pd.""CreatedBy"" 
	                            left join ""PharmacyDepartmentIssueHeader"" pdih ON pdih.""PharmacyDepartmentIndentHeaderId"" = pd.""PharmacyDepartmentIndentHeaderId"" 
	                            left join ""Account"" a ON a.""AccountId"" = pdih.""CreatedBy"" 
	                            left join ""RetailPharmacy"" rp on rp.""RetailPharmacyId"" = pd.""ApprovedRetailStoreId"" 
                                    {where}
                                order by pd.""CreatedDate"" desc
";
            if (model.PageIndex != null && model.PageSize != null)
            {
                model.PageIndex = model.PageIndex - 1;
                query += $@" limit {model.PageSize} offset {model.PageIndex * model.PageSize}";
            }

            return await this.unitOfWork.Current.QueryAsync<PharmacyDepartmentIndentHeaderModel>(query);
        }

        /// <inheritdoc/>
        public async Task<IEnumerable<PharmacyDepartmentIndentDetailModel>> FetchIndentDetailsAsync(PharmacyDepartmentIndentDetailModel model)
        {
            var where = "where 1=1";
            if (model.PharmacyDepartmentIndentHeaderId != null)
            {
                where += $@" and OID.""PharmacyDepartmentIndentHeaderId"" = {model.PharmacyDepartmentIndentHeaderId}";
            }

            var query = $@"SELECT PP.""PharmacyProductId"", OID.""PharmacyDepartmentIndentDetailId"",OID.""PharmacyDepartmentIndentHeaderId"",PP.""ProductName"", 
                                    PP.""GenericName"", PP.""PurchaseUnitQty"", PP.""SaleUnitQty"", PP.""CategoryId"", PP.""CompanyId"", PP.""PurchaseUnit"",
                                    PP.""SaleUnit"", PP.""TaxId"", PP.""IsProductExpire"", PP.""Active"",
                                    C.""Name"" as ""CompanyName"",Cat.""Name"" as ""CategoryName"",Tax.""Name"" as ""Tax"",
                                    PurchaseUnit.""Name"" as ""PurchaseUnitName"", SaleUnit.""Name"" as ""SaleUnitName"",
									OID.""RequestedQuantity"",OID.""IsReplaced"", pdid.""ApprovedQuantity"" 
									from ""PharmacyDepartmentIndentDetail"" OID								 
	                                    join ""PharmacyProduct"" PP on PP.""PharmacyProductId"" = OID.""PharmacyProductId""
										join ""Company"" C on C.""CompanyId"" = PP.""CompanyId""
	                                    join ""LookupValue"" Cat on Cat.""LookupValueId"" = PP.""CategoryId""
	                                    join ""LookupValue"" Tax on Tax.""LookupValueId"" = PP.""TaxId""
	                                    join ""LookupValue"" PurchaseUnit on PurchaseUnit.""LookupValueId"" = PP.""PurchaseUnit""
	                                    join ""LookupValue"" SaleUnit on SaleUnit.""LookupValueId"" = PP.""SaleUnit""
	                                    left join ""PharmacyDepartmentIssueDetail"" pdid on pdid.""PharmacyDepartmentIndentDetailId"" = OID.""PharmacyDepartmentIndentDetailId""
                                        {where}
                                        order by PP.""ProductName"" asc";

            return await this.unitOfWork.Current.QueryAsync<PharmacyDepartmentIndentDetailModel>(query);
        }

        /// <inheritdoc/>
        public async Task<long> ApprovePharmacyDepartmentIndentAsync(PharmacyDepartmentIndentHeaderModel model)
        {
            using var transaction = this.unitOfWork.BeginTransaction();
            var indent = await this.unitOfWork.PharmacyDepartmentIndentHeaders.FindAsync(h => h.PharmacyDepartmentIndentHeaderId == model.PharmacyDepartmentIndentHeaderId);
            if (indent == null)
            {
                transaction.Rollback();
                return 0;
            }
            var issueHeader = new PharmacyDepartmentIssueHeader
            {
                Comment = model.Comment,
                CreatedBy = model.CreatedBy,
                CreatedDate = DateTime.Now,
                PharmacyDepartmentIndentHeaderId = model.PharmacyDepartmentIndentHeaderId
            };

            issueHeader.PharmacyDepartmentIssueHeaderId = await this.unitOfWork.PharmacyDepartmentIssueHeaders.InsertAsync(issueHeader, transaction);
            if (issueHeader.PharmacyDepartmentIssueHeaderId == 0)
            {
                transaction.Rollback();
                return -1;
            }

            foreach (var product in model.Products)
            {
                var getStock = await this.unitOfWork.PharmacyRetailStocks.FindAsync(s => s.PharmacyRetailStockId == product.PharmacyRetailStockId);
                if (getStock != null)
                {
                    var detail = new PharmacyDepartmentIssueDetail
                    {
                        ApprovedQuantity = (int)product.ApprovedQuantity,
                        PharmacyDepartmentIndentDetailId = (long)product.PharmacyDepartmentIndentDetailId,
                        PharmacyDepartmentIssueHeaderId = issueHeader.PharmacyDepartmentIssueHeaderId,
                        PharmacyProductId = product.PharmacyProductId,
                        PharmacyRetailStockId = (int)product.PharmacyRetailStockId
                    };

                    detail.PharmacyDepartmentIssueDetailId = await this.unitOfWork.PharmacyDepartmentIssueDetails.InsertAsync(detail, transaction);
                    if (detail.PharmacyDepartmentIssueDetailId == 0)
                    {
                        transaction.Rollback();
                        return -1;
                    }

                    getStock.QuantityOut += (int)product.ApprovedQuantity;
                    getStock.ModifiedBy = model.CreatedBy;
                    getStock.ModifiedDate = DateTime.Now;

                    var updateStock = await this.unitOfWork.PharmacyRetailStocks.UpdateAsync(getStock, transaction);
                    if (updateStock == 0)
                    {
                        transaction.Rollback();
                        return -1;
                    }

                    var department = new PharmacyDepartmentalStock
                    {
                        PharmacyProductId = getStock.PharmacyProductId,
                        Barcode = getStock.Barcode,
                        BatchNumber = getStock.BatchNumber,
                        CreatedBy = model.CreatedBy,
                        CreatedDate = DateTime.Now,
                        ExpiryDate = getStock.ExpiryDate,
                        Mrp = getStock.Mrp,
                        PurchaseRate = getStock.PurchaseRate,
                        QuantityIn = (int)product.ApprovedQuantity,
                        QuantityOut = 0,
                        PharmacyRetailStockId = getStock.PharmacyRetailStockId,
                        TaxId = getStock.TaxId,
                        PharmacyDepartmentId = model.PharmacyDepartmentId
                    };

                    var pharmacyDepartmentStock = await this.unitOfWork.PharmacyDepartmentalStocks.FindAsync(r => r.PharmacyStockId == getStock.PharmacyStockId && r.BatchNumber == getStock.BatchNumber && r.PharmacyDepartmentId == department.PharmacyDepartmentId);

                    if (pharmacyDepartmentStock != null)
                    {
                        department.PharmacyDepartmentalStockId = pharmacyDepartmentStock.PharmacyDepartmentalStockId;
                        pharmacyDepartmentStock.QuantityIn += department.QuantityIn;
                        pharmacyDepartmentStock.ModifiedBy = department.CreatedBy;
                        pharmacyDepartmentStock.ModifiedDate = DateTime.Now;
                        var updateResponse = await this.unitOfWork.PharmacyDepartmentalStocks.UpdateAsync(pharmacyDepartmentStock, transaction);
                        if (updateResponse <= 0)
                        {
                            transaction.Rollback();
                            return -1;
                        }
                    }
                    else
                    {
                        department.PharmacyDepartmentalStockId = await this.unitOfWork.PharmacyDepartmentalStocks.InsertAsync(department, transaction);
                        if (department.PharmacyDepartmentalStockId == 0)
                        {
                            transaction.Rollback();
                            return -1;
                        }
                    }
                }
            }

            indent.ApprovedRetailStoreId = model.RetailPharmacyId;
            var updateIndent = await this.unitOfWork.PharmacyDepartmentIndentHeaders.UpdateAsync(indent, transaction);
            if (updateIndent == 0)
            {
                transaction.Rollback();
                return -1;
            }
            transaction.Commit();
            return issueHeader.PharmacyDepartmentIssueHeaderId;
        }

        /// <summary>
        /// The create department.
        /// </summary>
        /// <param name="departmentName">
        /// The department name.
        /// </param>
        /// <param name="createdBy">
        /// The created by.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        private async Task<int> CreateDepartment(string departmentName, int createdBy)
        {
            var department = new Department
            {
                CreatedBy = createdBy,
                DepartmentName = departmentName,
                CreatedDate = DateTime.Now,
                Active = true,
                DeptType = "Other"
            };
            return await this.unitOfWork.Departments.InsertAsync(department);
        }
    }
}