mirror of
https://codeberg.org/metamuffin/abrechenbarkeit.git
synced 2025-05-23 14:54:46 +00:00
add shortcuts to user list to purchase items without scanning
slight mirgation, i.e. sorting products by user is necessary
This commit is contained in:
parent
48cbf9adcd
commit
868fa10610
4 changed files with 138 additions and 29 deletions
|
@ -373,25 +373,27 @@ local function r_transaction_post()
|
||||||
local pcode = data.pcode
|
local pcode = data.pcode
|
||||||
local pcount = tonumber(data.pcount)
|
local pcount = tonumber(data.pcount)
|
||||||
local comment = data.comment
|
local comment = data.comment
|
||||||
local barcode_name = nil
|
local pname = data.pname
|
||||||
|
|
||||||
if pcode ~= nil and pcode ~= "" then
|
if pname ~= nil or (pcode ~= nil and pcode ~= "") then
|
||||||
-- check if barcode exists
|
-- check if barcode exists
|
||||||
local exists = false
|
if pname == nil then
|
||||||
for p_name, p_barcode in read_barcodes() do
|
local exists = false
|
||||||
if p_barcode == pcode then
|
for p_name, p_barcode in read_barcodes() do
|
||||||
exists = true
|
if p_barcode == pcode then
|
||||||
barcode_name = p_name
|
exists = true
|
||||||
|
pname = p_name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
if not exists then
|
||||||
if not exists then
|
return error_box("{+error.unknown_barcode}")
|
||||||
return error_box("{+error.unknown_barcode}")
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- check if product exists
|
-- check if product exists
|
||||||
local exists = false
|
local exists = false
|
||||||
for p_amount, p_user, p_name in read_products() do
|
for p_amount, p_user, p_name in read_products() do
|
||||||
if barcode_name == p_name then
|
if pname == p_name then
|
||||||
pcount = (tonumber(data.pcount) or 1) * (data.negate_pcount ~= nil and -1 or 1)
|
pcount = (tonumber(data.pcount) or 1) * (data.negate_pcount ~= nil and -1 or 1)
|
||||||
amount = amount or pcount * p_amount
|
amount = amount or pcount * p_amount
|
||||||
user_src = user_src or p_user
|
user_src = user_src or p_user
|
||||||
|
@ -401,7 +403,7 @@ local function r_transaction_post()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not exists then
|
if not exists then
|
||||||
return error_box("{+error.unknown_product}"..barcode_name)
|
return error_box("{+error.unknown_product}: "..pname)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -467,8 +469,8 @@ local function r_user(username)
|
||||||
{ time = format_duration(os.time() - last_txn), username = urlencode(username) }))
|
{ time = format_duration(os.time() - last_txn), username = urlencode(username) }))
|
||||||
print([[</div>]])
|
print([[</div>]])
|
||||||
end
|
end
|
||||||
print([[
|
|
||||||
<ul class="userforms"><li>
|
print([[<ul class="userforms"><li>
|
||||||
<div class="amount-presets backgroundbox">]])
|
<div class="amount-presets backgroundbox">]])
|
||||||
for _, type in ipairs({ 1, -1 }) do
|
for _, type in ipairs({ 1, -1 }) do
|
||||||
for _, amount in ipairs({ 50, 100, 150, 200, 500, 1000 }) do
|
for _, amount in ipairs({ 50, 100, 150, 200, 500, 1000 }) do
|
||||||
|
@ -488,6 +490,44 @@ local function r_user(username)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
print("</div></li>")
|
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>
|
||||||
|
<input type="checkbox" hidden />
|
||||||
|
<div>
|
||||||
|
<span class="button amount-ntr">{c}</span>
|
||||||
|
<ul>]], {
|
||||||
|
c = category:gsub("@", ""),
|
||||||
|
}))
|
||||||
|
|
||||||
|
lastcategory = category
|
||||||
|
end
|
||||||
|
|
||||||
|
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 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>")
|
||||||
|
|
||||||
|
print("</div></li>")
|
||||||
print(format([[
|
print(format([[
|
||||||
<li><form class="transaction box backgroundbox {disable_class}" action="" method="POST">
|
<li><form class="transaction box backgroundbox {disable_class}" action="" method="POST">
|
||||||
<h3>{+user.form.transaction}</h3>
|
<h3>{+user.form.transaction}</h3>
|
||||||
|
@ -516,11 +556,10 @@ local function r_user(username)
|
||||||
local users = get_active_users();
|
local users = get_active_users();
|
||||||
for _, u in ipairs(users) do
|
for _, u in ipairs(users) do
|
||||||
if u.name ~= username then
|
if u.name ~= username then
|
||||||
print(format("<option value={!name}>{name}</option>", { name = u.name }))
|
print(format([[<option value="{!name}">{name}</option>]], { name = u.name }))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
print(format([[
|
print(format([[</select>
|
||||||
</select>
|
|
||||||
<input type="text" name="user_src" value="{!username}" hidden />
|
<input type="text" name="user_src" value="{!username}" hidden />
|
||||||
<label for="amount">{+field.amount}: </label>
|
<label for="amount">{+field.amount}: </label>
|
||||||
<input type="number" name="amount" id="amount" />
|
<input type="number" name="amount" id="amount" />
|
||||||
|
@ -538,8 +577,11 @@ local function r_user(username)
|
||||||
<label for="pcode">{+field.barcode}: </label>
|
<label for="pcode">{+field.barcode}: </label>
|
||||||
<input type="text" name="pcode" id="pcode" />
|
<input type="text" name="pcode" id="pcode" />
|
||||||
<input type="submit" value="{+user.form.restock.submit}" class="button amount-pos" />
|
<input type="submit" value="{+user.form.restock.submit}" class="button amount-pos" />
|
||||||
</form></li>
|
</form></li>]],
|
||||||
]], { username = username, disable_class = is_special and "disabled" or "" }))
|
{
|
||||||
|
username = username,
|
||||||
|
disable_class = is_special and "disabled" or "",
|
||||||
|
}))
|
||||||
print("</ul>")
|
print("</ul>")
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
@ -744,6 +786,7 @@ local function r_products_post()
|
||||||
return error_box("{+error.invalid_name}")
|
return error_box("{+error.invalid_name}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- delete product
|
||||||
if data.delete then
|
if data.delete then
|
||||||
local new_products = io.open("products.new", "w+")
|
local new_products = io.open("products.new", "w+")
|
||||||
if new_products == nil then
|
if new_products == nil then
|
||||||
|
@ -798,13 +841,31 @@ local function r_products_post()
|
||||||
if user == nil or user:match(matchers_global.user) == nil then
|
if user == nil or user:match(matchers_global.user) == nil then
|
||||||
return error_box("{+error.invalid_user}")
|
return error_box("{+error.invalid_user}")
|
||||||
end
|
end
|
||||||
local products = io.open("products", "a+")
|
-- add product
|
||||||
if products == nil then
|
local new_products = io.open("products.new", "w+")
|
||||||
return error_box("{+error.open_products}")
|
if new_products == nil then
|
||||||
|
return error_box("{+error.open_new_products}")
|
||||||
end
|
end
|
||||||
products:write(string.format("%d,%s,%s\n", price, user, name))
|
local wrote = nil
|
||||||
products:flush()
|
-- prepend to any block in the file containing products of the same user
|
||||||
products:close()
|
-- 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))
|
||||||
|
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))
|
||||||
|
end
|
||||||
|
|
||||||
|
new_products:flush()
|
||||||
|
new_products:close()
|
||||||
|
os.rename("products.new", "products")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ time.minutes=Minuten
|
||||||
time.second=Sekunde
|
time.second=Sekunde
|
||||||
time.seconds=Sekunden
|
time.seconds=Sekunden
|
||||||
user.balance=Kontostand
|
user.balance=Kontostand
|
||||||
|
user.shortcuts=Schnellzugriff
|
||||||
user.form.buy.submit=Kaufen
|
user.form.buy.submit=Kaufen
|
||||||
user.form.buy=Produkt kaufen
|
user.form.buy=Produkt kaufen
|
||||||
user.form.restock.submit=Wiederauffüllen
|
user.form.restock.submit=Wiederauffüllen
|
||||||
|
|
|
@ -41,6 +41,7 @@ time.minutes=minutes
|
||||||
time.second=second
|
time.second=second
|
||||||
time.seconds=seconds
|
time.seconds=seconds
|
||||||
user.balance=Current balance
|
user.balance=Current balance
|
||||||
|
user.shortcuts=Shortcuts
|
||||||
user.form.buy.submit=Buy
|
user.form.buy.submit=Buy
|
||||||
user.form.buy=Buy Product
|
user.form.buy=Buy Product
|
||||||
user.form.restock.submit=Restock
|
user.form.restock.submit=Restock
|
||||||
|
|
52
style.css
52
style.css
|
@ -220,7 +220,7 @@ h1 {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
input.button {
|
.button {
|
||||||
place-content: center;
|
place-content: center;
|
||||||
padding: 0.8em 0.5em;
|
padding: 0.8em 0.5em;
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -257,7 +257,7 @@ input.amount-neg {
|
||||||
color: #00e1ff;
|
color: #00e1ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
input.amount-ntr {
|
.amount-ntr {
|
||||||
background-color: #0e646f;
|
background-color: #0e646f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,6 +291,53 @@ ul.userforms > li {
|
||||||
width: 36em;
|
width: 36em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* shortcuts */
|
||||||
|
.shortcuts > label {
|
||||||
|
display: inline-flex;
|
||||||
|
/* dunno why, but will otherwise clip the headline ¯\_(ツ)_/¯ */
|
||||||
|
}
|
||||||
|
|
||||||
|
.shortcuts > label > div > span {
|
||||||
|
display: block;
|
||||||
|
margin: .25em;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shortcuts > label > div > ul {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shortcuts > label > input:checked + div > span {
|
||||||
|
border: none;
|
||||||
|
text-decoration: underline;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shortcuts > label > input:checked + div > ul {
|
||||||
|
display: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shortcuts input.button {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
margin: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shortcuts ul {
|
||||||
|
content: '';
|
||||||
|
display: table;
|
||||||
|
clear: both;
|
||||||
|
list-style: none;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shortcuts li {
|
||||||
|
width: fit-content;
|
||||||
|
float: left;
|
||||||
|
padding: 0.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* create transaction box */
|
/* create transaction box */
|
||||||
.box {
|
.box {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
@ -350,7 +397,6 @@ form.disabled input {
|
||||||
}
|
}
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
|
|
||||||
nav,
|
nav,
|
||||||
.container {
|
.container {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
Loading…
Add table
Reference in a new issue