InventoryType from XML
Transaction updates
This commit is contained in:
@@ -24,7 +24,7 @@ namespace InventoryTraker.Web.Tests.Models
|
|||||||
{
|
{
|
||||||
AddedDate = DateTime.Today,
|
AddedDate = DateTime.Today,
|
||||||
ExpirationDate = DateTime.Today.AddDays(3),
|
ExpirationDate = DateTime.Today.AddDays(3),
|
||||||
InventoryTypeId = "1",
|
InventoryTypeId = 1,
|
||||||
Memo = "My Memo",
|
Memo = "My Memo",
|
||||||
Quantity = 32
|
Quantity = 32
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,6 +21,13 @@ namespace InventoryTraker.Web.ActionResults
|
|||||||
ErrorMessages.Add(errorMessage);
|
ErrorMessages.Add(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BetterJsonResult Error(string errorMessage)
|
||||||
|
{
|
||||||
|
var betterJsonResult = new BetterJsonResult();
|
||||||
|
betterJsonResult.AddError(errorMessage);
|
||||||
|
return betterJsonResult;
|
||||||
|
}
|
||||||
|
|
||||||
public override void ExecuteResult(ControllerContext context)
|
public override void ExecuteResult(ControllerContext context)
|
||||||
{
|
{
|
||||||
DoUninterestingBaseClassStuff(context);
|
DoUninterestingBaseClassStuff(context);
|
||||||
|
|||||||
@@ -84,47 +84,59 @@ namespace InventoryTraker.Web
|
|||||||
|
|
||||||
private static void AddInventory(AppDbContext context)
|
private static void AddInventory(AppDbContext context)
|
||||||
{
|
{
|
||||||
var pork = context.InventoryTypes.First(it => it.Identifier == "100139");
|
var r = new Random(1);
|
||||||
var beans = context.InventoryTypes.First(it => it.Identifier == "100363");
|
var inventoryTypes = context.InventoryTypes.ToList();
|
||||||
var pb = context.InventoryTypes.First(it => it.Identifier == "100395");
|
|
||||||
|
|
||||||
context.Inventories.Add(new Inventory
|
for (int i = 0; i < 100; i++)
|
||||||
{
|
{
|
||||||
InventoryType = pork,
|
var inventoryType = inventoryTypes.ElementAt(r.Next(0, context.InventoryTypes.Count()));
|
||||||
ExpirationDate = DateTime.Now.AddYears(1).AtMidnight(),
|
var addedDate = DateTime.Today.AddMonths(-r.Next(1, 24));
|
||||||
AddedDate = DateTime.Now.AddDays(-1).AtMidnight(),
|
var expiration = addedDate.AddMonths(r.Next(12, 48));
|
||||||
Memo = "Hormel",
|
var memo = "New " + inventoryType.Name;
|
||||||
Quantity = 10,
|
var quantity = r.Next(5, 112);
|
||||||
Transactions = new List<Transaction> { new Transaction
|
|
||||||
{
|
|
||||||
AddedQuantity = 10, Memo = "arrival", TransactionDate = DateTime.Now.AddDays(-1).AtMidnight(), Timestamp = DateTime.Now
|
|
||||||
}}
|
|
||||||
});
|
|
||||||
|
|
||||||
context.Inventories.Add(new Inventory
|
var previousTransaction = new Transaction
|
||||||
{
|
{
|
||||||
InventoryType = beans,
|
AddedQuantity = quantity, Memo = "Arrival", CurrentQuantity = quantity, TransactionDate = addedDate, Timestamp = addedDate
|
||||||
ExpirationDate = DateTime.Now.AddMonths(4).AtMidnight(),
|
};
|
||||||
AddedDate = DateTime.Now.AddMonths(-2).AtMidnight(),
|
var inventory = new Inventory
|
||||||
Memo = "Cut",
|
|
||||||
Quantity = 15,
|
|
||||||
Transactions = new List<Transaction> { new Transaction
|
|
||||||
{
|
{
|
||||||
AddedQuantity = 15, Memo = "arrival", TransactionDate = DateTime.Now.AddMonths(-2).AtMidnight(), Timestamp = DateTime.Now
|
InventoryType = inventoryType,
|
||||||
}}
|
ExpirationDate = expiration,
|
||||||
});
|
AddedDate = addedDate,
|
||||||
|
Memo = memo,
|
||||||
|
Quantity = quantity,
|
||||||
|
Transactions = new List<Transaction> { previousTransaction}
|
||||||
|
};
|
||||||
|
context.Inventories.Add(inventory);
|
||||||
|
|
||||||
context.Inventories.Add(new Inventory
|
for (int j = 0; j < 5 && previousTransaction.CurrentQuantity > 0; j++)
|
||||||
{
|
{
|
||||||
InventoryType = pb,
|
var transactionDate = previousTransaction.TransactionDate.AddDays(r.Next(1, 100));
|
||||||
ExpirationDate = DateTime.Now.AddDays(300).AtMidnight(),
|
if (transactionDate >= DateTime.Today)
|
||||||
AddedDate = DateTime.Now.AddDays(-34).AtMidnight(),
|
break;
|
||||||
Quantity = 700,
|
|
||||||
Transactions = new List<Transaction> { new Transaction
|
var quantityRemoved = r.Next(1, 100);
|
||||||
|
if (quantityRemoved > previousTransaction.CurrentQuantity)
|
||||||
|
quantityRemoved = previousTransaction.CurrentQuantity;
|
||||||
|
|
||||||
|
var transaction = new Transaction
|
||||||
{
|
{
|
||||||
AddedQuantity = 700, Memo = "arrival", TransactionDate = DateTime.Now.AddDays(-34).AtMidnight(), Timestamp = DateTime.Now
|
RemovedQuantity = quantityRemoved,
|
||||||
}}
|
CurrentQuantity = previousTransaction.CurrentQuantity - quantityRemoved,
|
||||||
});
|
Inventory = inventory,
|
||||||
|
Memo = "Distributed",
|
||||||
|
TransactionDate = transactionDate,
|
||||||
|
Timestamp = transactionDate
|
||||||
|
};
|
||||||
|
|
||||||
|
inventory.Quantity = transaction.CurrentQuantity;
|
||||||
|
|
||||||
|
inventory.Transactions.Add(transaction);
|
||||||
|
|
||||||
|
previousTransaction = transaction;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddTerminatedCustomers(AppDbContext context)
|
private static void AddTerminatedCustomers(AppDbContext context)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
{
|
{
|
||||||
public BetterJsonResult<T> BetterJson<T>(T model)
|
public BetterJsonResult<T> BetterJson<T>(T model)
|
||||||
{
|
{
|
||||||
return new BetterJsonResult<T>() {Data = model};
|
return new BetterJsonResult<T> {Data = model};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JsonResult PackageModelStateErrors()
|
protected JsonResult PackageModelStateErrors()
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ 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;
|
||||||
@@ -26,14 +27,22 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
|
|
||||||
public JsonResult All()
|
public JsonResult All()
|
||||||
{
|
{
|
||||||
var viewModels = _context.Inventories
|
var viewModels =
|
||||||
.OrderBy(x => x.InventoryType.Name)
|
AllInventory()
|
||||||
.ProjectTo<InventoryViewModel>()
|
.ProjectTo<InventoryViewModel>()
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
return BetterJson(viewModels);
|
return BetterJson(viewModels);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IQueryable<Inventory> AllInventory()
|
||||||
|
{
|
||||||
|
return _context
|
||||||
|
.Inventories
|
||||||
|
.Where(x => x.Quantity > 0)
|
||||||
|
.OrderBy(x => x.InventoryType.Name);
|
||||||
|
}
|
||||||
|
|
||||||
public JsonResult Add(InventoryAddForm form)
|
public JsonResult Add(InventoryAddForm form)
|
||||||
{
|
{
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
@@ -42,18 +51,56 @@ 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);
|
||||||
_context.Inventories.Add(inventory);
|
_context.Inventories.Add(inventory);
|
||||||
inventory.Transactions = new List<Transaction>();
|
inventory.Transactions = new List<Transaction>
|
||||||
inventory.Transactions.Add(new Transaction
|
{
|
||||||
|
new Transaction
|
||||||
{
|
{
|
||||||
AddedQuantity = inventory.Quantity,
|
AddedQuantity = inventory.Quantity,
|
||||||
|
CurrentQuantity = inventory.Quantity,
|
||||||
Memo = "Arrival",
|
Memo = "Arrival",
|
||||||
Timestamp = DateTime.Now,
|
Timestamp = DateTime.Now,
|
||||||
TransactionDate = inventory.AddedDate
|
TransactionDate = inventory.AddedDate
|
||||||
});
|
}
|
||||||
|
};
|
||||||
_context.SaveChanges();
|
_context.SaveChanges();
|
||||||
|
|
||||||
var model = Mapper.Map<InventoryViewModel>(inventory);
|
var model = Mapper.Map<InventoryViewModel>(inventory);
|
||||||
return BetterJson(model);
|
return BetterJson(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JsonResult Distribute(InventoryDistributeForm form)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
return PackageModelStateErrors();
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
if (inventory.Quantity < quantityForm.Quantity)
|
||||||
|
return BetterJsonResult.Error(
|
||||||
|
$"Inventory {inventory.InventoryType.Name} has only {inventory.Quantity}, trying to remove {quantityForm.Quantity}");
|
||||||
|
inventory.Quantity -= quantityForm.Quantity;
|
||||||
|
|
||||||
|
inventory.Transactions.Add(new Transaction
|
||||||
|
{
|
||||||
|
RemovedQuantity = quantityForm.Quantity,
|
||||||
|
CurrentQuantity = inventory.Quantity,
|
||||||
|
Memo = "Distributed to " + form.Destination,
|
||||||
|
Timestamp = DateTime.Now,
|
||||||
|
TransactionDate = form.DistributedDate
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_context.SaveChanges();
|
||||||
|
|
||||||
|
return BetterJson(AllInventory()
|
||||||
|
.ProjectTo<InventoryViewModel>()
|
||||||
|
.ToArray());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
using System;
|
||||||
|
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;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Controllers
|
||||||
|
{
|
||||||
|
public class TransactionController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly AppDbContext _context;
|
||||||
|
|
||||||
|
public TransactionController(AppDbContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionResult Index()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonResult All()
|
||||||
|
{
|
||||||
|
var viewModels =
|
||||||
|
_context.Transactions
|
||||||
|
.ProjectTo<TransactionViewModel>()
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
return BetterJson(viewModels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,9 @@ namespace InventoryTraker.Web.Core
|
|||||||
[Required]
|
[Required]
|
||||||
public int RemovedQuantity { get; set; }
|
public int RemovedQuantity { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public int CurrentQuantity { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public DateTime TransactionDate { get; set; }
|
public DateTime TransactionDate { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ namespace InventoryTraker.Web.Helpers
|
|||||||
{
|
{
|
||||||
//input.Attr("type", "date");
|
//input.Attr("type", "date");
|
||||||
input.Attr("bs-datepicker");
|
input.Attr("bs-datepicker");
|
||||||
input.Attr("data-date-format", "d/M/yyyy");
|
input.Attr("data-date-format", "M/d/yyyy");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metadata.DataTypeName == "PhoneNumber")
|
if (metadata.DataTypeName == "PhoneNumber")
|
||||||
|
|||||||
@@ -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.11.0\lib\net40-client\CsvHelper.dll</HintPath>
|
<HintPath>..\packages\CsvHelper.2.16.0.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">
|
||||||
@@ -238,6 +238,7 @@
|
|||||||
<Content Include="js\customer\CustomerDetailsDirective.js" />
|
<Content Include="js\customer\CustomerDetailsDirective.js" />
|
||||||
<Content Include="js\customer\customerSvc.js" />
|
<Content Include="js\customer\customerSvc.js" />
|
||||||
<Content Include="js\customer\CustomerListController.js" />
|
<Content Include="js\customer\CustomerListController.js" />
|
||||||
|
<Content Include="js\inventory\InventoryDistributeDirective.js" />
|
||||||
<Content Include="js\opportunity\AddOpportunityDirective.js" />
|
<Content Include="js\opportunity\AddOpportunityDirective.js" />
|
||||||
<Content Include="js\opportunity\templates\addOpportunity.tmpl.cshtml" />
|
<Content Include="js\opportunity\templates\addOpportunity.tmpl.cshtml" />
|
||||||
<Content Include="js\profile\EditProfileController.js" />
|
<Content Include="js\profile\EditProfileController.js" />
|
||||||
@@ -247,6 +248,7 @@
|
|||||||
<Content Include="js\report\templates\newCustomersReport.tmpl.html" />
|
<Content Include="js\report\templates\newCustomersReport.tmpl.html" />
|
||||||
<Content Include="js\risk\AddRiskDirective.js" />
|
<Content Include="js\risk\AddRiskDirective.js" />
|
||||||
<Content Include="js\risk\templates\addRisk.tmpl.cshtml" />
|
<Content Include="js\risk\templates\addRisk.tmpl.cshtml" />
|
||||||
|
<Content Include="js\transaction\transactionSvc.js" />
|
||||||
<Content Include="js\utility\ArrayExtensions.js" />
|
<Content Include="js\utility\ArrayExtensions.js" />
|
||||||
<Content Include="js\utility\FormGroupValidationDirective.js" />
|
<Content Include="js\utility\FormGroupValidationDirective.js" />
|
||||||
<Content Include="js\utility\InputValidationIconsDirective.js" />
|
<Content Include="js\utility\InputValidationIconsDirective.js" />
|
||||||
@@ -282,6 +284,7 @@
|
|||||||
<Content Include="App_Data\InventoryTypeSeedData.xlsx">
|
<Content Include="App_Data\InventoryTypeSeedData.xlsx">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
|
<Content Include="js\inventory\templates\inventoryDistribute.tmpl.cshtml" />
|
||||||
<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" />
|
||||||
@@ -304,6 +307,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="Controllers\TransactionController.cs" />
|
||||||
<Compile Include="Controllers\InventoryController.cs" />
|
<Compile Include="Controllers\InventoryController.cs" />
|
||||||
<Compile Include="Controllers\AuthenticationController.cs" />
|
<Compile Include="Controllers\AuthenticationController.cs" />
|
||||||
<Compile Include="Controllers\CustomerController.cs" />
|
<Compile Include="Controllers\CustomerController.cs" />
|
||||||
@@ -335,6 +339,7 @@
|
|||||||
<Compile Include="Identity\ApplicationUserManager.cs" />
|
<Compile Include="Identity\ApplicationUserManager.cs" />
|
||||||
<Compile Include="Identity\AspNetIdentityRegistry.cs" />
|
<Compile Include="Identity\AspNetIdentityRegistry.cs" />
|
||||||
<Compile Include="Migrations\Configuration.cs" />
|
<Compile Include="Migrations\Configuration.cs" />
|
||||||
|
<Compile Include="Models\InventoryDistributeForm.cs" />
|
||||||
<Compile Include="Models\InventoryAddForm.cs" />
|
<Compile Include="Models\InventoryAddForm.cs" />
|
||||||
<Compile Include="Models\AddCustomerForm.cs" />
|
<Compile Include="Models\AddCustomerForm.cs" />
|
||||||
<Compile Include="Models\AddRiskForm.cs" />
|
<Compile Include="Models\AddRiskForm.cs" />
|
||||||
@@ -351,6 +356,7 @@
|
|||||||
<Compile Include="Models\OpportunityViewModel.cs" />
|
<Compile Include="Models\OpportunityViewModel.cs" />
|
||||||
<Compile Include="Models\ProfileForm.cs" />
|
<Compile Include="Models\ProfileForm.cs" />
|
||||||
<Compile Include="Models\RiskViewModel.cs" />
|
<Compile Include="Models\RiskViewModel.cs" />
|
||||||
|
<Compile Include="Models\TransactionViewModel.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Utilities\ExcelParserBase.cs" />
|
<Compile Include="Utilities\ExcelParserBase.cs" />
|
||||||
<Compile Include="Utilities\InventoryTypeParser.cs" />
|
<Compile Include="Utilities\InventoryTypeParser.cs" />
|
||||||
@@ -380,6 +386,7 @@
|
|||||||
<Content Include="Views\Shared\_NavigationHero.cshtml" />
|
<Content Include="Views\Shared\_NavigationHero.cshtml" />
|
||||||
<Content Include="Views\Shared\_Navigation.cshtml" />
|
<Content Include="Views\Shared\_Navigation.cshtml" />
|
||||||
<Content Include="Views\_ViewStart.cshtml" />
|
<Content Include="Views\_ViewStart.cshtml" />
|
||||||
|
<Content Include="Views\Transaction\Index.cshtml" />
|
||||||
<None Include="Web.Debug.config">
|
<None Include="Web.Debug.config">
|
||||||
<DependentUpon>Web.config</DependentUpon>
|
<DependentUpon>Web.config</DependentUpon>
|
||||||
</None>
|
</None>
|
||||||
@@ -387,9 +394,7 @@
|
|||||||
<DependentUpon>Web.config</DependentUpon>
|
<DependentUpon>Web.config</DependentUpon>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup />
|
||||||
<Folder Include="js\app\" />
|
|
||||||
</ItemGroup>
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ namespace InventoryTraker.Web.Migrations
|
|||||||
public Configuration()
|
public Configuration()
|
||||||
{
|
{
|
||||||
AutomaticMigrationsEnabled = true;
|
AutomaticMigrationsEnabled = true;
|
||||||
|
// TODO false
|
||||||
|
AutomaticMigrationDataLossAllowed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Seed(AppDbContext context)
|
protected override void Seed(AppDbContext context)
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Models
|
||||||
|
{
|
||||||
|
public class InventoryQuantityForm
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public int InventoryId { get; set; }
|
||||||
|
|
||||||
|
[Required, Range(1, int.MaxValue, ErrorMessage = "Quantity must be greater than 0")]
|
||||||
|
public int Quantity { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InventoryDistributeForm
|
||||||
|
{
|
||||||
|
public IList<InventoryQuantityForm> InventoryQuantities { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public string Destination { get; set; }
|
||||||
|
|
||||||
|
[Required, Display(Name = "Distributed Date")]
|
||||||
|
public DateTime DistributedDate { get; set; }
|
||||||
|
|
||||||
|
public string Memo { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using Heroic.AutoMapper;
|
using Heroic.AutoMapper;
|
||||||
using InventoryTraker.Web.Core;
|
using InventoryTraker.Web.Core;
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using AutoMapper;
|
||||||
|
using Heroic.AutoMapper;
|
||||||
|
using InventoryTraker.Web.Core;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Models
|
||||||
|
{
|
||||||
|
public class TransactionViewModel : IMapFrom<Transaction>, IHaveCustomMappings
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
public int UnitsPerCase { get; set; }
|
||||||
|
public string ContainerType { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public int AddedQuantity { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public int RemovedQuantity { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public int CurrentQuantity { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public DateTime TransactionDate { get; set; }
|
||||||
|
|
||||||
|
public string Memo { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public DateTime Timestamp { get; set; }
|
||||||
|
|
||||||
|
public void CreateMappings(IMapperConfiguration configuration)
|
||||||
|
{
|
||||||
|
configuration.CreateMap<Transaction, TransactionViewModel>()
|
||||||
|
.ForMember(d => d.Name,
|
||||||
|
opt => opt.MapFrom(s => s.Inventory.InventoryType.Name))
|
||||||
|
.ForMember(d => d.UnitsPerCase,
|
||||||
|
opt => opt.MapFrom(s => s.Inventory.InventoryType.UnitsPerCase))
|
||||||
|
.ForMember(d => d.ContainerType,
|
||||||
|
opt => opt.MapFrom(s => s.Inventory.InventoryType.ContainerType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using ClosedXML.Excel;
|
|
||||||
using CsvHelper.Configuration;
|
using CsvHelper.Configuration;
|
||||||
using InventoryTraker.Web.Core;
|
using InventoryTraker.Web.Core;
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,12 @@
|
|||||||
|
|
||||||
<div ng-controller="InventoryListController as vm">
|
<div ng-controller="InventoryListController as vm">
|
||||||
<h1 class="page-header">
|
<h1 class="page-header">
|
||||||
Inventory
|
<i class="fa fa-cubes"></i> Inventory
|
||||||
<a class="pull-right" href="" ng-click="vm.add()"><i class="fa fa-plus-circle"></i></a>
|
|
||||||
</h1>
|
</h1>
|
||||||
|
<div class="pull-right">
|
||||||
|
<a class="btn btn-default" href="" ng-click="vm.add()"><i class="fa fa-plus-circle"></i> Arrival</a>
|
||||||
|
<a class="btn btn-default" href="" ng-click="vm.distribute()"><i class="fa fa-share-square"></i> Distribute</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<inventory-details inventories="vm.inventories"></inventory-details>
|
<inventory-details inventories="vm.inventories"></inventory-details>
|
||||||
</div>
|
</div>
|
||||||
@@ -27,7 +27,10 @@
|
|||||||
<div class="collapse navbar-collapse navbar-ex1-collapse">
|
<div class="collapse navbar-collapse navbar-ex1-collapse">
|
||||||
<ul class="nav navbar-nav side-nav">
|
<ul class="nav navbar-nav side-nav">
|
||||||
<li>
|
<li>
|
||||||
<a href="@(Html.BuildUrlFromExpression<InventoryController>(c => c.Index()))"><i class="fa fa-fw fa-list"></i> Inventory</a>
|
<a href="@(Html.BuildUrlFromExpression<InventoryController>(c => c.Index()))"><i class="fa fa-fw fa-cubes"></i> Inventory</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="@(Html.BuildUrlFromExpression<TransactionController>(c => c.Index()))"><i class="fa fa-fw fa-list"></i> Transactions</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
@using InventoryTraker.Web.Helpers
|
||||||
|
@using InventoryTraker.Web.Models
|
||||||
|
@model dynamic
|
||||||
|
|
||||||
|
@{
|
||||||
|
ViewBag.Title = "Inventory";
|
||||||
|
}
|
||||||
|
|
||||||
|
<div ng-controller="InventoryListController as vm">
|
||||||
|
<h1 class="page-header">
|
||||||
|
Transactions
|
||||||
|
</h1>
|
||||||
|
<div class="pull-right">
|
||||||
|
@*<a class="btn btn-default" href="" ng-click="vm.add()"><i class="fa fa-plus-circle"></i> Arrival</a>
|
||||||
|
<a class="btn btn-default" href="" ng-click="vm.distribute()"><i class="fa fa-share-square"></i> Distribute</a>*@
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@(Html.Angular().GridFor<TransactionController>(c => c.All())
|
||||||
|
.Title("Transactions")
|
||||||
|
.Columns<TransactionViewModel>(config =>
|
||||||
|
{
|
||||||
|
config.Add(x => x.Name);
|
||||||
|
config.Add(x => x.Memo);
|
||||||
|
config.Add(x => x.TransactionDate, "Transaction Date", "date: 'MM/dd/yyyy'");
|
||||||
|
config.Add(x => x.AddedQuantity, "Add Qty");
|
||||||
|
config.Add(x => x.RemovedQuantity, "Remove Qty");
|
||||||
|
config.Add(x => x.CurrentQuantity);
|
||||||
|
}))
|
||||||
|
</div>
|
||||||
@@ -102,4 +102,5 @@
|
|||||||
<remove name="TRACEVerbHandler" />
|
<remove name="TRACEVerbHandler" />
|
||||||
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||||
</handlers>
|
</handlers>
|
||||||
</system.webServer></configuration>
|
</system.webServer>
|
||||||
|
</configuration>
|
||||||
@@ -97,6 +97,6 @@ textarea {
|
|||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.has-feedback ng-transclude ~ input-validation-icons .form-control-feedback {
|
/*.has-feedback ng-transclude ~ input-validation-icons .form-control-feedback {
|
||||||
top: 26px;
|
top: 26px;
|
||||||
}
|
}*/
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
controller.$inject = ['$scope', 'inventorySvc', 'inventoryTypeSvc'];
|
controller.$inject = ['$scope', 'inventorySvc', 'inventoryTypeSvc'];
|
||||||
|
|
||||||
function controller($scope, inventorySvc, inventoryTypeSvc) {
|
function controller($scope, inventorySvc, inventoryTypeSvc) {
|
||||||
var vm = this;
|
var vm = this;
|
||||||
|
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
vm.saving = false;
|
vm.saving = false;
|
||||||
vm.inventory = {};
|
vm.inventory = {};
|
||||||
vm.inventoryTypes = inventoryTypeSvc.inventoryTypes;
|
vm.inventoryTypes = inventoryTypeSvc.inventoryTypes;
|
||||||
|
|
||||||
vm.errorMessage = null;
|
vm.errorMessage = null;
|
||||||
vm.quantity = quantity;
|
vm.quantity = quantity;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
window.app.directive('inventoryDistribute', inventoryDistribute);
|
||||||
|
|
||||||
|
function inventoryDistribute() {
|
||||||
|
return {
|
||||||
|
templateUrl: '/inventory/template/inventoryDistribute.tmpl.cshtml',
|
||||||
|
controller: controller,
|
||||||
|
controllerAs: 'vm'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
controller.$inject = ['$scope', 'inventorySvc'];
|
||||||
|
function controller($scope, inventorySvc) {
|
||||||
|
var vm = this;
|
||||||
|
|
||||||
|
vm.save = save;
|
||||||
|
vm.saving = false;
|
||||||
|
vm.quantities = angular.copy(inventorySvc.inventories);
|
||||||
|
vm.distribution = {};
|
||||||
|
vm.errorMessage = null;
|
||||||
|
|
||||||
|
function getInventoryDistributeQuantities(inventory) {
|
||||||
|
var invQty = [];
|
||||||
|
inventory.forEach(function (i) {
|
||||||
|
if (i.distributeQuantity > 0)
|
||||||
|
invQty.push({ inventoryId: i.id, quantity: i.distributeQuantity });
|
||||||
|
});
|
||||||
|
return invQty;
|
||||||
|
}
|
||||||
|
|
||||||
|
function save() {
|
||||||
|
vm.saving = true;
|
||||||
|
vm.distribution.inventoryQuantities = getInventoryDistributeQuantities(vm.quantities);
|
||||||
|
inventorySvc.distribute(vm.distribution)
|
||||||
|
.success(function () {
|
||||||
|
//Close the modal
|
||||||
|
$scope.$close();
|
||||||
|
})
|
||||||
|
.error(function(data) {
|
||||||
|
vm.errorMessage =
|
||||||
|
'There was a problem distributing the inventory: ' + data.errorMessage;
|
||||||
|
})
|
||||||
|
.finally(function() {
|
||||||
|
vm.saving = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
@@ -6,7 +6,9 @@
|
|||||||
InventoryListController.$inject = ['$uibModal', 'inventorySvc'];
|
InventoryListController.$inject = ['$uibModal', 'inventorySvc'];
|
||||||
function InventoryListController($uibModal, inventorySvc) {
|
function InventoryListController($uibModal, inventorySvc) {
|
||||||
var vm = this;
|
var vm = this;
|
||||||
|
|
||||||
vm.add = add;
|
vm.add = add;
|
||||||
|
vm.distribute = distribute;
|
||||||
vm.inventories = inventorySvc.inventories;
|
vm.inventories = inventorySvc.inventories;
|
||||||
|
|
||||||
function add() {
|
function add() {
|
||||||
@@ -15,5 +17,12 @@
|
|||||||
backdrop: 'static'
|
backdrop: 'static'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function distribute() {
|
||||||
|
$uibModal.open({
|
||||||
|
template: '<inventory-distribute />',
|
||||||
|
backdrop: 'static'
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
@@ -9,9 +9,10 @@
|
|||||||
|
|
||||||
var svc = {
|
var svc = {
|
||||||
add: add,
|
add: add,
|
||||||
|
distribute: distribute,
|
||||||
update: update,
|
update: update,
|
||||||
inventories: inventories,
|
inventories: inventories,
|
||||||
getInventory: getInventory,
|
getInventory: getInventory
|
||||||
};
|
};
|
||||||
|
|
||||||
return svc;
|
return svc;
|
||||||
@@ -19,7 +20,7 @@
|
|||||||
function loadInventories() {
|
function loadInventories() {
|
||||||
$http.post('/Inventory/All')
|
$http.post('/Inventory/All')
|
||||||
.success(function(data) {
|
.success(function(data) {
|
||||||
inventories.addRange(data);
|
angular.copy(data, inventories);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,6 +31,13 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function distribute(distribution) {
|
||||||
|
return $http.post('/Inventory/Distribute', distribution)
|
||||||
|
.success(function (data) {
|
||||||
|
angular.copy(data, inventories);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function update(existingInventory, updatedInventory) {
|
function update(existingInventory, updatedInventory) {
|
||||||
return $http.post('/Inventory/Update', updatedInventory)
|
return $http.post('/Inventory/Update', updatedInventory)
|
||||||
.success(function(inventory) {
|
.success(function(inventory) {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="form-group has-feedback" ng-class="vm.getValidationClass()" form-group-validation="Commodity">
|
<div class="form-group" form-group-validation="Commodity">
|
||||||
<label for="Commodity" class="control-label">Commodity</label>
|
<label for="Commodity" class="control-label">Commodity</label>
|
||||||
<input name="Commodity" type="text"
|
<input name="Commodity" type="text"
|
||||||
ng-model="vm.commodity"
|
ng-model="vm.commodity"
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
@inventory.FormGroupFor(m => m.ExpirationDate)
|
@inventory.FormGroupFor(m => m.ExpirationDate)
|
||||||
|
|
||||||
<div class="form-group has-feedback panel panel-default">
|
<div class="form-group panel panel-default">
|
||||||
<div class="panel-heading"><label>Quantity</label></div>
|
<div class="panel-heading"><label>Quantity</label></div>
|
||||||
<div class="panel-body container-fluid">
|
<div class="panel-body container-fluid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
@using InventoryTraker.Web.Helpers
|
||||||
|
@model InventoryTraker.Web.Models.InventoryDistributeForm
|
||||||
|
@{
|
||||||
|
var distribution = Html.Angular().ModelFor("vm.distribution");
|
||||||
|
}
|
||||||
|
<form novalidate
|
||||||
|
name="vm.form"
|
||||||
|
ng-submit="vm.form.$valid && vm.save()">
|
||||||
|
<fieldset ng-disabled="vm.saving">
|
||||||
|
|
||||||
|
<div class="modal-header">
|
||||||
|
<h3 class="modal-title">Inventory Distribution</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
|
@distribution.FormGroupFor(m => m.Destination)
|
||||||
|
|
||||||
|
<table class="table" ng-class="vm.getValidationClass()">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name<br />Units per Case</th>
|
||||||
|
<th>Available Case Qty</th>
|
||||||
|
<th>Distribute Case Qty</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr ng-repeat="inventory in vm.quantities" inventory="inventory">
|
||||||
|
<td>
|
||||||
|
<label class="control-label" for="DistributeQuantity{{inventory.name}}">
|
||||||
|
{{inventory.name}}<br />
|
||||||
|
{{inventory.unitsPerCase}} / {{inventory.containerType}}
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
<td>{{inventory.quantity}}</td>
|
||||||
|
<td>
|
||||||
|
<div class="form-group" form-group-validation="DistributeQuantity{{inventory.name}}">
|
||||||
|
<input name="DistributeQuantity{{inventory.name}}" type="number"
|
||||||
|
class="form-control"
|
||||||
|
ng-model="inventory.distributeQuantity"
|
||||||
|
ng-max="{{inventory.quantity}}"
|
||||||
|
ng-min="0" />
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
@distribution.FormGroupFor(m => m.DistributedDate)
|
||||||
|
|
||||||
|
@distribution.FormGroupFor(m => m.Memo)
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button class="btn btn-success">Save</button>
|
||||||
|
<button type="button" class="btn" ng-click="$dismiss()">Cancel</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
(function() {
|
||||||
|
window.app.factory('transactionSvc', transactionSvc);
|
||||||
|
|
||||||
|
transactionSvc.$inject = ['$http'];
|
||||||
|
function transactionSvc($http) {
|
||||||
|
var transactions = [];
|
||||||
|
|
||||||
|
loadTransactions();
|
||||||
|
|
||||||
|
var svc = {
|
||||||
|
add: add,
|
||||||
|
update: update,
|
||||||
|
transactions: transactions,
|
||||||
|
getTransaction: getTransaction
|
||||||
|
};
|
||||||
|
|
||||||
|
return svc;
|
||||||
|
|
||||||
|
function loadTransactions() {
|
||||||
|
$http.post('/Transaction/All')
|
||||||
|
.success(function(data) {
|
||||||
|
angular.copy(data, transactions);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(existingTransaction, updatedTransaction) {
|
||||||
|
return $http.post('/Transaction/Update', updatedTransaction)
|
||||||
|
.success(function(transaction) {
|
||||||
|
angular.extend(existingTransaction, transaction);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTransaction(id) {
|
||||||
|
for (var i = 0; i < transactions.length; i++) {
|
||||||
|
if (transactions[i].Id == id) return transactions[i];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
template:
|
template:
|
||||||
'<div class="has-feedback" ng-class="vm.getValidationClass()">' +
|
'<div class="has-feedback" ng-class="vm.getValidationClass()">' +
|
||||||
'<ng-transclude></ng-transclude>' +
|
'<ng-transclude></ng-transclude>' +
|
||||||
'<input-validation-icons field="vm.field"></input-validation-icons>' +
|
//'<input-validation-icons field="vm.field"></input-validation-icons>' +
|
||||||
'</div>',
|
'</div>',
|
||||||
scope: {
|
scope: {
|
||||||
field: '@formGroupValidation'
|
field: '@formGroupValidation'
|
||||||
|
|||||||
@@ -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.11.0" targetFramework="net451" />
|
<package id="CsvHelper" version="2.16.0.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" />
|
||||||
|
|||||||
Reference in New Issue
Block a user