complete redesign

This commit is contained in:
filipriec
2025-02-22 23:23:07 +01:00
parent d9e812ac1b
commit 5a81a37678
83 changed files with 3578 additions and 152 deletions

View File

@@ -0,0 +1,58 @@
POST
grpcurl -plaintext -d '{
"adresar_id": 1,
"c_dokladu": "DOC123",
"datum": "01:10:2023",
"c_faktury": "INV123",
"obsah": "Sample content",
"stredisko": "Center A",
"c_uctu": "ACC123",
"md": "MD123",
"identif": "ID123",
"poznanka": "Sample note",
"firma": "AAA"
}' localhost:50051 multieko2.uctovnictvo.Uctovnictvo/PostUctovnictvo
{
"id": "3",
"adresarId": "1",
"cDokladu": "DOC123",
"datum": "2023-10-01",
"cFaktury": "INV123",
"obsah": "Sample content",
"stredisko": "Center A",
"cUctu": "ACC123",
"md": "MD123",
"identif": "ID123",
"poznanka": "Sample note",
"firma": "AAA"
}
PUT
grpcurl -plaintext -d '{
"id": '1',
"adresar_id": 1,
"c_dokladu": "UPDATED-DOC",
"datum": "15.11.2023",
"c_faktury": "UPDATED-INV",
"obsah": "Updated content",
"stredisko": "Updated Center",
"c_uctu": "UPD-ACC",
"md": "UPD-MD",
"identif": "UPD-ID",
"poznanka": "Updated note",
"firma": "UPD"
}' localhost:50051 multieko2.uctovnictvo.Uctovnictvo/PutUctovnictvo
{
"id": "1",
"adresarId": "1",
"cDokladu": "UPDATED-DOC",
"datum": "15.11.2023",
"cFaktury": "UPDATED-INV",
"obsah": "Updated content",
"stredisko": "Updated Center",
"cUctu": "UPD-ACC",
"md": "UPD-MD",
"identif": "UPD-ID",
"poznanka": "Updated note",
"firma": "UPD"
}

View File

@@ -0,0 +1,41 @@
grpcurl -plaintext -d '{}' localhost:50051 multieko2.uctovnictvo.Uctovnictvo/GetUctovnictvoCount
{
"count": "4"
}
grpcurl -plaintext -d '{
"position": 2
}' localhost:50051 multieko2.uctovnictvo.Uctovnictvo/GetUctovnictvoByPosition
{
"id": "2",
"adresarId": "1",
"cDokladu": "DOC123",
"datum": "01.10.2023",
"cFaktury": "INV123",
"obsah": "Sample content",
"stredisko": "Center A",
"cUctu": "ACC123",
"md": "MD123",
"identif": "ID123",
"poznanka": "Sample note",
"firma": "AAA"
}
grpcurl -plaintext -d '{
"id": 1
}' localhost:50051 multieko2.uctovnictvo.Uctovnictvo/GetUctovnictvo
{
"id": "1",
"adresarId": "1",
"cDokladu": "DOC123",
"datum": "01.10.2023",
"cFaktury": "INV123",
"obsah": "Sample content",
"stredisko": "Center A",
"cUctu": "ACC123",
"md": "MD123",
"identif": "ID123",
"poznanka": "Sample note",
"firma": "AAA"
}

View File

@@ -0,0 +1,12 @@
// src/uctovnictvo/handlers.rs
pub mod post_uctovnictvo;
pub mod get_uctovnictvo;
pub mod get_uctovnictvo_count;
pub mod get_uctovnictvo_by_position;
pub mod put_uctovnictvo;
pub use post_uctovnictvo::post_uctovnictvo;
pub use get_uctovnictvo::get_uctovnictvo;
pub use get_uctovnictvo_count::get_uctovnictvo_count;
pub use get_uctovnictvo_by_position::get_uctovnictvo_by_position;
pub use put_uctovnictvo::put_uctovnictvo;

View File

