Compare commits
10
Commits
4f561dac11
...
5fd0577529
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5fd0577529 | ||
|
|
fdc34c4ef7 | ||
|
|
3caf0bd766 | ||
|
|
75b7c02979 | ||
|
|
6789c1b3b5 | ||
|
|
f473c64540 | ||
|
|
0b5dde065a | ||
|
|
9f50a4635c | ||
|
|
02555eba7e | ||
|
|
206a3f2def |
@@ -30,3 +30,4 @@ _ReSharper*/
|
|||||||
packages/**/
|
packages/**/
|
||||||
**/App_Data/*
|
**/App_Data/*
|
||||||
*/Logs/*
|
*/Logs/*
|
||||||
|
logs/*
|
||||||
|
|||||||
@@ -163,12 +163,20 @@
|
|||||||
</site>
|
</site>
|
||||||
<site name="InventoryTraker.Web" id="2">
|
<site name="InventoryTraker.Web" id="2">
|
||||||
<application path="/" applicationPool="Clr4IntegratedAppPool">
|
<application path="/" applicationPool="Clr4IntegratedAppPool">
|
||||||
<virtualDirectory path="/" physicalPath="C:\Users\poprhythm\Documents\code\InventoryTraker\InventoryTraker.Web" />
|
<virtualDirectory path="/" physicalPath="C:\Users\poprhythm\Documents\code\InventoryTraker-Box\InventoryTraker.Web" />
|
||||||
</application>
|
</application>
|
||||||
<bindings>
|
<bindings>
|
||||||
<binding protocol="http" bindingInformation="*:58446:localhost" />
|
<binding protocol="http" bindingInformation="*:58446:localhost" />
|
||||||
</bindings>
|
</bindings>
|
||||||
</site>
|
</site>
|
||||||
|
<site name="InventoryTraker.Web(1)" id="3">
|
||||||
|
<application path="/" applicationPool="Clr4IntegratedAppPool">
|
||||||
|
<virtualDirectory path="/" physicalPath="C:\Users\poprhythm\Documents\code\InventoryTraker-Box\InventoryTraker.Web" />
|
||||||
|
</application>
|
||||||
|
<bindings>
|
||||||
|
<binding protocol="http" bindingInformation="*:58448:localhost" />
|
||||||
|
</bindings>
|
||||||
|
</site>
|
||||||
<siteDefaults>
|
<siteDefaults>
|
||||||
<logFile logFormat="W3C" directory="%IIS_USER_HOME%\Logs" />
|
<logFile logFormat="W3C" directory="%IIS_USER_HOME%\Logs" />
|
||||||
<traceFailedRequestsLogging directory="%IIS_USER_HOME%\TraceLogFiles" enabled="true" maxLogFileSizeKB="1024" />
|
<traceFailedRequestsLogging directory="%IIS_USER_HOME%\TraceLogFiles" enabled="true" maxLogFileSizeKB="1024" />
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
using Heroic.AutoMapper;
|
|
||||||
|
|
||||||
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(InventoryTraker.Web.Tests.AutoMapperConfig), "Configure")]
|
|
||||||
namespace InventoryTraker.Web.Tests
|
|
||||||
{
|
|
||||||
public static class AutoMapperConfig
|
|
||||||
{
|
|
||||||
public static void Configure()
|
|
||||||
{
|
|
||||||
//NOTE: By default, the current project and all referenced projects will be scanned.
|
|
||||||
// You can customize this by passing in a lambda to filter the assemblies by name,
|
|
||||||
// like so:
|
|
||||||
//HeroicAutoMapperConfigurator.LoadMapsFromCallerAndReferencedAssemblies(x => x.Name.StartsWith("YourPrefix"));
|
|
||||||
HeroicAutoMapperConfigurator.LoadMapsFromCallerAndReferencedAssemblies();
|
|
||||||
//If you run into issues with the maps not being located at runtime, try using this method instead:
|
|
||||||
//HeroicAutoMapperConfigurator.LoadMapsFromAssemblyContainingTypeAndReferencedAssemblies<SomeControllerOrTypeInYourWebProject>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Tests
|
||||||
|
{
|
||||||
|
[SetUpFixture]
|
||||||
|
public class Setup
|
||||||
|
{
|
||||||
|
[OneTimeSetUp]
|
||||||
|
public void S()
|
||||||
|
{
|
||||||
|
AutoMapperConfig.Configure();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,20 +30,16 @@
|
|||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="AutoMapper, Version=4.2.0.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
|
<Reference Include="AutoMapper, Version=5.1.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\AutoMapper.4.2.0\lib\net45\AutoMapper.dll</HintPath>
|
<HintPath>..\packages\AutoMapper.5.1.1\lib\net45\AutoMapper.dll</HintPath>
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Heroic.AutoMapper, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Heroic.AutoMapper.2.0.0\lib\net45\Heroic.AutoMapper.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
|
<HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="nunit.framework, Version=3.4.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
<Reference Include="nunit.framework, Version=3.4.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NUnit.3.4.1\lib\net45\nunit.framework.dll</HintPath>
|
<HintPath>..\packages\NUnit.3.4.0\lib\net45\nunit.framework.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
@@ -60,10 +56,12 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="App_Start\AutoMapperConfig.cs" />
|
|
||||||
<Compile Include="Models\InventoryAddForm.cs" />
|
<Compile Include="Models\InventoryAddForm.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Utilities\InventoryTypeParserTests.cs" />
|
<Compile Include="App_Start\Setup.cs" />
|
||||||
|
<Compile Include="Services\InventoryImporterTests.cs" />
|
||||||
|
<Compile Include="Utilities\InventoryParserTests.cs" />
|
||||||
|
<Compile Include="Utilities\InventoryReportWriterTests.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\InventoryTraker.Web\InventoryTraker.Web.csproj">
|
<ProjectReference Include="..\InventoryTraker.Web\InventoryTraker.Web.csproj">
|
||||||
@@ -74,10 +72,20 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="app.config" />
|
<None Include="app.config" />
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
<Content Include="Utilities\Documents\InventoryTypeData.xlsx">
|
<Content Include="Utilities\Documents\InventoryData.xlsx">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Utilities\Documents\InventoryData-BadHeader.xlsx">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Utilities\Documents\InventoryData-BadDate.xlsx">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Utilities\Documents\InventoryTraker_ImportTemplate.xlsx">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using Heroic.AutoMapper;
|
|
||||||
using InventoryTraker.Web.Core;
|
using InventoryTraker.Web.Core;
|
||||||
using InventoryTraker.Web.Models;
|
using InventoryTraker.Web.Models;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@@ -10,10 +9,12 @@ namespace InventoryTraker.Web.Tests.Models
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class InventoryAddFormTests
|
public class InventoryAddFormTests
|
||||||
{
|
{
|
||||||
|
private IMapper _mapper;
|
||||||
|
|
||||||
[OneTimeSetUp]
|
[OneTimeSetUp]
|
||||||
public void StartUp()
|
public void StartUp()
|
||||||
{
|
{
|
||||||
HeroicAutoMapperConfigurator.LoadMapsFromAssemblyContainingTypeAndReferencedAssemblies<Inventory>();
|
_mapper = AutoMapperConfig.Config.CreateMapper();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -22,18 +23,15 @@ namespace InventoryTraker.Web.Tests.Models
|
|||||||
var form = new InventoryAddForm
|
var form = new InventoryAddForm
|
||||||
{
|
{
|
||||||
AddedDate = DateTime.Today,
|
AddedDate = DateTime.Today,
|
||||||
ExpirationDate = DateTime.Today.AddDays(3),
|
ShredReadyDate = DateTime.Today.AddDays(3),
|
||||||
InventoryTypeId = 1,
|
Memo = "My Memo"
|
||||||
Memo = "My Memo",
|
|
||||||
Quantity = 32
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var inventory = Mapper.Map<Inventory>(form);
|
var inventory = _mapper.Map<Inventory>(form);
|
||||||
|
|
||||||
Assert.That(inventory.AddedDate, Is.EqualTo(form.AddedDate));
|
Assert.That(inventory.AddedDate, Is.EqualTo(form.AddedDate));
|
||||||
Assert.That(inventory.ExpirationDate, Is.EqualTo(form.ExpirationDate));
|
Assert.That(inventory.ShredReadyDate, Is.EqualTo(form.ShredReadyDate));
|
||||||
Assert.That(inventory.Memo, Is.EqualTo(form.Memo));
|
Assert.That(inventory.Memo, Is.EqualTo(form.Memo));
|
||||||
Assert.That(inventory.Quantity, Is.EqualTo(form.Quantity));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using AutoMapper;
|
||||||
|
using InventoryTraker.Web.Services;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Tests.Services
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class InventoryImporterTests
|
||||||
|
{
|
||||||
|
private readonly string _documentFolder =
|
||||||
|
AppDomain.CurrentDomain.BaseDirectory + @"\Utilities\Documents\";
|
||||||
|
|
||||||
|
private IMapper _mapper;
|
||||||
|
|
||||||
|
[OneTimeSetUp]
|
||||||
|
public void StartUp()
|
||||||
|
{
|
||||||
|
_mapper = AutoMapperConfig.Config.CreateMapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Import()
|
||||||
|
{
|
||||||
|
var fileInfo = new FileInfo(Path.Combine(_documentFolder, "InventoryData.xlsx"));
|
||||||
|
|
||||||
|
var importer = new InventoryImporter(_mapper);
|
||||||
|
|
||||||
|
var inventories = importer.Import(fileInfo);
|
||||||
|
|
||||||
|
foreach (var inventory in inventories)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{inventory.Id} {inventory.ProgramName} {inventory.ShredReadyDate}");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Import_BadDate()
|
||||||
|
{
|
||||||
|
var fileInfo = new FileInfo(Path.Combine(_documentFolder, "InventoryData-BadDate.xlsx"));
|
||||||
|
|
||||||
|
var importer = new InventoryImporter(_mapper);
|
||||||
|
|
||||||
|
var importException = Assert.Throws<ImportException>(() => importer.Import(fileInfo));
|
||||||
|
|
||||||
|
Assert.That(importException.Message, Does.Contain("Date"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Import_BadHeader()
|
||||||
|
{
|
||||||
|
var fileInfo = new FileInfo(Path.Combine(_documentFolder, "InventoryData-BadHeader.xlsx"));
|
||||||
|
|
||||||
|
var importer = new InventoryImporter(_mapper);
|
||||||
|
|
||||||
|
var importException = Assert.Throws<ImportException>(() => importer.Import(fileInfo));
|
||||||
|
|
||||||
|
Assert.That(importException.Message, Does.Contain("Program Name"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using InventoryTraker.Web.Utilities;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Tests.Utilities
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class InventoryParserTests
|
||||||
|
{
|
||||||
|
private readonly string _documentFolder =
|
||||||
|
AppDomain.CurrentDomain.BaseDirectory + @"\Utilities\Documents\";
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Parse()
|
||||||
|
{
|
||||||
|
var fileInfo = new FileInfo(Path.Combine(_documentFolder, "InventoryData.xlsx"));
|
||||||
|
|
||||||
|
var parser = new InventoryParser(fileInfo);
|
||||||
|
|
||||||
|
var forms = parser.Parse();
|
||||||
|
|
||||||
|
Assert.That(forms.Count, Is.GreaterThan(0));
|
||||||
|
|
||||||
|
foreach (var form in forms)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"{form.Id} {form.ProgramName} {form.ShredReadyDate}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Parse_NullableValues()
|
||||||
|
{
|
||||||
|
var fileInfo = new FileInfo(Path.Combine(_documentFolder, "InventoryData.xlsx"));
|
||||||
|
|
||||||
|
var parser = new InventoryParser(fileInfo);
|
||||||
|
|
||||||
|
var forms = parser.Parse();
|
||||||
|
|
||||||
|
Assert.That(forms[0].ProgramSubtype, Is.Null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Parse_ImportTemplate()
|
||||||
|
{
|
||||||
|
var fileInfo = new FileInfo(Path.Combine(_documentFolder, "InventoryTraker_ImportTemplate.xlsx"));
|
||||||
|
|
||||||
|
var parser = new InventoryParser(fileInfo);
|
||||||
|
|
||||||
|
var forms = parser.Parse();
|
||||||
|
|
||||||
|
Assert.That(forms.Count, Is.EqualTo(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using InventoryTraker.Web.Models;
|
||||||
|
using InventoryTraker.Web.Utilities;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Tests.Utilities
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class InventoryReportWriterTests
|
||||||
|
{
|
||||||
|
private readonly InventoryViewModel[] _inventory =
|
||||||
|
{
|
||||||
|
new InventoryViewModel
|
||||||
|
{
|
||||||
|
Id = "34634584",
|
||||||
|
AddedDate = new DateTime(2015,3,1),
|
||||||
|
ShredReadyDate = new DateTime(2017,4,1),
|
||||||
|
Quantity = 1,
|
||||||
|
Memo = "my memo",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
[Test, Explicit]
|
||||||
|
public void Write()
|
||||||
|
{
|
||||||
|
using
|
||||||
|
(var outputFile
|
||||||
|
= new StreamWriter(Path.Combine(@"c:\temp", "InventoryReport.xlsx")))
|
||||||
|
{
|
||||||
|
var writer = new InventoryReportWriter();
|
||||||
|
writer.WriteStream(_inventory, outputFile.BaseStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using InventoryTraker.Web.Utilities;
|
|
||||||
using NUnit.Framework;
|
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Tests.Utilities
|
|
||||||
{
|
|
||||||
[TestFixture]
|
|
||||||
public class InventoryTypeParserTests
|
|
||||||
{
|
|
||||||
private readonly string _documentFolder =
|
|
||||||
AppDomain.CurrentDomain.BaseDirectory + @"\Utilities\Documents\";
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Parse()
|
|
||||||
{
|
|
||||||
var fileInfo = new FileInfo(Path.Combine(_documentFolder, "InventoryTypeData.xlsx"));
|
|
||||||
|
|
||||||
var parser = new InventoryTypeParser(fileInfo);
|
|
||||||
|
|
||||||
var inventoryTypes = parser.Parse();
|
|
||||||
|
|
||||||
foreach (var inventoryType in inventoryTypes)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"{inventoryType.Identifier} {inventoryType.Name} {inventoryType.PricePerCase}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -38,6 +38,10 @@
|
|||||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
|
||||||
|
<bindingRedirect oldVersion="0.0.0.0-5.1.1.0" newVersion="5.1.1.0" />
|
||||||
|
</dependentAssembly>
|
||||||
</assemblyBinding>
|
</assemblyBinding>
|
||||||
</runtime>
|
</runtime>
|
||||||
</configuration>
|
</configuration>
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="AutoMapper" version="4.2.0" targetFramework="net452" />
|
<package id="AutoMapper" version="5.1.1" targetFramework="net452" />
|
||||||
<package id="Heroic.AutoMapper" version="2.0.0" targetFramework="net452" />
|
|
||||||
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net452" />
|
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net452" />
|
||||||
<package id="NUnit" version="3.4.1" targetFramework="net452" />
|
<package id="NUnit" version="3.4.0" targetFramework="net452" />
|
||||||
<package id="WebActivatorEx" version="2.1.0" targetFramework="net452" />
|
<package id="WebActivatorEx" version="2.1.0" targetFramework="net452" />
|
||||||
</packages>
|
</packages>
|
||||||
@@ -1,21 +1,18 @@
|
|||||||
using Heroic.AutoMapper;
|
using AutoMapper;
|
||||||
using InventoryTraker.Web;
|
using InventoryTraker.Web;
|
||||||
using InventoryTraker.Web.Controllers;
|
|
||||||
|
|
||||||
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(AutoMapperConfig), "Configure")]
|
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(AutoMapperConfig), "Configure")]
|
||||||
namespace InventoryTraker.Web
|
namespace InventoryTraker.Web
|
||||||
{
|
{
|
||||||
public static class AutoMapperConfig
|
public static class AutoMapperConfig
|
||||||
{
|
{
|
||||||
|
public static MapperConfiguration Config { get; private set; }
|
||||||
|
|
||||||
public static void Configure()
|
public static void Configure()
|
||||||
{
|
{
|
||||||
//NOTE: By default, the current project and all referenced projects will be scanned.
|
Config = new MapperConfiguration(cfg =>
|
||||||
// You can customize this by passing in a lambda to filter the assemblies by name,
|
cfg.AddProfiles(typeof(Controllers.UserController))
|
||||||
// like so:
|
);
|
||||||
//HeroicAutoMapperConfigurator.LoadMapsFromCallerAndReferencedAssemblies(x => x.Name.StartsWith("YourPrefix"));
|
|
||||||
//HeroicAutoMapperConfigurator.LoadMapsFromCallerAndReferencedAssemblies();
|
|
||||||
//If you run into issues with the maps not being located at runtime, try using this method instead:
|
|
||||||
HeroicAutoMapperConfigurator.LoadMapsFromAssemblyContainingTypeAndReferencedAssemblies<ControllerBase>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,6 +23,10 @@ namespace InventoryTraker.Web
|
|||||||
.Include("~/Scripts/angular-strap.js")
|
.Include("~/Scripts/angular-strap.js")
|
||||||
.Include("~/Scripts/angular-strap.tpl.js")
|
.Include("~/Scripts/angular-strap.tpl.js")
|
||||||
.Include("~/Scripts/ui-grid.js")
|
.Include("~/Scripts/ui-grid.js")
|
||||||
|
.Include("~/Scripts/ui-grid.js")
|
||||||
|
.Include("~/Scripts/FileSaver.js")
|
||||||
|
.Include("~/Scripts/ng-file-upload-shim.js")
|
||||||
|
.Include("~/Scripts/ng-file-upload.js")
|
||||||
.Include("~/js/app.js")
|
.Include("~/js/app.js")
|
||||||
.IncludeDirectory("~/js/", "*.js", true)
|
.IncludeDirectory("~/js/", "*.js", true)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ namespace InventoryTraker.Web
|
|||||||
{
|
{
|
||||||
public static void Initialize()
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
Database.SetInitializer(new CreateDatabaseIfNotExists<AppDbContext>());
|
//Database.SetInitializer(new CreateDatabaseIfNotExists<AppDbContext>());
|
||||||
|
Database.SetInitializer(new DropCreateDatabaseAlways<AppDbContext>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
using Microsoft.AspNet.Identity;
|
using Heroic.Web.IoC;
|
||||||
|
using Microsoft.AspNet.Identity;
|
||||||
using Microsoft.Owin;
|
using Microsoft.Owin;
|
||||||
using Microsoft.Owin.Security.Cookies;
|
using Microsoft.Owin.Security.Cookies;
|
||||||
|
using Microsoft.Owin.Security.DataProtection;
|
||||||
using Owin;
|
using Owin;
|
||||||
|
|
||||||
namespace InventoryTraker.Web
|
namespace InventoryTraker.Web
|
||||||
@@ -9,6 +11,8 @@ namespace InventoryTraker.Web
|
|||||||
{
|
{
|
||||||
public void Configuration(IAppBuilder app)
|
public void Configuration(IAppBuilder app)
|
||||||
{
|
{
|
||||||
|
IoC.Container.Inject(app.GetDataProtectionProvider());
|
||||||
|
|
||||||
var authenticationOptions = new CookieAuthenticationOptions
|
var authenticationOptions = new CookieAuthenticationOptions
|
||||||
{
|
{
|
||||||
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
|
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ using System.Web;
|
|||||||
using Heroic.Web.IoC;
|
using Heroic.Web.IoC;
|
||||||
using System.Web.Http;
|
using System.Web.Http;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
|
using AutoMapper;
|
||||||
using InventoryTraker.Web.Core;
|
using InventoryTraker.Web.Core;
|
||||||
using InventoryTraker.Web.Data;
|
using InventoryTraker.Web.Data;
|
||||||
using Microsoft.AspNet.Identity;
|
using Microsoft.AspNet.Identity;
|
||||||
using Microsoft.AspNet.Identity.EntityFramework;
|
using Microsoft.AspNet.Identity.EntityFramework;
|
||||||
using Microsoft.Owin.Security;
|
using Microsoft.Owin.Security;
|
||||||
using StructureMap.Graph;
|
|
||||||
|
|
||||||
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(InventoryTraker.Web.StructureMapConfig), "Configure")]
|
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(InventoryTraker.Web.StructureMapConfig), "Configure")]
|
||||||
namespace InventoryTraker.Web
|
namespace InventoryTraker.Web
|
||||||
@@ -42,6 +42,8 @@ namespace InventoryTraker.Web
|
|||||||
cfg.For<IAuthenticationManager>().Use(ctx => ctx.GetInstance<HttpRequestBase>().GetOwinContext().Authentication);
|
cfg.For<IAuthenticationManager>().Use(ctx => ctx.GetInstance<HttpRequestBase>().GetOwinContext().Authentication);
|
||||||
|
|
||||||
//TODO: Add other registries and configure your container (if needed)
|
//TODO: Add other registries and configure your container (if needed)
|
||||||
|
var mapper = AutoMapperConfig.Config.CreateMapper();
|
||||||
|
cfg.For<IMapper>().Use(x => mapper);
|
||||||
});
|
});
|
||||||
|
|
||||||
var resolver = new StructureMapDependencyResolver();
|
var resolver = new StructureMapDependencyResolver();
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using System.Web.Http;
|
||||||
|
using InventoryTraker.Web.Attributes;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web
|
||||||
|
{
|
||||||
|
public class WebApiConfig
|
||||||
|
{
|
||||||
|
public static void Register(HttpConfiguration configuration)
|
||||||
|
{
|
||||||
|
configuration.Routes.MapHttpRoute(
|
||||||
|
"API Default",
|
||||||
|
"api/{controller}/{id}",
|
||||||
|
new { id = RouteParameter.Optional });
|
||||||
|
configuration.Filters.Add(new ExceptionHandlingAttribute());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
using System.Web.Http.Filters;
|
||||||
|
using InventoryTraker.Web.Utilities;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Attributes
|
||||||
|
{
|
||||||
|
// http://stackoverflow.com/questions/15167927/how-do-i-log-all-exceptions-globally-for-a-c-sharp-mvc4-webapi-app
|
||||||
|
public class ExceptionHandlingAttribute : ExceptionFilterAttribute
|
||||||
|
{
|
||||||
|
public override void OnException(HttpActionExecutedContext ctx)
|
||||||
|
{
|
||||||
|
if (ctx != null)
|
||||||
|
{
|
||||||
|
var loggerName = ctx.GetLoggerName();
|
||||||
|
var username = HttpContext.Current.User.Identity.Name;
|
||||||
|
var @params = string.Join(", ", ctx.ActionContext.ActionArguments.Select(i => $"{i.Key}: {{{i.Value}}}"));
|
||||||
|
|
||||||
|
LogManager.GetLogger(loggerName)
|
||||||
|
.Info("username: {0}, params: {{{1}}}", username, @params);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
|
||||||
|
{
|
||||||
|
Content = new StringContent("An error occurred, please try again or contact the administrator."),
|
||||||
|
ReasonPhrase = "Critical Exception"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
/*!
|
/*!
|
||||||
* ui-grid - v3.1.1 - 2016-02-09
|
* ui-grid - v3.2.9 - 2016-09-21
|
||||||
* Copyright (c) 2016 ; License: MIT
|
* Copyright (c) 2016 ; License: MIT
|
||||||
*/
|
*/
|
||||||
#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:before,
|
#ui-grid-twbs #ui-grid-twbs .form-horizontal .form-group:before,
|
||||||
@@ -614,7 +614,6 @@ input[type="text"].ui-grid-filter-input:hover {
|
|||||||
.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.focus,
|
.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.focus,
|
||||||
.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active.focus,
|
.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button:active.focus,
|
||||||
.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active.focus {
|
.ui-grid-menu .ui-grid-menu-inner .ui-grid-menu-close-button.active.focus {
|
||||||
outline: thin dotted;
|
|
||||||
outline: 5px auto -webkit-focus-ring-color;
|
outline: 5px auto -webkit-focus-ring-color;
|
||||||
outline-offset: -2px;
|
outline-offset: -2px;
|
||||||
}
|
}
|
||||||
@@ -1303,7 +1302,6 @@ div.ui-grid-cell input.ng-valid {
|
|||||||
.ui-grid-pager-control button.focus,
|
.ui-grid-pager-control button.focus,
|
||||||
.ui-grid-pager-control button:active.focus,
|
.ui-grid-pager-control button:active.focus,
|
||||||
.ui-grid-pager-control button.active.focus {
|
.ui-grid-pager-control button.active.focus {
|
||||||
outline: thin dotted;
|
|
||||||
outline: 5px auto -webkit-focus-ring-color;
|
outline: 5px auto -webkit-focus-ring-color;
|
||||||
outline-offset: -2px;
|
outline-offset: -2px;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
+2
-2
File diff suppressed because one or more lines are too long
@@ -6,29 +6,51 @@
|
|||||||
<font id="ui-grid" horiz-adv-x="1000" >
|
<font id="ui-grid" horiz-adv-x="1000" >
|
||||||
<font-face font-family="ui-grid" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
|
<font-face font-family="ui-grid" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
|
||||||
<missing-glyph horiz-adv-x="1000" />
|
<missing-glyph horiz-adv-x="1000" />
|
||||||
<glyph glyph-name="plus-squared" unicode="썐" d="m714 314v72q0 14-10 25t-25 10h-179v179q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-179h-178q-15 0-26-10t-10-25v-72q0-14 10-25t26-10h178v-179q0-14 11-25t25-11h71q15 0 25 11t11 25v179h179q14 0 25 10t10 25z m143 304v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" />
|
<glyph glyph-name="plus-squared" unicode="썐" d="M714 314v72q0 14-10 25t-25 10h-179v179q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-179h-178q-15 0-25-10t-11-25v-72q0-14 11-25t25-10h178v-179q0-14 11-25t25-11h71q15 0 25 11t11 25v179h179q14 0 25 10t10 25z m143 304v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" />
|
||||||
<glyph glyph-name="minus-squared" unicode="썑" d="m714 314v72q0 14-10 25t-25 10h-500q-15 0-26-10t-10-25v-72q0-14 10-25t26-10h500q14 0 25 10t10 25z m143 304v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" />
|
|
||||||
<glyph glyph-name="search" unicode="썒" d="m643 386q0 103-74 176t-176 74-177-74-73-176 73-177 177-73 176 73 74 177z m286-465q0-29-22-50t-50-21q-30 0-50 21l-191 191q-100-69-223-69-80 0-153 31t-125 84-84 125-31 153 31 152 84 126 125 84 153 31 152-31 126-84 84-126 31-152q0-123-69-223l191-191q21-21 21-51z" horiz-adv-x="928.6" />
|
<glyph glyph-name="minus-squared" unicode="썑" d="M714 314v72q0 14-10 25t-25 10h-500q-15 0-25-10t-11-25v-72q0-14 11-25t25-10h500q14 0 25 10t10 25z m143 304v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" />
|
||||||
<glyph glyph-name="cancel" unicode="썓" d="m724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164 164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164 164-164q15-15 15-38z" horiz-adv-x="785.7" />
|
|
||||||
<glyph glyph-name="info-circled" unicode="썔" d="m571 82v89q0 8-5 13t-12 5h-54v286q0 8-5 13t-13 5h-178q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h53v-179h-53q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h250q7 0 12 5t5 13z m-71 500v89q0 8-5 13t-13 5h-107q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h107q8 0 13 5t5 13z m357-232q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
|
<glyph glyph-name="search" unicode="썒" d="M643 386q0 103-73 176t-177 74-177-74-73-176 73-177 177-73 177 73 73 177z m286-465q0-29-22-50t-50-21q-30 0-50 21l-191 191q-100-69-223-69-80 0-153 31t-125 84-84 125-31 153 31 152 84 126 125 84 153 31 153-31 125-84 84-126 31-152q0-123-69-223l191-191q21-21 21-51z" horiz-adv-x="928.6" />
|
||||||
<glyph glyph-name="lock" unicode="썕" d="m179 421h285v108q0 59-42 101t-101 41-101-41-41-101v-108z m464-53v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h17v108q0 102 74 176t176 74 177-74 73-176v-108h18q23 0 38-15t16-38z" horiz-adv-x="642.9" />
|
|
||||||
<glyph glyph-name="lock-open" unicode="썖" d="m929 529v-143q0-15-11-25t-25-11h-36q-14 0-25 11t-11 25v143q0 59-41 101t-101 41-101-41-42-101v-108h53q23 0 38-15t16-38v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h375v108q0 103 73 176t177 74 176-74 74-176z" horiz-adv-x="928.6" />
|
<glyph glyph-name="cancel" unicode="썓" d="M724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164 164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164 164-164q15-15 15-38z" horiz-adv-x="785.7" />
|
||||||
<glyph glyph-name="pencil" unicode="썗" d="m203-7l50 51-131 131-51-51v-60h72v-71h60z m291 518q0 12-12 12-5 0-9-4l-303-302q-4-4-4-10 0-12 13-12 5 0 9 4l303 302q3 4 3 10z m-30 107l232-232-464-465h-232v233z m381-54q0-29-20-50l-93-93-232 233 93 92q20 21 50 21 29 0 51-21l131-131q20-22 20-51z" horiz-adv-x="857.1" />
|
|
||||||
<glyph glyph-name="down-dir" unicode="썘" d="m571 457q0-14-10-25l-250-250q-11-11-25-11t-25 11l-250 250q-11 11-11 25t11 25 25 11h500q14 0 25-11t10-25z" horiz-adv-x="571.4" />
|
<glyph glyph-name="info-circled" unicode="썔" d="M571 82v89q0 8-5 13t-12 5h-54v286q0 8-5 13t-13 5h-178q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h53v-179h-53q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h250q7 0 12 5t5 13z m-71 500v89q0 8-5 13t-13 5h-107q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h107q8 0 13 5t5 13z m357-232q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
|
||||||
<glyph glyph-name="up-dir" unicode="썙" d="m571 171q0-14-10-25t-25-10h-500q-15 0-25 10t-11 25 11 26l250 250q10 10 25 10t25-10l250-250q10-11 10-26z" horiz-adv-x="571.4" />
|
|
||||||
<glyph glyph-name="left-dir" unicode="썚" d="m357 600v-500q0-14-10-25t-26-11-25 11l-250 250q-10 11-10 25t10 25l250 250q11 11 25 11t26-11 10-25z" horiz-adv-x="357.1" />
|
<glyph glyph-name="lock" unicode="썕" d="M179 421h285v108q0 59-42 101t-101 41-101-41-41-101v-108z m464-53v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h17v108q0 102 74 176t176 74 177-74 73-176v-108h18q23 0 38-15t16-38z" horiz-adv-x="642.9" />
|
||||||
<glyph glyph-name="right-dir" unicode="썛" d="m321 350q0-14-10-25l-250-250q-11-11-25-11t-25 11-11 25v500q0 15 11 25t25 11 25-11l250-250q10-10 10-25z" horiz-adv-x="357.1" />
|
|
||||||
<glyph glyph-name="left-open" unicode="썜" d="m653 682l-296-296 296-297q11-10 11-25t-11-25l-92-93q-11-10-25-10t-25 10l-414 415q-11 10-11 25t11 25l414 414q10 10 25 10t25-10l92-93q11-10 11-25t-11-25z" horiz-adv-x="714.3" />
|
<glyph glyph-name="lock-open" unicode="썖" d="M929 529v-143q0-15-11-25t-25-11h-36q-14 0-25 11t-11 25v143q0 59-41 101t-101 41-101-41-42-101v-108h53q23 0 38-15t16-38v-322q0-22-16-37t-38-16h-535q-23 0-38 16t-16 37v322q0 22 16 38t38 15h375v108q0 103 73 176t177 74 176-74 74-176z" horiz-adv-x="928.6" />
|
||||||
<glyph glyph-name="right-open" unicode="썝" d="m618 361l-414-415q-11-10-25-10t-26 10l-92 93q-11 11-11 25t11 25l296 297-296 296q-11 11-11 25t11 25l92 93q11 10 26 10t25-10l414-414q10-11 10-25t-10-25z" horiz-adv-x="714.3" />
|
|
||||||
<glyph glyph-name="angle-down" unicode="썞" d="m600 439q0-7-6-13l-260-260q-5-5-13-5t-12 5l-260 260q-6 6-6 13t6 13l27 28q6 6 13 6t13-6l219-219 220 219q5 6 13 6t12-6l28-28q6-5 6-13z" horiz-adv-x="642.9" />
|
<glyph glyph-name="pencil" unicode="썗" d="M203-7l50 51-131 131-51-51v-60h72v-71h60z m291 518q0 12-12 12-5 0-9-4l-303-302q-4-4-4-10 0-12 13-12 5 0 9 4l303 302q3 4 3 10z m-30 107l232-232-464-465h-232v233z m381-54q0-29-20-50l-93-93-232 233 93 92q20 21 50 21 29 0 51-21l131-131q20-22 20-51z" horiz-adv-x="857.1" />
|
||||||
<glyph glyph-name="filter" unicode="썟" d="m783 685q9-23-8-39l-275-275v-414q0-23-22-33-7-3-14-3-15 0-25 11l-143 143q-10 10-10 25v271l-275 275q-18 16-8 39 9 22 33 22h714q23 0 33-22z" horiz-adv-x="785.7" />
|
|
||||||
<glyph glyph-name="sort-alt-up" unicode="썠" d="m411 46q0-6-6-13l-178-178q-5-5-13-5-6 0-13 5l-178 179q-8 9-4 19 4 11 17 11h107v768q0 8 5 13t13 5h107q8 0 13-5t5-13v-768h107q8 0 13-5t5-13z m589-71v-107q0-8-5-13t-13-5h-464q-8 0-13 5t-5 13v107q0 8 5 13t13 5h464q8 0 13-5t5-13z m-107 286v-107q0-8-5-13t-13-5h-357q-8 0-13 5t-5 13v107q0 8 5 13t13 5h357q8 0 13-5t5-13z m-107 285v-107q0-8-5-13t-13-5h-250q-8 0-13 5t-5 13v107q0 8 5 13t13 5h250q8 0 13-5t5-13z m-107 286v-107q0-8-5-13t-13-5h-143q-8 0-13 5t-5 13v107q0 8 5 13t13 5h143q8 0 13-5t5-13z" horiz-adv-x="1000" />
|
<glyph glyph-name="down-dir" unicode="썘" d="M571 457q0-14-10-25l-250-250q-11-11-25-11t-25 11l-250 250q-11 11-11 25t11 25 25 11h500q14 0 25-11t10-25z" horiz-adv-x="571.4" />
|
||||||
<glyph glyph-name="sort-alt-down" unicode="썡" d="m679-25v-107q0-8-5-13t-13-5h-143q-8 0-13 5t-5 13v107q0 8 5 13t13 5h143q8 0 13-5t5-13z m-268 71q0-6-6-13l-178-178q-5-5-13-5-6 0-13 5l-178 179q-8 9-4 19 4 11 17 11h107v768q0 8 5 13t13 5h107q8 0 13-5t5-13v-768h107q8 0 13-5t5-13z m375 215v-107q0-8-5-13t-13-5h-250q-8 0-13 5t-5 13v107q0 8 5 13t13 5h250q8 0 13-5t5-13z m107 285v-107q0-8-5-13t-13-5h-357q-8 0-13 5t-5 13v107q0 8 5 13t13 5h357q8 0 13-5t5-13z m107 286v-107q0-8-5-13t-13-5h-464q-8 0-13 5t-5 13v107q0 8 5 13t13 5h464q8 0 13-5t5-13z" horiz-adv-x="1000" />
|
|
||||||
<glyph glyph-name="ok" unicode="썢" d="m932 534q0-22-15-38l-404-404-76-76q-16-15-38-15t-38 15l-76 76-202 202q-15 16-15 38t15 38l76 76q16 16 38 16t38-16l164-165 366 367q16 16 38 16t38-16l76-76q15-16 15-38z" horiz-adv-x="1000" />
|
<glyph glyph-name="up-dir" unicode="썙" d="M571 171q0-14-10-25t-25-10h-500q-15 0-25 10t-11 25 11 26l250 250q10 10 25 10t25-10l250-250q10-11 10-26z" horiz-adv-x="571.4" />
|
||||||
<glyph glyph-name="menu" unicode="썣" d="m857 100v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 25t25 11h785q15 0 26-11t10-25z m0 286v-72q0-14-10-25t-26-10h-785q-15 0-25 10t-11 25v72q0 14 11 25t25 10h785q15 0 26-10t10-25z m0 285v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 26t25 10h785q15 0 26-10t10-26z" horiz-adv-x="857.1" />
|
|
||||||
<glyph glyph-name="indent-left" unicode="" d="m214 546v-321q0-7-5-13t-13-5q-7 0-12 5l-161 161q-5 5-5 13t5 13l161 160q5 5 12 5 8 0 13-5t5-13z m786-428v-107q0-7-5-13t-13-5h-964q-7 0-13 5t-5 13v107q0 7 5 12t13 6h964q7 0 13-6t5-12z m0 214v-107q0-7-5-13t-13-5h-607q-7 0-13 5t-5 13v107q0 7 5 13t13 5h607q7 0 13-5t5-13z m0 214v-107q0-7-5-12t-13-6h-607q-7 0-13 6t-5 12v107q0 8 5 13t13 5h607q7 0 13-5t5-13z m0 215v-107q0-8-5-13t-13-5h-964q-7 0-13 5t-5 13v107q0 7 5 12t13 6h964q7 0 13-6t5-12z" horiz-adv-x="1000" />
|
<glyph glyph-name="left-dir" unicode="썚" d="M357 600v-500q0-14-10-25t-26-11-25 11l-250 250q-10 11-10 25t10 25l250 250q11 11 25 11t26-11 10-25z" horiz-adv-x="357.1" />
|
||||||
<glyph glyph-name="indent-right" unicode="" d="m196 386q0-8-5-13l-160-161q-5-5-13-5-7 0-13 5t-5 13v321q0 8 5 13t13 5q8 0 13-5l160-160q5-5 5-13z m804-268v-107q0-7-5-13t-13-5h-964q-7 0-13 5t-5 13v107q0 7 5 12t13 6h964q7 0 13-6t5-12z m0 214v-107q0-7-5-13t-13-5h-607q-7 0-13 5t-5 13v107q0 7 5 13t13 5h607q7 0 13-5t5-13z m0 214v-107q0-7-5-12t-13-6h-607q-7 0-13 6t-5 12v107q0 8 5 13t13 5h607q7 0 13-5t5-13z m0 215v-107q0-8-5-13t-13-5h-964q-7 0-13 5t-5 13v107q0 7 5 12t13 6h964q7 0 13-6t5-12z" horiz-adv-x="1000" />
|
|
||||||
<glyph glyph-name="spin5" unicode="" d="m462 850c-6 0-11-5-11-11l0-183 0 0c0-6 5-11 11-11l69 0c1 0 1 0 1 0 7 0 12 5 12 11l0 183 0 0c0 6-5 11-12 11l-69 0c0 0 0 0-1 0z m250-47c-4 1-8-2-10-5l-91-158 0 0c-4-6-2-13 4-16l60-35c0 0 0 0 0 0 6-3 13-1 16 4l91 158c3 6 2 13-4 16l-61 35c-1 1-3 1-5 1z m-428-2c-2 0-4-1-6-2l-61-35c-5-3-7-10-4-16l91-157c0 0 0 0 0 0 3-6 10-8 16-5l61 35c5 4 7 11 4 16l-91 157c0 1 0 1 0 1-2 4-6 6-10 6z m620-163c-2 0-4 0-6-1l-157-91c0 0 0 0 0 0-6-3-8-10-5-16l35-61c4-5 11-7 16-4l157 91c1 0 1 0 1 0 6 3 7 10 4 16l-35 61c-2 3-6 5-10 5z m-810-4c-5 0-9-2-11-6l-35-61c-3-5-1-12 4-15l158-92 0 0c6-3 13-1 16 5l35 60c0 0 0 0 0 0 3 6 1 13-4 16l-158 91c-2 1-4 2-5 2z m712-235l0 0c-6 0-11-5-11-11l0-69c0-1 0-1 0-1 0-7 5-12 11-12l183 0 0 0c6 0 11 5 11 12l0 69c0 0 0 0 0 1 0 6-5 11-11 11l-183 0z m-794-5l0 0c-7 0-12-5-12-12l0-69c0 0 0 0 0-1 0-6 5-11 12-11l182 0 0 0c6 0 11 5 11 11l0 69c0 1 0 1 0 1 0 7-5 12-11 12l-182 0z m772-153c-4 0-8-2-10-6l-34-60c-1 0-1 0-1 0-3-6-1-13 4-16l158-91c6-3 13-2 16 4l35 61c3 5 1 12-4 15l-158 91 0 0c-2 1-4 2-6 2z m-566-5c-1 0-3 0-5-1l-157-91c0 0-1 0-1 0-5-3-7-11-4-16l35-61c3-5 10-7 16-4l157 91c0 0 0 0 0 0 6 3 8 10 5 16l-35 61c-3 3-7 5-11 5z m468-121c-2 0-4 0-6-1l-61-35c-5-4-7-11-4-16l91-157c0-1 0-1 0-1 3-6 11-7 16-4l61 35c5 3 7 10 4 16l-91 157c0 0 0 0 0 0-2 4-6 6-10 6z m-367-3c-4 1-8-2-10-5l-91-158c-3-6-1-13 4-16l61-35c5-3 12-1 15 4l92 158 0 0c3 6 1 13-5 16l-60 34c0 1 0 1 0 1-2 1-4 1-6 1z m149-57c-7 0-12-5-12-11l0-183 0 0c0-6 5-11 12-11l69 0c0 0 0 0 1 0 6 0 11 5 11 11l0 183 0 0c0 6-5 11-11 11l-69 0c-1 0-1 0-1 0z" horiz-adv-x="1000" />
|
<glyph glyph-name="right-dir" unicode="썛" d="M321 350q0-14-10-25l-250-250q-11-11-25-11t-25 11-11 25v500q0 15 11 25t25 11 25-11l250-250q10-10 10-25z" horiz-adv-x="357.1" />
|
||||||
|
|
||||||
|
<glyph glyph-name="left-open" unicode="썜" d="M654 682l-297-296 297-297q10-10 10-25t-10-25l-93-93q-11-10-25-10t-25 10l-414 415q-11 10-11 25t11 25l414 414q10 11 25 11t25-11l93-93q10-10 10-25t-10-25z" horiz-adv-x="714.3" />
|
||||||
|
|
||||||
|
<glyph glyph-name="right-open" unicode="썝" d="M618 361l-414-415q-11-10-25-10t-25 10l-93 93q-11 11-11 25t11 25l296 297-296 296q-11 11-11 25t11 25l93 93q10 11 25 11t25-11l414-414q10-11 10-25t-10-25z" horiz-adv-x="714.3" />
|
||||||
|
|
||||||
|
<glyph glyph-name="angle-down" unicode="썞" d="M600 439q0-7-6-12l-260-261q-5-5-13-5t-12 5l-260 261q-6 5-6 12t6 13l28 28q5 6 12 6t13-6l219-219 220 219q5 6 13 6t12-6l28-28q6-5 6-13z" horiz-adv-x="642.9" />
|
||||||
|
|
||||||
|
<glyph glyph-name="filter" unicode="썟" d="M783 685q9-22-8-39l-275-275v-414q0-23-22-33-7-3-14-3-15 0-25 11l-143 143q-10 11-10 25v271l-275 275q-18 17-8 39 9 22 33 22h714q23 0 33-22z" horiz-adv-x="785.7" />
|
||||||
|
|
||||||
|
<glyph glyph-name="sort-alt-up" unicode="썠" d="M411 46q0-6-6-13l-178-178q-5-5-13-5-6 0-12 5l-179 179q-8 9-4 19 4 11 17 11h107v768q0 8 5 13t13 5h107q8 0 13-5t5-13v-768h107q8 0 13-5t5-13z m589-71v-107q0-8-5-13t-13-5h-464q-8 0-13 5t-5 13v107q0 8 5 13t13 5h464q8 0 13-5t5-13z m-107 286v-107q0-8-5-13t-13-5h-357q-8 0-13 5t-5 13v107q0 8 5 13t13 5h357q8 0 13-5t5-13z m-107 285v-107q0-7-5-12t-13-6h-250q-8 0-13 6t-5 12v107q0 8 5 13t13 5h250q8 0 13-5t5-13z m-107 286v-107q0-8-5-13t-13-5h-143q-8 0-13 5t-5 13v107q0 8 5 13t13 5h143q8 0 13-5t5-13z" horiz-adv-x="1000" />
|
||||||
|
|
||||||
|
<glyph glyph-name="sort-alt-down" unicode="썡" d="M679-25v-107q0-8-5-13t-13-5h-143q-8 0-13 5t-5 13v107q0 8 5 13t13 5h143q8 0 13-5t5-13z m-268 71q0-6-6-13l-178-178q-5-5-13-5-6 0-12 5l-179 179q-8 9-4 19 4 11 17 11h107v768q0 8 5 13t13 5h107q8 0 13-5t5-13v-768h107q8 0 13-5t5-13z m375 215v-107q0-8-5-13t-13-5h-250q-8 0-13 5t-5 13v107q0 8 5 13t13 5h250q8 0 13-5t5-13z m107 285v-107q0-7-5-12t-13-6h-357q-8 0-13 6t-5 12v107q0 8 5 13t13 5h357q8 0 13-5t5-13z m107 286v-107q0-8-5-13t-13-5h-464q-8 0-13 5t-5 13v107q0 8 5 13t13 5h464q8 0 13-5t5-13z" horiz-adv-x="1000" />
|
||||||
|
|
||||||
|
<glyph glyph-name="ok" unicode="썢" d="M933 534q0-22-16-38l-404-404-76-76q-16-15-38-15t-38 15l-76 76-202 202q-15 16-15 38t15 38l76 76q16 16 38 16t38-16l164-165 366 367q16 16 38 16t38-16l76-76q16-15 16-38z" horiz-adv-x="1000" />
|
||||||
|
|
||||||
|
<glyph glyph-name="menu" unicode="썣" d="M857 100v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 25t25 11h785q15 0 26-11t10-25z m0 286v-72q0-14-10-25t-26-10h-785q-15 0-25 10t-11 25v72q0 14 11 25t25 10h785q15 0 26-10t10-25z m0 285v-71q0-14-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 26t25 10h785q15 0 26-10t10-26z" horiz-adv-x="857.1" />
|
||||||
|
|
||||||
|
<glyph glyph-name="indent-left" unicode="" d="M214 546v-321q0-7-5-13t-13-5q-7 0-12 5l-161 161q-5 5-5 13t5 13l161 160q5 5 12 5 8 0 13-5t5-13z m786-428v-107q0-7-5-13t-13-5h-964q-7 0-13 5t-5 13v107q0 7 5 12t13 6h964q7 0 13-6t5-12z m0 214v-107q0-7-5-13t-13-5h-607q-7 0-13 5t-5 13v107q0 7 5 13t13 5h607q7 0 13-5t5-13z m0 214v-107q0-7-5-12t-13-6h-607q-7 0-13 6t-5 12v107q0 8 5 13t13 5h607q7 0 13-5t5-13z m0 215v-107q0-8-5-13t-13-5h-964q-7 0-13 5t-5 13v107q0 7 5 12t13 6h964q7 0 13-6t5-12z" horiz-adv-x="1000" />
|
||||||
|
|
||||||
|
<glyph glyph-name="indent-right" unicode="" d="M196 386q0-8-5-13l-160-161q-5-5-13-5-7 0-13 5t-5 13v321q0 8 5 13t13 5q8 0 13-5l160-160q5-5 5-13z m804-268v-107q0-7-5-13t-13-5h-964q-7 0-13 5t-5 13v107q0 7 5 12t13 6h964q7 0 13-6t5-12z m0 214v-107q0-7-5-13t-13-5h-607q-7 0-13 5t-5 13v107q0 7 5 13t13 5h607q7 0 13-5t5-13z m0 214v-107q0-7-5-12t-13-6h-607q-7 0-13 6t-5 12v107q0 8 5 13t13 5h607q7 0 13-5t5-13z m0 215v-107q0-8-5-13t-13-5h-964q-7 0-13 5t-5 13v107q0 7 5 12t13 6h964q7 0 13-6t5-12z" horiz-adv-x="1000" />
|
||||||
|
|
||||||
|
<glyph glyph-name="spin5" unicode="" d="M462 850c-6 0-11-5-11-11l0-183 0 0c0-6 5-11 11-11l69 0c1 0 1 0 1 0 7 0 12 5 12 11l0 183 0 0c0 6-5 11-12 11l-69 0c0 0 0 0-1 0z m250-47c-4 1-8-2-10-5l-91-158 0 0c-4-6-2-13 4-16l60-34c0-1 0-1 0-1 6-3 13-1 16 4l91 158c3 6 2 13-4 16l-61 35c-1 1-3 1-5 1z m-428-2c-2 0-4-1-6-2l-61-35c-5-3-7-10-4-16l91-157c0 0 0 0 0 0 3-6 10-8 16-5l61 35c5 4 7 11 4 16l-91 157c0 1 0 1 0 1-2 4-6 6-10 6z m620-163c-2 0-4 0-6-1l-157-91c0 0 0 0 0 0-6-3-8-10-5-16l35-61c4-5 11-7 16-4l157 91c1 0 1 0 1 0 6 3 7 11 4 16l-35 61c-2 4-6 6-10 5z m-810-4c-5 0-9-2-11-6l-35-61c-3-5-1-12 4-15l158-91 0 0c6-4 13-2 16 4l35 60c0 0 0 0 0 0 3 6 1 13-4 16l-158 91c-2 1-4 2-5 2z m712-235l0 0c-6 0-11-5-11-11l0-69c0-1 0-1 0-1 0-7 5-12 11-12l183 0 0 0c6 0 11 5 11 12l0 69c0 0 0 0 0 1 0 6-5 11-11 11l-183 0z m-794-5l0 0c-7 0-12-5-12-12l0-69c0 0 0 0 0-1 0-6 5-11 12-11l182 0 0 0c6 0 11 5 11 11l0 69c0 1 0 1 0 1 0 7-5 12-11 12l-182 0z m772-153c-4 0-8-2-10-6l-34-60c-1 0-1 0-1 0-3-6-1-13 4-16l158-91c6-3 13-1 16 4l35 61c3 5 1 12-4 15l-158 92 0 0c-2 1-4 1-6 1z m-566-5c-1 0-3 0-5-1l-157-91c0 0-1 0-1 0-5-3-7-10-4-16l35-61c3-5 10-7 16-4l157 91c0 0 0 0 0 0 6 3 8 10 5 16l-35 61c-3 3-7 6-11 5z m468-121c-2 0-4 0-6-1l-61-35c-5-4-7-11-4-16l91-157c0-1 0-1 0-1 3-6 11-7 16-4l61 35c5 3 7 10 4 16l-91 157c0 0 0 0 0 0-2 4-6 6-10 6z m-367-2c-4 0-8-2-10-6l-91-158c-3-6-1-13 4-16l61-35c5-3 12-1 15 4l92 158 0 0c3 6 1 13-5 16l-60 35c0 0 0 0 0 0-2 1-4 1-6 2z m149-58c-7 0-12-5-12-11l0-183 0 0c0-6 5-11 12-11l69 0c0 0 0 0 1 0 6 0 11 5 11 11l0 183 0 0c0 6-5 11-11 11l-69 0c-1 0-1 0-1 0z" horiz-adv-x="1000" />
|
||||||
</font>
|
</font>
|
||||||
</defs>
|
</defs>
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.9 KiB |
Binary file not shown.
Binary file not shown.
@@ -50,7 +50,7 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
{
|
{
|
||||||
_authManager.SignOut();
|
_authManager.SignOut();
|
||||||
|
|
||||||
return this.RedirectToAction<HomeController>(c => c.Index());
|
return this.RedirectToAction(c => c.Login());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
|
using AutoMapper;
|
||||||
using InventoryTraker.Web.ActionResults;
|
using InventoryTraker.Web.ActionResults;
|
||||||
|
using InventoryTraker.Web.Data;
|
||||||
using InventoryTraker.Web.Utilities;
|
using InventoryTraker.Web.Utilities;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
using System.Web.Mvc;
|
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Controllers
|
|
||||||
{
|
|
||||||
public class HomeController : ControllerBase
|
|
||||||
{
|
|
||||||
public ActionResult Index()
|
|
||||||
{
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data.Entity.Infrastructure;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
|
using InventoryTraker.Web.Core;
|
||||||
|
using InventoryTraker.Web.Data;
|
||||||
|
using InventoryTraker.Web.Services;
|
||||||
|
using InventoryTraker.Web.Utilities;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Controllers
|
||||||
|
{
|
||||||
|
public class ImportController : ApiController
|
||||||
|
{
|
||||||
|
private readonly AppDbContext _context;
|
||||||
|
private readonly InventoryImporter _inventoryImporter;
|
||||||
|
|
||||||
|
public ImportController(AppDbContext context, InventoryImporter inventoryImporter)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
_inventoryImporter = inventoryImporter;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<HttpResponseMessage> Upload()
|
||||||
|
{
|
||||||
|
if (!Request.Content.IsMimeMultipartContent())
|
||||||
|
return Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
|
||||||
|
|
||||||
|
var provider = GetMultipartProvider();
|
||||||
|
var result = await Request.Content.ReadAsMultipartAsync(provider);
|
||||||
|
|
||||||
|
// uploadedFileInfo object will give you some additional stuff like file length,
|
||||||
|
// creation time, directory name, a few filesystem methods etc..
|
||||||
|
var uploadedFileInfo = new FileInfo(result.FileData.First().LocalFileName);
|
||||||
|
|
||||||
|
IEnumerable<Inventory> inventories;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
inventories = _inventoryImporter.Import(uploadedFileInfo);
|
||||||
|
}
|
||||||
|
catch (ImportException e)
|
||||||
|
{
|
||||||
|
LogManager.GetCurrentClassLogger().Info("Import Exception : {0}", e.Message);
|
||||||
|
return Request.CreateResponse(HttpStatusCode.BadRequest, e.Messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var inventory in inventories)
|
||||||
|
{
|
||||||
|
_context.Inventories.Add(inventory);
|
||||||
|
inventory.Transactions = ModelHelper.GetAddedTransaction(inventory.AddedDate);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_context.SaveChanges();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
var message = ModelHelper.GetUpdateExceptionMessage(e);
|
||||||
|
|
||||||
|
LogManager.GetCurrentClassLogger().Info("Import Exception : {0}", message);
|
||||||
|
return Request.CreateResponse(HttpStatusCode.BadRequest, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Request.CreateResponse(HttpStatusCode.OK, new {});
|
||||||
|
}
|
||||||
|
|
||||||
|
private MultipartFormDataStreamProvider GetMultipartProvider()
|
||||||
|
{
|
||||||
|
var uploadFolder = "~/App_Data/Tmp/FileUploads";
|
||||||
|
var root = HttpContext.Current.Server.MapPath(uploadFolder);
|
||||||
|
Directory.CreateDirectory(root);
|
||||||
|
return new MultipartFormDataExentisionStreamProvider(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://stackoverflow.com/questions/16800820/asp-net-webapi-file-upload-using-guid-and-file-extension
|
||||||
|
private class MultipartFormDataExentisionStreamProvider
|
||||||
|
: MultipartFormDataStreamProvider
|
||||||
|
{
|
||||||
|
public MultipartFormDataExentisionStreamProvider(string rootPath) : base(rootPath)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string GetLocalFileName(HttpContentHeaders headers)
|
||||||
|
{
|
||||||
|
// override the filename which is stored by the provider (by default is bodypart_x)
|
||||||
|
var oldfileName = headers.ContentDisposition.FileName.Replace("\"", string.Empty);
|
||||||
|
var newFileName = Guid.NewGuid() + Path.GetExtension(oldfileName);
|
||||||
|
|
||||||
|
return newFileName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,16 +8,20 @@ using InventoryTraker.Web.Attributes;
|
|||||||
using InventoryTraker.Web.Core;
|
using InventoryTraker.Web.Core;
|
||||||
using InventoryTraker.Web.Data;
|
using InventoryTraker.Web.Data;
|
||||||
using InventoryTraker.Web.Models;
|
using InventoryTraker.Web.Models;
|
||||||
|
using InventoryTraker.Web.Services;
|
||||||
|
using InventoryTraker.Web.Utilities;
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Controllers
|
namespace InventoryTraker.Web.Controllers
|
||||||
{
|
{
|
||||||
public class InventoryController : ControllerBase
|
public class InventoryController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly AppDbContext _context;
|
private readonly AppDbContext _context;
|
||||||
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
public InventoryController(AppDbContext context)
|
public InventoryController(AppDbContext context, IMapper mapper)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
|
_mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult Index()
|
public ActionResult Index()
|
||||||
@@ -28,26 +32,46 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
public JsonResult All()
|
public JsonResult All()
|
||||||
{
|
{
|
||||||
var viewModels =
|
var viewModels =
|
||||||
AllInventory()
|
CurrentInventory()
|
||||||
.ProjectTo<InventoryViewModel>()
|
.ProjectTo<InventoryViewModel>(_mapper.ConfigurationProvider)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
return BetterJson(viewModels);
|
return BetterJson(viewModels);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonResult Find(int id)
|
public JsonResult Find(string id)
|
||||||
{
|
{
|
||||||
var inventory = _context.Inventories.Find(id);
|
var inventory = _context.Inventories.Find(id);
|
||||||
var viewModel = Mapper.Map<InventoryViewModel>(inventory);
|
var viewModel = _mapper.Map<InventoryViewModel>(inventory);
|
||||||
return BetterJson(viewModel);
|
return BetterJson(viewModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IQueryable<Inventory> AllInventory()
|
private IQueryable<Inventory> CurrentInventory()
|
||||||
{
|
{
|
||||||
return _context
|
return _context
|
||||||
.Inventories
|
.Inventories
|
||||||
.Where(x => x.Quantity > 0)
|
.Where(i => i.Quantity > 0)
|
||||||
.OrderBy(x => x.InventoryType.Name);
|
.OrderByDescending(x => x.ShredReadyDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionResult Export()
|
||||||
|
{
|
||||||
|
var writer = new InventoryReportWriter();
|
||||||
|
|
||||||
|
var viewModels =
|
||||||
|
CurrentInventory()
|
||||||
|
.ProjectTo<InventoryViewModel>(_mapper.ConfigurationProvider)
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
var excel = writer.Write(viewModels);
|
||||||
|
|
||||||
|
var filename = $"Inventory{DateTime.Today:yyyyMMdd}.xlsx";
|
||||||
|
|
||||||
|
return
|
||||||
|
new FileContentResult(excel, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||||
|
{
|
||||||
|
FileDownloadName = filename
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[ActionLog]
|
[ActionLog]
|
||||||
@@ -56,87 +80,29 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
return GetModelStateErrorListJson();
|
return GetModelStateErrorListJson();
|
||||||
|
|
||||||
var inventory = Mapper.Map<Inventory>(form);
|
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);
|
_context.Inventories.Add(inventory);
|
||||||
inventory.Transactions = new List<Transaction>
|
inventory.Transactions = ModelHelper.GetAddedTransaction(inventory.AddedDate);
|
||||||
{
|
|
||||||
new Transaction
|
|
||||||
{
|
|
||||||
TransactionType = TransactionType.Added,
|
|
||||||
AddedQuantity = inventory.Quantity,
|
|
||||||
CurrentQuantity = inventory.Quantity,
|
|
||||||
Memo = "Arrival",
|
|
||||||
Timestamp = DateTime.Now,
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
[ActionLog]
|
[ActionLog]
|
||||||
public JsonResult Distribute(InventoryDistributeForm form)
|
public JsonResult Update(InventoryAddForm form)
|
||||||
{
|
{
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
return GetModelStateErrorListJson();
|
return GetModelStateErrorListJson();
|
||||||
|
|
||||||
if (form.InventoryQuantities == null || !form.InventoryQuantities.Any())
|
var inventory = _context.Inventories.Find(form.Id);
|
||||||
return GetErrorListJson("Must add at least one item");
|
_mapper.Map(form, inventory);
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
errors.Add($"'{quantityForm.InventoryId}' not found");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inventory.Quantity < 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,
|
|
||||||
Destination = form.Destination,
|
|
||||||
Memo = form.Memo,
|
|
||||||
Timestamp = DateTime.Now,
|
|
||||||
TransactionDate = form.DistributedDate
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errors.Any())
|
|
||||||
return GetErrorListJson(errors.ToArray());
|
|
||||||
|
|
||||||
_context.SaveChanges();
|
_context.SaveChanges();
|
||||||
|
|
||||||
return BetterJson(AllInventory()
|
var model = _mapper.Map<InventoryViewModel>(inventory);
|
||||||
.ProjectTo<InventoryViewModel>()
|
return BetterJson(model);
|
||||||
.ToArray());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[ActionLog]
|
[ActionLog]
|
||||||
@@ -158,7 +124,7 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
{
|
{
|
||||||
if (inventory.Quantity < form.Quantity)
|
if (inventory.Quantity < form.Quantity)
|
||||||
errors.Add(
|
errors.Add(
|
||||||
$"'{inventory.InventoryType.Name}' has only {inventory.Quantity} qty, " +
|
$"'{inventory.Id}' has only {inventory.Quantity} qty, " +
|
||||||
$"cannot remove {form.Quantity}");
|
$"cannot remove {form.Quantity}");
|
||||||
|
|
||||||
inventory.Quantity -= form.Quantity;
|
inventory.Quantity -= form.Quantity;
|
||||||
@@ -166,7 +132,7 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
var mostRecentTransaction =
|
var mostRecentTransaction =
|
||||||
inventory.Transactions.OrderByDescending(t => t.TransactionDate).First();
|
inventory.Transactions.OrderByDescending(t => t.TransactionDate).First();
|
||||||
if (form.RemovedDate < mostRecentTransaction.TransactionDate)
|
if (form.RemovedDate < mostRecentTransaction.TransactionDate)
|
||||||
errors.Add($"'{inventory.InventoryType.Name}' most recent transaction " +
|
errors.Add($"'{inventory.Id}' most recent transaction " +
|
||||||
$"is {mostRecentTransaction.TransactionDate.ToShortDateString()}. " +
|
$"is {mostRecentTransaction.TransactionDate.ToShortDateString()}. " +
|
||||||
$"Cannot add a transaction on {form.RemovedDate.ToShortDateString()}.");
|
$"Cannot add a transaction on {form.RemovedDate.ToShortDateString()}.");
|
||||||
|
|
||||||
@@ -186,7 +152,7 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
|
|
||||||
_context.SaveChanges();
|
_context.SaveChanges();
|
||||||
|
|
||||||
return BetterJson(Mapper.Map<InventoryViewModel>(inventory));
|
return BetterJson(_mapper.Map<InventoryViewModel>(inventory));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Web.Mvc;
|
|
||||||
using AutoMapper;
|
|
||||||
using AutoMapper.QueryableExtensions;
|
|
||||||
using InventoryTraker.Web.Core;
|
|
||||||
using InventoryTraker.Web.Data;
|
|
||||||
using InventoryTraker.Web.Models;
|
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Controllers
|
|
||||||
{
|
|
||||||
public class InventoryTypeController : ControllerBase
|
|
||||||
{
|
|
||||||
private readonly AppDbContext _context;
|
|
||||||
|
|
||||||
public InventoryTypeController(AppDbContext context)
|
|
||||||
{
|
|
||||||
_context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionResult Index()
|
|
||||||
{
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonResult All()
|
|
||||||
{
|
|
||||||
var viewModels = _context.InventoryTypes
|
|
||||||
.OrderByDescending(x => x.Name)
|
|
||||||
.ProjectTo<InventoryTypeViewModel>();
|
|
||||||
|
|
||||||
return BetterJson(viewModels.ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonResult Add(InventoryTypeViewModel form)
|
|
||||||
{
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return GetModelStateErrorListJson();
|
|
||||||
|
|
||||||
var inventoryType = Mapper.Map<InventoryType>(form);
|
|
||||||
_context.InventoryTypes.Add(inventoryType);
|
|
||||||
_context.SaveChanges();
|
|
||||||
|
|
||||||
var model = Mapper.Map<InventoryTypeViewModel>(inventoryType);
|
|
||||||
return BetterJson(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JsonResult Update(InventoryTypeViewModel form)
|
|
||||||
{
|
|
||||||
if (!ModelState.IsValid)
|
|
||||||
return GetModelStateErrorListJson();
|
|
||||||
|
|
||||||
var inventoryType = _context.InventoryTypes.Find(form.Id);
|
|
||||||
Mapper.Map(form, inventoryType);
|
|
||||||
|
|
||||||
_context.SaveChanges();
|
|
||||||
|
|
||||||
var model = Mapper.Map<InventoryTypeViewModel>(inventoryType);
|
|
||||||
return BetterJson(model);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
using System.Web.Mvc;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Web.Mvc;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
|
using InventoryTraker.Web.Attributes;
|
||||||
using InventoryTraker.Web.Identity;
|
using InventoryTraker.Web.Identity;
|
||||||
using InventoryTraker.Web.Models;
|
using InventoryTraker.Web.Models;
|
||||||
using Microsoft.AspNet.Identity;
|
using Microsoft.AspNet.Identity;
|
||||||
@@ -9,27 +12,54 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
public class ProfileController : ControllerBase
|
public class ProfileController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly ApplicationUserManager _userManager;
|
private readonly ApplicationUserManager _userManager;
|
||||||
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
public ProfileController(ApplicationUserManager userManager)
|
public ProfileController(ApplicationUserManager userManager, IMapper mapper)
|
||||||
{
|
{
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
|
_mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult Index()
|
public ActionResult Index()
|
||||||
{
|
{
|
||||||
var user = _userManager.FindById(User.Identity.GetUserId());
|
return View();
|
||||||
var model = Mapper.Map<ProfileForm>(user);
|
|
||||||
return View(model);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonResult Update(ProfileForm form)
|
public JsonResult Get()
|
||||||
{
|
{
|
||||||
var user = _userManager.FindById(User.Identity.GetUserId());
|
var user = _userManager.FindById(User.Identity.GetUserId());
|
||||||
user.Email = form.EmailAddress;
|
var model = _mapper.Map<ProfileForm>(user);
|
||||||
user.UserName = form.FullName;
|
return BetterJson(model);
|
||||||
_userManager.Update(user);
|
}
|
||||||
|
|
||||||
return Json(true);
|
[ActionLog]
|
||||||
|
public async Task<JsonResult> Update(ProfileForm form)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
return GetModelStateErrorListJson();
|
||||||
|
|
||||||
|
var user = _userManager.FindById(User.Identity.GetUserId());
|
||||||
|
user.Email = form.Email;
|
||||||
|
user.UserName = form.UserName;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(form.NewPassword))
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(form.CurrentPassword))
|
||||||
|
return GetErrorListJson("Current password required");
|
||||||
|
|
||||||
|
var result =
|
||||||
|
await _userManager.ChangePasswordAsync(
|
||||||
|
user.Id, form.CurrentPassword, form.NewPassword);
|
||||||
|
|
||||||
|
if (!result.Succeeded)
|
||||||
|
return GetErrorListJson(result.Errors.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
var identityResult = _userManager.Update(user);
|
||||||
|
if (!identityResult.Succeeded)
|
||||||
|
return GetErrorListJson(identityResult.Errors.ToArray());
|
||||||
|
|
||||||
|
return BetterJson(_mapper.Map<ProfileForm>(user));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,190 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Web.Mvc;
|
|
||||||
using AutoMapper;
|
|
||||||
using AutoMapper.QueryableExtensions;
|
|
||||||
using InventoryTraker.Web.Core;
|
|
||||||
using InventoryTraker.Web.Data;
|
|
||||||
using InventoryTraker.Web.Models;
|
|
||||||
using InventoryTraker.Web.Utilities;
|
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Controllers
|
|
||||||
{
|
|
||||||
public class ReportController : ControllerBase
|
|
||||||
{
|
|
||||||
private readonly AppDbContext _context;
|
|
||||||
|
|
||||||
public ReportController(AppDbContext context)
|
|
||||||
{
|
|
||||||
_context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
public ActionResult Distribution()
|
|
||||||
{
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionResult Distribution(DateTime startDate, DateTime endDate)
|
|
||||||
{
|
|
||||||
var query =
|
|
||||||
from t in _context.Transactions
|
|
||||||
where
|
|
||||||
t.TransactionType == TransactionType.Distributed
|
|
||||||
&& t.TransactionDate >= startDate
|
|
||||||
&& t.TransactionDate < endDate
|
|
||||||
group t by new { t.TransactionDate, t.Destination }
|
|
||||||
into g
|
|
||||||
select new
|
|
||||||
{
|
|
||||||
Date = g.Key.TransactionDate,
|
|
||||||
Destination = g.Key.Destination,
|
|
||||||
Transactions = g.ToList()
|
|
||||||
};
|
|
||||||
|
|
||||||
var report =
|
|
||||||
from item in query.ToArray()
|
|
||||||
select new DistributionReport
|
|
||||||
{
|
|
||||||
Date = item.Date,
|
|
||||||
Destination = item.Destination,
|
|
||||||
Transactions =
|
|
||||||
Mapper.Map<IList<Transaction>, IList<TransactionViewModel>>
|
|
||||||
(item.Transactions).ToArray()
|
|
||||||
};
|
|
||||||
|
|
||||||
return BetterJson(report.ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet]
|
|
||||||
public ActionResult Movement()
|
|
||||||
{
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActionResult Movement(DateTime month)
|
|
||||||
{
|
|
||||||
var startDate = month;
|
|
||||||
var endDate = startDate.AddMonths(1);
|
|
||||||
|
|
||||||
var inventoryTypeReport
|
|
||||||
= new MovementReport
|
|
||||||
{
|
|
||||||
Items = GetInventoryTypeReportItems(startDate, endDate),
|
|
||||||
Month = month
|
|
||||||
};
|
|
||||||
|
|
||||||
return BetterJson(inventoryTypeReport);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<MovementReportItem> GetInventoryTypeReportItems(DateTime startDate, DateTime endDate)
|
|
||||||
{
|
|
||||||
var transactionsMostRecentBefore =
|
|
||||||
(from transaction in _context.Transactions
|
|
||||||
where
|
|
||||||
transaction.TransactionDate < startDate
|
|
||||||
group transaction by transaction.Inventory
|
|
||||||
into g
|
|
||||||
let mostRecent =
|
|
||||||
g.OrderByDescending(t => t.TransactionDate)
|
|
||||||
.ThenBy(t => t.CurrentQuantity) // for days with multiple, assume it's the smallest
|
|
||||||
.FirstOrDefault()
|
|
||||||
where mostRecent.CurrentQuantity > 0
|
|
||||||
select mostRecent).ToList();
|
|
||||||
|
|
||||||
var transactionSums =
|
|
||||||
(from transaction in _context.Transactions
|
|
||||||
where
|
|
||||||
transaction.TransactionDate >= startDate
|
|
||||||
&& transaction.TransactionDate < endDate
|
|
||||||
group transaction by transaction.Inventory
|
|
||||||
into g
|
|
||||||
let addedQty = g.Sum(t => t.AddedQuantity)
|
|
||||||
let distributed = g.Where(t => t.TransactionType == TransactionType.Distributed)
|
|
||||||
let distributedQty = distributed.Any() ? distributed.Sum(t => t.RemovedQuantity) : 0
|
|
||||||
let adjustment = g.Where(t =>
|
|
||||||
t.TransactionType == TransactionType.Expired
|
|
||||||
|| t.TransactionType == TransactionType.Loss)
|
|
||||||
let adjustmentQty = adjustment.Any() ? adjustment.Sum(t => t.RemovedQuantity) : 0
|
|
||||||
let endingQty =
|
|
||||||
g
|
|
||||||
.OrderByDescending(t => t.TransactionDate)
|
|
||||||
.ThenBy(t => t.CurrentQuantity)
|
|
||||||
.FirstOrDefault().CurrentQuantity
|
|
||||||
select new
|
|
||||||
{
|
|
||||||
Inventory = g.Key,
|
|
||||||
addedQty,
|
|
||||||
adjustmentQty,
|
|
||||||
distributedQty,
|
|
||||||
endingQty
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
var inventoryReportItems =
|
|
||||||
transactionsMostRecentBefore.FullOuterJoin( // source
|
|
||||||
transactionSums, // inner
|
|
||||||
before => before.Inventory.Id, // fk
|
|
||||||
sums => sums.Inventory.Id, // pk
|
|
||||||
(before, sums, r) =>
|
|
||||||
{
|
|
||||||
var item = new MovementReportInventoryItem();
|
|
||||||
|
|
||||||
if (before != null)
|
|
||||||
{
|
|
||||||
item.Inventory = before.Inventory;
|
|
||||||
item.BeginningQuantity = before.CurrentQuantity;
|
|
||||||
if (sums != null)
|
|
||||||
{
|
|
||||||
item.AddedQuantity = sums.addedQty;
|
|
||||||
item.DistributedQuantity = sums.distributedQty;
|
|
||||||
item.AdjustmentQuantity = sums.adjustmentQty;
|
|
||||||
item.EndingQuantity = sums.endingQty;
|
|
||||||
}
|
|
||||||
else // no change
|
|
||||||
{
|
|
||||||
item.EndingQuantity = item.BeginningQuantity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (sums != null) // item was added in this time period
|
|
||||||
{
|
|
||||||
item.Inventory = sums.Inventory;
|
|
||||||
item.AddedQuantity = sums.addedQty;
|
|
||||||
item.DistributedQuantity = sums.distributedQty;
|
|
||||||
item.AdjustmentQuantity = sums.adjustmentQty;
|
|
||||||
item.EndingQuantity = sums.endingQty;
|
|
||||||
}
|
|
||||||
item.TotalAvailableQuantity = item.BeginningQuantity + item.AddedQuantity;
|
|
||||||
return item;
|
|
||||||
}).ToArray();
|
|
||||||
|
|
||||||
// group by inventory type
|
|
||||||
var inventoryTypeReportItems =
|
|
||||||
from item in inventoryReportItems
|
|
||||||
group item by item.Inventory.InventoryType
|
|
||||||
into grp
|
|
||||||
select new MovementReportItem
|
|
||||||
{
|
|
||||||
InventoryType = Mapper.Map<InventoryTypeViewModel>(grp.Key),
|
|
||||||
BeginningQuantity = grp.Sum(g => g.BeginningQuantity),
|
|
||||||
AddedQuantity = grp.Sum(g => g.AddedQuantity),
|
|
||||||
TotalAvailableQuantity = grp.Sum(g => g.TotalAvailableQuantity),
|
|
||||||
DistributedQuantity = grp.Sum(g => g.DistributedQuantity),
|
|
||||||
AdjustmentQuantity = grp.Sum(g => g.AdjustmentQuantity),
|
|
||||||
EndingQuantity = grp.Sum(g => g.EndingQuantity)
|
|
||||||
};
|
|
||||||
return inventoryTypeReportItems;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class MovementReportInventoryItem
|
|
||||||
{
|
|
||||||
public Inventory Inventory { get; set; }
|
|
||||||
public int BeginningQuantity { get; set; }
|
|
||||||
public int AddedQuantity { get; set; }
|
|
||||||
public int TotalAvailableQuantity { get; set; }
|
|
||||||
public int DistributedQuantity { get; set; }
|
|
||||||
public int AdjustmentQuantity { get; set; }
|
|
||||||
public int EndingQuantity { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using System.Collections;
|
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.Attributes;
|
using InventoryTraker.Web.Attributes;
|
||||||
using InventoryTraker.Web.Core;
|
using InventoryTraker.Web.Core;
|
||||||
@@ -12,10 +12,12 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
public class TransactionController : ControllerBase
|
public class TransactionController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly AppDbContext _context;
|
private readonly AppDbContext _context;
|
||||||
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
public TransactionController(AppDbContext context)
|
public TransactionController(AppDbContext context, IMapper mapper)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
|
_mapper = mapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult Index()
|
public ActionResult Index()
|
||||||
@@ -27,21 +29,21 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
{
|
{
|
||||||
var viewModels =
|
var viewModels =
|
||||||
_context.Transactions
|
_context.Transactions
|
||||||
.ProjectTo<TransactionViewModel>()
|
.ProjectTo<TransactionViewModel>(_mapper.ConfigurationProvider)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
return BetterJson(viewModels);
|
return BetterJson(viewModels);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonResult Get(int? pageNumber, int? pageSize, int? inventoryId)
|
public JsonResult Get(int? pageNumber, int? pageSize, string inventoryId)
|
||||||
{
|
{
|
||||||
IQueryable<Transaction> query =
|
IQueryable<Transaction> query =
|
||||||
_context.Transactions
|
_context.Transactions
|
||||||
.OrderByDescending(t => t.Timestamp);
|
.OrderByDescending(t => t.Timestamp);
|
||||||
|
|
||||||
if (inventoryId.HasValue)
|
if (!string.IsNullOrEmpty(inventoryId))
|
||||||
query =
|
query =
|
||||||
query.Where(t => t.Inventory.Id == inventoryId.Value);
|
query.Where(t => t.Inventory.Id == inventoryId);
|
||||||
|
|
||||||
if (pageNumber.HasValue && pageSize.HasValue)
|
if (pageNumber.HasValue && pageSize.HasValue)
|
||||||
query = query
|
query = query
|
||||||
@@ -50,7 +52,7 @@ namespace InventoryTraker.Web.Controllers
|
|||||||
|
|
||||||
var totalItems = _context.Transactions.Count();
|
var totalItems = _context.Transactions.Count();
|
||||||
var transactions = query
|
var transactions = query
|
||||||
.ProjectTo<TransactionViewModel>()
|
.ProjectTo<TransactionViewModel>(_mapper.ConfigurationProvider)
|
||||||
.ToArray();
|
.ToArray();
|
||||||
return BetterJson(new { totalItems, transactions });
|
return BetterJson(new { totalItems, transactions });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
using AutoMapper;
|
||||||
|
using InventoryTraker.Web.Attributes;
|
||||||
|
using InventoryTraker.Web.Core;
|
||||||
|
using InventoryTraker.Web.Identity;
|
||||||
|
using InventoryTraker.Web.Models;
|
||||||
|
using Microsoft.AspNet.Identity;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Controllers
|
||||||
|
{
|
||||||
|
[Authorize(Roles = ApplicationRoleManager.AdminRoleName)]
|
||||||
|
public class UserController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly ApplicationUserManager _userManager;
|
||||||
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
|
public UserController(ApplicationUserManager userManager, IMapper mapper)
|
||||||
|
{
|
||||||
|
_userManager = userManager;
|
||||||
|
_mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActionResult Index()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonResult All()
|
||||||
|
{
|
||||||
|
var users =
|
||||||
|
from u in _userManager.Users.ToList()
|
||||||
|
let ad = _userManager.GetRoles(u.Id).Contains(ApplicationRoleManager.AdminRoleName)
|
||||||
|
orderby u.UserName
|
||||||
|
select new UserViewModel
|
||||||
|
{
|
||||||
|
UserName = u.UserName,
|
||||||
|
Email = u.Email,
|
||||||
|
Administrator = ad
|
||||||
|
};
|
||||||
|
|
||||||
|
return BetterJson(users.ToList());
|
||||||
|
}
|
||||||
|
|
||||||
|
[ActionLog]
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<JsonResult> Create(UserEditForm form)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
return GetModelStateErrorListJson();
|
||||||
|
|
||||||
|
var user =
|
||||||
|
new User
|
||||||
|
{
|
||||||
|
Email = form.Email,
|
||||||
|
UserName = form.UserName,
|
||||||
|
};
|
||||||
|
|
||||||
|
var identityResult = await _userManager.CreateAsync(user, form.Password);
|
||||||
|
|
||||||
|
if (!identityResult.Succeeded)
|
||||||
|
return GetErrorListJson(identityResult.Errors.ToArray());
|
||||||
|
|
||||||
|
user = _userManager.FindByEmail(form.Email);
|
||||||
|
if (form.Administrator)
|
||||||
|
{
|
||||||
|
var result = _userManager.AddToRole(user.Id, ApplicationRoleManager.AdminRoleName);
|
||||||
|
if (!result.Succeeded)
|
||||||
|
return GetErrorListJson(result.Errors.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
var userViewModel = _mapper.Map<UserViewModel>(user);
|
||||||
|
userViewModel.Administrator = _userManager.IsInRole(user.Id, ApplicationRoleManager.AdminRoleName);
|
||||||
|
return BetterJson(userViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ActionLog]
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<JsonResult> Edit(UserEditForm form)
|
||||||
|
{
|
||||||
|
if (!ModelState.IsValid)
|
||||||
|
return GetModelStateErrorListJson();
|
||||||
|
|
||||||
|
var user = _userManager.FindByEmail(form.Email);
|
||||||
|
|
||||||
|
user.UserName = form.UserName;
|
||||||
|
user.Email = form.Email;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(form.Password))
|
||||||
|
{
|
||||||
|
var resetResult = await _userManager.ChangePasswordAsync(user, form.Password);
|
||||||
|
if (!resetResult.Succeeded)
|
||||||
|
return GetErrorListJson(resetResult.Errors.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
var rolesForUser = _userManager.GetRoles(user.Id);
|
||||||
|
|
||||||
|
if (rolesForUser.Contains(ApplicationRoleManager.AdminRoleName) && !form.Administrator)
|
||||||
|
{
|
||||||
|
var currentUser = _userManager.FindById(User.Identity.GetUserId());
|
||||||
|
if (currentUser == user)
|
||||||
|
return GetErrorListJson("Cannot remove admin from yourself");
|
||||||
|
|
||||||
|
var result = _userManager.RemoveFromRole(user.Id, ApplicationRoleManager.AdminRoleName);
|
||||||
|
if (!result.Succeeded)
|
||||||
|
return GetErrorListJson(result.Errors.ToArray());
|
||||||
|
}
|
||||||
|
else if (!rolesForUser.Contains(ApplicationRoleManager.AdminRoleName) && form.Administrator)
|
||||||
|
{
|
||||||
|
var result = _userManager.AddToRole(user.Id, ApplicationRoleManager.AdminRoleName);
|
||||||
|
if (!result.Succeeded)
|
||||||
|
return GetErrorListJson(result.Errors.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
var identityResult = _userManager.Update(user);
|
||||||
|
|
||||||
|
if (!identityResult.Succeeded)
|
||||||
|
return GetErrorListJson(identityResult.Errors.ToArray());
|
||||||
|
|
||||||
|
var userViewModel = _mapper.Map<UserViewModel>(user);
|
||||||
|
userViewModel.Administrator = _userManager.IsInRole(user.Id, ApplicationRoleManager.AdminRoleName);
|
||||||
|
return BetterJson(userViewModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,27 +1,33 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Core
|
namespace InventoryTraker.Web.Core
|
||||||
{
|
{
|
||||||
// AKA Commodity
|
|
||||||
public class Inventory
|
public class Inventory
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
[Key]
|
||||||
|
[DatabaseGenerated(DatabaseGeneratedOption.None)]
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
public virtual InventoryType InventoryType { get; set; }
|
[Required]
|
||||||
|
public string ProgramName { get; set; }
|
||||||
|
|
||||||
|
public string ProgramSubtype { get; set; }
|
||||||
|
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
public virtual ICollection<Transaction> Transactions { get; set; }
|
public virtual ICollection<Transaction> Transactions { get; set; }
|
||||||
|
|
||||||
|
public int Quantity { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public DateTime ExpirationDate { get; set; }
|
public DateTime ShredReadyDate { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public DateTime AddedDate { get; set; }
|
public DateTime AddedDate { get; set; }
|
||||||
|
|
||||||
[Required]
|
|
||||||
public int Quantity { get; set; }
|
|
||||||
|
|
||||||
public string Memo { get; set; }
|
public string Memo { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Core
|
|
||||||
{
|
|
||||||
public class InventoryType
|
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string Identifier { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public int UnitsPerCase { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string ContainerType { get; set; }
|
|
||||||
|
|
||||||
public double WeightPerCase { get; set; }
|
|
||||||
|
|
||||||
public decimal PricePerCase { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,8 +3,8 @@ namespace InventoryTraker.Web.Core
|
|||||||
public enum TransactionType
|
public enum TransactionType
|
||||||
{
|
{
|
||||||
Added,
|
Added,
|
||||||
Distributed,
|
Shreded,
|
||||||
Expired,
|
Loaned,
|
||||||
Loss
|
Loss
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,8 +8,6 @@ namespace InventoryTraker.Web.Data
|
|||||||
{
|
{
|
||||||
public IDbSet<Inventory> Inventories { get; set; }
|
public IDbSet<Inventory> Inventories { get; set; }
|
||||||
|
|
||||||
public IDbSet<InventoryType> InventoryTypes { get; set; }
|
|
||||||
|
|
||||||
public IDbSet<Transaction> Transactions { get; set; }
|
public IDbSet<Transaction> Transactions { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
using System.Web;
|
using System.Web;
|
||||||
|
using System.Web.Http;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using System.Web.Optimization;
|
using System.Web.Optimization;
|
||||||
using System.Web.Routing;
|
using System.Web.Routing;
|
||||||
|
using InventoryTraker.Web.Migrations;
|
||||||
|
|
||||||
namespace InventoryTraker.Web
|
namespace InventoryTraker.Web
|
||||||
{
|
{
|
||||||
@@ -10,11 +12,13 @@ namespace InventoryTraker.Web
|
|||||||
protected void Application_Start()
|
protected void Application_Start()
|
||||||
{
|
{
|
||||||
AreaRegistration.RegisterAllAreas();
|
AreaRegistration.RegisterAllAreas();
|
||||||
|
WebApiConfig.Register(GlobalConfiguration.Configuration);
|
||||||
RouteConfig.RegisterRoutes(RouteTable.Routes);
|
RouteConfig.RegisterRoutes(RouteTable.Routes);
|
||||||
BundleConfig.RegisterBundles(BundleTable.Bundles);
|
BundleConfig.RegisterBundles(BundleTable.Bundles);
|
||||||
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
|
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
|
||||||
EFConfig.Initialize();
|
EFConfig.Initialize();
|
||||||
//SeedData.Init();
|
SeedData.Init();
|
||||||
|
SeedData.AddAdminRole();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,41 +75,69 @@ namespace InventoryTraker.Web.Helpers
|
|||||||
|
|
||||||
var expression = ExpressionForInternal(property);
|
var expression = ExpressionForInternal(property);
|
||||||
|
|
||||||
//Creates <div class="form-group has-feedback"
|
|
||||||
// form-group-validation="Name">
|
|
||||||
var formGroup = new HtmlTag("div")
|
|
||||||
.AddClasses("form-group", "has-feedback")
|
|
||||||
.Attr("form-group-validation", name);
|
|
||||||
|
|
||||||
var labelText = metadata.DisplayName ?? name.Humanize(LetterCasing.Title);
|
var labelText = metadata.DisplayName ?? name.Humanize(LetterCasing.Title);
|
||||||
|
|
||||||
//Creates <label class="control-label" for="Name">Name</label>
|
//Creates <label class="control-label" for="Name">Name</label>
|
||||||
var label = new HtmlTag("label")
|
var label = new HtmlTag("label")
|
||||||
.AddClass("control-label")
|
|
||||||
.Attr("for", name)
|
.Attr("for", name)
|
||||||
.Text(labelText);
|
.Text(labelText);
|
||||||
|
|
||||||
var tagName = metadata.DataTypeName == "MultilineText"
|
var tagName =
|
||||||
|
metadata.DataTypeName == "MultilineText"
|
||||||
? "textarea"
|
? "textarea"
|
||||||
: "input";
|
: "input";
|
||||||
|
|
||||||
var placeholder = metadata.Watermark ??
|
|
||||||
(labelText + "...");
|
|
||||||
//Creates <input ng-model="expression"
|
//Creates <input ng-model="expression"
|
||||||
// class="form-control" name="Name" type="text" >
|
// class="form-control" name="Name" type="text" >
|
||||||
var input = new HtmlTag(tagName)
|
var input = new HtmlTag(tagName)
|
||||||
.AddClass("form-control")
|
|
||||||
.Attr("ng-model", expression)
|
.Attr("ng-model", expression)
|
||||||
.Attr("name", name)
|
.Attr("name", name);
|
||||||
|
|
||||||
|
var formGroup = new HtmlTag("div");
|
||||||
|
|
||||||
|
if (metadata.ModelType != typeof(bool))
|
||||||
|
{
|
||||||
|
label.AddClass("control-label");
|
||||||
|
|
||||||
|
var placeholder = metadata.Watermark ??
|
||||||
|
labelText + "...";
|
||||||
|
|
||||||
|
input
|
||||||
|
.AddClass("form-control")
|
||||||
.Attr("type", "text")
|
.Attr("type", "text")
|
||||||
.Attr("placeholder", placeholder);
|
.Attr("placeholder", placeholder);
|
||||||
|
|
||||||
ApplyValidationToInput(input, metadata);
|
ApplyValidationToInput(input, metadata);
|
||||||
|
|
||||||
return formGroup
|
//Creates <div class="form-group has-feedback"
|
||||||
|
// form-group-validation="Name">
|
||||||
|
formGroup
|
||||||
|
.AddClass("form-group")
|
||||||
|
.AddClass("has-feedback")
|
||||||
|
.Attr("form-group-validation", name)
|
||||||
.Append(label)
|
.Append(label)
|
||||||
.Append(input);
|
.Append(input);
|
||||||
}
|
}
|
||||||
|
else if (metadata.ModelType == typeof(bool))
|
||||||
|
{
|
||||||
|
label.AddClass("form-check-label");
|
||||||
|
|
||||||
|
input
|
||||||
|
.AddClass("form-check-input")
|
||||||
|
.Attr("type", "checkbox");
|
||||||
|
|
||||||
|
label.Text("")
|
||||||
|
.Append(input)
|
||||||
|
.AppendHtml(" ")
|
||||||
|
.Append(new HtmlTag("text").NoTag().Text(labelText));
|
||||||
|
|
||||||
|
formGroup
|
||||||
|
.AddClass("form-check")
|
||||||
|
.Append(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
return formGroup;
|
||||||
|
}
|
||||||
|
|
||||||
private void ApplyValidationToInput(HtmlTag input, ModelMetadata metadata)
|
private void ApplyValidationToInput(HtmlTag input, ModelMetadata metadata)
|
||||||
{
|
{
|
||||||
@@ -119,6 +147,9 @@ namespace InventoryTraker.Web.Helpers
|
|||||||
if (metadata.DataTypeName == "EmailAddress")
|
if (metadata.DataTypeName == "EmailAddress")
|
||||||
input.Attr("type", "email");
|
input.Attr("type", "email");
|
||||||
|
|
||||||
|
if (metadata.DataTypeName == "Password")
|
||||||
|
input.Attr("type", "password");
|
||||||
|
|
||||||
if (metadata.ModelType == typeof(DateTime))
|
if (metadata.ModelType == typeof(DateTime))
|
||||||
{
|
{
|
||||||
//input.Attr("type", "date");
|
//input.Attr("type", "date");
|
||||||
|
|||||||
@@ -1,11 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using InventoryTraker.Web.Core;
|
using InventoryTraker.Web.Core;
|
||||||
using Microsoft.AspNet.Identity;
|
using Microsoft.AspNet.Identity;
|
||||||
|
using Microsoft.AspNet.Identity.EntityFramework;
|
||||||
|
using Microsoft.AspNet.Identity.Owin;
|
||||||
|
using Microsoft.Owin.Security.DataProtection;
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Identity
|
namespace InventoryTraker.Web.Identity
|
||||||
{
|
{
|
||||||
|
public class ApplicationRoleManager : RoleManager<IdentityRole>
|
||||||
|
{
|
||||||
|
public const string AdminRoleName = "Admin";
|
||||||
|
|
||||||
|
public ApplicationRoleManager(IRoleStore<IdentityRole, string> store) : base(store)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class ApplicationUserManager : UserManager<User>
|
public class ApplicationUserManager : UserManager<User>
|
||||||
{
|
{
|
||||||
public ApplicationUserManager(IUserStore<User> store)
|
public ApplicationUserManager(IUserStore<User> store, IDataProtectionProvider dataProtectionProvider)
|
||||||
: base(store)
|
: base(store)
|
||||||
{
|
{
|
||||||
UserValidator = new UserValidator<User>(this)
|
UserValidator = new UserValidator<User>(this)
|
||||||
@@ -13,6 +27,21 @@ namespace InventoryTraker.Web.Identity
|
|||||||
AllowOnlyAlphanumericUserNames = false,
|
AllowOnlyAlphanumericUserNames = false,
|
||||||
RequireUniqueEmail = true
|
RequireUniqueEmail = true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (dataProtectionProvider != null)
|
||||||
|
{
|
||||||
|
var dataProtector = dataProtectionProvider.Create("Protector");
|
||||||
|
UserTokenProvider = new DataProtectorTokenProvider<User, string>(dataProtector)
|
||||||
|
{
|
||||||
|
TokenLifespan = TimeSpan.FromHours(1),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IdentityResult> ChangePasswordAsync(User user, string newPassword)
|
||||||
|
{
|
||||||
|
var resetToken = await GeneratePasswordResetTokenAsync(user.Id);
|
||||||
|
return await ResetPasswordAsync(user.Id, resetToken, newPassword);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -43,8 +43,8 @@
|
|||||||
<HintPath>..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
|
<HintPath>..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="AutoMapper, Version=4.2.0.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
|
<Reference Include="AutoMapper, Version=5.1.1.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\AutoMapper.4.2.0\lib\net45\AutoMapper.dll</HintPath>
|
<HintPath>..\packages\AutoMapper.5.1.1\lib\net45\AutoMapper.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="ClosedXML, Version=0.76.0.0, Culture=neutral, PublicKeyToken=fd1eb21b62ae805b, processorArchitecture=MSIL">
|
<Reference Include="ClosedXML, Version=0.76.0.0, Culture=neutral, PublicKeyToken=fd1eb21b62ae805b, processorArchitecture=MSIL">
|
||||||
@@ -71,10 +71,6 @@
|
|||||||
<HintPath>..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll</HintPath>
|
<HintPath>..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Heroic.AutoMapper, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Heroic.AutoMapper.2.0.0\lib\net45\Heroic.AutoMapper.dll</HintPath>
|
|
||||||
<Private>True</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Heroic.Web.IoC, Version=4.1.2.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Heroic.Web.IoC, Version=4.1.2.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Heroic.Web.IoC.4.1.2\lib\net45\Heroic.Web.IoC.dll</HintPath>
|
<HintPath>..\packages\Heroic.Web.IoC.4.1.2\lib\net45\Heroic.Web.IoC.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
@@ -133,7 +129,7 @@
|
|||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<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>
|
<HintPath>..\packages\NLog.4.3.10\lib\net45\NLog.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog.Web, Version=0.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog.Web, Version=0.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
@@ -144,8 +140,8 @@
|
|||||||
<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>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="StructureMap, Version=4.3.0.449, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="StructureMap, Version=4.4.1.451, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\StructureMap.4.4.0\lib\net45\StructureMap.dll</HintPath>
|
<HintPath>..\packages\StructureMap.4.4.1\lib\net45\StructureMap.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
@@ -206,7 +202,7 @@
|
|||||||
<Reference Include="System.Web.Services" />
|
<Reference Include="System.Web.Services" />
|
||||||
<Reference Include="System.EnterpriseServices" />
|
<Reference Include="System.EnterpriseServices" />
|
||||||
<Reference Include="WebActivatorEx, Version=2.0.0.0, Culture=neutral, PublicKeyToken=7b26dc2a43f6a0d4, processorArchitecture=MSIL">
|
<Reference Include="WebActivatorEx, Version=2.0.0.0, Culture=neutral, PublicKeyToken=7b26dc2a43f6a0d4, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\WebActivatorEx.2.1.0\lib\net40\WebActivatorEx.dll</HintPath>
|
<HintPath>..\packages\WebActivatorEx.2.2.0\lib\net40\WebActivatorEx.dll</HintPath>
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="WebGrease, Version=1.6.5135.21930, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="WebGrease, Version=1.6.5135.21930, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
@@ -215,6 +211,9 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Content Include="App_Data\placeholder.txt">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="Content\bootstrap-theme.css" />
|
<Content Include="Content\bootstrap-theme.css" />
|
||||||
<Content Include="Content\bootstrap-theme.min.css" />
|
<Content Include="Content\bootstrap-theme.min.css" />
|
||||||
<Content Include="Content\bootstrap.css" />
|
<Content Include="Content\bootstrap.css" />
|
||||||
@@ -232,27 +231,24 @@
|
|||||||
<Content Include="Global.asax" />
|
<Content Include="Global.asax" />
|
||||||
<Content Include="js\app.js" />
|
<Content Include="js\app.js" />
|
||||||
<Content Include="js\authentication\LoginController.js" />
|
<Content Include="js\authentication\LoginController.js" />
|
||||||
<Content Include="js\inventoryType\InventoryTypeAddDirective.js" />
|
<Content Include="js\inventory\InventoryImportDirective.js" />
|
||||||
<Content Include="js\inventoryType\InventoryTypeListDirective.js" />
|
<Content Include="js\profile\profileSvc.js" />
|
||||||
<Content Include="js\inventoryType\InventoryTypeEditDirective.js" />
|
<Content Include="js\profile\ProfileEditDirective.js" />
|
||||||
<Content Include="js\inventoryType\InventoryTypeController.js" />
|
<Content Include="js\user\UserCreateDirective.js" />
|
||||||
|
<Content Include="js\user\UserController.js" />
|
||||||
|
<Content Include="js\user\UserEditDirective.js" />
|
||||||
|
<Content Include="js\user\UserListDirective.js" />
|
||||||
|
<Content Include="js\user\userSvc.js" />
|
||||||
<Content Include="js\inventory\InventoryAddDirective.js" />
|
<Content Include="js\inventory\InventoryAddDirective.js" />
|
||||||
<Content Include="js\inventory\inventoryInfoDirective.js" />
|
<Content Include="js\inventory\inventoryInfoDirective.js" />
|
||||||
<Content Include="js\inventory\inventoryRemoveDirective.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\inventory\inventorySvc.js" />
|
<Content Include="js\inventory\inventorySvc.js" />
|
||||||
<Content Include="js\inventory\InventoryEditDirective.js" />
|
<Content Include="js\inventory\InventoryEditDirective.js" />
|
||||||
<Content Include="js\inventory\InventoryDistributeDirective.js" />
|
<Content Include="js\profile\ProfileController.js" />
|
||||||
<Content Include="js\profile\EditProfileController.js" />
|
|
||||||
<Content Include="js\report\MovementReportDirective.js" />
|
|
||||||
<Content Include="js\report\MovementReportController.js" />
|
|
||||||
<Content Include="js\report\DistributionReportDirective.js" />
|
|
||||||
<Content Include="js\utility\MonthQueryDirective.js" />
|
<Content Include="js\utility\MonthQueryDirective.js" />
|
||||||
<Content Include="js\utility\DateRangeQueryDirective.js" />
|
<Content Include="js\utility\DateRangeQueryDirective.js" />
|
||||||
<Content Include="js\report\DistributionReportController.js" />
|
|
||||||
<Content Include="js\report\reportSvc.js" />
|
|
||||||
<Content Include="js\transaction\TransactionController.js" />
|
<Content Include="js\transaction\TransactionController.js" />
|
||||||
<Content Include="js\transaction\transactionSvc.js" />
|
<Content Include="js\transaction\transactionSvc.js" />
|
||||||
<Content Include="js\utility\ArrayExtensions.js" />
|
<Content Include="js\utility\ArrayExtensions.js" />
|
||||||
@@ -263,11 +259,12 @@
|
|||||||
<Content Include="js\utility\FormGroupValidationDirective.js" />
|
<Content Include="js\utility\FormGroupValidationDirective.js" />
|
||||||
<Content Include="js\utility\HideZeroFilter.js" />
|
<Content Include="js\utility\HideZeroFilter.js" />
|
||||||
<Content Include="js\utility\InputValidationIconsDirective.js" />
|
<Content Include="js\utility\InputValidationIconsDirective.js" />
|
||||||
<Content Include="js\utility\MvcGridDirective.js" />
|
|
||||||
<Content Include="js\utility\ParseDateFilter.js" />
|
<Content Include="js\utility\ParseDateFilter.js" />
|
||||||
<Content Include="Scripts\angular-animate.js" />
|
<Content Include="Scripts\angular-animate.js" />
|
||||||
<Content Include="Scripts\angular-animate.min.js" />
|
<Content Include="Scripts\angular-animate.min.js" />
|
||||||
<Content Include="Scripts\angular-mocks.js" />
|
<Content Include="Scripts\angular-mocks.js" />
|
||||||
|
<Content Include="Scripts\angular-strap.compat.js" />
|
||||||
|
<Content Include="Scripts\angular-strap.compat.min.js" />
|
||||||
<Content Include="Scripts\angular-strap.js" />
|
<Content Include="Scripts\angular-strap.js" />
|
||||||
<Content Include="Scripts\angular-strap.min.js" />
|
<Content Include="Scripts\angular-strap.min.js" />
|
||||||
<Content Include="Scripts\angular-strap.tpl.js" />
|
<Content Include="Scripts\angular-strap.tpl.js" />
|
||||||
@@ -282,23 +279,12 @@
|
|||||||
<Content Include="Content\bootstrap.css.map" />
|
<Content Include="Content\bootstrap.css.map" />
|
||||||
<Content Include="Content\bootstrap-theme.min.css.map" />
|
<Content Include="Content\bootstrap-theme.min.css.map" />
|
||||||
<Content Include="Content\bootstrap-theme.css.map" />
|
<Content Include="Content\bootstrap-theme.css.map" />
|
||||||
<Content Include="Content\ui-grid.woff" />
|
|
||||||
<Content Include="Content\ui-grid.ttf" />
|
|
||||||
<Content Include="Content\ui-grid.eot" />
|
|
||||||
<Content Include="fonts\FontAwesome.otf" />
|
<Content Include="fonts\FontAwesome.otf" />
|
||||||
<Content Include="fonts\fontawesome-webfont.woff2" />
|
<Content Include="fonts\fontawesome-webfont.woff2" />
|
||||||
<Content Include="fonts\fontawesome-webfont.woff" />
|
<Content Include="fonts\fontawesome-webfont.woff" />
|
||||||
<Content Include="fonts\fontawesome-webfont.ttf" />
|
<Content Include="fonts\fontawesome-webfont.ttf" />
|
||||||
<Content Include="fonts\fontawesome-webfont.eot" />
|
<Content Include="fonts\fontawesome-webfont.eot" />
|
||||||
<Content Include="Scripts\angular-strap.min.js.map" />
|
|
||||||
<Content Include="fonts\glyphicons-halflings-regular.woff2" />
|
<Content Include="fonts\glyphicons-halflings-regular.woff2" />
|
||||||
<Content Include="App_Data\InventoryTypeSeedData.xlsx">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="js\inventory\templates\inventoryDistribute.tmpl.cshtml" />
|
|
||||||
<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\inventoryInfo.tmpl.cshtml" />
|
||||||
<Content Include="js\inventory\templates\inventoryRemove.tmpl.cshtml" />
|
<Content Include="js\inventory\templates\inventoryRemove.tmpl.cshtml" />
|
||||||
<Content Include="NLog.config">
|
<Content Include="NLog.config">
|
||||||
@@ -306,19 +292,40 @@
|
|||||||
</Content>
|
</Content>
|
||||||
<Content Include="js\utility\templates\dateRangeQuery.tmpl.cshtml" />
|
<Content Include="js\utility\templates\dateRangeQuery.tmpl.cshtml" />
|
||||||
<Content Include="js\utility\templates\errorList.tmpl.cshtml" />
|
<Content Include="js\utility\templates\errorList.tmpl.cshtml" />
|
||||||
<Content Include="js\report\templates\distributionReport.tmpl.cshtml" />
|
|
||||||
<Content Include="js\utility\templates\statusMessage.tmpl.cshtml" />
|
<Content Include="js\utility\templates\statusMessage.tmpl.cshtml" />
|
||||||
<Content Include="js\utility\templates\monthQuery.tmpl.cshtml" />
|
<Content Include="js\utility\templates\monthQuery.tmpl.cshtml" />
|
||||||
<Content Include="js\report\templates\movementReport.tmpl.cshtml" />
|
<Content Include="js\user\templates\userCreate.tmpl.cshtml" />
|
||||||
|
<Content Include="js\user\templates\userEdit.tmpl.cshtml" />
|
||||||
|
<Content Include="js\user\templates\userList.tmpl.cshtml" />
|
||||||
|
<Content Include="js\profile\templates\profileEdit.tmpl.cshtml" />
|
||||||
|
<Content Include="js\inventory\templates\inventoryImport.tmpl.cshtml" />
|
||||||
|
<Content Include="Content\InventoryTraker_ImportTemplate.xlsx">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="Content\ui-grid.woff" />
|
||||||
|
<Content Include="Content\ui-grid.ttf" />
|
||||||
|
<Content Include="Content\ui-grid.eot" />
|
||||||
<None Include="NLog.xsd">
|
<None Include="NLog.xsd">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</None>
|
</None>
|
||||||
<None Include="Properties\PublishProfiles\ETHRA.pubxml" />
|
<None Include="Properties\PublishProfiles\ETHRA.pubxml" />
|
||||||
|
<Content Include="Scripts\angular-strap.min.js.map" />
|
||||||
<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" />
|
||||||
<Content Include="Scripts\bootstrap.min.js" />
|
<Content Include="Scripts\bootstrap.min.js" />
|
||||||
|
<Content Include="Scripts\FileAPI.flash.swf" />
|
||||||
|
<Content Include="Scripts\FileAPI.js" />
|
||||||
|
<Content Include="Scripts\FileAPI.min.js" />
|
||||||
|
<Content Include="Scripts\FileSaver.js" />
|
||||||
|
<Content Include="Scripts\FileSaver.min.js" />
|
||||||
<Content Include="Scripts\jquery-1.9.1.js" />
|
<Content Include="Scripts\jquery-1.9.1.js" />
|
||||||
<Content Include="Scripts\jquery-1.9.1.min.js" />
|
<Content Include="Scripts\jquery-1.9.1.min.js" />
|
||||||
|
<Content Include="Scripts\ng-file-upload-all.js" />
|
||||||
|
<Content Include="Scripts\ng-file-upload-all.min.js" />
|
||||||
|
<Content Include="Scripts\ng-file-upload-shim.js" />
|
||||||
|
<Content Include="Scripts\ng-file-upload-shim.min.js" />
|
||||||
|
<Content Include="Scripts\ng-file-upload.js" />
|
||||||
|
<Content Include="Scripts\ng-file-upload.min.js" />
|
||||||
<Content Include="Scripts\ui-grid.js" />
|
<Content Include="Scripts\ui-grid.js" />
|
||||||
<Content Include="Scripts\ui-grid.min.js" />
|
<Content Include="Scripts\ui-grid.min.js" />
|
||||||
<Content Include="Web.config">
|
<Content Include="Web.config">
|
||||||
@@ -332,21 +339,23 @@
|
|||||||
<Compile Include="App_Start\EFConfig.cs" />
|
<Compile Include="App_Start\EFConfig.cs" />
|
||||||
<Compile Include="App_Start\FilterConfig.cs" />
|
<Compile Include="App_Start\FilterConfig.cs" />
|
||||||
<Compile Include="App_Start\RouteConfig.cs" />
|
<Compile Include="App_Start\RouteConfig.cs" />
|
||||||
|
<Compile Include="Utilities\ModelHelper.cs" />
|
||||||
|
<Content Include="js\utility\DownloadService.js" />
|
||||||
|
<Compile Include="App_Start\WebApiConfig.cs" />
|
||||||
|
<Compile Include="Attributes\ExceptionHandlingAttribute.cs" />
|
||||||
|
<Compile Include="Controllers\ImportController.cs" />
|
||||||
|
<Compile Include="Controllers\UserController.cs" />
|
||||||
<Compile Include="Migrations\SeedData.cs" />
|
<Compile Include="Migrations\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="Attributes\ActionLogAttribute.cs" />
|
||||||
<Compile Include="Controllers\ReportController.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" />
|
||||||
<Compile Include="Controllers\ControllerBase.cs" />
|
<Compile Include="Controllers\ControllerBase.cs" />
|
||||||
<Compile Include="Controllers\HomeController.cs" />
|
|
||||||
<Compile Include="Controllers\InventoryTypeController.cs" />
|
|
||||||
<Compile Include="Controllers\ProfileController.cs" />
|
<Compile Include="Controllers\ProfileController.cs" />
|
||||||
<Compile Include="Controllers\TemplateController.cs" />
|
<Compile Include="Controllers\TemplateController.cs" />
|
||||||
<Compile Include="Core\Inventory.cs" />
|
<Compile Include="Core\Inventory.cs" />
|
||||||
<Compile Include="Core\InventoryType.cs" />
|
|
||||||
<Compile Include="Core\Transaction.cs" />
|
<Compile Include="Core\Transaction.cs" />
|
||||||
<Compile Include="Core\TransactionType.cs" />
|
<Compile Include="Core\TransactionType.cs" />
|
||||||
<Compile Include="Core\User.cs" />
|
<Compile Include="Core\User.cs" />
|
||||||
@@ -362,33 +371,28 @@
|
|||||||
<Compile Include="Helpers\UIRatingTag.cs" />
|
<Compile Include="Helpers\UIRatingTag.cs" />
|
||||||
<Compile Include="Identity\ApplicationUserManager.cs" />
|
<Compile Include="Identity\ApplicationUserManager.cs" />
|
||||||
<Compile Include="Identity\AspNetIdentityRegistry.cs" />
|
<Compile Include="Identity\AspNetIdentityRegistry.cs" />
|
||||||
<Compile Include="Migrations\201609201242047_Initial.cs" />
|
|
||||||
<Compile Include="Migrations\201609201242047_Initial.Designer.cs">
|
|
||||||
<DependentUpon>201609201242047_Initial.cs</DependentUpon>
|
|
||||||
</Compile>
|
|
||||||
<Compile Include="Migrations\Configuration.cs" />
|
<Compile Include="Migrations\Configuration.cs" />
|
||||||
|
<Compile Include="Models\UserEditForm.cs" />
|
||||||
|
<Compile Include="Models\UserViewModel.cs" />
|
||||||
|
<Compile Include="Models\UserCreateForm.cs" />
|
||||||
<Compile Include="Models\DateRangeQuery.cs" />
|
<Compile Include="Models\DateRangeQuery.cs" />
|
||||||
<Compile Include="Models\DistributionReport.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\InventoryRemoveForm.cs" />
|
||||||
<Compile Include="Models\InventoryReportItem.cs" />
|
|
||||||
<Compile Include="Models\MovementReport.cs" />
|
|
||||||
<Compile Include="Models\MovementReportItem.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" />
|
||||||
<Compile Include="Models\ProfileForm.cs" />
|
<Compile Include="Models\ProfileForm.cs" />
|
||||||
<Compile Include="Models\TransactionViewModel.cs" />
|
<Compile Include="Models\TransactionViewModel.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Services\ImportException.cs" />
|
||||||
|
<Compile Include="Services\InventoryImporter.cs" />
|
||||||
<Compile Include="Utilities\ControllerContextExtensions.cs" />
|
<Compile Include="Utilities\ControllerContextExtensions.cs" />
|
||||||
|
<Compile Include="Utilities\InventoryParser.cs" />
|
||||||
|
<Compile Include="Utilities\InventoryReportWriter.cs" />
|
||||||
<Compile Include="Utilities\ExcelParserBase.cs" />
|
<Compile Include="Utilities\ExcelParserBase.cs" />
|
||||||
<Compile Include="Utilities\IEnumerableExtensions.cs" />
|
<Compile Include="Utilities\IEnumerableExtensions.cs" />
|
||||||
<Compile Include="Utilities\InventoryTypeParser.cs" />
|
|
||||||
<Compile Include="Utilities\DateExtensions.cs" />
|
<Compile Include="Utilities\DateExtensions.cs" />
|
||||||
<Compile Include="Utilities\JsonExtensions.cs" />
|
<Compile Include="Utilities\JsonExtensions.cs" />
|
||||||
<Compile Include="Utilities\MovementReportWriter.cs" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Views\web.config" />
|
<Content Include="Views\web.config" />
|
||||||
@@ -402,16 +406,15 @@
|
|||||||
<Content Include="Scripts\angular-animate.min.js.map" />
|
<Content Include="Scripts\angular-animate.min.js.map" />
|
||||||
<Content Include="Scripts\jquery-1.9.1.min.map" />
|
<Content Include="Scripts\jquery-1.9.1.min.map" />
|
||||||
<Content Include="Views\Authentication\Login.cshtml" />
|
<Content Include="Views\Authentication\Login.cshtml" />
|
||||||
<Content Include="Views\Home\Index.cshtml" />
|
|
||||||
<Content Include="Views\Inventory\Index.cshtml" />
|
<Content Include="Views\Inventory\Index.cshtml" />
|
||||||
<Content Include="Views\Profile\Index.cshtml" />
|
<Content Include="Views\Profile\Index.cshtml" />
|
||||||
<Content Include="Views\Shared\_NavigationNoAuth.cshtml" />
|
<Content Include="Views\Shared\_NavigationNoAuth.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" />
|
<Content Include="Views\Transaction\Index.cshtml" />
|
||||||
<Content Include="Views\InventoryType\Index.cshtml" />
|
|
||||||
<Content Include="Views\Report\Distribution.cshtml" />
|
<Content Include="Views\Report\Distribution.cshtml" />
|
||||||
<Content Include="Views\Report\Movement.cshtml" />
|
<Content Include="Views\Report\Movement.cshtml" />
|
||||||
|
<Content Include="Views\User\Index.cshtml" />
|
||||||
<None Include="Web.Debug.config">
|
<None Include="Web.Debug.config">
|
||||||
<DependentUpon>Web.config</DependentUpon>
|
<DependentUpon>Web.config</DependentUpon>
|
||||||
</None>
|
</None>
|
||||||
@@ -419,11 +422,7 @@
|
|||||||
<DependentUpon>Web.config</DependentUpon>
|
<DependentUpon>Web.config</DependentUpon>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup />
|
||||||
<EmbeddedResource Include="Migrations\201609201242047_Initial.resx">
|
|
||||||
<DependentUpon>201609201242047_Initial.cs</DependentUpon>
|
|
||||||
</EmbeddedResource>
|
|
||||||
</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>
|
||||||
@@ -439,7 +438,7 @@
|
|||||||
<AutoAssignPort>True</AutoAssignPort>
|
<AutoAssignPort>True</AutoAssignPort>
|
||||||
<DevelopmentServerPort>58523</DevelopmentServerPort>
|
<DevelopmentServerPort>58523</DevelopmentServerPort>
|
||||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||||
<IISUrl>http://localhost:58446/</IISUrl>
|
<IISUrl>http://localhost:58448/</IISUrl>
|
||||||
<NTLMAuthentication>False</NTLMAuthentication>
|
<NTLMAuthentication>False</NTLMAuthentication>
|
||||||
<UseCustomServer>False</UseCustomServer>
|
<UseCustomServer>False</UseCustomServer>
|
||||||
<CustomServerUrl>
|
<CustomServerUrl>
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
// <auto-generated />
|
|
||||||
namespace InventoryTraker.Web.Migrations
|
|
||||||
{
|
|
||||||
using System.CodeDom.Compiler;
|
|
||||||
using System.Data.Entity.Migrations;
|
|
||||||
using System.Data.Entity.Migrations.Infrastructure;
|
|
||||||
using System.Resources;
|
|
||||||
|
|
||||||
[GeneratedCode("EntityFramework.Migrations", "6.1.3-40302")]
|
|
||||||
public sealed partial class Initial : IMigrationMetadata
|
|
||||||
{
|
|
||||||
private readonly ResourceManager Resources = new ResourceManager(typeof(Initial));
|
|
||||||
|
|
||||||
string IMigrationMetadata.Id
|
|
||||||
{
|
|
||||||
get { return "201609201242047_Initial"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
string IMigrationMetadata.Source
|
|
||||||
{
|
|
||||||
get { return null; }
|
|
||||||
}
|
|
||||||
|
|
||||||
string IMigrationMetadata.Target
|
|
||||||
{
|
|
||||||
get { return Resources.GetString("Target"); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
namespace InventoryTraker.Web.Migrations
|
|
||||||
{
|
|
||||||
using System;
|
|
||||||
using System.Data.Entity.Migrations;
|
|
||||||
|
|
||||||
public partial class Initial : DbMigration
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
public override void Up()
|
|
||||||
{
|
|
||||||
CreateTable(
|
|
||||||
"dbo.Inventories",
|
|
||||||
c => new
|
|
||||||
{
|
|
||||||
Id = c.Int(nullable: false, identity: true),
|
|
||||||
ExpirationDate = c.DateTime(nullable: false),
|
|
||||||
AddedDate = c.DateTime(nullable: false),
|
|
||||||
Quantity = c.Int(nullable: false),
|
|
||||||
Memo = c.String(),
|
|
||||||
InventoryType_Id = c.Int(),
|
|
||||||
})
|
|
||||||
.PrimaryKey(t => t.Id)
|
|
||||||
.ForeignKey("dbo.InventoryTypes", t => t.InventoryType_Id)
|
|
||||||
.Index(t => t.InventoryType_Id);
|
|
||||||
|
|
||||||
CreateTable(
|
|
||||||
"dbo.InventoryTypes",
|
|
||||||
c => new
|
|
||||||
{
|
|
||||||
Id = c.Int(nullable: false, identity: true),
|
|
||||||
Identifier = c.String(nullable: false),
|
|
||||||
Name = c.String(nullable: false),
|
|
||||||
UnitsPerCase = c.Int(nullable: false),
|
|
||||||
ContainerType = c.String(nullable: false),
|
|
||||||
WeightPerCase = c.Double(nullable: false),
|
|
||||||
PricePerCase = c.Decimal(nullable: false, precision: 18, scale: 2),
|
|
||||||
})
|
|
||||||
.PrimaryKey(t => t.Id);
|
|
||||||
|
|
||||||
CreateTable(
|
|
||||||
"dbo.Transactions",
|
|
||||||
c => new
|
|
||||||
{
|
|
||||||
Id = c.Int(nullable: false, identity: true),
|
|
||||||
TransactionType = c.Int(nullable: false),
|
|
||||||
AddedQuantity = c.Int(nullable: false),
|
|
||||||
RemovedQuantity = c.Int(nullable: false),
|
|
||||||
CurrentQuantity = c.Int(nullable: false),
|
|
||||||
TransactionDate = c.DateTime(nullable: false),
|
|
||||||
Memo = c.String(),
|
|
||||||
Destination = c.String(),
|
|
||||||
Timestamp = c.DateTime(nullable: false),
|
|
||||||
Inventory_Id = c.Int(),
|
|
||||||
})
|
|
||||||
.PrimaryKey(t => t.Id)
|
|
||||||
.ForeignKey("dbo.Inventories", t => t.Inventory_Id)
|
|
||||||
.Index(t => t.Inventory_Id);
|
|
||||||
|
|
||||||
CreateTable(
|
|
||||||
"dbo.AspNetRoles",
|
|
||||||
c => new
|
|
||||||
{
|
|
||||||
Id = c.String(nullable: false, maxLength: 128),
|
|
||||||
Name = c.String(nullable: false, maxLength: 256),
|
|
||||||
})
|
|
||||||
.PrimaryKey(t => t.Id)
|
|
||||||
.Index(t => t.Name, unique: true, name: "RoleNameIndex");
|
|
||||||
|
|
||||||
CreateTable(
|
|
||||||
"dbo.AspNetUserRoles",
|
|
||||||
c => new
|
|
||||||
{
|
|
||||||
UserId = c.String(nullable: false, maxLength: 128),
|
|
||||||
RoleId = c.String(nullable: false, maxLength: 128),
|
|
||||||
})
|
|
||||||
.PrimaryKey(t => new { t.UserId, t.RoleId })
|
|
||||||
.ForeignKey("dbo.AspNetRoles", t => t.RoleId, cascadeDelete: true)
|
|
||||||
.ForeignKey("dbo.AspNetUsers", t => t.UserId, cascadeDelete: true)
|
|
||||||
.Index(t => t.UserId)
|
|
||||||
.Index(t => t.RoleId);
|
|
||||||
|
|
||||||
CreateTable(
|
|
||||||
"dbo.AspNetUsers",
|
|
||||||
c => new
|
|
||||||
{
|
|
||||||
Id = c.String(nullable: false, maxLength: 128),
|
|
||||||
Email = c.String(maxLength: 256),
|
|
||||||
EmailConfirmed = c.Boolean(nullable: false),
|
|
||||||
PasswordHash = c.String(),
|
|
||||||
SecurityStamp = c.String(),
|
|
||||||
PhoneNumber = c.String(),
|
|
||||||
PhoneNumberConfirmed = c.Boolean(nullable: false),
|
|
||||||
TwoFactorEnabled = c.Boolean(nullable: false),
|
|
||||||
LockoutEndDateUtc = c.DateTime(),
|
|
||||||
LockoutEnabled = c.Boolean(nullable: false),
|
|
||||||
AccessFailedCount = c.Int(nullable: false),
|
|
||||||
UserName = c.String(nullable: false, maxLength: 256),
|
|
||||||
})
|
|
||||||
.PrimaryKey(t => t.Id)
|
|
||||||
.Index(t => t.UserName, unique: true, name: "UserNameIndex");
|
|
||||||
|
|
||||||
CreateTable(
|
|
||||||
"dbo.AspNetUserClaims",
|
|
||||||
c => new
|
|
||||||
{
|
|
||||||
Id = c.Int(nullable: false, identity: true),
|
|
||||||
UserId = c.String(nullable: false, maxLength: 128),
|
|
||||||
ClaimType = c.String(),
|
|
||||||
ClaimValue = c.String(),
|
|
||||||
})
|
|
||||||
.PrimaryKey(t => t.Id)
|
|
||||||
.ForeignKey("dbo.AspNetUsers", t => t.UserId, cascadeDelete: true)
|
|
||||||
.Index(t => t.UserId);
|
|
||||||
|
|
||||||
CreateTable(
|
|
||||||
"dbo.AspNetUserLogins",
|
|
||||||
c => new
|
|
||||||
{
|
|
||||||
LoginProvider = c.String(nullable: false, maxLength: 128),
|
|
||||||
ProviderKey = c.String(nullable: false, maxLength: 128),
|
|
||||||
UserId = c.String(nullable: false, maxLength: 128),
|
|
||||||
})
|
|
||||||
.PrimaryKey(t => new { t.LoginProvider, t.ProviderKey, t.UserId })
|
|
||||||
.ForeignKey("dbo.AspNetUsers", t => t.UserId, cascadeDelete: true)
|
|
||||||
.Index(t => t.UserId);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Down()
|
|
||||||
{
|
|
||||||
DropForeignKey("dbo.AspNetUserRoles", "UserId", "dbo.AspNetUsers");
|
|
||||||
DropForeignKey("dbo.AspNetUserLogins", "UserId", "dbo.AspNetUsers");
|
|
||||||
DropForeignKey("dbo.AspNetUserClaims", "UserId", "dbo.AspNetUsers");
|
|
||||||
DropForeignKey("dbo.AspNetUserRoles", "RoleId", "dbo.AspNetRoles");
|
|
||||||
DropForeignKey("dbo.Transactions", "Inventory_Id", "dbo.Inventories");
|
|
||||||
DropForeignKey("dbo.Inventories", "InventoryType_Id", "dbo.InventoryTypes");
|
|
||||||
DropIndex("dbo.AspNetUserLogins", new[] { "UserId" });
|
|
||||||
DropIndex("dbo.AspNetUserClaims", new[] { "UserId" });
|
|
||||||
DropIndex("dbo.AspNetUsers", "UserNameIndex");
|
|
||||||
DropIndex("dbo.AspNetUserRoles", new[] { "RoleId" });
|
|
||||||
DropIndex("dbo.AspNetUserRoles", new[] { "UserId" });
|
|
||||||
DropIndex("dbo.AspNetRoles", "RoleNameIndex");
|
|
||||||
DropIndex("dbo.Transactions", new[] { "Inventory_Id" });
|
|
||||||
DropIndex("dbo.Inventories", new[] { "InventoryType_Id" });
|
|
||||||
DropTable("dbo.AspNetUserLogins");
|
|
||||||
DropTable("dbo.AspNetUserClaims");
|
|
||||||
DropTable("dbo.AspNetUsers");
|
|
||||||
DropTable("dbo.AspNetUserRoles");
|
|
||||||
DropTable("dbo.AspNetRoles");
|
|
||||||
DropTable("dbo.Transactions");
|
|
||||||
DropTable("dbo.InventoryTypes");
|
|
||||||
DropTable("dbo.Inventories");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<!--
|
|
||||||
Microsoft ResX Schema
|
|
||||||
|
|
||||||
Version 2.0
|
|
||||||
|
|
||||||
The primary goals of this format is to allow a simple XML format
|
|
||||||
that is mostly human readable. The generation and parsing of the
|
|
||||||
various data types are done through the TypeConverter classes
|
|
||||||
associated with the data types.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
... ado.net/XML headers & schema ...
|
|
||||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
|
||||||
<resheader name="version">2.0</resheader>
|
|
||||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
|
||||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
|
||||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
|
||||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
|
||||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
|
||||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
|
||||||
</data>
|
|
||||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
|
||||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
|
||||||
<comment>This is a comment</comment>
|
|
||||||
</data>
|
|
||||||
|
|
||||||
There are any number of "resheader" rows that contain simple
|
|
||||||
name/value pairs.
|
|
||||||
|
|
||||||
Each data row contains a name, and value. The row also contains a
|
|
||||||
type or mimetype. Type corresponds to a .NET class that support
|
|
||||||
text/value conversion through the TypeConverter architecture.
|
|
||||||
Classes that don't support this are serialized and stored with the
|
|
||||||
mimetype set.
|
|
||||||
|
|
||||||
The mimetype is used for serialized objects, and tells the
|
|
||||||
ResXResourceReader how to depersist the object. This is currently not
|
|
||||||
extensible. For a given mimetype the value must be set accordingly:
|
|
||||||
|
|
||||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
|
||||||
that the ResXResourceWriter will generate, however the reader can
|
|
||||||
read any of the formats listed below.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.binary.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.soap.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
|
||||||
value : The object must be serialized into a byte array
|
|
||||||
: using a System.ComponentModel.TypeConverter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
-->
|
|
||||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
|
||||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
|
||||||
<xsd:element name="root" msdata:IsDataSet="true">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:choice maxOccurs="unbounded">
|
|
||||||
<xsd:element name="metadata">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="assembly">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:attribute name="alias" type="xsd:string" />
|
|
||||||
<xsd:attribute name="name" type="xsd:string" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="data">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="resheader">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:choice>
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:schema>
|
|
||||||
<resheader name="resmimetype">
|
|
||||||
<value>text/microsoft-resx</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="version">
|
|
||||||
<value>2.0</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="reader">
|
|
||||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="writer">
|
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<data name="Target" xml:space="preserve">
|
|
||||||
<value>H4sIAAAAAAAEAO1dW2/kthV+L9D/IOipLZwZX7qLrWEncMZ2a3R96Y436ZvBkThjYXWZSJRjI8gv60N/Uv9CSV15FylpLhsEAYKxSH7nwkPy8JA8+7///Pfsu9codF5gmgVJfO4eTQ5dB8Ze4gfx6tzN0fKbD+533/7xD2dXfvTq/FDXOyH1cMs4O3efEVqfTqeZ9wwjkE2iwEuTLFmiiZdEU+An0+PDw79Nj46mEEO4GMtxzj7lMQoiWPyB/5wlsQfXKAfhbeLDMKu+45J5gercgQhma+DBc/cmfoExStK3xxR8genkR7iYXAIEXOciDADmZw7DpeuAOE4QQJjb088ZnKM0iVfzNf4Awse3NcT1liDMYCXFaVvdVKDDYyLQtG1YQ3l5hpLIEvDopNLQlG/eS89uo0Gswyusa/RGpC70SKnQdXhqp7MwJTXlep4lKZw0BQeOpM5BYyTYlsh/B84sD1GewvMY5igF4YHzkC/CwPsnfHtMvsD4PM7DkGYYs4zLmA/400OarGGK3j7BZS2G7zpTtt2Ub9g0o9rU8qGTY9e5w8TBIoSNPVC6mGPR4N9hDFOAoP8AEIJpTDBgoVGBOkfr6nUdpAUStk9Y0yW/H7HtS0jr4S58H/qjIP0rB5UAelXoUW5hlNQIeHzhCcN1bsHrRxiv0DMuBq+ucx28Qr/+UqF+jgM8v+BGKM1FInfgJVgVSuN7rrE1TNF1PsGwqJU9B+tyzLeG+cTVvU6T6FMS0iBslad5kqceUWyir/cI0hVE5kzjcRFnwCsYlfJMVXiihmXLsbRCw0fNr7xWLRXN7dm0nQ7MJolSh0MmClLv98lCP5rKessApiOMKcuRTP6/faq4NcoeYDoDGRw2E2H3AYEAa7401W0L8iMMVs+Ik+QywXZrj/WQBh7koaAXRCB0nYcU/6octQ+uM/cAwe3Sl/GIpyaRXuOdav/7aNd3M6Uqxma5JaEs6+MnjLPEf8JL/MtYYLM8TbF2xgGjlDSKS7QZZ4YjcgkzFMSVV79hWkQLGQLR2l413S7YmK4M73rpHZ5+rkw1KgkB3cx222ypLrL1HUSTuuGkhLxOMdzPSfplQiMeOMbt2hnw2HQGPDlaLE8+vHsP/JP3f4Un77Y/G0pM9Oj4ww78kON370ehqrTvzxnuHfnWgurvp6oatasQSsUNhVhlFJMmUOObdY26/6ZNOBXNW1qVCNRnJNQktj0aan43S9fY4ogaermFpOHX7Q9ur8+vIhCEI0yBBlTwpmkZpBFspPw+wQYHYvstC8gyPAP4/wDZ88bdmjn08hQb5px2bTZG7eE5ieFdHi1G2ZUb0xqtax5/Tq6xK5WkVzFpNRjvY+J9SXJ0FRdxyM/IE51LQ4BR2LnwPJhl19iYoT9L8hgN21OQiWrXLsgsBEEk90EIe091eet8UJ8Fr4Musw1dfkxWgSJoWcDW5Rwn5Wc5J1WZLScEQcNIVczxUXyVs1EWjeZ+Ffod3/8qYPffAdv3SMuuvLei+0aKRxpQ+gGE+dikeo2GYoyPPxoK2P0fDQWb+PNL4BOXwWBXUlfG8Eb15Rue7jHHcbbt4cCIuW3i25kD1MMlj+RR9nJ6uMmuQ7BqLyQMi7yPftaGdYD7LXzDOqPnbFbht5D4rXQA2nWKKencPRR6h6l8GWS4PxY5opoc6ZsU5+pU9WN99Y9JljV1T8Q+K3uH/niRZYkXFMrnI5/c0TJLFvvFjuE5cxvup0Klt7g/gjXuAWxF5+5fBLG68ZtzYQl+aW0sjcPJ5IjXCCW9XinygK+K5Y7or/T8w0YlHQflBgofpAxJhFDZeZpwIcUmE7RmOT1y+YXiPr6EIUTQufDKO0czkHnAF6dGbPC+BWMy/Qmhx65OwqsXJEc/ASBRBzzeQRAjcakLYi9Yg7BTS1xLQ7eUyN7Q4Esu4RrGhGCnJkyIyyONhIGGDtcpXRqyMER6m6jqaOmese3hMtS3FZOT7VAVtlbtszZibBKFbMHKJMKbUFXGvLdmXtXeX9upfCBgd+bFhR0U5lVtXDZnXqxCtmVerPBfh3mVER1tn3Lhnd0ZFxtM2v4yKWpjW5bFSL5nhlXuxJp7YfXGZL2+XJCP8BVJ9lmYv2qrlVUbPr7nCegcIm5TEJDwY7v3E91MwWeV4xSttVClC98Bx945FcAY97oDqgqtigwxvmmXeNxA0AG2g6UDtDqDF4DK4W/BUR1Q17JUuR4WsHV0XAtbLTkcLGXSEhvh7zZTtTuuQfOjzny32gjK2bwwkM03qBLI2vz5GZjVh4GuFBeRRE0ZbGAttrCUSOwQ1KhJv2k103sPDcmus0gMqWNLa7qppcSoxr/OcNR7UFod4pwyWCnM+ZqoDeW+qnNnRfFd6Vojv2xDpBC85nUcyesZSyG5zOXvdPrtJed8dYXkNa/jSF4ZkEJwiTPa5Y7ai816kSMZeh2QbtygpuxsWr6rqz6cTRUP8M5uwXodxCvqQV71xZmXr/Fm38ztH6hFJcbUY/TKO20NJTztgRXkSsmtfx9eB2mGyOu/RXFffuZHQjXG6VMs4DUp0a8T+61ez+s25Dfvx7EvEyfKtaXV5zUWMSIOdnHcKVsdxbYOeR4JQpBKjldnSZhHsdrZV7fmX63RSHyZOSr1eI0GpD6bY7U3yGmo9qs5Unnrm0Ypv4gIZ1Ouo4Q9jGAZwkaSNTYrU6x8o3GtUeYV2likvP1mrJJ+HsWitN/N0cpbPjRO+cUcgX28RCOxJeaI3CMmGpIrMsfkXibRmFyROSb7QomGZEv2ZgwxzvgoI4jeQtuPH23rzYwe4cyZhhIKLWd1+XTMFZljCm+OaFSh0GJ88c+PmBHGF/bSrbi+CYWbWJtUCMxzIxqIKbCQtH1SxMjYft6bMa9y2vssl3Ssq8dqqW2+meFuvrztyq0RdjWjdlUTRezfXWoIpUdQRbcZX0AR8Vaj1EfHzKSnOE7eWfepYkE9uqyI19p3k7zZhjZE5ZsMZh9UfrLEoK71C2BUmYUrxry8YFwxpsQckXteQUNyRRZc0o8oGCbpgl54Co3Ka1gsdMKzCWa9E0rNkSUPKGhoSXEPbAnPfJmFiye+sWDcPLHYYhPVPLjgJ809Xq+UIeCBC1Z5xjRsxVJgbGZeHGfBo+7JMw55+9kSq7oJL4BV3/fSppTB9YE2VR4wDrMpBYZ6FmLumbOTkPZyvBqTuTzORhw0l+fVeHaWu2n7YOP3ivgff+xrE+fj2xqHmMkphSoFhPxcV1Se2cTDYMnviFC89GdTeUWm9/yoZQx7H35Q3G66ycjbgeaOv43w/AmPtREpzsPtAl10S4uIlqRvtGfeQw1oDOPRHvPvp+n0MhvhfJCv0sx8zTkhdx54Vp3NdWftFA7ryiokp1U5heMNxluGYFQa3vyncBYGkLiTdYVbEAdLmKHyaYp7fHh0zKX83J/0m9Ms80PJ2Sb9Zk7xYGILjy4DotbOZ5W2mQukyS59/BuNkuyyNxKfb6qQfkB2qPgFpN4zSP8Ugdc/00gmbzXFuZ5iSriQeBP78PXc/aVofOrc/PuJb3/g3Kd4bJw6h86vel565n38bRinmFxR2YvWiYqGIcmSIPaxUGkKxGGsSdMaLsME2HMny2ro7yCr4W/DmhXJA/uYjTRXYB8gRabAXqYszxPYB0qRJbD3WjLaOiDJBDgIT8j211tE1qXsuTptaGVSHqVtYyjX/SM+HB9h8ehWLxGa/Co+H+BNAV45fspxwSNWKFExn6VmnNlTfx62pznazLWKjbZsyprrwB5mM7dZcVM2HcCNXT63r3cUMZnSpKjcKOifGG0R9PB4JEnRBs3w0sRngxAlyc3GwhtFharkZX2wlInLZOukibDyRGZ9WFMmMevj8PApzMznnrrlDtcXyenVV+uj79eCJCSjGjTQxYRTFnADkkr1sIyvLB/TaKvjg5huaTTsXZq2ynpGzNhDD5M+CXTkqH1T/vRLndJxw3/09+C6By4SYganfVtINWCXvsiyJzvsgnmErXqcvVnb2IZd6C/Kayxjd1bRM4/TvqRuah/Qa1/Xbzxj0zaTNGmu+5pGGLZkXKa5mXaV0USS80CfEWFjKU22bT+q23cW0ax9yr60DwZUZbdQGNCm0y1t24BUV+320YC68yvtg/3sahnbhfUYL187z6Ekvrrn+7K6Fibcc9GmSCqvA527/oIcsJX7P13OEyWZcpOmJlVdgdSQU+Sh4SkyrrpAjymVUdOliFFmFiqtXhSOKZZRK7NlyxNIqIi1w0xJsK2iJqrOXMETLucZgVj5WU/ATqrKedGKVdXRk1VkYNHRrtY9Le2qjp62IgfKDrNH0UNPkilAnLOku2tZ+667jQYq2FhSKEvW1WEAqrUuR9veZXuS5quRJXHrWOklKMp0cDvM7iSk9zEWk5l2FG93RhJ0jGRO/QVl5jjFg5KRBB2eu6m/mGOarUWuJvHONXby8picYpZ/XcIsWLUQ5Cp5DD3GvWvq3MTLpPYyOY7qKsIdKAR87PtdpChY4jkKF5MDzOKfVKiS7F9FC+jfxPc5WucIiwyjRchMhMRb1dEvElKxPJ/drwtfaQwRMJsBOfi9j7/Pg7D9hwSuJQcOCgjiBlfHhaQvETk2XL01SHdJbAhUqa/x3h9htA4xWHYfz8EL7MMbNr+PcAW8t/Z4SQXS3RGs2s8uA7BKQZRVGG17/Ce2YT96/fb/ZW0K6VaEAAA=</value>
|
|
||||||
</data>
|
|
||||||
<data name="DefaultSchema" xml:space="preserve">
|
|
||||||
<value>dbo</value>
|
|
||||||
</data>
|
|
||||||
</root>
|
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Web;
|
|
||||||
using InventoryTraker.Web.Core;
|
using InventoryTraker.Web.Core;
|
||||||
using InventoryTraker.Web.Data;
|
using InventoryTraker.Web.Data;
|
||||||
using InventoryTraker.Web.Identity;
|
using InventoryTraker.Web.Identity;
|
||||||
using InventoryTraker.Web.Utilities;
|
|
||||||
using Microsoft.AspNet.Identity;
|
using Microsoft.AspNet.Identity;
|
||||||
using Microsoft.AspNet.Identity.EntityFramework;
|
using Microsoft.AspNet.Identity.EntityFramework;
|
||||||
|
|
||||||
@@ -14,6 +11,33 @@ namespace InventoryTraker.Web.Migrations
|
|||||||
{
|
{
|
||||||
public static class SeedData
|
public static class SeedData
|
||||||
{
|
{
|
||||||
|
public static void AddAdminRole()
|
||||||
|
{
|
||||||
|
using (var context = new AppDbContext())
|
||||||
|
AddAdminRole(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddAdminRole(AppDbContext context)
|
||||||
|
{
|
||||||
|
var manager = new ApplicationRoleManager(new RoleStore<IdentityRole>(context));
|
||||||
|
if (!manager.RoleExists(ApplicationRoleManager.AdminRoleName))
|
||||||
|
{
|
||||||
|
var result = manager.Create(new IdentityRole(ApplicationRoleManager.AdminRoleName));
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no users are admins, make them all!
|
||||||
|
var adminRole = manager.Roles.First(r => r.Name == ApplicationRoleManager.AdminRoleName);
|
||||||
|
var userManager = new ApplicationUserManager(new UserStore<User>(context), null);
|
||||||
|
var admins = userManager.Users.Where(u => u.Roles.Any(r => r.RoleId == adminRole.Id));
|
||||||
|
if (!admins.Any())
|
||||||
|
{
|
||||||
|
foreach (var user in userManager.Users.ToList())
|
||||||
|
{
|
||||||
|
userManager.AddToRole(user.Id, ApplicationRoleManager.AdminRoleName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Init()
|
public static void Init()
|
||||||
{
|
{
|
||||||
using (var context = new AppDbContext())
|
using (var context = new AppDbContext())
|
||||||
@@ -24,7 +48,7 @@ namespace InventoryTraker.Web.Migrations
|
|||||||
{
|
{
|
||||||
if (!context.Users.Any())
|
if (!context.Users.Any())
|
||||||
{
|
{
|
||||||
var manager = new ApplicationUserManager(new UserStore<User>(context));
|
var manager = new ApplicationUserManager(new UserStore<User>(context), null);
|
||||||
manager.Create(new User
|
manager.Create(new User
|
||||||
{
|
{
|
||||||
Email = "james.kolpack@gmail.com",
|
Email = "james.kolpack@gmail.com",
|
||||||
@@ -52,32 +76,16 @@ namespace InventoryTraker.Web.Migrations
|
|||||||
|
|
||||||
if (!context.Inventories.Any())
|
if (!context.Inventories.Any())
|
||||||
{
|
{
|
||||||
AddInventoryTypes(context);
|
//AddInventory(context);
|
||||||
|
|
||||||
context.SaveChanges();
|
context.SaveChanges();
|
||||||
|
|
||||||
AddInventory(context);
|
|
||||||
|
|
||||||
context.SaveChanges();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AddInventoryTypes(AppDbContext context)
|
|
||||||
{
|
|
||||||
var folder = HttpContext.Current.Server.MapPath("~/App_Data");
|
|
||||||
var inventoryTypeFile = Path.Combine(folder, "InventoryTypeSeedData.xlsx");
|
|
||||||
var parser = new InventoryTypeParser(new FileInfo(inventoryTypeFile));
|
|
||||||
foreach (var inventoryType in parser.Parse())
|
|
||||||
{
|
|
||||||
context.InventoryTypes.Add(inventoryType);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddInventory(AppDbContext context)
|
private static void AddInventory(AppDbContext context)
|
||||||
{
|
{
|
||||||
var r = new Random(1);
|
var r = new Random(1);
|
||||||
var inventoryTypes = context.InventoryTypes.ToList();
|
var programs = new List<string> { "Aging", "Corrections", "Employment", "Family", "Health", "Housing" };
|
||||||
var counties = new List<string> {"Blount County", "Morgan County", "Knox County", "Anderson County", "Claiborne County", "Campbell County"};
|
|
||||||
var colors = new List<string> {"Red", "Purple", "Blue", "Yellow", "White"};
|
var colors = new List<string> {"Red", "Purple", "Blue", "Yellow", "White"};
|
||||||
|
|
||||||
for (var dd = DateTime.Today.AddYears(-4); dd < DateTime.Today.AddMonths(-2); dd = dd.AddMonths(3))
|
for (var dd = DateTime.Today.AddYears(-4); dd < DateTime.Today.AddMonths(-2); dd = dd.AddMonths(3))
|
||||||
@@ -86,31 +94,33 @@ namespace InventoryTraker.Web.Migrations
|
|||||||
// add some inventory
|
// add some inventory
|
||||||
for (int i = 0; i < r.Next(5,10); i++)
|
for (int i = 0; i < r.Next(5,10); i++)
|
||||||
{
|
{
|
||||||
var inventoryType = inventoryTypes.ElementAt(r.Next(0, context.InventoryTypes.Count()));
|
|
||||||
var addedDate = dd.AddDays(r.Next(-10, 10));
|
var addedDate = dd.AddDays(r.Next(-10, 10));
|
||||||
var expiration = addedDate.AddMonths(r.Next(2, 48));
|
var expiration = addedDate.AddMonths(r.Next(2, 48));
|
||||||
var memo =
|
var memo =
|
||||||
r.Next(0, 3) > 0
|
r.Next(0, 3) > 0
|
||||||
? colors.ElementAt(r.Next(0, colors.Count)) + $" {inventoryType.ContainerType}"
|
? colors.ElementAt(r.Next(0, colors.Count)) + " box"
|
||||||
: string.Empty;
|
: string.Empty;
|
||||||
var quantity = r.Next(5, 112);
|
var quantity = 1;
|
||||||
|
var id = r.Next(10000000, 99999999).ToString();
|
||||||
|
var program = programs.ElementAt(r.Next(0, programs.Count));
|
||||||
|
|
||||||
var addedTransaction = new Transaction
|
var addedTransaction = new Transaction
|
||||||
{
|
{
|
||||||
TransactionType = TransactionType.Added,
|
TransactionType = TransactionType.Added,
|
||||||
AddedQuantity = quantity,
|
AddedQuantity = quantity,
|
||||||
Memo = "Arrival",
|
Memo = "Added",
|
||||||
CurrentQuantity = quantity,
|
CurrentQuantity = quantity,
|
||||||
TransactionDate = addedDate,
|
TransactionDate = addedDate,
|
||||||
Timestamp = addedDate
|
Timestamp = addedDate
|
||||||
};
|
};
|
||||||
var inventory = new Inventory
|
var inventory = new Inventory
|
||||||
{
|
{
|
||||||
InventoryType = inventoryType,
|
ShredReadyDate = expiration,
|
||||||
ExpirationDate = expiration,
|
|
||||||
AddedDate = addedDate,
|
AddedDate = addedDate,
|
||||||
Memo = memo,
|
Memo = memo,
|
||||||
Quantity = quantity,
|
Quantity = quantity,
|
||||||
|
ProgramName = program,
|
||||||
|
Id = id,
|
||||||
Transactions = new List<Transaction> {addedTransaction}
|
Transactions = new List<Transaction> {addedTransaction}
|
||||||
};
|
};
|
||||||
context.Inventories.Add(inventory);
|
context.Inventories.Add(inventory);
|
||||||
@@ -120,135 +130,8 @@ namespace InventoryTraker.Web.Migrations
|
|||||||
ExprireLossInventory(context, dd, r);
|
ExprireLossInventory(context, dd, r);
|
||||||
|
|
||||||
dd = dd.AddDays(14);
|
dd = dd.AddDays(14);
|
||||||
// distribute some inventory
|
|
||||||
foreach (var destination in counties)
|
|
||||||
{
|
|
||||||
var availableInventories =
|
|
||||||
context.Inventories.Local.Where(i => i.Quantity > 0).ToList();
|
|
||||||
|
|
||||||
for (
|
|
||||||
var i = r.Next(0, availableInventories.Count);
|
|
||||||
i < availableInventories.Count;
|
|
||||||
i += r.Next(1, availableInventories.Count / 2))
|
|
||||||
{
|
|
||||||
var inventory = availableInventories.ElementAt(i);
|
|
||||||
if (inventory.ExpirationDate <= dd)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var quantityRemoved = r.Next(1, inventory.Quantity + 1);
|
|
||||||
|
|
||||||
var transMemo = $"Distributed to {destination}";
|
|
||||||
var transType = TransactionType.Distributed;
|
|
||||||
|
|
||||||
var distributeTransaction = new Transaction
|
|
||||||
{
|
|
||||||
TransactionType = transType,
|
|
||||||
RemovedQuantity = quantityRemoved,
|
|
||||||
CurrentQuantity = inventory.Quantity - quantityRemoved,
|
|
||||||
Inventory = inventory,
|
|
||||||
Memo = transMemo,
|
|
||||||
TransactionDate = dd,
|
|
||||||
Timestamp = dd,
|
|
||||||
Destination = destination
|
|
||||||
};
|
|
||||||
inventory.Quantity = distributeTransaction.CurrentQuantity;
|
|
||||||
|
|
||||||
inventory.Transactions.Add(distributeTransaction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ExprireLossInventory(context, dd, r);
|
ExprireLossInventory(context, dd, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
//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 =
|
|
||||||
// r.Next(0,3) > 0
|
|
||||||
// ? colors.ElementAt(r.Next(0, colors.Count)) + $" {inventoryType.ContainerType}"
|
|
||||||
// : string.Empty;
|
|
||||||
// var quantity = r.Next(5, 112);
|
|
||||||
|
|
||||||
// var previousTransaction = new Transaction
|
|
||||||
// {
|
|
||||||
// TransactionType = TransactionType.Added,
|
|
||||||
// AddedQuantity = quantity,
|
|
||||||
// Memo = "Arrival",
|
|
||||||
// CurrentQuantity = quantity,
|
|
||||||
// TransactionDate = addedDate,
|
|
||||||
// Timestamp = addedDate
|
|
||||||
// };
|
|
||||||
// var inventory = new Inventory
|
|
||||||
// {
|
|
||||||
// InventoryType = inventoryType,
|
|
||||||
// ExpirationDate = expiration,
|
|
||||||
// AddedDate = addedDate,
|
|
||||||
// Memo = memo,
|
|
||||||
// Quantity = quantity,
|
|
||||||
// Transactions = new List<Transaction> { previousTransaction}
|
|
||||||
// };
|
|
||||||
// context.Inventories.Add(inventory);
|
|
||||||
|
|
||||||
// for (int j = 0; j < 5 && previousTransaction.CurrentQuantity > 0; j++)
|
|
||||||
// {
|
|
||||||
// var transactionDate = previousTransaction.TransactionDate.AddDays(r.Next(1, 100));
|
|
||||||
// if (transactionDate >= DateTime.Today)
|
|
||||||
// break;
|
|
||||||
|
|
||||||
// Transaction transaction;
|
|
||||||
// if (transactionDate >= expiration)
|
|
||||||
// {
|
|
||||||
// if (r.Next(1, 3) == 1)
|
|
||||||
// break;
|
|
||||||
|
|
||||||
//transaction = new Transaction
|
|
||||||
//{
|
|
||||||
// TransactionType = TransactionType.Expired,
|
|
||||||
// RemovedQuantity = previousTransaction.CurrentQuantity,
|
|
||||||
// CurrentQuantity = 0,
|
|
||||||
// Inventory = inventory,
|
|
||||||
// Memo = $"Expired on {expiration.ToShortDateString()}",
|
|
||||||
// TransactionDate = transactionDate,
|
|
||||||
// Timestamp = transactionDate
|
|
||||||
//};
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// var quantityRemoved = r.Next(1, 100);
|
|
||||||
// if (quantityRemoved > previousTransaction.CurrentQuantity)
|
|
||||||
// quantityRemoved = previousTransaction.CurrentQuantity;
|
|
||||||
|
|
||||||
// var destination = counties.ElementAt(r.Next(0, counties.Count));
|
|
||||||
// var transMemo = $"Distributed to {destination}";
|
|
||||||
// var transType = TransactionType.Distributed;
|
|
||||||
|
|
||||||
// if (r.Next(1, 15) == 1)
|
|
||||||
// {
|
|
||||||
// transMemo = "Loss";
|
|
||||||
// transType = TransactionType.Loss;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// transaction = new Transaction
|
|
||||||
// {
|
|
||||||
// TransactionType = transType,
|
|
||||||
// RemovedQuantity = quantityRemoved,
|
|
||||||
// CurrentQuantity = previousTransaction.CurrentQuantity - quantityRemoved,
|
|
||||||
// Inventory = inventory,
|
|
||||||
// Memo = transMemo,
|
|
||||||
// TransactionDate = transactionDate,
|
|
||||||
// Timestamp = transactionDate,
|
|
||||||
// Destination = destination
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// inventory.Quantity = transaction.CurrentQuantity;
|
|
||||||
|
|
||||||
// inventory.Transactions.Add(transaction);
|
|
||||||
|
|
||||||
// previousTransaction = transaction;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ExprireLossInventory(AppDbContext context, DateTime dd, Random r)
|
private static void ExprireLossInventory(AppDbContext context, DateTime dd, Random r)
|
||||||
@@ -258,15 +141,15 @@ namespace InventoryTraker.Web.Migrations
|
|||||||
|
|
||||||
foreach (var inventory in availableInventories)
|
foreach (var inventory in availableInventories)
|
||||||
{
|
{
|
||||||
if (inventory.ExpirationDate <= dd && r.Next(0, 4) > 0)
|
if (inventory.ShredReadyDate <= dd && r.Next(0, 4) > 0)
|
||||||
{
|
{
|
||||||
var expiredTransaction = new Transaction
|
var expiredTransaction = new Transaction
|
||||||
{
|
{
|
||||||
TransactionType = TransactionType.Expired,
|
TransactionType = TransactionType.Shreded,
|
||||||
RemovedQuantity = inventory.Quantity,
|
RemovedQuantity = inventory.Quantity,
|
||||||
CurrentQuantity = 0,
|
CurrentQuantity = 0,
|
||||||
Inventory = inventory,
|
Inventory = inventory,
|
||||||
Memo = $"Expired on {inventory.ExpirationDate.ToShortDateString()}",
|
Memo = $"Shreded on {inventory.ShredReadyDate.ToShortDateString()}",
|
||||||
TransactionDate = dd,
|
TransactionDate = dd,
|
||||||
Timestamp = dd
|
Timestamp = dd
|
||||||
};
|
};
|
||||||
@@ -275,7 +158,7 @@ namespace InventoryTraker.Web.Migrations
|
|||||||
}
|
}
|
||||||
else if (r.Next(0, 40) == 0)
|
else if (r.Next(0, 40) == 0)
|
||||||
{
|
{
|
||||||
var lossQty = r.Next(1, inventory.Quantity + 1);
|
var lossQty = 1;
|
||||||
var lossTransaction = new Transaction
|
var lossTransaction = new Transaction
|
||||||
{
|
{
|
||||||
TransactionType = TransactionType.Loss,
|
TransactionType = TransactionType.Loss,
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Models
|
|
||||||
{
|
|
||||||
public class DistributionReport
|
|
||||||
{
|
|
||||||
public TransactionViewModel[] Transactions;
|
|
||||||
|
|
||||||
public string Destination { get; set; }
|
|
||||||
|
|
||||||
public DateTime Date { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,26 +1,37 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Web.Mvc;
|
using AutoMapper;
|
||||||
using Heroic.AutoMapper;
|
|
||||||
using InventoryTraker.Web.Core;
|
using InventoryTraker.Web.Core;
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Models
|
namespace InventoryTraker.Web.Models
|
||||||
{
|
{
|
||||||
public class InventoryAddForm : IMapTo<Inventory>
|
public class InventoryAddForm
|
||||||
{
|
{
|
||||||
[HiddenInput(DisplayValue = false)]
|
|
||||||
[Required]
|
[Required]
|
||||||
public int InventoryTypeId { get; set; }
|
public string Id { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public DateTime ExpirationDate { get; set; }
|
public string ProgramName { get; set; }
|
||||||
|
|
||||||
[Required, Range(1, int.MaxValue, ErrorMessage = "Quantity must be greater than 0")]
|
public string ProgramSubtype { get; set; }
|
||||||
public int Quantity { get; set; }
|
|
||||||
|
|
||||||
[Required, Display(Name = "Arrival Date")]
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public DateTime ShredReadyDate { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
public DateTime AddedDate { get; set; }
|
public DateTime AddedDate { get; set; }
|
||||||
|
|
||||||
public string Memo { get; set; }
|
public string Memo { get; set; }
|
||||||
|
|
||||||
|
public class AutoMapperProfile : Profile
|
||||||
|
{
|
||||||
|
public AutoMapperProfile()
|
||||||
|
{
|
||||||
|
CreateMap<InventoryAddForm, Inventory>()
|
||||||
|
.AfterMap((form, inventory) => { inventory.Quantity = 1; });
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Models
|
|
||||||
{
|
|
||||||
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; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,7 @@ namespace InventoryTraker.Web.Models
|
|||||||
public class InventoryQuantityForm
|
public class InventoryQuantityForm
|
||||||
{
|
{
|
||||||
[Required]
|
[Required]
|
||||||
public int InventoryId { get; set; }
|
public string InventoryId { get; set; }
|
||||||
|
|
||||||
[Required, Range(1, int.MaxValue, ErrorMessage = "Quantity must be greater than 0")]
|
[Required, Range(1, int.MaxValue, ErrorMessage = "Quantity must be greater than 0")]
|
||||||
public int Quantity { get; set; }
|
public int Quantity { get; set; }
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace InventoryTraker.Web.Models
|
|||||||
public class InventoryRemoveForm
|
public class InventoryRemoveForm
|
||||||
{
|
{
|
||||||
[Required]
|
[Required]
|
||||||
public int InventoryId { get; set; }
|
public string InventoryId { get; set; }
|
||||||
|
|
||||||
[Required, Range(1, int.MaxValue, ErrorMessage = "Quantity must be greater than 0")]
|
[Required, Range(1, int.MaxValue, ErrorMessage = "Quantity must be greater than 0")]
|
||||||
public int Quantity { get; set; }
|
public int Quantity { get; set; }
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
using InventoryTraker.Web.Core;
|
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Models
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.Web.Mvc;
|
|
||||||
using Heroic.AutoMapper;
|
|
||||||
using InventoryTraker.Web.Core;
|
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Models
|
|
||||||
{
|
|
||||||
public class InventoryTypeViewModel : IMapFrom<InventoryType>, IMapTo<InventoryType>
|
|
||||||
{
|
|
||||||
[HiddenInput]
|
|
||||||
public int Id { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string Identifier { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public int UnitsPerCase { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public string ContainerType { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public double WeightPerCase { get; set; }
|
|
||||||
|
|
||||||
[Required]
|
|
||||||
public decimal PricePerCase { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,46 +1,33 @@
|
|||||||
using System;
|
using System;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using Heroic.AutoMapper;
|
|
||||||
using InventoryTraker.Web.Core;
|
using InventoryTraker.Web.Core;
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Models
|
namespace InventoryTraker.Web.Models
|
||||||
{
|
{
|
||||||
public class InventoryViewModel : IMapFrom<Inventory>, IHaveCustomMappings
|
public class InventoryViewModel
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public string Id { get; set; }
|
||||||
|
|
||||||
public int InventoryTypeId { get; set; }
|
public DateTime ShredReadyDate { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
public int UnitsPerCase { get; set; }
|
|
||||||
|
|
||||||
public string ContainerType { get; set; }
|
|
||||||
|
|
||||||
public double WeightPerCase { get; set; }
|
|
||||||
|
|
||||||
public decimal PricePerCase { get; set; }
|
|
||||||
|
|
||||||
public int Quantity { get; set; }
|
|
||||||
|
|
||||||
public DateTime ExpirationDate { get; set; }
|
|
||||||
|
|
||||||
public DateTime AddedDate { get; set; }
|
public DateTime AddedDate { get; set; }
|
||||||
|
|
||||||
|
public int Quantity { get; set; }
|
||||||
|
|
||||||
public string Memo { get; set; }
|
public string Memo { get; set; }
|
||||||
|
|
||||||
public bool IsExpired => ExpirationDate < DateTime.Today;
|
public string ProgramName { get; set; }
|
||||||
|
|
||||||
public void CreateMappings(IMapperConfiguration configuration)
|
public string ProgramSubtype { get; set; }
|
||||||
|
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
public class AutoMapperProfile : Profile
|
||||||
{
|
{
|
||||||
configuration.CreateMap<Inventory, InventoryViewModel>()
|
public AutoMapperProfile()
|
||||||
.ForMember(d => d.InventoryTypeId, opt => opt.MapFrom(s => s.InventoryType.Id))
|
{
|
||||||
.ForMember(d => d.Name, opt => opt.MapFrom(s => s.InventoryType.Name))
|
CreateMap<Inventory, InventoryViewModel>();
|
||||||
.ForMember(d => d.UnitsPerCase, opt => opt.MapFrom(s => s.InventoryType.UnitsPerCase))
|
}
|
||||||
.ForMember(d => d.ContainerType, opt => opt.MapFrom(s => s.InventoryType.ContainerType))
|
|
||||||
.ForMember(d => d.WeightPerCase, opt => opt.MapFrom(s => s.InventoryType.WeightPerCase))
|
|
||||||
.ForMember(d => d.PricePerCase, opt => opt.MapFrom(s => s.InventoryType.PricePerCase))
|
|
||||||
.ForMember(d => d.AddedDate, opt => opt.MapFrom(s => s.AddedDate));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Models
|
|
||||||
{
|
|
||||||
public class MovementReport
|
|
||||||
{
|
|
||||||
public DateTime Month { get; set; }
|
|
||||||
public IEnumerable<MovementReportItem> Items { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
namespace InventoryTraker.Web.Models
|
|
||||||
{
|
|
||||||
public class MovementReportItem
|
|
||||||
{
|
|
||||||
public InventoryTypeViewModel InventoryType { get; set; }
|
|
||||||
public int BeginningQuantity { get; set; }
|
|
||||||
public int AddedQuantity { get; set; }
|
|
||||||
public int TotalAvailableQuantity { get; set; }
|
|
||||||
public int DistributedQuantity { get; set; }
|
|
||||||
public int AdjustmentQuantity { get; set; }
|
|
||||||
public int EndingQuantity { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +1,42 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using Heroic.AutoMapper;
|
|
||||||
using InventoryTraker.Web.Core;
|
using InventoryTraker.Web.Core;
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Models
|
namespace InventoryTraker.Web.Models
|
||||||
{
|
{
|
||||||
public class ProfileForm : IMapFrom<User>, IHaveCustomMappings
|
public class ProfileForm
|
||||||
{
|
{
|
||||||
[Required, Display(Name = "Full Name", Prompt = "Full Name (ex: John Doe)...")]
|
[Required]
|
||||||
public string FullName { get; set; }
|
[StringLength(128)]
|
||||||
|
[RegularExpression(@"[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Need complete name")]
|
||||||
|
public string UserName { get; set; }
|
||||||
|
|
||||||
[Required, DataType(DataType.EmailAddress), Display(Prompt = "your@email.com...")]
|
[Required]
|
||||||
public string EmailAddress { get; set; }
|
[DataType(DataType.EmailAddress)]
|
||||||
|
[RegularExpression(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}", ErrorMessage = "Must be an email address")]
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
public void CreateMappings(IMapperConfiguration configuration)
|
[DataType(DataType.Password)]
|
||||||
|
public string CurrentPassword { get; set; }
|
||||||
|
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
public string NewPassword { get; set; }
|
||||||
|
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Compare("NewPassword")]
|
||||||
|
public string ConfirmPassword { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
{
|
{
|
||||||
configuration.CreateMap<User, ProfileForm>()
|
return $"UserName: {UserName}, email: {Email}";
|
||||||
.ForMember(d => d.FullName, opt => opt.MapFrom(s => s.UserName))
|
}
|
||||||
.ForMember(d => d.EmailAddress, opt => opt.MapFrom(s => s.Email));
|
|
||||||
|
public class AutoMapperProfile : Profile
|
||||||
|
{
|
||||||
|
public AutoMapperProfile()
|
||||||
|
{
|
||||||
|
CreateMap<User, ProfileForm>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,25 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using Heroic.AutoMapper;
|
|
||||||
using InventoryTraker.Web.Core;
|
using InventoryTraker.Web.Core;
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Models
|
namespace InventoryTraker.Web.Models
|
||||||
{
|
{
|
||||||
public class TransactionViewModel : IMapFrom<Transaction>, IHaveCustomMappings
|
public class TransactionViewModel
|
||||||
{
|
{
|
||||||
[Required]
|
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public int InventoryId { get; set; }
|
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string InventoryId { get; set; }
|
||||||
public int UnitsPerCase { get; set; }
|
|
||||||
public string ContainerType { get; set; }
|
public string ProgramName { get; set; }
|
||||||
public DateTime ExpirationDate { get; set; }
|
|
||||||
|
public string ProgramSubtype { get; set; }
|
||||||
|
|
||||||
|
public string Description { get; set; }
|
||||||
|
|
||||||
|
public DateTime ShredReadyDate { get; set; }
|
||||||
|
|
||||||
public DateTime AddedDate { get; set; }
|
public DateTime AddedDate { get; set; }
|
||||||
public double WeightPerCase { get; set; }
|
|
||||||
|
|
||||||
public string TransactionType { get; set; }
|
public string TransactionType { get; set; }
|
||||||
|
|
||||||
@@ -33,27 +35,25 @@ namespace InventoryTraker.Web.Models
|
|||||||
|
|
||||||
public string Memo { get; set; }
|
public string Memo { get; set; }
|
||||||
|
|
||||||
public string Destination { get; set; }
|
|
||||||
|
|
||||||
public DateTime Timestamp { get; set; }
|
public DateTime Timestamp { get; set; }
|
||||||
|
|
||||||
public void CreateMappings(IMapperConfiguration configuration)
|
public class AutoMapperProfile : Profile
|
||||||
{
|
{
|
||||||
configuration.CreateMap<Transaction, TransactionViewModel>()
|
public AutoMapperProfile()
|
||||||
|
{
|
||||||
|
CreateMap<Transaction, TransactionViewModel>()
|
||||||
.ForMember(d => d.InventoryId,
|
.ForMember(d => d.InventoryId,
|
||||||
opt => opt.MapFrom(s => s.Inventory.Id))
|
opt => opt.MapFrom(s => s.Inventory.Id))
|
||||||
.ForMember(d => d.Name,
|
.ForMember(d => d.ProgramName,
|
||||||
opt => opt.MapFrom(s => s.Inventory.InventoryType.Name))
|
opt => opt.MapFrom(s => s.Inventory.ProgramName))
|
||||||
.ForMember(d => d.ExpirationDate,
|
.ForMember(d => d.ProgramSubtype,
|
||||||
opt => opt.MapFrom(s => s.Inventory.ExpirationDate))
|
opt => opt.MapFrom(s => s.Inventory.ProgramSubtype))
|
||||||
|
.ForMember(d => d.Description,
|
||||||
|
opt => opt.MapFrom(s => s.Inventory.Description))
|
||||||
|
.ForMember(d => d.ShredReadyDate,
|
||||||
|
opt => opt.MapFrom(s => s.Inventory.ShredReadyDate))
|
||||||
.ForMember(d => d.AddedDate,
|
.ForMember(d => d.AddedDate,
|
||||||
opt => opt.MapFrom(s => s.Inventory.AddedDate))
|
opt => opt.MapFrom(s => s.Inventory.AddedDate))
|
||||||
.ForMember(d => d.UnitsPerCase,
|
|
||||||
opt => opt.MapFrom(s => s.Inventory.InventoryType.UnitsPerCase))
|
|
||||||
.ForMember(d => d.ContainerType,
|
|
||||||
opt => opt.MapFrom(s => s.Inventory.InventoryType.ContainerType))
|
|
||||||
.ForMember(d => d.WeightPerCase,
|
|
||||||
opt => opt.MapFrom(s => s.Inventory.InventoryType.WeightPerCase))
|
|
||||||
.ForMember(d => d.TransactionType,
|
.ForMember(d => d.TransactionType,
|
||||||
opt => opt.MapFrom(s => s.TransactionType.ToString()))
|
opt => opt.MapFrom(s => s.TransactionType.ToString()))
|
||||||
.ForMember(d => d.PreviousQuantity,
|
.ForMember(d => d.PreviousQuantity,
|
||||||
@@ -61,3 +61,4 @@ namespace InventoryTraker.Web.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Models
|
||||||
|
{
|
||||||
|
public class UserCreateForm
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
[StringLength(128)]
|
||||||
|
[RegularExpression(@"[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Need complete name")]
|
||||||
|
public string UserName { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[DataType(DataType.EmailAddress)]
|
||||||
|
[RegularExpression(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}", ErrorMessage = "Must be an email address")]
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
public string Password { get; set; }
|
||||||
|
|
||||||
|
[Required(ErrorMessage = "Confirm Password is required")]
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Compare("Password")]
|
||||||
|
public string ConfirmPassword { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"UserName: {UserName}, email: {Email}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Models
|
||||||
|
{
|
||||||
|
public class UserEditForm
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
[StringLength(128)]
|
||||||
|
[RegularExpression(@"[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Need complete name")]
|
||||||
|
public string UserName { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[DataType(DataType.EmailAddress)]
|
||||||
|
[RegularExpression(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}", ErrorMessage = "Must be an email address")]
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
|
//[Required]
|
||||||
|
public bool Administrator { get; set; }
|
||||||
|
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
public string Password { get; set; }
|
||||||
|
|
||||||
|
[DataType(DataType.Password)]
|
||||||
|
[Compare("Password")]
|
||||||
|
public string ConfirmPassword { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"UserName: {UserName}, email: {Email}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using AutoMapper;
|
||||||
|
using InventoryTraker.Web.Core;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Models
|
||||||
|
{
|
||||||
|
public class UserViewModel
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
[StringLength(128)]
|
||||||
|
[RegularExpression(@"[A-Za-z().]+(\s+[A-Za-z().]+)+", ErrorMessage = "Need complete name")]
|
||||||
|
public string UserName { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
[DataType(DataType.EmailAddress)]
|
||||||
|
[RegularExpression(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}", ErrorMessage = "Must be an email address")]
|
||||||
|
public string Email { get; set; }
|
||||||
|
|
||||||
|
public bool Administrator { get; set; }
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"UserName: {UserName}, email: {Email}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AutoMapperProfile : Profile
|
||||||
|
{
|
||||||
|
public AutoMapperProfile()
|
||||||
|
{
|
||||||
|
CreateMap<User, UserViewModel>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,8 +16,8 @@
|
|||||||
for information on customizing logging rules and outputs.
|
for information on customizing logging rules and outputs.
|
||||||
-->
|
-->
|
||||||
<targets>
|
<targets>
|
||||||
<target name="debugLogger" xsi:type="File" fileName="${basedir}/../logs/Debug.${shortdate}.txt" />
|
<target name="debugLogger" xsi:type="File" fileName="${basedir}/../logs/InventoryTraker-Box/Debug.${shortdate}.txt" />
|
||||||
<target name="exceptionLogger" xsi:type="File" fileName="${basedir}/../logs/Error.${shortdate}.txt" />
|
<target name="exceptionLogger" xsi:type="File" fileName="${basedir}/../logs/InventoryTraker-Box/Error.${shortdate}.txt" />
|
||||||
</targets>
|
</targets>
|
||||||
<rules>
|
<rules>
|
||||||
<logger name="*" minlevel="Debug" writeTo="debugLogger" />
|
<logger name="*" minlevel="Debug" writeTo="debugLogger" />
|
||||||
|
|||||||
@@ -531,6 +531,7 @@
|
|||||||
<xs:element name="useDefaultRowHighlightingRules" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
<xs:element name="useDefaultRowHighlightingRules" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
||||||
<xs:element name="highlight-row" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.ConsoleRowHighlightingRule" />
|
<xs:element name="highlight-row" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.ConsoleRowHighlightingRule" />
|
||||||
<xs:element name="highlight-word" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.ConsoleWordHighlightingRule" />
|
<xs:element name="highlight-word" minOccurs="0" maxOccurs="unbounded" type="NLog.Targets.ConsoleWordHighlightingRule" />
|
||||||
|
<xs:element name="detectConsoleAvailable" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
||||||
<xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" />
|
<xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" />
|
||||||
<xs:element name="errorStream" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
<xs:element name="errorStream" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
||||||
</xs:choice>
|
</xs:choice>
|
||||||
@@ -559,6 +560,11 @@
|
|||||||
<xs:documentation>Indicates whether to use default row highlighting rules.</xs:documentation>
|
<xs:documentation>Indicates whether to use default row highlighting rules.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
|
<xs:attribute name="detectConsoleAvailable" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Indicates whether to auto-check if the console is available. - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App)</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
<xs:attribute name="encoding" type="xs:string">
|
<xs:attribute name="encoding" type="xs:string">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>The encoding for writing messages to the .</xs:documentation>
|
<xs:documentation>The encoding for writing messages to the .</xs:documentation>
|
||||||
@@ -670,6 +676,7 @@
|
|||||||
<xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" />
|
<xs:element name="header" minOccurs="0" maxOccurs="1" type="Layout" />
|
||||||
<xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" />
|
<xs:element name="footer" minOccurs="0" maxOccurs="1" type="Layout" />
|
||||||
<xs:element name="error" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
<xs:element name="error" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
||||||
|
<xs:element name="detectConsoleAvailable" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
||||||
<xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" />
|
<xs:element name="encoding" minOccurs="0" maxOccurs="1" type="xs:string" />
|
||||||
</xs:choice>
|
</xs:choice>
|
||||||
<xs:attribute name="name" type="xs:string">
|
<xs:attribute name="name" type="xs:string">
|
||||||
@@ -697,6 +704,11 @@
|
|||||||
<xs:documentation>Indicates whether to send the log messages to the standard error instead of the standard output.</xs:documentation>
|
<xs:documentation>Indicates whether to send the log messages to the standard error instead of the standard output.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
|
<xs:attribute name="detectConsoleAvailable" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Indicates whether to auto-check if the console is available - Disables console writing if Environment.UserInteractive = False (Windows Service) - Disables console writing if Console Standard Input is not available (Non-Console-App)</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
<xs:attribute name="encoding" type="xs:string">
|
<xs:attribute name="encoding" type="xs:string">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>The encoding for writing messages to the .</xs:documentation>
|
<xs:documentation>The encoding for writing messages to the .</xs:documentation>
|
||||||
@@ -1031,6 +1043,7 @@
|
|||||||
<xs:element name="archiveFileKind" minOccurs="0" maxOccurs="1" type="NLog.Targets.FilePathKind" />
|
<xs:element name="archiveFileKind" minOccurs="0" maxOccurs="1" type="NLog.Targets.FilePathKind" />
|
||||||
<xs:element name="cleanupFileName" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
<xs:element name="cleanupFileName" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
||||||
<xs:element name="forceManaged" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
<xs:element name="forceManaged" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
||||||
|
<xs:element name="writeFooterOnArchivingOnly" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
||||||
<xs:element name="fileName" minOccurs="0" maxOccurs="1" type="Layout" />
|
<xs:element name="fileName" minOccurs="0" maxOccurs="1" type="Layout" />
|
||||||
<xs:element name="archiveDateFormat" minOccurs="0" maxOccurs="1" type="xs:string" />
|
<xs:element name="archiveDateFormat" minOccurs="0" maxOccurs="1" type="xs:string" />
|
||||||
<xs:element name="archiveOldFileOnStartup" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
<xs:element name="archiveOldFileOnStartup" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
||||||
@@ -1039,7 +1052,7 @@
|
|||||||
<xs:element name="fileAttributes" minOccurs="0" maxOccurs="1" type="NLog.Targets.Win32FileAttributes" />
|
<xs:element name="fileAttributes" minOccurs="0" maxOccurs="1" type="NLog.Targets.Win32FileAttributes" />
|
||||||
<xs:element name="deleteOldFileOnStartup" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
<xs:element name="deleteOldFileOnStartup" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
||||||
<xs:element name="replaceFileContentsOnEachWrite" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
<xs:element name="replaceFileContentsOnEachWrite" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
||||||
<xs:element name="concurrentWriteAttemptDelay" minOccurs="0" maxOccurs="1" type="xs:integer" />
|
<xs:element name="concurrentWrites" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
||||||
<xs:element name="keepFileOpen" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
<xs:element name="keepFileOpen" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
||||||
<xs:element name="maxLogFilenames" minOccurs="0" maxOccurs="1" type="xs:integer" />
|
<xs:element name="maxLogFilenames" minOccurs="0" maxOccurs="1" type="xs:integer" />
|
||||||
<xs:element name="networkWrites" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
<xs:element name="networkWrites" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
||||||
@@ -1047,8 +1060,8 @@
|
|||||||
<xs:element name="openFileCacheTimeout" minOccurs="0" maxOccurs="1" type="xs:integer" />
|
<xs:element name="openFileCacheTimeout" minOccurs="0" maxOccurs="1" type="xs:integer" />
|
||||||
<xs:element name="bufferSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
|
<xs:element name="bufferSize" minOccurs="0" maxOccurs="1" type="xs:integer" />
|
||||||
<xs:element name="autoFlush" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
<xs:element name="autoFlush" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
||||||
|
<xs:element name="concurrentWriteAttemptDelay" minOccurs="0" maxOccurs="1" type="xs:integer" />
|
||||||
<xs:element name="concurrentWriteAttempts" minOccurs="0" maxOccurs="1" type="xs:integer" />
|
<xs:element name="concurrentWriteAttempts" minOccurs="0" maxOccurs="1" type="xs:integer" />
|
||||||
<xs:element name="concurrentWrites" minOccurs="0" maxOccurs="1" type="xs:boolean" />
|
|
||||||
</xs:choice>
|
</xs:choice>
|
||||||
<xs:attribute name="name" type="xs:string">
|
<xs:attribute name="name" type="xs:string">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
@@ -1130,6 +1143,11 @@
|
|||||||
<xs:documentation>Gets or set a value indicating whether a managed file stream is forced, instead of used the native implementation.</xs:documentation>
|
<xs:documentation>Gets or set a value indicating whether a managed file stream is forced, instead of used the native implementation.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
|
<xs:attribute name="writeFooterOnArchivingOnly" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Indicates whether the footer should be written only when the file is archived.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
<xs:attribute name="fileName" type="SimpleLayoutAttribute">
|
<xs:attribute name="fileName" type="SimpleLayoutAttribute">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>Name of the file to write to.</xs:documentation>
|
<xs:documentation>Name of the file to write to.</xs:documentation>
|
||||||
@@ -1170,9 +1188,9 @@
|
|||||||
<xs:documentation>Indicates whether to replace file contents on each write instead of appending log message at the end.</xs:documentation>
|
<xs:documentation>Indicates whether to replace file contents on each write instead of appending log message at the end.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
<xs:attribute name="concurrentWriteAttemptDelay" type="xs:integer">
|
<xs:attribute name="concurrentWrites" type="xs:boolean">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>Delay in milliseconds to wait before attempting to write to the file again.</xs:documentation>
|
<xs:documentation>Indicates whether concurrent writes to the log file by multiple processes on the same host.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
<xs:attribute name="keepFileOpen" type="xs:boolean">
|
<xs:attribute name="keepFileOpen" type="xs:boolean">
|
||||||
@@ -1210,16 +1228,16 @@
|
|||||||
<xs:documentation>Indicates whether to automatically flush the file buffers after each log message.</xs:documentation>
|
<xs:documentation>Indicates whether to automatically flush the file buffers after each log message.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
|
<xs:attribute name="concurrentWriteAttemptDelay" type="xs:integer">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Delay in milliseconds to wait before attempting to write to the file again.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
<xs:attribute name="concurrentWriteAttempts" type="xs:integer">
|
<xs:attribute name="concurrentWriteAttempts" type="xs:integer">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
<xs:documentation>Number of times the write is appended on the file before NLog discards the log message.</xs:documentation>
|
<xs:documentation>Number of times the write is appended on the file before NLog discards the log message.</xs:documentation>
|
||||||
</xs:annotation>
|
</xs:annotation>
|
||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
<xs:attribute name="concurrentWrites" type="xs:boolean">
|
|
||||||
<xs:annotation>
|
|
||||||
<xs:documentation>Indicates whether concurrent writes to the log file by multiple processes on the same host.</xs:documentation>
|
|
||||||
</xs:annotation>
|
|
||||||
</xs:attribute>
|
|
||||||
</xs:extension>
|
</xs:extension>
|
||||||
</xs:complexContent>
|
</xs:complexContent>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ by editing this MSBuild file. In order to learn more about this please visit htt
|
|||||||
<SiteUrlToLaunchAfterPublish />
|
<SiteUrlToLaunchAfterPublish />
|
||||||
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
|
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
|
||||||
<ExcludeApp_Data>False</ExcludeApp_Data>
|
<ExcludeApp_Data>False</ExcludeApp_Data>
|
||||||
<DesktopBuildPackageLocation>C:\Users\poprhythm\Documents\code\PublishPackages\InventoryTraker.Web.zip</DesktopBuildPackageLocation>
|
<DesktopBuildPackageLocation>C:\Users\poprhythm\Documents\code\PublishPackages\InventoryTraker-Box.Web.zip</DesktopBuildPackageLocation>
|
||||||
<PackageAsSingleFile>true</PackageAsSingleFile>
|
<PackageAsSingleFile>true</PackageAsSingleFile>
|
||||||
<DeployIisAppPath>Default Web Site</DeployIisAppPath>
|
<DeployIisAppPath>InventoryTraker-Box</DeployIisAppPath>
|
||||||
<PublishDatabaseSettings>
|
<PublishDatabaseSettings>
|
||||||
<Objects xmlns="">
|
<Objects xmlns="">
|
||||||
<ObjectGroup Name="DefaultConnection" Order="1" Enabled="True">
|
<ObjectGroup Name="DefaultConnection" Order="1" Enabled="True">
|
||||||
<Destination Path="Data Source=localhost;Initial Catalog=InventoryTraker;User ID=InventoryTrakerUser;Password=QcXxvpztGp1;Connect Timeout=60" Name="Data Source=localhost;Initial Catalog=InventoryTraker;User Id=InventoryTrakerUser;Password=QcXxvpztGp1;Connect Timeout=60" />
|
<Destination Path="Data Source=localhost;Initial Catalog=InventoryTraker-Box;User ID=InventoryTraker-BoxUser;Password=QcXxvpztGp3;Connect Timeout=60" Name="Data Source=localhost;Initial Catalog=InventoryTraker-Box;User Id=InventoryTraker-BoxUser;Password=QcXxvpztGp3;Connect Timeout=60" />
|
||||||
<Object Type="DbCodeFirst">
|
<Object Type="DbCodeFirst">
|
||||||
<Source Path="DBMigration" DbContext="InventoryTraker.Web.Data.AppDbContext, InventoryTraker.Web" MigrationConfiguration="InventoryTraker.Web.Migrations.Configuration, InventoryTraker.Web" Origin="Convention" />
|
<Source Path="DBMigration" DbContext="InventoryTraker.Web.Data.AppDbContext, InventoryTraker.Web" MigrationConfiguration="InventoryTraker.Web.Migrations.Configuration, InventoryTraker.Web" Origin="Convention" />
|
||||||
</Object>
|
</Object>
|
||||||
@@ -27,7 +27,7 @@ by editing this MSBuild file. In order to learn more about this please visit htt
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<MSDeployParameterValue Include="$(DeployParameterPrefix)DefaultConnection-Web.config Connection String">
|
<MSDeployParameterValue Include="$(DeployParameterPrefix)DefaultConnection-Web.config Connection String">
|
||||||
<ParameterValue>Data Source=localhost;Initial Catalog=InventoryTraker;User Id=InventoryTrakerUser;Password=QcXxvpztGp1;Connect Timeout=60</ParameterValue>
|
<ParameterValue>Data Source=localhost;Initial Catalog=InventoryTraker-Box;User Id=InventoryTraker-BoxUser;Password=QcXxvpztGp3;Connect Timeout=60</ParameterValue>
|
||||||
</MSDeployParameterValue>
|
</MSDeployParameterValue>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
+6
File diff suppressed because one or more lines are too long
@@ -0,0 +1,270 @@
|
|||||||
|
/* FileSaver.js
|
||||||
|
* A saveAs() FileSaver implementation.
|
||||||
|
* 1.1.20151003
|
||||||
|
*
|
||||||
|
* By Eli Grey, http://eligrey.com
|
||||||
|
* License: MIT
|
||||||
|
* See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*global self */
|
||||||
|
/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
|
||||||
|
|
||||||
|
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
|
||||||
|
|
||||||
|
var saveAs = saveAs || (function(view) {
|
||||||
|
"use strict";
|
||||||
|
// IE <10 is explicitly unsupported
|
||||||
|
if (typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var
|
||||||
|
doc = view.document
|
||||||
|
// only get URL when necessary in case Blob.js hasn't overridden it yet
|
||||||
|
, get_URL = function() {
|
||||||
|
return view.URL || view.webkitURL || view;
|
||||||
|
}
|
||||||
|
, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
|
||||||
|
, can_use_save_link = "download" in save_link
|
||||||
|
, click = function(node) {
|
||||||
|
var event = new MouseEvent("click");
|
||||||
|
node.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
, is_safari = /Version\/[\d\.]+.*Safari/.test(navigator.userAgent)
|
||||||
|
, webkit_req_fs = view.webkitRequestFileSystem
|
||||||
|
, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
|
||||||
|
, throw_outside = function(ex) {
|
||||||
|
(view.setImmediate || view.setTimeout)(function() {
|
||||||
|
throw ex;
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
, force_saveable_type = "application/octet-stream"
|
||||||
|
, fs_min_size = 0
|
||||||
|
// See https://code.google.com/p/chromium/issues/detail?id=375297#c7 and
|
||||||
|
// https://github.com/eligrey/FileSaver.js/commit/485930a#commitcomment-8768047
|
||||||
|
// for the reasoning behind the timeout and revocation flow
|
||||||
|
, arbitrary_revoke_timeout = 500 // in ms
|
||||||
|
, revoke = function(file) {
|
||||||
|
var revoker = function() {
|
||||||
|
if (typeof file === "string") { // file is an object URL
|
||||||
|
get_URL().revokeObjectURL(file);
|
||||||
|
} else { // file is a File
|
||||||
|
file.remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (view.chrome) {
|
||||||
|
revoker();
|
||||||
|
} else {
|
||||||
|
setTimeout(revoker, arbitrary_revoke_timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, dispatch = function(filesaver, event_types, event) {
|
||||||
|
event_types = [].concat(event_types);
|
||||||
|
var i = event_types.length;
|
||||||
|
while (i--) {
|
||||||
|
var listener = filesaver["on" + event_types[i]];
|
||||||
|
if (typeof listener === "function") {
|
||||||
|
try {
|
||||||
|
listener.call(filesaver, event || filesaver);
|
||||||
|
} catch (ex) {
|
||||||
|
throw_outside(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
, auto_bom = function(blob) {
|
||||||
|
// prepend BOM for UTF-8 XML and text/* types (including HTML)
|
||||||
|
if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
|
||||||
|
return new Blob(["\ufeff", blob], {type: blob.type});
|
||||||
|
}
|
||||||
|
return blob;
|
||||||
|
}
|
||||||
|
, FileSaver = function(blob, name, no_auto_bom) {
|
||||||
|
if (!no_auto_bom) {
|
||||||
|
blob = auto_bom(blob);
|
||||||
|
}
|
||||||
|
// First try a.download, then web filesystem, then object URLs
|
||||||
|
var
|
||||||
|
filesaver = this
|
||||||
|
, type = blob.type
|
||||||
|
, blob_changed = false
|
||||||
|
, object_url
|
||||||
|
, target_view
|
||||||
|
, dispatch_all = function() {
|
||||||
|
dispatch(filesaver, "writestart progress write writeend".split(" "));
|
||||||
|
}
|
||||||
|
// on any filesys errors revert to saving with object URLs
|
||||||
|
, fs_error = function() {
|
||||||
|
if (target_view && is_safari && typeof FileReader !== "undefined") {
|
||||||
|
// Safari doesn't allow downloading of blob urls
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onloadend = function() {
|
||||||
|
var base64Data = reader.result;
|
||||||
|
target_view.location.href = "data:attachment/file" + base64Data.slice(base64Data.search(/[,;]/));
|
||||||
|
filesaver.readyState = filesaver.DONE;
|
||||||
|
dispatch_all();
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(blob);
|
||||||
|
filesaver.readyState = filesaver.INIT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// don't create more object URLs than needed
|
||||||
|
if (blob_changed || !object_url) {
|
||||||
|
object_url = get_URL().createObjectURL(blob);
|
||||||
|
}
|
||||||
|
if (target_view) {
|
||||||
|
target_view.location.href = object_url;
|
||||||
|
} else {
|
||||||
|
var new_tab = view.open(object_url, "_blank");
|
||||||
|
if (new_tab == undefined && is_safari) {
|
||||||
|
//Apple do not allow window.open, see http://bit.ly/1kZffRI
|
||||||
|
view.location.href = object_url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filesaver.readyState = filesaver.DONE;
|
||||||
|
dispatch_all();
|
||||||
|
revoke(object_url);
|
||||||
|
}
|
||||||
|
, abortable = function(func) {
|
||||||
|
return function() {
|
||||||
|
if (filesaver.readyState !== filesaver.DONE) {
|
||||||
|
return func.apply(this, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
, create_if_not_found = {create: true, exclusive: false}
|
||||||
|
, slice
|
||||||
|
;
|
||||||
|
filesaver.readyState = filesaver.INIT;
|
||||||
|
if (!name) {
|
||||||
|
name = "download";
|
||||||
|
}
|
||||||
|
if (can_use_save_link) {
|
||||||
|
object_url = get_URL().createObjectURL(blob);
|
||||||
|
save_link.href = object_url;
|
||||||
|
save_link.download = name;
|
||||||
|
setTimeout(function() {
|
||||||
|
click(save_link);
|
||||||
|
dispatch_all();
|
||||||
|
revoke(object_url);
|
||||||
|
filesaver.readyState = filesaver.DONE;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Object and web filesystem URLs have a problem saving in Google Chrome when
|
||||||
|
// viewed in a tab, so I force save with application/octet-stream
|
||||||
|
// http://code.google.com/p/chromium/issues/detail?id=91158
|
||||||
|
// Update: Google errantly closed 91158, I submitted it again:
|
||||||
|
// https://code.google.com/p/chromium/issues/detail?id=389642
|
||||||
|
if (view.chrome && type && type !== force_saveable_type) {
|
||||||
|
slice = blob.slice || blob.webkitSlice;
|
||||||
|
blob = slice.call(blob, 0, blob.size, force_saveable_type);
|
||||||
|
blob_changed = true;
|
||||||
|
}
|
||||||
|
// Since I can't be sure that the guessed media type will trigger a download
|
||||||
|
// in WebKit, I append .download to the filename.
|
||||||
|
// https://bugs.webkit.org/show_bug.cgi?id=65440
|
||||||
|
if (webkit_req_fs && name !== "download") {
|
||||||
|
name += ".download";
|
||||||
|
}
|
||||||
|
if (type === force_saveable_type || webkit_req_fs) {
|
||||||
|
target_view = view;
|
||||||
|
}
|
||||||
|
if (!req_fs) {
|
||||||
|
fs_error();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fs_min_size += blob.size;
|
||||||
|
req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
|
||||||
|
fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
|
||||||
|
var save = function() {
|
||||||
|
dir.getFile(name, create_if_not_found, abortable(function(file) {
|
||||||
|
file.createWriter(abortable(function(writer) {
|
||||||
|
writer.onwriteend = function(event) {
|
||||||
|
target_view.location.href = file.toURL();
|
||||||
|
filesaver.readyState = filesaver.DONE;
|
||||||
|
dispatch(filesaver, "writeend", event);
|
||||||
|
revoke(file);
|
||||||
|
};
|
||||||
|
writer.onerror = function() {
|
||||||
|
var error = writer.error;
|
||||||
|
if (error.code !== error.ABORT_ERR) {
|
||||||
|
fs_error();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
"writestart progress write abort".split(" ").forEach(function(event) {
|
||||||
|
writer["on" + event] = filesaver["on" + event];
|
||||||
|
});
|
||||||
|
writer.write(blob);
|
||||||
|
filesaver.abort = function() {
|
||||||
|
writer.abort();
|
||||||
|
filesaver.readyState = filesaver.DONE;
|
||||||
|
};
|
||||||
|
filesaver.readyState = filesaver.WRITING;
|
||||||
|
}), fs_error);
|
||||||
|
}), fs_error);
|
||||||
|
};
|
||||||
|
dir.getFile(name, {create: false}, abortable(function(file) {
|
||||||
|
// delete file if it already exists
|
||||||
|
file.remove();
|
||||||
|
save();
|
||||||
|
}), abortable(function(ex) {
|
||||||
|
if (ex.code === ex.NOT_FOUND_ERR) {
|
||||||
|
save();
|
||||||
|
} else {
|
||||||
|
fs_error();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}), fs_error);
|
||||||
|
}), fs_error);
|
||||||
|
}
|
||||||
|
, FS_proto = FileSaver.prototype
|
||||||
|
, saveAs = function(blob, name, no_auto_bom) {
|
||||||
|
return new FileSaver(blob, name, no_auto_bom);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
// IE 10+ (native saveAs)
|
||||||
|
if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
|
||||||
|
return function(blob, name, no_auto_bom) {
|
||||||
|
if (!no_auto_bom) {
|
||||||
|
blob = auto_bom(blob);
|
||||||
|
}
|
||||||
|
return navigator.msSaveOrOpenBlob(blob, name || "download");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
FS_proto.abort = function() {
|
||||||
|
var filesaver = this;
|
||||||
|
filesaver.readyState = filesaver.DONE;
|
||||||
|
dispatch(filesaver, "abort");
|
||||||
|
};
|
||||||
|
FS_proto.readyState = FS_proto.INIT = 0;
|
||||||
|
FS_proto.WRITING = 1;
|
||||||
|
FS_proto.DONE = 2;
|
||||||
|
|
||||||
|
FS_proto.error =
|
||||||
|
FS_proto.onwritestart =
|
||||||
|
FS_proto.onprogress =
|
||||||
|
FS_proto.onwrite =
|
||||||
|
FS_proto.onabort =
|
||||||
|
FS_proto.onerror =
|
||||||
|
FS_proto.onwriteend =
|
||||||
|
null;
|
||||||
|
|
||||||
|
return saveAs;
|
||||||
|
}(
|
||||||
|
typeof self !== "undefined" && self
|
||||||
|
|| typeof window !== "undefined" && window
|
||||||
|
|| this.content
|
||||||
|
));
|
||||||
|
// `self` is undefined in Firefox for Android content script context
|
||||||
|
// while `this` is nsIContentFrameMessageManager
|
||||||
|
// with an attribute `content` that corresponds to the window
|
||||||
|
|
||||||
|
if (typeof module !== "undefined" && module.exports) {
|
||||||
|
module.exports.saveAs = saveAs;
|
||||||
|
} else if ((typeof define !== "undefined" && define !== null) && (define.amd != null)) {
|
||||||
|
define([], function() {
|
||||||
|
return saveAs;
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
|
||||||
|
var saveAs=saveAs||function(e){"use strict";if(typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),i="download"in r,o=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},a=/Version\/[\d\.]+.*Safari/.test(navigator.userAgent),f=e.webkitRequestFileSystem,u=e.requestFileSystem||f||e.mozRequestFileSystem,s=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},c="application/octet-stream",d=0,l=500,w=function(t){var r=function(){if(typeof t==="string"){n().revokeObjectURL(t)}else{t.remove()}};if(e.chrome){r()}else{setTimeout(r,l)}},p=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var i=e["on"+t[r]];if(typeof i==="function"){try{i.call(e,n||e)}catch(o){s(o)}}}},v=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob(["\ufeff",e],{type:e.type})}return e},y=function(t,s,l){if(!l){t=v(t)}var y=this,m=t.type,S=false,h,R,O=function(){p(y,"writestart progress write writeend".split(" "))},g=function(){if(R&&a&&typeof FileReader!=="undefined"){var r=new FileReader;r.onloadend=function(){var e=r.result;R.location.href="data:attachment/file"+e.slice(e.search(/[,;]/));y.readyState=y.DONE;O()};r.readAsDataURL(t);y.readyState=y.INIT;return}if(S||!h){h=n().createObjectURL(t)}if(R){R.location.href=h}else{var i=e.open(h,"_blank");if(i==undefined&&a){e.location.href=h}}y.readyState=y.DONE;O();w(h)},b=function(e){return function(){if(y.readyState!==y.DONE){return e.apply(this,arguments)}}},E={create:true,exclusive:false},N;y.readyState=y.INIT;if(!s){s="download"}if(i){h=n().createObjectURL(t);r.href=h;r.download=s;setTimeout(function(){o(r);O();w(h);y.readyState=y.DONE});return}if(e.chrome&&m&&m!==c){N=t.slice||t.webkitSlice;t=N.call(t,0,t.size,c);S=true}if(f&&s!=="download"){s+=".download"}if(m===c||f){R=e}if(!u){g();return}d+=t.size;u(e.TEMPORARY,d,b(function(e){e.root.getDirectory("saved",E,b(function(e){var n=function(){e.getFile(s,E,b(function(e){e.createWriter(b(function(n){n.onwriteend=function(t){R.location.href=e.toURL();y.readyState=y.DONE;p(y,"writeend",t);w(e)};n.onerror=function(){var e=n.error;if(e.code!==e.ABORT_ERR){g()}};"writestart progress write abort".split(" ").forEach(function(e){n["on"+e]=y["on"+e]});n.write(t);y.abort=function(){n.abort();y.readyState=y.DONE};y.readyState=y.WRITING}),g)}),g)};e.getFile(s,{create:false},b(function(e){e.remove();n()}),b(function(e){if(e.code===e.NOT_FOUND_ERR){n()}else{g()}}))}),g)}),g)},m=y.prototype,S=function(e,t,n){return new y(e,t,n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){if(!n){e=v(e)}return navigator.msSaveOrOpenBlob(e,t||"download")}}m.abort=function(){var e=this;e.readyState=e.DONE;p(e,"abort")};m.readyState=m.INIT=0;m.WRITING=1;m.DONE=2;m.error=m.onwritestart=m.onprogress=m.onwrite=m.onabort=m.onerror=m.onwriteend=null;return S}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!=null){define([],function(){return saveAs})}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
+3640
-3198
File diff suppressed because it is too large
Load Diff
+4
-5
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* angular-strap
|
* angular-strap
|
||||||
* @version v2.3.1 - 2015-07-19
|
* @version v2.3.9 - 2016-06-10
|
||||||
* @link http://mgcrea.github.io/angular-strap
|
* @link http://mgcrea.github.io/angular-strap
|
||||||
* @author Olivier Louvignes <olivier@mg-crea.com> (https://github.com/mgcrea)
|
* @author Olivier Louvignes <olivier@mg-crea.com> (https://github.com/mgcrea)
|
||||||
* @license MIT License, http://www.opensource.org/licenses/MIT
|
* @license MIT License, http://www.opensource.org/licenses/MIT
|
||||||
@@ -8,36 +8,36 @@
|
|||||||
(function(window, document, undefined) {
|
(function(window, document, undefined) {
|
||||||
'use strict';
|
'use strict';
|
||||||
angular.module('mgcrea.ngStrap.alert').run([ '$templateCache', function($templateCache) {
|
angular.module('mgcrea.ngStrap.alert').run([ '$templateCache', function($templateCache) {
|
||||||
$templateCache.put('alert/alert.tpl.html', '<div class="alert" ng-class="[type ? \'alert-\' + type : null]"><button type="button" class="close" ng-if="dismissable" ng-click="$hide()">×</button> <strong ng-bind="title"></strong> <span ng-bind-html="content"></span></div>');
|
$templateCache.put('alert/alert.tpl.html', '<div class="alert" ng-class="[type ? \'alert-\' + type : null]"><button type="button" class="close" ng-if="dismissable" ng-click="$hide()">×</button> <span ng-if="title"><strong ng-bind="title"></strong> <span ng-bind-html="content"></span></span> <span ng-if="!title" ng-bind-html="content"></span></div>');
|
||||||
} ]);
|
} ]);
|
||||||
angular.module('mgcrea.ngStrap.aside').run([ '$templateCache', function($templateCache) {
|
angular.module('mgcrea.ngStrap.aside').run([ '$templateCache', function($templateCache) {
|
||||||
$templateCache.put('aside/aside.tpl.html', '<div class="aside" tabindex="-1" role="dialog"><div class="aside-dialog"><div class="aside-content"><div class="aside-header" ng-show="title"><button type="button" class="close" ng-click="$hide()">×</button><h4 class="aside-title" ng-bind="title"></h4></div><div class="aside-body" ng-bind="content"></div><div class="aside-footer"><button type="button" class="btn btn-default" ng-click="$hide()">Close</button></div></div></div></div>');
|
$templateCache.put('aside/aside.tpl.html', '<div class="aside" tabindex="-1" role="dialog"><div class="aside-dialog"><div class="aside-content"><div class="aside-header" ng-show="title"><button type="button" class="close" ng-click="$hide()">×</button><h4 class="aside-title" ng-bind="title"></h4></div><div class="aside-body" ng-bind="content"></div><div class="aside-footer"><button type="button" class="btn btn-default" ng-click="$hide()">Close</button></div></div></div></div>');
|
||||||
} ]);
|
} ]);
|
||||||
angular.module('mgcrea.ngStrap.datepicker').run([ '$templateCache', function($templateCache) {
|
angular.module('mgcrea.ngStrap.datepicker').run([ '$templateCache', function($templateCache) {
|
||||||
$templateCache.put('datepicker/datepicker.tpl.html', '<div class="dropdown-menu datepicker" ng-class="\'datepicker-mode-\' + $mode" style="max-width: 320px"><table style="table-layout: fixed; height: 100%; width: 100%"><thead><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$selectPane(-1)"><i class="{{$iconLeft}}"></i></button></th><th colspan="{{ rows[0].length - 2 }}"><button tabindex="-1" type="button" class="btn btn-default btn-block text-strong" ng-click="$toggleMode()"><strong style="text-transform: capitalize" ng-bind="title"></strong></button></th><th><button tabindex="-1" type="button" class="btn btn-default pull-right" ng-click="$selectPane(+1)"><i class="{{$iconRight}}"></i></button></th></tr><tr ng-show="showLabels" ng-bind-html="labels"></tr></thead><tbody><tr ng-repeat="(i, row) in rows" height="{{ 100 / rows.length }}%"><td class="text-center" ng-repeat="(j, el) in row"><button tabindex="-1" type="button" class="btn btn-default" style="width: 100%" ng-class="{\'btn-primary\': el.selected, \'btn-info btn-today\': el.isToday && !el.selected}" ng-click="$select(el.date)" ng-disabled="el.disabled"><span ng-class="{\'text-muted\': el.muted}" ng-bind="el.label"></span></button></td></tr></tbody></table></div>');
|
$templateCache.put('datepicker/datepicker.tpl.html', '<div class="dropdown-menu datepicker" ng-class="\'datepicker-mode-\' + $mode" style="max-width: 320px"><table style="table-layout: fixed; height: 100%; width: 100%"><thead><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$selectPane(-1)"><i class="{{$iconLeft}}"></i></button></th><th colspan="{{ rows[0].length - 2 }}"><button tabindex="-1" type="button" class="btn btn-default btn-block text-strong" ng-click="$toggleMode()"><strong style="text-transform: capitalize" ng-bind="title"></strong></button></th><th><button tabindex="-1" type="button" class="btn btn-default pull-right" ng-click="$selectPane(+1)"><i class="{{$iconRight}}"></i></button></th></tr><tr ng-if="showLabels" ng-bind-html="labels"></tr></thead><tbody><tr ng-repeat="(i, row) in rows" height="{{ 100 / rows.length }}%"><td class="text-center" ng-repeat="(j, el) in row"><button tabindex="-1" type="button" class="btn btn-default" style="width: 100%" ng-class="{\'btn-primary\': el.selected, \'btn-info btn-today\': el.isToday && !el.selected}" ng-click="$select(el.date)" ng-disabled="el.disabled"><span ng-class="{\'text-muted\': el.muted}" ng-bind="el.label"></span></button></td></tr></tbody><tfoot><tr><td colspan="{{ rows[0].length }}"><div class="btn-group btn-group-justified" role="group"><div class="btn-group" role="group" ng-if="$hasToday"><button type="button" class="btn btn-default today" ng-click="$setToday()" ng-disabled="isTodayDisabled"><strong style="text-transform: capitalize">Today</strong></button></div><div class="btn-group" role="group" ng-if="$hasClear"><button type="button" class="btn btn-default clear" ng-click="$clear()"><strong style="text-transform: capitalize">Clear</strong></button></div></div></td></tr></tfoot></table></div>');
|
||||||
} ]);
|
} ]);
|
||||||
angular.module('mgcrea.ngStrap.dropdown').run([ '$templateCache', function($templateCache) {
|
angular.module('mgcrea.ngStrap.dropdown').run([ '$templateCache', function($templateCache) {
|
||||||
$templateCache.put('dropdown/dropdown.tpl.html', '<ul tabindex="-1" class="dropdown-menu" role="menu"><li role="presentation" ng-class="{divider: item.divider}" ng-repeat="item in content"><a role="menuitem" tabindex="-1" ng-href="{{item.href}}" ng-if="!item.divider && item.href" target="{{item.target || \'\'}}" ng-bind="item.text"></a> <a role="menuitem" tabindex="-1" href="javascript:void(0)" ng-if="!item.divider && item.click" ng-click="$eval(item.click);$hide()" ng-bind="item.text"></a></li></ul>');
|
$templateCache.put('dropdown/dropdown.tpl.html', '<ul tabindex="-1" class="dropdown-menu" role="menu" ng-show="content && content.length"><li role="presentation" ng-class="{divider: item.divider, active: item.active}" ng-repeat="item in content"><a role="menuitem" tabindex="-1" ng-href="{{item.href}}" ng-if="!item.divider && item.href" target="{{item.target || \'\'}}" ng-bind="item.text"></a> <a role="menuitem" tabindex="-1" href="javascript:void(0)" ng-if="!item.divider && item.click" ng-click="$eval(item.click);$hide()" ng-bind="item.text"></a></li></ul>');
|
||||||
} ]);
|
} ]);
|
||||||
angular.module('mgcrea.ngStrap.modal').run([ '$templateCache', function($templateCache) {
|
angular.module('mgcrea.ngStrap.modal').run([ '$templateCache', function($templateCache) {
|
||||||
$templateCache.put('modal/modal.tpl.html', '<div class="modal" tabindex="-1" role="dialog" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"><div class="modal-header" ng-show="title"><button type="button" class="close" aria-label="Close" ng-click="$hide()"><span aria-hidden="true">×</span></button><h4 class="modal-title" ng-bind="title"></h4></div><div class="modal-body" ng-bind="content"></div><div class="modal-footer"><button type="button" class="btn btn-default" ng-click="$hide()">Close</button></div></div></div></div>');
|
$templateCache.put('modal/modal.tpl.html', '<div class="modal" tabindex="-1" role="dialog" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"><div class="modal-header" ng-show="title"><button type="button" class="close" aria-label="Close" ng-click="$hide()"><span aria-hidden="true">×</span></button><h4 class="modal-title" ng-bind="title"></h4></div><div class="modal-body" ng-bind="content"></div><div class="modal-footer"><button type="button" class="btn btn-default" ng-click="$hide()">Close</button></div></div></div></div>');
|
||||||
} ]);
|
} ]);
|
||||||
angular.module('mgcrea.ngStrap.popover').run([ '$templateCache', function($templateCache) {
|
angular.module('mgcrea.ngStrap.popover').run([ '$templateCache', function($templateCache) {
|
||||||
$templateCache.put('popover/popover.tpl.html', '<div class="popover"><div class="arrow"></div><h3 class="popover-title" ng-bind="title" ng-show="title"></h3><div class="popover-content" ng-bind="content"></div></div>');
|
$templateCache.put('popover/popover.tpl.html', '<div class="popover" tabindex="-1"><div class="arrow"></div><h3 class="popover-title" ng-bind="title" ng-show="title"></h3><div class="popover-content" ng-bind="content"></div></div>');
|
||||||
} ]);
|
} ]);
|
||||||
angular.module('mgcrea.ngStrap.select').run([ '$templateCache', function($templateCache) {
|
angular.module('mgcrea.ngStrap.select').run([ '$templateCache', function($templateCache) {
|
||||||
$templateCache.put('select/select.tpl.html', '<ul tabindex="-1" class="select dropdown-menu" ng-show="$isVisible()" role="select"><li ng-if="$showAllNoneButtons"><div class="btn-group" style="margin-bottom: 5px; margin-left: 5px"><button type="button" class="btn btn-default btn-xs" ng-click="$selectAll()">{{$allText}}</button> <button type="button" class="btn btn-default btn-xs" ng-click="$selectNone()">{{$noneText}}</button></div></li><li role="presentation" ng-repeat="match in $matches" ng-class="{active: $isActive($index)}"><a style="cursor: default" role="menuitem" tabindex="-1" ng-click="$select($index, $event)"><i class="{{$iconCheckmark}} pull-right" ng-if="$isMultiple && $isActive($index)"></i> <span ng-bind="match.label"></span></a></li></ul>');
|
$templateCache.put('select/select.tpl.html', '<ul tabindex="-1" class="select dropdown-menu" ng-show="$isVisible()" role="select"><li ng-if="$showAllNoneButtons"><div class="btn-group" style="margin-bottom: 5px; margin-left: 5px"><button type="button" class="btn btn-default btn-xs" ng-click="$selectAll()">{{$allText}}</button> <button type="button" class="btn btn-default btn-xs" ng-click="$selectNone()">{{$noneText}}</button></div></li><li role="presentation" ng-repeat="match in $matches" ng-class="{active: $isActive($index)}"><a style="cursor: default" role="menuitem" tabindex="-1" ng-click="$select($index, $event)"><i class="{{$iconCheckmark}} pull-right" ng-if="$isMultiple && $isActive($index)"></i> <span ng-bind="match.label"></span></a></li></ul>');
|
||||||
} ]);
|
} ]);
|
||||||
angular.module('mgcrea.ngStrap.timepicker').run([ '$templateCache', function($templateCache) {
|
angular.module('mgcrea.ngStrap.timepicker').run([ '$templateCache', function($templateCache) {
|
||||||
$templateCache.put('timepicker/timepicker.tpl.html', '<div class="dropdown-menu timepicker" style="min-width: 0px;width: auto"><table height="100%"><thead><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 0)"><i class="{{ $iconUp }}"></i></button></th><th> </th><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 1)"><i class="{{ $iconUp }}"></i></button></th><th> </th><th><button ng-if="showSeconds" tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 2)"><i class="{{ $iconUp }}"></i></button></th></tr></thead><tbody><tr ng-repeat="(i, row) in rows"><td class="text-center"><button tabindex="-1" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[0].selected}" ng-click="$select(row[0].date, 0)" ng-disabled="row[0].disabled"><span ng-class="{\'text-muted\': row[0].muted}" ng-bind="row[0].label"></span></button></td><td><span ng-bind="i == midIndex ? timeSeparator : \' \'"></span></td><td class="text-center"><button tabindex="-1" ng-if="row[1].date" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[1].selected}" ng-click="$select(row[1].date, 1)" ng-disabled="row[1].disabled"><span ng-class="{\'text-muted\': row[1].muted}" ng-bind="row[1].label"></span></button></td><td><span ng-bind="i == midIndex ? timeSeparator : \' \'"></span></td><td class="text-center"><button tabindex="-1" ng-if="showSeconds && row[2].date" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[2].selected}" ng-click="$select(row[2].date, 2)" ng-disabled="row[2].disabled"><span ng-class="{\'text-muted\': row[2].muted}" ng-bind="row[2].label"></span></button></td><td ng-if="showAM"> </td><td ng-if="showAM"><button tabindex="-1" ng-show="i == midIndex - !isAM * 1" style="width: 100%" type="button" ng-class="{\'btn-primary\': !!isAM}" class="btn btn-default" ng-click="$switchMeridian()" ng-disabled="el.disabled">AM</button> <button tabindex="-1" ng-show="i == midIndex + 1 - !isAM * 1" style="width: 100%" type="button" ng-class="{\'btn-primary\': !isAM}" class="btn btn-default" ng-click="$switchMeridian()" ng-disabled="el.disabled">PM</button></td></tr></tbody><tfoot><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 0)"><i class="{{ $iconDown }}"></i></button></th><th> </th><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 1)"><i class="{{ $iconDown }}"></i></button></th><th> </th><th><button ng-if="showSeconds" tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 2)"><i class="{{ $iconDown }}"></i></button></th></tr></tfoot></table></div>');
|
$templateCache.put('timepicker/timepicker.tpl.html', '<div class="dropdown-menu timepicker" style="min-width: 0px;width: auto"><table height="100%"><thead><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 0)"><i class="{{ $iconUp }}"></i></button></th><th> </th><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 1)"><i class="{{ $iconUp }}"></i></button></th><th ng-if="showSeconds"> </th><th ng-if="showSeconds"><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 2)"><i class="{{ $iconUp }}"></i></button></th></tr></thead><tbody><tr ng-repeat="(i, row) in rows"><td class="text-center"><button tabindex="-1" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[0].selected}" ng-click="$select(row[0].date, 0)" ng-disabled="row[0].disabled"><span ng-class="{\'text-muted\': row[0].muted}" ng-bind="row[0].label"></span></button></td><td><span ng-bind="i == midIndex ? timeSeparator : \' \'"></span></td><td class="text-center"><button tabindex="-1" ng-if="row[1].date" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[1].selected}" ng-click="$select(row[1].date, 1)" ng-disabled="row[1].disabled"><span ng-class="{\'text-muted\': row[1].muted}" ng-bind="row[1].label"></span></button></td><td ng-if="showSeconds"><span ng-bind="i == midIndex ? timeSeparator : \' \'"></span></td><td ng-if="showSeconds" class="text-center"><button tabindex="-1" ng-if="row[2].date" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[2].selected}" ng-click="$select(row[2].date, 2)" ng-disabled="row[2].disabled"><span ng-class="{\'text-muted\': row[2].muted}" ng-bind="row[2].label"></span></button></td><td ng-if="showAM"> </td><td ng-if="showAM"><button tabindex="-1" ng-show="i == midIndex - !isAM * 1" style="width: 100%" type="button" ng-class="{\'btn-primary\': !!isAM}" class="btn btn-default" ng-click="$switchMeridian()" ng-disabled="el.disabled">AM</button> <button tabindex="-1" ng-show="i == midIndex + 1 - !isAM * 1" style="width: 100%" type="button" ng-class="{\'btn-primary\': !isAM}" class="btn btn-default" ng-click="$switchMeridian()" ng-disabled="el.disabled">PM</button></td></tr></tbody><tfoot><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 0)"><i class="{{ $iconDown }}"></i></button></th><th> </th><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 1)"><i class="{{ $iconDown }}"></i></button></th><th ng-if="showSeconds"> </th><th ng-if="showSeconds"><button ng-if="showSeconds" tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 2)"><i class="{{ $iconDown }}"></i></button></th></tr></tfoot></table></div>');
|
||||||
} ]);
|
|
||||||
angular.module('mgcrea.ngStrap.tab').run([ '$templateCache', function($templateCache) {
|
|
||||||
$templateCache.put('tab/tab.tpl.html', '<ul class="nav" ng-class="$navClass" role="tablist"><li role="presentation" ng-repeat="$pane in $panes track by $index" ng-class="[ $isActive($pane, $index) ? $activeClass : \'\', $pane.disabled ? \'disabled\' : \'\' ]"><a role="tab" data-toggle="tab" ng-click="!$pane.disabled && $setActive($pane.name || $index)" data-index="{{ $index }}" ng-bind-html="$pane.title" aria-controls="$pane.title"></a></li></ul><div ng-transclude class="tab-content"></div>');
|
|
||||||
} ]);
|
|
||||||
angular.module('mgcrea.ngStrap.typeahead').run([ '$templateCache', function($templateCache) {
|
|
||||||
$templateCache.put('typeahead/typeahead.tpl.html', '<ul tabindex="-1" class="typeahead dropdown-menu" ng-show="$isVisible()" role="select"><li role="presentation" ng-repeat="match in $matches" ng-class="{active: $index == $activeIndex}"><a role="menuitem" tabindex="-1" ng-click="$select($index, $event)" ng-bind="match.label"></a></li></ul>');
|
|
||||||
} ]);
|
} ]);
|
||||||
angular.module('mgcrea.ngStrap.tooltip').run([ '$templateCache', function($templateCache) {
|
angular.module('mgcrea.ngStrap.tooltip').run([ '$templateCache', function($templateCache) {
|
||||||
$templateCache.put('tooltip/tooltip.tpl.html', '<div class="tooltip in" ng-show="title"><div class="tooltip-arrow"></div><div class="tooltip-inner" ng-bind="title"></div></div>');
|
$templateCache.put('tooltip/tooltip.tpl.html', '<div class="tooltip in" ng-show="title"><div class="tooltip-arrow"></div><div class="tooltip-inner" ng-bind="title"></div></div>');
|
||||||
} ]);
|
} ]);
|
||||||
|
angular.module('mgcrea.ngStrap.tab').run([ '$templateCache', function($templateCache) {
|
||||||
|
$templateCache.put('tab/tab.tpl.html', '<ul class="nav" ng-class="$navClass" role="tablist"><li role="presentation" ng-repeat="$pane in $panes track by $index" ng-class="[ $isActive($pane, $index) ? $activeClass : \'\', $pane.disabled ? \'disabled\' : \'\' ]"><a role="tab" data-toggle="tab" ng-click="!$pane.disabled && $setActive($pane.name || $index)" data-index="{{ $index }}" ng-bind-html="$pane.title" aria-controls="$pane.title" href=""></a></li></ul><div ng-transclude class="tab-content"></div>');
|
||||||
|
} ]);
|
||||||
|
angular.module('mgcrea.ngStrap.typeahead').run([ '$templateCache', function($templateCache) {
|
||||||
|
$templateCache.put('typeahead/typeahead.tpl.html', '<ul tabindex="-1" class="typeahead dropdown-menu" ng-show="$isVisible()" role="select"><li role="presentation" ng-repeat="match in $matches" ng-class="{active: $index == $activeIndex}"><a role="menuitem" tabindex="-1" ng-click="$select($index, $event)" ng-bind="match.label"></a></li></ul>');
|
||||||
|
} ]);
|
||||||
})(window, document);
|
})(window, document);
|
||||||
+2
-2
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,421 @@
|
|||||||
|
/**!
|
||||||
|
* AngularJS file upload directives and services. Supports: file upload/drop/paste, resume, cancel/abort,
|
||||||
|
* progress, resize, thumbnail, preview, validation and CORS
|
||||||
|
* FileAPI Flash shim for old browsers not supporting FormData
|
||||||
|
* @author Danial <danial.farid@gmail.com>
|
||||||
|
* @version 12.2.12
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
/** @namespace FileAPI.noContentTimeout */
|
||||||
|
|
||||||
|
function patchXHR(fnName, newFn) {
|
||||||
|
window.XMLHttpRequest.prototype[fnName] = newFn(window.XMLHttpRequest.prototype[fnName]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function redefineProp(xhr, prop, fn) {
|
||||||
|
try {
|
||||||
|
Object.defineProperty(xhr, prop, {get: fn});
|
||||||
|
} catch (e) {/*ignore*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!window.FileAPI) {
|
||||||
|
window.FileAPI = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!window.XMLHttpRequest) {
|
||||||
|
throw 'AJAX is not supported. XMLHttpRequest is not defined.';
|
||||||
|
}
|
||||||
|
|
||||||
|
FileAPI.shouldLoad = !window.FormData || FileAPI.forceLoad;
|
||||||
|
if (FileAPI.shouldLoad) {
|
||||||
|
var initializeUploadListener = function (xhr) {
|
||||||
|
if (!xhr.__listeners) {
|
||||||
|
if (!xhr.upload) xhr.upload = {};
|
||||||
|
xhr.__listeners = [];
|
||||||
|
var origAddEventListener = xhr.upload.addEventListener;
|
||||||
|
xhr.upload.addEventListener = function (t, fn) {
|
||||||
|
xhr.__listeners[t] = fn;
|
||||||
|
if (origAddEventListener) origAddEventListener.apply(this, arguments);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
patchXHR('open', function (orig) {
|
||||||
|
return function (m, url, b) {
|
||||||
|
initializeUploadListener(this);
|
||||||
|
this.__url = url;
|
||||||
|
try {
|
||||||
|
orig.apply(this, [m, url, b]);
|
||||||
|
} catch (e) {
|
||||||
|
if (e.message.indexOf('Access is denied') > -1) {
|
||||||
|
this.__origError = e;
|
||||||
|
orig.apply(this, [m, '_fix_for_ie_crossdomain__', b]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
patchXHR('getResponseHeader', function (orig) {
|
||||||
|
return function (h) {
|
||||||
|
return this.__fileApiXHR && this.__fileApiXHR.getResponseHeader ? this.__fileApiXHR.getResponseHeader(h) : (orig == null ? null : orig.apply(this, [h]));
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
patchXHR('getAllResponseHeaders', function (orig) {
|
||||||
|
return function () {
|
||||||
|
return this.__fileApiXHR && this.__fileApiXHR.getAllResponseHeaders ? this.__fileApiXHR.getAllResponseHeaders() : (orig == null ? null : orig.apply(this));
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
patchXHR('abort', function (orig) {
|
||||||
|
return function () {
|
||||||
|
return this.__fileApiXHR && this.__fileApiXHR.abort ? this.__fileApiXHR.abort() : (orig == null ? null : orig.apply(this));
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
patchXHR('setRequestHeader', function (orig) {
|
||||||
|
return function (header, value) {
|
||||||
|
if (header === '__setXHR_') {
|
||||||
|
initializeUploadListener(this);
|
||||||
|
var val = value(this);
|
||||||
|
// fix for angular < 1.2.0
|
||||||
|
if (val instanceof Function) {
|
||||||
|
val(this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.__requestHeaders = this.__requestHeaders || {};
|
||||||
|
this.__requestHeaders[header] = value;
|
||||||
|
orig.apply(this, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
patchXHR('send', function (orig) {
|
||||||
|
return function () {
|
||||||
|
var xhr = this;
|
||||||
|
if (arguments[0] && arguments[0].__isFileAPIShim) {
|
||||||
|
var formData = arguments[0];
|
||||||
|
var config = {
|
||||||
|
url: xhr.__url,
|
||||||
|
jsonp: false, //removes the callback form param
|
||||||
|
cache: true, //removes the ?fileapiXXX in the url
|
||||||
|
complete: function (err, fileApiXHR) {
|
||||||
|
if (err && angular.isString(err) && err.indexOf('#2174') !== -1) {
|
||||||
|
// this error seems to be fine the file is being uploaded properly.
|
||||||
|
err = null;
|
||||||
|
}
|
||||||
|
xhr.__completed = true;
|
||||||
|
if (!err && xhr.__listeners.load)
|
||||||
|
xhr.__listeners.load({
|
||||||
|
type: 'load',
|
||||||
|
loaded: xhr.__loaded,
|
||||||
|
total: xhr.__total,
|
||||||
|
target: xhr,
|
||||||
|
lengthComputable: true
|
||||||
|
});
|
||||||
|
if (!err && xhr.__listeners.loadend)
|
||||||
|
xhr.__listeners.loadend({
|
||||||
|
type: 'loadend',
|
||||||
|
loaded: xhr.__loaded,
|
||||||
|
total: xhr.__total,
|
||||||
|
target: xhr,
|
||||||
|
lengthComputable: true
|
||||||
|
});
|
||||||
|
if (err === 'abort' && xhr.__listeners.abort)
|
||||||
|
xhr.__listeners.abort({
|
||||||
|
type: 'abort',
|
||||||
|
loaded: xhr.__loaded,
|
||||||
|
total: xhr.__total,
|
||||||
|
target: xhr,
|
||||||
|
lengthComputable: true
|
||||||
|
});
|
||||||
|
if (fileApiXHR.status !== undefined) redefineProp(xhr, 'status', function () {
|
||||||
|
return (fileApiXHR.status === 0 && err && err !== 'abort') ? 500 : fileApiXHR.status;
|
||||||
|
});
|
||||||
|
if (fileApiXHR.statusText !== undefined) redefineProp(xhr, 'statusText', function () {
|
||||||
|
return fileApiXHR.statusText;
|
||||||
|
});
|
||||||
|
redefineProp(xhr, 'readyState', function () {
|
||||||
|
return 4;
|
||||||
|
});
|
||||||
|
if (fileApiXHR.response !== undefined) redefineProp(xhr, 'response', function () {
|
||||||
|
return fileApiXHR.response;
|
||||||
|
});
|
||||||
|
var resp = fileApiXHR.responseText || (err && fileApiXHR.status === 0 && err !== 'abort' ? err : undefined);
|
||||||
|
redefineProp(xhr, 'responseText', function () {
|
||||||
|
return resp;
|
||||||
|
});
|
||||||
|
redefineProp(xhr, 'response', function () {
|
||||||
|
return resp;
|
||||||
|
});
|
||||||
|
if (err) redefineProp(xhr, 'err', function () {
|
||||||
|
return err;
|
||||||
|
});
|
||||||
|
xhr.__fileApiXHR = fileApiXHR;
|
||||||
|
if (xhr.onreadystatechange) xhr.onreadystatechange();
|
||||||
|
if (xhr.onload) xhr.onload();
|
||||||
|
},
|
||||||
|
progress: function (e) {
|
||||||
|
e.target = xhr;
|
||||||
|
if (xhr.__listeners.progress) xhr.__listeners.progress(e);
|
||||||
|
xhr.__total = e.total;
|
||||||
|
xhr.__loaded = e.loaded;
|
||||||
|
if (e.total === e.loaded) {
|
||||||
|
// fix flash issue that doesn't call complete if there is no response text from the server
|
||||||
|
var _this = this;
|
||||||
|
setTimeout(function () {
|
||||||
|
if (!xhr.__completed) {
|
||||||
|
xhr.getAllResponseHeaders = function () {
|
||||||
|
};
|
||||||
|
_this.complete(null, {status: 204, statusText: 'No Content'});
|
||||||
|
}
|
||||||
|
}, FileAPI.noContentTimeout || 10000);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
headers: xhr.__requestHeaders
|
||||||
|
};
|
||||||
|
config.data = {};
|
||||||
|
config.files = {};
|
||||||
|
for (var i = 0; i < formData.data.length; i++) {
|
||||||
|
var item = formData.data[i];
|
||||||
|
if (item.val != null && item.val.name != null && item.val.size != null && item.val.type != null) {
|
||||||
|
config.files[item.key] = item.val;
|
||||||
|
} else {
|
||||||
|
config.data[item.key] = item.val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
if (!FileAPI.hasFlash) {
|
||||||
|
throw 'Adode Flash Player need to be installed. To check ahead use "FileAPI.hasFlash"';
|
||||||
|
}
|
||||||
|
xhr.__fileApiXHR = FileAPI.upload(config);
|
||||||
|
}, 1);
|
||||||
|
} else {
|
||||||
|
if (this.__origError) {
|
||||||
|
throw this.__origError;
|
||||||
|
}
|
||||||
|
orig.apply(xhr, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
window.XMLHttpRequest.__isFileAPIShim = true;
|
||||||
|
window.FormData = FormData = function () {
|
||||||
|
return {
|
||||||
|
append: function (key, val, name) {
|
||||||
|
if (val.__isFileAPIBlobShim) {
|
||||||
|
val = val.data[0];
|
||||||
|
}
|
||||||
|
this.data.push({
|
||||||
|
key: key,
|
||||||
|
val: val,
|
||||||
|
name: name
|
||||||
|
});
|
||||||
|
},
|
||||||
|
data: [],
|
||||||
|
__isFileAPIShim: true
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
window.Blob = Blob = function (b) {
|
||||||
|
return {
|
||||||
|
data: b,
|
||||||
|
__isFileAPIBlobShim: true
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
/** @namespace FileAPI.forceLoad */
|
||||||
|
/** @namespace window.FileAPI.jsUrl */
|
||||||
|
/** @namespace window.FileAPI.jsPath */
|
||||||
|
|
||||||
|
function isInputTypeFile(elem) {
|
||||||
|
return elem[0].tagName.toLowerCase() === 'input' && elem.attr('type') && elem.attr('type').toLowerCase() === 'file';
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasFlash() {
|
||||||
|
try {
|
||||||
|
var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
|
||||||
|
if (fo) return true;
|
||||||
|
} catch (e) {
|
||||||
|
if (navigator.mimeTypes['application/x-shockwave-flash'] !== undefined) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOffset(obj) {
|
||||||
|
var left = 0, top = 0;
|
||||||
|
|
||||||
|
if (window.jQuery) {
|
||||||
|
return jQuery(obj).offset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.offsetParent) {
|
||||||
|
do {
|
||||||
|
left += (obj.offsetLeft - obj.scrollLeft);
|
||||||
|
top += (obj.offsetTop - obj.scrollTop);
|
||||||
|
obj = obj.offsetParent;
|
||||||
|
} while (obj);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
left: left,
|
||||||
|
top: top
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FileAPI.shouldLoad) {
|
||||||
|
FileAPI.hasFlash = hasFlash();
|
||||||
|
|
||||||
|
//load FileAPI
|
||||||
|
if (FileAPI.forceLoad) {
|
||||||
|
FileAPI.html5 = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FileAPI.upload) {
|
||||||
|
var jsUrl, basePath, script = document.createElement('script'), allScripts = document.getElementsByTagName('script'), i, index, src;
|
||||||
|
if (window.FileAPI.jsUrl) {
|
||||||
|
jsUrl = window.FileAPI.jsUrl;
|
||||||
|
} else if (window.FileAPI.jsPath) {
|
||||||
|
basePath = window.FileAPI.jsPath;
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < allScripts.length; i++) {
|
||||||
|
src = allScripts[i].src;
|
||||||
|
index = src.search(/\/ng\-file\-upload[\-a-zA-z0-9\.]*\.js/);
|
||||||
|
if (index > -1) {
|
||||||
|
basePath = src.substring(0, index + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FileAPI.staticPath == null) FileAPI.staticPath = basePath;
|
||||||
|
script.setAttribute('src', jsUrl || basePath + 'FileAPI.min.js');
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(script);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileAPI.ngfFixIE = function (elem, fileElem, changeFn) {
|
||||||
|
if (!hasFlash()) {
|
||||||
|
throw 'Adode Flash Player need to be installed. To check ahead use "FileAPI.hasFlash"';
|
||||||
|
}
|
||||||
|
var fixInputStyle = function () {
|
||||||
|
var label = fileElem.parent();
|
||||||
|
if (elem.attr('disabled')) {
|
||||||
|
if (label) label.removeClass('js-fileapi-wrapper');
|
||||||
|
} else {
|
||||||
|
if (!fileElem.attr('__ngf_flash_')) {
|
||||||
|
fileElem.unbind('change');
|
||||||
|
fileElem.unbind('click');
|
||||||
|
fileElem.bind('change', function (evt) {
|
||||||
|
fileApiChangeFn.apply(this, [evt]);
|
||||||
|
changeFn.apply(this, [evt]);
|
||||||
|
});
|
||||||
|
fileElem.attr('__ngf_flash_', 'true');
|
||||||
|
}
|
||||||
|
label.addClass('js-fileapi-wrapper');
|
||||||
|
if (!isInputTypeFile(elem)) {
|
||||||
|
label.css('position', 'absolute')
|
||||||
|
.css('top', getOffset(elem[0]).top + 'px').css('left', getOffset(elem[0]).left + 'px')
|
||||||
|
.css('width', elem[0].offsetWidth + 'px').css('height', elem[0].offsetHeight + 'px')
|
||||||
|
.css('filter', 'alpha(opacity=0)').css('display', elem.css('display'))
|
||||||
|
.css('overflow', 'hidden').css('z-index', '900000')
|
||||||
|
.css('visibility', 'visible');
|
||||||
|
fileElem.css('width', elem[0].offsetWidth + 'px').css('height', elem[0].offsetHeight + 'px')
|
||||||
|
.css('position', 'absolute').css('top', '0px').css('left', '0px');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
elem.bind('mouseenter', fixInputStyle);
|
||||||
|
|
||||||
|
var fileApiChangeFn = function (evt) {
|
||||||
|
var files = FileAPI.getFiles(evt);
|
||||||
|
//just a double check for #233
|
||||||
|
for (var i = 0; i < files.length; i++) {
|
||||||
|
if (files[i].size === undefined) files[i].size = 0;
|
||||||
|
if (files[i].name === undefined) files[i].name = 'file';
|
||||||
|
if (files[i].type === undefined) files[i].type = 'undefined';
|
||||||
|
}
|
||||||
|
if (!evt.target) {
|
||||||
|
evt.target = {};
|
||||||
|
}
|
||||||
|
evt.target.files = files;
|
||||||
|
// if evt.target.files is not writable use helper field
|
||||||
|
if (evt.target.files !== files) {
|
||||||
|
evt.__files_ = files;
|
||||||
|
}
|
||||||
|
(evt.__files_ || evt.target.files).item = function (i) {
|
||||||
|
return (evt.__files_ || evt.target.files)[i] || null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
FileAPI.disableFileInput = function (elem, disable) {
|
||||||
|
if (disable) {
|
||||||
|
elem.removeClass('js-fileapi-wrapper');
|
||||||
|
} else {
|
||||||
|
elem.addClass('js-fileapi-wrapper');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
if (!window.FileReader) {
|
||||||
|
window.FileReader = function () {
|
||||||
|
var _this = this, loadStarted = false;
|
||||||
|
this.listeners = {};
|
||||||
|
this.addEventListener = function (type, fn) {
|
||||||
|
_this.listeners[type] = _this.listeners[type] || [];
|
||||||
|
_this.listeners[type].push(fn);
|
||||||
|
};
|
||||||
|
this.removeEventListener = function (type, fn) {
|
||||||
|
if (_this.listeners[type]) _this.listeners[type].splice(_this.listeners[type].indexOf(fn), 1);
|
||||||
|
};
|
||||||
|
this.dispatchEvent = function (evt) {
|
||||||
|
var list = _this.listeners[evt.type];
|
||||||
|
if (list) {
|
||||||
|
for (var i = 0; i < list.length; i++) {
|
||||||
|
list[i].call(_this, evt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.onabort = this.onerror = this.onload = this.onloadstart = this.onloadend = this.onprogress = null;
|
||||||
|
|
||||||
|
var constructEvent = function (type, evt) {
|
||||||
|
var e = {type: type, target: _this, loaded: evt.loaded, total: evt.total, error: evt.error};
|
||||||
|
if (evt.result != null) e.target.result = evt.result;
|
||||||
|
return e;
|
||||||
|
};
|
||||||
|
var listener = function (evt) {
|
||||||
|
if (!loadStarted) {
|
||||||
|
loadStarted = true;
|
||||||
|
if (_this.onloadstart) _this.onloadstart(constructEvent('loadstart', evt));
|
||||||
|
}
|
||||||
|
var e;
|
||||||
|
if (evt.type === 'load') {
|
||||||
|
if (_this.onloadend) _this.onloadend(constructEvent('loadend', evt));
|
||||||
|
e = constructEvent('load', evt);
|
||||||
|
if (_this.onload) _this.onload(e);
|
||||||
|
_this.dispatchEvent(e);
|
||||||
|
} else if (evt.type === 'progress') {
|
||||||
|
e = constructEvent('progress', evt);
|
||||||
|
if (_this.onprogress) _this.onprogress(e);
|
||||||
|
_this.dispatchEvent(e);
|
||||||
|
} else {
|
||||||
|
e = constructEvent('error', evt);
|
||||||
|
if (_this.onerror) _this.onerror(e);
|
||||||
|
_this.dispatchEvent(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.readAsDataURL = function (file) {
|
||||||
|
FileAPI.readAsDataURL(file, listener);
|
||||||
|
};
|
||||||
|
this.readAsText = function (file) {
|
||||||
|
FileAPI.readAsText(file, listener);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
+11
-11
File diff suppressed because one or more lines are too long
@@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Services
|
||||||
|
{
|
||||||
|
public class ImportException : Exception
|
||||||
|
{
|
||||||
|
public readonly string[] Messages;
|
||||||
|
|
||||||
|
public ImportException(string message, Exception innerException) : base(message, innerException)
|
||||||
|
{
|
||||||
|
Messages = new[] { message };
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportException(string message) : base(message)
|
||||||
|
{
|
||||||
|
Messages = new [] {message};
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImportException(string[] messages) : base(string.Join(Environment.NewLine, messages))
|
||||||
|
{
|
||||||
|
Messages = messages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using AutoMapper;
|
||||||
|
using CsvHelper;
|
||||||
|
using InventoryTraker.Web.Core;
|
||||||
|
using InventoryTraker.Web.Models;
|
||||||
|
using InventoryTraker.Web.Utilities;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Services
|
||||||
|
{
|
||||||
|
public class InventoryImporter
|
||||||
|
{
|
||||||
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
|
public InventoryImporter(IMapper mapper)
|
||||||
|
{
|
||||||
|
_mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<Inventory> Import(FileSystemInfo excelFile)
|
||||||
|
{
|
||||||
|
var inventoryParser = new InventoryParser(excelFile);
|
||||||
|
|
||||||
|
IList<InventoryAddForm> forms;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
forms = inventoryParser.Parse();
|
||||||
|
}
|
||||||
|
catch (CsvMissingFieldException e)
|
||||||
|
{
|
||||||
|
var fieldname = Regex.Replace(e.Message, ".*'(.*)'.*", "$1");
|
||||||
|
|
||||||
|
throw new ImportException($"Cannot find required field titled '{fieldname}'", e);
|
||||||
|
}
|
||||||
|
//catch (CsvBadDataException e)
|
||||||
|
//{
|
||||||
|
// throw new ImportException(e.Message, e);
|
||||||
|
//}
|
||||||
|
//catch (CsvParserException e)
|
||||||
|
//{
|
||||||
|
// throw new ImportException(e.Message, e);
|
||||||
|
//}
|
||||||
|
//catch (CsvReaderException e)
|
||||||
|
//{
|
||||||
|
// throw new ImportException(e.Message, e);
|
||||||
|
//}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new ImportException(e.Message, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
IList<Inventory> inventories = new List<Inventory>();
|
||||||
|
var validationErrors = new List<string>();
|
||||||
|
foreach (var addForm in forms)
|
||||||
|
{
|
||||||
|
var results = new List<ValidationResult>();
|
||||||
|
var context = new ValidationContext(addForm, null, null);
|
||||||
|
if (!Validator.TryValidateObject(addForm, context, results))
|
||||||
|
{
|
||||||
|
// results will contain all the failed validation errors.
|
||||||
|
validationErrors.AddRange(
|
||||||
|
results.Select(result => $"{addForm.Id} - ${result.ErrorMessage}")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inventories.Add(_mapper.Map<Inventory>(addForm));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validationErrors.Any())
|
||||||
|
{
|
||||||
|
throw new ImportException(string.Join(Environment.NewLine, validationErrors));
|
||||||
|
}
|
||||||
|
|
||||||
|
return inventories;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Web.Mvc;
|
using System.Web.Http.Filters;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Utilities
|
namespace InventoryTraker.Web.Utilities
|
||||||
{
|
{
|
||||||
@@ -10,5 +11,12 @@ namespace InventoryTraker.Web.Utilities
|
|||||||
var action = ctx.RouteData.Values["action"].ToString();
|
var action = ctx.RouteData.Values["action"].ToString();
|
||||||
return $"{controller}Controller.{action}";
|
return $"{controller}Controller.{action}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetLoggerName(this HttpActionExecutedContext ctx)
|
||||||
|
{
|
||||||
|
var controller = ctx.ActionContext.ControllerContext.ControllerDescriptor.ControllerName;
|
||||||
|
var action = ctx.ActionContext.ActionDescriptor.ActionName;
|
||||||
|
return $"{controller}Controller.{action}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using CsvHelper.Configuration;
|
||||||
|
using CsvHelper.TypeConversion;
|
||||||
|
using InventoryTraker.Web.Models;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Utilities
|
||||||
|
{
|
||||||
|
public class InventoryParser
|
||||||
|
{
|
||||||
|
private readonly FileSystemInfo _excelFile;
|
||||||
|
|
||||||
|
// ReSharper disable once ClassNeverInstantiated.Local
|
||||||
|
private sealed class InventoryAddFormMap : CsvClassMap<InventoryAddForm>
|
||||||
|
{
|
||||||
|
public InventoryAddFormMap()
|
||||||
|
{
|
||||||
|
Map(m => m.Id).Name("Box ID").TypeConverter<StringNullConverter>();
|
||||||
|
Map(m => m.ProgramName).Name("Program Name").TypeConverter<StringNullConverter>();
|
||||||
|
Map(m => m.ProgramSubtype).Name("Program Subtype").TypeConverter<StringNullConverter>();
|
||||||
|
Map(m => m.Description).TypeConverter<StringNullConverter>();
|
||||||
|
Map(m => m.ShredReadyDate).Name("Shread Ready Date");
|
||||||
|
Map(m => m.AddedDate).Name("Added Date");
|
||||||
|
Map(m => m.Memo).TypeConverter<StringNullConverter>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class StringNullConverter : StringConverter
|
||||||
|
{
|
||||||
|
public override object ConvertFromString(TypeConverterOptions options, string text)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(text)) return null;
|
||||||
|
if (text.StartsWith("\"") && text.EndsWith("\""))
|
||||||
|
return base.ConvertFromString(options, Regex.Replace(text, @"^\""(.*)\""$", "$1"));
|
||||||
|
return base.ConvertFromString(options, text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public InventoryParser(FileSystemInfo excelFile)
|
||||||
|
{
|
||||||
|
_excelFile = excelFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IList<InventoryAddForm> Parse()
|
||||||
|
{
|
||||||
|
var csvConfiguration =
|
||||||
|
new CsvConfiguration
|
||||||
|
{
|
||||||
|
IsHeaderCaseSensitive = false,
|
||||||
|
IgnoreReadingExceptions = false,
|
||||||
|
TrimFields = true,
|
||||||
|
SkipEmptyRecords = true,
|
||||||
|
ShouldSkipRecord = strings => strings.Take(7).All(string.IsNullOrEmpty)
|
||||||
|
};
|
||||||
|
csvConfiguration.RegisterClassMap<InventoryAddFormMap>();
|
||||||
|
using (var reader = ExcelParserBase.OpenExcel(_excelFile, csvConfiguration))
|
||||||
|
{
|
||||||
|
return reader.GetRecords<InventoryAddForm>().ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using ClosedXML.Excel;
|
||||||
|
using CsvHelper;
|
||||||
|
using CsvHelper.Configuration;
|
||||||
|
using CsvHelper.Excel;
|
||||||
|
using InventoryTraker.Web.Models;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Utilities
|
||||||
|
{
|
||||||
|
public class InventoryReportWriter
|
||||||
|
{
|
||||||
|
private sealed class InventoryViewModelMap : CsvClassMap<InventoryViewModel>
|
||||||
|
{
|
||||||
|
public InventoryViewModelMap()
|
||||||
|
{
|
||||||
|
Map(m => m.Id).Name("Box ID");
|
||||||
|
Map(m => m.ProgramName).Name("Program Name");
|
||||||
|
Map(m => m.ProgramSubtype).Name("Program Subtype");
|
||||||
|
Map(m => m.Description).Name("Description");
|
||||||
|
Map(m => m.ShredReadyDate).Name("Shread Ready Date");
|
||||||
|
Map(m => m.AddedDate).Name("Added Date");
|
||||||
|
Map(m => m.Memo).Name("Memo");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] Write(IEnumerable<InventoryViewModel> items)
|
||||||
|
{
|
||||||
|
using (var stream = new MemoryStream())
|
||||||
|
{
|
||||||
|
WriteStream(items, stream);
|
||||||
|
return stream.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteStream(IEnumerable<InventoryViewModel> items, Stream stream)
|
||||||
|
{
|
||||||
|
using (var workbook = new XLWorkbook(XLEventTracking.Disabled))
|
||||||
|
{
|
||||||
|
var worksheet = workbook.AddWorksheet("Current Inventory");
|
||||||
|
using (var writer = new CsvWriter(new ExcelSerializer(worksheet)))
|
||||||
|
{
|
||||||
|
writer.Configuration.TrimFields = true;
|
||||||
|
writer.Configuration.RegisterClassMap(new InventoryViewModelMap());
|
||||||
|
writer.WriteRecords(items.OrderBy(i => i.Id));
|
||||||
|
workbook.SaveAs(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using CsvHelper.Configuration;
|
|
||||||
using InventoryTraker.Web.Core;
|
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Utilities
|
|
||||||
{
|
|
||||||
public class InventoryTypeParser
|
|
||||||
{
|
|
||||||
private readonly FileSystemInfo _excelFile;
|
|
||||||
|
|
||||||
// ReSharper disable once ClassNeverInstantiated.Local
|
|
||||||
private sealed class InventoryTypeMap : CsvClassMap<InventoryType>
|
|
||||||
{
|
|
||||||
public InventoryTypeMap()
|
|
||||||
{
|
|
||||||
Map(m => m.Identifier);
|
|
||||||
Map(m => m.Name);
|
|
||||||
Map(m => m.UnitsPerCase);
|
|
||||||
Map(m => m.ContainerType);
|
|
||||||
Map(m => m.WeightPerCase);
|
|
||||||
Map(m => m.PricePerCase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public InventoryTypeParser(FileSystemInfo excelFile)
|
|
||||||
{
|
|
||||||
_excelFile = excelFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IList<InventoryType> Parse()
|
|
||||||
{
|
|
||||||
var csvConfiguration =
|
|
||||||
new CsvConfiguration { IsHeaderCaseSensitive = false, IgnoreReadingExceptions = true};
|
|
||||||
csvConfiguration.RegisterClassMap<InventoryTypeMap>();
|
|
||||||
using (var reader = ExcelParserBase.OpenExcel(_excelFile, csvConfiguration))
|
|
||||||
{
|
|
||||||
return reader.GetRecords<InventoryType>().ToList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data.Entity.Infrastructure;
|
||||||
|
using System.Data.SqlClient;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using InventoryTraker.Web.Core;
|
||||||
|
|
||||||
|
namespace InventoryTraker.Web.Utilities
|
||||||
|
{
|
||||||
|
public static class ModelHelper
|
||||||
|
{
|
||||||
|
public static List<Transaction> GetAddedTransaction(DateTime addedDate)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
new List<Transaction>
|
||||||
|
{
|
||||||
|
new Transaction
|
||||||
|
{
|
||||||
|
TransactionType = TransactionType.Added,
|
||||||
|
AddedQuantity = 1,
|
||||||
|
CurrentQuantity = 1,
|
||||||
|
Memo = "Added",
|
||||||
|
Timestamp = DateTime.Now,
|
||||||
|
TransactionDate = addedDate
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetUpdateExceptionMessage(Exception e)
|
||||||
|
{
|
||||||
|
if (e.InnerException?.InnerException is SqlException)
|
||||||
|
{
|
||||||
|
var innerMessage = e.InnerException.InnerException.Message;
|
||||||
|
if (innerMessage.StartsWith(@"Violation of PRIMARY KEY constraint 'PK_dbo.Inventories'."))
|
||||||
|
{
|
||||||
|
var id = Regex.Replace(innerMessage, @".*\((.*)\).*", "$1", RegexOptions.Singleline);
|
||||||
|
return "Duplicate Inventory Id: " + id;
|
||||||
|
}
|
||||||
|
return innerMessage;
|
||||||
|
}
|
||||||
|
return e.InnerException?.Message ?? e.Message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Web;
|
|
||||||
using CsvHelper.Configuration;
|
|
||||||
using InventoryTraker.Web.Models;
|
|
||||||
|
|
||||||
namespace InventoryTraker.Web.Utilities
|
|
||||||
{
|
|
||||||
public class MovementReportWriter
|
|
||||||
{
|
|
||||||
public sealed class InventoryTypeReportMap : CsvClassMap<MovementReportItem>
|
|
||||||
{
|
|
||||||
public InventoryTypeReportMap()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user