Przeglądaj źródła

Add a form to enter a single business by hand

New /business/new page (linked from the Businesses list) and POST
/business/create. Same fields as the edit form, duplicate phone/email
warning with "Save anyway", status "new", source "Added manually".

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
master
Daniel Covington 2 tygodni temu
rodzic
commit
03dc5c4352
5 zmienionych plików z 231 dodań i 0 usunięć
  1. +103
    -0
      app/controllers/BusinessesController.asp
  2. +13
    -0
      app/repositories/BusinessRepository.asp
  3. +112
    -0
      app/views/Businesses/add.asp
  4. +1
    -0
      app/views/Businesses/index.asp
  5. +2
    -0
      public/Default.asp

+ 103
- 0
app/controllers/BusinessesController.asp Wyświetl plik

@@ -104,6 +104,109 @@ Class BusinessesController_Class
<%
End Sub

'-------------------------------------------------------------------------------------------------------------------
' GET /business/new : blank form to enter a business by hand ("new" is reserved in VBScript, hence the action name)
'-------------------------------------------------------------------------------------------------------------------
Public Sub add()
Dim fv
Set fv = CreateObject("Scripting.Dictionary")
Set fv("_area_ids") = CreateObject("Scripting.Dictionary")
RenderAdd Nothing, fv
End Sub

' dup is a matching other business (or Nothing); fv holds the form values to show.
Private Sub RenderAdd(dup, fv)
Dim industries, allAreas, areaSel, csrf, ix, indKey2
Set industries = BusinessRepository().Industries()
Set allAreas = AreaRepository().All()
Set areaSel = fv("_area_ids")
csrf = Csrf_Token("business")
m_title = "Add business"
%>
<!--#include file="../views/Businesses/add.asp" -->
<%
End Sub

'-------------------------------------------------------------------------------------------------------------------
' POST /business/create
'-------------------------------------------------------------------------------------------------------------------
Public Sub create()
Dim d, email, phone, indName, indSel, areaIds, areaNew, ai, areaId, areaName, dupMatch, fv, k, newId

If Not Csrf_Valid("business", F("csrf")) Then
Flash().AddError "Invalid form state. Please try again."
Response.Redirect "/business/new"
End If

Set d = CreateObject("Scripting.Dictionary")
d("name") = Left(Trim(F("name")), 255)
email = LCase(Left(Trim(F("email")), 255))
phone = Left(Trim(F("phone")), 40)
d("contact_name") = Left(Trim(F("contact_name")), 150)
d("phone") = phone
d("phone_digits") = ImportFile_PhoneDigits(phone)
d("email") = email
d("website") = Left(Trim(F("website")), 255)
d("address1") = Left(Trim(F("address1")), 255)
d("city") = Left(Trim(F("city")), 100)
d("state") = Left(Trim(F("state")), 50)
d("zip") = Left(Trim(F("zip")), 20)
d("notes") = Left(F("notes"), 10000)
If F("is_customer") = "1" Then d("is_customer") = 1 Else d("is_customer") = 0
d("first_order_date") = Date_Parse(F("first_order_date"))

indName = Trim(F("industry_new"))
indSel = F("industry_id")
If Valid_Id(indSel) Then d("industry_id") = CLng(indSel) Else d("industry_id") = Null

Set areaIds = CreateObject("Scripting.Dictionary")
For ai = 1 To Request.Form("area_ids").Count
If Valid_Id(Request.Form("area_ids")(ai)) Then areaIds(CStr(CLng(Request.Form("area_ids")(ai)))) = True
Next
areaNew = Left(Trim(F("area_new")), 500)

Set fv = CreateObject("Scripting.Dictionary")
For Each k In d.Keys
fv(k) = d(k)
Next
fv("_industry_new") = indName
fv("_area_new") = areaNew
Set fv("_area_ids") = areaIds

If Len(d("name")) = 0 Then
Flash().AddError "Business name is required."
RenderAdd Nothing, fv
Exit Sub
End If
If Len(email) > 0 And InStr(email, "@") = 0 Then
Flash().AddError "That email address doesn't look right, so nothing was saved."
RenderAdd Nothing, fv
Exit Sub
End If

' Warn when the phone/email already belongs to another business (unless "Save anyway" was pressed).
If F("allow_duplicate") <> "1" Then
Set dupMatch = BusinessRepository().FindDuplicate(0, d("phone_digits"), d("email"))
If Not dupMatch Is Nothing Then
RenderAdd dupMatch, fv
Exit Sub
End If
End If

If Len(indName) > 0 Then d("industry_id") = BusinessRepository().FindOrCreateIndustry(indName)

newId = BusinessRepository().Create(d)

For Each areaName In Split(areaNew, ",")
areaId = AreaRepository().FindOrCreate(areaName)
If Not IsNull(areaId) Then areaIds(CStr(areaId)) = True
Next
AreaRepository().SetForBusiness newId, areaIds

Flash().Success = "Added " & d("name") & "."
Response.Redirect "/businesses/" & newId
End Sub

