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 0000000..fcd3d68 Binary files /dev/null and b/BenchtopPDF/BenchtopPDF/BenchTopLogo.jpg differ diff --git a/BenchtopPDF/BenchtopPDF/BenchtopPDF.csproj b/BenchtopPDF/BenchtopPDF/BenchtopPDF.csproj new file mode 100644 index 0000000..50f6a1b --- /dev/null +++ b/BenchtopPDF/BenchtopPDF/BenchtopPDF.csproj @@ -0,0 +1,110 @@ + + + + + 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