feat: bootstrap billing templates

This commit is contained in:
Aravinth Manivannan 2025-01-10 21:29:51 +05:30
parent b6350f2225
commit 006c17e81e
Signed by: realaravinth
GPG key ID: F8F50389936984FF
15 changed files with 705 additions and 0 deletions

View file

@ -0,0 +1,69 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::cell::RefCell;
use derive_builder::*;
use derive_more::*;
use serde::*;
use tera::Context;
use url::Url;
pub use super::*;
use crate::utils::*;
pub const ADD_BILL_PAGE: TemplateFile = TemplateFile::new(
"billing.add_bill",
"billing/add_bill.html",
);
pub fn register_templates(t: &mut tera::Tera) {
ADD_BILL_PAGE
.register(t)
.expect(ADD_BILL_PAGE.name);
}
pub struct AddBillPage {
ctx: RefCell<Context>,
}
impl AddBillPage {
pub fn new() -> Self {
let mut ctx = context();
//ctx.insert(PAYLOAD_KEY, p);
let ctx = RefCell::new(ctx);
Self { ctx }
}
pub fn render(&self) -> String {
TEMPLATES
.render(ADD_BILL_PAGE.name, &self.ctx.borrow())
.unwrap()
}
pub fn page() -> String {
let p = Self::new();
p.render()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn render_page_and_write() {
const FILE: &str = "./tmp/billing-add_bill.html";
let tw = TestWriterBuilder::default()
.file(FILE.into())
.contents(AddBillPage::page())
.build()
.unwrap();
tw.write();
}
}

View file

@ -0,0 +1,69 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::cell::RefCell;
use derive_builder::*;
use derive_more::*;
use serde::*;
use tera::Context;
use url::Url;
pub use super::*;
use crate::utils::*;
pub const ADD_LINE_ITEM_PAGE: TemplateFile = TemplateFile::new(
"billing.add_line_item",
"billing/add_line_item.html",
);
pub fn register_templates(t: &mut tera::Tera) {
ADD_LINE_ITEM_PAGE
.register(t)
.expect(ADD_LINE_ITEM_PAGE.name);
}
pub struct AddLineItemPage {
ctx: RefCell<Context>,
}
impl AddLineItemPage {
pub fn new() -> Self {
let mut ctx = context();
//ctx.insert(PAYLOAD_KEY, p);
let ctx = RefCell::new(ctx);
Self { ctx }
}
pub fn render(&self) -> String {
TEMPLATES
.render(ADD_LINE_ITEM_PAGE.name, &self.ctx.borrow())
.unwrap()
}
pub fn page() -> String {
let p = Self::new();
p.render()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn render_page_and_write() {
const FILE: &str = "./tmp/billing-add_line_item.html";
let tw = TestWriterBuilder::default()
.file(FILE.into())
.contents(AddLineItemPage::page())
.build()
.unwrap();
tw.write();
}
}

View file

@ -0,0 +1,68 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::cell::RefCell;
use derive_builder::*;
use derive_more::*;
use serde::*;
use tera::Context;
use url::Url;
pub use super::*;
use crate::utils::*;
pub const DELETE_BILL_PAGE: TemplateFile = TemplateFile::new(
"billing.delete_bill",
"billing/delete_bill.html",
);
pub fn register_templates(t: &mut tera::Tera) {
DELETE_BILL_PAGE
.register(t)
.expect(DELETE_BILL_PAGE.name);
}
pub struct DeleteBillPage {
ctx: RefCell<Context>,
}
impl DeleteBillPage {
pub fn new() -> Self {
let mut ctx = context();
//ctx.insert(PAYLOAD_KEY, p);
let ctx = RefCell::new(ctx);
Self { ctx }
}
pub fn render(&self) -> String {
TEMPLATES
.render(DELETE_BILL_PAGE.name, &self.ctx.borrow())
.unwrap()
}
pub fn page() -> String {
let p = Self::new();
p.render()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn render_page_and_write() {
const FILE: &str = "./tmp/billing-delete_bill.html";
let tw = TestWriterBuilder::default()
.file(FILE.into())
.contents(DeleteBillPage::page())
.build()
.unwrap();
tw.write();
}
}

View file

@ -0,0 +1,67 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::cell::RefCell;
use derive_builder::*;
use derive_more::*;
use serde::*;
use tera::Context;
use url::Url;
pub use super::*;
use crate::utils::*;
pub const DELETE_LINE_ITEM_PAGE: TemplateFile = TemplateFile::new(
"billing.delete_line_item",
"billing/delete_line_item.html",
);
pub fn register_templates(t: &mut tera::Tera) {
DELETE_LINE_ITEM_PAGE
.register(t)
.expect(DELETE_LINE_ITEM_PAGE.name);
}
pub struct DeleteLineItemPage {
ctx: RefCell<Context>,
}
impl DeleteLineItemPage {
pub fn new() -> Self {
let mut ctx = context();
//ctx.insert(PAYLOAD_KEY, p);
let ctx = RefCell::new(ctx);
Self { ctx }
}
pub fn render(&self) -> String {
TEMPLATES
.render(DELETE_LINE_ITEM_PAGE.name, &self.ctx.borrow())
.unwrap()
}
pub fn page() -> String {
let p = Self::new();
p.render()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn render_page_and_write() {
const FILE: &str = "./tmp/billing-delete_line_item.html";
let tw = TestWriterBuilder::default()
.file(FILE.into())
.contents(DeleteLineItemPage::page())
.build()
.unwrap();
tw.write();
}
}

25
web_ui/src/billing/mod.rs Normal file
View file

@ -0,0 +1,25 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
pub mod add_bill;
pub mod update_bill;
pub mod delete_bill;
pub mod add_line_item;
pub mod update_line_item;
pub mod delete_line_item;
pub fn register_templates(t: &mut tera::Tera) {
for template in [
add_bill::ADD_BILL_PAGE,
update_bill::UPDATE_BILL_PAGE,
delete_bill::DELETE_BILL_PAGE,
add_line_item::ADD_LINE_ITEM_PAGE,
update_line_item::UPDATE_LINE_ITEM_PAGE,
delete_line_item::DELETE_LINE_ITEM_PAGE,
]
.iter()
{
template.register(t).expect(template.name);
}
}

View file

@ -0,0 +1,69 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::cell::RefCell;
use derive_builder::*;
use derive_more::*;
use serde::*;
use tera::Context;
use url::Url;
pub use super::*;
use crate::utils::*;
pub const UPDATE_BILL_PAGE: TemplateFile = TemplateFile::new(
"billing.update_bill",
"billing/update_bill.html",
);
pub fn register_templates(t: &mut tera::Tera) {
UPDATE_BILL_PAGE
.register(t)
.expect(UPDATE_BILL_PAGE.name);
}
pub struct UpdateBillPage {
ctx: RefCell<Context>,
}
impl UpdateBillPage {
pub fn new() -> Self {
let mut ctx = context();
//ctx.insert(PAYLOAD_KEY, p);
let ctx = RefCell::new(ctx);
Self { ctx }
}
pub fn render(&self) -> String {
TEMPLATES
.render(UPDATE_BILL_PAGE.name, &self.ctx.borrow())
.unwrap()
}
pub fn page() -> String {
let p = Self::new();
p.render()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn render_page_and_write() {
const FILE: &str = "./tmp/billing-update_bill.html";
let tw = TestWriterBuilder::default()
.file(FILE.into())
.contents(UpdateBillPage::page())
.build()
.unwrap();
tw.write();
}
}

View file

@ -0,0 +1,69 @@
// SPDX-FileCopyrightText: 2024 Aravinth Manivannan <realaravinth@batsense.net>
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use std::cell::RefCell;
use derive_builder::*;
use derive_more::*;
use serde::*;
use tera::Context;
use url::Url;
pub use super::*;
use crate::utils::*;
pub const UPDATE_LINE_ITEM_PAGE: TemplateFile = TemplateFile::new(
"billing.update_line_item",
"billing/update_line_item.html",
);
pub fn register_templates(t: &mut tera::Tera) {
UPDATE_LINE_ITEM_PAGE
.register(t)
.expect(UPDATE_LINE_ITEM_PAGE.name);
}
pub struct UpdateLineItemPage {
ctx: RefCell<Context>,
}
impl UpdateLineItemPage {
pub fn new() -> Self {
let mut ctx = context();
//ctx.insert(PAYLOAD_KEY, p);
let ctx = RefCell::new(ctx);
Self { ctx }
}
pub fn render(&self) -> String {
TEMPLATES
.render(UPDATE_LINE_ITEM_PAGE.name, &self.ctx.borrow())
.unwrap()
}
pub fn page() -> String {
let p = Self::new();
p.render()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn render_page_and_write() {
const FILE: &str = "./tmp/billing-update_line_item.html";
let tw = TestWriterBuilder::default()
.file(FILE.into())
.contents(UpdateLineItemPage::page())
.build()
.unwrap();
tw.write();
}
}

View file

@ -6,6 +6,7 @@ pub mod identity;
pub mod inventory;
mod log;
mod utils;
pub mod billing;
pub fn init() {
lazy_static::initialize(&utils::TEMPLATES);

View file

@ -48,6 +48,7 @@ lazy_static! {
tera.autoescape_on(vec![".html", ".sql"]);
crate::identity::register_templates(&mut tera);
crate::inventory::register_templates(&mut tera);
crate::billing::register_templates(&mut tera);
tera
};
}

View file

@ -0,0 +1,17 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Add Bill | Vanikam</title>
</head>
<body>
Token Refreshed
<form action="/billing/bill/add" method="post">
<label>
Store ID <input type="text" name="store_id" id="store_id"
/></label>
<button type="submit">Add Bill</button>
</form>
</body>
</html>

View file

@ -0,0 +1,91 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Add Line Item | Vanikam</title>
</head>
<body>
Token Refreshed
<form action="/billing/bill/add" method="post">
<label> Bill ID <input type="text" name="bill_id" id="bill_id" /></label>
<label>
Product ID <input type="text" name="product_id" id="product_id"
/></label>
<label>
Product name <input type="text" name="product_name" id="product_name"
/></label>
<!-- quantity -->
<label for="quantity_minor_unit">
Quantity minor unit
<input
type="text"
name="quantity_minor_unit"
id="quantity_minor_unit"
/>
</label>
<label for="quantity_minor_number">
Quantity minor number
<input
type="number"
name="quantity_minor_number"
id="quantity_minor_number"
/>
</label>
<label for="quantity_major_unit">
Quantity major unit
<input
type="text"
name="quantity_major_unit"
id="quantity_major_unit"
/>
</label>
<label for="quantity_major_number">
Quantity major number
<input
type="number"
name="quantity_major_number"
id="quantity_major_number"
/>
</label>
<!-- price -->
<label for="price_per_unit_unit">
Price per unit unit
<input
type="text"
name="price_per_unit_unit"
id="price_per_unit_unit"
/>
</label>
<label for="price_per_unit_minor_number">
Price per unit minor number
<input
type="number"
name="price_per_unit_minor_number"
id="price_per_unit_minor_number"
/>
</label>
<label for="price_per_unit_major_number">
Price per unit major number
<input
type="number"
name="price_per_unit_major_number"
id="price_per_unit_major_number"
/>
</label>
<button type="submit">Add Line Item</button>
</form>
</body>
</html>

View file

@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Delete Bill | Vanikam</title>
</head>
<body>
Token Refreshed
<form action="/billing/bill/delete" method="post">
<button type="submit">Delete Bill</button>
</form>
</body>
</html>

View file

@ -0,0 +1,15 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Delete Line Item | Vanikam</title>
</head>
<body>
Token Refreshed
<form action="/billing/bill/update" method="post">
<button type="submit">Delete Line Item</button>
</form>
</body>
</html>

View file

@ -0,0 +1,39 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Update Bill | Vanikam</title>
</head>
<body>
Token Refreshed
<form action="/billing/bill/add" method="post">
<!-- price -->
<label for="total_price_unit">
Total price unit
<input type="text" name="total_price_unit" id="total_price_unit" />
</label>
<label for="total_price_minor_number">
Total price minor number
<input
type="number"
name="total_price_minor_number"
id="total_price_minor_number"
/>
</label>
<label for="total_price_major_number">
Total price major number
<input
type="number"
name="total_price_major_number"
id="total_price_major_number"
/>
</label>
<button type="submit">Update Bill</button>
</form>
</body>
</html>

View file

@ -0,0 +1,91 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Update Line Item | Vanikam</title>
</head>
<body>
Token Refreshed
<form action="/billing/bill/update" method="post">
<label> Bill ID <input type="text" name="bill_id" id="bill_id" /></label>
<label>
Product ID <input type="text" name="product_id" id="product_id"
/></label>
<label>
Product name <input type="text" name="product_name" id="product_name"
/></label>
<!-- quantity -->
<label for="quantity_minor_unit">
Quantity minor unit
<input
type="text"
name="quantity_minor_unit"
id="quantity_minor_unit"
/>
</label>
<label for="quantity_minor_number">
Quantity minor number
<input
type="number"
name="quantity_minor_number"
id="quantity_minor_number"
/>
</label>
<label for="quantity_major_unit">
Quantity major unit
<input
type="text"
name="quantity_major_unit"
id="quantity_major_unit"
/>
</label>
<label for="quantity_major_number">
Quantity major number
<input
type="number"
name="quantity_major_number"
id="quantity_major_number"
/>
</label>
<!-- price -->
<label for="price_per_unit_unit">
Price per unit unit
<input
type="text"
name="price_per_unit_unit"
id="price_per_unit_unit"
/>
</label>
<label for="price_per_unit_minor_number">
Price per unit minor number
<input
type="number"
name="price_per_unit_minor_number"
id="price_per_unit_minor_number"
/>
</label>
<label for="price_per_unit_major_number">
Price per unit major number
<input
type="number"
name="price_per_unit_major_number"
id="price_per_unit_major_number"
/>
</label>
<button type="submit">Update Line Item</button>
</form>
</body>
</html>