diff --git a/samples/MyCRM.Lodgement.Automation/MyCRM.Lodgement.Automation.csproj b/samples/MyCRM.Lodgement.Automation/MyCRM.Lodgement.Automation.csproj
index 003a3f5..ecd6a51 100644
--- a/samples/MyCRM.Lodgement.Automation/MyCRM.Lodgement.Automation.csproj
+++ b/samples/MyCRM.Lodgement.Automation/MyCRM.Lodgement.Automation.csproj
@@ -4,7 +4,7 @@
Exe
true
full
- net6.0
+ net8.0
latest
diff --git a/samples/MyCRM.Lodgement.Core/Enums/ApplicationScenario.cs b/samples/MyCRM.Lodgement.Core/Enums/ApplicationScenario.cs
new file mode 100644
index 0000000..711163b
--- /dev/null
+++ b/samples/MyCRM.Lodgement.Core/Enums/ApplicationScenario.cs
@@ -0,0 +1,9 @@
+using System.ComponentModel;
+
+namespace MyCRM.Lodgement.Common.Models;
+
+public enum LoanApplicationScenario
+{
+ [Description("NewLoanApplication")]
+ NewLoanApplication,
+}
\ No newline at end of file
diff --git a/samples/MyCRM.Lodgement.Core/LixiPackageSamples/NewLoanApplication.json b/samples/MyCRM.Lodgement.Core/LixiPackageSamples/NewLoanApplication.json
new file mode 100644
index 0000000..b70cc6b
--- /dev/null
+++ b/samples/MyCRM.Lodgement.Core/LixiPackageSamples/NewLoanApplication.json
@@ -0,0 +1,1730 @@
+{
+ "ProductionData": false,
+ "Content": {
+ "Application": {
+ "UniqueID": "LoanScenario-5542468-ZVVVNU1",
+ "Address": [
+ {
+ "AustralianPostCode": "2640",
+ "AustralianState": "NSW",
+ "City": "Albury",
+ "Country": "AU",
+ "Latitude": -36.0741418,
+ "Longitude": 146.9101373,
+ "Suburb": "Albury",
+ "Type": "Standard",
+ "UniqueID": "Address_11696101",
+ "Standard": {
+ "StreetName": "Thurgoona",
+ "StreetNumber": "616",
+ "StreetType": "Street"
+ }
+ },
+ {
+ "AustralianPostCode": "6059",
+ "AustralianState": "WA",
+ "City": "Dianella",
+ "Country": "AU",
+ "Latitude": -31.8891855,
+ "Longitude": 115.8697586,
+ "Suburb": "Dianella",
+ "Type": "Standard",
+ "UniqueID": "Address_11829994",
+ "Standard": {
+ "StreetName": "Booker",
+ "StreetNumber": "75",
+ "StreetType": "Street"
+ }
+ },
+ {
+ "AustralianPostCode": "3978",
+ "AustralianState": "VIC",
+ "City": "clyde north",
+ "Country": "AU",
+ "Suburb": "clyde north",
+ "Type": "Standard",
+ "UniqueID": "Address_13531793",
+ "Standard": {
+ "StreetName": "harrys",
+ "StreetNumber": "12",
+ "StreetType": "Avenue"
+ }
+ },
+ {
+ "AustralianPostCode": "4113",
+ "AustralianState": "QLD",
+ "City": "Runcorn",
+ "Country": "AU",
+ "Latitude": -27.587909,
+ "Longitude": 153.076485,
+ "Suburb": "Runcorn",
+ "Type": "Standard",
+ "UniqueID": "Address_13627215",
+ "Standard": {
+ "StreetName": "Diamond",
+ "StreetNumber": "8",
+ "StreetType": "Place",
+ "Unit": "unit 60"
+ }
+ },
+ {
+ "AustralianPostCode": "4113",
+ "AustralianState": "QLD",
+ "City": "Runcorn",
+ "Country": "AU",
+ "Latitude": -27.587909,
+ "Longitude": 153.076485,
+ "Suburb": "Runcorn",
+ "Type": "Standard",
+ "UniqueID": "Address_13627292",
+ "Standard": {
+ "StreetName": "Diamond",
+ "StreetNumber": "8",
+ "StreetType": "Place",
+ "Unit": "unit 50"
+ }
+ },
+ {
+ "AustralianPostCode": "4113",
+ "AustralianState": "QLD",
+ "City": "Runcorn",
+ "Country": "AU",
+ "Latitude": -27.5888638,
+ "Longitude": 153.0762382,
+ "Suburb": "Runcorn",
+ "Type": "Standard",
+ "UniqueID": "Address_13627438",
+ "Standard": {
+ "StreetName": "Diamond",
+ "StreetNumber": "20",
+ "StreetType": "Place"
+ }
+ },
+ {
+ "AustralianPostCode": "4113",
+ "AustralianState": "QLD",
+ "City": "Runcorn",
+ "Country": "AU",
+ "Latitude": -27.5892457,
+ "Longitude": 153.0769254,
+ "Suburb": "Runcorn",
+ "Type": "Standard",
+ "UniqueID": "Address_13627498",
+ "Standard": {
+ "StreetName": "Diamond",
+ "StreetNumber": "45",
+ "StreetType": "Place"
+ }
+ },
+ {
+ "AustralianPostCode": "3029",
+ "AustralianState": "VIC",
+ "City": "Tarneit",
+ "Country": "AU",
+ "Suburb": "Tarneit",
+ "Type": "Standard",
+ "UniqueID": "Address_11168887",
+ "Standard": {
+ "StreetName": "Lamington",
+ "StreetNumber": "18",
+ "StreetType": "Drive"
+ }
+ },
+ {
+ "AustralianPostCode": "3124",
+ "AustralianState": "VIC",
+ "City": "Camberwell",
+ "Country": "AU",
+ "Latitude": -37.8281618,
+ "Longitude": 145.0587268,
+ "Suburb": "Camberwell",
+ "Type": "Standard",
+ "UniqueID": "Address_3510876",
+ "Standard": {
+ "StreetNumber": "19"
+ }
+ },
+ {
+ "AustralianPostCode": "2000",
+ "AustralianState": "NSW",
+ "City": "",
+ "Country": "AU",
+ "Latitude": -33.8688197,
+ "Longitude": 151.2092955,
+ "Suburb": "",
+ "UniqueID": "Address_3386157"
+ },
+ {
+ "AustralianPostCode": "4213",
+ "AustralianState": "QLD",
+ "City": "Mudgeeraba",
+ "Country": "AU",
+ "Latitude": -28.1040346,
+ "Longitude": 153.3530469,
+ "Suburb": "Mudgeeraba",
+ "Type": "Standard",
+ "UniqueID": "Address_8247579",
+ "Standard": {
+ "StreetName": "Strawberry",
+ "StreetNumber": "20-22",
+ "StreetType": "Road"
+ }
+ },
+ {
+ "AustralianPostCode": "4000",
+ "AustralianState": "QLD",
+ "City": "Brisbane City",
+ "Country": "AU",
+ "Suburb": "Brisbane City",
+ "Type": "Standard",
+ "UniqueID": "Address_11087379",
+ "Standard": {
+ "StreetName": "Quay",
+ "StreetNumber": "111",
+ "StreetType": "Street"
+ }
+ },
+ {
+ "AustralianPostCode": "4069",
+ "AustralianState": "QLD",
+ "City": "Fig Tree Pocket",
+ "Country": "AU",
+ "Latitude": -27.5286302,
+ "Longitude": 152.9664001,
+ "Suburb": "Fig Tree Pocket",
+ "Type": "Standard",
+ "UniqueID": "Address_11555582",
+ "Standard": {
+ "StreetName": "Oasis",
+ "StreetNumber": "9",
+ "StreetType": "Court"
+ }
+ },
+ {
+ "AustralianPostCode": "4110",
+ "AustralianState": "QLD",
+ "City": "Pallara",
+ "Country": "AU",
+ "Latitude": -27.6174073,
+ "Longitude": 153.0116075,
+ "Suburb": "Pallara",
+ "Type": "Standard",
+ "UniqueID": "Address_12459614",
+ "Standard": {
+ "StreetName": "Ponting",
+ "StreetNumber": "95"
+ }
+ },
+ {
+ "AustralianPostCode": "2000",
+ "AustralianState": "NSW",
+ "City": "Sydney",
+ "Country": "AU",
+ "Latitude": -33.869167,
+ "Longitude": 151.2087416,
+ "Suburb": "Sydney",
+ "Type": "Standard",
+ "UniqueID": "Address_3416383",
+ "Standard": {
+ "StreetNumber": "135"
+ }
+ },
+ {
+ "AustralianPostCode": "4000",
+ "AustralianState": "QLD",
+ "City": "BRISBANE CITY",
+ "Country": "AU",
+ "Latitude": -27.4676885,
+ "Longitude": 153.0303725,
+ "Suburb": "BRISBANE CITY",
+ "Type": "Standard",
+ "UniqueID": "Address_807535",
+ "Standard": {
+ "Level": "26",
+ "StreetName": "EAGLE",
+ "StreetNumber": "111",
+ "StreetType": "Street"
+ }
+ }
+ ],
+ "BusinessChannel": {
+ "CompanyName": "TestBank",
+ "OtherIdentifier": "C9RZZZ",
+ "UniqueID": "Lender_5054",
+ "Contact": {
+ "WebAddress": "https://www.Lender.com.au/",
+ "OfficePhone": {
+ "Number": "02 9999 9999"
+ }
+ }
+ },
+ "ContributionFunds": [
+ {
+ "Amount": 200000,
+ "Description": "FUNDS_AVAILABLE",
+ "Type": "Genuine Savings",
+ "UniqueID": "Funds_28548183"
+ }
+ ],
+ "DetailedComment": [
+ {
+ "ContextDescription": "Immediate goals & objectives",
+ "Comment": "Testing - SIT NextGen Submission"
+ },
+ {
+ "ContextDescription": "Advisor Notes - ",
+ "Comment": "Testing - SIT NextGen Submission"
+ },
+ {
+ "ContextDescription": "Lender and product selection rationale - Summary",
+ "Comment": "Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission
Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission Testing - SIT NextGen Submission"
+ }
+ ],
+ "Household": [
+ {
+ "NumberOfAdults": 2,
+ "NumberOfDependants": 0,
+ "UniqueID": "Family_7102929",
+ "ExpenseDetails": {
+ "LivingExpense": [
+ {
+ "Amount": 800,
+ "Category": "Groceries",
+ "Description": "Groceries",
+ "Frequency": "Monthly"
+ },
+ {
+ "Amount": 3300,
+ "Category": "Primary Residence Running Costs",
+ "Description": "Electricity & Gas, Council Rates, Water & Sewer, Body Corporate",
+ "Frequency": "Monthly"
+ },
+ {
+ "Amount": 1200,
+ "Category": "Investment Property Running Costs",
+ "Description": "Building Insurance",
+ "Frequency": "Monthly"
+ },
+ {
+ "Amount": 260,
+ "Category": "Health Insurance",
+ "Description": "Health Insurance",
+ "Frequency": "Monthly"
+ },
+ {
+ "Amount": 100,
+ "Category": "General Basic Insurances",
+ "Description": "Vehicle Insurance",
+ "Frequency": "Monthly"
+ },
+ {
+ "Amount": 50,
+ "Category": "Medical and health",
+ "Description": "Medical & Health",
+ "Frequency": "Monthly"
+ },
+ {
+ "Amount": 200,
+ "Category": "Clothing and personal care",
+ "Description": "Clothing & Footwear, Personal Care",
+ "Frequency": "Monthly"
+ },
+ {
+ "Amount": 530,
+ "Category": "Recreation and entertainment",
+ "Description": "Cinema/Concerts/Memberships, Dining Out, Gym / Sports",
+ "Frequency": "Monthly"
+ },
+ {
+ "Amount": 170,
+ "Category": "Telephone, internet, pay TV and media streaming subscriptions",
+ "Description": "Home/Mobile Phone, Internet, Pay TV & Media Streaming Subscriptions",
+ "Frequency": "Monthly"
+ },
+ {
+ "Amount": 375,
+ "Category": "Transport",
+ "Description": "Petrol, Registration, Vehicle Maintenance, Tolls/Parking etc",
+ "Frequency": "Monthly"
+ }
+ ]
+ }
+ }
+ ],
+ "Insurance": [
+ {
+ "Description": "Life Insurance",
+ "InsuranceType": "Life Insurance",
+ "InsuredAmount": 150000,
+ "OtherInsurerName": "",
+ "UniqueID": "Insurance_15254658",
+ "InsuredParty": [
+ {
+ "x_InsuredParty": "Family_8477374"
+ },
+ {
+ "x_InsuredParty": "Family_8477375"
+ }
+ ]
+ }
+ ],
+ "Liability": [
+ {
+ "AnnualInterestRate": 0,
+ "ClearingFromThisLoan": false,
+ "ClearingFromThisLoanAmount": 0,
+ "CreditCardType": "MasterCard",
+ "CreditLimit": 15000,
+ "HasArrears": false,
+ "OutstandingBalance": 0,
+ "Type": "Credit Card",
+ "UniqueID": "FinancialLiability_45722253",
+ "AccountNumber": {},
+ "ContinuingRepayment": [
+ {
+ "LoanPaymentScheduleType": "Even Total Payments",
+ "PaymentType": "Principal and Interest",
+ "TaxDeductible": false
+ }
+ ],
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477374"
+ },
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477375"
+ }
+ ]
+ },
+ "Repayment": [
+ {
+ "LoanPaymentScheduleType": "Even Total Payments",
+ "PaymentType": "Principal and Interest",
+ "Regular": true,
+ "RepaymentAmount": 0,
+ "RepaymentFrequency": "Monthly",
+ "TaxDeductible": false
+ }
+ ]
+ },
+ {
+ "AnnualInterestRate": 0,
+ "ClearingFromThisLoan": false,
+ "ClearingFromThisLoanAmount": 0,
+ "CreditCardType": "Other Credit Card",
+ "CreditLimit": 17000,
+ "HasArrears": false,
+ "OutstandingBalance": 0,
+ "Type": "Credit Card",
+ "UniqueID": "FinancialLiability_45722241",
+ "AccountNumber": {},
+ "ContinuingRepayment": [
+ {
+ "LoanPaymentScheduleType": "Even Total Payments",
+ "PaymentType": "Principal and Interest",
+ "TaxDeductible": false
+ }
+ ],
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 100,
+ "x_Party": "Family_8477374"
+ },
+ {
+ "Percent": 0,
+ "x_Party": "Family_8477375"
+ }
+ ]
+ },
+ "Repayment": [
+ {
+ "LoanPaymentScheduleType": "Even Total Payments",
+ "PaymentType": "Principal and Interest",
+ "Regular": true,
+ "RepaymentAmount": 0,
+ "RepaymentFrequency": "Monthly",
+ "TaxDeductible": false
+ }
+ ]
+ },
+ {
+ "AnnualInterestRate": 0,
+ "ClearingFromThisLoan": false,
+ "ClearingFromThisLoanAmount": 415817,
+ "CreditLimit": 415817,
+ "HasArrears": false,
+ "OutstandingBalance": 415817,
+ "Type": "Mortgage Loan",
+ "UniqueID": "FinancialLiability_63101829",
+ "AccountNumber": {
+ "FinancialInstitution": "Other",
+ "OtherFIName": "ANZ Australia"
+ },
+ "ContinuingRepayment": [
+ {
+ "LoanPaymentScheduleType": "Even Total Payments",
+ "PaymentType": "Principal and Interest",
+ "TaxDeductible": false
+ }
+ ],
+ "OriginalTerm": {
+ "PaymentType": "Principal and Interest",
+ "PaymentTypeUnits": "Years",
+ "TotalTermDuration": 30
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477374"
+ },
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477375"
+ }
+ ]
+ },
+ "Repayment": [
+ {
+ "LoanPaymentScheduleType": "Even Total Payments",
+ "PaymentType": "Principal and Interest",
+ "Regular": true,
+ "RepaymentAmount": 2666,
+ "RepaymentFrequency": "Monthly",
+ "TaxDeductible": false
+ }
+ ],
+ "Security": [
+ {
+ "Priority": "First Mortgage",
+ "x_Security": "FinancialInfo_15708480"
+ }
+ ]
+ },
+ {
+ "AnnualInterestRate": 5.2,
+ "ClearingFromThisLoan": false,
+ "ClearingFromThisLoanAmount": 203000,
+ "CreditLimit": 203000,
+ "HasArrears": false,
+ "OutstandingBalance": 203000,
+ "Type": "Mortgage Loan",
+ "UniqueID": "FinancialLiability_47859966",
+ "AccountNumber": {
+ "FinancialInstitution": "Other",
+ "OtherFIName": "Westpac"
+ },
+ "ContinuingRepayment": [
+ {
+ "LoanPaymentScheduleType": "Even Total Payments",
+ "PaymentType": "Principal and Interest",
+ "TaxDeductible": false
+ }
+ ],
+ "OriginalTerm": {
+ "PaymentType": "Principal and Interest",
+ "PaymentTypeUnits": "Years",
+ "TotalTermDuration": 30
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 100,
+ "x_Party": "Family_8477375"
+ },
+ {
+ "Percent": 0,
+ "x_Party": "Family_8477374"
+ }
+ ]
+ },
+ "Repayment": [
+ {
+ "LoanPaymentScheduleType": "Even Total Payments",
+ "PaymentType": "Principal and Interest",
+ "Regular": true,
+ "RepaymentAmount": 1400,
+ "RepaymentFrequency": "Monthly",
+ "TaxDeductible": false
+ }
+ ],
+ "Security": [
+ {
+ "Priority": "First Mortgage",
+ "x_Security": "FinancialInfo_13162992"
+ }
+ ]
+ },
+ {
+ "AnnualInterestRate": 0,
+ "ClearingFromThisLoan": false,
+ "ClearingFromThisLoanAmount": 291476,
+ "CreditLimit": 291476,
+ "HasArrears": false,
+ "OutstandingBalance": 291476,
+ "Type": "Mortgage Loan",
+ "UniqueID": "FinancialLiability_55290391",
+ "AccountNumber": {
+ "FinancialInstitution": "Other",
+ "OtherFIName": "Adelaide Bank"
+ },
+ "ContinuingRepayment": [
+ {
+ "LoanPaymentScheduleType": "Even Total Payments",
+ "PaymentType": "Principal and Interest",
+ "TaxDeductible": true
+ }
+ ],
+ "OriginalTerm": {
+ "PaymentType": "Principal and Interest",
+ "PaymentTypeUnits": "Years",
+ "TotalTermDuration": 26
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 100,
+ "x_Party": "Family_8477375"
+ },
+ {
+ "Percent": 0,
+ "x_Party": "Family_8477374"
+ }
+ ]
+ },
+ "Repayment": [
+ {
+ "LoanPaymentScheduleType": "Even Total Payments",
+ "PaymentType": "Principal and Interest",
+ "Regular": true,
+ "RepaymentAmount": 1902,
+ "RepaymentFrequency": "Monthly",
+ "TaxDeductible": true
+ }
+ ],
+ "Security": [
+ {
+ "Priority": "First Mortgage",
+ "x_Security": "FinancialInfo_14381322"
+ }
+ ]
+ },
+ {
+ "AnnualInterestRate": 7.15,
+ "ClearingFromThisLoan": false,
+ "ClearingFromThisLoanAmount": 875000,
+ "CreditLimit": 875000,
+ "HasArrears": false,
+ "OutstandingBalance": 875000,
+ "Type": "Mortgage Loan",
+ "UniqueID": "FinancialLiability_51868326",
+ "AccountNumber": {
+ "FinancialInstitution": "Other",
+ "OtherFIName": "Commonwealth Bank"
+ },
+ "ContinuingRepayment": [
+ {
+ "LoanPaymentScheduleType": "Even Total Payments",
+ "PaymentType": "Principal and Interest",
+ "TaxDeductible": false
+ }
+ ],
+ "OriginalTerm": {
+ "PaymentType": "Principal and Interest",
+ "PaymentTypeUnits": "Years",
+ "TotalTermDuration": 30
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477374"
+ },
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477375"
+ }
+ ]
+ },
+ "Repayment": [
+ {
+ "LoanPaymentScheduleType": "Even Total Payments",
+ "PaymentType": "Principal and Interest",
+ "Regular": true,
+ "RepaymentAmount": 5909.81,
+ "RepaymentFrequency": "Monthly",
+ "TaxDeductible": false
+ }
+ ],
+ "Security": [
+ {
+ "Priority": "First Mortgage",
+ "x_Security": "FinancialInfo_13821438"
+ }
+ ]
+ },
+ {
+ "AnnualInterestRate": 0,
+ "ClearingFromThisLoan": false,
+ "ClearingFromThisLoanAmount": 785406,
+ "CreditLimit": 785406,
+ "HasArrears": false,
+ "OutstandingBalance": 785406,
+ "Type": "Mortgage Loan",
+ "UniqueID": "FinancialLiability_55290515",
+ "AccountNumber": {
+ "FinancialInstitution": "Other",
+ "OtherFIName": "Adelaide Bank"
+ },
+ "ContinuingRepayment": [
+ {
+ "LoanPaymentScheduleType": "Even Total Payments",
+ "PaymentType": "Principal and Interest",
+ "TaxDeductible": true
+ }
+ ],
+ "OriginalTerm": {
+ "PaymentType": "Principal and Interest",
+ "PaymentTypeUnits": "Years",
+ "TotalTermDuration": 29
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477374"
+ },
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477375"
+ }
+ ]
+ },
+ "Repayment": [
+ {
+ "LoanPaymentScheduleType": "Even Total Payments",
+ "PaymentType": "Principal and Interest",
+ "Regular": true,
+ "RepaymentAmount": 5199,
+ "RepaymentFrequency": "Monthly",
+ "TaxDeductible": true
+ }
+ ],
+ "Security": [
+ {
+ "Priority": "First Mortgage",
+ "x_Security": "FinancialInfo_14381339"
+ }
+ ]
+ }
+ ],
+ "LoanDetails": [
+ {
+ "AmountRequested": 620000,
+ "LoanType": "Term Loan",
+ "LVR": 77.5,
+ "Secured": "true",
+ "StatementCycle": "Monthly",
+ "TaxDeductible": false,
+ "UniqueID": "LoanStructure_6717099",
+ "Borrowers": {
+ "Proportions": "Equal",
+ "Owner": [
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477374"
+ },
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477375"
+ }
+ ]
+ },
+ "FeaturesSelected": {
+ "ChequeBook": false,
+ "CreditCard": false,
+ "RateLock": false,
+ "Redraw": true
+ },
+ "LendingPurpose": [
+ {
+ "IncludesRefinancing": false
+ },
+ {
+ "ABSLendingPurpose": "Purchase a Property",
+ "ABSLendingPurposeCode": "ABS-129",
+ "PurposeAmount": 620000
+ }
+ ],
+ "LoanPurpose": {
+ "PrimaryPurpose": "Owner Occupied"
+ },
+ "ProposedRepayment": {
+ "RegularRepayment": [
+ {
+ "Amount": 0,
+ "Frequency": "Monthly"
+ }
+ ]
+ },
+ "Term": {
+ "PaymentType": "Principal and Interest",
+ "TotalTermDuration": 30,
+ "TotalTermType": "Total Term",
+ "TotalTermUnits": "Years"
+ }
+ }
+ ],
+ "NonRealEstateAsset": [
+ {
+ "ToBeSold": false,
+ "ToBeUsedAsSecurity": false,
+ "Type": "Motor Vehicle and Transport",
+ "UniqueID": "FinancialInfo_12811548",
+ "EstimatedValue": {
+ "EstimateBasis": "Applicant Estimate",
+ "Value": 15000
+ },
+ "MotorVehicle": {
+ "Age": 9,
+ "Description": "2015 Hyundai (Luxury Car)",
+ "Make": "Hyundai",
+ "Type": "Car",
+ "Year": "2015"
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477374"
+ },
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477375"
+ }
+ ]
+ }
+ },
+ {
+ "ToBeSold": false,
+ "ToBeUsedAsSecurity": false,
+ "Type": "Financial Asset",
+ "UniqueID": "FinancialInfo_12811552",
+ "EstimatedValue": {
+ "EstimateBasis": "Applicant Estimate",
+ "Value": 55000
+ },
+ "FinancialAsset": {
+ "Description": "ANZ Australia",
+ "Type": "Savings Account",
+ "AccountNumber": {
+ "FinancialInstitution": "Other",
+ "OtherFIName": "ANZ Australia"
+ }
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477374"
+ },
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477375"
+ }
+ ]
+ }
+ },
+ {
+ "ToBeSold": false,
+ "ToBeUsedAsSecurity": false,
+ "Type": "Financial Asset",
+ "UniqueID": "FinancialInfo_12811556",
+ "EstimatedValue": {
+ "EstimateBasis": "Applicant Estimate",
+ "Value": 80000
+ },
+ "FinancialAsset": {
+ "Description": "",
+ "Type": "Superannuation",
+ "AccountNumber": {
+ "FinancialInstitution": "Other",
+ "OtherFIName": ""
+ }
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 100,
+ "x_Party": "Family_8477375"
+ },
+ {
+ "Percent": 0,
+ "x_Party": "Family_8477374"
+ }
+ ]
+ }
+ },
+ {
+ "ToBeSold": false,
+ "ToBeUsedAsSecurity": false,
+ "Type": "Financial Asset",
+ "UniqueID": "FinancialInfo_12811554",
+ "EstimatedValue": {
+ "EstimateBasis": "Applicant Estimate",
+ "Value": 60000
+ },
+ "FinancialAsset": {
+ "Description": "",
+ "Type": "Superannuation",
+ "AccountNumber": {
+ "FinancialInstitution": "Other",
+ "OtherFIName": ""
+ }
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 100,
+ "x_Party": "Family_8477374"
+ },
+ {
+ "Percent": 0,
+ "x_Party": "Family_8477375"
+ }
+ ]
+ }
+ },
+ {
+ "ToBeSold": false,
+ "ToBeUsedAsSecurity": false,
+ "Type": "Other",
+ "UniqueID": "FinancialInfo_15254658",
+ "EstimatedValue": {
+ "EstimateBasis": "Applicant Estimate",
+ "Value": 150000
+ },
+ "Insurance": [
+ {
+ "x_Insurance": "Insurance_15254658"
+ }
+ ],
+ "OtherAsset": {
+ "Description": "Life Insurance",
+ "Type": "Other"
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477374"
+ },
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477375"
+ }
+ ]
+ }
+ }
+ ],
+ "Overview": {
+ "ApplicationType": "Loan",
+ "BrokerApplicationReferenceNumber": "5542468",
+ "IsBridgingFinance": false
+ },
+ "PersonApplicant": [
+ {
+ "ApplicantType": "Borrower",
+ "Citizenship": "AU",
+ "DateOfBirth": "1986-06-06",
+ "FirstHomeBuyer": false,
+ "Gender": "Female",
+ "HasPreviousName": false,
+ "IsExistingCustomer": false,
+ "MaritalStatus": "Single",
+ "MonthsInCurrentProfession": 3,
+ "MothersMaidenName": "",
+ "PrimaryApplicant": true,
+ "PrincipalForeignResidence": "AU",
+ "ResidencyStatus": "Permanently in Australia",
+ "UnderstandApplication": true,
+ "UniqueID": "Family_8477374",
+ "x_Household": "Family_7102929",
+ "YearsInCurrentProfession": 6,
+ "Contact": {
+ "PreferredContact": "Mobile",
+ "EmailAddress": [
+ {
+ "Email": "testEmail@testcompany.com",
+ "EmailType": "Home"
+ }
+ ],
+ "Mobile": {
+ "AustralianDialingCode": "04",
+ "CountryCode": "61",
+ "Number": "0499999999"
+ },
+ "PostSettlementAddress": {
+ "HousingStatus": "Own Home",
+ "x_ResidentialAddress": "Address_13627498"
+ },
+ "PreviousAddress": {
+ "EndDate": "2018-07-01",
+ "HousingStatus": "Own Home",
+ "StartDate": "2011-07-01",
+ "x_ResidentialAddress": "Address_11168887",
+ "Duration": {
+ "Length": 84,
+ "Units": "Months"
+ }
+ }
+ },
+ "Employment": [
+ {
+ "PAYG": {
+ "Basis": "Full Time",
+ "Occupation": "Testing 2",
+ "OnProbation": false,
+ "PositionTitle": "Testing 2",
+ "StartDate": "2018-04-10",
+ "Status": "Primary",
+ "UniqueID": "Employment_5283447",
+ "x_Employer": "EmployerCompany_5283447",
+ "Duration": {
+ "Length": 75,
+ "Units": "Months"
+ },
+ "Income": {
+ "GrossRegularOvertimeAmountConditionOfEmployment": false,
+ "GrossSalaryAmount": 90000,
+ "GrossSalaryFrequency": "Yearly",
+ "WorkAllowanceAmountConditionOfEmployment": false
+ }
+ }
+ },
+ {
+ "PAYG": {
+ "Basis": "Full Time",
+ "EndDate": "2018-03-19",
+ "Occupation": "Testing",
+ "OnProbation": false,
+ "PositionTitle": "Testing",
+ "StartDate": "2012-07-07",
+ "Status": "Previous",
+ "UniqueID": "Employment_5283440",
+ "x_Employer": "EmployerCompany_5283440",
+ "Duration": {
+ "Length": 68,
+ "Units": "Months"
+ },
+ "Income": {
+ "GrossRegularOvertimeAmountConditionOfEmployment": false,
+ "GrossSalaryAmount": 80000,
+ "GrossSalaryFrequency": "Yearly",
+ "WorkAllowanceAmountConditionOfEmployment": false
+ }
+ }
+ }
+ ],
+ "PersonName": {
+ "FirstName": "Wanda",
+ "KnownAs": "Wanda",
+ "MiddleNames": "",
+ "NameTitle": "Mrs",
+ "Surname": "Maximoff"
+ },
+ "Privacy": {
+ "AllowCreditBureauIdentityCheck": true,
+ "AllowCreditCheck": true,
+ "AllowElectronicIdentityCheck": true,
+ "PrivacyActConsentSigned": true
+ },
+ "ProofOfIdentity": [
+ {
+ "CertifiedCopy": false,
+ "CountryOfIssue": "AU",
+ "DocumentNumber": "",
+ "DocumentType": "Other",
+ "ExpiryDate": "2027-09-23",
+ "IssuingOrganisation": "",
+ "MiddleNameOnDocument": "Wanda",
+ "NameOnDocument": "Wanda Maximoff",
+ "Original": false,
+ "OtherDescription": "Drivers Licence Australia",
+ "PlaceOfIssue": ""
+ }
+ ],
+ "ResponsibleLending": {
+ "AnticipatedChanges": false
+ }
+ },
+ {
+ "ApplicantType": "Borrower",
+ "Citizenship": "AU",
+ "DateOfBirth": "1986-01-01",
+ "FirstHomeBuyer": false,
+ "Gender": "Male",
+ "HasPreviousName": false,
+ "IsExistingCustomer": false,
+ "MaritalStatus": "Single",
+ "MothersMaidenName": "",
+ "PrimaryApplicant": false,
+ "PrincipalForeignResidence": "AU",
+ "ResidencyStatus": "Permanently in Australia",
+ "UnderstandApplication": true,
+ "UniqueID": "Family_8477375",
+ "x_Household": "Family_7102929",
+ "YearsInCurrentProfession": 8,
+ "Contact": {
+ "PreferredContact": "Mobile",
+ "EmailAddress": [
+ {
+ "Email": "testBroker@testCompany.com",
+ "EmailType": "Home"
+ }
+ ],
+ "Mobile": {
+ "AustralianDialingCode": "04",
+ "CountryCode": "61",
+ "Number": "0488888888"
+ },
+ "PostSettlementAddress": {
+ "HousingStatus": "Own Home",
+ "x_ResidentialAddress": "Address_13627498"
+ },
+ "PreviousAddress": {
+ "EndDate": "2018-07-01",
+ "HousingStatus": "Own Home",
+ "StartDate": "2011-07-01",
+ "x_ResidentialAddress": "Address_11168887",
+ "Duration": {
+ "Length": 84,
+ "Units": "Months"
+ }
+ }
+ },
+ "Employment": [
+ {
+ "PAYG": {
+ "Basis": "Full Time",
+ "Occupation": "Senior DevOps Engineer",
+ "OnProbation": false,
+ "PositionTitle": "Senior DevOps Engineer",
+ "StartDate": "2016-08-02",
+ "Status": "Primary",
+ "UniqueID": "Employment_4688212",
+ "x_Employer": "EmployerCompany_4688212",
+ "Duration": {
+ "Length": 96,
+ "Units": "Months"
+ },
+ "Income": {
+ "GrossRegularOvertimeAmountConditionOfEmployment": false,
+ "GrossSalaryAmount": 5769,
+ "GrossSalaryFrequency": "Fortnightly",
+ "WorkAllowanceAmountConditionOfEmployment": false
+ }
+ }
+ }
+ ],
+ "PersonName": {
+ "FirstName": "Vision",
+ "KnownAs": "Vision",
+ "MiddleNames": "",
+ "NameTitle": "Mr",
+ "Surname": "Vis"
+ },
+ "Privacy": {
+ "AllowCreditBureauIdentityCheck": true,
+ "AllowCreditCheck": true,
+ "AllowElectronicIdentityCheck": true,
+ "PrivacyActConsentSigned": true
+ },
+ "ProofOfIdentity": [
+ {
+ "CertifiedCopy": false,
+ "CountryOfIssue": "AU",
+ "DocumentNumber": "",
+ "DocumentType": "Other",
+ "ExpiryDate": "2027-09-22",
+ "IssuingOrganisation": "",
+ "MiddleNameOnDocument": "ion",
+ "NameOnDocument": "Vision Vis",
+ "Original": false,
+ "OtherDescription": "Drivers Licence Australia",
+ "PlaceOfIssue": ""
+ }
+ ],
+ "ResponsibleLending": {
+ "AnticipatedChanges": false
+ }
+ }
+ ],
+ "RealEstateAsset": [
+ {
+ "ApprovalInPrinciple": false,
+ "Occupancy": "Owner Primary",
+ "PrimaryPurpose": "Owner Occupied",
+ "PrimaryUsage": "Residential",
+ "ToBeUsedAsSecurity": false,
+ "Transaction": "Owns",
+ "UniqueID": "FinancialInfo_15708480",
+ "x_Address": "Address_13531793",
+ "ContractDetails": {},
+ "Encumbrance": [
+ {
+ "EncumbranceType": "Mortgage",
+ "Priority": "First Mortgage",
+ "UniqueID": "FinancialLiability_10219681"
+ }
+ ],
+ "EstimatedValue": {
+ "EstimateBasis": "Applicant Estimate",
+ "Value": 453000
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 100,
+ "x_Party": "Family_8477374"
+ },
+ {
+ "Percent": 0,
+ "x_Party": "Family_8477375"
+ }
+ ]
+ },
+ "PropertyType": {
+ "PropertyTypeName": "Fully Detached House"
+ },
+ "Residential": {
+ "Type": "Fully Detached House"
+ },
+ "Zoning": {
+ "Type": "Residential"
+ }
+ },
+ {
+ "ApprovalInPrinciple": false,
+ "Occupancy": "Owner Primary",
+ "PrimaryPurpose": "Investment",
+ "PrimaryUsage": "Residential",
+ "ToBeUsedAsSecurity": false,
+ "Transaction": "Owns",
+ "UniqueID": "FinancialInfo_13162992",
+ "x_Address": "Address_11168887",
+ "ContractDetails": {},
+ "Encumbrance": [
+ {
+ "EncumbranceType": "Mortgage",
+ "Priority": "First Mortgage",
+ "UniqueID": "FinancialLiability_7966108"
+ }
+ ],
+ "EstimatedValue": {
+ "EstimateBasis": "Certified Valuation",
+ "Value": 740000
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 100,
+ "x_Party": "Family_8477375"
+ },
+ {
+ "Percent": 0,
+ "x_Party": "Family_8477374"
+ }
+ ]
+ },
+ "PropertyType": {
+ "PropertyTypeName": "Fully Detached House"
+ },
+ "Residential": {
+ "Type": "Fully Detached House"
+ },
+ "Zoning": {
+ "Type": "Residential"
+ }
+ },
+ {
+ "ApprovalInPrinciple": false,
+ "Occupancy": "Owner Primary",
+ "PrimaryPurpose": "Owner Occupied",
+ "PrimaryUsage": "Residential",
+ "ToBeUsedAsSecurity": false,
+ "Transaction": "Owns",
+ "UniqueID": "FinancialInfo_13790701",
+ "x_Address": "Address_8247579",
+ "ContractDetails": {},
+ "EstimatedValue": {
+ "EstimateBasis": "Certified Valuation",
+ "Value": 1312908
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477374"
+ },
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477375"
+ }
+ ]
+ },
+ "PropertyType": {
+ "PropertyTypeName": "Fully Detached House"
+ },
+ "Residential": {
+ "Type": "Fully Detached House"
+ },
+ "Zoning": {
+ "Type": "Residential"
+ }
+ },
+ {
+ "ApprovalInPrinciple": false,
+ "Occupancy": "Owner Primary",
+ "PrimaryPurpose": "Investment",
+ "PrimaryUsage": "Residential",
+ "ToBeUsedAsSecurity": false,
+ "Transaction": "Owns",
+ "UniqueID": "FinancialInfo_14381322",
+ "x_Address": "Address_11087379",
+ "ContractDetails": {},
+ "Encumbrance": [
+ {
+ "EncumbranceType": "Mortgage",
+ "Priority": "First Mortgage",
+ "UniqueID": "FinancialLiability_9060327"
+ }
+ ],
+ "EstimatedValue": {
+ "EstimateBasis": "Applicant Estimate",
+ "Value": 400000
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 100,
+ "x_Party": "Family_8477375"
+ },
+ {
+ "Percent": 0,
+ "x_Party": "Family_8477374"
+ }
+ ]
+ },
+ "PropertyType": {
+ "PropertyTypeName": "Std Apartment"
+ },
+ "Residential": {
+ "Type": "Apartment Unit Flat"
+ },
+ "Zoning": {
+ "Type": "Residential"
+ }
+ },
+ {
+ "ApprovalInPrinciple": false,
+ "Occupancy": "Owner Primary",
+ "PrimaryPurpose": "Owner Occupied",
+ "PrimaryUsage": "Residential",
+ "ToBeUsedAsSecurity": false,
+ "Transaction": "Owns",
+ "UniqueID": "FinancialInfo_13821438",
+ "x_Address": "Address_11555582",
+ "ContractDetails": {},
+ "Encumbrance": [
+ {
+ "EncumbranceType": "Mortgage",
+ "Priority": "First Mortgage",
+ "UniqueID": "FinancialLiability_8539113"
+ }
+ ],
+ "EstimatedValue": {
+ "EstimateBasis": "Applicant Estimate",
+ "Value": 1980000
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477374"
+ },
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477375"
+ }
+ ]
+ },
+ "PropertyType": {
+ "PropertyTypeName": "Fully Detached House"
+ },
+ "Residential": {
+ "Type": "Fully Detached House"
+ },
+ "Zoning": {
+ "Type": "Residential"
+ }
+ },
+ {
+ "ApprovalInPrinciple": false,
+ "Occupancy": "Owner Primary",
+ "PrimaryPurpose": "Investment",
+ "PrimaryUsage": "Residential",
+ "ToBeUsedAsSecurity": false,
+ "Transaction": "Owns",
+ "UniqueID": "FinancialInfo_14381339",
+ "x_Address": "Address_12459614",
+ "ContractDetails": {},
+ "Encumbrance": [
+ {
+ "EncumbranceType": "Mortgage",
+ "Priority": "First Mortgage",
+ "UniqueID": "FinancialLiability_9060352"
+ }
+ ],
+ "EstimatedValue": {
+ "EstimateBasis": "Applicant Estimate",
+ "Value": 1000000
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477374"
+ },
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477375"
+ }
+ ]
+ },
+ "PropertyType": {
+ "PropertyTypeName": "Fully Detached House"
+ },
+ "Residential": {
+ "Type": "Fully Detached House"
+ },
+ "Zoning": {
+ "Type": "Residential"
+ }
+ },
+ {
+ "ApprovalInPrinciple": false,
+ "Construction": false,
+ "Holding": "Joint Tenants",
+ "Occupancy": "Owner Primary",
+ "PrimaryPurpose": "Owner Occupied",
+ "PrimarySecurity": true,
+ "PrimaryUsage": "Residential",
+ "Status": "Established",
+ "ToBeUsedAsSecurity": true,
+ "Transaction": "Purchasing",
+ "UniqueID": "SecurityInfo_5583881",
+ "x_Address": "Address_13627215",
+ "ContractDetails": {
+ "LicencedRealEstateAgentContract": true
+ },
+ "EstimatedValue": {
+ "EstimateBasis": "Applicant Estimate",
+ "Value": 800000
+ },
+ "PercentOwned": {
+ "Proportions": "Specified",
+ "Owner": [
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477374"
+ },
+ {
+ "Percent": 50,
+ "x_Party": "Family_8477375"
+ }
+ ]
+ },
+ "PropertyType": {
+ "PropertyTypeName": "Fully Detached House"
+ },
+ "Residential": {
+ "Type": "Fully Detached House"
+ },
+ "Title": [
+ {
+ "TenureType": "Other Title",
+ "TitleSystem": "Torrens"
+ }
+ ],
+ "Zoning": {
+ "Type": "Residential"
+ }
+ }
+ ],
+ "RelatedCompany": [
+ {
+ "BusinessName": "Australian Council of Educational Research",
+ "CompanyName": "Australian Council of Educational Research",
+ "UniqueID": "EmployerCompany_4688212",
+ "Contact": {
+ "x_Address": "Address_3510876",
+ "OfficePhone": {
+ "Number": "61477777777"
+ }
+ }
+ },
+ {
+ "BusinessName": "Testing 2",
+ "CompanyName": "Testing 2",
+ "UniqueID": "EmployerCompany_5283447",
+ "Contact": {
+ "x_Address": "Address_3386157",
+ "ContactPerson": {
+ "x_ContactPerson": "EmployerContact_5283447"
+ },
+ "OfficePhone": {
+ "Number": "61400000000"
+ }
+ }
+ },
+ {
+ "BusinessName": "Testing 1",
+ "CompanyName": "Testing 1",
+ "UniqueID": "EmployerCompany_5283440",
+ "Contact": {
+ "x_Address": "Address_3386157",
+ "ContactPerson": {
+ "x_ContactPerson": "EmployerContact_5283440"
+ },
+ "OfficePhone": {
+ "Number": "61400000000"
+ }
+ }
+ }
+ ],
+ "RelatedPerson": [
+ {
+ "UniqueID": "EmployerContact_5283447",
+ "Contact": {
+ "x_Address": "Address_3386157",
+ "Mobile": {
+ "Number": "61400000000"
+ }
+ },
+ "PersonName": {
+ "FirstName": "Testing 2",
+ "KnownAs": "Testing 2"
+ }
+ },
+ {
+ "UniqueID": "EmployerContact_5283440",
+ "Contact": {
+ "x_Address": "Address_3386157",
+ "Mobile": {
+ "Number": "61400101010"
+ }
+ },
+ "PersonName": {
+ "FirstName": "Testing",
+ "KnownAs": "Testing 1"
+ }
+ }
+ ],
+ "SalesChannel": {
+ "Type": "Mortgage Broker",
+ "Aggregator": {
+ "ABN": "67666666666",
+ "LicenceNumber": "555555",
+ "LicenceType": "ACL",
+ "UniqueID": "Aggregator_2",
+ "Contact": {
+ "Email": "testcustomerservice@testCompany.com.au",
+ "x_Address": "Address_807535",
+ "OfficePhone": {
+ "Number": "1800 000 000(free call)"
+ }
+ }
+ },
+ "Company": {
+ "ABN": "12313212312",
+ "CompanyName": "Test Company",
+ "LicenceNumber": "777777"
+ },
+ "LoanWriter": {
+ "FirstName": "Jeremy",
+ "Surname": "Adviser",
+ "UniqueID": "Family_6430652",
+ "Contact": {
+ "Email": "testAdviser@testCompany.com.au",
+ "x_Address": "Address_3416383",
+ "Fax": {},
+ "Mobile": {
+ "Number": "0400000000"
+ },
+ "OfficePhone": {
+ "Number": "0222222222"
+ }
+ }
+ }
+ },
+ "Summary": {
+ "Fee": [
+ {
+ "Amount": 0,
+ "CapitaliseFee": false,
+ "PayFeesFrom": "Account",
+ "Type": "LMI"
+ }
+ ],
+ "LoanToValuationRatio": {
+ "ApplicationLVR": 77.5
+ }
+ }
+ },
+ "NeedsAnalysis": {
+ "Interview": {},
+ "Preferences": {
+ "ConflictExists": false,
+ "InterestRateType": "Standard Variable",
+ "PreferredLenders": true,
+ "PreferredLendersDetails": ", ",
+ "FundsAccessTypeDetails": {
+ "OffsetAccount": {
+ "Importance": "Important",
+ "RisksExplained": true,
+ "Reason": {
+ "AllowsAccessToFunds": false,
+ "AllowsPayingOffLoanSooner": true,
+ "ForTaxPurposes": false,
+ "Other": false
+ }
+ },
+ "Redraw": {
+ "Importance": "Important",
+ "RisksExplained": true,
+ "Reason": {
+ "FlexibilityToAccessPrepaidFundsIfNeeded": true,
+ "Other": false
+ }
+ }
+ },
+ "InterestRateTypeDetails": {
+ "FixedAndVariableRate": {
+ "Importance": "Not Important"
+ },
+ "FixedRate": {
+ "Importance": "Not Important"
+ },
+ "VariableRate": {
+ "Importance": "Important",
+ "RisksExplained": true,
+ "Reason": {
+ "Flexibility": false,
+ "Other": false,
+ "PotentialRateDecreases": true
+ }
+ }
+ },
+ "RepaymentTypeDetails": {
+ "InterestInAdvance": {
+ "Importance": "Not Important"
+ },
+ "InterestOnly": {
+ "Importance": "Not Important"
+ },
+ "LineOfCredit": {
+ "Importance": "Not Important"
+ },
+ "PrincipalAndInterest": {
+ "Importance": "Important",
+ "RepaymentFrequency": "Weekly",
+ "RisksExplained": true
+ }
+ }
+ },
+ "RetirementDetails": {
+ "Applicant": [
+ {
+ "ImminentlyRetiring": false,
+ "IntendedRetirementAge": 70,
+ "UnderstandsImpactOnRetirementPlans": false,
+ "x_Applicant": "Family_8477374",
+ "RepaymentOptions": {
+ "CoApplicantIncome": false,
+ "DownsizingHome": false,
+ "IncomeFromOtherInvestments": false,
+ "Other": false,
+ "RecurringIncomeFromSuperannuation": false,
+ "RepaymentOfLoanPriorToRetirement": false,
+ "SaleOfAssets": true,
+ "Savings": false,
+ "SuperannuationLumpSumFollowingRetirement": false
+ }
+ },
+ {
+ "ImminentlyRetiring": false,
+ "IntendedRetirementAge": 70,
+ "UnderstandsImpactOnRetirementPlans": false,
+ "x_Applicant": "Family_8477375",
+ "RepaymentOptions": {
+ "CoApplicantIncome": false,
+ "DownsizingHome": false,
+ "IncomeFromOtherInvestments": false,
+ "Other": false,
+ "RecurringIncomeFromSuperannuation": false,
+ "RepaymentOfLoanPriorToRetirement": false,
+ "SaleOfAssets": true,
+ "Savings": false,
+ "SuperannuationLumpSumFollowingRetirement": false
+ }
+ }
+ ]
+ }
+ }
+ },
+ "Instructions": {
+ "ApplicationInstructions": {
+ "Submit": {
+ "AssessmentType": "Full",
+ "IsAccountVariation": false
+ }
+ }
+ },
+ "Publisher": {
+ "LIXICode": "ZZZLO1"
+ },
+ "Recipient": [
+ {
+ "LIXICode": "ZZZANU1"
+ }
+ ],
+ "SchemaVersion": {
+ "GuidebookCode": "EGB-XD1ZZ3",
+ "LIXITransactionType": "CAL",
+ "LIXIVersion": "2.6.35"
+ }
+
+}
\ No newline at end of file
diff --git a/samples/MyCRM.Lodgement.Core/Models/SampleLodgementInformation.cs b/samples/MyCRM.Lodgement.Core/Models/SampleLodgementInformation.cs
new file mode 100644
index 0000000..693203a
--- /dev/null
+++ b/samples/MyCRM.Lodgement.Core/Models/SampleLodgementInformation.cs
@@ -0,0 +1,7 @@
+namespace MyCRM.Lodgement.Common.Models;
+
+public class SampleLodgementInformation
+{
+ public int LoanId { get; set; }
+ public LoanApplicationScenario Scenario { get; set; }
+}
\ No newline at end of file
diff --git a/samples/MyCRM.Lodgement.Core/MyCRM.Lodgement.Common.csproj b/samples/MyCRM.Lodgement.Core/MyCRM.Lodgement.Common.csproj
index 94612d1..f7fbacd 100644
--- a/samples/MyCRM.Lodgement.Core/MyCRM.Lodgement.Common.csproj
+++ b/samples/MyCRM.Lodgement.Core/MyCRM.Lodgement.Common.csproj
@@ -1,12 +1,18 @@
- net6.0
+ net8.0
default
-
+
+
+
+
+
+ Always
+
diff --git a/samples/MyCRM.Lodgement.Core/Routes.cs b/samples/MyCRM.Lodgement.Core/Routes.cs
index 3d8de3c..facbb42 100644
--- a/samples/MyCRM.Lodgement.Core/Routes.cs
+++ b/samples/MyCRM.Lodgement.Core/Routes.cs
@@ -4,5 +4,6 @@ public static class Routes
{
public const string Validate = "Validate";
public const string Submit = "Submit";
+ public const string SumbitTestPackage = "SubmitTestPackage";
}
}
diff --git a/samples/MyCRM.Lodgement.Core/Utilities/ObjectSerializer.cs b/samples/MyCRM.Lodgement.Core/Utilities/ObjectSerializer.cs
new file mode 100644
index 0000000..3253d6d
--- /dev/null
+++ b/samples/MyCRM.Lodgement.Core/Utilities/ObjectSerializer.cs
@@ -0,0 +1,31 @@
+using System;
+using System.IO;
+using System.Xml.Serialization;
+using MyCRMAPI.Lodgement.Models;
+using Newtonsoft.Json.Linq;
+
+namespace MyCRM.Lodgement.Common.Utilities;
+
+public class ObjectSerializer
+{
+
+ public static string Serialize(Package package ,string mediaType)
+ {
+ if (package == null) throw new ArgumentNullException(nameof(package));
+
+ return mediaType switch
+ {
+ "application/xml" => SerializeAsXml(package),
+ "application/json" => JObject.FromObject(package).ToString(),
+ _ => throw new NotImplementedException($"Media Type {mediaType} not supported.")
+ };
+ }
+
+ private static string SerializeAsXml(Package package)
+ {
+ using var writer = new StringWriter();
+ var serializer = new XmlSerializer(package.GetType());
+ serializer.Serialize(writer, package);
+ return writer.ToString();
+ }
+}
diff --git a/samples/MyCRM.Lodgement.Sample.Tests/MyCRM.Lodgement.Sample.Tests.csproj b/samples/MyCRM.Lodgement.Sample.Tests/MyCRM.Lodgement.Sample.Tests.csproj
index d05ff53..de664b2 100644
--- a/samples/MyCRM.Lodgement.Sample.Tests/MyCRM.Lodgement.Sample.Tests.csproj
+++ b/samples/MyCRM.Lodgement.Sample.Tests/MyCRM.Lodgement.Sample.Tests.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net8.0
false
diff --git a/samples/MyCRM.Lodgement.Sample.Tests/Services/Client/LodgementClientTests.cs b/samples/MyCRM.Lodgement.Sample.Tests/Services/Client/LodgementClientTests.cs
index b1f4084..e1d715c 100644
--- a/samples/MyCRM.Lodgement.Sample.Tests/Services/Client/LodgementClientTests.cs
+++ b/samples/MyCRM.Lodgement.Sample.Tests/Services/Client/LodgementClientTests.cs
@@ -10,6 +10,7 @@
using Moq;
using MyCRM.Lodgement.Common.Models;
using MyCRM.Lodgement.Sample.Services.Client;
+using MyCRM.Lodgement.Sample.Services.LixiPackage;
using MyCRM.Lodgement.Sample.Services.Settings;
using MyCRMAPI.Lodgement.Models;
using Newtonsoft.Json.Linq;
@@ -28,12 +29,14 @@ private class DelegatingHandlerStub : DelegatingHandler
private const string MediaType = "application/json";
private readonly Mock _httpClientFactoryMock;
+ private readonly Mock _lixiPackageService;
private readonly Mock> _optionsMock;
public LodgementClientTests()
{
_httpClientFactoryMock = new Mock();
_optionsMock = new Mock>();
+ _lixiPackageService = new Mock();
}
[Fact]
@@ -64,6 +67,7 @@ public async Task WhenValidatingAndOkResult_ThenReturnValidationResult()
.Returns(client);
var target = new LodgementClient(_httpClientFactoryMock.Object,
+ _lixiPackageService.Object,
_optionsMock.Object);
var result = await target.Validate(package, CancellationToken.None);
@@ -98,10 +102,11 @@ public async Task WhenSubmittingAndOkResult_ThenReturnSubmissionResult()
.Returns(client);
var target = new LodgementClient(_httpClientFactoryMock.Object,
+ _lixiPackageService.Object,
_optionsMock.Object);
- var result = await target.Validate(package, CancellationToken.None);
- result.ExternalReferenceId.Should().Be(submissionResult.ReferenceId);
+ var result = await target.Submit(package, CancellationToken.None);
+ result.Result.ReferenceId.Should().Be(submissionResult.ReferenceId);
}
}
}
diff --git a/samples/MyCRM.Lodgement.Sample.Tests/StartupTests.cs b/samples/MyCRM.Lodgement.Sample.Tests/StartupTests.cs
deleted file mode 100644
index 41cdc49..0000000
--- a/samples/MyCRM.Lodgement.Sample.Tests/StartupTests.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using System.Threading.Tasks;
-using FluentAssertions;
-using Microsoft.AspNetCore.Mvc.Testing;
-using Xunit;
-
-namespace MyCRM.Lodgement.Sample.Tests
-{
- public class StartupTests : IClassFixture>
- {
- private const string TextHtml = "text/html; charset=utf-8";
-
- private readonly WebApplicationFactory _factory;
-
- public StartupTests(WebApplicationFactory factory) => _factory = factory;
-
- [Theory]
- [InlineData("/swagger")]
- public async Task HtmlEndpointsRespondWithHtml(string url)
- {
- // Arrange
- var client = _factory.CreateClient();
-
- // Act
- var response = await client.GetAsync(url);
-
- // Assert
- response.EnsureSuccessStatusCode();
- response.Content.Headers.ContentType.ToString().Should().Be(TextHtml);
- }
- }
-}
diff --git a/samples/MyCRM.Lodgement.Sample/Contracts/PostTestPackageRequest.cs b/samples/MyCRM.Lodgement.Sample/Contracts/PostTestPackageRequest.cs
new file mode 100644
index 0000000..68dd35e
--- /dev/null
+++ b/samples/MyCRM.Lodgement.Sample/Contracts/PostTestPackageRequest.cs
@@ -0,0 +1,6 @@
+namespace MyCRM.Lodgement.Sample.Models;
+
+public record PostTestPackageRequest
+{
+ public required LoanApplicationScenario Scenario { get; init; }
+}
\ No newline at end of file
diff --git a/samples/MyCRM.Lodgement.Sample/Controllers/BackchannelController.cs b/samples/MyCRM.Lodgement.Sample/Controllers/BackchannelController.cs
index 7a04fbf..673b9ad 100644
--- a/samples/MyCRM.Lodgement.Sample/Controllers/BackchannelController.cs
+++ b/samples/MyCRM.Lodgement.Sample/Controllers/BackchannelController.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Mvc;
-using MyCRMAPI.Lodgement.Models;
+using MyCRMAPI.Lodgement.Models;
namespace MyCRM.Lodgement.Sample.Controllers
{
diff --git a/samples/MyCRM.Lodgement.Sample/Controllers/LodgementSubmissionController.cs b/samples/MyCRM.Lodgement.Sample/Controllers/LodgementSubmissionController.cs
index 67f8b69..4db1a7b 100644
--- a/samples/MyCRM.Lodgement.Sample/Controllers/LodgementSubmissionController.cs
+++ b/samples/MyCRM.Lodgement.Sample/Controllers/LodgementSubmissionController.cs
@@ -1,11 +1,4 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using MyCRM.Lodgement.Common;
-using MyCRM.Lodgement.Common.Models;
-using MyCRM.Lodgement.Sample.Services.Client;
+using MyCRM.Lodgement.Sample.Mapping;
using MyCRMAPI.Lodgement.Models;
namespace MyCRM.Lodgement.Sample.Controllers
@@ -36,5 +29,28 @@ public async Task Post(Package package, CancellationToken token)
return Ok(resultOrError.Result);
}
+
+
+ [HttpPost(Routes.SumbitTestPackage)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ValidationError))]
+ [ProducesResponseType(StatusCodes.Status500InternalServerError, Type = typeof(ProblemDetails))]
+ [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(SubmissionResult))]
+ public async Task PostTestPackage(PostTestPackageRequest request, CancellationToken token)
+ {
+ var model = request.MapToLodgementInformation();
+ if (model is null)
+ {
+ return BadRequest();
+ }
+
+ var resultOrError = await _lodgementClient.SubmitSampleLixiPackage(model, token);
+
+ if (resultOrError.IsError)
+ {
+ return BadRequest(resultOrError.Error);
+ }
+
+ return Ok(resultOrError.Result);
+ }
}
}
\ No newline at end of file
diff --git a/samples/MyCRM.Lodgement.Sample/Controllers/LodgementValidationController.cs b/samples/MyCRM.Lodgement.Sample/Controllers/LodgementValidationController.cs
index e3ed1d0..f949e53 100644
--- a/samples/MyCRM.Lodgement.Sample/Controllers/LodgementValidationController.cs
+++ b/samples/MyCRM.Lodgement.Sample/Controllers/LodgementValidationController.cs
@@ -1,12 +1,4 @@
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using MyCRM.Lodgement.Common;
-using MyCRM.Lodgement.Common.Models;
-using MyCRM.Lodgement.Sample.Services.Client;
-using MyCRMAPI.Lodgement.Models;
+using MyCRMAPI.Lodgement.Models;
namespace MyCRM.Lodgement.Sample.Controllers
{
diff --git a/samples/MyCRM.Lodgement.Sample/GlobalUsings.cs b/samples/MyCRM.Lodgement.Sample/GlobalUsings.cs
new file mode 100644
index 0000000..e7e6cb2
--- /dev/null
+++ b/samples/MyCRM.Lodgement.Sample/GlobalUsings.cs
@@ -0,0 +1,20 @@
+// Global using directives
+global using System;
+global using System.Collections.Generic;
+global using System.IO;
+global using System.Threading;
+global using System.Threading.Tasks;
+global using Microsoft.AspNetCore.Http;
+global using Microsoft.AspNetCore.Mvc;
+global using Microsoft.Extensions.Configuration;
+global using Microsoft.Extensions.DependencyInjection;
+global using Microsoft.Extensions.Options;
+global using Microsoft.OpenApi.Models;
+global using MyCRM.Lodgement.Common;
+global using MyCRM.Lodgement.Common.Models;
+global using MyCRM.Lodgement.Sample.Models;
+global using MyCRM.Lodgement.Sample.Services;
+global using MyCRM.Lodgement.Sample.Services.Client;
+global using MyCRM.Lodgement.Sample.Services.LixiPackage;
+global using MyCRM.Lodgement.Sample.Services.Settings;
+global using Newtonsoft.Json;
\ No newline at end of file
diff --git a/samples/MyCRM.Lodgement.Sample/Mapping/ContractMapping.cs b/samples/MyCRM.Lodgement.Sample/Mapping/ContractMapping.cs
new file mode 100644
index 0000000..53fbb57
--- /dev/null
+++ b/samples/MyCRM.Lodgement.Sample/Mapping/ContractMapping.cs
@@ -0,0 +1,16 @@
+namespace MyCRM.Lodgement.Sample.Mapping;
+
+public static class ContractMapping
+{
+ public static SampleLodgementInformation MapToLodgementInformation(this PostTestPackageRequest request)
+ {
+ if(request is null) throw new ArgumentNullException(nameof(request), "Source model cannot be null.");
+ Random random = new Random();
+ return new SampleLodgementInformation
+ {
+ LoanId = random.Next(0, int.MaxValue),
+ Scenario = request.Scenario
+ };
+ }
+
+}
\ No newline at end of file
diff --git a/samples/MyCRM.Lodgement.Sample/MyCRM.Lodgement.Sample.csproj b/samples/MyCRM.Lodgement.Sample/MyCRM.Lodgement.Sample.csproj
index d3a1e79..541964c 100644
--- a/samples/MyCRM.Lodgement.Sample/MyCRM.Lodgement.Sample.csproj
+++ b/samples/MyCRM.Lodgement.Sample/MyCRM.Lodgement.Sample.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net8.0
default
diff --git a/samples/MyCRM.Lodgement.Sample/Program.cs b/samples/MyCRM.Lodgement.Sample/Program.cs
index 42a471c..f240d60 100644
--- a/samples/MyCRM.Lodgement.Sample/Program.cs
+++ b/samples/MyCRM.Lodgement.Sample/Program.cs
@@ -1,20 +1,85 @@
-using Microsoft.AspNetCore.Hosting;
+using System.Text.Json.Serialization;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting;
-namespace MyCRM.Lodgement.Sample
+var builder = WebApplication.CreateBuilder(args);
+
+// Add services to the container.
+builder.Services.AddControllers(options => { options.Conventions.Add(new ApiExplorerConvention()); })
+ .AddXmlSerializerFormatters()
+ .AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); });
+
+
+//builder.Services.AddServicesSample(Configuration);
+
+// builder.Services.AddProblemDetails(options =>
+// {
+// options.IncludeExceptionDetails = (context, ex) => false;
+// });
+
+builder.Services.AddHealthChecks().AddCheck("default", _ => HealthCheckResult.Healthy("The API is responding"));
+
+builder.Services.AddSwaggerGen(c =>
{
- public class Program
+ c.CustomOperationIds(e =>
+ e.ActionDescriptor.AttributeRouteInfo?.Name
+ ?? $"{e.ActionDescriptor.RouteValues["controller"]}_{e.ActionDescriptor.RouteValues["action"]}");
+ c.SwaggerDoc(ApiExplorerConvention.LodgementApi,
+ new OpenApiInfo { Title = "MyCRM Lodgement API (v1)", Version = "v1" });
+ c.SwaggerDoc(ApiExplorerConvention.BackchannelApi,
+ new OpenApiInfo { Title = "MyCRM Lodgement Backchannel API (v1)", Version = "v1" });
+
+ c.CustomSchemaIds(x => x.FullName);
+
+ c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
+ {
+ Description = @"JWT authorization header using the Bearer scheme.",
+ Name = "Authorization",
+ In = ParameterLocation.Header,
+ Type = SecuritySchemeType.Http,
+ Scheme = "Bearer"
+ });
+
+ c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
- public static void Main(string[] args)
{
- CreateHostBuilder(args).Build().Run();
+ new OpenApiSecurityScheme
+ {
+ Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" },
+ Scheme = "oauth2",
+ Name = "Bearer",
+ In = ParameterLocation.Header
+ },
+ new List()
}
+ });
+});
+var app = builder.Build();
- public static IHostBuilder CreateHostBuilder(string[] args) =>
- Host.CreateDefaultBuilder(args)
- .ConfigureWebHostDefaults(webBuilder =>
- {
- webBuilder.UseStartup();
- });
- }
+if (!app.Environment.IsDevelopment())
+{
+ app.UseExceptionHandler("/Error");
+ // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
+ app.UseHsts();
}
+
+app.UseHttpsRedirection();
+app.UseStaticFiles();
+app.UseRouting();
+
+app.UseSwagger();
+app.UseSwaggerUI(c =>
+{
+ c.SwaggerEndpoint($"{ApiExplorerConvention.LodgementApi}/swagger.json", "MyCRM Lodgement API (v1)");
+ c.SwaggerEndpoint($"{ApiExplorerConvention.BackchannelApi}/swagger.json", "MyCRM LodgementApi Backchannel API (v1)");
+});
+
+app.UseAuthorization();
+
+app.UseEndpoints(endpoints =>
+{
+ endpoints.MapControllers();
+});
+
+app.Run();
\ No newline at end of file
diff --git a/samples/MyCRM.Lodgement.Sample/Services/Client/ILodgementClient.cs b/samples/MyCRM.Lodgement.Sample/Services/Client/ILodgementClient.cs
index 3a2d4b0..880643e 100644
--- a/samples/MyCRM.Lodgement.Sample/Services/Client/ILodgementClient.cs
+++ b/samples/MyCRM.Lodgement.Sample/Services/Client/ILodgementClient.cs
@@ -1,7 +1,4 @@
-using System.Threading;
-using System.Threading.Tasks;
-using MyCRM.Lodgement.Common.Models;
-using MyCRMAPI.Lodgement.Models;
+using MyCRMAPI.Lodgement.Models;
namespace MyCRM.Lodgement.Sample.Services.Client
{
@@ -9,5 +6,7 @@ public interface ILodgementClient
{
Task Validate(Package package, CancellationToken token);
Task> Submit(Package package, CancellationToken token);
+ Task> SubmitSampleLixiPackage(
+ SampleLodgementInformation lodgementInformation, CancellationToken token);
}
-}
+}
\ No newline at end of file
diff --git a/samples/MyCRM.Lodgement.Sample/Services/Client/LodgementClient.cs b/samples/MyCRM.Lodgement.Sample/Services/Client/LodgementClient.cs
index 0a82188..15dd49e 100644
--- a/samples/MyCRM.Lodgement.Sample/Services/Client/LodgementClient.cs
+++ b/samples/MyCRM.Lodgement.Sample/Services/Client/LodgementClient.cs
@@ -1,55 +1,67 @@
-using System;
-using System.IO;
-using System.Net;
+using System.Net;
using System.Net.Http;
using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Xml.Serialization;
-using Microsoft.Extensions.Options;
-using MyCRM.Lodgement.Common;
-using MyCRM.Lodgement.Common.Models;
-using MyCRM.Lodgement.Sample.Services.Settings;
+using Microsoft.AspNetCore.Mvc.Formatters;
+using MyCRM.Lodgement.Common.Utilities;
using MyCRMAPI.Lodgement.Models;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
namespace MyCRM.Lodgement.Sample.Services.Client
{
public class LodgementClient : ILodgementClient
{
private readonly IHttpClientFactory _httpClientFactory;
+ private readonly ILixiPackageService _lixiPackageService;
private readonly LodgementSettings _settings;
- public LodgementClient(IHttpClientFactory httpClientFactory,
+ public LodgementClient(IHttpClientFactory httpClientFactory,
+ ILixiPackageService lixiPackageService,
IOptions options)
{
_httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory));
+ _lixiPackageService = lixiPackageService;
_settings = options?.Value ?? throw new ArgumentNullException(nameof(options));
}
public async Task Validate(Package package, CancellationToken token)
{
- if (package == null) throw new ArgumentNullException(nameof(package));
-
using var response = await Send(package, Routes.Validate, token);
return response.StatusCode switch
{
HttpStatusCode.OK => await ReadResponse(response.Content),
- _ => throw new HttpRequestException($"Invalid response status code, {response.StatusCode} - {response.ReasonPhrase}")
+ _ => throw new HttpRequestException(
+ $"Invalid response status code, {response.StatusCode} - {response.ReasonPhrase}")
};
}
- public async Task> Submit(Package package, CancellationToken token)
+ public async Task> Submit(Package package,
+ CancellationToken token)
{
- if (package == null) throw new ArgumentNullException(nameof(package));
+ using var response = await Send(package, Routes.Submit, token);
+ return response.StatusCode switch
+ {
+ HttpStatusCode.OK => await ReadResponse(response.Content),
+ HttpStatusCode.BadRequest => await ReadResponse(response.Content),
+ _ => throw new HttpRequestException(
+ $"Invalid response status code, {response.StatusCode} - {response.ReasonPhrase}")
+ };
+ }
+
+ public async Task> SubmitSampleLixiPackage(
+ SampleLodgementInformation lodgementInformation, CancellationToken token)
+ {
+ if (lodgementInformation.Scenario == null)
+ throw new ArgumentNullException(nameof(lodgementInformation.Scenario));
+
+ var package = await _lixiPackageService.CreatePackageAsync(lodgementInformation.LoanId,
+ lodgementInformation.Scenario, token);
using var response = await Send(package, Routes.Submit, token);
return response.StatusCode switch
{
HttpStatusCode.OK => await ReadResponse(response.Content),
HttpStatusCode.BadRequest => await ReadResponse(response.Content),
- _ => throw new HttpRequestException($"Invalid response status code, {response.StatusCode} - {response.ReasonPhrase}")
+ _ => throw new HttpRequestException(
+ $"Invalid response status code, {response.StatusCode} - {response.ReasonPhrase}")
};
}
@@ -58,8 +70,7 @@ private Task Send(Package package, string route, Cancellati
if (package == null) throw new ArgumentNullException(nameof(package));
if (route == null) throw new ArgumentNullException(nameof(route));
- var payload = Serialize(package);
-
+ var payload = ObjectSerializer.Serialize(package, _settings.MediaType);
var message = new HttpRequestMessage(HttpMethod.Post, $"Lodgement/{route}")
{
Content = new StringContent(payload, Encoding.UTF8, _settings.MediaType)
@@ -78,25 +89,5 @@ private static async Task ReadResponse(HttpContent content) where T : clas
var ser = new JsonSerializer();
return ser.Deserialize(jsonReader);
}
-
- private string Serialize(Package package)
- {
- if (package == null) throw new ArgumentNullException(nameof(package));
-
- return _settings.MediaType switch
- {
- "application/xml" => SerializeAsXml(package),
- "application/json" => JObject.FromObject(package).ToString(),
- _ => throw new NotImplementedException($"Media Type {_settings.MediaType} not supported.")
- };
- }
-
- private static string SerializeAsXml(Package package)
- {
- using var writer = new StringWriter();
- var serializer = new XmlSerializer(package.GetType());
- serializer.Serialize(writer, package);
- return writer.ToString();
- }
}
}
\ No newline at end of file
diff --git a/samples/MyCRM.Lodgement.Sample/Services/LixiPackage/ILixiPackageService.cs b/samples/MyCRM.Lodgement.Sample/Services/LixiPackage/ILixiPackageService.cs
new file mode 100644
index 0000000..163c555
--- /dev/null
+++ b/samples/MyCRM.Lodgement.Sample/Services/LixiPackage/ILixiPackageService.cs
@@ -0,0 +1,8 @@
+using MyCRMAPI.Lodgement.Models;
+
+namespace MyCRM.Lodgement.Sample.Services.LixiPackage;
+
+public interface ILixiPackageService
+{
+ Task CreatePackageAsync(int loanId, LoanApplicationScenario scenario, CancellationToken token = default);
+}
\ No newline at end of file
diff --git a/samples/MyCRM.Lodgement.Sample/Services/LixiPackage/LixiPackageService.cs b/samples/MyCRM.Lodgement.Sample/Services/LixiPackage/LixiPackageService.cs
new file mode 100644
index 0000000..90226d5
--- /dev/null
+++ b/samples/MyCRM.Lodgement.Sample/Services/LixiPackage/LixiPackageService.cs
@@ -0,0 +1,27 @@
+using MyCRMAPI.Lodgement.Models;
+
+namespace MyCRM.Lodgement.Sample.Services.LixiPackage;
+
+public class LixiPackageService : ILixiPackageService
+{
+ private readonly string _packagSamplesBasePath = AppDomain.CurrentDomain.BaseDirectory + "\\LixiPackageSamples\\";
+
+ public async Task CreatePackageAsync(int loanId, LoanApplicationScenario scenario,
+ CancellationToken token = default)
+ {
+ var packagePath = _packagSamplesBasePath + Enum.GetName(typeof(LoanApplicationScenario), scenario) + ".json";
+ var package = await GetPackageFromJsonAsync(packagePath, token);
+
+ package.ProductionData = YesNoList.No;
+ package.Content.Application.Overview.BrokerApplicationReferenceNumber = loanId.ToString();
+ package.Content.Application.UniqueID = $"LoanScenario-{loanId}";
+
+ return package;
+ }
+
+ private async Task GetPackageFromJsonAsync(string path, CancellationToken token)
+ {
+ var fileContent = await File.ReadAllTextAsync(path, token);
+ return JsonConvert.DeserializeObject(fileContent);
+ }
+}
\ No newline at end of file
diff --git a/samples/MyCRM.Lodgement.Sample/Services/Client/ServiceCollectionExtensions.cs b/samples/MyCRM.Lodgement.Sample/Services/ServiceCollectionExtensions.cs
similarity index 69%
rename from samples/MyCRM.Lodgement.Sample/Services/Client/ServiceCollectionExtensions.cs
rename to samples/MyCRM.Lodgement.Sample/Services/ServiceCollectionExtensions.cs
index b514498..5c99bc9 100644
--- a/samples/MyCRM.Lodgement.Sample/Services/Client/ServiceCollectionExtensions.cs
+++ b/samples/MyCRM.Lodgement.Sample/Services/ServiceCollectionExtensions.cs
@@ -1,10 +1,4 @@
-using System;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Options;
-using MyCRM.Lodgement.Sample.Services.Settings;
-
-namespace MyCRM.Lodgement.Sample.Services.Client
+namespace MyCRM.Lodgement.Sample.Services.Client
{
public static class ServiceCollectionExtensions
{
@@ -28,5 +22,16 @@ public static IServiceCollection AddClient(this IServiceCollection services, ICo
services.AddTransient();
return services;
}
+
+ public static IServiceCollection AddServicesSample(this IServiceCollection services, IConfiguration configuration)
+ {
+ if (services == null) throw new ArgumentNullException(nameof(services));
+ if (configuration == null) throw new ArgumentNullException(nameof(configuration));
+
+ services.AddScoped();
+ services.AddClient(configuration);
+
+ return services;
+ }
}
}
diff --git a/samples/MyCRM.Lodgement.Sample/Startup.cs b/samples/MyCRM.Lodgement.Sample/Startup.cs
deleted file mode 100644
index 273e16c..0000000
--- a/samples/MyCRM.Lodgement.Sample/Startup.cs
+++ /dev/null
@@ -1,103 +0,0 @@
-using System.Collections.Generic;
-using Hellang.Middleware.ProblemDetails;
-using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Diagnostics.HealthChecks;
-using Microsoft.Extensions.Hosting;
-using Microsoft.OpenApi.Models;
-using MyCRM.Lodgement.Sample.Services;
-using MyCRM.Lodgement.Sample.Services.Client;
-
-namespace MyCRM.Lodgement.Sample
-{
- public class Startup
- {
- public Startup(IConfiguration configuration)
- {
- Configuration = configuration;
- }
-
- public IConfiguration Configuration { get; }
-
- // This method gets called by the runtime. Use this method to add services to the container.
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddControllers(options =>
- {
- options.Conventions.Add(new ApiExplorerConvention());
- })
- .AddXmlSerializerFormatters();
-
- services.AddClient(Configuration);
-
- services.AddProblemDetails(options =>
- {
- options.IncludeExceptionDetails = (context, ex) => false;
- });
-
- services.AddHealthChecks().AddCheck("default", _ => HealthCheckResult.Healthy("The API is responding"));
-
- services.AddSwaggerGen(c =>
- {
- c.CustomOperationIds(e =>
- e.ActionDescriptor.AttributeRouteInfo?.Name
- ?? $"{e.ActionDescriptor.RouteValues["controller"]}_{e.ActionDescriptor.RouteValues["action"]}");
-
- c.SwaggerDoc(ApiExplorerConvention.LodgementApi, new OpenApiInfo { Title = "MyCRM Lodgement API (v1)", Version = "v1" });
- c.SwaggerDoc(ApiExplorerConvention.BackchannelApi, new OpenApiInfo { Title = "MyCRM Lodgement Backchannel API (v1)", Version = "v1" });
-
- c.CustomSchemaIds(x => x.FullName);
-
- c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
- {
- Description = @"JWT authorization header using the Bearer scheme.",
- Name = "Authorization",
- In = ParameterLocation.Header,
- Type = SecuritySchemeType.Http,
- Scheme = "Bearer"
- });
-
- c.AddSecurityRequirement(new OpenApiSecurityRequirement
- {
- {
- new OpenApiSecurityScheme
- {
- Reference = new OpenApiReference {Type = ReferenceType.SecurityScheme, Id = "Bearer"},
- Scheme = "oauth2",
- Name = "Bearer",
- In = ParameterLocation.Header
- },
- new List()
- }
- });
- });
- }
-
- // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
- {
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
-
- app.UseRouting();
-
- app.UseSwagger();
- app.UseSwaggerUI(c =>
- {
- c.SwaggerEndpoint($"{ApiExplorerConvention.LodgementApi}/swagger.json", "MyCRM Lodgement API (v1)");
- c.SwaggerEndpoint($"{ApiExplorerConvention.BackchannelApi}/swagger.json", "MyCRM LodgementApi Backchannel API (v1)");
- });
-
- app.UseAuthorization();
-
- app.UseEndpoints(endpoints =>
- {
- endpoints.MapControllers();
- });
- }
- }
-}