React version complete
This commit is contained in:
2907
package-lock.json
generated
2907
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -3,13 +3,15 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@react-pdf/renderer": "^3.4.2",
|
||||||
"@testing-library/jest-dom": "^5.17.0",
|
"@testing-library/jest-dom": "^5.17.0",
|
||||||
"@testing-library/react": "^13.4.0",
|
"@testing-library/react": "^13.4.0",
|
||||||
"@testing-library/user-event": "^13.5.0",
|
"@testing-library/user-event": "^13.5.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-pdf": "^7.7.1",
|
||||||
"react-router-dom": "^6.22.3",
|
"react-router-dom": "^6.22.3",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "^5.0.1",
|
||||||
"web-vitals": "^2.1.4"
|
"web-vitals": "^2.1.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
import React, { useState } from 'react';
|
|
||||||
import objDefaults from './config'; // { defaultsMyBusiness, defaultsMyBusinessBank, defaultsTheirBusiness, defaultsTheirBusinessContact }
|
|
||||||
import MainContentForm from './components/MainContentForm';
|
|
||||||
|
|
||||||
const PageHome = () => {
|
|
||||||
const [formInvoiceData, setFormInvoiceData] = useState({
|
|
||||||
...objDefaults.getValuesDefaultFormMetadata,
|
|
||||||
...objDefaults.getValuesDefaultMyBusiness,
|
|
||||||
...objDefaults.getValuesDefaultMyBusinessBank,
|
|
||||||
...objDefaults.getValuesDefaultTheirBusiness,
|
|
||||||
...objDefaults.getValuesDefaultTheirBusinessContact,
|
|
||||||
...objDefaults.getValuesDefaultInvoice
|
|
||||||
});
|
|
||||||
console.log("formInvoiceData:", formInvoiceData);
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<MainContentForm data={formInvoiceData} />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
export default PageHome;
|
|
||||||
@@ -13,8 +13,8 @@ const BlockFormSection = (props) => {
|
|||||||
report(titleSection, inputs);
|
report(titleSection, inputs);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="section">
|
||||||
<label className="input_label">{titleSection}</label>
|
<label className="input_label.input_title">{titleSection}</label>
|
||||||
{inputs.map(input => (
|
{inputs.map(input => (
|
||||||
<InputWrapped key={input.id} data={input} />
|
<InputWrapped key={input.id} data={input} />
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -9,145 +9,44 @@ const makeInputJSON = (dictArgs) => {
|
|||||||
class ContentFormInvoiceOrEstimate extends Component {
|
class ContentFormInvoiceOrEstimate extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = this.props.stateMainContentForm;
|
console.log("ContentFormInvoiceOrEstimate props:", props);
|
||||||
this.initialiseElements();
|
this.values = this.props.stateMainContentForm.values || this.props.stateMainContentForm.placeholders || {};
|
||||||
|
this.placeholders = this.props.stateMainContentForm.placeholders || {};
|
||||||
|
// this.state = this.props.stateMainContentForm || {};
|
||||||
|
this.handleChangeStateFormInvoiceOrEstimate = this.handleChangeStateFormInvoiceOrEstimate.bind(this);
|
||||||
|
// this.initialiseElements = this.initialiseElements.bind(this);
|
||||||
|
// this.initialiseElements();
|
||||||
|
this.state = props.stateMainContentForm;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChangeStateContentFormInvoiceOrEstimate(stateNew) {
|
/*
|
||||||
const { stateMainContentForm, handleChangeStateMainContentForm } = this.props;
|
handleChangeStateConstructionFormInvoiceOrEstimate(stateNew) {
|
||||||
|
const { handleChangeStateConstructionMainContentForm } = this.props;
|
||||||
|
this.state = {
|
||||||
|
...this.state,
|
||||||
|
...stateNew
|
||||||
|
};
|
||||||
|
handleChangeStateConstructionMainContentForm(this.state);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
handleChangeStateFormInvoiceOrEstimate(stateNew) {
|
||||||
|
console.log(this);
|
||||||
|
const { handleChangeStateMainContentForm } = this.props;
|
||||||
this.setState((statePrevious) => ({
|
this.setState((statePrevious) => ({
|
||||||
...statePrevious,
|
...statePrevious,
|
||||||
...stateNew
|
...stateNew
|
||||||
}));
|
}));
|
||||||
handleChangeStateMainContentForm({
|
handleChangeStateMainContentForm(this.state);
|
||||||
...stateMainContentForm,
|
|
||||||
...stateNew
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChangeInput(event) {
|
handleChangeInput(event) {
|
||||||
const { elementInput } = event.target;
|
const { elementInput } = event.target;
|
||||||
this.handleChangeStateContentFormInvoiceOrEstimate({[elementInput.name]: elementInput.value});
|
this.handleChangeStateFormInvoiceOrEstimate({[elementInput.name]: elementInput.value});
|
||||||
}
|
|
||||||
|
|
||||||
initialiseElements() {
|
|
||||||
let typeForm = this.state.values['typeForm'] == "0" ? "Invoice" : "Estimate";
|
|
||||||
let sectionsForm = [
|
|
||||||
{
|
|
||||||
titleSection: typeForm,
|
|
||||||
inputs: [
|
|
||||||
makeInputJSON({id: 'dateBilling' + typeForm, name: 'dateBilling' + typeForm, type: 'date', placeholder: this.state.placeholders['dateBilling' + typeForm], value: this.state.values['dateBilling' + typeForm], textLabel: 'Billing date:', onChange: this.handleChangeInput}),
|
|
||||||
makeInputJSON({id: 'type' + typeForm, name: 'type' + typeForm, type: 'select', placeholder: this.state.placeholders['type' + typeForm], value: this.state.values['type' + typeForm], options: [
|
|
||||||
{text: 'Goods', value:'0'},
|
|
||||||
{text: 'Services', value:'1'}
|
|
||||||
], textLabel: 'Invoice type:', onChange: this.handleChangeInput})
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
let sectionsGoods = [];
|
|
||||||
if (this.state.values['type' + typeForm] == '0') {
|
|
||||||
sectionsForm = sectionsForm.concat([
|
|
||||||
{
|
|
||||||
titleSection: 'Goods',
|
|
||||||
inputs: [
|
|
||||||
makeInputJSON({id: 'quantityGoods' + typeForm, name: 'quantityGoods' + typeForm, type: 'number', placeholder: this.state.placeholders['quantityGoods' + typeForm], value: this.state.values['quantityGoods' + typeForm], textLabel: 'Number of different goods:', onChange: this.handleChangeInput})
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
if (this.state.values['quantityGoods' + typeForm] > 0) {
|
|
||||||
for (let i = 0; i < this.state.values['quantityGoods' + typeForm]; i++) {
|
|
||||||
sectionsGoods = sectionsGoods.concat([
|
|
||||||
{
|
|
||||||
titleSection: 'Good ' + (i + 1),
|
|
||||||
inputs: [
|
|
||||||
makeInputJSON({id: 'nameGood' + typeForm + (i + 1), name: 'nameGood' + typeForm + (i + 1), type: 'text', placeholder: this.state.placeholders['nameGood' + typeForm + (i + 1)], value: this.state.values['nameGood' + typeForm + (i + 1)], textLabel: 'Name:', onChange: this.handleChangeInput}),
|
|
||||||
makeInputJSON({id: 'valueGood' + typeForm + (i + 1), name: 'valueGood' + typeForm + (i + 1), type: 'number', placeholder: this.state.placeholders['valueGood' + typeForm + (i + 1)], value: this.state.values['valueGood' + typeForm + (i + 1)], textLabel: 'Value:', onChange: this.handleChangeInput}),
|
|
||||||
makeInputJSON({id: 'quantityGood' + typeForm + (i + 1), name: 'quantityGood' + typeForm + (i + 1), type: 'number', placeholder: this.state.placeholders['quantityGood' + typeForm + (i + 1)], value: this.state.values['quantityGood' + typeForm + (i + 1)], textLabel: 'Quantity:', onChange: this.handleChangeInput})
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let sectionsServices = [];
|
|
||||||
let subsectionsServices = [];
|
|
||||||
console.log("this.state.values[" + "type" + typeForm + "]:", this.state.values['type' + typeForm]);
|
|
||||||
if (this.state.values['type' + typeForm] == '1') {
|
|
||||||
sectionsForm = sectionsForm.concat([
|
|
||||||
{
|
|
||||||
titleSection: 'Services',
|
|
||||||
inputs: [
|
|
||||||
makeInputJSON({id: 'quantityServices' + typeForm, name: 'quantityServices' + typeForm, type: 'number', placeholder: this.state.placeholders['quantityServices' + typeForm], value: this.state.values['quantityServices' + typeForm], textLabel: 'Number of different services:', onChange: this.handleChangeInput})
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
console.log("this.state.values[" + 'quantityServices' + typeForm + "]:", this.state.values['quantityServices' + typeForm]);
|
|
||||||
if (this.state.values['quantityServices' + typeForm] > 0) {
|
|
||||||
let j;
|
|
||||||
for (let i = 0; i < this.state.values['quantityServices' + typeForm]; i++) {
|
|
||||||
console.log("adding service " + (i + 1));
|
|
||||||
sectionsServices = sectionsServices.concat([
|
|
||||||
{
|
|
||||||
titleSection: 'Service ' + (i + 1),
|
|
||||||
inputs: [
|
|
||||||
makeInputJSON({id: 'discretisationRateService' + typeForm + (i + 1), name: 'discretisationRateService' + typeForm + (i + 1), type: 'select', placeholder: this.state.placeholders['discretisationRateService' + typeForm + (i + 1)], value: this.state.values['discretisationRateService' + typeForm + (i + 1)], options: [
|
|
||||||
{text: 'Minute', value:'m'},
|
|
||||||
{text: 'Hour', value:'h'},
|
|
||||||
{text: 'Day', value:'d'},
|
|
||||||
{text: 'Week', value:'w'}
|
|
||||||
], textLabel: 'Rate discretisation:', onChange: this.handleChangeInput}),
|
|
||||||
makeInputJSON({id: 'quantityDiscretisationRateService' + typeForm + (i + 1), name: 'quantityDiscretisationRateService' + typeForm + (i + 1), type: 'number', placeholder: this.state.placeholders['quantityDiscretisationRateService' + typeForm + (i + 1)], value: this.state.values['quantityDiscretisationRateService' + typeForm + (i + 1)], textLabel: 'Quantity of rate discretisations per minimum unit rate:', onChange: this.handleChangeInput}),
|
|
||||||
makeInputJSON({id: 'rateService' + typeForm + (i + 1), name: 'rateService' + typeForm + (i + 1), type: 'number', placeholder: this.state.placeholders['rateService' + typeForm + (i + 1)], value: this.state.values['rateService' + typeForm + (i + 1)], textLabel: 'Rate [£ / hour]:', onChange: this.handleChangeInput}),
|
|
||||||
makeInputJSON({id: 'discretisationDurationService' + typeForm + (i + 1), name: 'discretisationDurationService' + typeForm + (i + 1), type: 'select', placeholder: this.state.placeholders['discretisationDurationService' + typeForm + (i + 1)], value: this.state.values['discretisationDurationService' + typeForm + (i + 1)], options: [
|
|
||||||
{text: 'Day', value:'d'},
|
|
||||||
{text: 'Week', value:'w'},
|
|
||||||
{text: 'Month', value:'M'},
|
|
||||||
{text: 'Year', value:'y'}
|
|
||||||
], textLabel: 'Duration discretisation:', onChange: this.handleChangeInput}),
|
|
||||||
makeInputJSON({id: 'quantityDiscretisationDurationService' + typeForm + (i + 1), name: 'quantityDiscretisationDurationService' + typeForm + (i + 1), type: 'number', placeholder: this.state.placeholders['quantityDiscretisationDurationService' + typeForm + (i + 1)], value: this.state.values['quantityDiscretisationDurationService' + typeForm + (i + 1)], textLabel: 'Quantity of duration discretisations per billing period:', onChange: this.handleChangeInput}),
|
|
||||||
makeInputJSON({id: 'quantityBillingPeriodService' + typeForm + (i + 1), name: 'quantityBillingPeriodService' + typeForm + (i + 1), type: 'number', placeholder: this.state.placeholders['quantityBillingPeriodService' + typeForm + (i + 1)], value: this.state.values['quantityBillingPeriodService' + typeForm + (i + 1)], textLabel: 'Quantity of billing periods:', onChange: this.handleChangeInput}),
|
|
||||||
makeInputJSON({id: 'isIncrementalBillingPeriodIdsService' + typeForm + (i + 1), name: 'isIncrementalBillingPeriodIdsService' + typeForm + (i + 1), type: 'checkbox', placeholder: this.state.placeholders['isIncrementalBillingPeriodIdsService' + typeForm + (i + 1)], value: this.state.values['isIncrementalBillingPeriodIdsService' + typeForm + (i + 1)], textLabel: 'Are billing period IDs incremental?', onChange: this.handleChangeInput}),
|
|
||||||
makeInputJSON({id: 'descriptionIncrementalService' + typeForm + (i + 1), name: 'descriptionIncrementalService' + typeForm + (i + 1), type: 'text', placeholder: this.state.placeholders['descriptionIncrementalService' + typeForm + (i + 1)], value: this.state.values['descriptionIncrementalService' + typeForm + (i + 1)], textLabel: 'Description:', onChange: this.handleChangeInput}),
|
|
||||||
makeInputJSON({id: 'idBillingPeriodFirstIncrementalService' + typeForm + (i + 1), name: 'idBillingPeriodFirstIncrementalService' + typeForm + (i + 1), type: 'number', placeholder: this.state.placeholders['idBillingPeriodFirstIncrementalService' + typeForm + (i + 1)], value: this.state.values['idBillingPeriodFirstIncrementalService' + typeForm + (i + 1)], textLabel: 'First billing period ID:', onChange: this.handleChangeInput})
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
let subsections = [];
|
|
||||||
if (this.state.values['quantityBillingPeriodService' + typeForm + (i + 1)] > 0) {
|
|
||||||
for (j = 0; j < this.state.values['quantityBillingPeriodService' + typeForm + (i + 1)]; j++) {
|
|
||||||
subsections = subsections.concat([
|
|
||||||
{
|
|
||||||
titleSection: 'Service billing period ' + (j + 1),
|
|
||||||
inputs: [
|
|
||||||
makeInputJSON({id: 'descriptionIncrementService' + typeForm + (i + 1) + 's' + (j + 1), name: 'descriptionIncrementService' + typeForm + (i + 1) + 's' + (j + 1), type: 'text', placeholder: this.state.placeholders['descriptionIncrementService' + typeForm + (i + 1) + 's' + (j + 1)], value: this.state.values['descriptionIncrementService' + typeForm + (i + 1) + 's' + (j + 1)], textLabel: 'Description:', onChange: this.handleChangeInput}),
|
|
||||||
makeInputJSON({id: 'quantityRatePeriodsIncrementService' + typeForm + (i + 1) + 's' + (j + 1), name: 'quantityRatePeriodsIncrementService' + typeForm + (i + 1) + 's' + (j + 1), type: 'number', placeholder: this.state.placeholders['quantityRatePeriodsIncrementService' + typeForm + (i + 1) + 's' + (j + 1)], value: this.state.values['quantityRatePeriodsIncrementService' + typeForm + (i + 1) + 's' + (j + 1)], textLabel: 'Quantity of unit rate periods worked:', onChange: this.handleChangeInput})
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
subsectionsServices = subsectionsServices.concat(subsections);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log("this.state.values['typeForm']:", this.state.values['typeForm']);
|
|
||||||
console.log("typeForm:", typeForm);
|
|
||||||
console.log("values:", this.state.values);
|
|
||||||
console.log("sectionsGoods:", sectionsGoods);
|
|
||||||
console.log("sectionsServices:", sectionsServices);
|
|
||||||
console.log("subsectionsServices:", subsectionsServices);
|
|
||||||
const dataInvoiceOrEstimate = {
|
|
||||||
// ...stateContentFormInvoiceOrEstimate,
|
|
||||||
sectionsForm: sectionsForm,
|
|
||||||
sectionsGoods: sectionsGoods,
|
|
||||||
sectionsServices: sectionsServices,
|
|
||||||
subsectionsServices: subsectionsServices,
|
|
||||||
};
|
|
||||||
this.handleChangeStateContentFormInvoiceOrEstimate(dataInvoiceOrEstimate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let typeForm = this.state.values['typeForm'] == "0" ? "Invoice" : "Estimate";
|
let typeForm = this.values['typeForm'] == "1" ? "Invoice" : "Estimate";
|
||||||
return (
|
return (
|
||||||
<div id={"div" + typeForm} className="container-section">
|
<div id={"div" + typeForm} className="container-section">
|
||||||
{this.state.sectionsForm.map(section => (
|
{this.state.sectionsForm.map(section => (
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ function getDateBilling() {
|
|||||||
}
|
}
|
||||||
function getValuesDefault() {
|
function getValuesDefault() {
|
||||||
return {
|
return {
|
||||||
typeForm: '0',
|
typeForm: '1',
|
||||||
currency: '0',
|
currency: '0',
|
||||||
nameMyBusiness: 'Precision And Research Technology Systems Limited',
|
nameMyBusiness: 'Precision And Research Technology Systems Limited',
|
||||||
companyNumberMyBusiness: '13587499',
|
companyNumberMyBusiness: '13587499',
|
||||||
|
|||||||
@@ -17,32 +17,32 @@ const makeInputJSON = (dictArgs) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const InputWrapped = (props) => {
|
const InputWrapped = (props) => {
|
||||||
const { id, name, value, textLabel, type, placeholder, step, valueMin, options, onChange } = props.data;
|
const { id, name, value, textLabel, type, placeholder, step, valueMin, options, onChange, namesection, namegroupsections } = props.data;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container-input">
|
<div className="container-input">
|
||||||
<label className="input_label">{textLabel}</label>
|
<label className="input_label">{textLabel}</label>
|
||||||
{(type == 'date') && (
|
{(type == 'date') && (
|
||||||
<input type="date" id={id} name={name} value={value == null ? "" : value} onChange={onChange}/>
|
<input type="date" id={id} name={name} value={value == null ? "" : value} onChange={onChange} namesection={namesection} namegroupsections={namegroupsections} />
|
||||||
)}
|
)}
|
||||||
{(type == 'text') && (
|
{(type == 'text') && (
|
||||||
<input type="text" id={id} name={name} value={value == null ? "" : value} placeholder={placeholder} onChange={onChange}/>
|
<input type="text" id={id} name={name} value={value == null ? "" : value} placeholder={placeholder} onChange={onChange} namesection={namesection} namegroupsections={namegroupsections} />
|
||||||
)}
|
)}
|
||||||
{(type == 'number') && (
|
{(type == 'number') && (
|
||||||
<input type="number" id={id} name={name} value={value == null ? "" : value} placeholder={placeholder} step={step} min={valueMin} onChange={onChange}/>
|
<input type="number" id={id} name={name} value={value == null ? "" : value} placeholder={placeholder} step={step} min={valueMin} onChange={onChange} namesection={namesection} namegroupsections={namegroupsections} />
|
||||||
)}
|
)}
|
||||||
{(type == 'checkbox') && (
|
{(type == 'checkbox') && (
|
||||||
<input type="checkbox" id={id} name={name} value={value == null ? "" : value} onChange={onChange}/>
|
<input type="checkbox" id={id} name={name} value={value == null ? "" : value} onChange={onChange} namesection={namesection} namegroupsections={namegroupsections} />
|
||||||
)}
|
)}
|
||||||
{(type == 'select') && (
|
{(type == 'select') && (
|
||||||
<select id={id} name={name} value={value == null ? "" : value} onChange={onChange}>
|
<select id={id} name={name} value={value == null ? "" : value} onChange={onChange} namesection={namesection} namegroupsections={namegroupsections} >
|
||||||
{options.map((item, index) => (
|
{options.map((item, index) => (
|
||||||
<option key={index} id={item['id']}>{item['textLabel']}</option>
|
<option key={index} id={item['value']} value={item['value']}>{item['text']}</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
)}
|
)}
|
||||||
{(type == 'button') && (
|
{(type == 'button') && (
|
||||||
<button id={id} name={name} value={value == null ? "" : value} onChange={onChange}>{textLabel}</button>
|
<button id={id} name={name} value={value == null ? "" : value} onChange={onChange} namesection={namesection} namegroupsections={namegroupsections} >{textLabel}</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
import { BrowserRouter as Router, Routes, Route, Link, useNavigate, withRouter } from 'react-router-dom';
|
||||||
|
// import { useNavigation } from '@react-navigation/native';
|
||||||
import BlockFormSection from './BlockFormSection';
|
import BlockFormSection from './BlockFormSection';
|
||||||
|
import PageInvoiceOrEstimate from '../pages/PageInvoiceOrEstimate_functional_react-pdf';
|
||||||
// import getValuesDefault from './ControlsFillDefaults';
|
// import getValuesDefault from './ControlsFillDefaults';
|
||||||
import InputWrapped from './Input';
|
import InputWrapped from './Input';
|
||||||
import ContentFormInvoiceOrEstimate from './ContentFormInvoiceOrEstimate';
|
import ContentFormInvoiceOrEstimate from './ContentFormInvoiceOrEstimate';
|
||||||
@@ -8,12 +11,30 @@ const makeInputJSON = (dictArgs) => {
|
|||||||
return methods.makeInputJSON(dictArgs);
|
return methods.makeInputJSON(dictArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
function MainContentFormWrapper(props) {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
return <MainContentForm navigate={navigate} placeholders={props.placeholders} values={props.values} />;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
function useHandleSubmitFunction(props) {
|
||||||
|
console.log("handleSubmitFunction");
|
||||||
|
console.log(props);
|
||||||
|
const navigation = useNavigate();
|
||||||
|
navigation.navigate('PageInvoiceOrEstimateWrapper', { state: props });
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
const withNavigate = Comp => props => <Comp {...props} navigate={useNavigate()} />;
|
||||||
|
|
||||||
class MainContentForm extends Component {
|
class MainContentForm extends Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
const values = {
|
const values = {
|
||||||
typeForm: "0",
|
typeForm: "1",
|
||||||
currency: '0',
|
currency: '0',
|
||||||
nameMyBusiness: '',
|
nameMyBusiness: '',
|
||||||
companyNumberMyBusiness: '',
|
companyNumberMyBusiness: '',
|
||||||
@@ -62,12 +83,27 @@ class MainContentForm extends Component {
|
|||||||
descriptionIncrementServiceInvoice1s4: '',
|
descriptionIncrementServiceInvoice1s4: '',
|
||||||
quantityRatePeriodsIncrementServiceInvoice1s4: ''
|
quantityRatePeriodsIncrementServiceInvoice1s4: ''
|
||||||
};
|
};
|
||||||
this.state = { values: {...values, ...props.values }, placeholders: props.placeholders, sectionsMainContentForm: [], sectionsForm: [], sectionsGoods: [], sectionsServices: [], subsectionsServices: []};
|
this.state = { values: {...values, ...props.values || {} }, placeholders: props.placeholders, sectionsMainContentForm: [], sectionsForm: [], sectionsGoods: [], sectionsServices: [], subsectionsServices: []};
|
||||||
console.log("placeholders: ", props.placeholders);
|
console.log("placeholders: ", props.placeholders);
|
||||||
|
this.handleChangeStateMainContentForm = this.handleChangeStateMainContentForm.bind(this);
|
||||||
this.initialiseElements();
|
this.initialiseElements();
|
||||||
|
this.handleSubmit = this.handleSubmit.bind(this);
|
||||||
|
this.getInputValues = this.getInputValues.bind(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
handleChangeStateConstructionMainContentForm(stateNew) {
|
||||||
|
console.log(this);
|
||||||
|
this.state = {
|
||||||
|
...this.state,
|
||||||
|
...stateNew
|
||||||
|
};
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
handleChangeStateMainContentForm(stateNew) {
|
handleChangeStateMainContentForm(stateNew) {
|
||||||
|
console.log(this);
|
||||||
this.setState((statePrevious) => ({
|
this.setState((statePrevious) => ({
|
||||||
...statePrevious,
|
...statePrevious,
|
||||||
...stateNew
|
...stateNew
|
||||||
@@ -75,7 +111,7 @@ class MainContentForm extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleChangeInput(event) {
|
handleChangeInput(event) {
|
||||||
const { elementInput } = event.target;
|
const elementInput = event.target;
|
||||||
this.handleChangeStateMainContentForm({[elementInput.name]: elementInput.value});
|
this.handleChangeStateMainContentForm({[elementInput.name]: elementInput.value});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,13 +182,40 @@ class MainContentForm extends Component {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
this.handleChangeStateMainContentForm({ sectionsMainContentForm: sectionsMainContentForm });
|
|
||||||
|
// this.handleChangeStateMainContentForm({ sectionsMainContentForm: sectionsMainContentForm });
|
||||||
|
this.state = { ...this.state, sectionsMainContentForm: sectionsMainContentForm };
|
||||||
|
}
|
||||||
|
handleSubmit(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
// navigate('/PageInvoiceOrEstimate', { state: this.state });
|
||||||
|
// this.props.history.push('/PageInvoiceOrEstimate', { state: this.state });
|
||||||
|
// console.log("state: ", this.state);
|
||||||
|
let statePageInvoiceOrEstimate = this.getInputValues();
|
||||||
|
console.log("statePageInvoiceOrEstimate: ", statePageInvoiceOrEstimate);
|
||||||
|
this.props.navigate('/PageInvoiceOrEstimate', { state: { data: statePageInvoiceOrEstimate } });
|
||||||
|
/*
|
||||||
|
const navigate = useNavigate();
|
||||||
|
navigate('/PageInvoiceOrEstimate', { state: statePageInvoiceOrEstimate });
|
||||||
|
*/
|
||||||
|
// this.props.navigation.navigate('PageInvoiceOrEstimateWrapper', { data: statePageInvoiceOrEstimate });
|
||||||
|
// useHandleSubmitFunction(statePageInvoiceOrEstimate);
|
||||||
|
}
|
||||||
|
getInputValues() {
|
||||||
|
let inputValues = {};
|
||||||
|
this.state.sectionsMainContentForm.forEach(section => {
|
||||||
|
section.inputs.forEach(input => {
|
||||||
|
inputValues[input.name] = input.value; // this.state.values[input.name];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
console.log("MainContentForm.getInputValues");
|
||||||
|
console.log(inputValues);
|
||||||
|
return inputValues;
|
||||||
}
|
}
|
||||||
handleSubmit() { };
|
|
||||||
clearForm() { };
|
clearForm() { };
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let typeForm = this.state.values['typeForm'] == "0" ? "Invoice" : "Estimate";
|
let typeForm = this.props.values['typeForm'] == "1" ? "Invoice" : "Estimate";
|
||||||
return (
|
return (
|
||||||
<form onSubmit={this.handleSubmit} align="center">
|
<form onSubmit={this.handleSubmit} align="center">
|
||||||
{this.state.sectionsMainContentForm.map(section => (
|
{this.state.sectionsMainContentForm.map(section => (
|
||||||
@@ -161,7 +224,7 @@ class MainContentForm extends Component {
|
|||||||
{/* <makeSectionsForm data={ {valuesDefault: valuesDefault, placeholdersDefault: placeholdersDefault} } /> */}
|
{/* <makeSectionsForm data={ {valuesDefault: valuesDefault, placeholdersDefault: placeholdersDefault} } /> */}
|
||||||
{typeForm}
|
{typeForm}
|
||||||
{(typeForm == 'Invoice' || typeForm == 'Estimate') &&
|
{(typeForm == 'Invoice' || typeForm == 'Estimate') &&
|
||||||
<ContentFormInvoiceOrEstimate stateMainContentForm={this.state} handleChangeStateMainContentForm={this.handleChangeStateMainContentForm} />
|
<ContentFormInvoiceOrEstimate stateMainContentForm={this.state} handleChangeStateMainContentForm={this.handleChangeStateMainContentForm} /> /* handleChangeStateConstructionMainContentForm={this.handleChangeStateConstructionMainContentForm} */
|
||||||
}
|
}
|
||||||
<div>
|
<div>
|
||||||
<button type="button" id="buttonFormClear" onClick={this.clearForm}>Clear Form</button>
|
<button type="button" id="buttonFormClear" onClick={this.clearForm}>Clear Form</button>
|
||||||
@@ -172,4 +235,5 @@ class MainContentForm extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MainContentForm;
|
const MainContentFormWrapper = withNavigate(MainContentForm);
|
||||||
|
export default MainContentFormWrapper;
|
||||||
@@ -1,142 +1,27 @@
|
|||||||
import React, {useEffect, useState} from 'react';
|
import React, { useState } from 'react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
import BlockFormSection from './BlockFormSection';
|
import BlockFormSection from './BlockFormSection';
|
||||||
import getValuesDefault from './ControlsFillDefaults';
|
|
||||||
import InputWrapped from './Input';
|
import InputWrapped from './Input';
|
||||||
import ContentFormInvoiceOrEstimate from './ContentFormInvoiceOrEstimate';
|
import ContentFormInvoiceOrEstimate from './ContentFormInvoiceOrEstimate';
|
||||||
import methods from './MethodsInput';
|
import methods from './MethodsInput';
|
||||||
|
|
||||||
const makeInputJSON = (dictArgs) => {
|
const makeInputJSON = (dictArgs) => {
|
||||||
return methods.makeInputJSON(dictArgs);
|
return methods.makeInputJSON(dictArgs);
|
||||||
}
|
};
|
||||||
|
|
||||||
const getValuesDefaultFromPlaceholders = (placeholdersDefault) => {
|
|
||||||
const values = {
|
|
||||||
typeForm: "0",
|
|
||||||
currency: '0',
|
|
||||||
nameMyBusiness: '',
|
|
||||||
companyNumberMyBusiness: '',
|
|
||||||
emailMyBusiness: '',
|
|
||||||
address1MyBusiness: '',
|
|
||||||
address2MyBusiness: '',
|
|
||||||
address3MyBusiness: '',
|
|
||||||
address4MyBusiness: '',
|
|
||||||
address5MyBusiness: '',
|
|
||||||
bankNameMyBusiness: '',
|
|
||||||
accountNameMyBusiness: '',
|
|
||||||
accountNumberMyBusiness: '',
|
|
||||||
sortCodeMyBusiness: '',
|
|
||||||
nameTheirBusiness: '',
|
|
||||||
codeTheirBusiness: '',
|
|
||||||
emailTheirBusiness: '',
|
|
||||||
phoneTheirBusiness: '',
|
|
||||||
address1TheirBusiness: '',
|
|
||||||
address2TheirBusiness: '',
|
|
||||||
address3TheirBusiness: '',
|
|
||||||
address4TheirBusiness: '',
|
|
||||||
address5TheirBusiness: '',
|
|
||||||
nameContactTheirBusiness: '',
|
|
||||||
address1ContactTheirBusiness: '',
|
|
||||||
address2ContactTheirBusiness: '',
|
|
||||||
address3ContactTheirBusiness: '',
|
|
||||||
address4ContactTheirBusiness: '',
|
|
||||||
address5ContactTheirBusiness: '',
|
|
||||||
typeInvoice: '',
|
|
||||||
quantityServicesInvoice: '',
|
|
||||||
discretisationRateServiceInvoice1: '',
|
|
||||||
quantityDiscretisationRateServiceInvoice1: '',
|
|
||||||
rateServiceInvoice1: '',
|
|
||||||
discretisationDurationServiceInvoice1: '',
|
|
||||||
quantityDiscretisationDurationServiceInvoice1: '',
|
|
||||||
quantityBillingPeriodServiceInvoice1: '',
|
|
||||||
isIncrementalBillingPeriodIdsServiceInvoice1: '',
|
|
||||||
descriptionIncrementalServiceInvoice1: '',
|
|
||||||
idBillingPeriodFirstIncrementalServiceInvoice1: '',
|
|
||||||
descriptionIncrementServiceInvoice1s1: '',
|
|
||||||
quantityRatePeriodsIncrementServiceInvoice1s1: '',
|
|
||||||
descriptionIncrementServiceInvoice1s2: '',
|
|
||||||
quantityRatePeriodsIncrementServiceInvoice1s2: '',
|
|
||||||
descriptionIncrementServiceInvoice1s3: '',
|
|
||||||
quantityRatePeriodsIncrementServiceInvoice1s3: '',
|
|
||||||
descriptionIncrementServiceInvoice1s4: '',
|
|
||||||
quantityRatePeriodsIncrementServiceInvoice1s4: ''
|
|
||||||
}; // = placeholdersDefault;
|
|
||||||
/*
|
|
||||||
const combined = {};
|
|
||||||
for (const key in values) {
|
|
||||||
if (placeholdersDefault.hasOwnProperty(key)) {
|
|
||||||
combined[key] = placeholdersDefault[key];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
combined[key] = values[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return combined;
|
|
||||||
*/
|
|
||||||
return Object.keys(values).reduce((result, key) => {
|
|
||||||
if (placeholdersDefault.hasOwnProperty(key)) {
|
|
||||||
result[key] = placeholdersDefault[key];
|
|
||||||
} else {
|
|
||||||
result[key] = values[key];
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}, {});
|
|
||||||
/*{
|
|
||||||
typeForm: typeForm,
|
|
||||||
currency: currency,
|
|
||||||
nameMyBusiness: nameMyBusiness,
|
|
||||||
companyNumberMyBusiness: companyNumberMyBusiness,
|
|
||||||
emailMyBusiness: emailMyBusiness,
|
|
||||||
address1MyBusiness: address1MyBusiness,
|
|
||||||
address2MyBusiness: address2MyBusiness,
|
|
||||||
address3MyBusiness: address3MyBusiness,
|
|
||||||
address4MyBusiness: address4MyBusiness,
|
|
||||||
address5MyBusiness: address5MyBusiness,
|
|
||||||
bankNameMyBusiness: bankNameMyBusiness,
|
|
||||||
accountNameMyBusiness: accountNameMyBusiness,
|
|
||||||
accountNumberMyBusiness: accountNumberMyBusiness,
|
|
||||||
sortCodeMyBusiness: sortCodeMyBusiness,
|
|
||||||
nameTheirBusiness: nameTheirBusiness,
|
|
||||||
codeTheirBusiness: codeTheirBusiness,
|
|
||||||
emailTheirBusiness: emailTheirBusiness,
|
|
||||||
phoneTheirBusiness: phoneTheirBusiness,
|
|
||||||
address1TheirBusiness: address1TheirBusiness,
|
|
||||||
address2TheirBusiness: address2TheirBusiness,
|
|
||||||
address3TheirBusiness: address3TheirBusiness,
|
|
||||||
address4TheirBusiness: address4TheirBusiness,
|
|
||||||
address5TheirBusiness: address5TheirBusiness,
|
|
||||||
nameContactTheirBusiness: nameContactTheirBusiness,
|
|
||||||
address1ContactTheirBusiness: address1ContactTheirBusiness,
|
|
||||||
address2ContactTheirBusiness: address2ContactTheirBusiness,
|
|
||||||
address3ContactTheirBusiness: address3ContactTheirBusiness,
|
|
||||||
address4ContactTheirBusiness: address4ContactTheirBusiness,
|
|
||||||
address5ContactTheirBusiness: address5ContactTheirBusiness,
|
|
||||||
typeInvoice: typeInvoice,
|
|
||||||
quantityServicesInvoice: quantityServicesInvoice,
|
|
||||||
discretisationRateServiceInvoice1: discretisationRateServiceInvoice1,
|
|
||||||
quantityDiscretisationRateServiceInvoice1: quantityDiscretisationRateServiceInvoice1,
|
|
||||||
rateServiceInvoice1: rateServiceInvoice1,
|
|
||||||
discretisationDurationServiceInvoice1: discretisationDurationServiceInvoice1,
|
|
||||||
quantityDiscretisationDurationServiceInvoice1: quantityDiscretisationDurationServiceInvoice1,
|
|
||||||
quantityBillingPeriodServiceInvoice1: quantityBillingPeriodServiceInvoice1,
|
|
||||||
isIncrementalBillingPeriodIdsServiceInvoice1: isIncrementalBillingPeriodIdsServiceInvoice1,
|
|
||||||
descriptionIncrementalServiceInvoice1: descriptionIncrementalServiceInvoice1,
|
|
||||||
idBillingPeriodFirstIncrementalServiceInvoice1: idBillingPeriodFirstIncrementalServiceInvoice1,
|
|
||||||
descriptionIncrementServiceInvoice1s1: descriptionIncrementServiceInvoice1s1,
|
|
||||||
quantityRatePeriodsIncrementServiceInvoice1s1: quantityRatePeriodsIncrementServiceInvoice1s1,
|
|
||||||
descriptionIncrementServiceInvoice1s2: descriptionIncrementServiceInvoice1s2,
|
|
||||||
quantityRatePeriodsIncrementServiceInvoice1s2: quantityRatePeriodsIncrementServiceInvoice1s2,
|
|
||||||
descriptionIncrementServiceInvoice1s3: descriptionIncrementServiceInvoice1s3,
|
|
||||||
quantityRatePeriodsIncrementServiceInvoice1s3: quantityRatePeriodsIncrementServiceInvoice1s3,
|
|
||||||
descriptionIncrementServiceInvoice1s4: descriptionIncrementServiceInvoice1s4,
|
|
||||||
quantityRatePeriodsIncrementServiceInvoice1s4: quantityRatePeriodsIncrementServiceInvoice1s4
|
|
||||||
};*/
|
|
||||||
}
|
|
||||||
|
|
||||||
const MainContentForm = (props) => {
|
const MainContentForm = (props) => {
|
||||||
const placeholdersDefault = props.data;
|
const navigate = useNavigate();
|
||||||
// const valuesDefault = getValuesDefault();
|
|
||||||
console.log("placeholders: ", placeholdersDefault);
|
const handleChangeInput = (event) => {
|
||||||
|
const elementInput = event.target;
|
||||||
|
setStateMainContentForm((statePrevious) => ({
|
||||||
|
...statePrevious,
|
||||||
|
[elementInput.name]: elementInput.value
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
const values = {
|
const values = {
|
||||||
typeForm: "0",
|
typeForm: "1",
|
||||||
currency: '0',
|
currency: '0',
|
||||||
nameMyBusiness: '',
|
nameMyBusiness: '',
|
||||||
companyNumberMyBusiness: '',
|
companyNumberMyBusiness: '',
|
||||||
@@ -165,6 +50,7 @@ const MainContentForm = (props) => {
|
|||||||
address3ContactTheirBusiness: '',
|
address3ContactTheirBusiness: '',
|
||||||
address4ContactTheirBusiness: '',
|
address4ContactTheirBusiness: '',
|
||||||
address5ContactTheirBusiness: '',
|
address5ContactTheirBusiness: '',
|
||||||
|
dateBillingInvoice: '',
|
||||||
typeInvoice: '',
|
typeInvoice: '',
|
||||||
quantityServicesInvoice: '',
|
quantityServicesInvoice: '',
|
||||||
discretisationRateServiceInvoice1: '',
|
discretisationRateServiceInvoice1: '',
|
||||||
@@ -183,137 +69,278 @@ const MainContentForm = (props) => {
|
|||||||
descriptionIncrementServiceInvoice1s3: '',
|
descriptionIncrementServiceInvoice1s3: '',
|
||||||
quantityRatePeriodsIncrementServiceInvoice1s3: '',
|
quantityRatePeriodsIncrementServiceInvoice1s3: '',
|
||||||
descriptionIncrementServiceInvoice1s4: '',
|
descriptionIncrementServiceInvoice1s4: '',
|
||||||
quantityRatePeriodsIncrementServiceInvoice1s4: ''
|
quantityRatePeriodsIncrementServiceInvoice1s4: '',
|
||||||
};
|
...props.values,
|
||||||
const valuesDefault = { ...values, ...placeholdersDefault }; // getValuesDefaultFromPlaceholders(placeholdersDefault);
|
|
||||||
let typeForm = valuesDefault['typeForm'] == 0 ? 'Invoice' : 'Estimate';
|
|
||||||
|
|
||||||
const [stateMainContentForm, setStateMainContentForm] = useState({ sectionsMainContentForm: [], sectionsForm: [], sectionsGoods: [], sectionsServices: [], subsectionsServices: []});
|
|
||||||
const handleChangeStateMainContentForm = (stateNew) => {
|
|
||||||
setStateMainContentForm(stateNew);
|
|
||||||
};
|
|
||||||
const handleChangeInputMainContentForm = (event) => {
|
|
||||||
const { elementInput } = event.target;
|
|
||||||
let valueInput = {};
|
|
||||||
valueInput[elementInput.name] = elementInput.value;
|
|
||||||
handleChangeStateMainContentForm({
|
|
||||||
...stateMainContentForm,
|
|
||||||
...valueInput
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
const stateTemp = {
|
||||||
const dataMainContentForm = {
|
sectionsMainContentForm: [
|
||||||
...stateMainContentForm,
|
{
|
||||||
sectionsMainContentForm: [
|
titleSection: 'Invoice Generator Form',
|
||||||
{
|
inputs: [
|
||||||
titleSection: 'Invoice Metadata',
|
makeInputJSON({id: 'typeForm', name: 'typeForm', value: props.values['typeForm'], textLabel: 'Form type:', type: 'select', placeholder: props.placeholders['typeForm'], options: [
|
||||||
inputs: [
|
{text: '-', value: '0'},
|
||||||
makeInputJSON({id: 'typeForm', name: 'typeForm', value: valuesDefault['typeForm'], textLabel: 'Form type:', type: 'select', placeholder: placeholdersDefault['typeForm'], options: [
|
{text: 'INVOICE', value: '1'},
|
||||||
{text: '-', value: '0'},
|
{text: 'ESTIMATE', value: '2'},
|
||||||
{text: 'INVOICE', value: '1'},
|
{text: 'PAYMENT-PLAN', value: '3'}
|
||||||
{text: 'ESTIMATE', value: '2'},
|
], onChange: handleChangeInput}),
|
||||||
{text: 'PAYMENT-PLAN', value: '3'}
|
makeInputJSON({id: 'currency', name: 'currency', value: props.values['currency'], textLabel: 'Currency:', type: 'select', options: [
|
||||||
], onChange: handleChangeInputMainContentForm}),
|
{text: '£', value: '£'},
|
||||||
makeInputJSON({id: 'currency', name: 'currency', value: valuesDefault['currency'], textLabel: 'Currency:', type: 'select', options: [
|
{text: '$', value: '$'},
|
||||||
{text: '£', value: '0'},
|
{text: '€', value: '€'},
|
||||||
{text: '$', value: '1'},
|
{text: 'Other', value: 'Other'}
|
||||||
{text: '€', value: '2'},
|
], onChange: handleChangeInput})
|
||||||
{text: 'Other', value: '3'}
|
]
|
||||||
], onChange: handleChangeInputMainContentForm})
|
},
|
||||||
]
|
{
|
||||||
},
|
titleSection: 'My Business Details',
|
||||||
{
|
inputs: [
|
||||||
titleSection: 'My Business Details',
|
makeInputJSON({id: 'nameMyBusiness', name: 'nameMyBusiness', value: props.values['nameMyBusiness'], textLabel: 'Name:', type: 'text', placeholder: props.placeholders['nameMyBusiness'], onChange: handleChangeInput}),
|
||||||
inputs: [
|
makeInputJSON({id: 'companyNumberMyBusiness', name: 'companyNumberMyBusiness', value: props.values['companyNumberMyBusiness'], textLabel: 'Company number:', type: 'text', placeholder: props.placeholders['companyNumberMyBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'nameMyBusiness', name: 'nameMyBusiness', value: valuesDefault['nameMyBusiness'], textLabel: 'Name:', type: 'text', placeholder: placeholdersDefault['nameMyBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'emailMyBusiness', name: 'emailMyBusiness', value: props.values['emailMyBusiness'], textLabel: 'Email:', type:'text', placeholder: props.placeholders['emailMyBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'companyNumberMyBusiness', name: 'companyNumberMyBusiness', value: valuesDefault['companyNumberMyBusiness'], textLabel: 'Company number:', type: 'text', placeholder: placeholdersDefault['companyNumberMyBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'address1MyBusiness', name: 'address1MyBusiness', value: props.values['address1MyBusiness'], textLabel: 'Address line 1:', type:'text', placeholder: props.placeholders['address1MyBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'emailMyBusiness', name: 'emailMyBusiness', value: valuesDefault['emailMyBusiness'], textLabel: 'Email:', type:'text', placeholder: placeholdersDefault['emailMyBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'address2MyBusiness', name: 'address2MyBusiness', value: props.values['address2MyBusiness'], textLabel: 'Address line 2:', type:'text', placeholder: props.placeholders['address2MyBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'address1MyBusiness', name: 'address1MyBusiness', value: valuesDefault['address1MyBusiness'], textLabel: 'Address line 1:', type:'text', placeholder: placeholdersDefault['address1MyBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'address3MyBusiness', name: 'address3MyBusiness', value: props.values['address3MyBusiness'], textLabel: 'Address line 3:', type:'text', placeholder: props.placeholders['address3MyBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'address2MyBusiness', name: 'address2MyBusiness', value: valuesDefault['address2MyBusiness'], textLabel: 'Address line 2:', type:'text', placeholder: placeholdersDefault['address2MyBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'address4MyBusiness', name: 'address4MyBusiness', value: props.values['address4MyBusiness'], textLabel: 'Address line 4:', type:'text', placeholder: props.placeholders['address4MyBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'address3MyBusiness', name: 'address3MyBusiness', value: valuesDefault['address3MyBusiness'], textLabel: 'Address line 3:', type:'text', placeholder: placeholdersDefault['address3MyBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'address5MyBusiness', name: 'address5MyBusiness', value: props.values['address5MyBusiness'], textLabel: 'Address line 5:', type:'text', placeholder: props.placeholders['address5MyBusiness'], onChange: handleChangeInput})
|
||||||
makeInputJSON({id: 'address4MyBusiness', name: 'address4MyBusiness', value: valuesDefault['address4MyBusiness'], textLabel: 'Address line 4:', type:'text', placeholder: placeholdersDefault['address4MyBusiness'], onChange: handleChangeInputMainContentForm}),
|
]
|
||||||
makeInputJSON({id: 'address5MyBusiness', name: 'address5MyBusiness', value: valuesDefault['address5MyBusiness'], textLabel: 'Address line 5:', type:'text', placeholder: placeholdersDefault['address5MyBusiness'], onChange: handleChangeInputMainContentForm})
|
},
|
||||||
]
|
{
|
||||||
},
|
titleSection: 'My Business Bank Details',
|
||||||
{
|
inputs: [
|
||||||
titleSection: 'My Business Bank Details',
|
makeInputJSON({id: 'nameBankMyBusiness', name: 'nameBankMyBusiness', value: props.values['nameBankMyBusiness'], textLabel: 'Bank name:', type:'text', placeholder: props.placeholders['nameBankMyBusiness'], onChange: handleChangeInput}),
|
||||||
inputs: [
|
makeInputJSON({id: 'accountNameBankMyBusiness', name: 'accountNameBankMyBusiness', value: props.values['accountNameBankMyBusiness'], textLabel: 'Account name:', type:'text', placeholder: props.placeholders['accountNameBankMyBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'nameBankMyBusiness', name: 'nameBankMyBusiness', value: valuesDefault['nameBankMyBusiness'], textLabel: 'Bank name:', type:'text', placeholder: placeholdersDefault['nameBankMyBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'accountNumberBankMyBusiness', name: 'accountNumberBankMyBusiness', value: props.values['accountNumberBankMyBusiness'], textLabel: 'Account number:', type:'text', placeholder: props.placeholders['accountNumberBankMyBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'accountNameBankMyBusiness', name: 'accountNameBankMyBusiness', value: valuesDefault['accountNameBankMyBusiness'], textLabel: 'Account name:', type:'text', placeholder: placeholdersDefault['accountNameBankMyBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'sortCodeBankMyBusiness', name: 'sortCodeBankMyBusiness', value: props.values['sortCodeBankMyBusiness'], textLabel: 'Sort code:', type:'text', placeholder: props.placeholders['sortCodeBankMyBusiness'], onChange: handleChangeInput})
|
||||||
makeInputJSON({id: 'accountNumberBankMyBusiness', name: 'accountNumberBankMyBusiness', value: valuesDefault['accountNumberBankMyBusiness'], textLabel: 'Account number:', type:'text', placeholder: placeholdersDefault['accountNumberBankMyBusiness'], onChange: handleChangeInputMainContentForm}),
|
]
|
||||||
makeInputJSON({id: 'sortCodeBankMyBusiness', name: 'sortCodeBankMyBusiness', value: valuesDefault['sortCodeBankMyBusiness'], textLabel: 'Sort code:', type:'text', placeholder: placeholdersDefault['sortCodeBankMyBusiness'], onChange: handleChangeInputMainContentForm})
|
},
|
||||||
]
|
{
|
||||||
},
|
titleSection: 'Their Business Details',
|
||||||
{
|
inputs: [
|
||||||
titleSection: 'Their Business Details',
|
makeInputJSON({id: 'nameTheirBusiness', name: 'nameTheirBusiness', value: props.values['nameTheirBusiness'], textLabel: 'Name:', type:'text', placeholder: props.placeholders['nameTheirBusiness'], onChange: handleChangeInput}),
|
||||||
inputs: [
|
makeInputJSON({id: 'codeTheirBusiness', name: 'codeTheirBusiness', value: props.values['codeTheirBusiness'], textLabel: 'Code:', type:'text', placeholder: props.placeholders['codeTheirBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'nameTheirBusiness', name: 'nameTheirBusiness', value: valuesDefault['nameTheirBusiness'], textLabel: 'Name:', type:'text', placeholder: placeholdersDefault['nameTheirBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'emailTheirBusiness', name: 'emailTheirBusiness', value: props.values['emailTheirBusiness'], textLabel: 'Email:', type:'text', placeholder: props.placeholders['emailTheirBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'codeTheirBusiness', name: 'codeTheirBusiness', value: valuesDefault['codeTheirBusiness'], textLabel: 'Code:', type:'text', placeholder: placeholdersDefault['codeTheirBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'phoneTheirBusiness', name: 'phoneTheirBusiness', value: props.values['phoneTheirBusiness'], textLabel: 'Phone:', type:'text', placeholder: props.placeholders['phoneTheirBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'emailTheirBusiness', name: 'emailTheirBusiness', value: valuesDefault['emailTheirBusiness'], textLabel: 'Email:', type:'text', placeholder: placeholdersDefault['emailTheirBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'address1TheirBusiness', name: 'address1TheirBusiness', value: props.values['address1TheirBusiness'], textLabel: 'Address line 1:', type:'text', placeholder: props.placeholders['address1TheirBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'phoneTheirBusiness', name: 'phoneTheirBusiness', value: valuesDefault['phoneTheirBusiness'], textLabel: 'Phone:', type:'text', placeholder: placeholdersDefault['phoneTheirBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'address2TheirBusiness', name: 'address2TheirBusiness', value: props.values['address2TheirBusiness'], textLabel: 'Address line 2:', type:'text', placeholder: props.placeholders['address2TheirBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'address1TheirBusiness', name: 'address1TheirBusiness', value: valuesDefault['address1TheirBusiness'], textLabel: 'Address line 1:', type:'text', placeholder: placeholdersDefault['address1TheirBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'address3TheirBusiness', name: 'address3TheirBusiness', value: props.values['address3TheirBusiness'], textLabel: 'Address line 3:', type:'text', placeholder: props.placeholders['address3TheirBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'address2TheirBusiness', name: 'address2TheirBusiness', value: valuesDefault['address2TheirBusiness'], textLabel: 'Address line 2:', type:'text', placeholder: placeholdersDefault['address2TheirBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'address4TheirBusiness', name: 'address4TheirBusiness', value: props.values['address4TheirBusiness'], textLabel: 'Address line 4:', type:'text', placeholder: props.placeholders['address4TheirBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'address3TheirBusiness', name: 'address3TheirBusiness', value: valuesDefault['address3TheirBusiness'], textLabel: 'Address line 3:', type:'text', placeholder: placeholdersDefault['address3TheirBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'address5TheirBusiness', name: 'address5TheirBusiness', value: props.values['address5TheirBusiness'], textLabel: 'Address line 5:', type:'text', placeholder: props.placeholders['address5TheirBusiness'], onChange: handleChangeInput})
|
||||||
makeInputJSON({id: 'address4TheirBusiness', name: 'address4TheirBusiness', value: valuesDefault['address4TheirBusiness'], textLabel: 'Address line 4:', type:'text', placeholder: placeholdersDefault['address4TheirBusiness'], onChange: handleChangeInputMainContentForm}),
|
]
|
||||||
makeInputJSON({id: 'address5TheirBusiness', name: 'address5TheirBusiness', value: valuesDefault['address5TheirBusiness'], textLabel: 'Address line 5:', type:'text', placeholder: placeholdersDefault['address5TheirBusiness'], onChange: handleChangeInputMainContentForm})
|
},
|
||||||
]
|
{
|
||||||
},
|
titleSection: 'Their Business Contact Details',
|
||||||
{
|
inputs: [
|
||||||
titleSection: 'Their Business Contact Details',
|
makeInputJSON({id: 'nameContactTheirBusiness', name: 'nameContactTheirBusiness', value: props.values['nameContactTheirBusiness'], textLabel: 'Name:', type:'text', placeholder: props.placeholders['nameContactTheirBusiness'], onChange: handleChangeInput}),
|
||||||
inputs: [
|
makeInputJSON({id: 'address1ContactTheirBusiness', name: 'address1ContactTheirBusiness', value: props.values['address1ContactTheirBusiness'], textLabel: 'Address line 1:', type:'text', placeholder: props.placeholders['address1ContactTheirBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'nameContactTheirBusiness', name: 'nameContactTheirBusiness', value: valuesDefault['nameContactTheirBusiness'], textLabel: 'Name:', type:'text', placeholder: placeholdersDefault['nameContactTheirBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'address2ContactTheirBusiness', name: 'address2ContactTheirBusiness', value: props.values['address2ContactTheirBusiness'], textLabel: 'Address line 2:', type:'text', placeholder: props.placeholders['address2ContactTheirBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'address1ContactTheirBusiness', name: 'address1ContactTheirBusiness', value: valuesDefault['address1ContactTheirBusiness'], textLabel: 'Address line 1:', type:'text', placeholder: placeholdersDefault['address1ContactTheirBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'address3ContactTheirBusiness', name: 'address3ContactTheirBusiness', value: props.values['address3ContactTheirBusiness'], textLabel: 'Address line 3:', type:'text', placeholder: props.placeholders['address3ContactTheirBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'address2ContactTheirBusiness', name: 'address2ContactTheirBusiness', value: valuesDefault['address2ContactTheirBusiness'], textLabel: 'Address line 2:', type:'text', placeholder: placeholdersDefault['address2ContactTheirBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'address4ContactTheirBusiness', name: 'address4ContactTheirBusiness', value: props.values['address4ContactTheirBusiness'], textLabel: 'Address line 4:', type:'text', placeholder: props.placeholders['address4ContactTheirBusiness'], onChange: handleChangeInput}),
|
||||||
makeInputJSON({id: 'address3ContactTheirBusiness', name: 'address3ContactTheirBusiness', value: valuesDefault['address3ContactTheirBusiness'], textLabel: 'Address line 3:', type:'text', placeholder: placeholdersDefault['address3ContactTheirBusiness'], onChange: handleChangeInputMainContentForm}),
|
makeInputJSON({id: 'address5ContactTheirBusiness', name: 'address5ContactTheirBusiness', value: props.values['address5ContactTheirBusiness'], textLabel: 'Address line 5:', type:'text', placeholder: props.placeholders['address5ContactTheirBusiness'], onChange: handleChangeInput})
|
||||||
makeInputJSON({id: 'address4ContactTheirBusiness', name: 'address4ContactTheirBusiness', value: valuesDefault['address4ContactTheirBusiness'], textLabel: 'Address line 4:', type:'text', placeholder: placeholdersDefault['address4ContactTheirBusiness'], onChange: handleChangeInputMainContentForm}),
|
]
|
||||||
makeInputJSON({id: 'address5ContactTheirBusiness', name: 'address5ContactTheirBusiness', value: valuesDefault['address5ContactTheirBusiness'], textLabel: 'Address line 5:', type:'text', placeholder: placeholdersDefault['address5ContactTheirBusiness'], onChange: handleChangeInputMainContentForm})
|
}
|
||||||
]
|
]
|
||||||
}
|
};
|
||||||
|
|
||||||
|
let typeForm = props.values['typeForm'] == "1" ? "Invoice" : "Estimate";
|
||||||
|
let sectionsForm = [
|
||||||
|
{
|
||||||
|
titleSection: typeForm,
|
||||||
|
inputs: [
|
||||||
|
makeInputJSON({id: 'dateBilling' + typeForm, name: 'dateBilling' + typeForm, type: 'date', placeholder: props.placeholders['dateBilling' + typeForm], value: props.values['dateBilling' + typeForm], textLabel: 'Billing date:', onChange: handleChangeInput}),
|
||||||
|
makeInputJSON({id: 'type' + typeForm, name: 'type' + typeForm, type: 'select', placeholder: props.placeholders['type' + typeForm], value: props.values['type' + typeForm], options: [
|
||||||
|
{text: 'Goods', value:'0'},
|
||||||
|
{text: 'Services', value:'1'}
|
||||||
|
], textLabel: 'Invoice type:', onChange: handleChangeInput})
|
||||||
]
|
]
|
||||||
};
|
}
|
||||||
handleChangeStateMainContentForm(dataMainContentForm);
|
];
|
||||||
}, [placeholdersDefault, valuesDefault]);
|
let sectionsGoods = [];
|
||||||
|
if (props.values['type' + typeForm] == '0') {
|
||||||
|
sectionsForm = sectionsForm.concat([
|
||||||
|
{
|
||||||
|
titleSection: 'Goods',
|
||||||
|
inputs: [
|
||||||
|
makeInputJSON({id: 'quantityGoods' + typeForm, name: 'quantityGoods' + typeForm, type: 'number', placeholder: props.placeholders['quantityGoods' + typeForm], value: props.values['quantityGoods' + typeForm], textLabel: 'Number of different goods:', onChange: handleChangeInput})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
if (props.values['quantityGoods' + typeForm] > 0) {
|
||||||
|
for (let i = 0; i < props.values['quantityGoods' + typeForm]; i++) {
|
||||||
|
sectionsGoods = sectionsGoods.concat([
|
||||||
|
{
|
||||||
|
titleSection: 'Good ' + (i + 1),
|
||||||
|
inputs: [
|
||||||
|
makeInputJSON({id: 'nameGood' + typeForm + (i + 1), name: 'nameGood' + typeForm + (i + 1), type: 'text', placeholder: props.placeholders['nameGood' + typeForm + (i + 1)], value: props.values['nameGood' + typeForm + (i + 1)], textLabel: 'Name:', onChange: handleChangeInput}),
|
||||||
|
makeInputJSON({id: 'valueGood' + typeForm + (i + 1), name: 'valueGood' + typeForm + (i + 1), type: 'number', placeholder: props.placeholders['valueGood' + typeForm + (i + 1)], value: props.values['valueGood' + typeForm + (i + 1)], textLabel: 'Value:', onChange: handleChangeInput}),
|
||||||
|
makeInputJSON({id: 'quantityGood' + typeForm + (i + 1), name: 'quantityGood' + typeForm + (i + 1), type: 'number', placeholder: props.placeholders['quantityGood' + typeForm + (i + 1)], value: props.values['quantityGood' + typeForm + (i + 1)], textLabel: 'Quantity:', onChange: handleChangeInput})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let sectionsServices = [];
|
||||||
|
let subsectionsServices = [];
|
||||||
|
console.log("props.values[" + "type" + typeForm + "]:", props.values['type' + typeForm]);
|
||||||
|
if (props.values['type' + typeForm] == '1') {
|
||||||
|
sectionsForm = sectionsForm.concat([
|
||||||
|
{
|
||||||
|
titleSection: 'Services',
|
||||||
|
inputs: [
|
||||||
|
makeInputJSON({id: 'quantityServices' + typeForm, name: 'quantityServices' + typeForm, type: 'number', placeholder: props.placeholders['quantityServices' + typeForm], value: props.values['quantityServices' + typeForm], textLabel: 'Number of different services:', onChange: handleChangeInput})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
console.log("props.values[" + 'quantityServices' + typeForm + "]:", props.values['quantityServices' + typeForm]);
|
||||||
|
if (props.values['quantityServices' + typeForm] > 0) {
|
||||||
|
let j;
|
||||||
|
for (let i = 0; i < props.values['quantityServices' + typeForm]; i++) {
|
||||||
|
console.log("adding service " + (i + 1));
|
||||||
|
sectionsServices = sectionsServices.concat([
|
||||||
|
{
|
||||||
|
titleSection: 'Service ' + (i + 1),
|
||||||
|
inputs: [
|
||||||
|
makeInputJSON({id: 'discretisationRateService' + typeForm + (i + 1), name: 'discretisationRateService' + typeForm + (i + 1), type: 'select', placeholder: props.placeholders['discretisationRateService' + typeForm + (i + 1)], value: props.values['discretisationRateService' + typeForm + (i + 1)], options: [
|
||||||
|
{text: 'Minute', value:'m'},
|
||||||
|
{text: 'Hour', value:'h'},
|
||||||
|
{text: 'Day', value:'d'},
|
||||||
|
{text: 'Week', value:'w'}
|
||||||
|
], textLabel: 'Rate discretisation:', onChange: handleChangeInput}),
|
||||||
|
makeInputJSON({id: 'quantityDiscretisationRateService' + typeForm + (i + 1), name: 'quantityDiscretisationRateService' + typeForm + (i + 1), type: 'number', placeholder: props.placeholders['quantityDiscretisationRateService' + typeForm + (i + 1)], value: props.values['quantityDiscretisationRateService' + typeForm + (i + 1)], textLabel: 'Quantity of rate discretisations per minimum unit rate:', onChange: handleChangeInput}),
|
||||||
|
makeInputJSON({id: 'rateService' + typeForm + (i + 1), name: 'rateService' + typeForm + (i + 1), type: 'number', placeholder: props.placeholders['rateService' + typeForm + (i + 1)], value: props.values['rateService' + typeForm + (i + 1)], textLabel: 'Rate [£ / hour]:', onChange: handleChangeInput}),
|
||||||
|
makeInputJSON({id: 'discretisationDurationService' + typeForm + (i + 1), name: 'discretisationDurationService' + typeForm + (i + 1), type: 'select', placeholder: props.placeholders['discretisationDurationService' + typeForm + (i + 1)], value: props.values['discretisationDurationService' + typeForm + (i + 1)], options: [
|
||||||
|
{text: 'Day', value:'d'},
|
||||||
|
{text: 'Week', value:'w'},
|
||||||
|
{text: 'Month', value:'M'},
|
||||||
|
{text: 'Year', value:'y'}
|
||||||
|
], textLabel: 'Duration discretisation:', onChange: handleChangeInput}),
|
||||||
|
makeInputJSON({id: 'quantityDiscretisationDurationService' + typeForm + (i + 1), name: 'quantityDiscretisationDurationService' + typeForm + (i + 1), type: 'number', placeholder: props.placeholders['quantityDiscretisationDurationService' + typeForm + (i + 1)], value: props.values['quantityDiscretisationDurationService' + typeForm + (i + 1)], textLabel: 'Quantity of duration discretisations per billing period:', onChange: handleChangeInput}),
|
||||||
|
makeInputJSON({id: 'quantityBillingPeriodService' + typeForm + (i + 1), name: 'quantityBillingPeriodService' + typeForm + (i + 1), type: 'number', placeholder: props.placeholders['quantityBillingPeriodService' + typeForm + (i + 1)], value: props.values['quantityBillingPeriodService' + typeForm + (i + 1)], textLabel: 'Quantity of billing periods:', onChange: handleChangeInput}),
|
||||||
|
makeInputJSON({id: 'isIncrementalBillingPeriodIdsService' + typeForm + (i + 1), name: 'isIncrementalBillingPeriodIdsService' + typeForm + (i + 1), type: 'checkbox', placeholder: props.placeholders['isIncrementalBillingPeriodIdsService' + typeForm + (i + 1)], value: props.values['isIncrementalBillingPeriodIdsService' + typeForm + (i + 1)], textLabel: 'Are billing period IDs incremental?', onChange: handleChangeInput}),
|
||||||
|
makeInputJSON({id: 'descriptionIncrementalService' + typeForm + (i + 1), name: 'descriptionIncrementalService' + typeForm + (i + 1), type: 'text', placeholder: props.placeholders['descriptionIncrementalService' + typeForm + (i + 1)], value: props.values['descriptionIncrementalService' + typeForm + (i + 1)], textLabel: 'Description:', onChange: handleChangeInput}),
|
||||||
|
makeInputJSON({id: 'idBillingPeriodFirstIncrementalService' + typeForm + (i + 1), name: 'idBillingPeriodFirstIncrementalService' + typeForm + (i + 1), type: 'number', placeholder: props.placeholders['idBillingPeriodFirstIncrementalService' + typeForm + (i + 1)], value: props.values['idBillingPeriodFirstIncrementalService' + typeForm + (i + 1)], textLabel: 'First billing period ID:', onChange: handleChangeInput})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
let subsections = [];
|
||||||
|
if (props.values['quantityBillingPeriodService' + typeForm + (i + 1)] > 0) {
|
||||||
|
for (j = 0; j < props.values['quantityBillingPeriodService' + typeForm + (i + 1)]; j++) {
|
||||||
|
subsections = subsections.concat([
|
||||||
|
{
|
||||||
|
titleSection: 'Service billing period ' + (j + 1),
|
||||||
|
inputs: [
|
||||||
|
makeInputJSON({id: 'descriptionIncrementService' + typeForm + (i + 1) + 's' + (j + 1), name: 'descriptionIncrementService' + typeForm + (i + 1) + 's' + (j + 1), type: 'text', placeholder: props.placeholders['descriptionIncrementService' + typeForm + (i + 1) + 's' + (j + 1)], value: props.values['descriptionIncrementService' + typeForm + (i + 1) + 's' + (j + 1)], textLabel: 'Description:', onChange: handleChangeInput}),
|
||||||
|
makeInputJSON({id: 'quantityRatePeriodsIncrementService' + typeForm + (i + 1) + 's' + (j + 1), name: 'quantityRatePeriodsIncrementService' + typeForm + (i + 1) + 's' + (j + 1), type: 'number', placeholder: props.placeholders['quantityRatePeriodsIncrementService' + typeForm + (i + 1) + 's' + (j + 1)], value: props.values['quantityRatePeriodsIncrementService' + typeForm + (i + 1) + 's' + (j + 1)], textLabel: 'Quantity of unit rate periods worked:', onChange: handleChangeInput})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
subsectionsServices = subsectionsServices.concat(subsections);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("typeForm:", typeForm);
|
||||||
|
console.log("sectionsGoods:", sectionsGoods);
|
||||||
|
console.log("sectionsServices:", sectionsServices);
|
||||||
|
console.log("subsectionsServices:", subsectionsServices);
|
||||||
|
|
||||||
|
|
||||||
|
let dataInvoiceOrEstimate = {
|
||||||
|
...stateTemp,
|
||||||
|
sectionsForm: sectionsForm,
|
||||||
|
sectionsGoods: sectionsGoods,
|
||||||
|
sectionsServices: sectionsServices,
|
||||||
|
subsectionsServices: subsectionsServices,
|
||||||
|
};
|
||||||
|
|
||||||
|
const [stateMainContentForm, setStateMainContentForm] = useState(dataInvoiceOrEstimate);
|
||||||
|
|
||||||
|
console.log("MainContentForm");
|
||||||
|
console.log(props);
|
||||||
|
console.log(stateMainContentForm);
|
||||||
|
|
||||||
|
const handleSubmit = (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
let statePageInvoiceOrEstimate = getInputValues();
|
||||||
|
console.log("statePageInvoiceOrEstimate: ", statePageInvoiceOrEstimate);
|
||||||
|
navigate('/PageInvoiceOrEstimate', { state: { data: statePageInvoiceOrEstimate }, nips: 'good' });
|
||||||
|
};
|
||||||
|
|
||||||
|
const getInputValues = () => {
|
||||||
|
let inputValues = {};
|
||||||
|
console.log("getInputValues");
|
||||||
|
console.log("stateMainContentForm: ", stateMainContentForm);
|
||||||
|
stateMainContentForm.sectionsMainContentForm.forEach(section => {
|
||||||
|
section.inputs.forEach(input => {
|
||||||
|
inputValues[input.name] = getInputValue(input);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
stateMainContentForm.sectionsForm.forEach(section => {
|
||||||
|
section.inputs.forEach(input => {
|
||||||
|
inputValues[input.name] = getInputValue(input);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
stateMainContentForm.sectionsGoods.forEach(section => {
|
||||||
|
section.inputs.forEach(input => {
|
||||||
|
inputValues[input.name] = getInputValue(input);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
stateMainContentForm.sectionsServices.forEach(section => {
|
||||||
|
section.inputs.forEach(input => {
|
||||||
|
inputValues[input.name] = getInputValue(input);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
stateMainContentForm.subsectionsServices.forEach(section => {
|
||||||
|
section.inputs.forEach(input => {
|
||||||
|
inputValues[input.name] = getInputValue(input);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return inputValues;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getInputValue = (input) => {
|
||||||
|
console.log("getInputValue: ", input);
|
||||||
|
return input.type == "select" && isNumeric(input.value) ? input.options[Number(input.value)].value : input.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isNumeric = (value) => {
|
||||||
|
return !isNaN(Number(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearForm = () => {
|
||||||
|
// Implement form clearing logic here
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
const handleButtonClick = () => {
|
React.useEffect(() => {
|
||||||
const inputsUpdated = dataForm.inputs.map(input => ({
|
initialiseElements();
|
||||||
...input,
|
}, []);
|
||||||
value: 'Default value for input ${input.id}'
|
|
||||||
}));
|
|
||||||
setDataForm({
|
|
||||||
...dataForm,
|
|
||||||
inputs: inputsUpdated
|
|
||||||
});
|
|
||||||
};
|
|
||||||
*/
|
*/
|
||||||
const handleSubmit = () => {
|
|
||||||
};
|
|
||||||
const clearForm = () => {
|
|
||||||
};
|
|
||||||
|
|
||||||
const fillDefaults = () => {
|
|
||||||
/*
|
|
||||||
for (let i = 0; i < valuesDefault.length; i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
// let typeForm = stateTemp.sectionsMainContentForm[0].inputs[0].value == "1" ? "Invoice" : "Estimate";
|
||||||
*/
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit} align="center">
|
<form onSubmit={handleSubmit} align="center">
|
||||||
{stateMainContentForm.sectionsMainContentForm.map(section => (
|
{stateTemp.sectionsMainContentForm.map(section => (
|
||||||
<BlockFormSection key={section.titleSection} data={section} />
|
<BlockFormSection key={section.titleSection} data={section} />
|
||||||
))}
|
))}
|
||||||
{/* <makeSectionsForm data={ {valuesDefault: valuesDefault, placeholdersDefault: placeholdersDefault} } /> */}
|
|
||||||
{typeForm}
|
{typeForm}
|
||||||
{(typeForm == 'Invoice' || typeForm == 'Estimate') &&
|
{(typeForm === 'Invoice' || typeForm === 'Estimate') && (
|
||||||
<ContentFormInvoiceOrEstimate valuesDefault={valuesDefault} placeholdersDefault={placeholdersDefault} handleChangeStateMainContentForm={handleChangeStateMainContentForm} />
|
<ContentFormInvoiceOrEstimate
|
||||||
}
|
stateMainContentForm={stateMainContentForm}
|
||||||
|
// handleChangeStateMainContentForm={setStateMainContentForm}
|
||||||
|
// submitFinalStateMainContentForm={SubmitFinalStateMainContentForm}
|
||||||
|
handleChangeInput={handleChangeInput}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<div>
|
<div>
|
||||||
<button type="button" id="buttonFormClear" onClick={clearForm}>Clear Form</button>
|
<button type="button" id="buttonFormClear" onClick={clearForm}>
|
||||||
<input type="submit" value="Submit" id="buttonFormSubmit"/>
|
Clear Form
|
||||||
|
</button>
|
||||||
|
<input type="submit" value="Submit" id="buttonFormSubmit" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
import * as shared from './scripts/shared.js';
|
||||||
|
|
||||||
const getValuesDefaultFormMetadata = {
|
const getValuesDefaultFormMetadata = {
|
||||||
typeForm: '0',
|
typeForm: '1',
|
||||||
currency: '0',
|
currency: '0',
|
||||||
};
|
};
|
||||||
const getValuesDefaultMyBusiness = {
|
const getValuesDefaultMyBusiness = {
|
||||||
@@ -15,10 +15,10 @@ const getValuesDefaultMyBusiness = {
|
|||||||
address5MyBusiness: 'CV22 7DH',
|
address5MyBusiness: 'CV22 7DH',
|
||||||
};
|
};
|
||||||
const getValuesDefaultMyBusinessBank = {
|
const getValuesDefaultMyBusinessBank = {
|
||||||
bankNameMyBusiness: 'Starling',
|
nameBankMyBusiness: 'Starling',
|
||||||
accountNameMyBusiness: 'Precision And Research Technology Systems Limited',
|
accountNameBankMyBusiness: 'Precision And Research Technology Systems Limited',
|
||||||
accountNumberMyBusiness: '40168366',
|
accountNumberBankMyBusiness: '40168366',
|
||||||
sortCodeMyBusiness: '60-83-71',
|
sortCodeBankMyBusiness: '60-83-71',
|
||||||
};
|
};
|
||||||
const getValuesDefaultTheirBusiness = {
|
const getValuesDefaultTheirBusiness = {
|
||||||
nameTheirBusiness: 'Contechs Technical Resourcing Limited',
|
nameTheirBusiness: 'Contechs Technical Resourcing Limited',
|
||||||
@@ -41,12 +41,9 @@ const getValuesDefaultTheirBusinessContact = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function date2str(date_in) {
|
|
||||||
return date_in.getFullYear().toString() + '-' + (date_in.getMonth() + 1).toString().padStart(2, '0') + '-' + date_in.getDate().toString().padStart(2, '0');
|
|
||||||
}
|
|
||||||
function getDateBilling() {
|
function getDateBilling() {
|
||||||
let nowTime = new Date(Date.now());
|
let nowTime = new Date(Date.now());
|
||||||
return date2str(new Date(nowTime.getFullYear(), nowTime.getMonth(), -1));
|
return shared.date2str(nowTime); // new Date(nowTime.getFullYear(), nowTime.getMonth(), -1));
|
||||||
}
|
}
|
||||||
const getValuesDefaultInvoice = {
|
const getValuesDefaultInvoice = {
|
||||||
dateBillingInvoice: getDateBilling(),
|
dateBillingInvoice: getDateBilling(),
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
@@ -1,8 +1,8 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from 'react-dom/client';
|
||||||
import './index.css';
|
import './styles/index.css';
|
||||||
import App from './App';
|
import App from './pages/App';
|
||||||
import reportWebVitals from './reportWebVitals';
|
import reportWebVitals from './scripts/reportWebVitals';
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||||
root.render(
|
root.render(
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import imageLogo from './Logo.png';
|
import imageLogo from '../content/images/Logo.png';
|
||||||
|
|
||||||
import './App.css';
|
import '../styles/App.css';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
|
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom';
|
||||||
import PageHome from './PageHome';
|
import PageHome from './PageHome';
|
||||||
import InputWrapped from './components/Input';
|
import InputWrapped from '../components/Input';
|
||||||
import methods from './components/MethodsInput';
|
import methods from '../components/MethodsInput';
|
||||||
|
import PageInvoiceOrEstimate from './PageInvoiceOrEstimate';
|
||||||
|
|
||||||
// const makeInputJSON = methods.makeInputJSON;
|
// const makeInputJSON = methods.makeInputJSON;
|
||||||
const makeInputJSON = (dictArgs) => {
|
const makeInputJSON = (dictArgs) => {
|
||||||
return methods.makeInputJSON(dictArgs);
|
return methods.makeInputJSON(dictArgs);
|
||||||
@@ -42,6 +44,7 @@ function App() {
|
|||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<PageHome/>}></Route>
|
<Route path="/" element={<PageHome/>}></Route>
|
||||||
<Route path="/PageHome" component={<PageHome/>}></Route>
|
<Route path="/PageHome" component={<PageHome/>}></Route>
|
||||||
|
<Route path="/PageInvoiceOrEstimate" element={<PageInvoiceOrEstimate />}></Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
{/*
|
{/*
|
||||||
31
src/pages/PageHome.jsx
Normal file
31
src/pages/PageHome.jsx
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import objDefaults from '../config'; // { defaultsMyBusiness, defaultsMyBusinessBank, defaultsTheirBusiness, defaultsTheirBusinessContact }
|
||||||
|
// import MainContentFormWrapper from '../components/MainContentForm';
|
||||||
|
import MainContentForm from '../components/MainContentForm_functional';
|
||||||
|
|
||||||
|
|
||||||
|
class PageHome extends Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
...objDefaults.getValuesDefaultFormMetadata,
|
||||||
|
...objDefaults.getValuesDefaultMyBusiness,
|
||||||
|
...objDefaults.getValuesDefaultMyBusinessBank,
|
||||||
|
...objDefaults.getValuesDefaultTheirBusiness,
|
||||||
|
...objDefaults.getValuesDefaultTheirBusinessContact,
|
||||||
|
...objDefaults.getValuesDefaultInvoice
|
||||||
|
};
|
||||||
|
console.log("global state:", this.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<MainContentForm placeholders={this.state} values={this.state} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PageHome;
|
||||||
354
src/pages/PageInvoiceOrEstimate.jsx
Normal file
354
src/pages/PageInvoiceOrEstimate.jsx
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
import React, { useRef, useEffect } from 'react';
|
||||||
|
import { useLocation } from 'react-router-dom';
|
||||||
|
import imageLogo from '../content/images/Logo.png';
|
||||||
|
import * as shared from '../scripts/shared.js';
|
||||||
|
|
||||||
|
const PageInvoiceOrEstimate = () => {
|
||||||
|
const canvasRefs = useRef([]);
|
||||||
|
const location = useLocation();
|
||||||
|
console.log("location:", location);
|
||||||
|
const props = location.state.data;
|
||||||
|
|
||||||
|
let styles = {
|
||||||
|
container: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
padding: 20,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
logo: {
|
||||||
|
width: 80,
|
||||||
|
height: 80,
|
||||||
|
marginRight: 20,
|
||||||
|
},
|
||||||
|
line: {
|
||||||
|
height: 1,
|
||||||
|
backgroundColor: '#000',
|
||||||
|
marginVertical: 10,
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
backgroundColor: '#E4E4E4',
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
padding: 20,
|
||||||
|
},
|
||||||
|
section: {
|
||||||
|
margin: 10,
|
||||||
|
padding: 10,
|
||||||
|
flexGrow: 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log("PageInvoiceOrEstimate");
|
||||||
|
console.log(props);
|
||||||
|
|
||||||
|
|
||||||
|
const heightA4 = 1123;
|
||||||
|
const widthA4 = 794;
|
||||||
|
const borderPage = 75;
|
||||||
|
const marginTable = 50;
|
||||||
|
const spacingLabel = marginTable - 20;
|
||||||
|
const heightLine = 25;
|
||||||
|
// positioning
|
||||||
|
const heightMyBusiness = 180;
|
||||||
|
const heightIssue = 325;
|
||||||
|
const heightBankMyBusiness = 420;
|
||||||
|
const heightBillToSite = 560;
|
||||||
|
const heightHeadTable = 800;
|
||||||
|
const heightRowMax = 1050; // update this !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
const maxRows = Math.floor((heightRowMax - heightHeadTable - heightLine) / (heightLine + spacingLabel));
|
||||||
|
console.log("maxRows:", maxRows);
|
||||||
|
const xPositionTableColumns = [120, 420, 520, 620];
|
||||||
|
const typeForm = props.typeForm == "1" ? "Invoice" : "Estimate";
|
||||||
|
console.log("typeForm:", typeForm);
|
||||||
|
let countRowsTemp = 0;
|
||||||
|
if (props["type" + typeForm] == "0") {
|
||||||
|
countRowsTemp = props["quantityGoods" + typeForm];
|
||||||
|
} else {
|
||||||
|
for (let indexService = 0; indexService < props["quantityServices" + typeForm]; indexService++) {
|
||||||
|
countRowsTemp += props["quantityBillingPeriodService" + typeForm + (indexService + 1)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const countRows = countRowsTemp;
|
||||||
|
console.log("countRows:", countRows);
|
||||||
|
const countPages = Math.ceil(props["quantityServices" + typeForm] / maxRows);
|
||||||
|
console.log("countPages:", countPages);
|
||||||
|
const nameFont = "Arial";
|
||||||
|
|
||||||
|
const renderCanvases = () => {
|
||||||
|
const canvases = [];
|
||||||
|
for (let indexCanvas = 0; indexCanvas < countPages; indexCanvas++) {
|
||||||
|
canvases.push(
|
||||||
|
<canvas
|
||||||
|
key={indexCanvas}
|
||||||
|
ref={(ref) => (canvasRefs.current[indexCanvas] = ref)}
|
||||||
|
width={widthA4}
|
||||||
|
height={heightA4}
|
||||||
|
style={{ border: '1px solid black', margin: '10px' }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return canvases;
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let hasGoods = props["type" + typeForm] == "0";
|
||||||
|
let hasServices = props["type" + typeForm] == "1";
|
||||||
|
let countGoods = props["quantityGoods" + typeForm];
|
||||||
|
let countServices = props["quantityServices" + typeForm];
|
||||||
|
let indexGoodOrService = -1;
|
||||||
|
let indexSubservice = -1;
|
||||||
|
let indexRow = -1;
|
||||||
|
let pages = [];
|
||||||
|
let page;
|
||||||
|
let isRequiredPageNew = true;
|
||||||
|
while ((hasGoods && indexGoodOrService < countGoods - 1) || (hasServices && indexGoodOrService < countServices && indexRow < countRows - 1)) {
|
||||||
|
if (isRequiredPageNew) {
|
||||||
|
page = {
|
||||||
|
hasServices: hasServices,
|
||||||
|
hasGoods: hasGoods,
|
||||||
|
services: [],
|
||||||
|
goods: [],
|
||||||
|
total: 0,
|
||||||
|
hasTotal: false,
|
||||||
|
};
|
||||||
|
isRequiredPageNew = false;
|
||||||
|
}
|
||||||
|
indexRow++;
|
||||||
|
if (hasGoods) {
|
||||||
|
indexGoodOrService++;
|
||||||
|
let good = {
|
||||||
|
description: props["descriptionGood" + typeForm + (indexGoodOrService + 1)],
|
||||||
|
quantity: props["quantityGood" + typeForm + (indexGoodOrService + 1)],
|
||||||
|
rate: props["rateGood" + typeForm + (indexGoodOrService + 1)],
|
||||||
|
subtotal: props["subtotalGood" + typeForm + (indexGoodOrService + 1)],
|
||||||
|
};
|
||||||
|
page.goods.push(good);
|
||||||
|
page.total += good.subtotal;
|
||||||
|
}
|
||||||
|
if (hasServices) {
|
||||||
|
indexSubservice++;
|
||||||
|
if (indexGoodOrService == -1 || indexSubservice == props["quantityBillingPeriodService" + typeForm + (indexGoodOrService + 1)]) {
|
||||||
|
indexSubservice = -1;
|
||||||
|
indexGoodOrService++;
|
||||||
|
indexRow--;
|
||||||
|
} else {
|
||||||
|
let service = {
|
||||||
|
description: props["descriptionIncrementService" + typeForm + (indexGoodOrService + 1) + "s" + (indexSubservice + 1)],
|
||||||
|
quantity: props["quantityRatePeriodsIncrementService" + typeForm + (indexGoodOrService + 1) + "s" + (indexSubservice + 1)],
|
||||||
|
rate: props["rateService" + typeForm + (indexGoodOrService + 1)],
|
||||||
|
};
|
||||||
|
service["subtotal"] = service.quantity * service.rate;
|
||||||
|
page.services.push(service);
|
||||||
|
page.total += service.subtotal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (indexRow >= maxRows) {
|
||||||
|
indexRow = 0;
|
||||||
|
pages.push(page);
|
||||||
|
isRequiredPageNew = true;
|
||||||
|
}
|
||||||
|
if (indexRow == countRows - 1) {
|
||||||
|
page.hasTotal = true;
|
||||||
|
pages.push(page);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log("pages:", pages);
|
||||||
|
|
||||||
|
|
||||||
|
let indexPage = -1;
|
||||||
|
canvasRefs.current.forEach((canvasRef) => {
|
||||||
|
indexPage++;
|
||||||
|
let page = pages[indexPage];
|
||||||
|
console.log("plotting page:", indexPage, page);
|
||||||
|
const canvas = canvasRef;
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
// Clear the canvas
|
||||||
|
ctx.clearRect(0, 0, widthA4, heightA4);
|
||||||
|
ctx.fillStyle = '#fff';
|
||||||
|
ctx.fillRect(0, 0, widthA4, heightA4);
|
||||||
|
ctx.fillStyle = '#000';
|
||||||
|
|
||||||
|
plot(ctx, page);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const plot = (context, page) => { // typeForm, do_goods, rows_g, n_goods, do_services, rows_s, n_services, n_subs, ratedisc, date_due, my_ref) {
|
||||||
|
plotPageLayout(context);
|
||||||
|
plotPageInterpersonal(context);
|
||||||
|
plotHeadingsTableInvoiceOrEstimate(context);
|
||||||
|
|
||||||
|
let currency = props.currency;
|
||||||
|
|
||||||
|
if (page.hasServices) {
|
||||||
|
context.font = '12px ' + nameFont;
|
||||||
|
// page.services.map((service, index) => {
|
||||||
|
let service;
|
||||||
|
for (let indexService = 0; indexService < page.services.length; indexService++) {
|
||||||
|
service = page.services[indexService];
|
||||||
|
context.fillText(service.description, xPositionTableColumns[0], heightHeadTable + (indexService + 1) * heightLine);
|
||||||
|
context.fillText(service.quantity, xPositionTableColumns[1], heightHeadTable + (indexService + 1) * heightLine);
|
||||||
|
context.fillText(service.rate, xPositionTableColumns[2], heightHeadTable + (indexService + 1) * heightLine);
|
||||||
|
context.fillText(service.subtotal, xPositionTableColumns[3], heightHeadTable + (indexService + 1) * heightLine);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (page.hasGoods) {
|
||||||
|
context.font = '12px ' + nameFont;
|
||||||
|
// page.goods.map((good, index) => {
|
||||||
|
let good;
|
||||||
|
for (let indexGood = 0; indexGood < page.goods.length; indexGood++) {
|
||||||
|
good = page.goods[indexGood];
|
||||||
|
context.fillText(good.description, xPositionTableColumns[0], heightHeadTable + (indexGood + 1) * heightLine);
|
||||||
|
context.fillText(good.quantity, xPositionTableColumns[1], heightHeadTable + (indexGood + 1) * heightLine);
|
||||||
|
context.fillText(good.rate, xPositionTableColumns[2], heightHeadTable + (indexGood + 1) * heightLine);
|
||||||
|
context.fillText(good.subtotal, xPositionTableColumns[3], heightHeadTable + (indexGood + 1) * heightLine);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (page.hasTotal) {
|
||||||
|
context.font = '12px ' + nameFont;
|
||||||
|
let heightRowTotal = heightHeadTable + (1 + (page.hasGoods ? page.goods.length : page.services.length)) * heightLine;
|
||||||
|
console.log("page total: ", page.total);
|
||||||
|
context.fillText(currency + page.total, xPositionTableColumns[3] - 10, heightRowTotal);
|
||||||
|
context.fillText('TOTAL:', xPositionTableColumns[3] - borderPage - 10, heightRowTotal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const plotPageLayout = (context) => {
|
||||||
|
context.beginPath();
|
||||||
|
context.font = '20px ' + nameFont;
|
||||||
|
context.fillText(typeForm, borderPage, 100);
|
||||||
|
// context.fillText('ESTIMATE', borderPage, 100);
|
||||||
|
context.font = 'bold 12px ' + nameFont;
|
||||||
|
context.fillText('BANK NAME:', borderPage, heightBankMyBusiness);
|
||||||
|
context.fillText('ACCOUNT NAME:', borderPage, heightBankMyBusiness + heightLine);
|
||||||
|
context.fillText('ACCOUNT NUMBER:', borderPage, heightBankMyBusiness + heightLine * 2);
|
||||||
|
context.fillText('SORT CODE:', borderPage, heightBankMyBusiness + heightLine * 3);
|
||||||
|
context.font = 'bold 12px ' + nameFont;
|
||||||
|
context.fillText('ISSUE DATE:', widthA4 / 2 + marginTable, heightIssue);
|
||||||
|
context.fillText('DUE DATE:', widthA4 / 2 + marginTable, heightIssue + heightLine);
|
||||||
|
context.fillText('REFERENCE:', widthA4 / 2 + marginTable, heightIssue + heightLine * 2);
|
||||||
|
context.font = 'bold 12px ' + nameFont;
|
||||||
|
context.fillText('BILL TO:', borderPage, heightBillToSite);
|
||||||
|
context.fillText('SITE / LOCATION:', widthA4 / 2 + marginTable, heightBillToSite);
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
const plotPageInterpersonal = (context) => {
|
||||||
|
context.font = '14px ' + nameFont;
|
||||||
|
context.fillText(props.nameMyBusiness, borderPage, heightMyBusiness );
|
||||||
|
context.font = '12px ' + nameFont;
|
||||||
|
context.fillText(props.address1MyBusiness, borderPage, heightMyBusiness + heightLine * 1);
|
||||||
|
context.fillText(props.address2MyBusiness, borderPage, heightMyBusiness + heightLine * 2);
|
||||||
|
context.fillText(props.address3MyBusiness, borderPage, heightMyBusiness + heightLine * 3);
|
||||||
|
context.fillText(props.address4MyBusiness, borderPage, heightMyBusiness + heightLine * 4);
|
||||||
|
context.fillText(props.address5MyBusiness, borderPage, heightMyBusiness + heightLine * 5);
|
||||||
|
context.fillText(props.emailMyBusiness, borderPage, heightMyBusiness + heightLine * 6);
|
||||||
|
context.fillText(props.companyNumberMyBusiness, borderPage, heightMyBusiness + heightLine * 7);
|
||||||
|
|
||||||
|
// logo
|
||||||
|
var img = new Image();
|
||||||
|
img.crossOrigin = "anonymous";
|
||||||
|
// CORS_ALLOW_ALL_ORIGINS = true;
|
||||||
|
img.style.border = 'none';
|
||||||
|
img.src = imageLogo; // "https://raw.githubusercontent.com/Teddy-1024/Neural_Network/master/Deane_logo.png";
|
||||||
|
let sz_img = 200;
|
||||||
|
img.onload = function() {
|
||||||
|
context.drawImage(img, widthA4 - borderPage * 3 / 2 -sz_img, borderPage, sz_img, sz_img); // , 0, 0, 0, 0, borderPage + 25, borderPage + 2, sz_img, sz_img);
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
context.font = '12px ' + nameFont;
|
||||||
|
context.fillText(props.nameBankMyBusiness, borderPage + 150, heightBankMyBusiness);
|
||||||
|
context.fillText(props.accountNameBankMyBusiness, borderPage + 150, heightBankMyBusiness + heightLine);
|
||||||
|
context.fillText(props.accountNumberBankMyBusiness, borderPage + 150, heightBankMyBusiness + heightLine * 2);
|
||||||
|
context.fillText(props.sortCodeBankMyBusiness, borderPage + 150, heightBankMyBusiness + heightLine * 3);
|
||||||
|
|
||||||
|
context.font = '12px ' + nameFont;
|
||||||
|
context.fillText(getDateIssue(), widthA4 / 2 + marginTable + 120, heightIssue);
|
||||||
|
context.fillText(getDateDue(), widthA4 / 2 + marginTable + 120, heightIssue + heightLine);
|
||||||
|
context.fillText(getReference(), widthA4 / 2 + marginTable + 120, heightIssue + heightLine * 2);
|
||||||
|
|
||||||
|
context.font = '12px ' + nameFont;
|
||||||
|
context.fillText(props.nameTheirBusiness, borderPage, heightBillToSite + heightLine * 1);
|
||||||
|
context.fillText(props.address1TheirBusiness, borderPage, heightBillToSite + heightLine * 2);
|
||||||
|
context.fillText(props.address2TheirBusiness, borderPage, heightBillToSite + heightLine * 3);
|
||||||
|
context.fillText(props.address3TheirBusiness, borderPage, heightBillToSite + heightLine * 4);
|
||||||
|
context.fillText(props.address4TheirBusiness, borderPage, heightBillToSite + heightLine * 5);
|
||||||
|
context.fillText(props.address5TheirBusiness, borderPage, heightBillToSite + heightLine * 6);
|
||||||
|
context.fillText(props.emailTheirBusiness, borderPage, heightBillToSite + heightLine * 7);
|
||||||
|
context.fillText(props.phoneTheirBusiness, borderPage, heightBillToSite + heightLine * 8);
|
||||||
|
|
||||||
|
context.fillText(props.nameContactTheirBusiness, widthA4 / 2 + marginTable, heightBillToSite + heightLine * 1);
|
||||||
|
context.fillText(props.address1ContactTheirBusiness, widthA4 / 2 + marginTable, heightBillToSite + heightLine * 2);
|
||||||
|
context.fillText(props.address2ContactTheirBusiness, widthA4 / 2 + marginTable, heightBillToSite + heightLine * 3);
|
||||||
|
context.fillText(props.address3ContactTheirBusiness, widthA4 / 2 + marginTable, heightBillToSite + heightLine * 4);
|
||||||
|
context.fillText(props.address4ContactTheirBusiness, widthA4 / 2 + marginTable, heightBillToSite + heightLine * 5);
|
||||||
|
context.fillText(props.address5ContactTheirBusiness, widthA4 / 2 + marginTable, heightBillToSite + heightLine * 6);
|
||||||
|
context.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
const getDateIssue = () => {
|
||||||
|
let date = new Date(props["dateBilling" + typeForm]);
|
||||||
|
return shared.date2str(new Date(date.getFullYear(), date.getMonth(), -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
const getDateDue = () => {
|
||||||
|
let date_0 = new Date(props.dateBillingInvoice);
|
||||||
|
let y0 = date_0.getFullYear();
|
||||||
|
let m0 = date_0.getMonth();
|
||||||
|
let date_1 = new Date(y0, m0 + 1, 1);
|
||||||
|
let n_working_days = 1;
|
||||||
|
let n_days_total = 4;
|
||||||
|
let date_temp = date_1;
|
||||||
|
for (let i = 1; i < 6; i++) {
|
||||||
|
date_temp.setDate(date_temp.getDate() + 1);
|
||||||
|
let billday = date_temp.getDay();
|
||||||
|
if (!(billday == 0 || billday == 6)) {
|
||||||
|
n_working_days++;
|
||||||
|
}
|
||||||
|
if (n_working_days == n_days_total) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let date_2 = date_temp;
|
||||||
|
return convertDateToString(date_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
const convertDateToString = (date) => {
|
||||||
|
return date.getFullYear().toString() + '-' + (date.getMonth() + 1).toString().padStart(2, '0') + '-' + date.getDate().toString().padStart(2, '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
const getReference = (pageHasGoods) => {
|
||||||
|
let name;
|
||||||
|
if (pageHasGoods) {
|
||||||
|
name = "goods" + convertDateToString(new Date());
|
||||||
|
} else {
|
||||||
|
let week1 = props["idBillingPeriodFirstIncrementalService" + typeForm + "1"];
|
||||||
|
let weekN = String(Number(week1) + Number(props["quantityBillingPeriodService" + typeForm + "1"]) - 1);
|
||||||
|
let year = props["dateBilling" + typeForm].substr(2, 2);// date.getFullYear();
|
||||||
|
name = year + "_wks_" + week1 + "-" + weekN;
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function plotHeadingsTableInvoiceOrEstimate(context) {
|
||||||
|
context.font = 'bold 12px ' + nameFont;
|
||||||
|
context.fillText('DESCRIPTION', xPositionTableColumns[0] + 30, heightHeadTable);
|
||||||
|
context.fillText('QUANTITY', xPositionTableColumns[1] - 20, heightHeadTable);
|
||||||
|
context.fillText('UNIT COST [' + props.currency + ']', xPositionTableColumns[2] - 12, heightHeadTable);
|
||||||
|
context.fillText('SUBTOTAL', xPositionTableColumns[3] - 10, heightHeadTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{renderCanvases()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PageInvoiceOrEstimate;
|
||||||
427
src/pages/PageInvoiceOrEstimate_functional_react-pdf.jsx
Normal file
427
src/pages/PageInvoiceOrEstimate_functional_react-pdf.jsx
Normal file
@@ -0,0 +1,427 @@
|
|||||||
|
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { useNavigate, useLocation } from 'react-router-dom';
|
||||||
|
import { Document } from 'react-pdf';
|
||||||
|
import { Page, View, Text, Image, StyleSheet } from '@react-pdf/renderer';
|
||||||
|
import logo from '../content/images/Logo.png'; // Imp
|
||||||
|
|
||||||
|
const PageInvoiceOrEstimate = () => {
|
||||||
|
const location = useLocation();
|
||||||
|
console.log("location:", location);
|
||||||
|
const props = location.state.data;
|
||||||
|
|
||||||
|
let styles = {
|
||||||
|
container: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
padding: 20,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
logo: {
|
||||||
|
width: 80,
|
||||||
|
height: 80,
|
||||||
|
marginRight: 20,
|
||||||
|
},
|
||||||
|
line: {
|
||||||
|
height: 1,
|
||||||
|
backgroundColor: '#000',
|
||||||
|
marginVertical: 10,
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
backgroundColor: '#E4E4E4',
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
padding: 20,
|
||||||
|
},
|
||||||
|
section: {
|
||||||
|
margin: 10,
|
||||||
|
padding: 10,
|
||||||
|
flexGrow: 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log("PageInvoiceOrEstimate");
|
||||||
|
console.log(props);
|
||||||
|
|
||||||
|
|
||||||
|
let heightA4 = 1123;
|
||||||
|
let widthA4 = 794;
|
||||||
|
let borderPage = 75;
|
||||||
|
let marginTable = 50;
|
||||||
|
let spacingLabel = marginTable - 20;
|
||||||
|
let heightLine = 25;
|
||||||
|
// positioning
|
||||||
|
let heightMyBusiness = 180;
|
||||||
|
let heightIssue = 325;
|
||||||
|
let heightBankMyBusiness = 420;
|
||||||
|
let heightBillToSite = 560;
|
||||||
|
let heightHeadTable = 800;
|
||||||
|
let heightRowMax = 1050; // update this !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
let maxRows = Math.floor((heightRowMax - heightHeadTable - heightLine) / (heightLine + spacingLabel));
|
||||||
|
console.log("maxRows:", maxRows);
|
||||||
|
let xPositionTableColumns = [120, 420, 520, 620];
|
||||||
|
let typeForm = props.typeForm == "1" ? "Invoice" : "Estimate";
|
||||||
|
console.log("typeForm:", typeForm);
|
||||||
|
let countRows = Math.ceil(props["type" + typeForm] == "0" ? props["quantityGoods" + typeForm] : props["quantityServices" + typeForm]);
|
||||||
|
let countPages = Math.ceil(props["quantityServices" + typeForm] / maxRows);
|
||||||
|
console.log("countPages:", countPages);
|
||||||
|
|
||||||
|
let pages = [];
|
||||||
|
for (let indexPage = 0; indexPage < countPages; indexPage++) {
|
||||||
|
let page = {
|
||||||
|
hasServices: props["type" + typeForm] == "1",
|
||||||
|
hasGoods: props["type" + typeForm] == "0",
|
||||||
|
services: [],
|
||||||
|
goods: [],
|
||||||
|
total: 0,
|
||||||
|
};
|
||||||
|
if (page.hasServices) {
|
||||||
|
for (let indexService = 0; indexService < maxRows; indexService++) {
|
||||||
|
let indexData = indexPage * maxRows + indexService;
|
||||||
|
if (indexData < props["quantityServices" + typeForm]) {
|
||||||
|
let service = {
|
||||||
|
description: props["descriptionService" + typeForm + indexData],
|
||||||
|
quantity: props["quantityService" + typeForm + indexData],
|
||||||
|
rate: props["rateService" + typeForm + indexData],
|
||||||
|
subtotal: props["subtotalService" + typeForm + indexData],
|
||||||
|
};
|
||||||
|
page.services.push(service);
|
||||||
|
page.total += service.subtotal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (page.hasGoods) {
|
||||||
|
for (let indexGood = 0; indexGood < maxRows; indexGood++) {
|
||||||
|
let indexData = indexPage * maxRows + indexGood;
|
||||||
|
if (indexData < props["quantityGoods" + typeForm]) {
|
||||||
|
let good = {
|
||||||
|
description: props["descriptionGood" + typeForm + indexData],
|
||||||
|
quantity: props["quantityGood" + typeForm + indexData],
|
||||||
|
rate: props["rateGood" + typeForm + indexData],
|
||||||
|
subtotal: props["subtotalGood" + typeForm + indexData],
|
||||||
|
};
|
||||||
|
page.goods.push(good);
|
||||||
|
page.total += good.subtotal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pages.push(page);
|
||||||
|
}
|
||||||
|
console.log("pages:", pages);
|
||||||
|
|
||||||
|
let currency = props.currency;
|
||||||
|
let dateDue = props.dateDue;
|
||||||
|
let reference = props.reference;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Document>
|
||||||
|
{pages.map((page, index) => {
|
||||||
|
console.log("outputting page: ", index);
|
||||||
|
return (
|
||||||
|
<Page size="A4" style={styles.page} key={"page" + index} >
|
||||||
|
<Text style={{
|
||||||
|
...styles.heading,
|
||||||
|
top: 100,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{typeForm.toUpperCase()}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBankMyBusiness,
|
||||||
|
left: borderPage,
|
||||||
|
}}>BANK NAME:</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBankMyBusiness + heightLine,
|
||||||
|
left: borderPage,
|
||||||
|
}}>ACCOUNT NAME:</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBankMyBusiness + heightLine * 2,
|
||||||
|
left: borderPage,
|
||||||
|
}}>ACCOUNT NUMBER:</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBankMyBusiness + heightLine * 2,
|
||||||
|
left: borderPage,
|
||||||
|
}}>SORT CODE:</Text>
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightIssue,
|
||||||
|
left: borderPage,
|
||||||
|
}}>ISSUE DATE:</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightIssue + heightLine,
|
||||||
|
left: borderPage,
|
||||||
|
}}>DUE DATE:</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightIssue + heightLine * 2,
|
||||||
|
left: borderPage,
|
||||||
|
}}>REFERENCE:</Text>
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite,
|
||||||
|
left: borderPage,
|
||||||
|
}}>BILL TO:</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite + heightLine,
|
||||||
|
left: borderPage,
|
||||||
|
}}>SITE / LOCATION:</Text>
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...styles.subheading,
|
||||||
|
top: heightMyBusiness,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.nameMyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightMyBusiness + heightLine,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.address1MyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightMyBusiness + heightLine * 2,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.address2MyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightMyBusiness + heightLine * 3,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.address3MyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightMyBusiness + heightLine * 4,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.address4MyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightMyBusiness + heightLine * 5,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.address5MyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightMyBusiness + heightLine * 6,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.emailMyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightMyBusiness + heightLine * 7,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.companyNumberMyBusiness}</Text>
|
||||||
|
|
||||||
|
<Image style={styles.logo} src={logo} />
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBankMyBusiness,
|
||||||
|
left: borderPage + 150,
|
||||||
|
}}>{props.nameBankMyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBankMyBusiness + heightLine,
|
||||||
|
left: borderPage + 150,
|
||||||
|
}}>{props.accountNameBankMyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBankMyBusiness + heightLine * 2,
|
||||||
|
left: borderPage + 150,
|
||||||
|
}}>{props.accountNumberBankMyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBankMyBusiness + heightLine * 3,
|
||||||
|
left: borderPage + 150,
|
||||||
|
}}>{props.sortCodeBankMyBusiness}</Text>
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightIssue,
|
||||||
|
left: widthA4 / 2 + marginTable + 120,
|
||||||
|
}}>{props.date}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightIssue + heightLine,
|
||||||
|
left: widthA4 / 2 + marginTable + 120,
|
||||||
|
}}>{dateDue}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightIssue + heightLine * 2,
|
||||||
|
left: widthA4 / 2 + marginTable + 120,
|
||||||
|
}}>{reference}</Text>
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite + heightLine,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.nameTheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 2,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.address1TheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 3,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.address1TheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 4,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.address1TheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 5,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.address1TheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 6,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.address1TheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 7,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.emailTheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 8,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{props.phoneNumberTheirBusiness}</Text>
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite + heightLine,
|
||||||
|
left: widthA4 / 2 + marginTable,
|
||||||
|
}}>{props.nameContactTheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 2,
|
||||||
|
left: widthA4 / 2 + marginTable,
|
||||||
|
}}>{props.address1ContactTheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 3,
|
||||||
|
left: widthA4 / 2 + marginTable,
|
||||||
|
}}>{props.address2ContactTheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 4,
|
||||||
|
left: widthA4 / 2 + marginTable,
|
||||||
|
}}>{props.address3ContactTheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 5,
|
||||||
|
left: widthA4 / 2 + marginTable,
|
||||||
|
}}>{props.address4ContactTheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 6,
|
||||||
|
left: widthA4 / 2 + marginTable,
|
||||||
|
}}>{props.address4ContactTheirBusiness}</Text>
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightHeadTable + heightLine,
|
||||||
|
left: xPositionTableColumns[0] + 30,
|
||||||
|
}}>DESCRIPTION</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[1] - 20,
|
||||||
|
}}>QUANTITY</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[2] - 12,
|
||||||
|
}}>{"UNIT COST [" + currency + "]"}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[3] - 10,
|
||||||
|
}}>SUBTOTAL</Text>
|
||||||
|
|
||||||
|
{(page.hasServices) && page.services.map((service, index) => {
|
||||||
|
return (
|
||||||
|
<View key={"services" + index} >
|
||||||
|
<Text key={"services" + index + "0"} style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[0],
|
||||||
|
}}>{service.description}</Text>
|
||||||
|
<Text key={"services" + index + "1"} style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[1],
|
||||||
|
}}>{service.quantity}</Text>
|
||||||
|
<Text key={"services" + index + "2"} style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[2],
|
||||||
|
}}>{service.rate}</Text>
|
||||||
|
<Text key={"services" + index + "3"} style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[3],
|
||||||
|
}}>{service.subtotal}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{(page.hasGoods) && page.goods.map((good, index) => {
|
||||||
|
return (
|
||||||
|
<View key={"goods" + index} >
|
||||||
|
<Text key={"goods" + index + "0"} style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[0],
|
||||||
|
}}>{good.description}</Text>
|
||||||
|
<Text key={"goods" + index + "1"} style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[1],
|
||||||
|
}}>{good.quantity}</Text>
|
||||||
|
<Text key={"goods" + index + "2"} style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[2],
|
||||||
|
}}>{good.rate}</Text>
|
||||||
|
<Text key={"goods" + index + "3"} style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[3],
|
||||||
|
}}>{good.subtotal}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
{(page.hasTotal) && (
|
||||||
|
<View key={"total" + index} >
|
||||||
|
<Text key={"total" + index + "0"} style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[3] - 10,
|
||||||
|
}}>{currency + page.total}</Text>
|
||||||
|
<Text key={"total" + index + "1"} style={{
|
||||||
|
...styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[3] - borderPage - 10,
|
||||||
|
}}>TOTAL:</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Document>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PageInvoiceOrEstimate;
|
||||||
429
src/pages/PageInvoiceOrEstimate_react-pdf.jsx
Normal file
429
src/pages/PageInvoiceOrEstimate_react-pdf.jsx
Normal file
@@ -0,0 +1,429 @@
|
|||||||
|
import React, { Component } from 'react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { Document, Page, View, Text, Image, StyleSheet } from '@react-pdf/renderer';
|
||||||
|
import logo from '../content/images/Logo.png'; // Imp
|
||||||
|
|
||||||
|
function PageInvoiceOrEstimateWrapper(props) {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
console.log("PageInvoiceOrEstimateWrapper");
|
||||||
|
console.log(props);
|
||||||
|
return <PageInvoiceOrEstimate navigate={navigate} state={props.state} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PageInvoiceOrEstimate extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.styles = {
|
||||||
|
container: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
padding: 20,
|
||||||
|
},
|
||||||
|
header: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginBottom: 20,
|
||||||
|
},
|
||||||
|
logo: {
|
||||||
|
width: 80,
|
||||||
|
height: 80,
|
||||||
|
marginRight: 20,
|
||||||
|
},
|
||||||
|
line: {
|
||||||
|
height: 1,
|
||||||
|
backgroundColor: '#000',
|
||||||
|
marginVertical: 10,
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
backgroundColor: '#E4E4E4',
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
padding: 20,
|
||||||
|
},
|
||||||
|
section: {
|
||||||
|
margin: 10,
|
||||||
|
padding: 10,
|
||||||
|
flexGrow: 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log("PageInvoiceOrEstimate");
|
||||||
|
console.log(this.props);
|
||||||
|
console.log(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
console.log("PageInvoiceOrEstimate");
|
||||||
|
console.log(this.props);
|
||||||
|
let heightA4 = 1123;
|
||||||
|
let widthA4 = 794;
|
||||||
|
let borderPage = 75;
|
||||||
|
let marginTable = 50;
|
||||||
|
let spacingLabel = marginTable - 20;
|
||||||
|
let heightLine = 25;
|
||||||
|
// positioning
|
||||||
|
let heightMyBusiness = 180;
|
||||||
|
let heightIssue = 325;
|
||||||
|
let heightBankMyBusiness = 420;
|
||||||
|
let heightBillToSite = 560;
|
||||||
|
let heightHeadTable = 800;
|
||||||
|
let heightRowMax = 1050; // update this !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
let maxRows = Math.floor((heightRowMax - heightHeadTable - heightLine) / (heightLine + spacingLabel));
|
||||||
|
let xPositionTableColumns = [120, 420, 520, 620];
|
||||||
|
let typeForm = this.props.data.sectionsMainContentForm[0].inputs[0].value;
|
||||||
|
console.log("typeForm:", typeForm);
|
||||||
|
let countRows = Math.ceil(this.props.data["type" + typeForm] == "0" ? this.props.data["quantityGoods" + typeForm] : this.props.data["quantityServices" + typeForm]);
|
||||||
|
let countPages = Math.ceil(this.props.data["quantityServices" + typeForm] / maxRows);
|
||||||
|
|
||||||
|
let pages = [];
|
||||||
|
for (let indexPage = 0; indexPage < countPages; indexPage++) {
|
||||||
|
let page = {
|
||||||
|
hasServices: this.props.data["type" + typeForm] == "1",
|
||||||
|
hasGoods: this.props.data["type" + typeForm] == "0",
|
||||||
|
services: [],
|
||||||
|
goods: [],
|
||||||
|
total: 0,
|
||||||
|
};
|
||||||
|
if (page.hasServices) {
|
||||||
|
for (let indexService = 0; indexService < maxRows; indexService++) {
|
||||||
|
let indexData = indexPage * maxRows + indexService;
|
||||||
|
if (indexData < this.props.data["quantityServices" + typeForm]) {
|
||||||
|
let service = {
|
||||||
|
description: this.props.data["descriptionService" + typeForm + indexData],
|
||||||
|
quantity: this.props.data["quantityService" + typeForm + indexData],
|
||||||
|
rate: this.props.data["rateService" + typeForm + indexData],
|
||||||
|
subtotal: this.props.data["subtotalService" + typeForm + indexData],
|
||||||
|
};
|
||||||
|
page.services.push(service);
|
||||||
|
page.total += service.subtotal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (page.hasGoods) {
|
||||||
|
for (let indexGood = 0; indexGood < maxRows; indexGood++) {
|
||||||
|
let indexData = indexPage * maxRows + indexGood;
|
||||||
|
if (indexData < this.props.data["quantityGoods" + typeForm]) {
|
||||||
|
let good = {
|
||||||
|
description: this.props.data["descriptionGood" + typeForm + indexData],
|
||||||
|
quantity: this.props.data["quantityGood" + typeForm + indexData],
|
||||||
|
rate: this.props.data["rateGood" + typeForm + indexData],
|
||||||
|
subtotal: this.props.data["subtotalGood" + typeForm + indexData],
|
||||||
|
};
|
||||||
|
page.goods.push(good);
|
||||||
|
page.total += good.subtotal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pages.push(page);
|
||||||
|
}
|
||||||
|
let currency = this.props.data.currency;
|
||||||
|
let dateDue = this.props.data.dateDue;
|
||||||
|
let reference = this.props.data.reference;
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Document>
|
||||||
|
{pages.map((page, index) => {
|
||||||
|
return (
|
||||||
|
<Page size="A4" style={this.styles.page}>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.heading,
|
||||||
|
top: 100,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{typeForm.toUpper()}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBankMyBusiness,
|
||||||
|
left: borderPage,
|
||||||
|
}}>BANK NAME:</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBankMyBusiness + heightLine,
|
||||||
|
left: borderPage,
|
||||||
|
}}>ACCOUNT NAME:</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBankMyBusiness + heightLine * 2,
|
||||||
|
left: borderPage,
|
||||||
|
}}>ACCOUNT NUMBER:</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBankMyBusiness + heightLine * 2,
|
||||||
|
left: borderPage,
|
||||||
|
}}>SORT CODE:</Text>
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightIssue,
|
||||||
|
left: borderPage,
|
||||||
|
}}>ISSUE DATE:</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightIssue + heightLine,
|
||||||
|
left: borderPage,
|
||||||
|
}}>DUE DATE:</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightIssue + heightLine * 2,
|
||||||
|
left: borderPage,
|
||||||
|
}}>REFERENCE:</Text>
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite,
|
||||||
|
left: borderPage,
|
||||||
|
}}>BILL TO:</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite + heightLine,
|
||||||
|
left: borderPage,
|
||||||
|
}}>SITE / LOCATION:</Text>
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.subheading,
|
||||||
|
top: heightMyBusiness,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.nameMyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightMyBusiness + heightLine,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.address1MyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightMyBusiness + heightLine * 2,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.address2MyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightMyBusiness + heightLine * 3,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.address3MyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightMyBusiness + heightLine * 4,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.address4MyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightMyBusiness + heightLine * 5,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.address5MyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightMyBusiness + heightLine * 6,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.emailMyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightMyBusiness + heightLine * 7,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.companyNumberMyBusiness}</Text>
|
||||||
|
|
||||||
|
<Image style={this.styles.logo} src={logo} />
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBankMyBusiness,
|
||||||
|
left: borderPage + 150,
|
||||||
|
}}>{this.state.nameBankMyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBankMyBusiness + heightLine,
|
||||||
|
left: borderPage + 150,
|
||||||
|
}}>{this.state.accountNameBankMyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBankMyBusiness + heightLine * 2,
|
||||||
|
left: borderPage + 150,
|
||||||
|
}}>{this.state.accountNumberBankMyBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBankMyBusiness + heightLine * 3,
|
||||||
|
left: borderPage + 150,
|
||||||
|
}}>{this.state.sortCodeBankMyBusiness}</Text>
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightIssue,
|
||||||
|
left: widthA4 / 2 + marginTable + 120,
|
||||||
|
}}>{this.state.date}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightIssue + heightLine,
|
||||||
|
left: widthA4 / 2 + marginTable + 120,
|
||||||
|
}}>{dateDue}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightIssue + heightLine * 2,
|
||||||
|
left: widthA4 / 2 + marginTable + 120,
|
||||||
|
}}>{reference}</Text>
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite + heightLine,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.nameTheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 2,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.address1TheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 3,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.address1TheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 4,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.address1TheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 5,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.address1TheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 6,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.address1TheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 7,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.emailTheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 8,
|
||||||
|
left: borderPage,
|
||||||
|
}}>{this.state.phoneNumberTheirBusiness}</Text>
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite + heightLine,
|
||||||
|
left: widthA4 / 2 + marginTable,
|
||||||
|
}}>{this.state.nameContactTheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 2,
|
||||||
|
left: widthA4 / 2 + marginTable,
|
||||||
|
}}>{this.state.address1ContactTheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 3,
|
||||||
|
left: widthA4 / 2 + marginTable,
|
||||||
|
}}>{this.state.address2ContactTheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 4,
|
||||||
|
left: widthA4 / 2 + marginTable,
|
||||||
|
}}>{this.state.address3ContactTheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 5,
|
||||||
|
left: widthA4 / 2 + marginTable,
|
||||||
|
}}>{this.state.address4ContactTheirBusiness}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightBillToSite + heightLine * 6,
|
||||||
|
left: widthA4 / 2 + marginTable,
|
||||||
|
}}>{this.state.address4ContactTheirBusiness}</Text>
|
||||||
|
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightHeadTable + heightLine,
|
||||||
|
left: xPositionTableColumns[0] + 30,
|
||||||
|
}}>DESCRIPTION</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[1] - 20,
|
||||||
|
}}>QUANTITY</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[2] - 12,
|
||||||
|
}}>{"UNIT COST [" + currency + "]"}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[3] - 10,
|
||||||
|
}}>SUBTOTAL</Text>
|
||||||
|
|
||||||
|
{(page.hasServices) && page.services.map((service, index) => {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[0],
|
||||||
|
}}>{service.description}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[1],
|
||||||
|
}}>{service.quantity}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[2],
|
||||||
|
}}>{service.rate}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[3],
|
||||||
|
}}>{service.subtotal}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{(page.hasGoods) && page.goods.map((good, index) => {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[0],
|
||||||
|
}}>{good.description}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[1],
|
||||||
|
}}>{good.quantity}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[2],
|
||||||
|
}}>{good.rate}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[3],
|
||||||
|
}}>{good.subtotal}</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
{(page.hasTotal) && (
|
||||||
|
<View>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[3] - 10,
|
||||||
|
}}>{currency + page.total}</Text>
|
||||||
|
<Text style={{
|
||||||
|
...this.styles.label,
|
||||||
|
top: heightHeadTable,
|
||||||
|
left: xPositionTableColumns[3] - borderPage - 10,
|
||||||
|
}}>TOTAL:</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</Page>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Document>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PageInvoiceOrEstimateWrapper;
|
||||||
3
src/scripts/shared.js
Normal file
3
src/scripts/shared.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function date2str(date) {
|
||||||
|
return date.getFullYear().toString() + '-' + (date.getMonth() + 1).toString().padStart(2, '0') + '-' + date.getDate().toString().padStart(2, '0');
|
||||||
|
}
|
||||||
@@ -22,15 +22,16 @@ div {
|
|||||||
input, button {
|
input, button {
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
height: 4vh;
|
height: 4vh;
|
||||||
width: 20vw;
|
width: 30vw;
|
||||||
border-radius: 1vh;
|
border-radius: 1vh;
|
||||||
border-color: darkviolet;
|
border-color: darkviolet;
|
||||||
padding: 3px 10px 3px;
|
padding: 3px 10px 3px;
|
||||||
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
height: 3vh;
|
height: 3vh;
|
||||||
width: 100px;
|
width: 15vw;
|
||||||
border-radius: 1vh;
|
border-radius: 1vh;
|
||||||
border-width: 2px;
|
border-width: 2px;
|
||||||
border-color: darkviolet;
|
border-color: darkviolet;
|
||||||
@@ -57,7 +58,7 @@ input[type="number"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
input[type="date"] {
|
input[type="date"] {
|
||||||
width: 8vw;
|
width: 15vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="checkbox"] {
|
input[type="checkbox"] {
|
||||||
@@ -87,6 +88,19 @@ input[type="checkbox"]:checked:before {
|
|||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.container-input::after {
|
||||||
|
content: "";
|
||||||
|
display: table;
|
||||||
|
clear: both;
|
||||||
|
height: 0.25vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section::after {
|
||||||
|
content: "";
|
||||||
|
display: table;
|
||||||
|
clear: both;
|
||||||
|
height: 2.5vh;
|
||||||
|
}
|
||||||
|
|
||||||
/* Labels */
|
/* Labels */
|
||||||
label {
|
label {
|
||||||
@@ -94,11 +108,11 @@ label {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.div_title {
|
.div_title {
|
||||||
font-size: 24px;
|
font-size: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input_title {
|
.input_title {
|
||||||
font-size: 20px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input_subtitle {
|
.input_subtitle {
|
||||||
@@ -128,6 +142,7 @@ label {
|
|||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.input_label.label_title {
|
.input_label.label_title {
|
||||||
@@ -143,8 +158,8 @@ label {
|
|||||||
}
|
}
|
||||||
|
|
||||||
label.input_label {
|
label.input_label {
|
||||||
padding-left: 5% !important;
|
padding-left: 0% !important;
|
||||||
padding-right: 5% !important;
|
padding-right: 2.5% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.column {
|
.column {
|
||||||
@@ -153,3 +168,4 @@ label.input_label {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { render, screen } from '@testing-library/react';
|
import { render, screen } from '@testing-library/react';
|
||||||
import App from './App';
|
import App from '../pages/App';
|
||||||
|
|
||||||
test('renders learn react link', () => {
|
test('renders learn react link', () => {
|
||||||
render(<App />);
|
render(<App />);
|
||||||
@@ -180,9 +180,6 @@ function plot_table_headings_invest(ratedisc, h, page_i) {
|
|||||||
ctxs[i].fillText('# ' + ratedisc[1], w_tc2 - 20, h);
|
ctxs[i].fillText('# ' + ratedisc[1], w_tc2 - 20, h);
|
||||||
}
|
}
|
||||||
ctxs[i].fillText('SUBTOTAL', w_tc4-10, h);
|
ctxs[i].fillText('SUBTOTAL', w_tc4-10, h);
|
||||||
// latinum conversion rates
|
|
||||||
// 500 .bars, 10,000 .strips, 1,000,000 .slips
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function plot_subtotal(tot, h, page_i) {
|
function plot_subtotal(tot, h, page_i) {
|
||||||
|
|||||||
Reference in New Issue
Block a user