Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/tally/compatibility/compatibility-matrix.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"schema_version": 1,
"bridge_commit_sha": "be1c20cc3fd66fa1ece196505c69f26e555e4b8e",
"compatibility_surface_sha256": "c6cb7e5a3f23618922ba9d562e9b805782c03d5350c01222ead547547f01598b",
"compatibility_surface_sha256": "75387c68586650f337502929bf9ad6dcbd2d3b2f99e1641d9652395a806f22d8",
"claims": [
{
"claim_id": "erp9-6-6-3-windows-education-xml-one-company",
Expand Down
12 changes: 6 additions & 6 deletions docs/tally/compatibility/compatibility-surface.json
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@
},
{
"path": "src-tauri/src/commands.rs",
"sha256": "116c0ab468896bff2c98db3aaada794d5378ef8e32934bcad737c27fb592a5e7"
"sha256": "d12c341e5f5fecd6e41436293699bd8f318f0ae2127ccd7ede29e0af2db9d19e"
},
{
"path": "src-tauri/src/db/encrypted.rs",
Expand Down Expand Up @@ -303,7 +303,7 @@
},
{
"path": "src-tauri/src/lib.rs",
"sha256": "33bdd1cf9cf4a1e945db9b7eaec0f037b1122e5bafd013c208254b9ad3817196"
"sha256": "62c950aacaff7b1b431b65f32e14ead421d87a0bd3cd44a580912adfb5bf3730"
},
{
"path": "src-tauri/src/sync/coordinator.rs",
Expand Down Expand Up @@ -339,7 +339,7 @@
},
{
"path": "src-tauri/src/tally/runtime.rs",
"sha256": "2d2ce6d7d59b4b7e7286ca0f583f87604fa86cd1a1eed1c5353f7ae487152b55"
"sha256": "1d2ae890a240344ad9a2a59b4624be2726d13c11e5e529a0b084e355f865deec"
},
{
"path": "src-tauri/src/tally/serial_queue.rs",
Expand All @@ -359,7 +359,7 @@
},
{
"path": "src/OutstandingsScreen.tsx",
"sha256": "df11bdbbbfb4f62b7738cd30ea69a2ce5b15eb8a5b5567358e67d6d04569bb90"
"sha256": "5fbb3bc7a47487cf5a5d9f5bc527c5a7e01940589fd519c4a07c1e6c6f094cf3"
},
{
"path": "src/TallyReadinessFlow.tsx",
Expand All @@ -379,7 +379,7 @@
},
{
"path": "src/styles.css",
"sha256": "ff23d59914a48f3f3621499a8121fc63ee93f7b18ad4ae787d7f1d6e04b81281"
"sha256": "b488d5305557b4c356e4d2e16971d387724e9be17ede1d8c05213f64c9661146"
},
{
"path": "src/tally-company-selection.ts",
Expand Down Expand Up @@ -434,5 +434,5 @@
"sha256": "a27f294ee15e407b69fdfc73609e8708ac0509b6e6a8872daef5451fde61a8db"
}
],
"manifest_sha256": "c6cb7e5a3f23618922ba9d562e9b805782c03d5350c01222ead547547f01598b"
"manifest_sha256": "75387c68586650f337502929bf9ad6dcbd2d3b2f99e1641d9652395a806f22d8"
}
97 changes: 97 additions & 0 deletions src-tauri/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ use crate::db::tally_mirror::{
WriteFixtureEnrollmentInput, WriteFixtureEnrollmentStatus,
};
use crate::gst::{GstDraftRequest, GstReturnDraft};
use crate::reports::bulk_party_statement::{
bulk_party_statement_party_count, write_bulk_party_statements,
};
use crate::reports::party_statement::{build_party_statement, PartyStatementError};
use crate::reports::party_statement_pdf::render_party_statement_pdf;
use crate::reports::party_statement_xlsx::render_party_statement_xlsx;
Expand Down Expand Up @@ -2918,6 +2921,100 @@ pub enum PartyStatementFormat {
Pdf,
}