@@ -0,0 +1,51 @@
// src/uctovnictvo/handlers/get_uctovnictvo.rs
use tonic::Status;
use sqlx::PgPool;
use crate::uctovnictvo::models::Uctovnictvo;
use common::proto::multieko2::uctovnictvo::{GetUctovnictvoRequest, UctovnictvoResponse};
pub async fn get_uctovnictvo(
db_pool: &PgPool,
request: GetUctovnictvoRequest,
) -> Result<UctovnictvoResponse, Status> {
let uctovnictvo = sqlx::query_as!(
Uctovnictvo,
r#"
SELECT
id,
deleted,
adresar_id,
c_dokladu,
datum as "datum: chrono::NaiveDate",
c_faktury,
obsah,
stredisko,
c_uctu,
md,
identif,
poznanka,
firma
FROM uctovnictvo
WHERE id = $1
"#,
request.id
)
.fetch_one(db_pool)
.await
.map_err(|e| Status::not_found(e.to_string()))?;
Ok(UctovnictvoResponse {
id: uctovnictvo.id,
adresar_id: uctovnictvo.adresar_id,
c_dokladu: uctovnictvo.c_dokladu,
datum: uctovnictvo.datum.format("%d.%m.%Y").to_string(),
c_faktury: uctovnictvo.c_faktury,
obsah: uctovnictvo.obsah.unwrap_or_default(),
stredisko: uctovnictvo.stredisko.unwrap_or_default(),
c_uctu: uctovnictvo.c_uctu.unwrap_or_default(),
md: uctovnictvo.md.unwrap_or_default(),
identif: uctovnictvo.identif.unwrap_or_default(),
poznanka: uctovnictvo.poznanka.unwrap_or_default(),
firma: uctovnictvo.firma,
})
}

View File

@@ -0,0 +1,34 @@
// src/uctovnictvo/handlers/get_uctovnictvo_by_position.rs
use tonic::Status;
use sqlx::PgPool;
use common::proto::multieko2::common::PositionRequest;
use super::get_uctovnictvo;
pub async fn get_uctovnictvo_by_position(
db_pool: &PgPool,
request: PositionRequest,
) -> Result<common::proto::multieko2::uctovnictvo::UctovnictvoResponse, Status> {
if request.position < 1 {
return Err(Status::invalid_argument("Position must be at least 1"));
}
// Find the ID of the Nth non-deleted record
let id: i64 = sqlx::query_scalar!(
r#"
SELECT id
FROM uctovnictvo
WHERE deleted = FALSE
ORDER BY id ASC
OFFSET $1
LIMIT 1
"#,
request.position - 1
)
.fetch_optional(db_pool)
.await
.map_err(|e| Status::internal(e.to_string()))?
.ok_or_else(|| Status::not_found("Position out of bounds"))?;
// Now fetch the complete record using the existing get_uctovnictvo function
get_uctovnictvo(db_pool, common::proto::multieko2::uctovnictvo::GetUctovnictvoRequest { id }).await
}

View File

@@ -0,0 +1,23 @@
// src/uctovnictvo/handlers/get_uctovnictvo_count.rs
use tonic::Status;
use sqlx::PgPool;
use common::proto::multieko2::common::{CountResponse, Empty};
pub async fn get_uctovnictvo_count(
db_pool: &PgPool,
_request: Empty,
) -> Result<CountResponse, Status> {
let count: i64 = sqlx::query_scalar!(
r#"
SELECT COUNT(*) AS count
FROM uctovnictvo
WHERE deleted = FALSE
"#
)
.fetch_one(db_pool)
.await
.map_err(|e| Status::internal(e.to_string()))?
.unwrap_or(0);
Ok(CountResponse { count })
}

View File

@@ -0,0 +1,73 @@
// src/uctovnictvo/handlers/post_uctovnictvo.rs
use tonic::Status;
use sqlx::PgPool;
use crate::uctovnictvo::models::Uctovnictvo;
use common::proto::multieko2::uctovnictvo::{PostUctovnictvoRequest, UctovnictvoResponse};
use crate::shared::date_utils::parse_date_with_multiple_formats; // Import from shared module
pub async fn post_uctovnictvo(
db_pool: &PgPool,
request: PostUctovnictvoRequest,
) -> Result<UctovnictvoResponse, Status> {
let datum = parse_date_with_multiple_formats(&request.datum)
.ok_or_else(|| Status::invalid_argument(format!("Invalid date format: {}", request.datum)))?;
// Pass the NaiveDate value directly.
let uctovnictvo = sqlx::query_as!(
Uctovnictvo,
r#"
INSERT INTO uctovnictvo (
adresar_id, c_dokladu, datum, c_faktury, obsah, stredisko,
c_uctu, md, identif, poznanka, firma, deleted
)
VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12
)
RETURNING
id,
deleted,
adresar_id,
c_dokladu,
datum as "datum: chrono::NaiveDate",
c_faktury,
obsah,
stredisko,
c_uctu,
md,
identif,
poznanka,
firma
"#,
request.adresar_id,
request.c_dokladu,
datum as chrono::NaiveDate,
request.c_faktury,
request.obsah,
request.stredisko,
request.c_uctu,
request.md,
request.identif,
request.poznanka,
request.firma,
false
)
.fetch_one(db_pool)
.await
.map_err(|e| Status::internal(e.to_string()))?;
// Return the response with formatted date
Ok(UctovnictvoResponse {
id: uctovnictvo.id,
adresar_id: uctovnictvo.adresar_id,
c_dokladu: uctovnictvo.c_dokladu,
datum: uctovnictvo.datum.format("%d.%m.%Y").to_string(), // Standard Slovak format
c_faktury: uctovnictvo.c_faktury,
obsah: uctovnictvo.obsah.unwrap_or_default(),
stredisko: uctovnictvo.stredisko.unwrap_or_default(),
c_uctu: uctovnictvo.c_uctu.unwrap_or_default(),
md: uctovnictvo.md.unwrap_or_default(),
identif: uctovnictvo.identif.unwrap_or_default(),
poznanka: uctovnictvo.poznanka.unwrap_or_default(),
firma: uctovnictvo.firma,
})
}

