From 0ccf9fb4292cb09284ca99dab7404fdd01b6daad Mon Sep 17 00:00:00 2001 From: Tyrel Souza Date: Thu, 27 Jul 2023 14:37:01 -0400 Subject: [PATCH] Add in C# Project --- .gitignore | 2 +- BenchtopPDF/.gitignore | 5 + .../.idea/.idea.BenchtopPDF/.idea/.gitignore | 13 ++ .../.idea.BenchtopPDF/.idea/encodings.xml | 4 + .../.idea.BenchtopPDF/.idea/indexLayout.xml | 8 + .../.idea/.idea.BenchtopPDF/.idea/vcs.xml | 6 + BenchtopPDF/BenchtopPDF.sln | 16 ++ BenchtopPDF/BenchtopPDF.sln.DotSettings.user | 3 + BenchtopPDF/BenchtopPDF/BenchTopLogo.jpg | Bin 0 -> 20369 bytes BenchtopPDF/BenchtopPDF/BenchtopPDF.csproj | 110 ++++++++++++ BenchtopPDF/BenchtopPDF/Program.cs | 24 +++ .../BenchtopPDF/Properties/AssemblyInfo.cs | 35 ++++ BenchtopPDF/BenchtopPDF/SheetDocument.cs | 170 ++++++++++++++++++ BenchtopPDF/BenchtopPDF/SheetModel.cs | 94 ++++++++++ BenchtopPDF/BenchtopPDF/packages.config | 18 ++ README.md | 27 +++ benchtopdevices/sheets/parsers/transducer.py | 48 ++--- .../sheets/templates/sheets/upload.html | 34 +++- 18 files changed, 593 insertions(+), 24 deletions(-) create mode 100644 BenchtopPDF/.gitignore create mode 100644 BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/.gitignore create mode 100644 BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/encodings.xml create mode 100644 BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/indexLayout.xml create mode 100644 BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/vcs.xml create mode 100644 BenchtopPDF/BenchtopPDF.sln create mode 100644 BenchtopPDF/BenchtopPDF.sln.DotSettings.user create mode 100644 BenchtopPDF/BenchtopPDF/BenchTopLogo.jpg create mode 100644 BenchtopPDF/BenchtopPDF/BenchtopPDF.csproj create mode 100644 BenchtopPDF/BenchtopPDF/Program.cs create mode 100644 BenchtopPDF/BenchtopPDF/Properties/AssemblyInfo.cs create mode 100644 BenchtopPDF/BenchtopPDF/SheetDocument.cs create mode 100644 BenchtopPDF/BenchtopPDF/SheetModel.cs create mode 100644 BenchtopPDF/BenchtopPDF/packages.config create mode 100644 README.md diff --git a/.gitignore b/.gitignore index 962457f..1a34d5e 100644 --- a/.gitignore +++ b/.gitignore @@ -285,4 +285,4 @@ tags.temp # End of https://www.toptal.com/developers/gitignore/api/tags,python,django - +.idea diff --git a/BenchtopPDF/.gitignore b/BenchtopPDF/.gitignore new file mode 100644 index 0000000..add57be --- /dev/null +++ b/BenchtopPDF/.gitignore @@ -0,0 +1,5 @@ +bin/ +obj/ +/packages/ +riderModule.iml +/_ReSharper.Caches/ \ No newline at end of file diff --git a/BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/.gitignore b/BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/.gitignore new file mode 100644 index 0000000..306314f --- /dev/null +++ b/BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/contentModel.xml +/.idea.BenchtopPDF.iml +/modules.xml +/projectSettingsUpdater.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/encodings.xml b/BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/indexLayout.xml b/BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/vcs.xml b/BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/BenchtopPDF/.idea/.idea.BenchtopPDF/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/BenchtopPDF/BenchtopPDF.sln b/BenchtopPDF/BenchtopPDF.sln new file mode 100644 index 0000000..00be03b --- /dev/null +++ b/BenchtopPDF/BenchtopPDF.sln @@ -0,0 +1,16 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BenchtopPDF", "BenchtopPDF\BenchtopPDF.csproj", "{552E9774-67EF-461E-AECD-80130D33D891}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {552E9774-67EF-461E-AECD-80130D33D891}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {552E9774-67EF-461E-AECD-80130D33D891}.Debug|Any CPU.Build.0 = Debug|Any CPU + {552E9774-67EF-461E-AECD-80130D33D891}.Release|Any CPU.ActiveCfg = Release|Any CPU + {552E9774-67EF-461E-AECD-80130D33D891}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/BenchtopPDF/BenchtopPDF.sln.DotSettings.user b/BenchtopPDF/BenchtopPDF.sln.DotSettings.user new file mode 100644 index 0000000..0b0a825 --- /dev/null +++ b/BenchtopPDF/BenchtopPDF.sln.DotSettings.user @@ -0,0 +1,3 @@ + + + /usr/lib/mono/msbuild/15.0/bin/MSBuild.dll \ No newline at end of file diff --git a/BenchtopPDF/BenchtopPDF/BenchTopLogo.jpg b/BenchtopPDF/BenchtopPDF/BenchTopLogo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fcd3d68a8b92060d2da70e3bc74770da0cd964c9 GIT binary patch literal 20369 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