'-------------------------------------------------------------------------------------------------------------------
' POST /businesses/:id/update : edit details
'-------------------------------------------------------------------------------------------------------------------


+ 13
- 0
app/repositories/BusinessRepository.asp Wyświetl plik

@@ -217,6 +217,19 @@ Class BusinessRepository_Class
' Changes
'---------------------------------------------------------------------------------------------------------------------

' Inserts a business entered by hand (status "new") and returns its id. d holds the same keys as Update.
Public Function Create(d)
Dim rs
Db_Exec "INSERT INTO businesses (name, contact_name, industry_id, phone, phone_digits, email, website, address1, city, state, zip, " & _
"source, status, is_customer, first_order_date, notes, created_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,Now())", _
Array(Db_PS(d("name")), Db_PS(d("contact_name")), Db_PI(d("industry_id")), Db_PS(d("phone")), Db_PS(d("phone_digits")), Db_PS(d("email")), _
Db_PS(d("website")), Db_PS(d("address1")), Db_PS(d("city")), Db_PS(d("state")), Db_PS(d("zip")), _
Db_PS("Added manually"), Db_PS("new"), Db_PI(d("is_customer")), Db_PD(d("first_order_date")), Db_PS(d("notes")))
Set rs = Db_Query("SELECT @@IDENTITY", Array())
Create = CLng(rs(0))
rs.Close
End Function

Public Sub Update(id, d)
Db_Exec "UPDATE businesses SET name = ?, contact_name = ?, industry_id = ?, phone = ?, phone_digits = ?, email = ?, " & _
"website = ?, address1 = ?, city = ?, state = ?, zip = ?, notes = ?, is_customer = ?, first_order_date = ? WHERE id = ?", _


+ 112
- 0
app/views/Businesses/add.asp Wyświetl plik

@@ -0,0 +1,112 @@
<% Flash().ShowErrorsIfPresent : Flash().ShowSuccessIfPresent %>

<nav aria-label="breadcrumb">
<ol class="breadcrumb small mb-2">
<li class="breadcrumb-item"><a href="/businesses">Businesses</a></li>
<li class="breadcrumb-item active" aria-current="page">Add business</li>
</ol>
</nav>

<h1 class="h3 mb-3">Add business</h1>

<div class="row">
<div class="col-lg-7">
<% If Not dup Is Nothing Then %>
<div class="alert alert-warning small">
<i class="bi bi-exclamation-triangle"></i>
Nothing was saved yet. The <%= dup("matched") %> you entered is already used by
<a href="/businesses/<%= dup("id") %>" target="_blank" rel="noopener"><%= H(dup("name")) %></a>.
Fix it, or press <strong>Save anyway</strong> to add it as a second business.
</div>
<% End If %>

<div class="card shadow-sm mb-3">
<div class="card-body">
<form method="post" action="/business/create">
<input type="hidden" name="csrf" value="<%= H(csrf) %>" />
<% If Not dup Is Nothing Then %><input type="hidden" name="allow_duplicate" value="1" /><% End If %>

