Remove inventory, delete transactions

This commit is contained in:
2016-09-14 07:53:41 -04:00
parent 9cdf90b1e9
commit 052f812d6f
33 changed files with 3250 additions and 142 deletions
+5 -1
View File
@@ -75,13 +75,17 @@ namespace InventoryTraker.Web
var r = new Random(1);
var inventoryTypes = context.InventoryTypes.ToList();
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++)
{
var inventoryType = inventoryTypes.ElementAt(r.Next(0, context.InventoryTypes.Count()));
var addedDate = DateTime.Today.AddMonths(-r.Next(1, 24));
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 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};
}
protected IEnumerable<string> GetModelStateErrorList()
protected string[] GetModelStateErrorList()
{
var errorList =
from kvp in ModelState
@@ -20,13 +20,18 @@ namespace InventoryTraker.Web.Controllers
let errors = string.Join(", ", kvp.Value.Errors.Select(e => e.ErrorMessage))
let msg = kvp.Key + ": " + errors
select msg;
return errorList;
return errorList.ToArray();
}
protected JsonResult GetModelStateErrorListJson()
{
return GetErrorListJson(GetModelStateErrorList());
}
protected JsonResult GetErrorListJson(params string[] errors)
{
var betterJsonResult = new BetterJsonResult();
foreach (var err in GetModelStateErrorList())
foreach (var err in errors)
betterJsonResult.AddError(err);
return betterJsonResult;
}
@@ -4,7 +4,6 @@ using System.Linq;
using System.Web.Mvc;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using InventoryTraker.Web.ActionResults;
using InventoryTraker.Web.Core;
using InventoryTraker.Web.Data;
using InventoryTraker.Web.Models;
@@ -57,6 +56,10 @@ namespace InventoryTraker.Web.Controllers
var inventory = Mapper.Map<Inventory>(form);
inventory.InventoryType = _context.InventoryTypes.Find(form.InventoryTypeId);
if (inventory.InventoryType == null)
return GetErrorListJson("Inventory Type not found");
_context.Inventories.Add(inventory);
inventory.Transactions = new List<Transaction>
{
@@ -81,35 +84,105 @@ namespace InventoryTraker.Web.Controllers
if (!ModelState.IsValid)
return GetModelStateErrorListJson();
var errors = new List<string>();
foreach (var quantityForm in form.InventoryQuantities)
{
var inventory = _context.Inventories.Find(quantityForm.InventoryId);
// check if it's really there
if (inventory == null)
return BetterJsonResult.Error($"Inventory {quantityForm.InventoryId} not found");
{
errors.Add($"'{quantityForm.InventoryId}' not found");
continue;
}
if (inventory.Quantity < quantityForm.Quantity)
return BetterJsonResult.Error(
$"Inventory {inventory.InventoryType.Name} has only {inventory.Quantity}, trying to remove {quantityForm.Quantity}");
errors.Add(
$"'{inventory.InventoryType.Name}' has only {inventory.Quantity} qty, " +
$"cannot remove {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
{
TransactionType = TransactionType.Distributed,
RemovedQuantity = quantityForm.Quantity,
CurrentQuantity = inventory.Quantity,
Memo = "Distributed to " + form.Destination,
Memo =
string.IsNullOrEmpty(form.Memo)
? $"{form.Memo} | "
: ""
+ $"Distributed to {form.Destination}",
Timestamp = DateTime.Now,
TransactionDate = form.DistributedDate
});
}
if (errors.Any())
return GetErrorListJson(errors.ToArray());
_context.SaveChanges();
return BetterJson(AllInventory()
.ProjectTo<InventoryViewModel>()
.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.Linq;
using System.Web.Mvc;
using AutoMapper;
using AutoMapper.QueryableExtensions;
using InventoryTraker.Web.ActionResults;
using InventoryTraker.Web.Core;
using InventoryTraker.Web.Data;
using InventoryTraker.Web.Models;
@@ -35,7 +33,7 @@ namespace InventoryTraker.Web.Controllers
return BetterJson(viewModels);
}
public JsonResult GetTransactions(int? pageNumber, int? pageSize, int? inventoryId)
public JsonResult Get(int? pageNumber, int? pageSize, int? inventoryId)
{
IQueryable<Transaction> query =
_context.Transactions
@@ -56,5 +54,38 @@ namespace InventoryTraker.Web.Controllers
.ToArray();
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});
}
}
}
-8
View File
@@ -28,12 +28,4 @@ namespace InventoryTraker.Web.Core
[Required]
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
}
}
+22 -1
View File
@@ -52,7 +52,7 @@
<Private>True</Private>
</Reference>
<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>
</Reference>
<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>
<Private>True</Private>
</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">
<HintPath>..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
<Private>True</Private>
@@ -229,6 +237,8 @@
<Content Include="js\inventoryType\InventoryTypeEditDirective.js" />
<Content Include="js\inventoryType\InventoryTypeController.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\InventoryListController.js" />
<Content Include="js\inventoryType\inventoryTypeSvc.js" />
@@ -278,6 +288,14 @@
<Content Include="js\inventoryType\templates\inventoryTypeEdit.tmpl.cshtml" />
<Content Include="js\inventoryType\templates\inventoryTypeAdd.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="Scripts\jquery-1.9.1.intellisense.js" />
<Content Include="Scripts\bootstrap.js" />
@@ -300,6 +318,7 @@
<Compile Include="App_Start\SeedData.cs" />
<Compile Include="App_Start\Startup.cs" />
<Compile Include="App_Start\StructureMapConfig.cs" />
<Compile Include="Attributes\ActionLogAttribute.cs" />
<Compile Include="Controllers\TransactionController.cs" />
<Compile Include="Controllers\InventoryController.cs" />
<Compile Include="Controllers\AuthenticationController.cs" />
@@ -311,6 +330,7 @@
<Compile Include="Core\Inventory.cs" />
<Compile Include="Core\InventoryType.cs" />
<Compile Include="Core\Transaction.cs" />
<Compile Include="Core\TransactionType.cs" />
<Compile Include="Core\User.cs" />
<Compile Include="Data\AppDbContext.cs" />
<Compile Include="Global.asax.cs">
@@ -328,6 +348,7 @@
<Compile Include="Models\InventoryDistributeForm.cs" />
<Compile Include="Models\InventoryAddForm.cs" />
<Compile Include="Models\InventoryQuantityForm.cs" />
<Compile Include="Models\InventoryRemoveForm.cs" />
<Compile Include="Models\InventoryTypeViewModel.cs" />
<Compile Include="Models\InventoryViewModel.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; }
}
}
+22
View File
@@ -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
});
window.app.constant('model', @Html.JsonFor(Model))
window.app.constant('model', @Html.JsonFor(Model));
</script>
}
+5 -1
View File
@@ -70,7 +70,11 @@ textarea {
}
th.control-column {
width: 1%;
width: 50px;
}
.modal-window-slim {
/*width: 300px;*/
}
/*.has-feedback ng-transclude ~ input-validation-icons .form-control-feedback {
@@ -18,10 +18,10 @@
vm.add = add;
vm.saving = false;
vm.inventory = {};
vm.inventory = { };
vm.inventoryTypes = inventoryTypeSvc.inventoryTypes;
vm.errorMessages = [];
vm.errorMessage = null;
vm.quantity = quantity;
function zeroNaN(v) {
@@ -37,6 +37,11 @@
return vm.inventory.quantity > 0 ? vm.inventory.quantity : "";
}
$scope.$watch('vm.commodity', function (newValue) {
if (newValue)
vm.inventory.inventoryTypeId = newValue.id;
});
function add() {
vm.saving = true;
inventorySvc.add(vm.inventory)
@@ -45,17 +50,11 @@
$scope.$close();
})
.error(function(data) {
vm.errorMessage =
'There was a problem adding the inventory: ' + data.errorMessage;
vm.errorMessages = angular.copy(data.errorMessages, vm.errorMessages);
})
.finally(function() {
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.quantities = angular.copy(inventorySvc.inventories);
vm.distribution = {};
vm.errorMessage = null;
vm.errorMessages = [];
function getInventoryDistributeQuantities(inventory) {
var invQty = [];
@@ -39,8 +39,7 @@
$scope.$close();
})
.error(function(data) {
vm.errorMessage =
'There was a problem distributing the inventory: ' + data.errorMessage;
vm.errorMessages = angular.copy(data.errorMessages, vm.errorMessages);
})
.finally(function() {
vm.saving = false;
@@ -14,25 +14,49 @@
}
}
controller.$inject = ['$scope', 'inventorySvc', 'transactionSvc'];
function controller($scope, inventorySvc, transactionSvc) {
controller.$inject = ['$scope', '$uibModal', 'inventorySvc', 'transactionSvc'];
function controller($scope, $uibModal, inventorySvc, transactionSvc) {
var vm = this;
vm.inventory = angular.copy($scope.inventory);
vm.inventory = $scope.inventory;
vm.transactions = [];
function loadTransactions() {
function refreshTransactions() {
vm.loadingTransactions = true;
vm.transactions = [];
transactionSvc
.filterByInventoryId(vm.inventory.id)
.success(function(data) {
angular.merge(vm.transactions, data.transactions);
});
.success(function (data) {
if (data.transactions.length === 0) {
$scope.$parent.$close();
} else {
angular.copy(data.transactions, vm.transactions);
}
})
.finally(function(){vm.loadingTransactions = false;});
}
loadTransactions();
refreshTransactions(); // initial call
vm.save = save;
vm.deleteTransaction = deleteTransaction;
vm.removeInventory = removeInventory;
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() {
vm.saving = true;
@@ -42,7 +66,7 @@
$scope.$parent.$close();
})
.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() {
vm.saving = false;
@@ -17,6 +17,7 @@
vm.inventories = $scope.inventories;
vm.edit = edit;
vm.remove = remove;
function edit(inventory) {
$uibModal.open({
@@ -24,5 +25,12 @@
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() {
window.app.factory('inventorySvc', inventorySvc);
inventorySvc.$inject = ['$http'];
function inventorySvc($http) {
inventorySvc.$inject = ['$http', '$filter'];
function inventorySvc($http, $filter) {
var inventories = [];
loadInventories();
@@ -11,8 +11,11 @@
add: add,
distribute: distribute,
update: update,
remove: remove,
inventories: inventories,
getInventory: getInventory
get: get,
refresh: refresh,
find: find
};
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 });
}
}
@@ -14,12 +14,15 @@
<div class="modal-body">
<div class="alert alert-info" ng-hide="vm.errorMessage != null">
Enter details for the inventory arrival below.
</div>
<div class="alert alert-danger" ng-show="vm.errorMessage != null">
{{vm.errorMessage}}
</div>
<div class="alert alert-info" ng-hide="vm.errorMessages.length">
Enter details for the inventory arrival below.
</div>
<div class="alert alert-danger" ng-show="vm.errorMessages.length">
There were problems adding the inventory.
<ul>
<li ng-repeat="error in vm.errorMessages">{{error}}</li>
</ul>
</div>
<script type="text/ng-template" id="commodityTypeahead.html">
<a>
@@ -14,11 +14,14 @@
<div class="modal-body">
<div class="alert alert-info" ng-hide="vm.errorMessage != null">
Enter details for the inventory arrival below.
<div class="alert alert-info" ng-hide="vm.errorMessages.length">
Enter details for the inventory distribution below.
</div>
<div class="alert alert-danger" ng-show="vm.errorMessage != null">
{{vm.errorMessage}}
<div class="alert alert-danger" ng-show="vm.errorMessages.length">
There were problems distributing the inventory.
<ul>
<li ng-repeat="error in vm.errorMessages">{{error}}</li>
</ul>
</div>
@distribution.FormGroupFor(m => m.Destination)
@@ -42,7 +45,7 @@
{{inventory.name}}<br/>
{{inventory.unitsPerCase}} / {{inventory.containerType}}<br/>
</td>
<td>{{inventory.expirationDate | date:'shortDate'}}</td>
<td ng-class="{ danger: inventory.isExpired }">{{inventory.expirationDate | date:'shortDate'}}</td>
<td>{{inventory.quantity}}</td>
<td>
<div class="form-group col-sm-9" form-group-validation="DistributeQuantity{{inventory.name}}">
@@ -56,8 +59,6 @@
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
@@ -1,62 +1,71 @@
@using InventoryTraker.Web.Helpers
@model InventoryTraker.Web.Models.InventoryAddForm
@model InventoryTraker.Web.Models.InventoryAddForm
<form novalidate
name="vm.form"
ng-submit="vm.form.$valid && vm.save()">
<fieldset ng-disabled="vm.saving">
name="vm.form"
ng-submit="vm.form.$valid && vm.save()">
<fieldset ng-disabled="vm.saving">
<div class="modal-header">
<h3 class="modal-title"><i class="fa fa-cubes"></i> Inventory Details</h3>
</div>
<div class="modal-header">
<h3 class="modal-title"><i class="fa fa-cubes"></i> Inventory Details</h3>
</div>
<div class="modal-body">
<div class="modal-body">
<div class="alert alert-danger" ng-show="vm.errorMessage != null">
{{vm.errorMessage}}
</div>
<div class="alert alert-danger" ng-show="vm.errorMessage != null">
{{vm.errorMessage}}
</div>
<dl class="dl-horizontal">
<dt>Name</dt>
<dd>{{vm.inventory.name}}</dd>
<dt>Added</dt>
<dd>{{vm.inventory.addedDate | date:'shortDate'}}</dd>
<dt>Expiration</dt>
<dd>{{vm.inventory.expirationDate | date:'shortDate'}}</dd>
</dl>
<inventory-info inventory="inventory"></inventory-info>
<div class="modal-footer">
<button ng-click="vm.removeInventory()" class="btn btn-sm pull-left"><i class="fa fa-minus-circle"></i> Remove Inventory</button>
<button class="btn btn-success">Save</button>
<button type="button" class="btn" ng-click="$parent.$dismiss()">Cancel</button>
</div>
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Memo</th>
<th>Transaction Date</th>
<th>Add Qty</th>
<th>Remove Qty</th>
<th>Qty</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="transaction in vm.transactions | orderBy:'-transactionDate'">
<hr />
<h4 class="modal-title pull-left"><i class="fa fa-fw fa-list"></i> Transactions</h4>
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>Type</th>
<th>Memo</th>
<th>Transaction Date</th>
<th>Add Qty</th>
<th>Remove Qty</th>
<th>Qty</th>
<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.memo}}</td>
<td>{{transaction.transactionDate | date:'shortDate'}}</td>
<td>{{transaction.addedQuantity}}</td>
<td>{{transaction.removedQuantity}}</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>
</tbody>
</table>
<div >
</div>
<tr ng-repeat-end ng-show="$first && vm.confirmDeleteTransaction">
<td colspan="7">
<span ng-show="vm.transactions.length == 1" class="text-danger">
Warning: Deleting the only transaction will delete the entire inventory
</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 class="modal-footer">
<button class="btn btn-success">Save</button>
<button type="button" class="btn" ng-click="$parent.$dismiss()">Cancel</button>
</div>
</fieldset>
</fieldset>
</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>
<tbody>
<tr ng-repeat="inventory in vm.inventories">
<td><a href="" ng-click="vm.edit(inventory)"><i class="fa fa-edit"></i></a></td>
<td>@inventory.BindingFor(x => x.Name) </td>
<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.Quantity)</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.inventoryType = {};
vm.errorMessage = null;
vm.errorMessages = [];
function add() {
vm.saving = true;
@@ -30,8 +30,7 @@
$scope.$close();
})
.error(function(data) {
vm.errorMessage =
'There was a problem adding the commodity type: ' + data.errorMessage;
vm.errorMessages = angular.copy(data.errorMessages, vm.errorMessages);
})
.finally(function() {
vm.saving = false;
@@ -22,7 +22,7 @@
vm.saving = false;
vm.inventoryTypeSvc = inventoryTypeSvc;
vm.errorMessage = null;
vm.errorMessages = [];
function save() {
vm.saving = true;
@@ -32,7 +32,7 @@
$scope.$parent.$close();
})
.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() {
vm.saving = false;
@@ -14,12 +14,15 @@
<div class="modal-body">
<div class="alert alert-info" ng-hide="vm.errorMessage != null">
Enter details for the commodity type below.
</div>
<div class="alert alert-danger" ng-show="vm.errorMessage != null">
{{vm.errorMessage}}
</div>
<div class="alert alert-info" ng-hide="vm.errorMessages.length">
Enter details for the added commodity below.
</div>
<div class="alert alert-danger" ng-show="vm.errorMessages.length">
There were problems adding the commodity.
<ul>
<li ng-repeat="error in vm.errorMessages">{{error}}</li>
</ul>
</div>
@Html.Angular().FormForModel("vm.inventoryType")
@@ -11,12 +11,15 @@
<div class="modal-body">
<div class="alert alert-info" ng-hide="vm.errorMessage != null">
Make changes to the commodity type below.
</div>
<div class="alert alert-danger" ng-show="vm.errorMessage != null">
{{vm.errorMessage}}
</div>
<div class="alert alert-info" ng-hide="vm.errorMessages.length">
Edit details for the commodity below.
</div>
<div class="alert alert-danger" ng-show="vm.errorMessages.length">
There were problems saving the commodity.
<ul>
<li ng-repeat="error in vm.errorMessages">{{error}}</li>
</ul>
</div>
@Html.Angular().FormForModel("vm.inventoryType")
@@ -24,7 +27,7 @@
<div class="modal-footer">
<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>
</fieldset>
@@ -65,12 +65,15 @@
updateData();
$scope.editInventory = function (inventoryId) {
inventorySvc.getInventory(inventoryId)
inventorySvc.find(inventoryId)
.success(function(inventory) {
$uibModal.open({
template: '<edit-inventory inventory="inventory" />',
scope: angular.extend($scope.$new(true), { inventory: inventory })
});
template: '<edit-inventory inventory="inventory" />',
scope: angular.extend($scope.$new(true), { inventory: inventory })
})
.closed.then(function() {
updateData();
});
});
}
}
@@ -1,12 +1,13 @@
(function() {
window.app.factory('transactionSvc', transactionSvc);
transactionSvc.$inject = ['$http'];
function transactionSvc($http) {
transactionSvc.$inject = ['$http', 'inventorySvc'];
function transactionSvc($http, inventorySvc) {
var svc = {
filterByPage: filterByPage,
filterByInventoryId: filterByInventoryId
filterByInventoryId: filterByInventoryId,
deleteTransaction: deleteTransaction
};
return svc;
@@ -20,10 +21,17 @@
}
function getTransactions(params) {
var url = '/Transaction/GetTransactions';
var url = '/Transaction/Get';
return $http.post(url, params)
.success(function (data) {
});
}
function deleteTransaction(transactionId) {
return $http.post('/Transaction/Delete', { transactionId: transactionId })
.success(function (data) {
inventorySvc.refresh(data.inventoryId);
});
}
}
})();
+5 -1
View File
@@ -9,7 +9,7 @@
<package id="AutoMapper" version="4.2.0" targetFramework="net451" />
<package id="bootstrap" version="3.3.7" 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="DocumentFormat.OpenXml" version="2.5" 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.Web.Infrastructure" version="1.0.0.0" 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="StructureMap" version="4.4.0" targetFramework="net451" />
<package id="WebActivatorEx" version="2.1.0" targetFramework="net451" />