rp62jFwWo0O3+ZxinP* z$VGQ0Ay|?7rGTr3Bntt7k|2a_va@r>@0@R4=MTJ-cV;s0GtcaK9toDmi4&X+0Hsgq z>ghP5WplP;P1?^mE=nL2;M)^jo4+r2TuSy7oG;`=4KY&rlkHEa?YzdeF~xr1P*k_1u`0Lw%C!)z@f7=K-0^XnvZ+8)r864bbCj@L9MgR=*NW}b z9tL!_okP)vW`TEQTAz4<2xu5++Q;L=#yIC{iQlpD>kfZ53s$K<0N8ZXY82>89${ zyi8qX(h2n77!_6}lG5{-Q2+Dr{gtUq^A%n`1Qbo0>oB`TT4+zN2vsl*rCEkk#69W- zUq*d_^KWIg19ya~E!QhM6K{)bK2Vljknvx%IT<%KHlYn2Yuw~Ft8hf=RUe?SF+0y) zlIwva=pAMF$v`qK*qU9BSw;E`?m4{okVV9vBZoi+ht}UEc>6i6hZs;863vfRJpe*d z_>(+h>&;z3%Y}rIpHl5u%w8Va-^AZ6jA&G(WJgG=37y@9=&uKp3WhyS5H0*q{- z))$XF$7STg>X9el;QaW`$-4t^jfK$>mnIi>TV34ChLYZstc~qW^|MOPUxi7DUf3WB zr@(8zY5Y4M*=6Qr&_Dkbc-5&Ao2d;pk0>{~-c3%a&C4sNRi3XchfBt+mZ9*cwLePj?IXrr_l>TKDu@21&&*VZCO39QMZjnR2wQ z<3OCxC(Bg_tFr@2y`w`u?H#T@=$+%_Or4ofEMX3U3rI5h!bFWKE#bnO{)A}XCWfdR zgeZyQ4=_KOO6C~mcE@D~hcqjT`YKd5^9iasrA04a9O@b>ZW}93g?2N%X&cSeKTci%ukMS6x@+44Z$^r$4Vl-*agb~}C51iKphXkSED$riU}yE2M#K*P732tLa` zAuG+x+V{ShNLDvoaqt)0LG`Gv#I7cxI^^ndVe(rYB68sN=?zvcrDLvA!onY-IKu{& zjQ{c5fEqMqQeZzC2bqz3jZ(TMZ<(lvx@p?J3)CNugT}%3_jfMq4eko)ub)Y0Ajt3C z)I!@hWPwh#AlPB7UvE%aO;!HRZ$x#r@r3bND9PbhKq6-{Mze7+7!Ty6>x@;PrE#a9 zgTA)!(L6B03MO)O#_mvjZ=9qT>jJZpXmA=sfF<@%NQr9=@PB|esk26c;EPT$;R@3M z8ksYaD&tX{#!1#2^bMf{miY|1vjUlAUYXMyceZh&kby=jthD5sfx(#K z)ui+{n)Q9lTQ3gIx(z8+gxzCr;u6-!e-oAbn7L{?t&26pgBC=@r5n(dhWQkOy$-a_ z8R7r2ZpQt%Zgw(fjRUDF3l+LTmt=z2$ZfxO`NpHae#(%0AE&Okz@s8(iNT-+7>vgW zbUnX<2F`jh&>QTDgB;2e08Xjkdeq<}6HCRqy^wOy=KlYa+?OK29C?>P8-T03#@VKX zCk%mf55i1=xj3q;^xam@9rX9XmQod{+3aq z%a5+*d$#&|H(-UGHXl7qS%ewbf}4Eg>s7{Pc4+c9Eid<;X(3;UjO+bS+4HrgH!!Q@ zGr3!KsciPkyJKBR + + + + Debug + AnyCPU + {552E9774-67EF-461E-AECD-80130D33D891} + Exe + Properties + BenchtopPDF + BenchtopPDF + v4.8 + 512 + true + default + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\HarfBuzzSharp.2.8.2.4-preview.89\lib\net462\HarfBuzzSharp.dll + + + + ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll + + + ..\packages\QuestPDF.2023.6.1\lib\net462\QuestPDF.dll + + + ..\packages\SkiaSharp.2.88.4-preview.89\lib\net462\SkiaSharp.dll + + + ..\packages\SkiaSharp.HarfBuzz.2.88.3\lib\net462\SkiaSharp.HarfBuzz.dll + + + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + + + + + + + + + + + + + Always + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105.The missing file is {0}. + + + + + + + + + + + + + + + + diff --git a/BenchtopPDF/BenchtopPDF/Program.cs b/BenchtopPDF/BenchtopPDF/Program.cs new file mode 100644 index 0000000..7b1cf21 --- /dev/null +++ b/BenchtopPDF/BenchtopPDF/Program.cs @@ -0,0 +1,24 @@ +using Newtonsoft.Json; +using QuestPDF.Fluent; +using QuestPDF.Helpers; +using QuestPDF.Infrastructure; + + + +namespace BenchtopPDF +{ + internal class Program + { + public static void Main(string[] args) + { + QuestPDF.Settings.License = LicenseType.Community; + // TODO get json from file + var data = "{\"Instrument\": \"CTS0JODFDASH\", \"Customer Name\": \"Anthony Souza\", \"Customer Address\": \"PO Box 357, West Chesterfield, NH 03466\", \"Control Number\": \"123123\", \"Serial Number\": \"123313\", \"Accuracy\": 0.5, \"Barometric Pressure\": 1013.25, \"Temperature\": 50.3, \"Humidity\": 27, \"Transducers\": [{\"Accuracy\": 0.005, \"Part Number\": \"D34-442\", \"Value\": \"115PSIA\", \"Transducer Name\": \"1\", \"Transducer Type\": \"Pressure\", \"Instrument Pressure\": [{\"Value\": 0, \"In Range\": true, \"Delta\": 0}, {\"Value\": 20002, \"In Range\": true, \"Delta\": 102}, {\"Value\": 39997, \"In Range\": true, \"Delta\": 197}, {\"Value\": 60010, \"In Range\": true, \"Delta\": 310}, {\"Value\": 80001, \"In Range\": true, \"Delta\": 401}, {\"Value\": 100002, \"In Range\": true, \"Delta\": 502}], \"Master Value\": [{\"Low Limit\": 0, \"Master Value\": 0, \"High Limit\": 0}, {\"Low Limit\": 19900, \"Master Value\": 20000, \"High Limit\": 20099}, {\"Low Limit\": 39800, \"Master Value\": 40000, \"High Limit\": 40199}, {\"Low Limit\": 59700, \"Master Value\": 60000, \"High Limit\": 60299}, {\"Low Limit\": 79600, \"Master Value\": 80000, \"High Limit\": 80399}, {\"Low Limit\": 99500, \"Master Value\": 100000, \"High Limit\": 100499}], \"Verify Date\": \"07/20/22\", \"Verify Time\": \"11:20:26\"}, {\"Accuracy\": 0.005, \"Part Number\": \"A12-221\", \"Value\": \"250SCCM\", \"Transducer Name\": \"2\", \"Transducer Type\": \"Flow\", \"Master Value\": [{\"Low Limit\": 0, \"Master Value\": 0, \"High Limit\": 0}, {\"Low Limit\": 24875, \"Master Value\": 25000, \"High Limit\": 25124}, {\"Low Limit\": 49750, \"Master Value\": 50000, \"High Limit\": 50249}, {\"Low Limit\": 74625, \"Master Value\": 75000, \"High Limit\": 75374}, {\"Low Limit\": 99500, \"Master Value\": 100000, \"High Limit\": 100499}, {\"Low Limit\": 124375, \"Master Value\": 125000, \"High Limit\": 125624}, {\"Low Limit\": 149250, \"Master Value\": 150000, \"High Limit\": 150749}, {\"Low Limit\": 174125, \"Master Value\": 175000, \"High Limit\": 175874}, {\"Low Limit\": 199000, \"Master Value\": 200000, \"High Limit\": 200999}, {\"Low Limit\": 223875, \"Master Value\": 225000, \"High Limit\": 226124}, {\"Low Limit\": 248750, \"Master Value\": 250000, \"High Limit\": 251249}], \"Instrument Flow\": [{\"Value\": -82, \"In Range\": false, \"Delta\": 82}, {\"Value\": 24802, \"In Range\": false, \"Delta\": 73}, {\"Value\": 49664, \"In Range\": false, \"Delta\": 86}, {\"Value\": 74836, \"In Range\": true, \"Delta\": 211}, {\"Value\": 99416, \"In Range\": false, \"Delta\": 84}, {\"Value\": 125289, \"In Range\": true, \"Delta\": 914}, {\"Value\": 150205, \"In Range\": true, \"Delta\": 955}, {\"Value\": 175290, \"In Range\": true, \"Delta\": 1165}, {\"Value\": 200165, \"In Range\": true, \"Delta\": 1165}, {\"Value\": 224748, \"In Range\": true, \"Delta\": 873}, {\"Value\": 249825, \"In Range\": true, \"Delta\": 1075}], \"Verify Date\": \"07/15/21\", \"Verify Time\": \"14:55:10\"}]}"; + var model = JsonConvert.DeserializeObject(data); + + var document = new SheetDocument(model); + document.GeneratePdfAndShow(); + + } + } +} \ No newline at end of file diff --git a/BenchtopPDF/BenchtopPDF/Properties/AssemblyInfo.cs b/BenchtopPDF/BenchtopPDF/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..883331a --- /dev/null +++ b/BenchtopPDF/BenchtopPDF/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("BenchtopPDF")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("BenchtopPDF")] +[assembly: AssemblyCopyright("Copyright © 2023")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("552E9774-67EF-461E-AECD-80130D33D891")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/BenchtopPDF/BenchtopPDF/SheetDocument.cs b/BenchtopPDF/BenchtopPDF/SheetDocument.cs new file mode 100644 index 0000000..acc925f --- /dev/null +++ b/BenchtopPDF/BenchtopPDF/SheetDocument.cs @@ -0,0 +1,170 @@ +using System.Globalization; +using System.Linq; +using QuestPDF.Drawing; +using QuestPDF.Fluent; +using QuestPDF.Helpers; +using QuestPDF.Infrastructure; + +namespace BenchtopPDF +{ + public class SheetDocument : IDocument + { + public static Image LogoImage { get; } = Image.FromFile("BenchTopLogo.jpg"); + + public Sheet Model { get; } + + public SheetDocument(Sheet model) + { + Model = model; + } + + public DocumentMetadata GetMetadata() => DocumentMetadata.Default; + public DocumentSettings GetSettings() + { + return new DocumentSettings(); + } + + public void Compose(IDocumentContainer container) + { + container + .Page(page => + { + page.Margin(50); + + page.Header().Element(ComposeHeader); + page.Content().Element(ComposeContent); + + page.Footer().AlignCenter().Text(text => + { + text.CurrentPageNumber(); + text.Span(" / "); + text.TotalPages(); + }); + }); + } + + void ComposeHeader(IContainer container) + { + container.Row(row => + { + row.RelativeItem().Column(column => + { + column + .Item().Text("Certificate Of Calibration") + .FontSize(20).SemiBold().FontColor(Colors.Blue.Medium); + + column.Item().Text(text => + { + text.Span("Issue date: ").SemiBold(); + text.Span($"{Model.IssueDate:d}"); + }); + }); + + row.ConstantItem(175).Image(LogoImage); + }); + } + + void ComposeContent(IContainer container) + { + container.PaddingVertical(40).Column(column => + { + column.Spacing(20); + + column.Item().Row(row => + { + row.RelativeItem().Component(new AddressComponent("From", Model.SellerAddress)); + row.ConstantItem(50); + row.RelativeItem().Component(new AddressComponent("For", Model.CustomerAddress)); + }); + + column.Item().Element(ComposeTable); + + var totalPrice = Model.Items.Sum(x => x.Price * x.Quantity); + column.Item().PaddingRight(5).AlignRight().Text($"Grand total: {totalPrice:C}").SemiBold(); + + if (!string.IsNullOrWhiteSpace(Model.Comments)) + column.Item().PaddingTop(25).Element(ComposeComments); + }); + } + + void ComposeTable(IContainer container) + { + var headerStyle = TextStyle.Default.SemiBold(); + + container.Table(table => + { + table.ColumnsDefinition(columns => + { + columns.ConstantColumn(25); + columns.RelativeColumn(3); + columns.RelativeColumn(); + columns.RelativeColumn(); + columns.RelativeColumn(); + }); + + table.Header(header => + { + header.Cell().Text("#"); + header.Cell().Text("Product").Style(headerStyle); + header.Cell().AlignRight().Text("Unit price").Style(headerStyle); + header.Cell().AlignRight().Text("Quantity").Style(headerStyle); + header.Cell().AlignRight().Text("Total").Style(headerStyle); + + header.Cell().ColumnSpan(5).PaddingTop(5).BorderBottom(1).BorderColor(Colors.Black); + }); + + foreach (var item in Model.Items) + { + var index = Model.Items.IndexOf(item) + 1; + + table.Cell().Element(CellStyle).Text($"{index}"); + table.Cell().Element(CellStyle).Text(item.Name); + table.Cell().Element(CellStyle).AlignRight().Text($"{item.Price:C}"); + table.Cell().Element(CellStyle).AlignRight().Text($"{item.Quantity}"); + table.Cell().Element(CellStyle).AlignRight().Text($"{item.Price * item.Quantity:C}"); + + static IContainer CellStyle(IContainer container) => container.BorderBottom(1).BorderColor(Colors.Grey.Lighten2).PaddingVertical(5); + } + }); + } + + void ComposeComments(IContainer container) + { + container.ShowEntire().Background(Colors.Grey.Lighten3).Padding(10).Column(column => + { + column.Spacing(5); + column.Item().Text("Comments").FontSize(14).SemiBold(); + column.Item().Text(Model.Comments); + }); + } + } + + public class AddressComponent : IComponent + { + private string Title { get; } + private Address Address { get; } + + public AddressComponent(string title, Address address) + { + Title = title; + Address = address; + } + + public void Compose(IContainer container) + { + container.ShowEntire().Column(column => + { + column.Spacing(2); + + column.Item().Text(Title).SemiBold(); + column.Item().PaddingBottom(5).LineHorizontal(1); + + column.Item().Text(Address.CompanyName); + column.Item().Text(Address.Street); + column.Item().Text($"{Address.City}, {Address.State}"); + column.Item().Text(Address.Email); + column.Item().Text(Address.Phone); + }); + } + } +} \ No newline at end of file diff --git a/BenchtopPDF/BenchtopPDF/SheetModel.cs b/BenchtopPDF/BenchtopPDF/SheetModel.cs new file mode 100644 index 0000000..36c87d6 --- /dev/null +++ b/BenchtopPDF/BenchtopPDF/SheetModel.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace BenchtopPDF +{ + /// Sheet myDeserializedClass = JsonConvert.DeserializeObject(myJsonResponse); + public class InstrumentFlow + { + public int Value { get; set; } + + [JsonProperty("In Range")] + public bool InRange { get; set; } + public int Delta { get; set; } + } + + public class InstrumentPressure + { + public int Value { get; set; } + + [JsonProperty("In Range")] + public bool InRange { get; set; } + public int Delta { get; set; } + } + + public class MasterValue + { + [JsonProperty("Low Limit")] + public int LowLimit { get; set; } + public int Value { get; set; } + + [JsonProperty("High Limit")] + public int HighLimit { get; set; } + } + + public class Sheet + { + public string Instrument { get; set; } + + [JsonProperty("Customer Name")] + public string CustomerName { get; set; } + + [JsonProperty("Customer Address")] + public string CustomerAddress { get; set; } + + [JsonProperty("Control Number")] + public string ControlNumber { get; set; } + + [JsonProperty("Serial Number")] + public string SerialNumber { get; set; } + public double Accuracy { get; set; } + + [JsonProperty("Barometric Pressure")] + public double BarometricPressure { get; set; } + public double Temperature { get; set; } + public int Humidity { get; set; } + public List Transducers { get; set; } + } + + public class Transducer + { + public double Accuracy { get; set; } + + [JsonProperty("Part Number")] + public string PartNumber { get; set; } + public string Value { get; set; } + + [JsonProperty("Transducer Name")] + public string TransducerName { get; set; } + + [JsonProperty("Transducer Type")] + public string TransducerType { get; set; } + + [JsonProperty("Instrument Pressure")] + public List InstrumentPressure { get; set; } + + [JsonProperty("Master Value")] + public List MasterValue { get; set; } + + [JsonProperty("Verify Date")] + public string VerifyDate { get; set; } + + [JsonProperty("Verify Time")] + public string VerifyTime { get; set; } + + [JsonProperty("Instrument Flow")] + public List InstrumentFlow { get; set; } + } + + + + + +} \ No newline at end of file diff --git a/BenchtopPDF/BenchtopPDF/packages.config b/BenchtopPDF/BenchtopPDF/packages.config new file mode 100644 index 0000000..c3adcb2 --- /dev/null +++ b/BenchtopPDF/BenchtopPDF/packages.config @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..7faa4a2 --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# Benchtop Devices Project + + +Django app to parse data from Transducers and Hardware Calibration. + +Returns a PDF and prints a label + + +## App Structure + +``` +├── benchtopdevices # Django Project +│   ├── benchtopdevices +│   └── sheets +└── BenchtopPDF # C# PDF Generator Project +    ├── BenchtopPDF +    └── packages +``` + + + +## TODO + +- [x] Django app to take in data +- [x] Parse data +- [ ] Generate PDF +- [ ] Generate Label diff --git a/benchtopdevices/sheets/parsers/transducer.py b/benchtopdevices/sheets/parsers/transducer.py index 64ef693..e92372f 100644 --- a/benchtopdevices/sheets/parsers/transducer.py +++ b/benchtopdevices/sheets/parsers/transducer.py @@ -1,7 +1,5 @@ -from decimal import * - import re - +import json def in_range(index, value, master_values): return ( @@ -9,10 +7,12 @@ def in_range(index, value, master_values): ) -def parse_transducer(content, accuracy): - getcontext().prec = 6 +def delta(index, value, master_values): + return abs(master_values[index]["Low Limit"] - value) - accuracy = Decimal(f"{accuracy/100.0}") # Comes in as Percent + +def parse_transducer(content, accuracy): + accuracy = accuracy/100.0 # Comes in as Percent transducer_data = [] # Split the content into sections based on the blank line @@ -50,7 +50,6 @@ def parse_transducer(content, accuracy): "Value": value, "Transducer Name": transducer_name, "Transducer Type": transducer_type, - # "Setpoint Pressure": [], "Instrument Pressure": [], "Master Value": [], "Instrument Flow": [], @@ -69,30 +68,30 @@ def parse_transducer(content, accuracy): continue # Toss anything else where it belongs - v = Decimal(value.split(" ")[0]) + v = value.split(" ")[0] key = re.match(r"(.*)\W(\d)", key)[1] if key in transducer_info: - value = Decimal(value.split()[0]) + value = int(float(value.split()[0])*1000) # special case Master to get the limits if "Master" in key: - hi = Decimal(Decimal(1.0) + accuracy) - lo = Decimal(Decimal(1.0) - accuracy) + hi = 1.0 + accuracy + lo = 1.0 - accuracy transducer_info[key].append( { - "Low Limit": lo, - "Value": value, - "High Limit": value * hi, + "Low Limit": int(value*lo), + "Master Value": value, + "High Limit": int(value * hi), } ) else: transducer_info[key].append(value) - + # Once we have the readings, and master values, we can do the math transducer_info[f"Instrument {transducer_type}"] = [ { "Value": v, "In Range": in_range(idx, v, transducer_info["Master Value"]), - "Delta":"TODO" + "Delta": delta(idx, v, transducer_info["Master Value"]) } for idx, v in enumerate(transducer_info[f"Instrument {transducer_type}"]) ] @@ -108,9 +107,18 @@ def parse_transducer(content, accuracy): if __name__ == "__main__": from pprint import pprint - file_path = "./transducer_verify.txt" with open(file_path, "r") as file: - content = file.read() - parsed_data = parse_transducer(content, 0.5) - pprint(parsed_data) + output = { + "Instrument": "CTS0JODFDASH", + "Customer Name": "Anthony Souza", + "Customer Address": "PO Box 357, West Chesterfield, NH 03466", + "Control Number": "123123", + "Serial Number": "123313", + "Accuracy": 0.5, + "Barometric Pressure": 1013.25, + "Temperature": 50.3, + "Humidity": 27, + "Transducers": parse_transducer(file.read(), 0.5) + } + print(json.dumps(output)) diff --git a/benchtopdevices/sheets/templates/sheets/upload.html b/benchtopdevices/sheets/templates/sheets/upload.html index a7717c2..d50c917 100644 --- a/benchtopdevices/sheets/templates/sheets/upload.html +++ b/benchtopdevices/sheets/templates/sheets/upload.html @@ -13,9 +13,35 @@

{% csrf_token %} - {{ form.as_p }} + + + + + + + + + + + + + + + + + + + + + + + + + + +
Customer Name{{ form.customer_name }}
Customer Address{{ form.customer_address }}

Instrument{{ form.instrument }}
Control Number{{ form.control_number }}
Serial Number{{ form.serial_number }}

Accuracy{{ form.accuracy }}
Barometric Pressure (mbar){{ form.barometric_pressure }}
Temperature (°F){{ form.temperature }}
Humidity{{ form.humidity }}

Report Type{{ form.report_type }}
Configuration(s){{ form.configuration }}

As Found: {{ form.as_found }}As Left:{{ form.as_left }}
One File: {{ form.both }}

 
- +
@@ -91,4 +117,6 @@ } }).mount("#app") -{% endverbatim %} \ No newline at end of file +{% endverbatim %} + + \ No newline at end of file