diff --git a/README.md b/README.md
index 58beeac..e6d8489 100644
--- a/README.md
+++ b/README.md
@@ -68,3 +68,10 @@ This section has moved here: [https://facebook.github.io/create-react-app/docs/d
### `npm run build` fails to minify
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
+
+
+
+
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+v2a
\ No newline at end of file
diff --git a/v1a/Logo_Slogan.png b/v1a/Logo_Slogan.png
new file mode 100644
index 0000000..2bb9055
Binary files /dev/null and b/v1a/Logo_Slogan.png differ
diff --git a/v1a/invoice.html b/v1a/invoice.html
new file mode 100644
index 0000000..71a5977
--- /dev/null
+++ b/v1a/invoice.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+To export: Print -> Save as PDF with normal A4 settings, except no margins, 1st page only.
+Or, press the button below to save to your C:\Downloads folder with the name in the textbox.
+';
+ child_div.id = 'div_' + this_form_type + '_service_' + si;
+ // child_div.className = "div_service"; - d
+ let child_title = document.createElement('label');
+ child_title.className = 'div_title';
+ child_title.innerText = 'Service ' + si;
+ let child_disc_rate_label = document.createElement('label');
+ // child_disc_rate_label.outerHTML = '
Invoice service rate discretisation: ';
+ child_disc_rate_label.id = this_form_type + '_disc_rate_s' + si + '_label';
+ child_disc_rate_label.innerText = 'Rate discretisation:';
+ child_disc_rate_label.className = 'input_label label_title';
+ let child_disc_durn_label = document.createElement('label');
+ // child_disc_rate_label.outerHTML = '
Invoice service rate discretisation: ';
+ child_disc_durn_label.id = this_form_type + '_disc_rate_s' + si + '_label';
+ child_disc_durn_label.innerText = 'Duration discretisation:';
+ child_disc_durn_label.className = 'input_label label_title';
+ // let child_break = document.createElement('br');
+ let child_disc_rate_select = document.createElement('select');
+ // child_disc_rate_select.outerHTML = '
'
+ child_disc_rate_select.id = this_form_type + '_disc_rate_s' + si;
+ let child_disc_durn_select = document.createElement('select');
+ // child_disc_durn_select.outerHTML = '
'
+ child_disc_durn_select.id = this_form_type + '_disc_durn_s' + si;
+ let child_disc_rate_option_min = document.createElement('option');
+ // child_disc_rate_option_min.outerHTML = '
Minute ';
+ child_disc_rate_option_min.value = 'm';
+ child_disc_rate_option_min.innerText = 'Minute';
+ let child_disc_rate_option_hr = document.createElement('option');
+ // child_disc_rate_option_hr.outerHTML = '
Hour ';
+ child_disc_rate_option_hr.value = 'h';
+ child_disc_rate_option_hr.innerText = 'Hour';
+ child_disc_rate_option_hr.selected = true;
+ let child_disc_rate_option_day = document.createElement('option');
+ // child_disc_rate_option_day.outerHTML = '
Day ';
+ child_disc_rate_option_day.value = 'd';
+ child_disc_rate_option_day.innerText = 'Day';
+ let child_disc_rate_option_week = document.createElement('option');
+ // child_disc_rate_option_week.outerHTML = '
Week ';
+ child_disc_rate_option_week.value = 'w';
+ child_disc_rate_option_week.innerText = 'Week';
+ let child_disc_durn_option_day = document.createElement('option');
+ // child_disc_durn_option_month.outerHTML = '
Month ';
+ child_disc_durn_option_day.value = 'd';
+ child_disc_durn_option_day.innerText = 'Day';
+ let child_disc_durn_option_week = document.createElement('option');
+ // child_disc_durn_option_month.outerHTML = '
Month ';
+ child_disc_durn_option_week.value = 'w';
+ child_disc_durn_option_week.innerText = 'Week';
+ let child_disc_durn_option_month = document.createElement('option');
+ // child_disc_durn_option_month.outerHTML = '
Month ';
+ child_disc_durn_option_month.value = 'M';
+ child_disc_durn_option_month.innerText = 'Month';
+ let child_disc_durn_option_year = document.createElement('option');
+ // child_disc_durn_option_year.outerHTML = '
Year ';
+ child_disc_durn_option_year.value = 'y';
+ child_disc_durn_option_year.innerText = 'Year';
+ child_disc_rate_select.appendChild(child_disc_rate_option_min);
+ child_disc_rate_select.appendChild(child_disc_rate_option_hr);
+ child_disc_rate_select.appendChild(child_disc_rate_option_day);
+ child_disc_rate_select.appendChild(child_disc_rate_option_week);
+ child_disc_rate_select.onchange = function () {
+ change_rate_discretisation(this_form_type, i);
+ };
+ child_disc_durn_select.appendChild(child_disc_durn_option_day);
+ child_disc_durn_select.appendChild(child_disc_durn_option_week);
+ child_disc_durn_select.appendChild(child_disc_durn_option_month);
+ child_disc_durn_select.appendChild(child_disc_durn_option_year);
+ child_disc_durn_select.onchange = function () {
+ change_rate_discretisation(this_form_type, i);
+ };
+ let child_disc_rate_quantity_label = document.createElement('label');
+ // child_disc_rate_quantity_label.outerHTML = '
Quantity of duration discretisations: ';
+ child_disc_rate_quantity_label.id = this_form_type + '_ratedisc_quantity_s' + si + '_label';
+ child_disc_rate_quantity_label.innerText = 'Quantity of rate discretisations per minimum unit rate:';
+ child_disc_rate_quantity_label.className = 'input_label label_title';
+ let child_disc_rate_quantity = document.createElement('input');
+ // child_disc_rate_quantity.outerHTML = '
';
+ child_disc_rate_quantity.type = 'number';
+ child_disc_rate_quantity.id = this_form_type + '_ratedisc_quantity_s' + si;
+ child_disc_rate_quantity.value = "1";
+ child_disc_rate_quantity.step = '1';
+ child_disc_rate_quantity.min = '1';
+ child_disc_rate_quantity.onchange = function() {
+ change_rate_discretisation(this_form_type, i);
+ };
+ let child_rate_label = document.createElement('label');
+ // child_rate_label.outerHTML = '
Rate [£ / duration discretisation] ';
+ child_rate_label.id = this_form_type + '_rate_s' + si + '_label';
+ child_rate_label.innerText = 'Rate [£ / Hour]';
+ child_rate_label.className = 'input_label label_title';
+ let child_rate = document.createElement('input');
+ // child_rate.outerHTML = '
';
+ child_rate.type = 'number';
+ child_rate.id = this_form_type + '_rate_s' + si;
+ // Chassis Business Process Analyst
+ // child_rate.placeholder = "20.33";
+ // RADs Software Engineer
+ child_rate.placeholder = "23.94";
+ child_rate.step = '0.001';
+ child_rate.min = '0';
+ let child_disc_durn_quantity_label = document.createElement('label');
+ // child_disc_durn_quantity_label.outerHTML = '
Quantity of duration discretisations: ';
+ child_disc_durn_quantity_label.id = this_form_type + '_durndisc_quantity_s' + si + '_label';
+ child_disc_durn_quantity_label.innerText = 'Quantity of duration discretisations:';
+ child_disc_durn_quantity_label.className = 'input_label label_title'
+ let child_disc_durn_quantity = document.createElement('input');
+ // child_disc_durn_quantity.outerHTML = '
';
+ child_disc_durn_quantity.type = 'number';
+ child_disc_durn_quantity.id = this_form_type + '_durndisc_quantity_s' + si;
+ child_disc_durn_quantity.placeholder = "4";
+ child_disc_durn_quantity.step = "0.001";
+ child_disc_durn_quantity.min = "0.001";
+ child_disc_durn_quantity.onchange = function() {
+ show_discs(this_form_type, "s", i, Number(this.value));
+ };
+ let child_sub_quantity_label = document.createElement('label');
+ // child_quantity_label.outerHTML = '
Week 1: ';
+ child_sub_quantity_label.id = this_form_type + '_sub_quantity_s' + si + '_label';
+ child_sub_quantity_label.innerText = 'Quantity of billing periods:';
+ child_sub_quantity_label.className = 'input_label label_title';
+ let child_sub_quantity = document.createElement('input');
+ // child_quantity.outerHTML = '
';
+ child_sub_quantity.type = 'number';
+ child_sub_quantity.id = this_form_type + '_sub_quantity_s' + si;
+ child_sub_quantity.onchange = function() {
+ show_discs(this_form_type, 's', i, Number(this.value));
+ }
+ child_sub_quantity.placeholder = "4";
+ child_sub_quantity.step = "1";
+ child_sub_quantity.min = "1";
+ // incremental
+ let child_incremental_label = document.createElement('label');
+ child_incremental_label.id = this_form_type + '_incremental_label_s' + si;
+ child_incremental_label.innerText = 'Incremental duration discretisation IDs:';
+ child_incremental_label.className = 'input_label label_title';
+ let child_incremental_check_yes = document.createElement('input');
+ child_incremental_check_yes.type = 'checkbox';
+ child_incremental_check_yes.id = this_form_type + '_increment_yes_s' + si;
+ child_incremental_check_yes.value = "Yes";
+ child_incremental_check_yes.checked = true;
+ child_incremental_check_yes.onchange = function () {
+ toggle_incremental_weeks(this_form_type, 'Yes', i);
+ };
+ let child_incremental_check_yes_label = document.createElement('label');
+ child_incremental_check_yes_label.id = this_form_type + '_increment_yes_s' + si + '_label';
+ child_incremental_check_yes_label.innerText = "Yes";
+ child_incremental_check_yes_label.className = 'input_subtitle';
+ let child_incremental_check_no = document.createElement('input');
+ child_incremental_check_no.type = 'checkbox';
+ child_incremental_check_no.id = this_form_type + '_increment_no_s' + si;
+ child_incremental_check_no.value = "No";
+ child_incremental_check_no.checked = false;
+ child_incremental_check_no.onchange = function () {
+ toggle_incremental_weeks(this_form_type, 'No', i);
+ };
+ let child_incremental_check_no_label = document.createElement('label');
+ child_incremental_check_no_label.id = this_form_type + '_increment_no_s' + si + '_label';
+ child_incremental_check_no_label.innerText = "No";
+ child_incremental_check_no_label.className = 'input_subtitle';
+ let child_div_incremental = document.createElement('div');
+ child_div_incremental.id = 'div_' + this_form_type + '_incremental_s' + si;
+ child_div_incremental.className = 'tbl_container';
+ let child_tbl_incremental = document.createElement('table');
+ child_tbl_incremental.id = 'tbl_inv_incremental_s' + si;
+ let child_tr_incremental = document.createElement('tr');
+ let child_td_incremental_base = document.createElement('td');
+ let child_div_incremental_base = document.createElement('div');
+ child_div_incremental_base.className = 'div_input_label';
+ let child_baseID_label = document.createElement('label');
+ child_baseID_label.id = this_form_type + '_baseID_s' + si + '_label';
+ child_baseID_label.innerText = 'Service description base (prefix):';
+ child_baseID_label.className = 'input_label label_title';
+ let child_baseID = document.createElement('input');
+ child_baseID.type = 'text';
+ child_baseID.id = this_form_type + '_baseID_s' + si;
+ child_baseID.onchange = function () {
+ change_incremental_phrase(this_form_type, i);
+ }
+ let child_td_incremental_suffix = document.createElement('td');
+ let child_div_incremental_suffix = document.createElement('div');
+ child_div_incremental_suffix.className = 'div_input_label';
+ let child_week1_label = document.createElement('label');
+ child_week1_label.id = this_form_type + '_week1_s' + si + '_label';
+ child_week1_label.innerText = 'First week ID:';
+ child_week1_label.className = 'input_label label_title';
+ let child_week1 = document.createElement('input');
+ child_week1.type = 'number';
+ child_week1.id = this_form_type + '_week1_s' + si;
+ child_week1.onchange = function () {
+ change_incremental_phrase(this_form_type, i);
+ };
+ child_div_incremental_base.appendChild(child_baseID_label);
+ child_div_incremental_base.appendChild(child_baseID);
+ child_td_incremental_base.appendChild(child_div_incremental_base);
+ child_tr_incremental.appendChild(child_td_incremental_base);
+ child_div_incremental_suffix.appendChild(child_week1_label);
+ child_div_incremental_suffix.appendChild(child_week1);
+ child_td_incremental_suffix.appendChild(child_div_incremental_suffix);
+ child_tr_incremental.appendChild(child_td_incremental_suffix);
+ child_tbl_incremental.appendChild(child_tr_incremental);
+ child_div_incremental.appendChild(child_tbl_incremental);
+
+ // bringing it all together
+ child_div.appendChild(child_title);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_disc_rate_label);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_disc_rate_select);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_disc_rate_quantity_label);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_disc_rate_quantity);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_rate_label);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_rate);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_disc_durn_label);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_disc_durn_select);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_disc_durn_quantity_label);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_disc_durn_quantity);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_sub_quantity_label);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_sub_quantity);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_incremental_label);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_incremental_check_yes);
+ child_div.appendChild(child_incremental_check_yes_label);
+ child_div.appendChild(child_incremental_check_no);
+ child_div.appendChild(child_incremental_check_no_label);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_div_incremental);
+ child_div.appendChild(document.createElement('br'));
+ // child_div.appendChild(child_div_service);
+ let date_disc = 'week'; // get_select_text(document.getElementById(this_form_type + '_disc_durn_s' + si));
+ let rate_disc = 'hour'; // get_select_text(document.getElementById(this_form_type + '_disc_rate_s' + si));
+ child_div.appendChild(create_service_div(this_form_type, si, date_disc, rate_disc));
+
+ switch (this_form_type) {
+ case 'inv':
+ div_inv_services.appendChild(child_div);
+ inv_services_children.push(1);
+ inv_services_max++;
+ break;
+ case 'est':
+ div_est_services.appendChild(child_div);
+ est_services_children.push(1);
+ est_services_max++;
+ break;
+ }
+ }
+ update_currency();
+ }
+ for (let i = 1; i <= N; i++) {
+ document.getElementById('div_' + this_form_type + '_service_' + String(i)).style.display = 'block'; // 'table';
+ }
+ if (N < inv_services_max) {
+ for (let i = N + 1; i <= inv_services_max; i++) {
+ document.getElementById('div_' + this_form_type + '_service_' + String(i)).style.display = 'none';
+ }
+ }
+}
+
+function create_service_div(this_form_type, i_str, date_disc, rate_disc) {
+
+ let child_div_service = document.createElement('div');
+ // child_div_service.outerHTML = '
goods_max) {
+ for (let i = goods_max + 1; i <= N; i++) {
+ // let child_div = create_good_div(this_form_type, String(i));
+ let tr_good = create_sub_good_tr(this_form_type, String(i));
+
+ switch (this_form_type) {
+ case 'inv':
+ div_inv_goods.appendChild(tr_good);
+ inv_goods_max++;
+ break;
+ case 'est':
+ div_est_goods.appendChild(tr_good);
+ est_goods_max++;
+ break;
+ }
+ }
+ update_currency();
+ }
+ for (let i = 1; i <= N; i++) {
+ document.getElementById('tr_' + this_form_type + '_good_' + String(i)).style.display = 'flex';
+ }
+ switch (this_form_type) {
+ case 'inv':
+ if (N < inv_goods_max && this_form_type == 'inv') {
+ for (let i = N + 1; i <= inv_goods_max; i++) {
+ document.getElementById('tr_inv_good_' + String(i)).style.display = 'none';
+ }
+ }
+ break;
+ case 'est':
+ if (N < est_goods_max && this_form_type == 'est') {
+ for (let i = N + 1; i <= est_goods_max; i++) {
+ document.getElementById('tr_est_good_' + String(i)).style.display = 'none';
+ }
+ }
+ break;
+ }
+}
+
+function create_good_div(this_form_type, i_str) {
+ let child_div = document.createElement('div');
+ child_div.id = 'div_' + this_form_type + '_good_' + i_str;
+ child_div.className = 'div_good tbl_container';
+ let child_title = document.createElement('label');
+ child_title.className = 'div_title';
+ child_title.innerText = 'Good ' + i_str;
+ let child_table = document.createElement('table');
+ child_table.id = 'tbl_' + this_form_type + '_good_' + i_str;
+
+ // bringing it all together
+ child_div.appendChild(child_title);
+ child_div.appendChild(document.createElement('br'));
+ child_table.appendChild(create_sub_good_tr(this_form_type, i_str));
+ child_div.appendChild(child_table);
+
+ return child_div;
+}
+
+function create_sub_good_tr(this_form_type, i_str) {
+ let el_tr = document.createElement('tr');
+ el_tr.id = 'tr_' + this_form_type + '_good_' + i_str;
+ let el_td_heading = document.createElement('td');
+ // el_td_heading.style.width = '100px';
+ let el_heading_label = document.createElement('label');
+ el_heading_label.id = this_form_type + '_heading_g' + i_str + '_label';
+ el_heading_label.innerText = 'Good ' + i_str;
+ el_heading_label.className = 'input_label';
+ el_heading_label.style.whiteSpace = 'nowrap';
+ let el_td_name = document.createElement('td');
+ let el_div_name = document.createElement('div');
+ el_div_name.className = 'div_input_label';
+ let el_name_label = document.createElement('label');
+ // el_disc_rate_label.outerHTML = '
Invoice service rate discretisation: ';
+ el_name_label.id = this_form_type + '_name_g' + i_str + '_label';
+ el_name_label.innerText = 'Name:';
+ el_name_label.className = 'input_label';
+ // let el_break = document.createElement('br');
+ let el_name = document.createElement('input');
+ // el_disc_rate_quantity.outerHTML = '
';
+ el_name.type = 'text';
+ el_name.id = this_form_type + '_name_g' + i_str;
+ el_name.className = 'input_label';
+ let el_td_value = document.createElement('td');
+ let el_div_value = document.createElement('div');
+ el_div_name.className = 'div_input_label';
+ let el_value_label = document.createElement('label');
+ // el_disc_rate_label.outerHTML = '
Invoice service rate discretisation: ';
+ el_value_label.id = this_form_type + '_value_g' + i_str + '_label';
+ el_value_label.innerText = 'Value [£]:';
+ el_value_label.className = 'input_label';
+ // let el_break = document.createElement('br');
+ let el_value = document.createElement('input');
+ // el_disc_rate_quantity.outerHTML = '
';
+ el_value.type = 'number';
+ el_value.className = 'input_label';
+ el_value.id = this_form_type + '_value_g' + i_str;
+ el_value.placeholder = "20000";
+ el_value.step = '0.01';
+ let el_td_quantity = document.createElement('td');
+ let el_div_quantity = document.createElement('div');
+ el_div_name.className = 'div_input_label';
+ let el_quantity_label = document.createElement('label');
+ // el_disc_rate_label.outerHTML = '
Invoice service rate discretisation: ';
+ el_quantity_label.id = this_form_type + '_quantity_g' + i_str + '_label';
+ el_quantity_label.innerText = 'Quantity of goods:';
+ el_quantity_label.className = 'input_label';
+ // let el_break = document.createElement('br');
+ let el_quantity = document.createElement('input');
+ // el_disc_rate_quantity.outerHTML = '
';
+ el_quantity.type = 'number';
+ el_quantity.id = this_form_type + '_quantity_g' + i_str;
+ el_quantity.className = 'input_label';
+ el_quantity.placeholder = "1";
+ el_quantity.step = '1';
+ el_quantity.min = '1';
+
+ // el_div_heading.appendChild(el_heading_label);
+ // el_td_heading.appendChild(el_div_heading);
+ el_td_heading.appendChild(el_heading_label);
+ el_tr.appendChild(el_td_heading);
+ el_div_name.appendChild(el_name_label);
+ el_div_name.appendChild(el_name);
+ el_td_name.appendChild(el_div_name);
+ el_tr.appendChild(el_td_name);
+ el_div_value.appendChild(el_value_label);
+ el_div_value.appendChild(el_value);
+ el_td_value.appendChild(el_div_value);
+ el_tr.appendChild(el_td_value);
+ el_div_quantity.appendChild(el_quantity_label);
+ el_div_quantity.appendChild(el_quantity);
+ el_td_quantity.appendChild(el_div_quantity);
+ el_tr.appendChild(el_td_quantity);
+
+ return el_tr;
+}
+
+function change_rate_discretisation(this_form_type, service_index) { // , subservice_index
+ // FUNCTION
+ // following change of rate discretisation, update UI
+ // ARGUMENTS
+ // string this_form_type - 'inv' or 'est'
+ // long service_index - index of service within form_type services
+ // long subservice_index - index of subservice within service within form_type
+ // OUTPUTS
+ // METHODS
+ // console.log('this form type = ' + this_form_type);
+ // console.log('service index = ' + service_index.toString());
+ let si = service_index.toString();
+ // let ssi = subservice_index.toString();
+ let elem_rate = document.getElementById(this_form_type + '_disc_rate_s' + si);
+ let rate_quant = document.getElementById(this_form_type + '_ratedisc_quantity_s' + si).value;
+ let new_rate = get_select_text(elem_rate);
+ let elem_durn = document.getElementById(this_form_type + '_disc_durn_s' + si);
+ let new_durn = get_select_text(elem_durn);
+ let durn_quant = document.getElementById(this_form_type + '_durndisc_quantity_s' + si).value;
+ let subservice_quantity = Number(document.getElementById(this_form_type + '_sub_quantity_s' + si).value);
+ // assign rate text
+ document.getElementById(this_form_type + '_ratedisc_quantity_s' + si + '_label').innerText = 'Quantity of ' + new_rate.toLowerCase() + 's per minimum unit rate:'; // does not work
+ if (rate_quant == "1") {
+ document.getElementById(this_form_type + '_rate_s' + si + '_label').innerText = 'Rate [£ / ' + new_rate + ']:';
+ for (let i = 1; i <= subservice_quantity; i++) {
+ let sj = String(i);
+ console.log('si = ' + si + ' + sj = ' + sj);
+ document.getElementById(this_form_type + '_quantity_s' + si + '_' + sj + '_label').innerText = new_rate + 's worked:';
+ }
+ } else {
+ document.getElementById(this_form_type + '_rate_s' + si + '_label').innerText = 'Rate [£ / ' + rate_quant + ' ' + new_rate + 's]:';
+ for (let i = 1; i <= subservice_quantity; i++) {
+ let sj = String(i);
+ console.log('si = ' + si + ' + sj = ' + sj);
+ document.getElementById(this_form_type + '_quantity_s' + si + '_' + sj + '_label').innerText = 'x' + rate_quant + ' ' + new_rate + 's worked:';
+ }
+ }
+ document.getElementById(this_form_type + '_durndisc_quantity_s' + si + '_label').innerText = 'Quantity of ' + new_durn.toLowerCase() + 's per billing period:';
+ if (durn_quant == "1") {
+ document.getElementById(this_form_type + '_week1_s' + si + '_label').innerText = 'First ' + new_durn.toLowerCase() + ' ID:';
+ document.getElementById(this_form_type + '_incremental_label_s' + si).innerText = 'Incremental ' + new_durn.toLowerCase() + ' IDs:';
+ for (let i = 1; i <= subservice_quantity; i++) {
+ let sj = String(i);
+ console.log('si = ' + si + ' + sj = ' + sj);
+ document.getElementById(this_form_type + '_description_s' + si + '_' + sj + '_label').innerText = new_durn + ' ' + sj + ':';
+ }
+ } else {
+ document.getElementById(this_form_type + '_week1_s' + si + '_label').innerText = 'First x' + durn_quant + ' ' + new_durn.toLowerCase() + 's ID:';
+ document.getElementById(this_form_type + '_incremental_label_s' + si).innerText = 'Incremental x' + durn_quant + ' ' + new_durn.toLowerCase() + 's IDs:';
+ for (let i = 1; i <= subservice_quantity; i++) {
+ let sj = String(i);
+ console.log('si = ' + si + ' + sj = ' + sj);
+ document.getElementById(this_form_type + '_description_s' + si + '_' + sj + '_label').innerText = 'x' + durn_quant + ' ' + new_durn.toLowerCase() + 's ' + sj + ':';
+ }
+ }
+ // document.getElementById(this_form_type + '_week1_s' + si + '_label').innerText = 'First ' + new_durn.toLowerCase() + ' ID:';
+ // document.getElementById(this_form_type + '_incremental_label_s' + si).innerText = 'Incremental ' + new_durn.toLowerCase() + ' IDs:';
+ // for (let i = 1; i <= subservice_quantity; i++) {
+ // let sj = String(i);
+ // console.log('si = ' + si + ' + sj = ' + sj);
+ // document.getElementById('inv_description_s' + si + '_' + sj + '_label').innerText = new_durn + ' ' + sj + ':';
+ // }
+}
+
+function change_incremental_phrase(this_form_type, service_index) {
+ let si = service_index.toString();
+ let week1 = Number(document.getElementById(this_form_type + '_week1_s' + si).value);
+ let baseID = document.getElementById(this_form_type + '_baseID_s' + si).value;
+ let N;
+ switch (this_form_type) {
+ case 'inv':
+ N = inv_services_children[service_index - 1];
+ break;
+ case 'est':
+ N = est_services_children[service_index - 1];
+ break;
+ }
+ for (let j = 1; j <= N; j++) {
+ let myphrase = baseID + (week1 + j - 1).toString();
+ let sj = j.toString();
+ console.log('si = ' + si + ' + sj = ' + sj);
+ let my_elem_str = this_form_type + '_description_s' + si + '_' + sj;
+ console.log('my_elem_str = ' + my_elem_str);
+ document.getElementById(my_elem_str).value = myphrase;
+ }
+}
+
+function toggle_incremental_weeks(this_form_type, increment, service_index) {
+ let si = service_index.toString();
+ let check_yes = document.getElementById(this_form_type + '_increment_yes_s' + si);
+ let check_no = document.getElementById(this_form_type + '_increment_no_s' + si);
+ let div_increment = document.getElementById('div_' + this_form_type + '_incremental_s' + si);
+ switch (increment) {
+ case 'Yes':
+ if (check_yes.checked) {
+ check_no.checked = false;
+ div_increment.style.display = 'flex';
+ change_incremental_phrase(this_form_type, service_index);
+ } else {
+ check_no.checked = true;
+ div_increment.style.display = 'none';
+ }
+ break;
+ case 'No':
+ if (check_no.checked) {
+ check_yes.checked = false;
+ div_increment.style.display = 'none';
+ } else {
+ check_yes.checked = true;
+ div_increment.style.display = 'flex';
+ change_incremental_phrase(this_form_type, service_index);
+ }
+ break;
+ }
+}
+
+function show_discs(this_form_type, gvs, index, quantity) {
+ switch (gvs) {
+ case "g":
+ break;
+ case "s":
+ let N;
+ switch (this_form_type) {
+ case 'inv':
+ N = inv_services_children[index - 1];
+ break;
+ case 'est':
+ N = est_services_children[index - 1];
+ break;
+ }
+ let si = String(index);
+ let service_table = document.getElementById('tbl_' + this_form_type + '_service_' + si); //'div_' + this_form_type + '_service_' + si);
+ console.log('service_table id: ' + 'tbl_' + this_form_type + '_service_' + si);
+ let date_disc = get_select_text(document.getElementById(this_form_type + '_disc_durn_s' + si));
+ let rate_disc = get_select_text(document.getElementById(this_form_type + '_disc_rate_s' + si));
+ if (quantity > N) {
+ for (let i = N + 1; i <= quantity; i++) {
+ let sj = String(i);
+ let child_tr_service = create_sub_service_tr(this_form_type, si, sj, date_disc, rate_disc);
+
+ service_table.appendChild(child_tr_service);
+
+ switch (this_form_type) {
+ case 'inv':
+ inv_services_children[index - 1]++;
+ break;
+ case 'est':
+ est_services_children[index - 1]++;
+ break;
+ }
+ console.log('new service div added');
+ if (document.getElementById(this_form_type + '_increment_yes_s' + si).checked) {
+ change_incremental_phrase(this_form_type, index);
+ }
+ }
+ change_rate_discretisation(this_form_type, index);
+ }
+ for (let i = 1; i <= quantity; i++) {
+ // console.log("showing: " + 'tr_' + this_form_type + '_service_' + si + '_' + String(i));
+ document.getElementById('tr_' + this_form_type + '_service_' + si + '_' + String(i)).style.display = 'table-row';
+ }
+ if (quantity < N) {
+ for (let i = quantity + 1; i <= N; i++) {
+ document.getElementById('tr_' + this_form_type + '_service_' + si + '_' + String(i)).style.display = 'none';
+ }
+ }
+ break;
+ }
+}
+
+function create_sub_service_tr(this_form_type, i_str, j_str, date_disc, rate_disc) {
+ let child_tr_service = document.createElement('tr');
+ child_tr_service.id = 'tr_' + this_form_type + '_service_' + i_str + '_' + j_str;
+ let child_td_description = document.createElement('td');
+ let child_div_description = document.createElement('div');
+ // child_div_service.outerHTML = '
Week 1:';
+ child_description_label.innerText = date_disc + " " + j_str + ":";
+ child_description_label.id = this_form_type + '_description_s' + i_str + '_' + j_str + '_label';
+ child_description_label.className = 'input_label';
+ let child_description = document.createElement('input');
+ // child_description.outerHTML = '
';
+ child_description.type = "text";
+ console.log('creating ' + this_form_type + '_description_s with i_str=' + i_str + ' + j_str=' + j_str);
+ child_description.id = this_form_type + "_description_s" + i_str + "_" + j_str;
+ child_description.className = "input_label";
+
+ let child_td_quantity = document.createElement('td');
+ let child_div_quantity = document.createElement('div');
+ let child_quantity_label = document.createElement('label');
+ // child_quantity_label.outerHTML = '
Hours worked: ';
+ child_quantity_label.id = this_form_type + '_quantity_s' + i_str + '_' + j_str + '_label';
+ child_quantity_label.innerText = rate_disc + "s worked:";
+ child_quantity_label.className = 'input_label';
+ let child_quantity = document.createElement('input');
+ // child_quantity.outerHTML = '
';
+ child_quantity.type = "number";
+ child_quantity.id = this_form_type + "_quantity_s" + i_str + "_" + j_str;
+ child_quantity.className = "input_label";
+ child_quantity.step = "0.001";
+ // child_quantity.min = "0.001";
+
+ child_div_description.appendChild(child_description_label);
+ child_div_description.appendChild(child_description);
+ child_td_description.appendChild(child_div_description);
+ child_tr_service.appendChild(child_td_description);
+
+ child_div_quantity.appendChild(child_quantity_label);
+ child_div_quantity.appendChild(child_quantity);
+ child_td_quantity.appendChild(child_div_quantity);
+ child_tr_service.appendChild(child_td_quantity);
+
+ return child_tr_service;
+}
+
+function show_goods_services(this_form_type) {
+ let check_goods = document.getElementById(this_form_type + '_type_goods');
+ let check_services = document.getElementById(this_form_type + '_type_services');
+ let div_goods = document.getElementById('div_' + this_form_type + '_goods');
+ let div_services = document.getElementById('div_' + this_form_type + '_services');
+ if (check_goods.checked) {
+ div_goods.style.display = 'inline-block';
+ } else {
+ div_goods.style.display = 'none';
+ }
+ if (check_services.checked) {
+ div_services.style.display = 'inline-block';
+ } else {
+ div_services.style.display = 'none';
+ }
+}
+// estimate
+// perfectly encompassed by invoice code?
+
+// payment plan
+function show_payschemes() {
+ let N = Number(pay_n.value);
+ if (N > 1) {
+ div_pay_type.style.display = 'inline-block';
+ show_paytypes(N);
+ div_payscheme.style.display = 'inline-block';
+ }
+}
+
+function change_paytype(my_paytype) {
+ let my_this, my_that1, my_that2;
+ switch (my_paytype) {
+ case 'linear':
+ my_this = paytype_linear;
+ my_that1 = paytype_multiplier;
+ my_that2 = paytype_random;
+ break;
+ case 'multiplier':
+ my_this = paytype_multiplier;
+ my_that1 = paytype_linear;
+ my_that2 = paytype_random;
+ break;
+ case 'random':
+ my_this = paytype_random;
+ my_that1 = paytype_multiplier;
+ my_that2 = paytype_linear;
+ break;
+ }
+ if (my_this.checked) {
+ my_that1.checked = false;
+ my_that2.checked = false;
+ } else {
+ if (!(my_that1.checked || my_that2.checked)) {
+ my_this.checked = true;
+ }
+ }
+ show_paytypes();
+}
+
+function show_paytypes(N = Number(pay_n.value)) {
+ if (paytype_linear.checked) {
+ div_paytype_linear.style.display = 'inline-block';
+ div_paytype_multiplier.style.display = 'none';
+ div_paytype_random.style.display = 'none';
+ } else if (paytype_multiplier.checked) {
+ div_paytype_linear.style.display = 'none';
+ div_paytype_multiplier.style.display = 'inline-block';
+ div_paytype_random.style.display = 'none';
+ if (N > paytype_mult_max) {
+ for (let i = 1 + paytype_mult_max; i <= N; i++) {
+ let si = i.toString();
+ let child_label = document.createElement('label');
+ // child_label.outerHTML = "
Payment multiplier" + si + ": ";
+ child_label.id = 'paytype_mult_' + si + '_label';
+ child_label.innerText = "Payment multiplier " + si + ":";
+ child_label.className = 'input_label';
+ let child_input = document.createElement('input');
+ // child_input.outerHTML = "
";
+ child_input.type = 'number';
+ child_input.id = 'paytype_mult_' + si;
+ child_input.value = '1';
+ child_input.step = '0.001';
+
+ div_paytype_multiplier.appendChild(child_label);
+ div_paytype_multiplier.appendChild(child_input);
+ div_paytype_multiplier.appendChild(document.createElement('br'));
+ div_paytype_multiplier.appendChild(document.createElement('br'));
+ }
+ paytype_mult_max = N;
+ } else if (N < paytype_mult_max) {
+ for (let i = 1; i <= N; i++) {
+ let si = i.toString();
+ let element1 = document.getElementById("paytype_mult_" + si + '_label');
+ element1.style.display = 'inline-block';
+ let element2 = document.getElementById("paytype_mult_" + si);
+ element2.style.display = 'inline-block';
+ }
+ for (let i = N + 1; i <= paytype_mult_max; i++) {
+ let si = i.toString();
+ let element1 = document.getElementById("paytype_mult_" + si + '_label');
+ element1.style.display = 'none';
+ let element2 = document.getElementById("paytype_mult_" + si);
+ element2.style.display = 'none';
+ }
+ }
+ } else {
+ div_paytype_linear.style.display = 'none';
+ div_paytype_multiplier.style.display = 'none';
+ div_paytype_random.style.display = 'inline-block';
+ if (N > paytype_random_max) {
+ for (let i = 1 + paytype_random_max; i <= N; i++) {
+ let si = String(i);
+ let child_label = document.createElement('label');
+ // child_label.outerHTML = "
Payment multiplier" + si + ": ";
+ child_label.id = 'paytype_value_' + si + '_label';
+ child_label.innerText = "Payment " + si + " [£]:";
+ child_label.className = 'input_label';
+ let child_input = document.createElement('input');
+ // child_input.outerHTML = "
";
+ child_input.type = 'number';
+ child_input.id = 'paytype_value_' + si;
+ child_input.placeholder = '10';
+ child_input.step = '0.01';
+
+ div_paytype_random.appendChild(child_label);
+ div_paytype_random.appendChild(child_input);
+ div_paytype_random.appendChild(document.createElement('br'));
+ div_paytype_random.appendChild(document.createElement('br'));
+ }
+ update_currency();
+ paytype_random_max = N;
+ } else if (N < paytype_random_max) {
+ for (let i = 1; i <= N; i++) {
+ let si = i.toString();
+ let element1 = document.getElementById("label_paytype_value_" + si);
+ element1.style.display = 'inline-block';
+ let element2 = document.getElementById("paytype_value_" + si);
+ element2.style.display = 'inline-block';
+ }
+ for (let i = N + 1; i <= paytype_random_max; i++) {
+ let si = i.toString();
+ let element1 = document.getElementById("label_paytype_value_" + si);
+ element1.style.display = 'none';
+ let element2 = document.getElementById("paytype_value_" + si);
+ element2.style.display = 'none';
+ }
+ }
+ }
+}
+
+function change_pay_disctype(my_disctype) {
+ let my_this, my_that;
+ switch (my_disctype) {
+ case 'absolute':
+ my_this = pay_disc_type_absolute;
+ my_that = pay_disc_type_relative;
+ break;
+ case 'relative':
+ my_this = pay_disc_type_relative;
+ my_that = pay_disc_type_absolute;
+ break;
+ }
+ if (my_this.checked) {
+ my_that.checked = false;
+ } else {
+ if (!my_that.checked) {
+ my_that.checked = true;
+ }
+ }
+}
+
+function show_schemes(N = Number(pay_n.value)) {
+ if (payscheme_linear.checked) {
+ // div_payscheme_linear.style.display = 'inline-block';
+ div_payscheme_multiplier.style.display = 'none';
+ } else { // if (payscheme_multiplier.checked) {
+ // div_payscheme_linear.style.display = 'none';
+ div_payscheme_multiplier.style.display = 'inline-block';
+ if (N > payscheme_mult_max) {
+ for (let i = 1 + payscheme_mult_max; i <= N; i++) {
+ let si = String(i);
+ let child_div = document.createElement('div');
+ child_div.id = 'div_payscheme_mult_' + si;
+ let child_label = document.createElement('label');
+ // child_label.outerHTML = "
Payment multiplier" + si + ": ";
+ child_label.id = 'payscheme_mult_' + si + '_label';
+ child_label.innerText = "Payment minimum unit duration multiplier " + si + ":";
+ child_label.className = 'input_label label_title';
+ let child_input = document.createElement('input');
+ // child_input.outerHTML = "
";
+ child_input.type = 'number';
+ child_input.id = 'payscheme_mult_' + si;
+ child_input.value = '1';
+ child_input.step = '1';
+ child_input.min = '1';
+
+ child_div.appendChild(child_label);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(child_input);
+ child_div.appendChild(document.createElement('br'));
+ child_div.appendChild(document.createElement('br'));
+
+ div_payscheme_multiplier.appendChild(child_div);
+ div_payscheme_multiplier.appendChild(document.createElement('br'));
+ div_payscheme_multiplier.appendChild(document.createElement('br'));
+ }
+ update_currency();
+ payscheme_mult_max = N;
+ } else if (N < payscheme_mult_max) {
+ for (let i = 1; i <= N; i++) {
+ document.getElementById("label_payscheme_mult_" + si).style.display = 'inline-block';
+ document.getElementById("payscheme_mult_" + si).style.display = 'inline-block';
+ }
+ for (let i = N + 1; i <= payscheme_mult_max; i++) {
+ document.getElementById("label_payscheme_mult_" + si).style.display = 'none';
+ document.getElementById("payscheme_mult_" + si).style.display = 'none';
+ }
+ }
+ }
+}
+
+function change_payscheme(my_payscheme) {
+ let my_this, my_that;
+ switch (my_payscheme) {
+ case 'linear':
+ my_this = payscheme_linear;
+ my_that = payscheme_multiplier;
+ break;
+ case 'multiplier':
+ my_this = payscheme_multiplier;
+ my_that = payscheme_linear;
+ break;
+ }
+ if (my_this.checked) {
+ my_that.checked = false;
+ } else {
+ if (!(my_that.checked)) {
+ my_this.checked = true;
+ }
+ }
+ show_schemes();
+}
+
+function max(a, b) {
+ if (a > b) {
+ return a;
+ } else {
+ return b;
+ }
+}
+
+function min(a, b) {
+ return -1 * max(-a, -b);
+}
+
+function update_pay_durndisc() {
+ let new_durndisc = get_select_text(pay_discretisation);
+ document.getElementById('pay_disc_quantity_label').innerText = 'Quantity of ' + new_durndisc.toLowerCase() + 's in minimum unit duration:';
+ // document.getElementById('pay_disc_type_label').innerText = 'Payment ' + new_durndisc.toLowerCase() + 's in minimum unit duration:';
+}
+
+// element interation
+function get_select_text(html_elem) {
+ let my_options = html_elem.getElementsByTagName('option');
+ let new_text = '';
+ for (let i = 0; i < my_options.length; i++) {
+ if (my_options[i].value == html_elem.value) {
+ console.log('my_options[i].value = ' + my_options[i].value + '= html_elem.value = ' + html_elem.value);
+ new_text = my_options[i].innerText;
+ break;
+ }
+ }
+ // console.log(new_text);
+ return new_text;
+}
+
+function set_select(select_elem, new_value) {
+ let my_options = select_elem.getElementsByTagName('option');
+ for (let i = 0; i < my_options.length; i++) {
+ if (new_value == my_options[i].innerText) {
+ my_options[i].selected = true;
+ } else {
+ my_options[i].selected = false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/v1a/stylesheet.css b/v1a/stylesheet.css
new file mode 100644
index 0000000..d761fdb
--- /dev/null
+++ b/v1a/stylesheet.css
@@ -0,0 +1,145 @@
+body {
+ background-color: lightpink;
+ font-family: "Arial, Helvetica, sans-serif";
+}
+
+div {
+ width: 100%;
+ display: inline-block;
+}
+
+/* Inputs */
+input, button {
+ margin: 5px;
+ height: 4vh;
+ width: 20vw;
+ border-radius: 1vh;
+ border-color: darkviolet;
+ padding: 3px 10px 3px;
+}
+
+select {
+ height: 3vh;
+ width: 100px;
+ border-radius: 1vh;
+ border-width: 2px;
+ border-color: darkviolet;
+ padding: 3px 10px 3px;
+}
+
+
+datalist {
+
+ /* display: flex;
+ display: block;
+ position: relative; */
+}
+option {
+ border-color: darkviolet;
+}
+
+input[type="text"] {
+ border-radius: 1vh;
+}
+
+input[type="number"] {
+ width: 3vw;
+}
+
+input[type="date"] {
+ width: 8vw;
+}
+
+input[type="checkbox"] {
+ -moz-appearance:none;
+ -webkit-appearance:none;
+ -o-appearance:none;
+ outline: none;
+ content: none;
+ width: 50px;
+}
+input[type="checkbox"]:before {
+ width: 30px;
+ height: 30px;
+ content: '✓';
+ font-size: 20px;
+ font-style: bold;
+ text-align: center;
+ border-radius: 5px;
+ border: 2px solid darkviolet;
+ background-color: white;
+ color: transparent;
+ display: inline-block;
+ margin-top: 0px;
+ margin-bottom: 20px;
+}
+input[type="checkbox"]:checked:before {
+ color: black;
+}
+
+
+/* Labels */
+label {
+ margin: 5px;
+}
+
+.div_title {
+ font-size: 24px;
+}
+
+.input_title {
+ font-size: 20px;
+}
+
+.input_subtitle {
+ font-size: 18px;
+}
+
+.errmsg {
+ display: none;
+ visibility: hidden;
+}
+
+
+
+/* table */
+.div_label_input {
+ margin: auto;
+ width: 100%;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+}
+
+.input_label {
+ box-sizing: border-box;
+ flex: 1;
+ margin: 1rem;
+ padding: 1rem;
+ border-radius: 5px;
+ width: 100%;
+}
+
+.input_label.label_title {
+ margin: 0;
+ padding: 0;
+ font-size: 20px;
+}
+
+.tbl_container {
+ display: flex;
+ flex-wrap: flex;
+ justify-content: center;
+}
+
+label.input_label {
+ padding-left: 5% !important;
+ padding-right: 5% !important;
+}
+
+.column {
+ align-items: center;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+}
\ No newline at end of file
diff --git a/v1a/userin.html b/v1a/userin.html
new file mode 100644
index 0000000..51043a8
--- /dev/null
+++ b/v1a/userin.html
@@ -0,0 +1,745 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file