public HttpResponseMessage Post(HenDepreciation value)
        {
            HttpResponseMessage response = null;
            ValidateModel(value);

            if (!ModelState.IsValid)
            {
                response = Request.CreateResponse(HttpStatusCode.BadRequest, GetModelErrors());
                return response;
            }

            try
            {
                service.Save(value);
                response = Request.CreateResponse(HttpStatusCode.Created, value);
                string uri = Url.Link("DefaultApi", new { id = value.Id });
                response.Headers.Location = new Uri(uri);
            }
            catch (Exception ex)
            {
                response = Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
            }

            return response;
        }
        public void Should_HaveDetails()
        {
            var info = new HenDepreciation();
            var errors = info.Validate();

            Assert.True(errors.Any(e => e.Message == "HenDepreciation_RequireDetails"));
        }
        public void Should_ConsistOf_DifferentHouses()
        {
            var houseId = Guid.NewGuid();

            var info = new HenDepreciation
                {
                    Date = DateTime.Today,
                    Details = new List<HenDepreciationDetail>()
                        {
                            new HenDepreciationDetail {HouseId = houseId},
                            new HenDepreciationDetail {HouseId = houseId}
                        }
                };

            var errors = info.Validate();

            Assert.True(errors.Any(e => e.Message == "HenDepreciation_DuplicateHouse"));
        }
        public HttpResponseMessage Put(Guid id, HenDepreciation value)
        {
            ValidateModel(value);

            if (!ModelState.IsValid || value.Id != id)
            {
                return Request.CreateResponse(HttpStatusCode.BadRequest, GetModelErrors());
            }

            HttpResponseMessage response = null;

            try
            {
                service.Save(value);
                response = Request.CreateResponse(HttpStatusCode.OK);
            }
            catch (Exception ex)
            {
                response = Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
            }

            return response;
        }
        public HenDepreciation GetInitialValues(DateTime date)
        {
            var depreciation = new HenDepreciation{Date = date.Date};

            string totalFeedQuery = @"SELECT SUM(ConsumableUsageDetail.Count * COnsumableUsageDetail.UnitPrice)
            FROM ConsumableUsageDetail JOIN ConsumableUsage ON  ConsumableUsageDetail.UsageId = ConsumableUsage.Id
            JOIN Consumable ON ConsumableUsagedetail.ConsumableId = Consumable.Id WHERE  ConsumableUsageDetail.HouseId=@houseId AND ConsumableUsage.Date=@date
            AND Consumable.Type=0";

            string retailQuantityQuery =
                @"SELECT RetailQuantity FROM EggProductionDetail JOIN EggProduction ON EggProductionDetail.ProductionId = EggProduction.Id
            WHERE EggProductionDetail.HouseId=@houseId AND EggProduction.Date=@date";

            using (var db = factory.OpenDbConnection())
            {
                var houses = db.Select<HenHouse>(h => h.Active).OrderBy(h => h.Name).ToList();

                foreach (var house in houses)
                {
                    var detail = new HenDepreciationDetail();
                    detail.HouseId = house.Id;

                    var hens = db.Where<Hen>(new{HouseId = house.Id, Active=true}).ToList();
                    var cost = hens.Sum(h => h.Count * h.Cost);

                    detail.InitialPrice = cost;

                    if (house.ProductiveAge > 0)
                    {
                         int totalFeed = 0;

                        var command = db.CreateCommand();
                        command.CommandType = CommandType.Text;
                        command.CommandText = totalFeedQuery;
                        command.Parameters.Add(new MySqlParameter("@houseId", MySqlDbType.Guid) { Value = house.Id });
                        command.Parameters.Add(new MySqlParameter("@date", MySqlDbType.DateTime) { Value = date });

                        object result = command.ExecuteScalar();

                        if (result != null && result != DBNull.Value)
                            totalFeed = Convert.ToInt32(result);

                        if (totalFeed > 0 )
                        {
                            command = db.CreateCommand();
                            command.CommandType = CommandType.Text;
                            command.CommandText = retailQuantityQuery;
                            command.Parameters.Add(new MySqlParameter("@houseId", MySqlDbType.Guid) { Value = house.Id });
                            command.Parameters.Add(new MySqlParameter("@date", MySqlDbType.DateTime) { Value = date });

                            result = command.ExecuteScalar();

                            decimal retailQuantity = 0;

                            if (result != null && result != DBNull.Value)
                                retailQuantity = Convert.ToDecimal(result);

                            if (retailQuantity > 0)
                            {

                                detail.Depreciation = totalFeed/retailQuantity/house.ProductiveAge;
                            }
                        }
                    }
                    else
                    {
                        detail.SellingPrice = 0;
                    }

                    depreciation.Details.Add(detail);
                }
            }

            return depreciation;
        }
        public void Save(HenDepreciation depreciation)
        {
            using (var db = factory.OpenDbConnection())
            {
                using (var tx = db.OpenTransaction())
                {
                    bool isNew = depreciation.IsNew;

                    Models.Data.HenDepreciation depreciationData = null;

                    if (isNew)
                    {
                        depreciationData = db.FirstOrDefault<Models.Data.HenDepreciation>(u => u.Date == depreciation.Date);
                    }
                    else
                    {
                        depreciationData = db.Query<Models.Data.HenDepreciation>("Date = @Date and Id <> @Id",
                                                                      new { Date = depreciation.Date, Id = depreciation.Id.ToString() })
                                     .FirstOrDefault();
                    }
                    if (depreciationData != null)
                    {
                        tx.Rollback();
                        throw new ServiceException("HenDepreciation_DuplicateDate");
                    }

                    if (isNew)
                        depreciation.Id = Guid.NewGuid();

                    depreciationData = Mapper.Map<HenDepreciation, Models.Data.HenDepreciation>(depreciation);

                    if (isNew) db.InsertParam(depreciationData); else db.UpdateParam(depreciationData);

                    if (!isNew)
                        db.Delete<Models.Data.HenDepreciationDetail>(where: "DepreciationId = {0}".Params(depreciationData.Id.ToString()));

                    foreach (var detail in depreciation.Details)
                    {
                        var detailData = Mapper.Map<HenDepreciationDetail, Models.Data.HenDepreciationDetail>(detail);
                        detailData.DepreciationId = depreciation.Id;
                        db.InsertParam(detailData);
                    }
                    try
                    {
                        tx.Commit();
                    }
                    catch (Exception ex)
                    {
                        tx.Rollback();
                        throw new ServiceException(ex.Message);
                    }
                }
            }
        }