Add print button

This commit is contained in:
metamuffin 2025-05-13 19:29:56 +02:00
parent ee7987599e
commit 3b5948682a
No known key found for this signature in database
GPG key ID: 718F9749DCDBD654
2 changed files with 154 additions and 146 deletions

View file

@ -114,6 +114,8 @@ local translations = load_translations({ "en", config.language })
local stylesheet = io.open("style.css"):read("a")
local script = io.open("script.js"):read("a")
local can_print = false
local function format(template, params)
params = params or {}
if template == nil then return "NIL TEMPLATE" end
@ -144,23 +146,23 @@ local function format_amount(amount, tag, classes)
end
local function format_list(list)
if list == nil then
return nil
end
if list == nil then
return nil
end
local not_first = false
local out = ""
for _, barcode in pairs(list) do
if not_first then
out = out .. ", " .. barcode
else
out = barcode
end
local not_first = false
local out = ""
for _, barcode in pairs(list) do
if not_first then
out = out .. ", " .. barcode
else
out = barcode
end
not_first = true
end
not_first = true
end
return out
return out
end
local function get_user_theme(username)
@ -225,6 +227,7 @@ local function respond(status, title, body)
<a href="/?spus">{+spus}</a>
<a href="/?products">{+products}</a>
<a href="/?log">{+log}</a>
{print_button}
<a href="/?about">{+about}</a>
</nav>
]], {
@ -232,7 +235,9 @@ local function respond(status, title, body)
style = stylesheet,
user_style = get_user_theme(path and path:sub(2)),
script = script,
head_extra = config.head_extra or ""
head_extra = config.head_extra or "",
print_button = can_print and
[[<script>document.write('<a href="javascript:print()" style="float:right;">{+print}</a>')</script>]] or ""
}))
if config.header ~= nil then
print(config.header)
@ -373,24 +378,24 @@ local function r_transaction_post()
local pcode = data.pcode
local pcount = tonumber(data.pcount)
local comment = data.comment
local pname = data.pname
local pname = data.pname
if pname ~= nil or (pcode ~= nil and pcode ~= "") then
-- check if barcode exists
if pname == nil then
local exists = false
for p_name, p_barcode in read_barcodes() do
if p_barcode == pcode then
exists = true
pname = p_name
end
end
if not exists then
return error_box("{+error.unknown_barcode}")
end
-- check if barcode exists
if pname == nil then
local exists = false
for p_name, p_barcode in read_barcodes() do
if p_barcode == pcode then
exists = true
pname = p_name
end
end
if not exists then
return error_box("{+error.unknown_barcode}")
end
end
-- check if product exists
-- check if product exists
local exists = false
for p_amount, p_user, p_name in read_products() do
if pname == p_name then
@ -403,11 +408,11 @@ local function r_transaction_post()
end
end
if not exists then
return error_box("{+error.unknown_product}: "..pname)
return error_box("{+error.unknown_product}: " .. pname)
end
end
-- for outside money
-- for outside money
user_src = user_src or "@Potential"
if amount == nil then
return error_box("{+error.invalid_amount}")
@ -469,8 +474,8 @@ local function r_user(username)
{ time = format_duration(os.time() - last_txn), username = urlencode(username) }))
print([[</div>]])
end
print([[<ul class="userforms"><li>
print([[<ul class="userforms"><li>
<div class="amount-presets backgroundbox">]])
for _, type in ipairs({ 1, -1 }) do
for _, amount in ipairs({ 50, 100, 150, 200, 500, 1000 }) do
@ -490,45 +495,45 @@ local function r_user(username)
end
end
print("</div></li>")
print(format([[<li><div class="backgroundbox shortcuts">
<h3>{+user.shortcuts}</h3>]]))
local lastcategory = nil
-- user is category; @ is removed for ZSKs
for price, category, name in read_products() do
if lastcategory ~= category then
if lastcategory ~= nil then
print("</ul></div></label>")
end
print(format([[<label>
-- user is category; @ is removed for ZSKs
for price, category, name in read_products() do
if lastcategory ~= category then
if lastcategory ~= nil then
print("</ul></div></label>")
end
print(format([[<label>
<input type="checkbox" hidden />
<div>
<span class="button amount-ntr">{c}</span>
<ul>]], {
c = category:gsub("@", ""),
}))
c = category:gsub("@", ""),
}))
lastcategory = category
end
lastcategory = category
end
print(format([[<li><form method="POST">
print(format([[<li><form method="POST">
<input type="text" name="user_dst" value="{!username}" hidden />
<input type="number" name="pcount" value="-1" hidden />
<input type="text" name="pname" value="{name}" hidden />
<input type="text" name="pname" value="{name}" hidden />
<input class="button amount-ntr" value="{name}
{+price.amount}" type="submit" />
</form></li>]], {
name = name,
username = username,
sign = price >= 0 and "-" or "+",
amount = string.format("%.2f", math.abs(price / 100)),
unit = config.unit or "",
}))
end
print("</ul></div></label>")
name = name,
username = username,
sign = price >= 0 and "-" or "+",
amount = string.format("%.2f", math.abs(price / 100)),
unit = config.unit or "",
}))
end
print("</ul></div></label>")
print("</div></li>")
print(format([[
print("</div></li>")
print(format([[
<li><form class="transaction box backgroundbox {disable_class}" action="" method="POST">
<h3>{+user.form.transaction}</h3>
<input type="text" name="user_dst" value="{!username}" hidden />
@ -552,13 +557,13 @@ local function r_user(username)
<h3>{+user.form.transfer}</h3>
<label for="user_dst">{+field.destination}: </label>
<select name="user_dst">]],
{ username = username, disable_class = is_special and "disabled" or "" }))
local users = get_active_users();
for _, u in ipairs(users) do
if u.name ~= username then
print(format([[<option value="{!name}">{name}</option>]], { name = u.name }))
end
end
{ username = username, disable_class = is_special and "disabled" or "" }))
local users = get_active_users();
for _, u in ipairs(users) do
if u.name ~= username then
print(format([[<option value="{!name}">{name}</option>]], { name = u.name }))
end
end
print(format([[</select>
<input type="text" name="user_src" value="{!username}" hidden />
<label for="amount">{+field.amount}: </label>
@ -579,8 +584,8 @@ local function r_user(username)
<input type="submit" value="{+user.form.restock.submit}" class="button amount-pos" />
</form></li>]],
{
username = username,
disable_class = is_special and "disabled" or "",
username = username,
disable_class = is_special and "disabled" or "",
}))
print("</ul>")
end)
@ -591,6 +596,7 @@ local function r_log(filter)
if method == "POST" then
notif = r_transaction_post()
end
can_print = true
return respond(200, "Abrechnungen", function()
if notif then print(notif) end
print([[<table class="log"]])
@ -648,9 +654,9 @@ local function r_log(filter)
end
local function r_users(show_special, filter_negative)
if filter_negative ~= nil then
filter_negative = tonumber(filter_negative) or 0
end
if filter_negative ~= nil then
filter_negative = tonumber(filter_negative) or 0
end
return respond(200, "Abrechenbarkeit", function()
local users = get_active_users()
@ -701,8 +707,8 @@ local function r_users(show_special, filter_negative)
local is_spu = user.name:sub(1, 1) == "@"
local filter_out = query.prefix ~= nil and user.name:sub(1, 1):lower() ~= query.prefix
if is_spu == show_special and
((filter_negative ~= nil and user.balance < filter_negative)
or (filter_negative == nil and (not filter_out))) then
((filter_negative ~= nil and user.balance < filter_negative)
or (filter_negative == nil and (not filter_out))) then
print(format([[<li>
<a href="/{username_url}">
<span class="name">{!username}</span>
@ -715,31 +721,31 @@ local function r_users(show_special, filter_negative)
}))
end
end
if filter_negative ~= nil then
table.sort(users, function(a, b)
return a.balance < b.balance
end)
table.sort(users, function(a, b)
return a.balance < b.balance
end)
end
local inactive_cutoff = os.time() - (tonumber(config.inactive_cutoff) or (30 * 24 * 60 * 60))
local embezzlement = 0
for _, user in ipairs(users) do
for _, user in ipairs(users) do
if filter_negative or user.time > inactive_cutoff then
show_user(user)
show_user(user)
if user.name:sub(1,1) ~= "@" then
if user.balance < 0 then embezzlement = embezzlement - user.balance end
end
if user.name:sub(1, 1) ~= "@" then
if user.balance < 0 then embezzlement = embezzlement - user.balance end
end
end
end
print("</ul>")
if filter_negative ~= nil then
print(format([[<section class="section" style="margin-top: 0">{+users.embezzlement}</section>]], {
amount = format_amount(embezzlement)
}))
print(format([[<section class="section" style="margin-top: 0">{+users.embezzlement}</section>]], {
amount = format_amount(embezzlement)
}))
return
return
end
print(format([[
<details {oclass}><summary>{+users.inactive_list}</summary><ul class="userlist">
@ -763,7 +769,7 @@ local function r_products_post()
local data = form_data()
if data.deletebarcode then
local barcode = data.barcode
local barcode = data.barcode
-- remove barcode
local new_barcodes = io.open("barcodes.new", "w+")
@ -778,9 +784,9 @@ local function r_products_post()
new_barcodes:flush()
new_barcodes:close()
os.rename("barcodes.new", "barcodes")
return
return
end
local name = data.name
if name == nil or name:match("^" .. matchers.name .. "$") == nil then
return error_box("{+error.invalid_name}")
@ -801,31 +807,31 @@ local function r_products_post()
new_products:close()
os.rename("products.new", "products")
elseif data.addbarcode then
-- add barcode
local name = data.name
local barcode = data.barcode
-- add barcode
local name = data.name
local barcode = data.barcode
if name == nil or name:match(matchers_global.name) == nil then
return error_box("{+error.invalid_name}")
end
if barcode == nil or barcode:match(matchers_global.barcode) == nil then
return error_box("{+error.invalid_barcode}")
end
local exists = false
for _, a_barcode in read_barcodes() do
if a_barcode == barcode then
exists = true
end
end
local exists = false
for _, a_barcode in read_barcodes() do
if a_barcode == barcode then
exists = true
end
end
if exists then
return error_box("{+error.invalid_barcode}")
end
if exists then
return error_box("{+error.invalid_barcode}")
end
local barcodes = io.open("barcodes", "a+")
if barcodes == nil then
return error_box("{+error.open_barcodes}")
end
barcodes:write(string.format("%s,%s\n", name, barcode))
local barcodes = io.open("barcodes", "a+")
if barcodes == nil then
return error_box("{+error.open_barcodes}")
end
barcodes:write(string.format("%s,%s\n", name, barcode))
barcodes:flush()
barcodes:close()
else
@ -841,26 +847,26 @@ local function r_products_post()
if user == nil or user:match(matchers_global.user) == nil then
return error_box("{+error.invalid_user}")
end
-- add product
-- add product
local new_products = io.open("products.new", "w+")
if new_products == nil then
return error_box("{+error.open_new_products}")
end
local wrote = nil
-- prepend to any block in the file containing products of the same user
-- the shortcuts feature expects this!
local wrote = nil
-- prepend to any block in the file containing products of the same user
-- the shortcuts feature expects this!
for a_price, a_user, a_name in read_products() do
if user == a_user and not wrote then
wrote = true
products:write(string.format("%d,%s,%s\n", price, user, name))
wrote = true
products:write(string.format("%d,%s,%s\n", price, user, name))
end
new_products:write(string.format("%d,%s,%s\n", a_price, a_user, a_name))
end
-- append if not wrote already
if not wrote then
products:write(string.format("%d,%s,%s\n", price, user, name))
-- append if not wrote already
if not wrote then
products:write(string.format("%d,%s,%s\n", price, user, name))
end
new_products:flush()
@ -874,6 +880,7 @@ local function r_products()
if method == "POST" then
notif = r_products_post()
end
can_print = true
respond(200, "Abrechenbare Product List", function()
print(format("<h1>{+products.title}</h1>"))
if notif then print(notif) end
@ -895,15 +902,15 @@ local function r_products()
<label for="name">{+field.name}: </label>
<select type="text" name="name" id="name">
]], {
currency = config.unit or "",
currency = config.unit or "",
}))
for _, _, name in read_products() do
print(format([[<option value="{name}">{name}</option>]], {
name = name,
}))
end
print(format([[</select>
print(format([[<option value="{name}">{name}</option>]], {
name = name,
}))
end
print(format([[</select>
<label for="barcode">{+field.barcode}: </label>
<input type="text" name="barcode" id="barcode" />
<input type="submit" value="{+products.form.add.submit}" class="amount-ntr button" />
@ -914,14 +921,14 @@ local function r_products()
<label for="name">{+field.name}: </label>
<select type="text" name="name" id="name">
]], {
currency = config.unit or "",
currency = config.unit or "",
}))
for _, _, name in read_products() do
print(format([[<option value="{name}">{!name}</option>]], {
name = name,
}))
end
print(format([[</select>
print(format([[<option value="{name}">{!name}</option>]], {
name = name,
}))
end
print(format([[</select>
<input type="submit" value="{+products.form.remove.submit}" class="amount-ntr button" />
</form>
<!-- remove barcode -->
@ -931,24 +938,24 @@ local function r_products()
<label for="barcode">{+field.barcode}: </label>
<select type="text" name="barcode" id="barcode">
]], {
currency = config.unit or "",
currency = config.unit or "",
}))
local barcodes = {}
for name, barcode in read_barcodes() do
print(format([[<option value="{barcode}">{!barcode} ({!name})</option>]], {
name = name,
barcode = barcode,
}))
if barcodes[name] ~= nil then
table.insert(barcodes[name], barcode)
else
barcodes[name] = {}
table.insert(barcodes[name], barcode)
end
end
print(format([[<option value="{barcode}">{!barcode} ({!name})</option>]], {
name = name,
barcode = barcode,
}))
if barcodes[name] ~= nil then
table.insert(barcodes[name], barcode)
else
barcodes[name] = {}
table.insert(barcodes[name], barcode)
end
end
print(format([[</select>
print(format([[</select>
<input type="submit" value="{+products.form.remove.submit}" class="amount-ntr button" />
</form>
</div>
@ -977,8 +984,8 @@ local function r_products()
user = user,
barcodes = format_list(barcodes[name]) or "{+field.not_set}",
}))
end
end
print("</table>")
end)
end
@ -1063,7 +1070,7 @@ if path == "/" then
elseif query.spus then
return r_users(true, nil)
elseif query.users and query.export then
return r_export_balances()
return r_export_balances()
else
return r_users(false, query.negative and (query.maximum or 0))
end

View file

@ -79,3 +79,4 @@ error.open_barcodes=Failed to open barcodes file
error.no_path=No path
users.inactive_list=Inactive Users
users.embezzlement=A total of {amount} are currently under embezzlement.
print=Print