#[derive(Debug, Deserialize)]
pub struct ExportBulkPartyStatementsRequest {
pub company: String,
pub as_of_yyyymmdd: String,
pub format: PartyStatementFormat,
/// Chosen by the native folder picker. The command still checks that it
/// exists and is a directory before any statement name is joined to it.
pub destination: String,
/// These are complete statement-source rows from the finished local read,
/// not the dashboard's display projections.
pub open_bills: Vec<OpenBillRowInput>,
pub unallocated_by_party: Vec<UnallocatedParty>,
}

#[derive(Debug, Deserialize)]
pub struct PreviewBulkPartyStatementsRequest {
/// The same complete rows the export command will consume. This command
/// performs no I/O or Tally read; it only makes the pending scope explicit.
pub open_bills: Vec<OpenBillRowInput>,
pub unallocated_by_party: Vec<UnallocatedParty>,
}

#[derive(Debug, Serialize)]
pub struct BulkPartyStatementsPreview {
pub party_count: usize,
}

/// Lets the operator choose where the whole statement batch will be written.
#[tauri::command]
pub async fn select_party_statement_destination() -> Result<Option<String>, String> {
tokio::task::spawn_blocking(|| {
Ok(rfd::FileDialog::new()
.set_title("Choose a folder for party statements")
.pick_folder()
.map(|path| path.to_string_lossy().into_owned()))
})
.await
.map_err(|_| "Bridge could not open the statement destination picker.".to_string())?
}

/// Counts the unique, non-zero parties that the bulk writer will process.
/// Kept beside the writer's source conversion so the confirmation cannot use
/// a separately implemented frontend approximation of the export scope.
#[tauri::command]
pub async fn preview_bulk_party_statements(
request: PreviewBulkPartyStatementsRequest,
) -> Result<BulkPartyStatementsPreview, String> {
let open_bills = request
.open_bills
.into_iter()
.map(into_open_bill_row)
.collect::<Result<Vec<_>, _>>()?;
Ok(BulkPartyStatementsPreview {
party_count: bulk_party_statement_party_count(&open_bills, &request.unallocated_by_party),
})
}

/// Writes a separate statement for every party in the completed source rows.
/// A failed party remains visible in the returned result and manifest while
/// the remaining parties continue, so an operator cannot mistake a partial
/// batch for a complete send-ready set.
#[tauri::command]
pub async fn export_bulk_party_statements(
request: ExportBulkPartyStatementsRequest,
) -> Result<crate::reports::bulk_party_statement::BulkPartyStatementResult, String> {
let open_bills = request
.open_bills
.into_iter()
.map(into_open_bill_row)
.collect::<Result<Vec<_>, _>>()?;
let destination = std::path::PathBuf::from(request.destination);
Comment thread
lamemustafa marked this conversation as resolved.

match request.format {
PartyStatementFormat::Xlsx => write_bulk_party_statements(
&destination,
&request.company,
&request.as_of_yyyymmdd,
"xlsx",
&open_bills,
&request.unallocated_by_party,
|statement| render_party_statement_xlsx(statement).map_err(|error| error.to_string()),
),
PartyStatementFormat::Pdf => write_bulk_party_statements(
&destination,
&request.company,
&request.as_of_yyyymmdd,
"pdf",
&open_bills,
&request.unallocated_by_party,
|statement| render_party_statement_pdf(statement).map_err(|error| error.to_string()),
Comment thread
lamemustafa marked this conversation as resolved.
),
}
}

/// Builds one party's aged-bills statement in the requested format and writes
/// it to the user's Downloads folder.
///
Expand Down
3 changes: 3 additions & 0 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ pub fn run() {
commands::save_report_download,
commands::reveal_exported_file,
commands::export_party_statement,
commands::select_party_statement_destination,
commands::preview_bulk_party_statements,
commands::export_bulk_party_statements,
commands::fetch_tally_outstandings_all_companies,
commands::detect_tally_base_currency,
commands::tally_persisted_company_profiles,
Expand Down
Loading
Loading