Skip to content

Commit

Permalink
Merge pull request #6395 from msupply-foundation/6204-name-insurance-…
Browse files Browse the repository at this point in the history
…join

6204 name insurance join
  • Loading branch information
jmbrunskill authored Feb 6, 2025
2 parents 7d827b4 + 33cc234 commit a671bbb
Show file tree
Hide file tree
Showing 12 changed files with 523 additions and 7 deletions.
1 change: 1 addition & 0 deletions server/cli/src/refresh_dates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ fn get_date_fields() -> Vec<TableAndFieldName> {
("asset", "warranty_end"),
("rnr_form_line", "expiry_date"),
("vaccination", "vaccination_date"),
("name_insurance_join", "expiry_date"),
]
.iter()
.map(|(table_name, field_name)| TableAndFieldName {
Expand Down
2 changes: 2 additions & 0 deletions server/repository/src/db_diesel/changelog/changelog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ pub enum ChangelogTableName {
ContactForm,
SystemLog,
InsuranceProvider,
NameInsuranceJoin,
}

pub(crate) enum ChangeLogSyncStyle {
Expand Down Expand Up @@ -186,6 +187,7 @@ impl ChangelogTableName {
ChangelogTableName::ContactForm => ChangeLogSyncStyle::RemoteToCentral,
ChangelogTableName::SystemLog => ChangeLogSyncStyle::RemoteToCentral, // System Log records won't be synced to remote site on initialisation
ChangelogTableName::InsuranceProvider => ChangeLogSyncStyle::Legacy,
ChangelogTableName::NameInsuranceJoin => ChangeLogSyncStyle::Legacy,
}
}
}
Expand Down
1 change: 1 addition & 0 deletions server/repository/src/db_diesel/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ pub mod master_list_name_join;
mod master_list_row;
mod migration_fragment_log;
pub mod name;
pub mod name_insurance_join_row;
mod name_link_row;
pub mod name_property;
pub mod name_property_row;
Expand Down
109 changes: 109 additions & 0 deletions server/repository/src/db_diesel/name_insurance_join_row.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
use super::{
ChangeLogInsertRow, ChangelogRepository, ChangelogTableName, RowActionType, StorageConnection,
};

use crate::{repository_error::RepositoryError, Upsert};
use diesel::prelude::*;
use diesel_derive_enum::DbEnum;
use serde::{Deserialize, Serialize};

#[derive(DbEnum, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
#[DbValueStyle = "SCREAMING_SNAKE_CASE"]
pub enum InsurancePolicyType {
#[default]
Personal,
Business,
}

table! {
name_insurance_join (id) {
id -> Text,
name_link_id -> Text,
insurance_provider_id -> Text,
policy_number_person -> Nullable<Text>,
policy_number_family -> Nullable<Text>,
policy_number -> Text,
policy_type -> crate::db_diesel::name_insurance_join_row::InsurancePolicyTypeMapping,
discount_percentage -> Double,
expiry_date -> Date,
is_active -> Bool,
entered_by_id -> Nullable<Text>,
}
}

#[derive(
Clone, Insertable, Queryable, Debug, PartialEq, AsChangeset, Default, Serialize, Deserialize,
)]
#[diesel(table_name = name_insurance_join)]
pub struct NameInsuranceJoinRow {
pub id: String,
pub name_link_id: String,
pub insurance_provider_id: String,
pub policy_number_person: Option<String>,
pub policy_number_family: Option<String>,
pub policy_number: String,
pub policy_type: InsurancePolicyType,
pub discount_percentage: f64,
pub expiry_date: chrono::NaiveDate,
pub is_active: bool,
pub entered_by_id: Option<String>,
}

pub struct NameInsuranceJoinRowRepository<'a> {
connection: &'a StorageConnection,
}

impl<'a> NameInsuranceJoinRowRepository<'a> {
pub fn new(connection: &'a StorageConnection) -> Self {
NameInsuranceJoinRowRepository { connection }
}

pub fn find_one_by_id(
&self,
id: &str,
) -> Result<Option<NameInsuranceJoinRow>, RepositoryError> {
let result = name_insurance_join::table
.filter(name_insurance_join::id.eq(id))
.first(self.connection.lock().connection())
.optional()?;
Ok(result)
}

pub fn upsert_one(&self, row: &NameInsuranceJoinRow) -> Result<i64, RepositoryError> {
diesel::insert_into(name_insurance_join::table)
.values(row)
.on_conflict(name_insurance_join::id)
.do_update()
.set(row)
.execute(self.connection.lock().connection())?;
self.insert_changelog(&row.id, RowActionType::Upsert)
}

fn insert_changelog(&self, uid: &str, action: RowActionType) -> Result<i64, RepositoryError> {
let row = ChangeLogInsertRow {
table_name: ChangelogTableName::NameInsuranceJoin,
record_id: uid.to_string(),
row_action: action,
store_id: None,
name_link_id: None,
};

ChangelogRepository::new(self.connection).insert(&row)
}
}

