diff --git a/Jenkinsfile b/Jenkinsfile index e1215375e..754b7a288 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -15,7 +15,7 @@ pipeline { stage('Checkout') { steps { script { - env.COMPOSE_PROJECT_NAME = env.JOB_NAME.replace('/', '-'); + env.COMPOSE_PROJECT_NAME = env.JOB_NAME.replace('/', '-') env.GIT_COMMITTER_EMAIL = sh( script: 'git --no-pager show -s --format="%ae"', returnStdout: true @@ -24,21 +24,24 @@ pipeline { switch (env.BRANCH_NAME) { case 'master': env.PORT = 5002 - break; - case 'test': + break + case 'test': env.PORT = 5001 - break; + break + case 'test': + env.PORT = 5000 + break } switch (env.BRANCH_NAME) { case 'master': env.NODE_ENV = 'production' - break; - case 'test': + break + case 'test': env.NODE_ENV = 'test' - break; + break case 'dev': env.NODE_ENV = 'development' - break; + break } } echo "Committer: ${env.GIT_COMMITTER_EMAIL}" @@ -57,7 +60,7 @@ pipeline { } stage('Test') { when { - branch 'dev'; + branch 'dev' } environment { NODE_ENV = "" @@ -67,7 +70,7 @@ pipeline { steps { nodejs('node-lts') { sh 'karma start --junit' - sh 'gulp backTestDocker --junit --random --run-chown' + sh 'gulp backTestDockerOnce --junit --random --run-chown' } } } diff --git a/e2e/helpers/extensions.js b/e2e/helpers/extensions.js index e311df432..958c92d02 100644 --- a/e2e/helpers/extensions.js +++ b/e2e/helpers/extensions.js @@ -441,6 +441,31 @@ let actions = { .waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`) .then(done) .catch(done); + }, + + checkboxState: function(selector, done) { + this.wait(selector) + .evaluate(checkboxSelector => { + return document.querySelector(checkboxSelector).getAttribute('class'); + }, selector) + .then(elementClass => { + let classList = elementClass.split(' '); + let className; + + if (classList.includes('md-checked')) + className = 'checked'; + if (classList.includes('md-intermediate')) + className = 'intermediate'; + if (!classList.includes('md-intermediate') && !classList.includes('md-checked')) + className = 'unchecked'; + + if (!className) + throw new Error(`selector: ${selector} is not a md-checkbox`); + + done(null, className); + }) + .then(done) + .catch(done); } }; diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 941c86038..77ecc3867 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -57,34 +57,29 @@ export default { fiscalDataButton: `vn-left-menu a[ui-sref="client.card.fiscalData"]`, socialNameInput: `${components.vnTextfield}[name="socialName"]`, fiscalIdInput: `${components.vnTextfield}[name="fi"]`, - equalizationTaxCheckboxLabel: `vn-check[label='Is equalizated'] > label > input`, + equalizationTaxCheckbox: `vn-check[label='Is equalizated'] md-checkbox`, acceptPropagationButton: `vn-client-fiscal-data > vn-confirm button[response=ACCEPT]`, addressInput: `${components.vnTextfield}[name="street"]`, cityInput: `${components.vnTextfield}[name="city"]`, postcodeInput: `${components.vnTextfield}[name="postcode"]`, provinceAutocomplete: `vn-autocomplete[field="$ctrl.client.provinceFk"]`, countryAutocomplete: `vn-autocomplete[field="$ctrl.client.countryFk"]`, - activeCheckboxLabel: `vn-check[label="Active"] > label`, - activeCheckboxInput: `vn-check[label="Active"] input`, - frozenCheckboxLabel: `vn-check[label="Frozen"] > label`, - frozenCheckboxInput: `vn-check[label="Frozen"] input`, - invoiceByAddressCheckboxInput: `vn-check[label='Invoice by address'] > label > input`, - verifiedDataCheckbox: `vn-check[label="Verified data"] input`, - verifiedDataCheckboxInput: `vn-check[label="Verified data"] > label > input`, - hasToInvoiceCheckboxLabel: `vn-check[label='Has to invoice'] > label`, - hasToInvoiceCheckboxInput: `vn-check[label='Has to invoice'] input`, - invoiceByMailCheckboxLabel: `vn-check[label='Invoice by mail'] > label`, - invoiceByMailCheckboxInput: `vn-check[label='Invoice by mail'] input`, - viesCheckboxInput: `vn-check[label='Vies'] > label > input`, + activeCheckbox: `vn-check[label="Active"] md-checkbox`, + frozenCheckbox: `vn-check[label="Frozen"] md-checkbox`, + invoiceByAddressCheckbox: `vn-check[label='Invoice by address'] md-checkbox`, + verifiedDataCheckbox: `vn-check[label="Verified data"] md-checkbox`, + hasToInvoiceCheckbox: `vn-check[label='Has to invoice'] md-checkbox`, + invoiceByMailCheckbox: `vn-check[label='Invoice by mail'] md-checkbox`, + viesCheckbox: `vn-check[label='Vies'] md-checkbox`, saveButton: `${components.vnSubmit}` }, clientPayMethod: { payMethodAutocomplete: `vn-autocomplete[field="$ctrl.client.payMethodFk"]`, IBANInput: `${components.vnTextfield}[name="iban"]`, dueDayInput: `${components.vnTextfield}[name="dueDay"]`, - receivedCoreLCRCheckbox: `vn-check[label='Received LCR'] > label > input`, - receivedCoreVNLCheckbox: `vn-check[label='Received core VNL'] > label > input`, - receivedB2BVNLCheckbox: `vn-check[label='Received B2B VNL'] > label > input`, + receivedCoreLCRCheckbox: `vn-check[label='Received LCR'] md-checkbox`, + receivedCoreVNLCheckbox: `vn-check[label='Received core VNL'] md-checkbox`, + receivedB2BVNLCheckbox: `vn-check[label='Received B2B VNL'] md-checkbox`, swiftBicAutocomplete: 'vn-client-billing-data vn-autocomplete[field="$ctrl.client.bankEntityFk"]', clearswiftBicButton: `vn-client-billing-data vn-autocomplete[field="$ctrl.client.bankEntityFk"] > div > div > div > vn-icon > i`, newBankEntityButton: 'vn-client-billing-data vn-icon-button[vn-tooltip="New bank entity"] > button', @@ -96,7 +91,7 @@ export default { clientAddresses: { addressesButton: `vn-left-menu a[ui-sref="client.card.address.index"]`, createAddress: `vn-client-address-index ${components.vnFloatButton}`, - defaultCheckboxInput: `vn-check[label='Default'] > label > input`, + defaultCheckboxInput: `vn-check[label='Default'] md-checkbox`, consigneeInput: `${components.vnTextfield}[name="nickname"]`, streetAddressInput: `${components.vnTextfield}[name="street"]`, postcodeInput: `${components.vnTextfield}[name="postalCode"]`, @@ -109,8 +104,8 @@ export default { secondMakeDefaultStar: 'vn-client-address-index vn-card vn-horizontal:nth-child(2) vn-icon-button[icon="star_border"]', firstEditButton: `vn-client-address-index vn-icon-button[icon='edit']`, secondEditButton: `vn-client-address-index vn-horizontal:nth-child(2) vn-icon-button[icon='edit']`, - activeCheckbox: `vn-check[label='Enabled'] > label > input`, - equalizationTaxCheckboxLabel: `vn-client-address-edit vn-check[label='Is equalizated'] > label > input`, + activeCheckbox: `vn-check[label='Enabled'] md-checkbox`, + equalizationTaxCheckbox: `vn-client-address-edit vn-check[label="Is equalizated"] md-checkbox`, firstObservationTypeAutocomplete: `vn-client-address-edit [name=observations] :nth-child(1) [field="observation.observationTypeFk"]`, firstObservationDescriptionInput: `vn-client-address-edit [name=observations] :nth-child(1) [model="observation.description"] input`, secondObservationTypeAutocomplete: `vn-client-address-edit [name=observations] :nth-child(2) [field="observation.observationTypeFk"]`, @@ -122,7 +117,7 @@ export default { }, clientWebAccess: { webAccessButton: `vn-left-menu a[ui-sref="client.card.webAccess"]`, - enableWebAccessCheckbox: `vn-check[label='Enable web access'] > label > input`, + enableWebAccessCheckbox: `vn-check[label='Enable web access'] md-checkbox`, userNameInput: `${components.vnTextfield}[name="name"]`, saveButton: `${components.vnSubmit}` }, @@ -205,7 +200,7 @@ export default { originAutocomplete: `vn-autocomplete[field="$ctrl.item.originFk"]`, expenceAutocomplete: `vn-autocomplete[field="$ctrl.item.expenceFk"]`, longNameInput: `vn-textfield[field="$ctrl.item.longName"] input`, - isActiveCheckbox: `vn-check[label='Active'] > label > input`, + isActiveCheckbox: `vn-check[label='Active'] md-checkbox`, submitBasicDataButton: `${components.vnSubmit}` }, itemTags: { @@ -350,7 +345,7 @@ export default { firstSaleReservedIcon: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td:nth-child(2) > vn-icon:nth-child(3)', firstSaleColour: `vn-ticket-sale vn-tr:nth-child(1) vn-td:nth-child(5) section:nth-child(1)`, firstSaleLength: `vn-ticket-sale vn-tr:nth-child(1) vn-td:nth-child(5) section:nth-child(3)`, - firstSaleCheckbox: `vn-ticket-sale vn-tr:nth-child(1) vn-check[field="sale.checked"] label`, + firstSaleCheckbox: `vn-ticket-sale vn-tr:nth-child(1) vn-check[field="sale.checked"] md-checkbox`, secondSaleClaimIcon: 'vn-ticket-sale > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(2) > a > vn-icon', secondSaleColour: `vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(5) section:nth-child(5)`, secondSalePrice: `vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(7)`, @@ -358,9 +353,9 @@ export default { secondSaleImport: `vn-ticket-sale vn-tr:nth-child(2) vn-td:nth-child(9)`, secondSaleText: `vn-table div > vn-tbody > vn-tr:nth-child(2)`, totalImport: 'vn-ticket-sale > vn-vertical > vn-card > div > vn-vertical > vn-horizontal > vn-one > p:nth-child(3) > strong', - selectAllSalesCheckbox: `vn-ticket-sale vn-thead vn-check label`, - secondSaleCheckbox: `vn-ticket-sale vn-tr:nth-child(2) vn-check[field="sale.checked"] label`, - thirdSaleCheckbox: `vn-ticket-sale vn-tr:nth-child(3) vn-check[field="sale.checked"] label`, + selectAllSalesCheckbox: `vn-ticket-sale vn-thead vn-check md-checkbox`, + secondSaleCheckbox: `vn-ticket-sale vn-tr:nth-child(2) vn-check[field="sale.checked"] md-checkbox`, + thirdSaleCheckbox: `vn-ticket-sale vn-tr:nth-child(3) vn-check[field="sale.checked"] md-checkbox`, deleteSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="delete"]', transferSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="call_split"]', moveToTicketInput: 'vn-ticket-sale vn-popover.transfer vn-textfield[model="$ctrl.moveToTicketFk"] input', @@ -441,7 +436,7 @@ export default { }, claimBasicData: { claimStateAutocomplete: 'vn-claim-basic-data vn-autocomplete[field="$ctrl.claim.claimStateFk"]', - isPaidWithManaCheckbox: 'vn-check[field="$ctrl.claim.isChargedToMana"] > label > input', + isPaidWithManaCheckbox: 'vn-check[field="$ctrl.claim.isChargedToMana"] md-checkbox', responsabilityInputRange: `vn-input-range`, observationInput: `vn-textarea[label="Observation"] textarea`, saveButton: `${components.vnSubmit}` diff --git a/e2e/paths/claim-module/01_edit_basic_data.spec.js b/e2e/paths/claim-module/01_edit_basic_data.spec.js index 0b7c4e5c8..a53356f45 100644 --- a/e2e/paths/claim-module/01_edit_basic_data.spec.js +++ b/e2e/paths/claim-module/01_edit_basic_data.spec.js @@ -33,12 +33,10 @@ describe('Claim edit basic data path', () => { }); it('should confirm the Is paid with mana checkbox is checked', async() => { - const value = await nightmare - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.claimBasicData.isPaidWithManaCheckbox); + const result = await nightmare + .checkboxState(selectors.claimBasicData.isPaidWithManaCheckbox); - expect(value).toBeTruthy(); + expect(result).toBe('checked'); }); it('should confirm the claim observation was edited', async() => { diff --git a/e2e/paths/client-module/03_edit_fiscal_data.spec.js b/e2e/paths/client-module/03_edit_fiscal_data.spec.js index 2326a1108..e8b4ada00 100644 --- a/e2e/paths/client-module/03_edit_fiscal_data.spec.js +++ b/e2e/paths/client-module/03_edit_fiscal_data.spec.js @@ -15,12 +15,9 @@ describe('Client Edit fiscalData path', () => { it(`should click on the 1st edit icon to check EQtax isnt checked`, async() => { const result = await nightmare .waitToClick(selectors.clientAddresses.firstEditButton) - .wait(selectors.clientAddresses.equalizationTaxCheckboxLabel) - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientAddresses.equalizationTaxCheckboxLabel); + .checkboxState(selectors.clientAddresses.equalizationTaxCheckbox); - expect(result).toBeFalsy(); + expect(result).toBe('unchecked'); }); // Confirms all addresses have EQtax false for future propagation test step 2 @@ -28,12 +25,9 @@ describe('Client Edit fiscalData path', () => { const result = await nightmare .waitToClick(selectors.clientAddresses.addressesButton) .waitToClick(selectors.clientAddresses.secondEditButton) - .wait(selectors.clientAddresses.equalizationTaxCheckboxLabel) - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientAddresses.equalizationTaxCheckboxLabel); + .checkboxState(selectors.clientAddresses.equalizationTaxCheckbox); - expect(result).toBeFalsy(); + expect(result).toBe('unchecked'); }); it(`should click on the fiscal data button`, async() => { @@ -47,9 +41,10 @@ describe('Client Edit fiscalData path', () => { it('should not be able to edit the verified data checkbox', async() => { const result = await nightmare + .wait(selectors.clientFiscalData.verifiedDataCheckbox) .evaluate(selector => { - return document.querySelector(selector).disabled; - }, selectors.clientFiscalData.verifiedDataCheckboxInput); + return document.querySelector(selector).getAttribute('disabled'); + }, selectors.clientFiscalData.verifiedDataCheckbox); expect(result).toBeTruthy(); }); @@ -78,14 +73,14 @@ describe('Client Edit fiscalData path', () => { .write(selectors.clientFiscalData.cityInput, 'N/A') .autocompleteSearch(selectors.clientFiscalData.countryAutocomplete, 'Francia') .autocompleteSearch(selectors.clientFiscalData.provinceAutocomplete, 'Province two') - .waitToClick(selectors.clientFiscalData.activeCheckboxLabel) - .waitToClick(selectors.clientFiscalData.frozenCheckboxLabel) - .waitToClick(selectors.clientFiscalData.hasToInvoiceCheckboxLabel) - .waitToClick(selectors.clientFiscalData.viesCheckboxInput) - .waitToClick(selectors.clientFiscalData.invoiceByMailCheckboxLabel) - .waitToClick(selectors.clientFiscalData.invoiceByAddressCheckboxInput) - .waitToClick(selectors.clientFiscalData.equalizationTaxCheckboxLabel) - .waitToClick(selectors.clientFiscalData.verifiedDataCheckboxInput) + .waitToClick(selectors.clientFiscalData.activeCheckbox) + .waitToClick(selectors.clientFiscalData.frozenCheckbox) + .waitToClick(selectors.clientFiscalData.hasToInvoiceCheckbox) + .waitToClick(selectors.clientFiscalData.viesCheckbox) + .waitToClick(selectors.clientFiscalData.invoiceByMailCheckbox) + .waitToClick(selectors.clientFiscalData.invoiceByAddressCheckbox) + .waitToClick(selectors.clientFiscalData.equalizationTaxCheckbox) + .waitToClick(selectors.clientFiscalData.verifiedDataCheckbox) .waitToClick(selectors.clientFiscalData.saveButton) .waitForLastSnackbar(); @@ -94,7 +89,7 @@ describe('Client Edit fiscalData path', () => { it('should receive an error if the fiscal id contains A or B at the beginning', async() => { const result = await nightmare - .waitToClick(selectors.clientFiscalData.viesCheckboxInput) + .waitToClick(selectors.clientFiscalData.viesCheckbox) .clearInput(selectors.clientFiscalData.fiscalIdInput) .write(selectors.clientFiscalData.fiscalIdInput, 'A94980061C') .waitToClick(selectors.clientFiscalData.saveButton) @@ -135,12 +130,9 @@ describe('Client Edit fiscalData path', () => { it(`should click on the 1st edit icon to confirm EQtax is checked`, async() => { const result = await nightmare .waitToClick(selectors.clientAddresses.firstEditButton) - .wait(selectors.clientAddresses.equalizationTaxCheckboxLabel) - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientAddresses.equalizationTaxCheckboxLabel); + .checkboxState(selectors.clientAddresses.equalizationTaxCheckbox); - expect(result).toBeTruthy(); + expect(result).toBe('checked'); }); // confirm all addresses have now EQtax checked step 3 @@ -148,19 +140,16 @@ describe('Client Edit fiscalData path', () => { const result = await nightmare .waitToClick(selectors.clientAddresses.addressesButton) .waitToClick(selectors.clientAddresses.secondEditButton) - .wait(selectors.clientAddresses.equalizationTaxCheckboxLabel) - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientAddresses.equalizationTaxCheckboxLabel); + .checkboxState(selectors.clientAddresses.equalizationTaxCheckbox); - expect(result).toBeTruthy(); + expect(result).toBe('checked'); }); it('should navigate back to fiscal data and uncheck EQtax then check VIES', async() => { const result = await nightmare .waitToClick(selectors.clientFiscalData.fiscalDataButton) - .waitToClick(selectors.clientFiscalData.viesCheckboxInput) - .waitToClick(selectors.clientFiscalData.equalizationTaxCheckboxLabel) + .waitToClick(selectors.clientFiscalData.viesCheckbox) + .waitToClick(selectors.clientFiscalData.equalizationTaxCheckbox) .waitToClick(selectors.clientFiscalData.saveButton) .waitForLastSnackbar(); @@ -227,74 +216,58 @@ describe('Client Edit fiscalData path', () => { it('should confirm active checkbox is unchecked', async() => { const result = await nightmare - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientFiscalData.activeCheckboxLabel); + .checkboxState(selectors.clientFiscalData.activeCheckbox); - expect(result).toBeFalsy(); + expect(result).toBe('unchecked'); }); it('should confirm frozen checkbox is unchecked', async() => { const result = await nightmare - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientFiscalData.frozenCheckboxLabel); + .checkboxState(selectors.clientFiscalData.frozenCheckbox); - expect(result).toBeFalsy(); + expect(result).toBe('unchecked'); }); it('should confirm Has to invoice checkbox is unchecked', async() => { const result = await nightmare - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientFiscalData.hasToInvoiceCheckboxLabel); + .checkboxState(selectors.clientFiscalData.hasToInvoiceCheckbox); - expect(result).toBeFalsy(); + expect(result).toBe('unchecked'); }); it('should confirm Vies checkbox is checked', async() => { const result = await nightmare - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientFiscalData.viesCheckboxInput); + .checkboxState(selectors.clientFiscalData.viesCheckbox); - expect(result).toBeTruthy(); + expect(result).toBe('checked'); }); it('should confirm Invoice by mail checkbox is unchecked', async() => { const result = await nightmare - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientFiscalData.invoiceByMailCheckboxLabel); + .checkboxState(selectors.clientFiscalData.invoiceByMailCheckbox); - expect(result).toBeFalsy(); + expect(result).toBe('unchecked'); }); it('should confirm invoice by address checkbox is unchecked', async() => { const result = await nightmare - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientFiscalData.invoiceByAddressCheckboxInput); + .checkboxState(selectors.clientFiscalData.invoiceByAddressCheckbox); - expect(result).toBeFalsy(); + expect(result).toBe('unchecked'); }); it('should confirm Equalization tax checkbox is unchecked', async() => { const result = await nightmare - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientFiscalData.equalizationTaxCheckboxLabel); + .checkboxState(selectors.clientFiscalData.equalizationTaxCheckbox); - expect(result).toBeFalsy(); + expect(result).toBe('unchecked'); }); it('should confirm Verified data checkbox is checked', async() => { const result = await nightmare - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientFiscalData.verifiedDataCheckboxInput); + .checkboxState(selectors.clientFiscalData.verifiedDataCheckbox); - expect(result).toBeTruthy(); + expect(result).toBe('checked'); }); // confirm invoice by address checkbox gets checked if the EQtax differs between addresses step 1 @@ -311,7 +284,7 @@ describe('Client Edit fiscalData path', () => { it(`should click on the 1st edit icon to access the address details and uncheck EQtax checkbox`, async() => { const result = await nightmare .waitToClick(selectors.clientAddresses.firstEditButton) - .waitToClick(selectors.clientAddresses.equalizationTaxCheckboxLabel) + .waitToClick(selectors.clientAddresses.equalizationTaxCheckbox) .waitToClick(selectors.clientAddresses.saveButton) .waitForLastSnackbar(); @@ -322,12 +295,9 @@ describe('Client Edit fiscalData path', () => { it('should navigate back to fiscal data to confirm invoice by address is now checked', async() => { const result = await nightmare .waitToClick(selectors.clientFiscalData.fiscalDataButton) - .wait(selectors.clientFiscalData.invoiceByAddressCheckboxInput) - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientFiscalData.invoiceByAddressCheckboxInput); + .checkboxState(selectors.clientFiscalData.invoiceByAddressCheckbox); - expect(result).toBeTruthy(); + expect(result).toBe('checked'); }); }); }); diff --git a/e2e/paths/client-module/04_edit_pay_method.spec.js b/e2e/paths/client-module/04_edit_pay_method.spec.js index 5af4c894f..a8b58ca11 100644 --- a/e2e/paths/client-module/04_edit_pay_method.spec.js +++ b/e2e/paths/client-module/04_edit_pay_method.spec.js @@ -98,29 +98,23 @@ describe('Client Edit pay method path', () => { }); it('should confirm Received LCR checkbox is checked', async() => { - const checkedBox = await nightmare - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientPayMethod.receivedCoreLCRCheckbox); + const result = await nightmare + .checkboxState(selectors.clientPayMethod.receivedCoreLCRCheckbox); - expect(checkedBox).toBeTruthy(); + expect(result).toBe('checked'); }); it('should confirm Received core VNL checkbox is unchecked', async() => { - const checkedBox = await nightmare - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientPayMethod.receivedCoreVNLCheckbox); + const result = await nightmare + .checkboxState(selectors.clientPayMethod.receivedCoreVNLCheckbox); - expect(checkedBox).toBeFalsy(); + expect(result).toBe('unchecked'); }); it('should confirm Received B2B VNL checkbox is unchecked', async() => { - const checkedBox = await nightmare - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientPayMethod.receivedB2BVNLCheckbox); + const result = await nightmare + .checkboxState(selectors.clientPayMethod.receivedB2BVNLCheckbox); - expect(checkedBox).toBeFalsy(); + expect(result).toBe('unchecked'); }); }); diff --git a/e2e/paths/client-module/07_edit_web_access.spec.js b/e2e/paths/client-module/07_edit_web_access.spec.js index 6f8ef2843..999b1c123 100644 --- a/e2e/paths/client-module/07_edit_web_access.spec.js +++ b/e2e/paths/client-module/07_edit_web_access.spec.js @@ -28,12 +28,9 @@ describe('Client Edit web access path', () => { .wait(selectors.clientBasicData.nameInput) .waitToClick(selectors.clientsIndex.othersButton) .waitToClick(selectors.clientWebAccess.webAccessButton) - .wait(selectors.clientWebAccess.enableWebAccessCheckbox) - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientWebAccess.enableWebAccessCheckbox); + .checkboxState(selectors.clientWebAccess.enableWebAccessCheckbox); - expect(result).toBeFalsy(); + expect(result).toBe('unchecked'); }); it('should confirm web access name have been updated', async() => { diff --git a/e2e/paths/client-module/12_lock_of_verified_data.spec.js b/e2e/paths/client-module/12_lock_of_verified_data.spec.js index 5c4d0e87b..971d1e5f9 100644 --- a/e2e/paths/client-module/12_lock_of_verified_data.spec.js +++ b/e2e/paths/client-module/12_lock_of_verified_data.spec.js @@ -15,9 +15,9 @@ describe('Client lock verified data path', () => { it('should confirm verified data button is disabled for salesPerson', async() => { const result = await nightmare .wait(200) - .wait(selectors.clientFiscalData.verifiedDataCheckboxInput) + .wait(selectors.clientFiscalData.verifiedDataCheckbox) .evaluate(selector => { - return document.querySelector(selector).disabled; + return document.querySelector(selector).getAttribute('disabled'); }, selectors.clientFiscalData.verifiedDataCheckbox); expect(result).toBeTruthy(); @@ -92,17 +92,17 @@ describe('Client lock verified data path', () => { it('should confirm verified data button is enabled for administrative', async() => { const result = await nightmare - .wait(selectors.clientFiscalData.verifiedDataCheckboxInput) + .wait(selectors.clientFiscalData.verifiedDataCheckbox) .evaluate(selector => { return document.querySelector(selector).disabled; }, selectors.clientFiscalData.verifiedDataCheckbox); - expect(result).not.toBeTruthy(); + expect(result).toBeFalsy(); }); it('should check the Verified data checkbox', async() => { const result = await nightmare - .waitToClick(selectors.clientFiscalData.verifiedDataCheckboxInput) + .waitToClick(selectors.clientFiscalData.verifiedDataCheckbox) .waitToClick(selectors.clientFiscalData.saveButton) .waitForLastSnackbar(); @@ -112,12 +112,9 @@ describe('Client lock verified data path', () => { it('should confirm Verified data checkbox is checked', async() => { const result = await nightmare .reloadSection('client.card.fiscalData') - .wait(selectors.clientFiscalData.verifiedDataCheckboxInput) - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.clientFiscalData.verifiedDataCheckboxInput); + .checkboxState(selectors.clientFiscalData.verifiedDataCheckbox); - expect(result).toBeTruthy(); + expect(result).toBe('checked'); }); it('should again edit the social name', async() => { @@ -189,12 +186,12 @@ describe('Client lock verified data path', () => { it('should confirm verified data button is disabled once again for salesPerson', async() => { const result = await nightmare - .wait(selectors.clientFiscalData.verifiedDataCheckboxInput) + .wait(selectors.clientFiscalData.verifiedDataCheckbox) .evaluate(selector => { - return document.querySelector(selector).disabled; + return document.querySelector(selector).getAttribute('disabled'); }, selectors.clientFiscalData.verifiedDataCheckbox); - expect(result).toBe(true); + expect(result).toBeTruthy(); }); it('should not be able to save change throwing a verified data error', async() => { @@ -258,9 +255,9 @@ describe('Client lock verified data path', () => { it('should confirm verified data button is enabled for salesAssistant', async() => { const result = await nightmare - .wait(selectors.clientFiscalData.verifiedDataCheckboxInput) + .wait(selectors.clientFiscalData.verifiedDataCheckbox) .evaluate(selector => { - return document.querySelector(selector).disabled; + return document.querySelector(selector).getAttribute('disabled'); }, selectors.clientFiscalData.verifiedDataCheckbox); expect(result).toBeFalsy(); @@ -334,12 +331,12 @@ describe('Client lock verified data path', () => { it('should confirm verified data button is enabled once again', async() => { const result = await nightmare - .wait(selectors.clientFiscalData.verifiedDataCheckboxInput) + .wait(selectors.clientFiscalData.verifiedDataCheckbox) .evaluate(selector => { - return document.querySelector(selector).disabled; + return document.querySelector(selector).getAttribute('disabled'); }, selectors.clientFiscalData.verifiedDataCheckbox); - expect(result).toBe(true); + expect(result).toBeTruthy(); }); it('should confirm the form is enabled for salesPerson', async() => { @@ -349,7 +346,7 @@ describe('Client lock verified data path', () => { return document.querySelector(selector).disabled; }, 'vn-textfield[field="$ctrl.client.socialName"] > div'); - expect(result).not.toBe(true); + expect(result).toBeFalsy(); }); }); }); diff --git a/e2e/paths/item-module/02_edit_item_basic_data.spec.js b/e2e/paths/item-module/02_edit_item_basic_data.spec.js index 3a06a2a77..15cea353a 100644 --- a/e2e/paths/item-module/02_edit_item_basic_data.spec.js +++ b/e2e/paths/item-module/02_edit_item_basic_data.spec.js @@ -89,10 +89,8 @@ describe('Item Edit basic data path', () => { it('should confirm isActive checkbox is unchecked', async() => { const result = await nightmare - .evaluate(selector => { - return document.querySelector(selector).checked; - }, selectors.itemBasicData.isActiveCheckbox); + .checkboxState(selectors.itemBasicData.isActiveCheckbox); - expect(result).toBeFalsy(); + expect(result).toBe('unchecked'); }); }); diff --git a/front/core/components/check/check.html b/front/core/components/check/check.html index b2f5558b2..59fbd1192 100644 --- a/front/core/components/check/check.html +++ b/front/core/components/check/check.html @@ -1,7 +1,11 @@ - + + {{::$ctrl.label}} + diff --git a/front/core/components/check/check.js b/front/core/components/check/check.js index 99098ce89..63d049264 100644 --- a/front/core/components/check/check.js +++ b/front/core/components/check/check.js @@ -1,41 +1,59 @@ import ngModule from '../../module'; -import Input from '../../lib/input'; +import Component from '../../lib/component'; import './style.scss'; -export default class Controller extends Input { +export default class Controller extends Component { constructor($element, $scope, $attrs) { super($element, $scope); - componentHandler.upgradeElement(this.element.firstChild); - this.mdlElement = this.element.firstChild.MaterialCheckbox; - this.input.addEventListener('change', () => this.onChange()); this.hasInfo = Boolean($attrs.info); this.info = $attrs.info || null; } - set field(value) { + + set checkValue(value) { + this.checkIntermediate(); + if (this.isIntermediate) + value = false; + this._field = value; - this.input.checked = value == true; - this.mdlUpdate(); + + if (typeof this._checkValue === 'boolean') + this.emit('change', {value: this.field}); + + this._checkValue = value; } + + get checkValue() { + return this._checkValue; + } + + set field(value) { + this.checkValue = value; + } + get field() { + if (!this._field && this.isIntermediate) + return null; + return this._field; } - $onInit() { - if (this.model) { - this.model.$render = () => { - this.input.checked = this.model.$viewValue || false; - this.mdlUpdate(); - }; - this.$element.on('blur keyup change', () => { - this.$.$evalAsync(() => { - this.model.$setViewValue(this.input.checked); - }); - }); - } + + set tripleState(value) { + this._tripleState = value; + this.checkIntermediate(); } - onChange() { - this._field = this.input.checked == true; - this.$.$applyAsync(); - this.emit('change'); + + get tripleState() { + return this._tripleState; + } + + checkIntermediate() { + if ((this.intermediate || (!this._field && this.tripleState)) && !this.isIntermediate) { + this.isIntermediate = true; + return; + } + + if (!this.intermediate) + this.isIntermediate = false; } } Controller.$inject = ['$element', '$scope', '$attrs']; @@ -48,9 +66,10 @@ ngModule.component('vnCheck', { }, bindings: { field: '=?', - onChange: '&?', label: '@?', disabled: ' div { position: relative; box-shadow: 0 0 .4em $color-shadow; - background-color: white; + background-color: $color-bg-panel; border-radius: .2em; overflow: auto; padding: 2em; diff --git a/front/core/components/icon-button/icon-button.js b/front/core/components/icon-button/icon-button.js index 100c76179..b4022ccec 100644 --- a/front/core/components/icon-button/icon-button.js +++ b/front/core/components/icon-button/icon-button.js @@ -6,7 +6,7 @@ export default class IconButton { if ($element[0].getAttribute('tabindex') == null) $element[0].tabIndex = 0; - $element.on("keyup", event => this.onKeyDown(event, $element)); + $element.on('keyup', event => this.onKeyDown(event, $element)); let button = $element[0].querySelector('button'); $element[0].addEventListener('click', event => { if (this.disabled || button.disabled) diff --git a/front/core/components/icon-button/style.scss b/front/core/components/icon-button/style.scss index 0874c5758..d5932fa39 100644 --- a/front/core/components/icon-button/style.scss +++ b/front/core/components/icon-button/style.scss @@ -3,16 +3,20 @@ vn-icon-button { outline: 0; color: $color-main; + display: inline-block; - button { - background: transparent !important; - background-color: transparent !important; - display: inline-block; + & > button { + background-color: transparent; + display: block; color: inherit; border: 0; + padding: .25em; - &.mdl-button--colored { - color: inherit; + &:hover { + background-color: initial; + } + & > vn-icon { + display: block; } } } diff --git a/front/core/components/searchbar/searchbar.js b/front/core/components/searchbar/searchbar.js index 6555b707e..f5ead38a4 100644 --- a/front/core/components/searchbar/searchbar.js +++ b/front/core/components/searchbar/searchbar.js @@ -61,7 +61,8 @@ export default class Controller extends Component { if (event.defaultPrevented) return; event.preventDefault(); - this.$panel = this.$compile(`<${this.panel}/>`)(this.$.$new()); + this.$panelScope = this.$.$new(); + this.$panel = this.$compile(`<${this.panel}/>`)(this.$panelScope); let panel = this.$panel.isolateScope().$ctrl; panel.filter = this._filter; panel.onSubmit = filter => this.onPanelSubmit(filter); @@ -72,7 +73,7 @@ export default class Controller extends Component { } onPopoverClose() { - this.$panel.scope().$destroy(); + this.$panelScope.$destroy(); this.$panel.remove(); this.$panel = null; } diff --git a/front/core/components/table/style.scss b/front/core/components/table/style.scss index f05c6f4e1..65f2344c9 100644 --- a/front/core/components/table/style.scss +++ b/front/core/components/table/style.scss @@ -15,7 +15,7 @@ vn-table { display: table-header-group; border-bottom: .15em solid $color-spacer; - vn-th[field] { + & > * > vn-th[field] { position: relative; overflow: visible; cursor: pointer; @@ -49,17 +49,22 @@ vn-table { border-top: .15em solid $color-spacer; display: table-footer-group } - vn-tr, a.vn-tr { + & > * > vn-tr, + & > * > a.vn-tr { display: table-row } vn-thead, vn-tbody, vn-tfoot { & > * { display: table-row; - - vn-th { - font-weight: bold + + & > vn-th { + font-weight: bold; + padding-top: 1em; + padding-bottom: .8em; } - vn-td, vn-th, vn-td-editable { + & > vn-th, + & > vn-td, + & > vn-td-editable { vertical-align: middle; display: table-cell; text-align: left; @@ -87,11 +92,6 @@ vn-table { color: #f7931e; } } - vn-th { - font-weight: bold; - padding-top: 1em; - padding-bottom: .8em; - } & > :last-child { padding-right: 1em; } @@ -99,18 +99,13 @@ vn-table { padding-left: 1em; } } - a.vn-tr { + & > a.vn-tr { color: inherit; } } vn-tbody > * { border-bottom: .1em solid $color-spacer-light; - &, - & > vn-td, - & > vn-td > .chip { - transition: background-color 200ms ease-in-out; - } &:last-child { border-bottom: none; } @@ -124,37 +119,44 @@ vn-table { &.notice, & > .notice, & > vn-td > .notice { - color: white; - background-color: $color-notice; + color: $color-font-bg; + background-color: $color-notice-medium; } &.success, & > .success, & > vn-td > .success { - color: white; - background-color: $color-success; + color: $color-font-bg; + background-color: $color-success-medium; } &.warning, & > .warning, & > vn-td > .warning { - color: white; - background-color: $color-main; + color: $color-font-bg; + background-color: $color-main-medium; } &.alert, & > .alert, & > vn-td > .alert { - color: white; - background-color: $color-alert; + color: $color-font-bg; + background-color: $color-alert-medium; + } + & > [actions] { + width: 1px; + + & > * { + vertical-align: middle; + } } } - } - vn-empty-rows { - display: table-caption; - caption-side: bottom; - text-align: center; - padding: 1.5em; - width: 100%; - box-sizing: border-box; - color: $color-font-secondary; + & > vn-empty-rows { + display: table-caption; + caption-side: bottom; + text-align: center; + padding: 1.5em; + width: 100%; + box-sizing: border-box; + color: $color-font-secondary; + } } vn-autocomplete { div.mdl-textfield { diff --git a/front/core/directives/acl.js b/front/core/directives/acl.js index 51ceb3b6d..2ff35a87f 100644 --- a/front/core/directives/acl.js +++ b/front/core/directives/acl.js @@ -40,7 +40,7 @@ function vnAcl(aclService, $timeout) { if (!aclService.hasAny(acls)) { if (action === 'disabled') { let input = $element[0]; - let selector = 'input, textarea, button, submit'; + let selector = 'input, textarea, button, submit, md-checkbox'; if (!input.matches(selector)) input = input.querySelector(selector); diff --git a/front/core/styles/salixfont.css b/front/core/styles/salixfont.css index bfd4b0f6e..8e9a02963 100644 --- a/front/core/styles/salixfont.css +++ b/front/core/styles/salixfont.css @@ -1,8 +1,9 @@ @font-face { font-family: 'salixfont'; - src: url('./salixfont.ttf?1qesj4') format('truetype'), - url('./salixfont.woff?1qesj4') format('woff'), - url('./salixfont.svg?1qesj4#salixfont') format('svg'); + src: + url('./salixfont.ttf?wtrl3') format('truetype'), + url('./salixfont.woff?wtrl3') format('woff'), + url('./salixfont.svg?wtrl3#salixfont') format('svg'); font-weight: normal; font-style: normal; } @@ -22,36 +23,15 @@ -moz-osx-font-smoothing: grayscale; } -.icon-columndelete:before { - content: "\e90f"; -} -.icon-columnadd:before { - content: "\e944"; -} -.icon-linesplit:before { - content: "\e945"; -} -.icon-linedelete:before { - content: "\e946"; -} -.icon-item:before { - content: "\e941"; -} -.icon-basket:before { - content: "\e942"; -} -.icon-worker:before { - content: "\e943"; -} -.icon-reserve:before { - content: "\e92f"; -} -.icon-services:before { - content: "\e93f"; +.icon-pets:before { + content: "\e94e"; } .icon-100:before { content: "\e940"; } +.icon-accessory:before { + content: "\e90a"; +} .icon-actions:before { content: "\e900"; } @@ -61,12 +41,18 @@ .icon-albaran:before { content: "\e902"; } +.icon-apps:before { + content: "\e948"; +} .icon-artificial:before { content: "\e903"; } .icon-barcode:before { content: "\e904"; } +.icon-basket:before { + content: "\e942"; +} .icon-bin:before { content: "\e905"; } @@ -82,18 +68,21 @@ .icon-clone:before { content: "\e909"; } -.icon-accessory:before { - content: "\e90a"; +.icon-columnadd:before { + content: "\e944"; +} +.icon-columndelete:before { + content: "\e90f"; } .icon-components:before { content: "\e90b"; } -.icon-handmade:before { - content: "\e90c"; -} .icon-consignatarios:before { content: "\e90d"; } +.icon-control:before { + content: "\e93f"; +} .icon-credit:before { content: "\e90e"; } @@ -103,8 +92,8 @@ .icon-details:before { content: "\e911"; } -.icon-fiscal:before { - content: "\e912"; +.icon-disabled:before { + content: "\e91b"; } .icon-doc:before { content: "\e913"; @@ -112,36 +101,63 @@ .icon-entry:before { content: "\e914"; } +.icon-exit:before { + content: "\e947"; +} .icon-eye:before { content: "\e915"; } +.icon-fiscal:before { + content: "\e912"; +} .icon-flower:before { content: "\e916"; } .icon-frozen:before { content: "\e917"; } +.icon-greenery:before { + content: "\e93c"; +} .icon-greuge:before { content: "\e918"; } .icon-grid:before { content: "\e919"; } +.icon-handmade:before { + content: "\e90c"; +} .icon-history:before { content: "\e91a"; } -.icon-disabled:before { - content: "\e91b"; +.icon-info:before { + content: "\e949"; +} +.icon-invoices1:before { + content: "\e94a"; } .icon-invoices:before { content: "\e91c"; } +.icon-item:before { + content: "\e941"; +} .icon-languaje:before { content: "\e91d"; } +.icon-linedelete:before { + content: "\e946"; +} .icon-lines:before { content: "\e91e"; } +.icon-linesplit:before { + content: "\e945"; +} +.icon-linesprepaired:before { + content: "\e94b"; +} .icon-logout:before { content: "\e91f"; } @@ -181,18 +197,24 @@ .icon-plant:before { content: "\e92b"; } -.icon-stowaway:before { - content: "\e92c"; -} .icon-recovery:before { content: "\e92d"; } .icon-regentry:before { content: "\e92e"; } +.icon-reserve:before { + content: "\e92f"; +} +.icon-revision:before { + content: "\e94c"; +} .icon-risk:before { content: "\e930"; } +.icon-services:before { + content: "\e94d"; +} .icon-settings:before { content: "\e931"; } @@ -208,6 +230,9 @@ .icon-splur:before { content: "\e935"; } +.icon-stowaway:before { + content: "\e92c"; +} .icon-supplier:before { content: "\e936"; } @@ -226,12 +251,12 @@ .icon-transaction:before { content: "\e93b"; } -.icon-greenery:before { - content: "\e93c"; -} .icon-volume:before { content: "\e93d"; } .icon-web:before { content: "\e93e"; } +.icon-worker:before { + content: "\e943"; +} \ No newline at end of file diff --git a/front/core/styles/salixfont.svg b/front/core/styles/salixfont.svg index aa5ec8c3c..d6654ec1e 100644 --- a/front/core/styles/salixfont.svg +++ b/front/core/styles/salixfont.svg @@ -9,7 +9,7 @@ - + @@ -70,7 +70,7 @@ - + @@ -78,4 +78,12 @@ + + + + + + + + \ No newline at end of file diff --git a/front/core/styles/salixfont.ttf b/front/core/styles/salixfont.ttf index 3bf8cbdda..7c0ac2492 100644 Binary files a/front/core/styles/salixfont.ttf and b/front/core/styles/salixfont.ttf differ diff --git a/front/core/styles/salixfont.woff b/front/core/styles/salixfont.woff index 75b97ffde..2a9a880f5 100644 Binary files a/front/core/styles/salixfont.woff and b/front/core/styles/salixfont.woff differ diff --git a/front/core/vendor.js b/front/core/vendor.js index e10cd1036..7de458072 100644 --- a/front/core/vendor.js +++ b/front/core/vendor.js @@ -8,12 +8,15 @@ import 'angular-translate-loader-partial'; import '@uirouter/angularjs'; import 'mg-crud'; import 'oclazyload'; +import 'angular-material'; +import 'angular-material/modules/scss/angular-material.scss'; export const ngDeps = [ 'pascalprecht.translate', 'ui.router', 'mgCrud', - 'oc.lazyLoad' + 'oc.lazyLoad', + 'ngMaterial' ]; import 'material-design-lite'; diff --git a/front/package-lock.json b/front/package-lock.json index 52fc8d351..a81776d0c 100644 --- a/front/package-lock.json +++ b/front/package-lock.json @@ -1,5 +1,5 @@ { - "name": "salix-client", + "name": "salix-front", "version": "1.0.0", "lockfileVersion": 1, "requires": true, @@ -31,6 +31,21 @@ "resolved": "https://registry.npmjs.org/angular/-/angular-1.7.5.tgz", "integrity": "sha512-760183yxtGzni740IBTieNuWLtPNAoMqvmC0Z62UoU0I3nqk+VJuO3JbQAXOyvo3Oy/ZsdNQwrSTh/B0OQZjNw==" }, + "angular-animate": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/angular-animate/-/angular-animate-1.7.7.tgz", + "integrity": "sha512-KLbU9gtgCyNSaMZKnNe9Yi6UTlDMN2EWyokQ06TG5fbDWOePm+kv2xqeUg1S2h+ZLjK0NnoVDIvwDhVQ+AWAag==" + }, + "angular-aria": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/angular-aria/-/angular-aria-1.7.7.tgz", + "integrity": "sha512-Jju0VudfKVp+6FUtfzpDBuOJE8+8cGPSM10nRicXvJRX/Nx/YOu38f2aL3HQwThrRK+3E5jfo7yRwVNYoSmSxg==" + }, + "angular-material": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/angular-material/-/angular-material-1.1.12.tgz", + "integrity": "sha512-hvYgVSAxmXy+ozm+FcdGrTrBKm/TLubCgJ8xZR3LNYYmLfsIfzh4Eyk87inmTCXS02KYL0EX2dUeiVmanHlIaQ==" + }, "angular-translate": { "version": "2.18.1", "resolved": "https://registry.npmjs.org/angular-translate/-/angular-translate-2.18.1.tgz", diff --git a/front/package.json b/front/package.json index bcbe3c77c..78ddecce8 100644 --- a/front/package.json +++ b/front/package.json @@ -12,6 +12,9 @@ "@babel/polyfill": "^7.2.5", "@uirouter/angularjs": "^1.0.20", "angular": "^1.7.5", + "angular-animate": "^1.7.7", + "angular-aria": "^1.7.7", + "angular-material": "^1.1.12", "angular-translate": "^2.18.1", "angular-translate-loader-partial": "^2.18.1", "flatpickr": "^4.5.2", diff --git a/front/salix/components/home/style.scss b/front/salix/components/home/style.scss index 6c1e1762b..72322d0e0 100644 --- a/front/salix/components/home/style.scss +++ b/front/salix/components/home/style.scss @@ -24,7 +24,7 @@ vn-home { overflow:hidden; border-radius: 6px; background-color: $color-main; - color: white; + color: $color-font-dark; display: flex; flex-direction: column; height: 8em; @@ -54,7 +54,7 @@ vn-home { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; - color: white; + color: inherit; margin: 0; /* & > .bind-letter { diff --git a/front/salix/components/main-menu/style.scss b/front/salix/components/main-menu/style.scss index c4e0f7a88..fb7acf296 100644 --- a/front/salix/components/main-menu/style.scss +++ b/front/salix/components/main-menu/style.scss @@ -1,4 +1,5 @@ @import "effects"; +@import "variables"; vn-main-menu { display: flex; @@ -31,7 +32,7 @@ vn-main-menu { vn-menu.vn-popover > div > div.content > ul { list-style-type: none; margin: 0; - color: white; + color: $color-font-dark; & > li { @extend %clickable-light; diff --git a/front/salix/components/topbar/style.scss b/front/salix/components/topbar/style.scss index 5c0ea23bd..dc5273dbf 100644 --- a/front/salix/components/topbar/style.scss +++ b/front/salix/components/topbar/style.scss @@ -2,7 +2,7 @@ vn-topbar { display: flex; - color: white; + color: $color-font-dark; box-sizing: border-box; background-color: $color-header; align-items: center; diff --git a/front/salix/components/user-configuration-popover/index.js b/front/salix/components/user-configuration-popover/index.js index 5f8eeb330..446cb1153 100644 --- a/front/salix/components/user-configuration-popover/index.js +++ b/front/salix/components/user-configuration-popover/index.js @@ -92,7 +92,7 @@ class Controller { this.company = value; if (value && (!window.localStorage.localCompanyFk || window.localStorage.localCompanyFk === 'null')) - window.localStorage.setItem('localCompanyFk', value); + window.localStorage.setItem('defaultCompanyFk', value); this.setUserConfig('companyFk', value); } @@ -118,7 +118,7 @@ class Controller { if (res.data && res.data.warehouseFk) { this.warehouse = res.data.warehouseFk; if (res.data.warehouseFk && !window.localStorage.localWarehouseFk) - window.localStorage.setItem('localWarehouseFk', res.data.warehouseFk); + window.localStorage.setItem('defaultWarehouseFk', res.data.warehouseFk); } if (res.data && res.data.companyFk) { diff --git a/front/salix/styles/descriptor.scss b/front/salix/styles/descriptor.scss index af72b9c41..782a57e66 100644 --- a/front/salix/styles/descriptor.scss +++ b/front/salix/styles/descriptor.scss @@ -8,10 +8,9 @@ & > .header { display: flex; background: $color-main; - color: white; justify-content: space-between; align-items: stretch; - color: white; + color: $color-font-dark; & > * { min-width: 1.8em; diff --git a/front/salix/styles/misc.scss b/front/salix/styles/misc.scss index d02d4676a..266994d26 100644 --- a/front/salix/styles/misc.scss +++ b/front/salix/styles/misc.scss @@ -20,7 +20,7 @@ input[type=reset]::-moz-focus-inner { } a , .link{ - color: $color-main; + color: $color-font-link; text-decoration: none; } .link { @@ -148,11 +148,9 @@ vn-tool-bar { max-width: 36em; margin: 0 auto; } - a.vn-list-item { @extend %clickable; } - .vn-list-item { padding: $pad-medium; border-bottom: $border-thin solid $color-spacer-light; @@ -180,7 +178,13 @@ a.vn-list-item { } } } - } + } +} +vn-empty-rows.vn-list-item { + text-align: center; + padding: 1.5em; + box-sizing: border-box; + color: $color-font-secondary; } /** START - FORM ELEMENTS DISABLED **/ diff --git a/front/salix/styles/summary.scss b/front/salix/styles/summary.scss index 2dd5b58fe..fd1e99a22 100644 --- a/front/salix/styles/summary.scss +++ b/front/salix/styles/summary.scss @@ -9,7 +9,7 @@ padding: $pad-small; border: none; background: $color-main; - color: white; + color: $color-font-dark; margin: 0; text-align: center; line-height: 1.3em; diff --git a/front/salix/styles/variables.scss b/front/salix/styles/variables.scss index 418c605a6..b794d5610 100644 --- a/front/salix/styles/variables.scss +++ b/front/salix/styles/variables.scss @@ -28,8 +28,10 @@ $border-thick: .15em; $color-header: #3d3d3d; $color-bg: #e5e5e5; $color-bg-dark: #3d3d3d; -$color-font:#222222; +$color-font: #222222; $color-font-secondary: #9b9b9b; +$color-font-dark: white; +$color-font-bg: rgba(0, 0, 0, .7); $color-active: #3d3d3d; $color-active-font: white; $color-bg-panel: white; @@ -47,6 +49,7 @@ $color-hover-cd: rgba(0, 0, 0, .1); $color-hover-dc: .7; $color-disabled: .6; +$color-font-link: darken($color-main, 10%); $color-main-medium: lighten($color-main, 20%); $color-main-light: lighten($color-main, 35%); $color-success-medium: lighten($color-success, 20%); @@ -63,6 +66,8 @@ $color-bg: #222; $color-bg-dark: #222; $color-font: white; $color-font-secondary: #777; +$color-font-dark: white; +$color-font-bg: rgba(0, 0, 0, .8); $color-active: #666; $color-active-font: white; $color-bg-panel: #3c3b3b; @@ -80,6 +85,7 @@ $color-hover-cd: rgba(255, 255, 255, .1); $color-hover-dc: .7; $color-disabled: .6; +$color-font-link: lighten($color-main, 10%); $color-main-medium: darken($color-main, 20%); $color-main-light: darken($color-main, 35%); $color-success-medium: darken($color-success, 20%); diff --git a/gulpfile.js b/gulpfile.js index b6427cdd1..b8394b8fb 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -123,7 +123,7 @@ async function backTestDocker() { if (argv['random']) await execP(`docker rm -fv ${containerId}`); } -backTestDocker.description = `Runs backend tests using in site container`; +backTestDocker.description = `Runs backend tests restoring fixtures first`; function backTest(done) { const nodemon = require('gulp-nodemon'); diff --git a/modules/client/front/index/index.html b/modules/client/front/index/index.html index 07b394073..32f01c7e4 100644 --- a/modules/client/front/index/index.html +++ b/modules/client/front/index/index.html @@ -22,11 +22,11 @@ ng-repeat="client in clients track by client.id" client="::client"> - No results - Enter a new search diff --git a/modules/item/back/methods/item/filter.js b/modules/item/back/methods/item/filter.js index fd14357b8..5d1f49568 100644 --- a/modules/item/back/methods/item/filter.js +++ b/modules/item/back/methods/item/filter.js @@ -37,7 +37,7 @@ module.exports = Self => { t.name type, u.id userId, intr.description AS intrastat, i.stems, ori.code AS origin, t.name AS type, - ic.name AS category + ic.name AS category, i.density, tc.description AS taxClass FROM item i JOIN itemType t ON t.id = i.typeFk LEFT JOIN itemCategory ic ON ic.id = t.categoryFk @@ -45,7 +45,8 @@ module.exports = Self => { JOIN account.user u ON u.id = w.userFk LEFT JOIN intrastat intr ON intr.id = i.intrastatFk LEFT JOIN producer pr ON pr.id = i.producerFk - LEFT JOIN origin ori ON ori.id = i.originFk` + LEFT JOIN origin ori ON ori.id = i.originFk + LEFT JOIN taxClass tc ON tc.id = i.taxClassFk` ); if (tags) { diff --git a/modules/item/front/descriptor/index.js b/modules/item/front/descriptor/index.js index 552ccd85a..79e669b87 100644 --- a/modules/item/front/descriptor/index.js +++ b/modules/item/front/descriptor/index.js @@ -28,7 +28,7 @@ class Controller { get warehouseFk() { if (!this._warehouseFk) - this._warehouseFk = parseInt(window.localStorage.localWarehouseFk); + this._warehouseFk = parseInt(window.localStorage.defaultWarehouseFk); return this._warehouseFk; } diff --git a/modules/item/front/index/index.html b/modules/item/front/index/index.html index 6330d6bf8..9b5b6df64 100644 --- a/modules/item/front/index/index.html +++ b/modules/item/front/index/index.html @@ -31,6 +31,8 @@ Intrastat Origin Sales person + Density + Tax class Active @@ -71,6 +73,8 @@ {{::item.userNickname}} + {{::item.density}} + {{::item.taxClass}} + + - - + + + + { let rowToDelete; afterAll(async() => { - await app.models.OrderRow.removes({rows: [rowToDelete], actualOrderId: 16}); + await app.models.OrderRow.removes({rows: [rowToDelete], actualOrderId: 20}); }); it('should add a row to a given order', async() => { - let unmodifiedRows = await app.models.OrderRow.find({where: {orderFk: 16}}); + let unmodifiedRows = await app.models.OrderRow.find({where: {orderFk: 20}}); - expect(unmodifiedRows.length).toBe(4); + expect(unmodifiedRows.length).toBe(1); let params = { - orderFk: 16, + orderFk: 20, items: [{ itemFk: 1, quantity: 1, @@ -22,10 +22,10 @@ describe('order addToOrder()', () => { await app.models.OrderRow.addToOrder(params); - let modifiedRows = await app.models.OrderRow.find({where: {orderFk: 16}}); + let modifiedRows = await app.models.OrderRow.find({where: {orderFk: 20}}); rowToDelete = modifiedRows[modifiedRows.length - 1].id; - expect(modifiedRows.length).toBe(5); + expect(modifiedRows.length).toBe(2); }); }); diff --git a/modules/order/front/filter/index.js b/modules/order/front/filter/index.js index c2bfb8e4b..8a80a80e2 100644 --- a/modules/order/front/filter/index.js +++ b/modules/order/front/filter/index.js @@ -136,7 +136,8 @@ class Controller { if (event.defaultPrevented) return; event.preventDefault(); - this.$panel = this.$compile(``)(this.$scope.$new()); + this.$panelScope = this.$scope.$new(); + this.$panel = this.$compile(``)(this.$panelScope); const panel = this.$panel.isolateScope().$ctrl; panel.filter = this.filter; panel.onSubmit = filter => this.onPanelSubmit(filter); @@ -153,7 +154,7 @@ class Controller { } onPopoverClose() { - this.$panel.scope().$destroy(); + this.$panelScope.$destroy(); this.$panel.remove(); this.$panel = null; } diff --git a/modules/order/front/search-panel/index.html b/modules/order/front/search-panel/index.html index 07dbdf1bc..691fb4642 100644 --- a/modules/order/front/search-panel/index.html +++ b/modules/order/front/search-panel/index.html @@ -60,6 +60,7 @@ diff --git a/modules/ticket/back/methods/sale/updateDiscount.js b/modules/ticket/back/methods/sale/updateDiscount.js index a90597726..1c1db1927 100644 --- a/modules/ticket/back/methods/sale/updateDiscount.js +++ b/modules/ticket/back/methods/sale/updateDiscount.js @@ -60,8 +60,10 @@ module.exports = Self => { await model.Sale.update({id: params.editLines[i].id}, {discount: params.editLines[i].discount}); } - query = ` + if (usesMana) { + query = ` call vn.manaSpellersRequery(?)`; - await Self.rawSql(query, [ticket[0].client().salesPersonFk]); + await Self.rawSql(query, [ticket[0].client().salesPersonFk]); + } }; }; diff --git a/modules/ticket/back/methods/ticket/specs/getSales.spec.js b/modules/ticket/back/methods/ticket/specs/getSales.spec.js index 121b02195..da44716cf 100644 --- a/modules/ticket/back/methods/ticket/specs/getSales.spec.js +++ b/modules/ticket/back/methods/ticket/specs/getSales.spec.js @@ -1,7 +1,7 @@ const app = require('vn-loopback/server/server'); describe('ticket getSales()', () => { - it('should return the sales of a ticket', async () => { + it('should return the sales of a ticket', async() => { let sales = await app.models.Ticket.getSales(16); expect(sales.length).toEqual(4); diff --git a/modules/ticket/front/descriptor/style.scss b/modules/ticket/front/descriptor/style.scss index 32fd7d9dc..ae7f338d0 100644 --- a/modules/ticket/front/descriptor/style.scss +++ b/modules/ticket/front/descriptor/style.scss @@ -1,10 +1,12 @@ @import "variables"; vn-dialog.modal-form { - vn-horizontal.header{ + vn-horizontal.header { background-color: $color-main; - h5{ - color: white; + color: $color-font-dark; + + h5 { + color: inherit; margin: 0 auto; } } @@ -14,23 +16,22 @@ vn-dialog.modal-form { table { width: 100% } - &>div{ - padding: 0!important; + & > div { + padding: 0 !important; } vn-textfield { width: 100%; } - .buttons{ - margin-top: 0!important; + .buttons { + margin-top: 0 !important; } - - p{ + p { display: none; } - button.close > vn-icon{ - color: white!important; + button.close > vn-icon { + color: white !important; } vn-ticket-sale-edit-discount > div { - padding-bottom: 0!important; + padding-bottom: 0 !important; } } \ No newline at end of file diff --git a/modules/ticket/front/index/index.html b/modules/ticket/front/index/index.html index 02dad3337..6bc9cf17e 100644 --- a/modules/ticket/front/index/index.html +++ b/modules/ticket/front/index/index.html @@ -88,7 +88,7 @@ {{::ticket.agencyMode}} {{::ticket.warehouse}} {{::ticket.total | currency: 'EUR': 2}} - + { - this.hide(); + this.onHide(); this.vnApp.showSuccess(this.$translate.instant('Data saved!')); this.clear(); modified = false; }).catch(e => { this.vnApp.showError(e.data.error.message); }); - } else { + } else this.vnApp.showError(this.$translate.instant('There is no changes to save')); - } } clear() { @@ -70,6 +69,6 @@ ngModule.component('vnTicketSaleEditDiscount', { edit: ' + on-hide="$ctrl.hideEditPopover()"> @@ -204,7 +204,7 @@ mana="$ctrl.mana" bulk="true" edit="$ctrl.edit" - hide="$ctrl.hideEditDialog()"> + on-hide="$ctrl.hideEditDialog()"> diff --git a/modules/ticket/front/sale/style.scss b/modules/ticket/front/sale/style.scss index 33ac275ef..a0d6d24a8 100644 --- a/modules/ticket/front/sale/style.scss +++ b/modules/ticket/front/sale/style.scss @@ -1,38 +1,35 @@ @import "variables"; + vn-ticket-sale { .header { justify-content: space-between !important; align-items: center; } - vn-popover.edit { - div.popover{ + div.popover { width: 200px; } - - vn-horizontal.header{ + vn-horizontal.header { background-color: $color-main; - h5{ - color: white; + color: $color-font-dark; + + h5 { + color: inherit; margin: 0 auto; } } - - p.simulatorTitle{ + p.simulatorTitle { margin-bottom: 0px; font-size: 12px; color: $color-main; } - - vn-label-value{ + vn-label-value { padding-bottom: 20px; } - div.simulator{ text-align: center; } } - vn-dialog.edit { @extend vn-popover.edit; @@ -45,8 +42,7 @@ vn-ticket-sale { .buttons{ margin-top: 0!important; } - - p{ + p { display: none; } button.close > vn-icon{ diff --git a/services/db/install/changes/1.2-CHECK/01-workerDepartment.sql b/services/db/install/changes/1.2-CHECK/01-workerDepartment.sql new file mode 100644 index 000000000..b52f29182 --- /dev/null +++ b/services/db/install/changes/1.2-CHECK/01-workerDepartment.sql @@ -0,0 +1,18 @@ +USE `vn`; +CREATE + OR REPLACE ALGORITHM = UNDEFINED + DEFINER = `root`@`%` + SQL SECURITY DEFINER +VIEW `vn`.`workerDepartment` AS + SELECT + `p`.`id_trabajador` AS `workerFk`, + `d`.`id` AS `departmentFk` + FROM + (((`postgresql`.`person` `p` + JOIN `postgresql`.`profile` `pr` ON ((`pr`.`person_id` = `p`.`person_id`))) + LEFT JOIN (`postgresql`.`business` `b` + LEFT JOIN `postgresql`.`business_labour` `bl` ON ((`b`.`business_id` = `bl`.`business_id`))) ON ((`pr`.`profile_id` = `b`.`client_id`))) + JOIN `vn`.`department` `d` ON ((`d`.`id` = `bl`.`department_id`))) + WHERE + (ISNULL(`b`.`date_end`) + OR (`b`.`date_end` > CURDATE())); diff --git a/services/db/install/changes/1.2-CHECK/02-orderAddItem.sql b/services/db/install/changes/1.2-CHECK/02-orderAddItem.sql new file mode 100644 index 000000000..35bee1117 --- /dev/null +++ b/services/db/install/changes/1.2-CHECK/02-orderAddItem.sql @@ -0,0 +1,108 @@ +USE `hedera`; +DROP procedure IF EXISTS `orderAddItem`; + +DELIMITER $$ +USE `hedera`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `orderAddItem`(IN `vOrder` INT, IN `vWarehouse` INT, IN `vItem` INT, IN `vAmount` INT) +BEGIN + DECLARE vRow INT; + DECLARE vAdd INT; + DECLARE vAvailable INT; + DECLARE vDone BOOL; + DECLARE vGrouping INT; + DECLARE vRate INT; + DECLARE vShipment DATE; + DECLARE vPrice DECIMAL(10,2); + DECLARE vDate DATE; + DECLARE vAddress INT; + DECLARE vAgencyMode INT; + DECLARE cur CURSOR FOR + SELECT grouping, price, rate + FROM tmp.bionic_price + WHERE warehouse_id = vWarehouse + AND item_id = vItem + ORDER BY grouping DESC; + + DECLARE CONTINUE HANDLER FOR NOT FOUND + SET vDone = TRUE; + + DECLARE EXIT HANDLER FOR SQLEXCEPTION + BEGIN + ROLLBACK; + RESIGNAL; + END; + + SELECT date_send, address_id, agency_id + INTO vDate, vAddress, vAgencyMode + FROM `order` + WHERE id = vOrder; + + CALL vn2008.bionic_from_item(vDate, vAddress, vAgencyMode, vItem); + + START TRANSACTION; + + SELECT shipped INTO vShipment + FROM tmp.travel_tree + WHERE warehouseFk = vWarehouse; + + SELECT available INTO vAvailable + FROM tmp.bionic_lot + WHERE warehouse_id = vWarehouse + AND item_id = vItem; + + IF vAmount > IFNULL(vAvailable, 0) + THEN + CALL util.throw ('ORDER_ROW_UNAVAILABLE'); + END IF; + + OPEN cur; + + l: LOOP + SET vDone = FALSE; + FETCH cur INTO vGrouping, vPrice, vRate; + + IF vDone THEN + LEAVE l; + END IF; + + SET vAdd = vAmount - MOD(vAmount, vGrouping); + SET vAmount = vAmount - vAdd; + + IF vAdd = 0 THEN + ITERATE l; + END IF; + + INSERT INTO order_row SET + order_id = vOrder, + item_id = vItem, + warehouse_id = vWarehouse, + shipment = vShipment, + rate = vRate, + amount = vAdd, + price = vPrice; + + SET vRow = LAST_INSERT_ID(); + + INSERT INTO order_component (order_row_id, component_id, price) + SELECT vRow, c.component_id, c.cost + FROM tmp.bionic_component c + JOIN bi.tarifa_componentes t + ON t.Id_Componente = c.component_id + AND (t.tarifa_class IS NULL OR t.tarifa_class = vRate) + WHERE c.warehouse_id = vWarehouse + AND c.item_id = vItem; + END LOOP; + + CLOSE cur; + + IF vAmount > 0 + THEN + CALL util.throw ('AMOUNT_NOT_MATCH_GROUPING'); + END IF; + + COMMIT; + CALL vn2008.bionic_free (); +END$$ + +DELIMITER ; + diff --git a/services/db/install/changes/1.2-CHECK/03-acl.sql b/services/db/install/changes/1.2-CHECK/03-acl.sql new file mode 100644 index 000000000..32ec03b5c --- /dev/null +++ b/services/db/install/changes/1.2-CHECK/03-acl.sql @@ -0,0 +1 @@ +INSERT INTO salix.ACL(id,model, property, accessType, permission, principalType, principalId)VALUES(147,'UserConfigView', '*', '*', 'ALLOW', 'ROLE', 'employee'); \ No newline at end of file diff --git a/services/db/install/dump/fixtures.sql b/services/db/install/dump/fixtures.sql index a95d5db47..5613f974e 100644 --- a/services/db/install/dump/fixtures.sql +++ b/services/db/install/dump/fixtures.sql @@ -879,84 +879,90 @@ INSERT INTO `hedera`.`order`(`id`, `date_send`, `customer_id`, `delivery_method_ (17, CURDATE(), 106, 2, 4, 126, 442, NULL, 'SALIX', 0, CURDATE() , CURDATE() , CURDATE() ), (18, CURDATE(), 107, 3, 4, 127, 442, NULL, 'SALIX', 0, CURDATE() , CURDATE() , CURDATE() ), (19, CURDATE(), 108, 1, 5, 128, 442, NULL, 'SALIX', 0, CURDATE() , CURDATE() , CURDATE() ), - (20, CURDATE(), 109, 2, 5, 119, 442, NULL, 'SALIX', 0, CURDATE() , CURDATE() , CURDATE() ), + (20, CURDATE(), 109, 2, 1, 119, 442, NULL, 'SALIX', 0, CURDATE() , CURDATE() , CURDATE() ), (21, CURDATE(), 110, 3, 5, 129, 442, NULL, 'SALIX', 0, CURDATE() , CURDATE() , CURDATE() ); INSERT INTO `hedera`.`orderRow`(`id`, `orderFk`, `itemFk`, `warehouseFk`, `shipment`, `amount`, `price`, `rate`, `created`, `saleFk`) VALUES - ( 1, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 5, 9.10, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 1), - ( 2, 1, 2, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 10, 1.07, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 2), - ( 3, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 2, 9.10, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 3), - ( 4, 1, 4, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 20, 3.06, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 4), - ( 5, 2, 1, 1, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 10, 9.10, 0, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 5), - ( 6, 3, 1, 2, DATE_ADD(CURDATE(), INTERVAL -5 DAY), 15, 6.50, 0, DATE_ADD(CURDATE(), INTERVAL -5 DAY), 6), - ( 7, 11, 2, 1, CURDATE(), 15, 1.30, 0, CURDATE(), 7), - ( 8, 11, 4, 1, CURDATE(), 10, 3.26, 0, CURDATE(), 8), - ( 9, 16, 1, 1, CURDATE(), 5, 9.10, 0, CURDATE(), 9), - ( 10, 16, 2, 1, CURDATE(), 10, 1.07, 0, CURDATE(), 10), - ( 11, 16, 1, 1, CURDATE(), 2, 9.10, 0, CURDATE(), 11), - ( 12, 16, 4, 1, CURDATE(), 20, 3.06, 0, CURDATE(), 12); + (1, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 5, 9.10, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 1), + (2, 1, 2, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 10, 1.07, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 2), + (3, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 2, 9.10, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 3), + (4, 1, 4, 1, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 20, 3.06, 0, DATE_ADD(CURDATE(), INTERVAL -15 DAY), 4), + (5, 2, 1, 1, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 10, 9.10, 0, DATE_ADD(CURDATE(), INTERVAL -10 DAY), 5), + (6, 3, 1, 2, DATE_ADD(CURDATE(), INTERVAL -5 DAY), 15, 6.50, 0, DATE_ADD(CURDATE(), INTERVAL -5 DAY), 6), + (7, 11, 2, 1, CURDATE(), 15, 1.30, 0, CURDATE(), 7), + (8, 11, 4, 1, CURDATE(), 10, 3.26, 0, CURDATE(), 8), + (9, 16, 1, 1, CURDATE(), 5, 9.10, 0, CURDATE(), 9), + (10, 16, 2, 1, CURDATE(), 10, 1.07, 0, CURDATE(), 10), + (11, 16, 1, 1, CURDATE(), 2, 9.10, 0, CURDATE(), 11), + (12, 16, 4, 1, CURDATE(), 20, 3.06, 0, CURDATE(), 12), + (13, 20, 1, 1, CURDATE(), 2, 9.10, 0, CURDATE(), NULL); INSERT INTO `hedera`.`orderRowComponent`(`rowFk`, `componentFk`, `price`) VALUES - ( 1, 15, 0.58), - ( 1, 23, 6.5), - ( 1, 28, 20.72), - ( 1, 29, -18.72), - ( 1, 39, 0.02), - ( 2, 15, 0.058), - ( 2, 21, 0.002), - ( 2, 28, 5.6), - ( 2, 29, -4.6), - ( 2, 39, 0.01), - ( 3, 15, 0.58), - ( 3, 23, 6.5), - ( 3, 28, 20.72), - ( 3, 29, -18.72), - ( 3, 39, 0.02), - ( 4, 15, 0.051), - ( 4, 21, -0.001), - ( 4, 28, 20.72), - ( 4, 29, -19.72), - ( 4, 37, 2), - ( 4, 39, 0.01), - ( 5, 15, 0.58), - ( 5, 23, 6.5), - ( 5, 28, 20.72), - ( 5, 29, -18.72), - ( 5, 39, 0.02), - ( 6, 23, 6.5), - ( 7, 15, 0.29), - ( 7, 28, 5.6), - ( 7, 29, -4.6), - ( 7, 39, 0.01), - ( 8, 15, 0.254), - ( 8, 21, -0.004), - ( 8, 28, 20.72), - ( 8, 29, -19.72), - ( 8, 37, 2), - ( 8, 39, 0.01), - ( 9, 15, 0.58), - ( 9, 23, 6.5), - ( 9, 28, 20.72), - ( 9, 29, -18.72), - ( 9, 39, 0.02), - ( 10, 15, 0.058), - ( 10, 21, 0.002), - ( 10, 28, 5.6), - ( 10, 29, -4.6), - ( 10, 39, 0.01), - ( 11, 15, 0.58), - ( 11, 23, 6.5), - ( 11, 28, 20.72), - ( 11, 29, -18.72), - ( 11, 39, 0.02), - ( 12, 15, 0.051), - ( 12, 22, -0.001), - ( 12, 28, 20.72), - ( 12, 29, -19.72), - ( 12, 37, 2), - ( 12, 39, 0.01); + (1, 15, 0.58), + (1, 23, 6.5), + (1, 28, 20.72), + (1, 29, -18.72), + (1, 39, 0.02), + (2, 15, 0.058), + (2, 21, 0.002), + (2, 28, 5.6), + (2, 29, -4.6), + (2, 39, 0.01), + (3, 15, 0.58), + (3, 23, 6.5), + (3, 28, 20.72), + (3, 29, -18.72), + (3, 39, 0.02), + (4, 15, 0.051), + (4, 21, -0.001), + (4, 28, 20.72), + (4, 29, -19.72), + (4, 37, 2), + (4, 39, 0.01), + (5, 15, 0.58), + (5, 23, 6.5), + (5, 28, 20.72), + (5, 29, -18.72), + (5, 39, 0.02), + (6, 23, 6.5), + (7, 15, 0.29), + (7, 28, 5.6), + (7, 29, -4.6), + (7, 39, 0.01), + (8, 15, 0.254), + (8, 21, -0.004), + (8, 28, 20.72), + (8, 29, -19.72), + (8, 37, 2), + (8, 39, 0.01), + (9, 15, 0.58), + (9, 23, 6.5), + (9, 28, 20.72), + (9, 29, -18.72), + (9, 39, 0.02), + (10, 15, 0.058), + (10, 21, 0.002), + (10, 28, 5.6), + (10, 29, -4.6), + (10, 39, 0.01), + (11, 15, 0.58), + (11, 23, 6.5), + (11, 28, 20.72), + (11, 29, -18.72), + (11, 39, 0.02), + (12, 15, 0.051), + (12, 22, -0.001), + (12, 28, 20.72), + (12, 29, -19.72), + (12, 37, 2), + (12, 39, 0.01), + (13, 15, 0.58), + (13, 23, 6.5), + (13, 28, 20.72), + (13, 29, -18.72), + (13, 39, 0.02); INSERT INTO `vn`.`clientContact`(`id`, `clientFk`, `name`, `phone`) VALUES @@ -1042,12 +1048,7 @@ INSERT INTO `vn`.`orderTicket`(`orderFk`, `ticketFk`) (12, 12), (13, 13), (14, 14), - (15, 15), - (17, 17), - (18, 18), - (19, 19), - (20, 20), - (21, 21); + (15, 15); INSERT INTO `vn`.`userConfig` (`userFk`, `warehouseFk`, `companyFk`) VALUES