Remove inventory, delete transactions
This commit is contained in:
@@ -75,13 +75,17 @@ namespace InventoryTraker.Web
|
|||||||
var r = new Random(1);
|
var r = new Random(1);
|
||||||
var inventoryTypes = context.InventoryTypes.ToList();
|
var inventoryTypes = context.InventoryTypes.ToList();
|
||||||
var cityNames = new List<string> {"Maryville", "Wartburg", "Clinton", "Oak Ridge", "Alcoa", "Jellico"};
|
var cityNames = new List<string> {"Maryville", "Wartburg", "Clinton", "Oak Ridge", "Alcoa", "Jellico"};
|
||||||
|
var colorNames = new List<string> {"Red", "Purple", "Blue", "Yellow", "White"};
|
||||||
|
|
||||||
for (int i = 0; i < 200; i++)
|
for (int i = 0; i < 200; i++)
|
||||||
{
|
{
|
||||||
var inventoryType = inventoryTypes.ElementAt(r.Next(0, context.InventoryTypes.Count()));
|
var inventoryType = inventoryTypes.ElementAt(r.Next(0, context.InventoryTypes.Count()));
|
||||||
var addedDate = DateTime.Today.AddMonths(-r.Next(1, 24));
|
var addedDate = DateTime.Today.AddMonths(-r.Next(1, 24));
|
||||||
var expiration = addedDate.AddMonths(r.Next(2, 48));
|
var expiration = addedDate.AddMonths(r.Next(2, 48));
|
||||||
var memo = "New " + inventoryType.Name;
|
var memo =
|
||||||
|
r.Next(0,3) > 0
|
||||||
|
? colorNames.ElementAt(r.Next(0, colorNames.Count)) + $" {inventoryType.ContainerType}"
|
||||||
|
: string.Empty;
|
||||||
var quantity = r.Next(5, 112);
|
var quantity = r.Next(5, 112);
|
||||||
|
|
||||||
var previousTransaction = new Transaction
|
var previousTransaction = new Transaction
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Attributes
|
||||||
|
{
|
||||||
|
public class ActionLogAttribute : ActionFilterAttribute
|
||||||
|
{
|
||||||
|
public override void OnActionExecuting(ActionExecutingContext filterContext)
|
||||||
|
{
|
||||||
|
if (filterContext != null)
|
||||||
|
{
|
||||||
|
var controller = filterContext.RouteData.Values["controller"].ToString();
|
||||||
|
var action = filterContext.RouteData.Values["action"].ToString();
|
||||||
|
var username = filterContext.HttpContext.User.Identity.Name;
|
||||||
|
var loggerName = $"{controller}Controller.{action}";
|
||||||
|
var @params = string.Join(", ", filterContext.ActionParameters.Select(i => $"{i.Key}: {{{i.Value}}}"));
|
||||||
|
|
||||||
|
var hostAddress = filterContext.HttpContext.Request.UserHostAddress;
|
||||||
|
|
||||||
|
LogManager.GetLogger(loggerName)
|
||||||
|
.Info("UserHostAddress: {0}, username: {1}, params: {{{2}}}", hostAddress, username, @params);
|
||||||
|
}
|
||||||
|
base.OnActionExecuting(filterContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
return new BetterJsonResult<T> {Data = model};
|
return new BetterJsonResult<T> {Data = model};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IEnumerable<string> GetModelStateErrorList()
|
protected string[] GetModelStateErrorList()
|
||||||
{
|
{
|
||||||
var errorList =
|
var errorList =
|
||||||
from kvp in ModelState
|
from kvp in ModelState
|
||||||
@@ -20,13 +20,18 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
let errors = string.Join(", ", kvp.Value.Errors.Select(e => e.ErrorMessage))
|
let errors = string.Join(", ", kvp.Value.Errors.Select(e => e.ErrorMessage))
|
||||||
let msg = kvp.Key + ": " + errors
|
let msg = kvp.Key + ": " + errors
|
||||||
select msg;
|
select msg;
|
||||||
return errorList;
|
return errorList.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JsonResult GetModelStateErrorListJson()
|
protected JsonResult GetModelStateErrorListJson()
|
||||||
|
{
|
||||||
|
return GetErrorListJson(GetModelStateErrorList());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected JsonResult GetErrorListJson(params string[] errors)
|
||||||
{
|
{
|
||||||
var betterJsonResult = new BetterJsonResult();
|
var betterJsonResult = new BetterJsonResult();
|
||||||
foreach (var err in GetModelStateErrorList())
|
foreach (var err in errors)
|
||||||
betterJsonResult.AddError(err);
|
betterJsonResult.AddError(err);
|
||||||
return betterJsonResult;
|
return betterJsonResult;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using System.Linq;
|
|||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using AutoMapper.QueryableExtensions;
|
using AutoMapper.QueryableExtensions;
|
||||||
using InventoryTraker.Web.ActionResults;
|
|
||||||
using InventoryTraker.Web.Core;
|
using InventoryTraker.Web.Core;
|
||||||
using InventoryTraker.Web.Data;
|
using InventoryTraker.Web.Data;
|
||||||
using InventoryTraker.Web.Models;
|
using InventoryTraker.Web.Models;
|
||||||
@@ -57,6 +56,10 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
|
|
||||||
var inventory = Mapper.Map<Inventory>(form);
|
var inventory = Mapper.Map<Inventory>(form);
|
||||||
inventory.InventoryType = _context.InventoryTypes.Find(form.InventoryTypeId);
|
inventory.InventoryType = _context.InventoryTypes.Find(form.InventoryTypeId);
|
||||||
|
|
||||||
|
if (inventory.InventoryType == null)
|
||||||
|
return GetErrorListJson("Inventory Type not found");
|
||||||
|
|
||||||
_context.Inventories.Add(inventory);
|
_context.Inventories.Add(inventory);
|
||||||
inventory.Transactions = new List<Transaction>
|
inventory.Transactions = new List<Transaction>
|
||||||
{
|
{
|
||||||
@@ -81,35 +84,105 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
return GetModelStateErrorListJson();
|
return GetModelStateErrorListJson();
|
||||||
|
|
||||||
|
var errors = new List<string>();
|
||||||
|
|
||||||
foreach (var quantityForm in form.InventoryQuantities)
|
foreach (var quantityForm in form.InventoryQuantities)
|
||||||
{
|
{
|
||||||
var inventory = _context.Inventories.Find(quantityForm.InventoryId);
|
var inventory = _context.Inventories.Find(quantityForm.InventoryId);
|
||||||
|
|
||||||
// check if it's really there
|
// check if it's really there
|
||||||
if (inventory == null)
|
if (inventory == null)
|
||||||
return BetterJsonResult.Error($"Inventory {quantityForm.InventoryId} not found");
|
{
|
||||||
|
errors.Add($"'{quantityForm.InventoryId}' not found");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (inventory.Quantity < quantityForm.Quantity)
|
if (inventory.Quantity < quantityForm.Quantity)
|
||||||
return BetterJsonResult.Error(
|
errors.Add(
|
||||||
$"Inventory {inventory.InventoryType.Name} has only {inventory.Quantity}, trying to remove {quantityForm.Quantity}");
|
$"'{inventory.InventoryType.Name}' has only {inventory.Quantity} qty, " +
|
||||||
|
$"cannot remove {quantityForm.Quantity}");
|
||||||
|
|
||||||
inventory.Quantity -= quantityForm.Quantity;
|
inventory.Quantity -= quantityForm.Quantity;
|
||||||
|
|
||||||
|
var mostRecentTransaction =
|
||||||
|
inventory.Transactions.OrderByDescending(t => t.TransactionDate).First();
|
||||||
|
if (form.DistributedDate < mostRecentTransaction.TransactionDate)
|
||||||
|
errors.Add($"'{inventory.InventoryType.Name}' most recent transaction " +
|
||||||
|
$"is {mostRecentTransaction.TransactionDate.ToShortDateString()}. " +
|
||||||
|
$"Cannot add a transaction on {form.DistributedDate.ToShortDateString()}.");
|
||||||
|
|
||||||
inventory.Transactions.Add(new Transaction
|
inventory.Transactions.Add(new Transaction
|
||||||
{
|
{
|
||||||
TransactionType = TransactionType.Distributed,
|
TransactionType = TransactionType.Distributed,
|
||||||
RemovedQuantity = quantityForm.Quantity,
|
RemovedQuantity = quantityForm.Quantity,
|
||||||
CurrentQuantity = inventory.Quantity,
|
CurrentQuantity = inventory.Quantity,
|
||||||
Memo = "Distributed to " + form.Destination,
|
Memo =
|
||||||
|
string.IsNullOrEmpty(form.Memo)
|
||||||
|
? $"{form.Memo} | "
|
||||||
|
: ""
|
||||||
|
+ $"Distributed to {form.Destination}",
|
||||||
Timestamp = DateTime.Now,
|
Timestamp = DateTime.Now,
|
||||||
TransactionDate = form.DistributedDate
|
TransactionDate = form.DistributedDate
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (errors.Any())
|
||||||
|
return GetErrorListJson(errors.ToArray());
|
||||||
|
|
||||||
_context.SaveChanges();
|
_context.SaveChanges();
|
||||||
|
|
||||||
return BetterJson(AllInventory()
|
return BetterJson(AllInventory()
|
||||||
.ProjectTo<InventoryViewModel>()
|
.ProjectTo<InventoryViewModel>()
|
||||||
.ToArray());
|
.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JsonResult Remove(InventoryRemoveForm form)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
return GetModelStateErrorListJson();
|
||||||
|
|
||||||
|
var errors = new List<string>();
|
||||||
|
|
||||||
|
var inventory = _context.Inventories.Find(form.InventoryId);
|
||||||
|
|
||||||
|
// check if it's really there
|
||||||
|
if (inventory == null)
|
||||||
|
{
|
||||||
|
errors.Add($"'{form.InventoryId}' not found");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (inventory.Quantity < form.Quantity)
|
||||||
|
errors.Add(
|
||||||
|
$"'{inventory.InventoryType.Name}' has only {inventory.Quantity} qty, " +
|
||||||
|
$"cannot remove {form.Quantity}");
|
||||||
|
|
||||||
|
inventory.Quantity -= form.Quantity;
|
||||||
|
|
||||||
|
var mostRecentTransaction =
|
||||||
|
inventory.Transactions.OrderByDescending(t => t.TransactionDate).First();
|
||||||
|
if (form.RemovedDate < mostRecentTransaction.TransactionDate)
|
||||||
|
errors.Add($"'{inventory.InventoryType.Name}' most recent transaction " +
|
||||||
|
$"is {mostRecentTransaction.TransactionDate.ToShortDateString()}. " +
|
||||||
|
$"Cannot add a transaction on {form.RemovedDate.ToShortDateString()}.");
|
||||||
|
|
||||||
|
inventory.Transactions.Add(new Transaction
|
||||||
|
{
|
||||||
|
TransactionType = form.TransactionType,
|
||||||
|
RemovedQuantity = form.Quantity,
|
||||||
|
CurrentQuantity = inventory.Quantity,
|
||||||
|
Memo = form.Memo,
|
||||||
|
Timestamp = DateTime.Now,
|
||||||
|
TransactionDate = form.RemovedDate
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors.Any())
|
||||||
|
return GetErrorListJson(errors.ToArray());
|
||||||
|
|
||||||
|
_context.SaveChanges();
|
||||||
|
|
||||||
|
return BetterJson(Mapper.Map<InventoryViewModel>(inventory));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,9 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using AutoMapper;
|
|
||||||
using AutoMapper.QueryableExtensions;
|
using AutoMapper.QueryableExtensions;
|
||||||
using InventoryTraker.Web.ActionResults;
|
|
||||||
using InventoryTraker.Web.Core;
|
using InventoryTraker.Web.Core;
|
||||||
using InventoryTraker.Web.Data;
|
using InventoryTraker.Web.Data;
|
||||||
using InventoryTraker.Web.Models;
|
using InventoryTraker.Web.Models;
|
||||||
@@ -35,7 +33,7 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
return BetterJson(viewModels);
|
return BetterJson(viewModels);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonResult GetTransactions(int? pageNumber, int? pageSize, int? inventoryId)
|
public JsonResult Get(int? pageNumber, int? pageSize, int? inventoryId)
|
||||||
{
|
{
|
||||||
IQueryable<Transaction> query =
|
IQueryable<Transaction> query =
|
||||||
_context.Transactions
|
_context.Transactions
|
||||||
@@ -56,5 +54,38 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
.ToArray();
|
.ToArray();
|
||||||
return BetterJson(new { totalItems, transactions });
|
return BetterJson(new { totalItems, transactions });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JsonResult Delete(int transactionId)
|
||||||
|
{
|
||||||
|
var transaction = _context.Transactions.Find(transactionId);
|
||||||
|
|
||||||
|
if (transaction == null)
|
||||||
|
return GetErrorListJson("Transaction not found");
|
||||||
|
|
||||||
|
var inventory = transaction.Inventory;
|
||||||
|
var inventoryId = inventory.Id;
|
||||||
|
|
||||||
|
var inventoryTransactionsMostRecent =
|
||||||
|
inventory
|
||||||
|
.Transactions.OrderByDescending(t => t.TransactionDate)
|
||||||
|
.First() == transaction;
|
||||||
|
|
||||||
|
if (!inventoryTransactionsMostRecent)
|
||||||
|
return GetErrorListJson("Delete permitted only when transaction is the most recent");
|
||||||
|
|
||||||
|
// roll back that transaction
|
||||||
|
inventory.Quantity -= transaction.AddedQuantity;
|
||||||
|
inventory.Quantity += transaction.RemovedQuantity;
|
||||||
|
|
||||||
|
inventory.Transactions.Remove(transaction);
|
||||||
|
_context.Transactions.Remove(transaction);
|
||||||
|
|
||||||
|
if (!inventory.Transactions.Any())
|
||||||
|
_context.Inventories.Remove(inventory);
|
||||||
|
|
||||||
|
_context.SaveChanges();
|
||||||
|
|
||||||
|
return BetterJson(new { inventoryId});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -28,12 +28,4 @@ namespace InventoryTraker.Web.Core
|
|||||||
[Required]
|
[Required]
|
||||||
public DateTime Timestamp { get; set; }
|
public DateTime Timestamp { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum TransactionType
|
|
||||||
{
|
|
||||||
Added,
|
|
||||||
Distributed,
|
|
||||||
Expired,
|
|
||||||
Loss
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
namespace InventoryTraker.Web.Core
|
||||||
|
{
|
||||||
|
public enum TransactionType
|
||||||
|
{
|
||||||
|
Added,
|
||||||
|
Distributed,
|
||||||
|
Expired,
|
||||||
|
Loss
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="CsvHelper, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8c4959082be5c823, processorArchitecture=MSIL">
|
<Reference Include="CsvHelper, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8c4959082be5c823, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\CsvHelper.2.16.0.0\lib\net45\CsvHelper.dll</HintPath>
|
<HintPath>..\packages\CsvHelper.2.16.3.0\lib\net45\CsvHelper.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="CsvHelper.Excel, Version=1.0.5.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="CsvHelper.Excel, Version=1.0.5.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
@@ -132,6 +132,14 @@
|
|||||||
<HintPath>..\packages\Newtonsoft.Json.6.0.7\lib\net45\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.6.0.7\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\NLog.4.3.8\lib\net45\NLog.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="NLog.Web, Version=0.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\NLog.Web.4.2.1\lib\net35\NLog.Web.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
|
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
|
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
@@ -229,6 +237,8 @@
|
|||||||
<Content Include="js\inventoryType\InventoryTypeEditDirective.js" />
|
<Content Include="js\inventoryType\InventoryTypeEditDirective.js" />
|
||||||
<Content Include="js\inventoryType\InventoryTypeController.js" />
|
<Content Include="js\inventoryType\InventoryTypeController.js" />
|
||||||
<Content Include="js\inventory\InventoryAddDirective.js" />
|
<Content Include="js\inventory\InventoryAddDirective.js" />
|
||||||
|
<Content Include="js\inventory\inventoryInfoDirective.js" />
|
||||||
|
<Content Include="js\inventory\inventoryRemoveDirective.js" />
|
||||||
<Content Include="js\inventory\InventoryListDirective.js" />
|
<Content Include="js\inventory\InventoryListDirective.js" />
|
||||||
<Content Include="js\inventory\InventoryListController.js" />
|
<Content Include="js\inventory\InventoryListController.js" />
|
||||||
<Content Include="js\inventoryType\inventoryTypeSvc.js" />
|
<Content Include="js\inventoryType\inventoryTypeSvc.js" />
|
||||||
@@ -278,6 +288,14 @@
|
|||||||
<Content Include="js\inventoryType\templates\inventoryTypeEdit.tmpl.cshtml" />
|
<Content Include="js\inventoryType\templates\inventoryTypeEdit.tmpl.cshtml" />
|
||||||
<Content Include="js\inventoryType\templates\inventoryTypeAdd.tmpl.cshtml" />
|
<Content Include="js\inventoryType\templates\inventoryTypeAdd.tmpl.cshtml" />
|
||||||
<Content Include="js\inventoryType\templates\inventoryTypeList.tmpl.cshtml" />
|
<Content Include="js\inventoryType\templates\inventoryTypeList.tmpl.cshtml" />
|
||||||
|
<Content Include="js\inventory\templates\inventoryInfo.tmpl.cshtml" />
|
||||||
|
<Content Include="js\inventory\templates\inventoryRemove.tmpl.cshtml" />
|
||||||
|
<Content Include="NLog.config">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<None Include="NLog.xsd">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</None>
|
||||||
<None Include="Properties\PublishProfiles\ETHRA.pubxml" />
|
<None Include="Properties\PublishProfiles\ETHRA.pubxml" />
|
||||||
<None Include="Scripts\jquery-1.9.1.intellisense.js" />
|
<None Include="Scripts\jquery-1.9.1.intellisense.js" />
|
||||||
<Content Include="Scripts\bootstrap.js" />
|
<Content Include="Scripts\bootstrap.js" />
|
||||||
@@ -300,6 +318,7 @@
|
|||||||
<Compile Include="App_Start\SeedData.cs" />
|
<Compile Include="App_Start\SeedData.cs" />
|
||||||
<Compile Include="App_Start\Startup.cs" />
|
<Compile Include="App_Start\Startup.cs" />
|
||||||
<Compile Include="App_Start\StructureMapConfig.cs" />
|
<Compile Include="App_Start\StructureMapConfig.cs" />
|
||||||
|
<Compile Include="Attributes\ActionLogAttribute.cs" />
|
||||||
<Compile Include="Controllers\TransactionController.cs" />
|
<Compile Include="Controllers\TransactionController.cs" />
|
||||||
<Compile Include="Controllers\InventoryController.cs" />
|
<Compile Include="Controllers\InventoryController.cs" />
|
||||||
<Compile Include="Controllers\AuthenticationController.cs" />
|
<Compile Include="Controllers\AuthenticationController.cs" />
|
||||||
@@ -311,6 +330,7 @@
|
|||||||
<Compile Include="Core\Inventory.cs" />
|
<Compile Include="Core\Inventory.cs" />
|
||||||
<Compile Include="Core\InventoryType.cs" />
|
<Compile Include="Core\InventoryType.cs" />
|
||||||
<Compile Include="Core\Transaction.cs" />
|
<Compile Include="Core\Transaction.cs" />
|
||||||
|
<Compile Include="Core\TransactionType.cs" />
|
||||||
<Compile Include="Core\User.cs" />
|
<Compile Include="Core\User.cs" />
|
||||||
<Compile Include="Data\AppDbContext.cs" />
|
<Compile Include="Data\AppDbContext.cs" />
|
||||||
<Compile Include="Global.asax.cs">
|
<Compile Include="Global.asax.cs">
|
||||||
@@ -328,6 +348,7 @@
|
|||||||
<Compile Include="Models\InventoryDistributeForm.cs" />
|
<Compile Include="Models\InventoryDistributeForm.cs" />
|
||||||
<Compile Include="Models\InventoryAddForm.cs" />
|
<Compile Include="Models\InventoryAddForm.cs" />
|
||||||
<Compile Include="Models\InventoryQuantityForm.cs" />
|
<Compile Include="Models\InventoryQuantityForm.cs" />
|
||||||
|
<Compile Include="Models\InventoryRemoveForm.cs" />
|
||||||
<Compile Include="Models\InventoryTypeViewModel.cs" />
|
<Compile Include="Models\InventoryTypeViewModel.cs" />
|
||||||
<Compile Include="Models\InventoryViewModel.cs" />
|
<Compile Include="Models\InventoryViewModel.cs" />
|
||||||
<Compile Include="Models\LoginForm.cs" />
|
<Compile Include="Models\LoginForm.cs" />
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using InventoryTraker.Web.Core;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Models
|
||||||
|
{
|
||||||
|
public class InventoryRemoveForm
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public int InventoryId { get; set; }
|
||||||
|
|
||||||
|
[Required, Range(1, int.MaxValue, ErrorMessage = "Quantity must be greater than 0")]
|
||||||
|
public int Quantity { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public TransactionType TransactionType { get; set; }
|
||||||
|
|
||||||
|
[Required, Display(Name = "Removed Date")]
|
||||||
|
public DateTime RemovedDate { get; set; }
|
||||||
|
|
||||||
|
public string Memo { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
|
||||||
|
autoReload="true"
|
||||||
|
throwExceptions="false"
|
||||||
|
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
|
||||||
|
|
||||||
|
<!-- optional, add some variables
|
||||||
|
https://github.com/nlog/NLog/wiki/Configuration-file#variables
|
||||||
|
-->
|
||||||
|
<variable name="myvar" value="myvalue"/>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
See https://github.com/nlog/nlog/wiki/Configuration-file
|
||||||
|
for information on customizing logging rules and outputs.
|
||||||
|
-->
|
||||||
|
<targets>
|
||||||
|
<target name="debugLogger" xsi:type="File" fileName="${basedir}/Logs/Debug.${shortdate}.txt" />
|
||||||
|
<target name="exceptionLogger" xsi:type="File" fileName="${basedir}/Logs/Error.${shortdate}.txt" />
|
||||||
|
</targets>
|
||||||
|
</nlog>
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -45,6 +45,6 @@
|
|||||||
saveUrl: url
|
saveUrl: url
|
||||||
});
|
});
|
||||||
|
|
||||||
window.app.constant('model', @Html.JsonFor(Model))
|
window.app.constant('model', @Html.JsonFor(Model));
|
||||||
</script>
|
</script>
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,11 @@ textarea {
|
|||||||
}
|
}
|
||||||
|
|
||||||
th.control-column {
|
th.control-column {
|
||||||
width: 1%;
|
width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-window-slim {
|
||||||
|
/*width: 300px;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*.has-feedback ng-transclude ~ input-validation-icons .form-control-feedback {
|
/*.has-feedback ng-transclude ~ input-validation-icons .form-control-feedback {
|
||||||
|
|||||||
@@ -18,10 +18,10 @@
|
|||||||
|
|
||||||
vm.add = add;
|
vm.add = add;
|
||||||
vm.saving = false;
|
vm.saving = false;
|
||||||
vm.inventory = {};
|
vm.inventory = { };
|
||||||
vm.inventoryTypes = inventoryTypeSvc.inventoryTypes;
|
vm.inventoryTypes = inventoryTypeSvc.inventoryTypes;
|
||||||
|
vm.errorMessages = [];
|
||||||
|
|
||||||
vm.errorMessage = null;
|
|
||||||
vm.quantity = quantity;
|
vm.quantity = quantity;
|
||||||
|
|
||||||
function zeroNaN(v) {
|
function zeroNaN(v) {
|
||||||
@@ -37,6 +37,11 @@
|
|||||||
return vm.inventory.quantity > 0 ? vm.inventory.quantity : "";
|
return vm.inventory.quantity > 0 ? vm.inventory.quantity : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$scope.$watch('vm.commodity', function (newValue) {
|
||||||
|
if (newValue)
|
||||||
|
vm.inventory.inventoryTypeId = newValue.id;
|
||||||
|
});
|
||||||
|
|
||||||
function add() {
|
function add() {
|
||||||
vm.saving = true;
|
vm.saving = true;
|
||||||
inventorySvc.add(vm.inventory)
|
inventorySvc.add(vm.inventory)
|
||||||
@@ -45,17 +50,11 @@
|
|||||||
$scope.$close();
|
$scope.$close();
|
||||||
})
|
})
|
||||||
.error(function(data) {
|
.error(function(data) {
|
||||||
vm.errorMessage =
|
vm.errorMessages = angular.copy(data.errorMessages, vm.errorMessages);
|
||||||
'There was a problem adding the inventory: ' + data.errorMessage;
|
|
||||||
})
|
})
|
||||||
.finally(function() {
|
.finally(function() {
|
||||||
vm.saving = false;
|
vm.saving = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.$watch('vm.commodity', function (newValue, oldValue) {
|
|
||||||
if (newValue)
|
|
||||||
vm.inventory.inventoryTypeId = newValue.id;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
vm.saving = false;
|
vm.saving = false;
|
||||||
vm.quantities = angular.copy(inventorySvc.inventories);
|
vm.quantities = angular.copy(inventorySvc.inventories);
|
||||||
vm.distribution = {};
|
vm.distribution = {};
|
||||||
vm.errorMessage = null;
|
vm.errorMessages = [];
|
||||||
|
|
||||||
function getInventoryDistributeQuantities(inventory) {
|
function getInventoryDistributeQuantities(inventory) {
|
||||||
var invQty = [];
|
var invQty = [];
|
||||||
@@ -39,8 +39,7 @@
|
|||||||
$scope.$close();
|
$scope.$close();
|
||||||
})
|
})
|
||||||
.error(function(data) {
|
.error(function(data) {
|
||||||
vm.errorMessage =
|
vm.errorMessages = angular.copy(data.errorMessages, vm.errorMessages);
|
||||||
'There was a problem distributing the inventory: ' + data.errorMessage;
|
|
||||||
})
|
})
|
||||||
.finally(function() {
|
.finally(function() {
|
||||||
vm.saving = false;
|
vm.saving = false;
|
||||||
|
|||||||
@@ -14,25 +14,49 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
controller.$inject = ['$scope', 'inventorySvc', 'transactionSvc'];
|
controller.$inject = ['$scope', '$uibModal', 'inventorySvc', 'transactionSvc'];
|
||||||
function controller($scope, inventorySvc, transactionSvc) {
|
function controller($scope, $uibModal, inventorySvc, transactionSvc) {
|
||||||
var vm = this;
|
var vm = this;
|
||||||
vm.inventory = angular.copy($scope.inventory);
|
vm.inventory = $scope.inventory;
|
||||||
vm.transactions = [];
|
vm.transactions = [];
|
||||||
|
|
||||||
function loadTransactions() {
|
function refreshTransactions() {
|
||||||
|
vm.loadingTransactions = true;
|
||||||
|
vm.transactions = [];
|
||||||
transactionSvc
|
transactionSvc
|
||||||
.filterByInventoryId(vm.inventory.id)
|
.filterByInventoryId(vm.inventory.id)
|
||||||
.success(function(data) {
|
.success(function (data) {
|
||||||
angular.merge(vm.transactions, data.transactions);
|
if (data.transactions.length === 0) {
|
||||||
});
|
$scope.$parent.$close();
|
||||||
|
} else {
|
||||||
|
angular.copy(data.transactions, vm.transactions);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(function(){vm.loadingTransactions = false;});
|
||||||
}
|
}
|
||||||
|
refreshTransactions(); // initial call
|
||||||
loadTransactions();
|
|
||||||
|
|
||||||
vm.save = save;
|
vm.save = save;
|
||||||
|
vm.deleteTransaction = deleteTransaction;
|
||||||
|
vm.removeInventory = removeInventory;
|
||||||
vm.saving = false;
|
vm.saving = false;
|
||||||
vm.errorMessage = null;
|
vm.errorMessages = [];
|
||||||
|
vm.confirmDeleteTransaction = false;
|
||||||
|
vm.loadingTransactions = false;
|
||||||
|
|
||||||
|
function deleteTransaction(transactionId) {
|
||||||
|
vm.confirmDeleteTransaction = false;
|
||||||
|
transactionSvc
|
||||||
|
.deleteTransaction(transactionId)
|
||||||
|
.success(refreshTransactions);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeInventory() {
|
||||||
|
$uibModal.open({
|
||||||
|
template: '<inventory-remove inventory="inventory" />',
|
||||||
|
scope: angular.extend($scope.$new(true), { inventory: vm.inventory })
|
||||||
|
}).closed.then(refreshTransactions);
|
||||||
|
}
|
||||||
|
|
||||||
function save() {
|
function save() {
|
||||||
vm.saving = true;
|
vm.saving = true;
|
||||||
@@ -42,7 +66,7 @@
|
|||||||
$scope.$parent.$close();
|
$scope.$parent.$close();
|
||||||
})
|
})
|
||||||
.error(function(data) {
|
.error(function(data) {
|
||||||
vm.errorMessage = 'There was a problem saving changes to the inventory: ' + data.errorMessage;
|
vm.errorMessages = angular.copy(data.errorMessages, vm.errorMessages);
|
||||||
})
|
})
|
||||||
.finally(function() {
|
.finally(function() {
|
||||||
vm.saving = false;
|
vm.saving = false;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
vm.inventories = $scope.inventories;
|
vm.inventories = $scope.inventories;
|
||||||
vm.edit = edit;
|
vm.edit = edit;
|
||||||
|
vm.remove = remove;
|
||||||
|
|
||||||
function edit(inventory) {
|
function edit(inventory) {
|
||||||
$uibModal.open({
|
$uibModal.open({
|
||||||
@@ -24,5 +25,12 @@
|
|||||||
scope: angular.extend($scope.$new(true), { inventory: inventory })
|
scope: angular.extend($scope.$new(true), { inventory: inventory })
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function remove(inventory) {
|
||||||
|
$uibModal.open({
|
||||||
|
template: '<inventory-remove inventory="inventory" />',
|
||||||
|
scope: angular.extend($scope.$new(true), { inventory: inventory })
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
window.app.directive('inventoryInfo', inventoryInfo);
|
||||||
|
|
||||||
|
function inventoryInfo() {
|
||||||
|
return {
|
||||||
|
scope: { "inventory": "=" },
|
||||||
|
templateUrl: '/inventory/template/inventoryInfo.tmpl.cshtml',
|
||||||
|
controller: controller,
|
||||||
|
controllerAs: 'vm'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.$inject = ['$scope'];
|
||||||
|
function controller($scope) {
|
||||||
|
var vm = this;
|
||||||
|
vm.inventory = $scope.inventory;
|
||||||
|
}
|
||||||
|
})();
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
window.app.directive('inventoryRemove', inventoryRemove);
|
||||||
|
|
||||||
|
function inventoryRemove() {
|
||||||
|
return {
|
||||||
|
scope: { "inventory": "=" },
|
||||||
|
templateUrl: '/inventory/template/inventoryRemove.tmpl.cshtml',
|
||||||
|
controller: controller,
|
||||||
|
controllerAs: 'vm'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.$inject = ['$scope', 'inventorySvc'];
|
||||||
|
function controller($scope, inventorySvc) {
|
||||||
|
var vm = this;
|
||||||
|
vm.inventory = $scope.inventory;
|
||||||
|
|
||||||
|
vm.save = save;
|
||||||
|
vm.saving = false;
|
||||||
|
vm.removeForm = {
|
||||||
|
inventoryId: vm.inventory.id,
|
||||||
|
quantity: vm.inventory.quantity,
|
||||||
|
transactionType: vm.inventory.isExpired ? "Expired" : null
|
||||||
|
};
|
||||||
|
|
||||||
|
vm.errorMessages = [];
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
vm.saving = true;
|
||||||
|
inventorySvc.remove(vm.removeForm)
|
||||||
|
.success(function (data) {
|
||||||
|
//Close the modal
|
||||||
|
$scope.$parent.$close();
|
||||||
|
})
|
||||||
|
.error(function (data) {
|
||||||
|
vm.errorMessages = angular.copy(data.errorMessages, vm.errorMessages);
|
||||||
|
})
|
||||||
|
.finally(function () {
|
||||||
|
vm.saving = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
(function() {
|
(function() {
|
||||||
window.app.factory('inventorySvc', inventorySvc);
|
window.app.factory('inventorySvc', inventorySvc);
|
||||||
|
|
||||||
inventorySvc.$inject = ['$http'];
|
inventorySvc.$inject = ['$http', '$filter'];
|
||||||
function inventorySvc($http) {
|
function inventorySvc($http, $filter) {
|
||||||
var inventories = [];
|
var inventories = [];
|
||||||
|
|
||||||
loadInventories();
|
loadInventories();
|
||||||
@@ -11,8 +11,11 @@
|
|||||||
add: add,
|
add: add,
|
||||||
distribute: distribute,
|
distribute: distribute,
|
||||||
update: update,
|
update: update,
|
||||||
|
remove: remove,
|
||||||
inventories: inventories,
|
inventories: inventories,
|
||||||
getInventory: getInventory
|
get: get,
|
||||||
|
refresh: refresh,
|
||||||
|
find: find
|
||||||
};
|
};
|
||||||
|
|
||||||
return svc;
|
return svc;
|
||||||
@@ -45,7 +48,34 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInventory(id) {
|
// remove quantity from this inventory
|
||||||
|
function remove(removeForm) {
|
||||||
|
var existingInventory = get(removeForm.inventoryId);
|
||||||
|
return $http.post('/Inventory/Remove', removeForm)
|
||||||
|
.success(function(data) {
|
||||||
|
angular.copy(data, existingInventory);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function get(id) {
|
||||||
|
var results = $filter('filter')(inventories, { id: id });
|
||||||
|
if (results.length > 0)
|
||||||
|
return results[0];
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// refresh this inventory from the server
|
||||||
|
function refresh(id) {
|
||||||
|
var existingInventory = get(id);
|
||||||
|
if (existingInventory) {
|
||||||
|
find(id)
|
||||||
|
.success(function(inventory) {
|
||||||
|
angular.copy(inventory, existingInventory);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function find(id) {
|
||||||
return $http.post('/Inventory/Find', { id: id });
|
return $http.post('/Inventory/Find', { id: id });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,15 @@
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="alert alert-info" ng-hide="vm.errorMessage != null">
|
<div class="alert alert-info" ng-hide="vm.errorMessages.length">
|
||||||
Enter details for the inventory arrival below.
|
Enter details for the inventory arrival below.
|
||||||
</div>
|
</div>
|
||||||
<div class="alert alert-danger" ng-show="vm.errorMessage != null">
|
<div class="alert alert-danger" ng-show="vm.errorMessages.length">
|
||||||
{{vm.errorMessage}}
|
There were problems adding the inventory.
|
||||||
</div>
|
<ul>
|
||||||
|
<li ng-repeat="error in vm.errorMessages">{{error}}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script type="text/ng-template" id="commodityTypeahead.html">
|
<script type="text/ng-template" id="commodityTypeahead.html">
|
||||||
<a>
|
<a>
|
||||||
|
|||||||
@@ -14,11 +14,14 @@
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="alert alert-info" ng-hide="vm.errorMessage != null">
|
<div class="alert alert-info" ng-hide="vm.errorMessages.length">
|
||||||
Enter details for the inventory arrival below.
|
Enter details for the inventory distribution below.
|
||||||
</div>
|
</div>
|
||||||
<div class="alert alert-danger" ng-show="vm.errorMessage != null">
|
<div class="alert alert-danger" ng-show="vm.errorMessages.length">
|
||||||
{{vm.errorMessage}}
|
There were problems distributing the inventory.
|
||||||
|
<ul>
|
||||||
|
<li ng-repeat="error in vm.errorMessages">{{error}}</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@distribution.FormGroupFor(m => m.Destination)
|
@distribution.FormGroupFor(m => m.Destination)
|
||||||
@@ -42,7 +45,7 @@
|
|||||||
{{inventory.name}}<br/>
|
{{inventory.name}}<br/>
|
||||||
{{inventory.unitsPerCase}} / {{inventory.containerType}}<br/>
|
{{inventory.unitsPerCase}} / {{inventory.containerType}}<br/>
|
||||||
</td>
|
</td>
|
||||||
<td>{{inventory.expirationDate | date:'shortDate'}}</td>
|
<td ng-class="{ danger: inventory.isExpired }">{{inventory.expirationDate | date:'shortDate'}}</td>
|
||||||
<td>{{inventory.quantity}}</td>
|
<td>{{inventory.quantity}}</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="form-group col-sm-9" form-group-validation="DistributeQuantity{{inventory.name}}">
|
<div class="form-group col-sm-9" form-group-validation="DistributeQuantity{{inventory.name}}">
|
||||||
@@ -56,8 +59,6 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
|||||||
@@ -1,62 +1,71 @@
|
|||||||
@using InventoryTraker.Web.Helpers
|
@model InventoryTraker.Web.Models.InventoryAddForm
|
||||||
@model InventoryTraker.Web.Models.InventoryAddForm
|
|
||||||
<form novalidate
|
<form novalidate
|
||||||
name="vm.form"
|
name="vm.form"
|
||||||
ng-submit="vm.form.$valid && vm.save()">
|
ng-submit="vm.form.$valid && vm.save()">
|
||||||
<fieldset ng-disabled="vm.saving">
|
<fieldset ng-disabled="vm.saving">
|
||||||
|
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h3 class="modal-title"><i class="fa fa-cubes"></i> Inventory Details</h3>
|
<h3 class="modal-title"><i class="fa fa-cubes"></i> Inventory Details</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="alert alert-danger" ng-show="vm.errorMessage != null">
|
<div class="alert alert-danger" ng-show="vm.errorMessage != null">
|
||||||
{{vm.errorMessage}}
|
{{vm.errorMessage}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<dl class="dl-horizontal">
|
<inventory-info inventory="inventory"></inventory-info>
|
||||||
<dt>Name</dt>
|
<div class="modal-footer">
|
||||||
<dd>{{vm.inventory.name}}</dd>
|
<button ng-click="vm.removeInventory()" class="btn btn-sm pull-left"><i class="fa fa-minus-circle"></i> Remove Inventory</button>
|
||||||
<dt>Added</dt>
|
<button class="btn btn-success">Save</button>
|
||||||
<dd>{{vm.inventory.addedDate | date:'shortDate'}}</dd>
|
<button type="button" class="btn" ng-click="$parent.$dismiss()">Cancel</button>
|
||||||
<dt>Expiration</dt>
|
</div>
|
||||||
<dd>{{vm.inventory.expirationDate | date:'shortDate'}}</dd>
|
|
||||||
</dl>
|
|
||||||
|
|
||||||
<table class="table table-striped table-condensed">
|
<hr />
|
||||||
<thead>
|
|
||||||
<tr>
|
<h4 class="modal-title pull-left"><i class="fa fa-fw fa-list"></i> Transactions</h4>
|
||||||
<th>Type</th>
|
|
||||||
<th>Memo</th>
|
<table class="table table-striped table-condensed">
|
||||||
<th>Transaction Date</th>
|
<thead>
|
||||||
<th>Add Qty</th>
|
<tr>
|
||||||
<th>Remove Qty</th>
|
<th>Type</th>
|
||||||
<th>Qty</th>
|
<th>Memo</th>
|
||||||
<th></th>
|
<th>Transaction Date</th>
|
||||||
</tr>
|
<th>Add Qty</th>
|
||||||
</thead>
|
<th>Remove Qty</th>
|
||||||
<tbody>
|
<th>Qty</th>
|
||||||
<tr ng-repeat="transaction in vm.transactions | orderBy:'-transactionDate'">
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody ng-hide="vm.loadingTransactions">
|
||||||
|
<tr ng-repeat-start="transaction in vm.transactions | orderBy:'-transactionDate'">
|
||||||
<td>{{transaction.transactionType}}</td>
|
<td>{{transaction.transactionType}}</td>
|
||||||
<td>{{transaction.memo}}</td>
|
<td>{{transaction.memo}}</td>
|
||||||
<td>{{transaction.transactionDate | date:'shortDate'}}</td>
|
<td>{{transaction.transactionDate | date:'shortDate'}}</td>
|
||||||
<td>{{transaction.addedQuantity}}</td>
|
<td>{{transaction.addedQuantity}}</td>
|
||||||
<td>{{transaction.removedQuantity}}</td>
|
<td>{{transaction.removedQuantity}}</td>
|
||||||
<td>{{transaction.currentQuantity}}</td>
|
<td>{{transaction.currentQuantity}}</td>
|
||||||
<td><a href="" ng-show="$first"><i class="fa fa-trash"></i></a></td>
|
<td>
|
||||||
|
<a href="" ng-show="$first"
|
||||||
|
ng-click="vm.confirmDeleteTransaction = !vm.confirmDeleteTransaction">
|
||||||
|
<i class="fa fa-trash"></i>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
<tr ng-repeat-end ng-show="$first && vm.confirmDeleteTransaction">
|
||||||
</table>
|
<td colspan="7">
|
||||||
<div >
|
<span ng-show="vm.transactions.length == 1" class="text-danger">
|
||||||
|
Warning: Deleting the only transaction will delete the entire inventory
|
||||||
</div>
|
</span>
|
||||||
|
<button
|
||||||
|
ng-click="vm.deleteTransaction(transaction.id)"
|
||||||
|
class="btn btn-danger btn-sm pull-right">
|
||||||
|
<i class="fa fa-trash"></i> Confirm Delete
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
</fieldset>
|
||||||
<div class="modal-footer">
|
|
||||||
<button class="btn btn-success">Save</button>
|
|
||||||
<button type="button" class="btn" ng-click="$parent.$dismiss()">Cancel</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</fieldset>
|
|
||||||
</form>
|
</form>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<dl class="dl-horizontal">
|
||||||
|
<dt>Name</dt>
|
||||||
|
<dd>{{inventory.name}}</dd>
|
||||||
|
<dt>Units per Case</dt>
|
||||||
|
<dd>{{inventory.unitsPerCase}} / {{inventory.containerType}}</dd>
|
||||||
|
<dt>Added Date</dt>
|
||||||
|
<dd>{{inventory.addedDate | date:'shortDate'}}</dd>
|
||||||
|
<dt>Expiration Date</dt>
|
||||||
|
<dd>
|
||||||
|
<span ng-class="{ 'bg-danger': inventory.isExpired }">
|
||||||
|
{{inventory.expirationDate | date:'shortDate'}}
|
||||||
|
<span ng-show="inventory.isExpired" class="label label-danger">Expired</span>
|
||||||
|
</span>
|
||||||
|
</dd>
|
||||||
|
<dt>Quantity (in Cases)</dt>
|
||||||
|
<dd>{{inventory.quantity}}</dd>
|
||||||
|
<dt ng-show="inventory.memo">Memo</dt>
|
||||||
|
<dd ng-show="inventory.memo">{{inventory.memo}}</dd>
|
||||||
|
</dl>
|
||||||
@@ -19,8 +19,10 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="inventory in vm.inventories">
|
<tr ng-repeat="inventory in vm.inventories">
|
||||||
<td><a href="" ng-click="vm.edit(inventory)"><i class="fa fa-edit"></i></a></td>
|
<td>
|
||||||
<td>@inventory.BindingFor(x => x.Name) </td>
|
<a href="" ng-click="vm.edit(inventory)" title="Details"><i class="fa fa-edit"></i></a>
|
||||||
|
</td>
|
||||||
|
<td>@inventory.BindingFor(x => x.Name)</td>
|
||||||
<td>@inventory.BindingFor(x => x.UnitsPerCase) / @inventory.BindingFor(x => x.ContainerType)</td>
|
<td>@inventory.BindingFor(x => x.UnitsPerCase) / @inventory.BindingFor(x => x.ContainerType)</td>
|
||||||
<td>@inventory.BindingFor(x => x.Quantity)</td>
|
<td>@inventory.BindingFor(x => x.Quantity)</td>
|
||||||
<td>{{inventory.quantity * inventory.unitsPerCase}}</td>
|
<td>{{inventory.quantity * inventory.unitsPerCase}}</td>
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
@using InventoryTraker.Web.Helpers
|
||||||
|
@model InventoryTraker.Web.Models.InventoryRemoveForm
|
||||||
|
@{
|
||||||
|
var removeForm = Html.Angular().ModelFor("vm.removeForm");
|
||||||
|
}
|
||||||
|
<form novalidate
|
||||||
|
name="form"
|
||||||
|
ng-submit="form.$valid && vm.save()">
|
||||||
|
<fieldset ng-disabled="vm.saving">
|
||||||
|
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3 class="modal-title"><i class="fa fa-cubes"></i> Inventory Removal</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<div class="alert alert-info" ng-hide="vm.errorMessages.length">
|
||||||
|
Enter details for the inventory removal below.
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-danger" ng-show="vm.errorMessages.length">
|
||||||
|
There were problems removing the inventory.
|
||||||
|
<ul>
|
||||||
|
<li ng-repeat="error in vm.errorMessages">{{error}}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-body">
|
||||||
|
<inventory-info inventory="inventory"></inventory-info>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group" form-group-validation="TransactionType">
|
||||||
|
<label class="radio-inline">
|
||||||
|
<input type="radio" name="TransactionType"
|
||||||
|
ng-model="vm.removeForm.transactionType"
|
||||||
|
value="Expired"
|
||||||
|
required />
|
||||||
|
Expired
|
||||||
|
</label>
|
||||||
|
<label class="radio-inline">
|
||||||
|
<input type="radio" name="TransactionType"
|
||||||
|
ng-model="vm.removeForm.transactionType"
|
||||||
|
value="Loss"
|
||||||
|
required />
|
||||||
|
Loss
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@removeForm.FormGroupFor(m => m.Quantity)
|
||||||
|
@removeForm.FormGroupFor(m => m.RemovedDate)
|
||||||
|
@removeForm.FormGroupFor(m => m.Memo)
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-success">Remove</button>
|
||||||
|
<button type="button" class="btn" ng-click="$parent.$dismiss()">Cancel</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
vm.saving = false;
|
vm.saving = false;
|
||||||
vm.inventoryType = {};
|
vm.inventoryType = {};
|
||||||
|
|
||||||
vm.errorMessage = null;
|
vm.errorMessages = [];
|
||||||
|
|
||||||
function add() {
|
function add() {
|
||||||
vm.saving = true;
|
vm.saving = true;
|
||||||
@@ -30,8 +30,7 @@
|
|||||||
$scope.$close();
|
$scope.$close();
|
||||||
})
|
})
|
||||||
.error(function(data) {
|
.error(function(data) {
|
||||||
vm.errorMessage =
|
vm.errorMessages = angular.copy(data.errorMessages, vm.errorMessages);
|
||||||
'There was a problem adding the commodity type: ' + data.errorMessage;
|
|
||||||
})
|
})
|
||||||
.finally(function() {
|
.finally(function() {
|
||||||
vm.saving = false;
|
vm.saving = false;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
vm.saving = false;
|
vm.saving = false;
|
||||||
vm.inventoryTypeSvc = inventoryTypeSvc;
|
vm.inventoryTypeSvc = inventoryTypeSvc;
|
||||||
vm.errorMessage = null;
|
vm.errorMessages = [];
|
||||||
|
|
||||||
function save() {
|
function save() {
|
||||||
vm.saving = true;
|
vm.saving = true;
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
$scope.$parent.$close();
|
$scope.$parent.$close();
|
||||||
})
|
})
|
||||||
.error(function(data) {
|
.error(function(data) {
|
||||||
vm.errorMessage = 'There was a problem saving changes to the commodity type: ' + data.errorMessage;
|
vm.errorMessages = angular.copy(data.errorMessages, vm.errorMessages);
|
||||||
})
|
})
|
||||||
.finally(function() {
|
.finally(function() {
|
||||||
vm.saving = false;
|
vm.saving = false;
|
||||||
|
|||||||
@@ -14,12 +14,15 @@
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="alert alert-info" ng-hide="vm.errorMessage != null">
|
<div class="alert alert-info" ng-hide="vm.errorMessages.length">
|
||||||
Enter details for the commodity type below.
|
Enter details for the added commodity below.
|
||||||
</div>
|
</div>
|
||||||
<div class="alert alert-danger" ng-show="vm.errorMessage != null">
|
<div class="alert alert-danger" ng-show="vm.errorMessages.length">
|
||||||
{{vm.errorMessage}}
|
There were problems adding the commodity.
|
||||||
</div>
|
<ul>
|
||||||
|
<li ng-repeat="error in vm.errorMessages">{{error}}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
@Html.Angular().FormForModel("vm.inventoryType")
|
@Html.Angular().FormForModel("vm.inventoryType")
|
||||||
|
|
||||||
|
|||||||
@@ -11,12 +11,15 @@
|
|||||||
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="alert alert-info" ng-hide="vm.errorMessage != null">
|
<div class="alert alert-info" ng-hide="vm.errorMessages.length">
|
||||||
Make changes to the commodity type below.
|
Edit details for the commodity below.
|
||||||
</div>
|
</div>
|
||||||
<div class="alert alert-danger" ng-show="vm.errorMessage != null">
|
<div class="alert alert-danger" ng-show="vm.errorMessages.length">
|
||||||
{{vm.errorMessage}}
|
There were problems saving the commodity.
|
||||||
</div>
|
<ul>
|
||||||
|
<li ng-repeat="error in vm.errorMessages">{{error}}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
@Html.Angular().FormForModel("vm.inventoryType")
|
@Html.Angular().FormForModel("vm.inventoryType")
|
||||||
|
|
||||||
@@ -24,7 +27,7 @@
|
|||||||
|
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class="btn btn-success">Save</button>
|
<button class="btn btn-success">Save</button>
|
||||||
<button type="button" class="btn btn-warning" ng-click="$parent.$dismiss()">Cancel</button>
|
<button type="button" class="btn" ng-click="$parent.$dismiss()">Cancel</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
pageSizes: [20,50,100],
|
pageSizes: [20,50,100],
|
||||||
sort: null
|
sort: null
|
||||||
};
|
};
|
||||||
|
|
||||||
vm.gridOptions = {
|
vm.gridOptions = {
|
||||||
enablePaginationControls: true,
|
enablePaginationControls: true,
|
||||||
paginationPageSize: paginationOptions.pageSize,
|
paginationPageSize: paginationOptions.pageSize,
|
||||||
@@ -65,12 +65,15 @@
|
|||||||
updateData();
|
updateData();
|
||||||
|
|
||||||
$scope.editInventory = function (inventoryId) {
|
$scope.editInventory = function (inventoryId) {
|
||||||
inventorySvc.getInventory(inventoryId)
|
inventorySvc.find(inventoryId)
|
||||||
.success(function(inventory) {
|
.success(function(inventory) {
|
||||||
$uibModal.open({
|
$uibModal.open({
|
||||||
template: '<edit-inventory inventory="inventory" />',
|
template: '<edit-inventory inventory="inventory" />',
|
||||||
scope: angular.extend($scope.$new(true), { inventory: inventory })
|
scope: angular.extend($scope.$new(true), { inventory: inventory })
|
||||||
});
|
})
|
||||||
|
.closed.then(function() {
|
||||||
|
updateData();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
(function() {
|
(function() {
|
||||||
window.app.factory('transactionSvc', transactionSvc);
|
window.app.factory('transactionSvc', transactionSvc);
|
||||||
|
|
||||||
transactionSvc.$inject = ['$http'];
|
transactionSvc.$inject = ['$http', 'inventorySvc'];
|
||||||
function transactionSvc($http) {
|
function transactionSvc($http, inventorySvc) {
|
||||||
|
|
||||||
var svc = {
|
var svc = {
|
||||||
filterByPage: filterByPage,
|
filterByPage: filterByPage,
|
||||||
filterByInventoryId: filterByInventoryId
|
filterByInventoryId: filterByInventoryId,
|
||||||
|
deleteTransaction: deleteTransaction
|
||||||
};
|
};
|
||||||
|
|
||||||
return svc;
|
return svc;
|
||||||
@@ -20,10 +21,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getTransactions(params) {
|
function getTransactions(params) {
|
||||||
var url = '/Transaction/GetTransactions';
|
var url = '/Transaction/Get';
|
||||||
return $http.post(url, params)
|
return $http.post(url, params)
|
||||||
.success(function (data) {
|
.success(function (data) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteTransaction(transactionId) {
|
||||||
|
return $http.post('/Transaction/Delete', { transactionId: transactionId })
|
||||||
|
.success(function (data) {
|
||||||
|
inventorySvc.refresh(data.inventoryId);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<package id="AutoMapper" version="4.2.0" targetFramework="net451" />
|
<package id="AutoMapper" version="4.2.0" targetFramework="net451" />
|
||||||
<package id="bootstrap" version="3.3.7" targetFramework="net451" />
|
<package id="bootstrap" version="3.3.7" targetFramework="net451" />
|
||||||
<package id="ClosedXML" version="0.76.0" targetFramework="net451" />
|
<package id="ClosedXML" version="0.76.0" targetFramework="net451" />
|
||||||
<package id="CsvHelper" version="2.16.0.0" targetFramework="net451" />
|
<package id="CsvHelper" version="2.16.3.0" targetFramework="net451" />
|
||||||
<package id="CsvHelper.Excel" version="1.0.5" targetFramework="net451" />
|
<package id="CsvHelper.Excel" version="1.0.5" targetFramework="net451" />
|
||||||
<package id="DocumentFormat.OpenXml" version="2.5" targetFramework="net451" />
|
<package id="DocumentFormat.OpenXml" version="2.5" targetFramework="net451" />
|
||||||
<package id="EntityFramework" version="6.1.3" targetFramework="net451" />
|
<package id="EntityFramework" version="6.1.3" targetFramework="net451" />
|
||||||
@@ -38,6 +38,10 @@
|
|||||||
<package id="Microsoft.Owin.Security.OAuth" version="3.0.1" targetFramework="net451" />
|
<package id="Microsoft.Owin.Security.OAuth" version="3.0.1" targetFramework="net451" />
|
||||||
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net451" />
|
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net451" />
|
||||||
<package id="Newtonsoft.Json" version="6.0.7" targetFramework="net451" />
|
<package id="Newtonsoft.Json" version="6.0.7" targetFramework="net451" />
|
||||||
|
<package id="NLog" version="4.3.8" targetFramework="net451" />
|
||||||
|
<package id="NLog.Config" version="4.3.8" targetFramework="net451" />
|
||||||
|
<package id="NLog.Schema" version="4.3.8" targetFramework="net451" />
|
||||||
|
<package id="NLog.Web" version="4.2.1" targetFramework="net451" />
|
||||||
<package id="Owin" version="1.0" targetFramework="net451" />
|
<package id="Owin" version="1.0" targetFramework="net451" />
|
||||||
<package id="StructureMap" version="4.4.0" targetFramework="net451" />
|
<package id="StructureMap" version="4.4.0" targetFramework="net451" />
|
||||||
<package id="WebActivatorEx" version="2.1.0" targetFramework="net451" />
|
<package id="WebActivatorEx" version="2.1.0" targetFramework="net451" />
|
||||||
|
|||||||
Reference in New Issue
Block a user