impl Upsert for NameInsuranceJoinRow {
fn upsert(&self, con: &StorageConnection) -> Result<Option<i64>, RepositoryError> {
let change_log = NameInsuranceJoinRowRepository::new(con).upsert_one(self)?;
Ok(Some(change_log))
}

// Test only
fn assert_upserted(&self, con: &StorageConnection) {
assert_eq!(
NameInsuranceJoinRowRepository::new(con).find_one_by_id(&self.id),
Ok(Some(self.clone()))
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use crate::migrations::*;

pub(crate) struct Migrate;

impl MigrationFragment for Migrate {
fn identifier(&self) -> &'static str {
"add_name_insurance_join"
}

fn migrate(&self, connection: &StorageConnection) -> anyhow::Result<()> {
let policy_type = if cfg!(feature = "postgres") {
"insurance_policy_type"
} else {
"TEXT"
};

if cfg!(feature = "postgres") {
// Postgres changelog variant
sql!(
connection,
r#"
ALTER TYPE changelog_table_name ADD VALUE IF NOT EXISTS 'name_insurance_join';
"#
)?;

// Postgres enum variant for policy_type
sql!(
connection,
r#"
CREATE TYPE insurance_policy_type AS ENUM ('PERSONAL', 'BUSINESS');
"#
)?;
}

sql!(
connection,
r#"
CREATE TABLE name_insurance_join (
id TEXT NOT NULL PRIMARY KEY,
name_link_id TEXT NOT NULL REFERENCES name_link(id),
insurance_provider_id TEXT NOT NULL REFERENCES insurance_provider(id),
policy_number_person TEXT,
policy_number_family TEXT,
policy_number TEXT NOT NULL,
policy_type {policy_type} NOT NULL,
discount_percentage {DOUBLE} NOT NULL,
expiry_date DATE NOT NULL,
is_active BOOLEAN NOT NULL,
entered_by_id TEXT
);
"#
)?;

Ok(())
}
}
2 changes: 2 additions & 0 deletions server/repository/src/migrations/v2_06_00/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod add_create_invoice_from_requisition_permission;
mod add_index_to_sync_buffer;
mod add_insurance_provider;
mod add_invoice_line_prescribed_quantity;
mod add_name_insurance_join;
mod add_name_next_of_kin_id;
mod add_name_next_of_kin_name;
mod add_program_deleted_datetime;
Expand Down Expand Up @@ -35,6 +36,7 @@ impl Migration for V2_06_00 {
Box::new(add_insurance_provider::Migrate),
Box::new(prescribed_quantity_store_pref::Migrate),
Box::new(add_name_next_of_kin_name::Migrate),
Box::new(add_name_insurance_join::Migrate),
]
}
}
Expand Down
4 changes: 2 additions & 2 deletions server/service/src/sync/test/test_data/insurance_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use repository::InsuranceProviderRow;
const TABLE_NAME: &str = "insuranceProvider";

const INSURANCE_PROVIDER_1: (&str, &str) = (
"3CB14F143AFF4232889615B52EC56A1D",
"INSURANCE_PROVIDER_1_ID",
r#"{
"ID": "3CB14F143AFF4232889615B52EC56A1D",
"ID": "INSURANCE_PROVIDER_1_ID",
"comment": "Test",
"isActive": true,
"prescriptionValidityDays": 30,
Expand Down
3 changes: 3 additions & 0 deletions server/service/src/sync/test/test_data/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub(crate) mod master_list;
pub(crate) mod master_list_line;
pub(crate) mod master_list_name_join;
pub(crate) mod name;
pub(crate) mod name_insurance_join;
pub(crate) mod name_oms_fields;
pub(crate) mod name_property;
pub(crate) mod name_store_join;
Expand Down Expand Up @@ -145,6 +146,7 @@ pub(crate) fn get_all_pull_upsert_remote_test_records() -> Vec<TestSyncIncomingR
test_records.append(&mut special::name_to_name_store_join::test_pull_upsert_records());
test_records.append(&mut currency::test_pull_upsert_records());
test_records.append(&mut indicator_value::test_pull_upsert_records());
test_records.append(&mut name_insurance_join::test_pull_upsert_records());

// Open mSupply central
test_records.append(&mut rnr_form::test_pull_upsert_records());
Expand Down Expand Up @@ -203,6 +205,7 @@ pub(crate) fn get_all_push_test_records() -> Vec<TestSyncOutgoingRecord> {
test_records.append(&mut barcode::test_push_records());
test_records.append(&mut name_store_join::test_push_upsert());
test_records.append(&mut name_to_name_store_join::test_push_records());
test_records.append(&mut name_insurance_join::test_push_records());

test_records
}
Expand Down
126 changes: 126 additions & 0 deletions server/service/src/sync/test/test_data/name_insurance_join.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
use repository::name_insurance_join_row::{InsurancePolicyType, NameInsuranceJoinRow};

use crate::sync::{
test::{TestSyncIncomingRecord, TestSyncOutgoingRecord},
translations::name_insurance_join::{LegacyInsurancePolicyType, LegacyNameInsuranceJoinRow},
};
use serde_json::json;

const TABLE_NAME: &str = "nameInsuranceJoin";

const NAME_INSURANCE_JOIN_1: (&str, &str) = (
"NAME_INSURANCE_JOIN_1_ID",
r#"{
"ID": "NAME_INSURANCE_JOIN_1_ID",
"discountRate": 30,
"enteredByID": "",
"expiryDate": "2026-01-23",
"insuranceProviderID": "INSURANCE_PROVIDER_1_ID",
"isActive": true,
"nameID": "1FB32324AF8049248D929CFB35F255BA",
"policyNumberFamily": "888",
"policyNumberFull": "888",
"policyNumberPerson": "",
"type": "personal"
}"#,
);

