| @@ -1,3 +1,4 @@ | |||
| *.csv | |||
| *.mdb | |||
| *.ldb | |||
| *.ldb | |||
| /volumes | |||
| @@ -0,0 +1,39 @@ | |||
| # Repository Guidelines | |||
| ## Project Structure & Module Organization | |||
| - `index.asp` and `web.config` are the IIS entry point and configuration. | |||
| - `App/` contains the application code: `Controllers/`, `Views/`, `DomainModels/`, `ViewModels/`, and `DAL/`. | |||
| - `MVC/` provides the shared Classic ASP MVC framework and helper libraries (`lib.*.asp`). | |||
| - `Data/` stores reports, sample assets, and database migrations under `Data/Migrations/`. | |||
| - `Tests/` holds ASPUnit and test pages (`Test_*.asp`, `TestCase_*.asp`). | |||
| - `ImportService/` and `CiCd/` include VBScript/PowerShell automation. | |||
| - `Dependancies/` contains native/ActiveX binaries used by the app. | |||
| - `dist/` and `uploads/` hold static assets and user-uploaded files. | |||
| ## Build, Test, and Development Commands | |||
| - No build step is required for Classic ASP; run under IIS with the repo as a site root. | |||
| - Run unit tests through IIS by opening `Tests/Test_All.asp` (ASPUnit runner) in a browser. | |||
| - Service/automation scripts are VBScript or PowerShell, e.g. `cscript ImportService/TrackingDataImport.vbs`. | |||
| - `codex.cmd` uses Docker Compose for Codex tooling: `docker compose up -d --build`. | |||
| ## Coding Style & Naming Conventions | |||
| - VBScript/Classic ASP with `Option Explicit` at file start. | |||
| - Keep includes near the top using `<!--#include file="..."-->`. | |||
| - Prefer PascalCase for classes (`HomeController`) and descriptive, PascalCase file names. | |||
| - Migrations live in `Data/Migrations/` and follow `Migration_XX_Description.asp`. | |||
| - No formatter/linter is configured; follow existing indentation and spacing in nearby files. | |||
| ## Testing Guidelines | |||
| - Framework: ASPUnit (`Tests/ASPUnit/`). | |||
| - Test pages: `Tests/Test_*.asp`; test case definitions: `Tests/TestCase_*.asp`. | |||
| - Execute tests through IIS; the runner renders HTML output in the browser. | |||
| ## Commit & Pull Request Guidelines | |||
| - Recent commits are short, descriptive sentences (e.g., “cleanup typo”). | |||
| - Use concise, present-tense messages describing the behavior change. | |||
| - PRs should include: a summary of changes, testing performed (or “not run”), and screenshots for UI changes. | |||
| ## Configuration & Security Notes | |||
| - Review `App/app.config.asp` and `web.config` for environment settings. | |||
| - Do not commit secrets or machine-specific paths; prefer documented placeholders. | |||
| - `Dependancies/` includes executables and ActiveX DLLs; verify licensing before redistribution. | |||
| @@ -131,7 +131,7 @@ Class SnailWorksRepository_Class | |||
| dim rs : set rs = DAL.Query(sql,id) | |||
| If rs.EOF then | |||
| Err.Raise 1,"FindSnailWorksDetailRecordsByKitId","FindSnailWorksDetailRecordsByKitId was not ound with Id of: " & id | |||
| Err.Raise 1,"FindSnailWorksDetailRecordsByKitId","FindSnailWorksDetailRecordsByKitId was not found with Id of: " & id | |||
| Else | |||
| set FindSnailWorksDetailRecordsByKitId = SnailWorksDetailRecordList(rs) | |||
| Destroy rs | |||
| @@ -0,0 +1,163 @@ | |||
| <% | |||
| '======================================================================================================================= | |||
| ' Settings Model | |||
| '======================================================================================================================= | |||
| Class SnailWorksExportModel_Class | |||
| Public Header | |||
| Public DetailRecords | |||
| End Class | |||
| Class SnailWorksExportHeaderModel_Class | |||
| Public Class_Get_Properties | |||
| Public RecordType | |||
| Public Version | |||
| Public UserId | |||
| Public ClientName | |||
| Public ParentClientName | |||
| Public JobName | |||
| Public JobDescription | |||
| Public SplitName | |||
| Public SplitDescription | |||
| Public PieceType | |||
| Public MailDate | |||
| Public UploadType | |||
| Public TrackedQuanity | |||
| Public PiecesMailed | |||
| Public TargetInHomeDateStart | |||
| Public TargetInHomeDateEnd | |||
| Public ConfirmationEmail | |||
| Public JobId | |||
| Public SplitId | |||
| Public TypeOfTracking | |||
| Public ReturnedPostalRoutingCode | |||
| Public ReportId1 | |||
| Public Report1Email | |||
| Public ReportId2 | |||
| Public Report2Email | |||
| Public INFOONLY | |||
| Private Sub Class_Initialize | |||
| 'ValidateExitsts Me, "","" | |||
| Class_Get_Properties = Array("RecordType","Version","UserId","ClientName","ParentClientName","JobName" _ | |||
| ,"JobDescription","SplitName","SplitDescription","PieceType","MailDate","UploadType" _ | |||
| ,"TrackedQuanity","PiecesMailed","TargetInHomeDateStart","TargetInHomeDateEnd","ConfirmationEmail","JobId" _ | |||
| ,"SplitId","TypeOfTracking","ReturnedPostalRoutingCode","ReportId1","Report1Email","ReportId2","Report2Email","INFOONLY") | |||
| End Sub | |||
| End CLass | |||
| Class SnailWorksExportDetailModel_Class | |||
| Public Class_Get_Properties | |||
| Public RecordType | |||
| Public CustomerUniqueIdentifier | |||
| Public IMB | |||
| Public Greeting | |||
| Public FirstName | |||
| Public MI | |||
| Public LastName | |||
| Public Suffix | |||
| Public FullName | |||
| Public Company | |||
| Public Title | |||
| Public Address1 | |||
| Public Address2 | |||
| Public City | |||
| Public State | |||
| Public Zip | |||
| Public UserDefined1 | |||
| Public UserDefined2 | |||
| Public UserDefined3 | |||
| Public UserDefinedIdentifier4 | |||
| Public UserDefinedIdentifier5 | |||
| Public SeedIndicator | |||
| Public InductionPoint | |||
| Public InductionDate | |||
| Public InBoundIMB | |||
| Public IMCB | |||
| Public IMTB | |||
| Private Sub Class_Initialize | |||
| 'ValidateExitsts Me, "","" | |||
| Class_Get_Properties = Array("RecordType","CustomerUniqueIdentifier","IMB","Greeting","FirstName" _ | |||
| ,"MI","LastName","Suffix","FullName","Company","Title","Address1","Address2","City","State","Zip" _ | |||
| ,"UserDefined1","UserDefined2","UserDefined3","UserDefinedIdentifier4","UserDefinedIdentifier5" _ | |||
| ,"SeedIndicator","InductionPoint","InductionDate","InBoundIMB","IMCB","IMTB") | |||
| End Sub | |||
| End Class | |||
| '======================================================================================================================= | |||
| ' SnailWorks Repository | |||
| '======================================================================================================================= | |||
| Class SnailWorksRepository_Class | |||
| Public Function GetSnailWorksExportById(id) | |||
| dim SnailWorksExport:set SnailWorksExport = new SnailWorksExportModel_Class | |||
| set SnailWorksExport.Header = GetSnailWorksHeaderByKitId(id) | |||
| set SnailWorksExport.DetailRecords = FindSnailWorksDetailRecordsByKitId(id) | |||
| set GetSnailWorksExportById = SnailWorksExport | |||
| End Function | |||
| Private Function GetSnailWorksHeaderByKitId(id) | |||
| Dim Header:Set Header = New SnailWorksExportHeaderModel_Class | |||
| dim sql : sql = "SELECT ""H"" as RecordType,""5.2"" as Version, ""KCI2024Type2FTPUser"" as UserId,[Jcode] as ClientName,"""" as ParentClientName," &_ | |||
| """Tracking Kit - "" & [JobNumber] as JobName,"""" as JobDescription,"""" as SplitName,"""" as SplitDescription,""L"" as PieceType," &_ | |||
| "Year(Now()) & ""/"" & RIGHT(""0"" & Month(Now()),2) & ""/"" & RIGHT(""0"" & Day(Now()),2) as MailDate,""N"" as UploadType,"""" as TrackedQuanity," &_ | |||
| """"" as PiecesMailed,"""" as TargetInHomeDateStart,"""" as TargetInHomeDateEnd,""amandaw@kentcommunications.com"" as ConfirmationEmail,"""" as JobId," &_ | |||
| """"" as SplitId,""R"" as TypeofTracking,"""" as ReturnedPostalRoutingCode,"""" as ReportId1," &_ | |||
| """"" as Report1Email,"""" as ReportId2,"""" as Report2Email,"""" as INFOONLY From Kit WHERE ID =?;" | |||
| dim rs : set rs = DAL.Query(sql,id) | |||
| If rs.EOF then | |||
| Err.Raise 1, "GetSnailWorksHeaderByKitId", "SnailWorksHeaderByKitId was not found with Id of: " & id | |||
| Else | |||
| Set GetSnailWorksHeaderByKitId = Automapper.AutoMap(rs,"SnailWorksExportHeaderModel_Class") | |||
| Destroy rs | |||
| End If | |||
| End Function | |||
| Private Function FindSnailWorksDetailRecordsByKitId(id) | |||
| dim sql : sql = "SELECT ""D"" as RecordType, OutboundSerial as CustomerUniqueIdentifier, OutboundIMBDigits as IMB, """" as Greeting , """" as FirstName," &_ | |||
| """"" as MI, """" as LastName,"""" as Suffix,"""" as FullName,"""" as Address1,"""" as Address2,"""" as City,"""" as State," &_ | |||
| """"" as Zip,Jcode as UserDefined1,"""" as UserDefined2,"""" as UserDefined3,"""" as UserDefinedIdentifier4,"""" as UserDefinedIdentifier5,"""" as SeedIndicator," &_ | |||
| """"" as InductionPoint,"""" as InductionDate,InBoundIMBDigits as InboundIMB,"""" as IMCB,"""" as IMTB " &_ | |||
| "FROM (InkjetRecords RIGHT JOIN [KitLabels] ON InkjetRecords.KitLabelID = KitLabels.ID) INNER JOIN Kit On Kit.ID = KitLabels.KitID WHERE KitLabels.KitID = ?" | |||
| dim rs : set rs = DAL.Query(sql,id) | |||
| If rs.EOF then | |||
| Err.Raise 1,"FindSnailWorksDetailRecordsByKitId","FindSnailWorksDetailRecordsByKitId was not ound with Id of: " & id | |||
| Else | |||
| set FindSnailWorksDetailRecordsByKitId = SnailWorksDetailRecordList(rs) | |||
| Destroy rs | |||
| End If | |||
| End Function | |||
| Private Function SnailWorksDetailRecordList(rs) | |||
| dim list : set list = new LinkedList_Class | |||
| dim model | |||
| Do until rs.EOF | |||
| set model = new SnailWorksExportDetailModel_Class | |||
| list.Push Automapper.AutoMap(rs, model) | |||
| rs.MoveNext | |||
| Loop | |||
| set SnailWorksDetailRecordList = list | |||
| End Function | |||
| End Class | |||
| dim SnailWorksRepository__Singleton | |||
| Function SnailWorksRepository() | |||
| If IsEmpty(SnailWorksRepository__Singleton) then | |||
| set SnailWorksRepository__Singleton = new SnailWorksRepository_Class | |||
| End If | |||
| set SnailWorksRepository = SnailWorksRepository__Singleton | |||
| End Function | |||
| %> | |||
| @@ -0,0 +1,71 @@ | |||
| <% | |||
| Class Migration_19_Create_Colors_Table | |||
| Public Migration | |||
| Public Sub Up | |||
| Migration.Do "CREATE TABLE [Colors] (" &_ | |||
| "[ID] COUNTER," &_ | |||
| "[Name] VARCHAR(255)," &_ | |||
| "[Filepath] VARCHAR(255)" &_ | |||
| ");" | |||
| Migration.Do "CREATE UNIQUE INDEX [ID] ON [Colors]( [ID] ) WITH PRIMARY;" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Aqua', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Aqua.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Black', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Black.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Blue', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Blue.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Brown', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Brown.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('BurlyWood', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\BurlyWood.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Chocolate', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Chocolate.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Coral', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Coral.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('CornflowerBlue', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\CornflowerBlue.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Crimson', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Crimson.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('DarkOrange', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\DarkOrange.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('DeepPink', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\DeepPink.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('DeepSkyBlue', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\DeepSkyBlue.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('DimGray', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\DimGray.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('DodgerBlue', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\DodgerBlue.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('FireBrick', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\FireBrick.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('ForestGreen', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\ForestGreen.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Fuchsia', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Fuchsia.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Gold', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Gold.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Goldenrod', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Goldenrod.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Green', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Green.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('HotPink', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\HotPink.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Indigo', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Indigo.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('LightSeaGreen', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\LightSeaGreen.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Lime', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Lime.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('LimeGreen', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\LimeGreen.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('MediumOrchid', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\MediumOrchid.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('MediumPurple', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\MediumPurple.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('MediumTurquoise', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\MediumTurquoise.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Navy', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Navy.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Olive', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Olive.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('OliveDrab', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\OliveDrab.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Orange', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Orange.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('OrangeRed', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\OrangeRed.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Orchid', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Orchid.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Peru', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Peru.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Pink', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Pink.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Purple', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Purple.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Red', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Red.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('RoyalBlue', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\RoyalBlue.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('SaddleBrown', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\SaddleBrown.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('SeaGreen', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\SeaGreen.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Sienna', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Sienna.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Silver', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Silver.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('SteelBlue', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\SteelBlue.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Tan', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Tan.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Teal', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Teal.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Tomato', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Tomato.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Turquoise', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Turquoise.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Violet', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Violet.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('White', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\White.bmp');" | |||
| Migration.Do "INSERT INTO [Colors] ([Name], [Filepath]) VALUES ('Yellow', '\\\\kci1\\inkjet\\BMP\\Purple_ballot_envelopes\\Yellow.bmp');" | |||
| End Sub | |||
| Public Sub Down | |||
| Migration.Do "DROP TABLE [Colors]" | |||
| End Sub | |||
| End Class | |||
| Migrations.Add "Migration_19_Create_Colors_Table" | |||
| %> | |||
| @@ -46,6 +46,7 @@ Migrations.Tracing = false | |||
| <!--#include file="Migration_15_Alter_InkJetRecords_Table_With_KitLabelID.asp"--> | |||
| <!--#include file="Migration_17_Alter_Kit_Table_With_OfficeCopiesAmount.asp"--> | |||
| <!--#include file="Migration_18_Create_CustomOfficeCopyJob_Table.asp"--> | |||
| <!--#include file="Migration_19_Create_Colors_Table.asp"--> | |||
| <% | |||
| Sub HandleMigration | |||
| putl "<b>Starting Version: " & Migrations.Version & "</b>" | |||
| @@ -1,5 +1,5 @@ | |||
| # Define file paths | |||
| $excelFilePath = "C:\Users\danielc\Desktop\Changed Addrs12.xlsx" | |||
| $excelFilePath = "C:\Users\danielc\Desktop\Changed Addrs17.xlsx" | |||
| $accessDbPath = "\\kci-app01\c$\inetpub\Data\webdata - Copy.mdb" | |||
| $tableName = "Jurisdiction" | |||
| @@ -0,0 +1,15 @@ | |||
| FROM node:20-bookworm | |||
| # Useful dev tools (git is handy because Codex often interacts with repos) | |||
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |||
| git \ | |||
| openssh-client \ | |||
| ca-certificates \ | |||
| ripgrep \ | |||
| && rm -rf /var/lib/apt/lists/* | |||
| # Install Codex CLI | |||
| RUN npm i -g @openai/codex@latest | |||
| WORKDIR /workspace | |||
| CMD ["bash"] | |||
| @@ -0,0 +1,298 @@ | |||
| Option Explicit | |||
| Const ForReading = 1 | |||
| Const TristateTrue = -1 | |||
| Dim fso:Set fso = CreateObject("Scripting.FileSystemObject") | |||
| Dim scriptDir: scriptDir = fso.GetParentFolderName(WScript.ScriptFullName) | |||
| Dim repoRoot: repoRoot = fso.GetParentFolderName(scriptDir) | |||
| Dim sourcePath: sourcePath = fso.BuildPath(repoRoot, "ImportService\\TrackingDataImport.vbs") | |||
| Dim objFSO | |||
| Dim DataDirectory | |||
| Dim functionNames | |||
| functionNames = Array( _ | |||
| "PadLeft", _ | |||
| "CheckForFiles", _ | |||
| "Truncate", _ | |||
| "PadString", _ | |||
| "CleanNull", _ | |||
| "Assign", _ | |||
| "Choice", _ | |||
| "CompressArray", _ | |||
| "TrimLeadingZeros", _ | |||
| "PushNonEmptyToBottom", _ | |||
| "GetState", _ | |||
| "GetCityFromLine" _ | |||
| ) | |||
| LoadFunctions sourcePath, functionNames | |||
| Dim passed: passed = 0 | |||
| Dim failed: failed = 0 | |||
| Dim q: q = Chr(34) | |||
| AssertEqual Truncate("abcdef", 3), q & "abc" & q & ",", "Truncate trims and quotes" | |||
| AssertEqual Truncate("ab", 3), q & "ab" & q & ",", "Truncate short string" | |||
| AssertEqual PadLeft("7", 3, "0"), "007", "PadLeft pads" | |||
| AssertEqual PadLeft("1234", 3, "0"), "1234", "PadLeft no pad when longer" | |||
| AssertEqual PadString("ab", 4), "ab ", "PadString right pads" | |||
| AssertEqual PadString("abcd", 4), "abcd", "PadString same length" | |||
| AssertEqual PadString(Null, 3), " ", "PadString null" | |||
| AssertEqual CleanNull(Null), "", "CleanNull null" | |||
| AssertEqual CleanNull("x"), "x", "CleanNull value" | |||
| Dim arr | |||
| arr = Array("", "a", "", "b") | |||
| arr = CompressArray(arr) | |||
| AssertArrayEqual arr, Array("a", "b", "", ""), "CompressArray moves blanks to end" | |||
| AssertEqual TrimLeadingZeros("000123"), "123", "TrimLeadingZeros removes leading zeros" | |||
| AssertEqual TrimLeadingZeros("0000"), "", "TrimLeadingZeros all zeros" | |||
| Dim arr2 | |||
| arr2 = Array("a", "", "b", "") | |||
| PushNonEmptyToBottom arr2 | |||
| AssertArrayEqual arr2, Array("", "", "a", "b"), "PushNonEmptyToBottom" | |||
| AssertEqual GetState("Lansing, MI 48906"), "MI", "GetState matches state" | |||
| AssertEqual GetState("No match"), "", "GetState no match" | |||
| AssertEqual GetCityFromLine("Lansing, MI 48906"), "Lansing", "GetCityFromLine with comma" | |||
| AssertEqual GetCityFromLine("NoComma"), "NoComma", "GetCityFromLine no comma" | |||
| AssertEqual GetCityFromLine(Null), "", "GetCityFromLine null" | |||
| Dim tempDir | |||
| tempDir = fso.BuildPath(repoRoot, "Tests\\_tmp_checkforfiles") | |||
| If Not fso.FolderExists(tempDir) Then | |||
| fso.CreateFolder tempDir | |||
| End If | |||
| Set objFSO = fso | |||
| DataDirectory = tempDir | |||
| On Error Resume Next | |||
| Dim checkResult | |||
| checkResult = CheckForFiles() | |||
| If Err.Number = 0 Then | |||
| passed = passed + 1 | |||
| WScript.Echo "PASS: CheckForFiles runs without error (empty dir)" | |||
| Else | |||
| failed = failed + 1 | |||
| WScript.Echo "FAIL: CheckForFiles error " & Err.Number & " - " & Err.Description | |||
| Err.Clear | |||
| End If | |||
| On Error GoTo 0 | |||
| WScript.Echo "" | |||
| WScript.Echo "Passed: " & passed | |||
| WScript.Echo "Failed: " & failed | |||
| If failed > 0 Then | |||
| WScript.Quit 1 | |||
| End If | |||
| Sub LoadFunctions(ByVal filePath, ByVal names) | |||
| Dim fileText, lines, i, line | |||
| Dim capturing: capturing = False | |||
| Dim endKeyword: endKeyword = "" | |||
| Dim block: block = "" | |||
| If Not fso.FileExists(filePath) Then | |||
| WScript.Echo "FAIL: Source file not found: " & filePath | |||
| WScript.Quit 1 | |||
| End If | |||
| With fso.OpenTextFile(filePath, ForReading, False, TristateTrue) | |||
| fileText = .ReadAll | |||
| .Close | |||
| End With | |||
| ' Normalize line endings and remove nulls/BOM that can appear in UTF-16 reads | |||
| fileText = Replace(fileText, ChrW(&HFEFF), "") | |||
| fileText = Replace(fileText, Chr(0), "") | |||
| fileText = Replace(fileText, vbTab, " ") | |||
| fileText = Replace(fileText, vbCrLf, vbLf) | |||
| fileText = Replace(fileText, vbCr, vbLf) | |||
| lines = Split(fileText, vbLf) | |||
| For i = 0 To UBound(lines) | |||
| line = lines(i) | |||
| If Not capturing Then | |||
| Dim nameIndex | |||
| For nameIndex = 0 To UBound(names) | |||
| Dim kind | |||
| If TryStartLine(line, names(nameIndex), kind) Then | |||
| capturing = True | |||
| endKeyword = "End " & kind | |||
| block = block & line & vbCrLf | |||
| Exit For | |||
| End If | |||
| Next | |||
| Else | |||
| block = block & line & vbCrLf | |||
| If LCase(Trim(line)) = LCase(endKeyword) Then | |||
| capturing = False | |||
| block = block & vbCrLf | |||
| End If | |||
| End If | |||
| Next | |||
| If Len(block) = 0 Then | |||
| ' Fallback: simple text scan for each function/sub | |||
| Dim nameIndex2 | |||
| For nameIndex2 = 0 To UBound(names) | |||
| Dim extracted | |||
| extracted = ExtractBlock(fileText, names(nameIndex2)) | |||
| If Len(extracted) > 0 Then | |||
| block = block & extracted & vbCrLf & vbCrLf | |||
| End If | |||
| Next | |||
| End If | |||
| If Len(block) = 0 Then | |||
| WScript.Echo "FAIL: No functions loaded from " & filePath | |||
| WScript.Echo "Debug: file length=" & Len(fileText) | |||
| WScript.Quit 1 | |||
| End If | |||
| ExecuteGlobal block | |||
| End Sub | |||
| Function ExtractBlock(ByVal fileText, ByVal name) | |||
| Dim lowerText, lowerName, startPos, endPos, kind, endToken | |||
| lowerText = LCase(fileText) | |||
| lowerName = LCase(name) | |||
| startPos = FindDeclPos(lowerText, lowerName, "function") | |||
| kind = "Function" | |||
| If startPos = 0 Then | |||
| startPos = FindDeclPos(lowerText, lowerName, "sub") | |||
| kind = "Sub" | |||
| End If | |||
| If startPos = 0 Then | |||
| ExtractBlock = "" | |||
| Exit Function | |||
| End If | |||
| endToken = "end " & LCase(kind) | |||
| endPos = InStr(startPos, lowerText, endToken) | |||
| If endPos = 0 Then | |||
| ExtractBlock = "" | |||
| Exit Function | |||
| End If | |||
| endPos = endPos + Len(endToken) - 1 | |||
| ExtractBlock = Mid(fileText, startPos, endPos - startPos + 1) | |||
| End Function | |||
| Function FindDeclPos(ByVal lowerText, ByVal lowerName, ByVal keyword) | |||
| Dim pos, idx, ch, nameLen, nextChar | |||
| nameLen = Len(lowerName) | |||
| pos = InStr(1, lowerText, keyword) | |||
| Do While pos > 0 | |||
| idx = pos + Len(keyword) | |||
| Do While idx <= Len(lowerText) | |||
| ch = Mid(lowerText, idx, 1) | |||
| If IsWs(ch) Then | |||
| idx = idx + 1 | |||
| Else | |||
| Exit Do | |||
| End If | |||
| Loop | |||
| If LCase(Mid(lowerText, idx, nameLen)) = lowerName Then | |||
| nextChar = Mid(lowerText, idx + nameLen, 1) | |||
| If nextChar = "" Or Not IsNameChar(nextChar) Then | |||
| FindDeclPos = pos | |||
| Exit Function | |||
| End If | |||
| End If | |||
| pos = InStr(pos + 1, lowerText, keyword) | |||
| Loop | |||
| FindDeclPos = 0 | |||
| End Function | |||
| Function IsWs(ByVal ch) | |||
| IsWs = (ch = " " Or ch = vbTab Or ch = vbLf Or ch = vbCr Or AscW(ch) = 160) | |||
| End Function | |||
| Function IsNameChar(ByVal ch) | |||
| Dim code | |||
| code = AscW(ch) | |||
| IsNameChar = (code >= 48 And code <= 57) Or (code >= 65 And code <= 90) Or (code >= 97 And code <= 122) Or ch = "_" | |||
| End Function | |||
| Function TryStartLine(ByVal line, ByVal name, ByRef kind) | |||
| Dim lowerLine, lowerName, pos | |||
| lowerLine = LCase(line) | |||
| lowerName = LCase(name) | |||
| pos = FindDeclPos(lowerLine, lowerName, "function") | |||
| If pos > 0 Then | |||
| kind = "Function" | |||
| TryStartLine = True | |||
| Exit Function | |||
| End If | |||
| pos = FindDeclPos(lowerLine, lowerName, "sub") | |||
| If pos > 0 Then | |||
| kind = "Sub" | |||
| TryStartLine = True | |||
| Exit Function | |||
| End If | |||
| TryStartLine = False | |||
| End Function | |||
| Sub AssertEqual(ByVal actual, ByVal expected, ByVal testName) | |||
| If actual = expected Then | |||
| passed = passed + 1 | |||
| WScript.Echo "PASS: " & testName | |||
| Else | |||
| failed = failed + 1 | |||
| WScript.Echo "FAIL: " & testName & " | expected=" & FormatValue(expected) & " actual=" & FormatValue(actual) | |||
| End If | |||
| End Sub | |||
| Sub AssertArrayEqual(ByVal actual, ByVal expected, ByVal testName) | |||
| Dim ok: ok = True | |||
| Dim i | |||
| If (UBound(actual) <> UBound(expected)) Then | |||
| ok = False | |||
| Else | |||
| For i = 0 To UBound(actual) | |||
| If actual(i) <> expected(i) Then | |||
| ok = False | |||
| Exit For | |||
| End If | |||
| Next | |||
| End If | |||
| If ok Then | |||
| passed = passed + 1 | |||
| WScript.Echo "PASS: " & testName | |||
| Else | |||
| failed = failed + 1 | |||
| WScript.Echo "FAIL: " & testName & " | expected=" & ArrayToString(expected) & " actual=" & ArrayToString(actual) | |||
| End If | |||
| End Sub | |||
| Function ArrayToString(ByVal arr) | |||
| Dim i, s | |||
| s = "[" | |||
| For i = 0 To UBound(arr) | |||
| If i > 0 Then s = s & ", " | |||
| s = s & FormatValue(arr(i)) | |||
| Next | |||
| s = s & "]" | |||
| ArrayToString = s | |||
| End Function | |||
| Function FormatValue(ByVal v) | |||
| If IsNull(v) Then | |||
| FormatValue = "<null>" | |||
| Else | |||
| FormatValue = "\"" & CStr(v) & "\"" | |||
| End If | |||
| End Function | |||
| @@ -0,0 +1,3 @@ | |||
| mkdir .\volumes\codex_home | |||
| docker compose up -d --build | |||
| docker compose exec codex bash | |||
| @@ -0,0 +1,29 @@ | |||
| services: | |||
| codex: | |||
| build: | |||
| context: . | |||
| dockerfile: Dockerfile | |||
| container_name: TrackingKits-codex | |||
| working_dir: /workspace | |||
| tty: true | |||
| stdin_open: true | |||
| # Mount your current folder into /workspace (run compose from your repo folder) | |||
| volumes: | |||
| - ./:/workspace | |||
| # Persist Codex auth + config (maps to CODEX_HOME) | |||
| - ./volumes/codex_home:/codex | |||
| # Optional (recommended if you want Codex to run docker commands): | |||
| # Gives the container access to your host Docker daemon. | |||
| # SECURITY NOTE: docker.sock is effectively root on the host. | |||
| - /var/run/docker.sock:/var/run/docker.sock | |||
| environment: | |||
| - CODEX_HOME=/codex | |||
| # Optional: if you prefer API-key auth instead of ChatGPT login | |||
| # - OPENAI_API_KEY=${OPENAI_API_KEY} | |||
| # Keep container running so you can exec into it anytime | |||
| command: ["bash", "-lc", "sleep infinity"] | |||
Powered by TurnKey Linux.