<div class="mb-2">
<label class="form-label small mb-1" for="f_name">Business name</label>
<input type="text" class="form-control form-control-sm" id="f_name" name="name" value="<%= H(fv("name")) %>" maxlength="255" required autofocus />
</div>
<div class="mb-2">
<label class="form-label small mb-1" for="f_contact">Contact</label>
<input type="text" class="form-control form-control-sm" id="f_contact" name="contact_name" value="<%= H(fv("contact_name")) %>" maxlength="150" />
</div>
<div class="row g-2 mb-2">
<div class="col-6">
<label class="form-label small mb-1" for="f_phone">Phone</label>
<input type="text" class="form-control form-control-sm" id="f_phone" name="phone" value="<%= H(fv("phone")) %>" maxlength="40" />
</div>
<div class="col-6">
<label class="form-label small mb-1" for="f_email">Email</label>
<input type="text" class="form-control form-control-sm" id="f_email" name="email" value="<%= H(fv("email")) %>" maxlength="255" />
</div>
</div>
<div class="mb-2">
<label class="form-label small mb-1" for="f_web">Website</label>
<input type="text" class="form-control form-control-sm" id="f_web" name="website" value="<%= H(fv("website")) %>" maxlength="255" />
</div>
<div class="mb-2">
<label class="form-label small mb-1" for="f_addr">Address</label>
<input type="text" class="form-control form-control-sm" id="f_addr" name="address1" value="<%= H(fv("address1")) %>" maxlength="255" />
</div>
<div class="row g-2 mb-2">
<div class="col-5"><label class="form-label small mb-1" for="f_city">City</label><input type="text" class="form-control form-control-sm" id="f_city" name="city" value="<%= H(fv("city")) %>" maxlength="100" /></div>
<div class="col-3"><label class="form-label small mb-1" for="f_state">State</label><input type="text" class="form-control form-control-sm" id="f_state" name="state" value="<%= H(fv("state")) %>" maxlength="50" /></div>
<div class="col-4"><label class="form-label small mb-1" for="f_zip">Zip</label><input type="text" class="form-control form-control-sm" id="f_zip" name="zip" value="<%= H(fv("zip")) %>" maxlength="20" /></div>
</div>
<div class="row g-2 mb-2">
<div class="col-6">
<label class="form-label small mb-1" for="f_ind">Industry</label>
<select class="form-select form-select-sm" id="f_ind" name="industry_id">
<option value="">(none)</option>
<% For Each indKey2 In industries.Keys %>
<option value="<%= indKey2 %>"<% If CStr(fv("industry_id") & "") = indKey2 Then Response.Write " selected" %>><%= H(industries(indKey2)) %></option>
<% Next %>
</select>
</div>
<div class="col-6">
<label class="form-label small mb-1" for="f_indnew">&hellip;or add new</label>
<input type="text" class="form-control form-control-sm" id="f_indnew" name="industry_new" maxlength="100" value="<% If fv.Exists("_industry_new") Then Response.Write H(fv("_industry_new")) %>" />
</div>
</div>
<fieldset class="mb-2">
<legend class="form-label small mb-1">Areas served</legend>
<% If allAreas.Count > 0 Then %>
<div class="border rounded px-2 py-1 mb-1" style="max-height:9rem;overflow-y:auto">
<% For ix = 0 To allAreas.Count - 1 %>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="f_area_<%= allAreas(ix)("id") %>" name="area_ids" value="<%= allAreas(ix)("id") %>"<% If areaSel.Exists(CStr(allAreas(ix)("id"))) Then Response.Write " checked" %> />
<label class="form-check-label small" for="f_area_<%= allAreas(ix)("id") %>"><%= H(allAreas(ix)("name")) %></label>
</div>
<% Next %>
</div>
<% End If %>
<label class="visually-hidden" for="f_areanew">Add new areas</label>
<input type="text" class="form-control form-control-sm" id="f_areanew" name="area_new" maxlength="500" placeholder="<% If allAreas.Count > 0 Then Response.Write "&hellip;or add new, comma-separated" Else Response.Write "e.g. Dallas, Fort Worth" %>" value="<% If fv.Exists("_area_new") Then Response.Write H(fv("_area_new")) %>" />
</fieldset>
<div class="row g-2 mb-2 align-items-end">
<div class="col-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="f_cust" name="is_customer" value="1"<% If fv("is_customer") & "" = "1" Then Response.Write " checked" %> />
<label class="form-check-label small" for="f_cust">Previous customer</label>
</div>
</div>
<div class="col-6">
<label class="form-label small mb-1" for="f_first">First order</label>
<input type="date" class="form-control form-control-sm" id="f_first" name="first_order_date" value="<%= Date_Iso(fv("first_order_date")) %>" />
</div>
</div>
<div class="mb-3">
<label class="form-label small mb-1" for="f_notes">Notes</label>
<textarea class="form-control form-control-sm" id="f_notes" name="notes" rows="4" maxlength="10000"><%= H(fv("notes")) %></textarea>
</div>
<button type="submit" class="btn <% If dup Is Nothing Then Response.Write "btn-primary" Else Response.Write "btn-warning" %> btn-sm"><% If dup Is Nothing Then Response.Write "Add business" Else Response.Write "Save anyway" %></button>
<a href="/businesses" class="btn btn-outline-secondary btn-sm">Cancel</a>
</form>
</div>
</div>
</div>
</div>

+ 1
- 0
app/views/Businesses/index.asp Wyświetl plik

@@ -3,6 +3,7 @@
<div class="d-flex justify-content-between align-items-center mb-3">
<h1 class="h3 mb-0">Businesses</h1>
<div class="d-flex gap-2">
<a href="/business/new" class="btn btn-primary btn-sm"><i class="bi bi-plus-lg"></i> Add business</a>
<a href="/export/businesses<%= H(Businesses_QS(f, 1, sort, dir)) %>" class="btn btn-outline-success btn-sm" title="Download everything matching the current search and filters as a spreadsheet (CSV)"><i class="bi bi-download"></i> Export<% If total > 0 Then Response.Write " " & FormatNumber(total, 0) %></a>
<a href="/import" class="btn btn-outline-primary btn-sm"><i class="bi bi-upload"></i> Import</a>
</div>


+ 2
- 0
public/Default.asp Wyświetl plik

@@ -15,6 +15,8 @@

' Businesses
router.AddRoute "GET", "/businesses", "BusinessesController", "Index"
router.AddRoute "GET", "/business/new", "BusinessesController", "Add"
router.AddRoute "POST", "/business/create", "BusinessesController", "Create"
router.AddRoute "GET", "/businesses/:id", "BusinessesController", "Show"
router.AddRoute "POST", "/businesses/:id/update", "BusinessesController", "Update"
router.AddRoute "POST", "/businesses/:id/log", "BusinessesController", "Log"


Ładowanie…
Anuluj
Zapisz

Powered by TurnKey Linux.