fn name_insurance_join_1() -> TestSyncIncomingRecord {
TestSyncIncomingRecord::new_pull_upsert(
TABLE_NAME,
NAME_INSURANCE_JOIN_1,
NameInsuranceJoinRow {
id: NAME_INSURANCE_JOIN_1.0.to_owned(),
name_link_id: "1FB32324AF8049248D929CFB35F255BA".to_owned(),
insurance_provider_id: "INSURANCE_PROVIDER_1_ID".to_owned(),
policy_number_person: None,
policy_number_family: Some("888".to_owned()),
policy_number: "888".to_owned(),
policy_type: InsurancePolicyType::Personal,
discount_percentage: 30.0,
expiry_date: "2026-01-23".parse().unwrap(),
is_active: true,
entered_by_id: None,
},
)
}

const NAME_INSURANCE_JOIN_2: (&str, &str) = (
"NAME_INSURANCE_JOIN_2_ID",
r#"{
"ID": "NAME_INSURANCE_JOIN_2_ID",
"discountRate": 20.5,
"enteredByID": "",
"expiryDate": "2027-01-01",
"insuranceProviderID": "INSURANCE_PROVIDER_1_ID",
"isActive": true,
"nameID": "1FB32324AF8049248D929CFB35F255BA",
"policyNumberFamily": "",
"policyNumberFull": "777",
"policyNumberPerson": "777",
"type": "business"
}"#,
);

fn name_insurance_join_2() -> TestSyncIncomingRecord {
TestSyncIncomingRecord::new_pull_upsert(
TABLE_NAME,
NAME_INSURANCE_JOIN_2,
NameInsuranceJoinRow {
id: NAME_INSURANCE_JOIN_2.0.to_owned(),
name_link_id: "1FB32324AF8049248D929CFB35F255BA".to_owned(),
insurance_provider_id: "INSURANCE_PROVIDER_1_ID".to_owned(),
policy_number_person: Some("777".to_owned()),
policy_number_family: None,
policy_number: "777".to_owned(),
policy_type: InsurancePolicyType::Business,
discount_percentage: 20.5,
expiry_date: "2027-01-01".parse().unwrap(),
is_active: true,
entered_by_id: None,
},
)
}

pub(crate) fn test_pull_upsert_records() -> Vec<TestSyncIncomingRecord> {
vec![name_insurance_join_1(), name_insurance_join_2()]
}

pub(crate) fn test_push_records() -> Vec<TestSyncOutgoingRecord> {
vec![
TestSyncOutgoingRecord {
record_id: NAME_INSURANCE_JOIN_1.0.to_string(),
table_name: TABLE_NAME.to_string(),
push_data: json!(LegacyNameInsuranceJoinRow {
ID: NAME_INSURANCE_JOIN_1.0.to_string(),
nameID: "1FB32324AF8049248D929CFB35F255BA".to_string(),
insuranceProviderID: "INSURANCE_PROVIDER_1_ID".to_string(),
discountRate: 30.0,
enteredByID: None,
expiryDate: "2026-01-23".parse().unwrap(),
isActive: true,
policyNumberFamily: Some("888".to_string()),
policyNumberFull: "888".to_string(),
policyNumberPerson: None,
policyType: LegacyInsurancePolicyType::Personal,
}),
},
TestSyncOutgoingRecord {
record_id: NAME_INSURANCE_JOIN_2.0.to_string(),
table_name: TABLE_NAME.to_string(),
push_data: json!(LegacyNameInsuranceJoinRow {
ID: NAME_INSURANCE_JOIN_2.0.to_string(),
nameID: "1FB32324AF8049248D929CFB35F255BA".to_string(),
insuranceProviderID: "INSURANCE_PROVIDER_1_ID".to_string(),
discountRate: 20.5,
enteredByID: None,
expiryDate: "2027-01-01".parse().unwrap(),
isActive: true,
policyNumberFamily: None,
policyNumberFull: "777".to_string(),
policyNumberPerson: Some("777".to_string()),
policyType: LegacyInsurancePolicyType::Business,
}),
},
]
}
5 changes: 0 additions & 5 deletions server/service/src/sync/translations/insurance_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ impl SyncTranslation for InsuranceProviderTranslator {
_connection: &StorageConnection,
sync_record: &SyncBufferRow,
) -> Result<PullTranslateResult, anyhow::Error> {
println!(
"Translating insurance provider record: {}",
sync_record.data
);

let LegacyInsuranceProvider {
id,
comment,
Expand Down
Loading

0 comments on commit a671bbb

Please sign in to comment.