View File

@@ -0,0 +1,78 @@
// src/uctovnictvo/handlers/put_uctovnictvo.rs
use tonic::Status;
use sqlx::PgPool;
use crate::uctovnictvo::models::Uctovnictvo;
use common::proto::multieko2::uctovnictvo::{PutUctovnictvoRequest, UctovnictvoResponse};
use crate::shared::date_utils::parse_date_with_multiple_formats; // Import from shared module
pub async fn put_uctovnictvo(
db_pool: &PgPool,
request: PutUctovnictvoRequest,
) -> Result<UctovnictvoResponse, Status> {
let datum = parse_date_with_multiple_formats(&request.datum)
.ok_or_else(|| Status::invalid_argument("Invalid date format"))?;
let uctovnictvo = sqlx::query_as!(
Uctovnictvo,
r#"
UPDATE uctovnictvo
SET
adresar_id = $2,
c_dokladu = $3,
datum = $4,
c_faktury = $5,
obsah = $6,
stredisko = $7,
c_uctu = $8,
md = $9,
identif = $10,
poznanka = $11,
firma = $12
WHERE id = $1 AND deleted = FALSE
RETURNING
id,
deleted,
adresar_id,
c_dokladu,
datum as "datum: chrono::NaiveDate",
c_faktury,
obsah,
stredisko,
c_uctu,
md,
identif,
poznanka,
firma
"#,
request.id,
request.adresar_id,
request.c_dokladu,
datum as chrono::NaiveDate,
request.c_faktury,
request.obsah,
request.stredisko,
request.c_uctu,
request.md,
request.identif,
request.poznanka,
request.firma
)
.fetch_one(db_pool)
.await
.map_err(|e| Status::internal(e.to_string()))?;
Ok(UctovnictvoResponse {
id: uctovnictvo.id,
adresar_id: uctovnictvo.adresar_id,
c_dokladu: uctovnictvo.c_dokladu,
datum: uctovnictvo.datum.format("%d.%m.%Y").to_string(),
c_faktury: uctovnictvo.c_faktury,
obsah: uctovnictvo.obsah.unwrap_or_default(),
stredisko: uctovnictvo.stredisko.unwrap_or_default(),
c_uctu: uctovnictvo.c_uctu.unwrap_or_default(),
md: uctovnictvo.md.unwrap_or_default(),
identif: uctovnictvo.identif.unwrap_or_default(),
poznanka: uctovnictvo.poznanka.unwrap_or_default(),
firma: uctovnictvo.firma,
})
}

View File

@@ -0,0 +1,4 @@
// src/uctovnictvo/mod.rs
pub mod models;
pub mod handlers;

View File

@@ -0,0 +1,21 @@
// src/uctovnictvo/models.rs
use chrono::NaiveDate;
use serde::{Deserialize, Serialize};
#[derive(Debug, sqlx::FromRow, Serialize, Deserialize)]
pub struct Uctovnictvo {
pub id: i64,
pub deleted: bool,
pub adresar_id: i64,
pub c_dokladu: String,
pub datum: NaiveDate,
pub c_faktury: String,
pub obsah: Option<String>,
pub stredisko: Option<String>,
pub c_uctu: Option<String>,
pub md: Option<String>,
pub identif: Option<String>,
pub poznanka: Option<String>,
pub firma: String,
}