5914-transferInvoiceOut #1761
18
CHANGELOG.md
18
CHANGELOG.md
|
@ -5,7 +5,8 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [2330.01] - 2023-07-27
|
||||
|
||||
## [2334.01] - 2023-08-24
|
||||
|
||||
### Added
|
||||
|
||||
|
@ -14,6 +15,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
### Fixed
|
||||
|
||||
|
||||
## [2332.01] - 2023-08-09
|
||||
|
||||
### Added
|
||||
- (Trabajadores -> Gestión documental) Soporte para Docuware
|
||||
- (General -> Agencia) Soporte para Viaexpress
|
||||
|
||||
### Changed
|
||||
- (General -> Tickets) Devuelve el motivo por el cual no es editable
|
||||
- (Desplegables -> Trabajadores) Mejorados
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
## [2330.01] - 2023-07-27
|
||||
|
||||
### Added
|
||||
|
@ -24,7 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
### Changed
|
||||
- (General -> Iconos) Añadidos nuevos iconos
|
||||
- (Clientes -> Razón social) Nuevas restricciones por pais
|
||||
- (Clientes -> Razón social) Permite crear clientes con la misma razón social según el país
|
||||
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -47,7 +47,7 @@ module.exports = Self => {
|
|||
const user = await Self.findById(userId, {fields: ['hasGrant']}, myOptions);
|
||||
|
||||
const userToUpdate = await Self.findById(id, {
|
||||
fields: ['id', 'name', 'hasGrant', 'roleFk', 'password'],
|
||||
fields: ['id', 'name', 'hasGrant', 'roleFk', 'password', 'email'],
|
||||
include: {
|
||||
relation: 'role',
|
||||
scope: {
|
||||
|
|
|
@ -20,7 +20,7 @@ module.exports = function(Self) {
|
|||
Self.validatesFormatOf('email', {
|
||||
message: 'Invalid email',
|
||||
allowNull: true,
|
||||
allowBlank: true,
|
||||
allowBlank: false,
|
||||
with: /^[\w|.|-]+@[\w|-]+(\.[\w|-]+)*(,[\w|.|-]+@[\w|-]+(\.[\w|-]+)*)*$/
|
||||
});
|
||||
|
||||
|
@ -115,6 +115,14 @@ module.exports = function(Self) {
|
|||
Self.validateLogin = async function(user, password) {
|
||||
let loginInfo = Object.assign({password}, Self.userUses(user));
|
||||
token = await Self.login(loginInfo, 'user');
|
||||
|
||||
const userToken = await token.user.get();
|
||||
try {
|
||||
await Self.app.models.Account.sync(userToken.name, password);
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
}
|
||||
|
||||
return {token: token.id, ttl: token.ttl};
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`client_create`(
|
||||
vFirstname VARCHAR(50),
|
||||
vSurnames VARCHAR(50),
|
||||
vFi VARCHAR(9),
|
||||
vAddress TEXT,
|
||||
vPostcode CHAR(5),
|
||||
vCity VARCHAR(25),
|
||||
vProvinceFk SMALLINT(5),
|
||||
vCompanyFk SMALLINT(5),
|
||||
vPhone VARCHAR(11),
|
||||
vEmail VARCHAR(255),
|
||||
vUserFk INT
|
||||
)
|
||||
BEGIN
|
||||
/**
|
||||
* Create new client
|
||||
*
|
||||
* @params vFirstname firstName
|
||||
* @params vSurnames surnames
|
||||
* @params vFi company code from accounting transactions
|
||||
* @params vAddress address
|
||||
* @params vPostcode postCode
|
||||
* @params vCity city
|
||||
* @params vProvinceFk province
|
||||
* @params vCompanyFk company in which he has become a client
|
||||
* @params vPhone telephone number
|
||||
* @params vEmail email address
|
||||
* @params vUserFk user id
|
||||
*/
|
||||
DECLARE vPayMethodFk INT;
|
||||
DECLARE vDueDay INT;
|
||||
DECLARE vDefaultCredit DECIMAL(10, 2);
|
||||
DECLARE vIsTaxDataChecked TINYINT(1);
|
||||
DECLARE vHasCoreVnl BOOLEAN;
|
||||
DECLARE vMandateTypeFk INT;
|
||||
|
||||
SELECT defaultPayMethodFk,
|
||||
defaultDueDay,
|
||||
defaultCredit,
|
||||
defaultIsTaxDataChecked,
|
||||
defaultHasCoreVnl,
|
||||
defaultMandateTypeFk
|
||||
INTO vPayMethodFk,
|
||||
vDueDay,
|
||||
vDefaultCredit,
|
||||
vIsTaxDataChecked,
|
||||
vHasCoreVnl,
|
||||
vMandateTypeFk
|
||||
FROM clientConfig;
|
||||
|
||||
INSERT INTO `client`
|
||||
SET id = vUserFk,
|
||||
name = CONCAT(vFirstname, ' ', vSurnames),
|
||||
street = vAddress,
|
||||
fi = TRIM(vFi),
|
||||
phone = vPhone,
|
||||
email = vEmail,
|
||||
provinceFk = vProvinceFk,
|
||||
city = vCity,
|
||||
postcode = vPostcode,
|
||||
socialName = UPPER(CONCAT(vSurnames, ' ', vFirstname)),
|
||||
payMethodFk = vPayMethodFk,
|
||||
dueDay = vDueDay,
|
||||
credit = vDefaultCredit,
|
||||
isTaxDataChecked = vIsTaxDataChecked,
|
||||
hasCoreVnl = vHasCoreVnl,
|
||||
isEqualizated = FALSE
|
||||
ON duplicate KEY UPDATE
|
||||
payMethodFk = vPayMethodFk,
|
||||
dueDay = vDueDay,
|
||||
credit = vDefaultCredit,
|
||||
isTaxDataChecked = vIsTaxDataChecked,
|
||||
hasCoreVnl = vHasCoreVnl,
|
||||
isActive = TRUE;
|
||||
|
||||
INSERT INTO mandate (clientFk, companyFk, mandateTypeFk)
|
||||
SELECT vUserFk, vCompanyFk, vMandateTypeFk
|
||||
WHERE NOT EXISTS (
|
||||
SELECT id
|
||||
FROM mandate
|
||||
WHERE clientFk = vUserFk
|
||||
AND companyFk = vCompanyFk
|
||||
AND mandateTypeFk = vMandateTypeFk
|
||||
);
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -360,13 +360,13 @@ INSERT INTO `vn`.`contactChannel`(`id`, `name`)
|
|||
|
||||
INSERT INTO `vn`.`client`(`id`,`name`,`fi`,`socialName`,`contact`,`street`,`city`,`postcode`,`phone`,`mobile`,`isRelevant`,`email`,`iban`,`dueDay`,`accountingAccount`,`isEqualizated`,`provinceFk`,`hasToInvoice`,`credit`,`countryFk`,`isActive`,`gestdocFk`,`quality`,`payMethodFk`,`created`,`isToBeMailed`,`contactChannelFk`,`hasSepaVnl`,`hasCoreVnl`,`hasCoreVnh`,`riskCalculated`,`clientTypeFk`, `hasToInvoiceByAddress`,`isTaxDataChecked`,`isFreezed`,`creditInsurance`,`isCreatedAsServed`,`hasInvoiceSimplified`,`salesPersonFk`,`isVies`,`eypbc`, `businessTypeFk`)
|
||||
VALUES
|
||||
(1101, 'Bruce Wayne', '84612325V', 'Batman', 'Alfred', '1007 Mountain Drive, Gotham', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceWayne@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist'),
|
||||
(1102, 'Petter Parker', '87945234L', 'Spider man', 'Aunt May', '20 Ingram Street, Queens, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'PetterParker@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist'),
|
||||
(1101, 'Bruce Wayne', '84612325V', 'BATMAN', 'Alfred', '1007 MOUNTAIN DRIVE, GOTHAM', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceWayne@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist'),
|
||||
(1102, 'Petter Parker', '87945234L', 'SPIDER MAN', 'Aunt May', '20 INGRAM STREET, QUEENS, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'PetterParker@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist'),
|
||||
(1103, 'Clark Kent', '06815934E', 'Super man', 'lois lane', '344 Clinton Street, Apartament 3-D', 'Gotham', 46460, 1111111111, 222222222, 1, 'ClarkKent@mydomain.com', NULL, 0, 1234567890, 0, 3, 1, 0, 19, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist'),
|
||||
(1104, 'Tony Stark', '06089160W', 'Iron man', 'Pepper Potts', '10880 Malibu Point, 90265', 'Gotham', 46460, 1111111111, 222222222, 1, 'TonyStark@mydomain.com', NULL, 0, 1234567890, 0, 2, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 18, 0, 1, 'florist'),
|
||||
(1105, 'Max Eisenhardt', '251628698', 'Magneto', 'Rogue', 'Unknown Whereabouts', 'Gotham', 46460, 1111111111, 222222222, 1, 'MaxEisenhardt@mydomain.com', NULL, 0, 1234567890, 0, 3, 1, 300, 8, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, NULL, 0, 0, 18, 0, 1, 'florist'),
|
||||
(1106, 'DavidCharlesHaller', '53136686Q', 'Legion', 'Charles Xavier', 'City of New York, New York, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'DavidCharlesHaller@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 0, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 19, 0, 1, 'florist'),
|
||||
(1107, 'Hank Pym', '09854837G', 'Ant man', 'Hawk', 'Anthill, San Francisco, California', 'Gotham', 46460, 1111111111, 222222222, 1, 'HankPym@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, 0, NULL, 0, 0, 19, 0, 1, 'florist'),
|
||||
(1106, 'DavidCharlesHaller', '53136686Q', 'LEGION', 'Charles Xavier', 'CITY OF NEW YORK, NEW YORK, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'DavidCharlesHaller@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 0, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 0, NULL, 0, 0, 19, 0, 1, 'florist'),
|
||||
(1107, 'Hank Pym', '09854837G', 'ANT MAN', 'Hawk', 'ANTHILL, SAN FRANCISCO, CALIFORNIA', 'Gotham', 46460, 1111111111, 222222222, 1, 'HankPym@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, 0, NULL, 0, 0, 19, 0, 1, 'florist'),
|
||||
(1108, 'Charles Xavier', '22641921P', 'Professor X', 'Beast', '3800 Victory Pkwy, Cincinnati, OH 45207, USA', 'Gotham', 46460, 1111111111, 222222222, 1, 'CharlesXavier@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 1, 1, NULL, 0, 0, 19, 0, 1, 'florist'),
|
||||
(1109, 'Bruce Banner', '16104829E', 'Hulk', 'Black widow', 'Somewhere in New York', 'Gotham', 46460, 1111111111, 222222222, 1, 'BruceBanner@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, 0, NULL, 0, 0, 9, 0, 1, 'florist'),
|
||||
(1110, 'Jessica Jones', '58282869H', 'Jessica Jones', 'Luke Cage', 'NYCC 2015 Poster', 'Gotham', 46460, 1111111111, 222222222, 1, 'JessicaJones@mydomain.com', NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 1, 1, 0, 0, NULL, 0, 0, NULL, 0, 1, 'florist'),
|
||||
|
|
|
@ -73,8 +73,8 @@ describe('Client create path', () => {
|
|||
|
||||
it(`should attempt to create a new user with all it's data but wrong email`, async() => {
|
||||
await page.write(selectors.createClientView.name, 'Carol Danvers');
|
||||
await page.write(selectors.createClientView.socialName, 'AVG tax');
|
||||
await page.write(selectors.createClientView.street, 'Many places');
|
||||
await page.write(selectors.createClientView.socialName, 'AVG TAX');
|
||||
await page.write(selectors.createClientView.street, 'MANY PLACES');
|
||||
await page.clearInput(selectors.createClientView.email);
|
||||
await page.write(selectors.createClientView.email, 'incorrect email format');
|
||||
await page.waitToClick(selectors.createClientView.createButton);
|
||||
|
|
|
@ -61,7 +61,7 @@ describe('Client Edit fiscalData path', () => {
|
|||
await page.clearInput(selectors.clientFiscalData.fiscalId);
|
||||
await page.write(selectors.clientFiscalData.fiscalId, 'INVALID!');
|
||||
await page.clearInput(selectors.clientFiscalData.address);
|
||||
await page.write(selectors.clientFiscalData.address, 'Somewhere edited');
|
||||
await page.write(selectors.clientFiscalData.address, 'SOMEWHERE EDITED');
|
||||
await page.autocompleteSearch(selectors.clientFiscalData.country, 'España');
|
||||
await page.autocompleteSearch(selectors.clientFiscalData.province, 'Province one');
|
||||
await page.clearInput(selectors.clientFiscalData.city);
|
||||
|
@ -190,7 +190,7 @@ describe('Client Edit fiscalData path', () => {
|
|||
const verifiedData = await page.checkboxState(selectors.clientFiscalData.verifiedDataCheckbox);
|
||||
|
||||
expect(fiscalId).toEqual('94980061C');
|
||||
expect(address).toEqual('Somewhere edited');
|
||||
expect(address).toEqual('SOMEWHERE EDITED');
|
||||
expect(postcode).toContain('46000');
|
||||
expect(sageTax).toEqual('Operaciones no sujetas');
|
||||
expect(sageTransaction).toEqual('Regularización de inversiones');
|
||||
|
|
|
@ -28,7 +28,7 @@ describe('Client lock verified data path', () => {
|
|||
it('should edit the social name', async() => {
|
||||
await page.waitForSelector(selectors.clientFiscalData.socialName);
|
||||
await page.clearInput(selectors.clientFiscalData.socialName);
|
||||
await page.write(selectors.clientFiscalData.socialName, 'Captain America Civil War');
|
||||
await page.write(selectors.clientFiscalData.socialName, 'CAPTAIN AMERICA CIVIL WAR');
|
||||
await page.waitToClick(selectors.clientFiscalData.saveButton);
|
||||
const message = await page.waitForSnackbar();
|
||||
|
||||
|
@ -39,7 +39,7 @@ describe('Client lock verified data path', () => {
|
|||
await page.reloadSection('client.card.fiscalData');
|
||||
const result = await page.waitToGetProperty(selectors.clientFiscalData.socialName, 'value');
|
||||
|
||||
expect(result).toEqual('Captain America Civil War');
|
||||
expect(result).toEqual('CAPTAIN AMERICA CIVIL WAR');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -88,7 +88,7 @@ describe('Client lock verified data path', () => {
|
|||
await page.reloadSection('client.card.fiscalData');
|
||||
const result = await page.waitToGetProperty(selectors.clientFiscalData.socialName, 'value');
|
||||
|
||||
expect(result).toEqual('Ant man and the Wasp');
|
||||
expect(result).toEqual('ANT MAN AND THE WASP');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -142,7 +142,7 @@ describe('Client lock verified data path', () => {
|
|||
await page.reloadSection('client.card.fiscalData');
|
||||
const result = await page.waitToGetProperty(selectors.clientFiscalData.socialName, 'value');
|
||||
|
||||
expect(result).toEqual('new social name edition');
|
||||
expect(result).toEqual('NEW SOCIAL NAME EDITION');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ describe('Client summary path', () => {
|
|||
it('should display fiscal address details', async() => {
|
||||
const result = await page.waitToGetProperty(selectors.clientSummary.street, 'innerText');
|
||||
|
||||
expect(result).toContain('20 Ingram Street');
|
||||
expect(result).toContain('20 INGRAM STREET');
|
||||
});
|
||||
|
||||
it('should display some fiscal data', async() => {
|
||||
|
|
|
@ -23,7 +23,7 @@ describe('Worker create path', () => {
|
|||
await page.write(selectors.workerCreate.fi, '78457139E');
|
||||
await page.write(selectors.workerCreate.phone, '12356789');
|
||||
await page.write(selectors.workerCreate.postcode, '46680');
|
||||
await page.write(selectors.workerCreate.street, 'S/ Doomstadt');
|
||||
await page.write(selectors.workerCreate.street, 'S/ DOOMSTADT');
|
||||
await page.write(selectors.workerCreate.email, 'doctorDoom@marvel.com');
|
||||
await page.write(selectors.workerCreate.iban, 'ES9121000418450200051332');
|
||||
|
||||
|
|
|
@ -339,8 +339,9 @@ export default class SmartTable extends Component {
|
|||
if (!header) return;
|
||||
|
||||
const tbody = this.element.querySelector('tbody');
|
||||
const columns = header.querySelectorAll('th');
|
||||
if (!tbody) return;
|
||||
|
||||
const columns = header.querySelectorAll('th');
|
||||
const hasSearchRow = tbody.querySelector('tr#searchRow');
|
||||
if (hasSearchRow) {
|
||||
if (this.$inputsScope)
|
||||
|
|
|
@ -179,6 +179,8 @@
|
|||
"You can not use the same password": "You can not use the same password",
|
||||
"Valid priorities": "Valid priorities: %d",
|
||||
"Negative basis of tickets": "Negative basis of tickets: {{ticketsIds}}",
|
||||
"Social name should be uppercase": "Social name should be uppercase",
|
||||
"Street should be uppercase": "Street should be uppercase",
|
||||
"You don't have enough privileges.": "You don't have enough privileges.",
|
||||
"This ticket is locked.": "This ticket is locked.",
|
||||
"This ticket is not editable.": "This ticket is not editable.",
|
||||
|
|
|
@ -305,6 +305,7 @@
|
|||
"The renew period has not been exceeded": "El periodo de renovación no ha sido superado",
|
||||
"Valid priorities": "Prioridades válidas: %d",
|
||||
"Negative basis of tickets": "Base negativa para los tickets: {{ticketsIds}}",
|
||||
"You cannot assign an alias that you are not assigned to": "No puede asignar un alias que no tenga asignado",
|
||||
"The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias",
|
||||
"You cannot assign/remove an alias that you are not assigned to": "No puede asignar/eliminar un alias que no tenga asignado",
|
||||
"This invoice has a linked vehicle.": "Esta factura tiene un vehiculo vinculado",
|
||||
|
@ -312,5 +313,11 @@
|
|||
"This ticket is locked.": "Este ticket está bloqueado.",
|
||||
"This ticket is not editable.": "Este ticket no es editable.",
|
||||
"The ticket doesn't exist.": "No existe el ticket.",
|
||||
<<<<<<< HEAD
|
||||
"There are missing fields.": "There are missing fields."
|
||||
}
|
||||
=======
|
||||
"Social name should be uppercase": "La razón social debe ir en mayúscula",
|
||||
"Street should be uppercase": "La dirección fiscal debe ir en mayúscula"
|
||||
}
|
||||
>>>>>>> ce78fc8e5dd383b3c6457fe5f78a45b21b246858
|
||||
|
|
|
@ -7,8 +7,8 @@ describe('Client Create', () => {
|
|||
email: 'Deadpool@marvel.com',
|
||||
fi: '16195279J',
|
||||
name: 'Wade',
|
||||
socialName: 'Deadpool Marvel',
|
||||
street: 'Wall Street',
|
||||
socialName: 'DEADPOOL MARVEL',
|
||||
street: 'WALL STREET',
|
||||
city: 'New York',
|
||||
businessTypeFk: 'florist',
|
||||
provinceFk: 1
|
||||
|
|
|
@ -36,6 +36,20 @@ module.exports = Self => {
|
|||
min: 3, max: 10
|
||||
});
|
||||
|
||||
Self.validatesFormatOf('street', {
|
||||
message: 'Street should be uppercase',
|
||||
allowNull: false,
|
||||
allowBlank: false,
|
||||
with: /^[^a-z]*$/
|
||||
});
|
||||
|
||||
Self.validatesFormatOf('socialName', {
|
||||
message: 'Social name should be uppercase',
|
||||
allowNull: false,
|
||||
allowBlank: false,
|
||||
with: /^[^a-z]*$/
|
||||
});
|
||||
|
||||
Self.validateAsync('socialName', socialNameIsUnique, {
|
||||
message: 'The company name must be unique'
|
||||
});
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
ng-model="$ctrl.client.socialName"
|
||||
info="Only letters, numbers and spaces can be used"
|
||||
required="true"
|
||||
ng-keyup="$ctrl.client.socialName = $ctrl.client.socialName.toUpperCase()"
|
||||
rule>
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
|
@ -46,6 +47,7 @@
|
|||
vn-two
|
||||
label="Street"
|
||||
ng-model="$ctrl.client.street"
|
||||
ng-keyup="$ctrl.client.street = $ctrl.client.street.toUpperCase()"
|
||||
rule>
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
label="Recovery email"
|
||||
ng-model="$ctrl.account.email"
|
||||
info="This email is used for user to regain access their account."
|
||||
rule="VnUser.name">
|
||||
rule="VnUser.email">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
name: invoice in
|
||||
columns:
|
||||
id: id
|
||||
serialNumber: serial number
|
||||
serial: serial
|
||||
supplierFk: supplier
|
||||
issued: issued
|
||||
supplierRef: supplierRef
|
||||
isBooked: is booked
|
||||
currencyFk: currency
|
||||
created: created
|
||||
companyFk: company
|
||||
docFk: document
|
||||
booked: booked
|
||||
operated: operated
|
||||
bookEntried: book entried
|
||||
isVatDeductible: is VAT deductible
|
||||
withholdingSageFk: withholding
|
||||
expenceFkDeductible: expence deductible
|
||||
editorFk: editor
|
|
@ -0,0 +1,20 @@
|
|||
name: factura recibida
|
||||
columns:
|
||||
id: id
|
||||
serialNumber: número de serie
|
||||
serial: serie
|
||||
supplierFk: proveedor
|
||||
issued: fecha emisión
|
||||
supplierRef: referéncia proveedor
|
||||
isBooked: facturado
|
||||
currencyFk: moneda
|
||||
created: creado
|
||||
companyFk: empresa
|
||||
docFk: documento
|
||||
booked: fecha contabilización
|
||||
operated: fecha entrega
|
||||
bookEntried: fecha asiento
|
||||
isVatDeductible: impuesto deducible
|
||||
withholdingSageFk: código de retención
|
||||
expenceFkDeductible: gasto deducible
|
||||
editorFk: editor
|
|
@ -0,0 +1,9 @@
|
|||
name: invoice in due day
|
||||
columns:
|
||||
id: id
|
||||
invoiceInFk: invoice in
|
||||
dueDated: due date
|
||||
bankFk: bank
|
||||
amount: amount
|
||||
foreignValue : foreign amount
|
||||
created: created
|
|
@ -0,0 +1,9 @@
|
|||
name: vencimientos factura recibida
|
||||
columns:
|
||||
id: id
|
||||
invoiceInFk: factura
|
||||
dueDated: fecha vto.
|
||||
bankFk: banco
|
||||
amount: importe
|
||||
foreignValue : importe divisa
|
||||
created: creado
|
|
@ -0,0 +1,12 @@
|
|||
name: invoice in tax
|
||||
columns:
|
||||
id: id
|
||||
invoiceInFk: invoice in
|
||||
taxCodeFk: tax
|
||||
taxableBase: taxable base
|
||||
expenceFk: expence
|
||||
foreignValue: foreign amount
|
||||
taxTypeSageFk: tax type
|
||||
transactionTypeSageFk: transaction type
|
||||
created: created
|
||||
editorFk: editor
|
|
@ -0,0 +1,12 @@
|
|||
name: factura recibida impuesto
|
||||
columns:
|
||||
id: id
|
||||
invoiceInFk: factura recibida
|
||||
taxCodeFk: código IVA
|
||||
taxableBase: base imponible
|
||||
expenceFk: código gasto
|
||||
foreignValue: importe divisa
|
||||
taxTypeSageFk: código impuesto
|
||||
transactionTypeSageFk: código transacción
|
||||
created: creado
|
||||
editorFk: editor
|
|
@ -2,37 +2,37 @@
|
|||
<vn-auto>
|
||||
<section
|
||||
class="inline-tag ellipsize"
|
||||
ng-class="::{empty: !$ctrl.item.value5}"
|
||||
ng-class="::{empty: !$ctrl.item.tag5}"
|
||||
title="{{::$ctrl.item.tag5}}: {{::$ctrl.item.value5}}">
|
||||
{{::$ctrl.item.value5}}
|
||||
</section>
|
||||
<section
|
||||
class="inline-tag ellipsize"
|
||||
ng-class="::{empty: !$ctrl.item.value6}"
|
||||
ng-class="::{empty: !$ctrl.item.tag6}"
|
||||
title="{{::$ctrl.item.tag6}}: {{::$ctrl.item.value6}}">
|
||||
{{::$ctrl.item.value6}}
|
||||
</section>
|
||||
<section
|
||||
class="inline-tag ellipsize"
|
||||
ng-class="::{empty: !$ctrl.item.value7}"
|
||||
ng-class="::{empty: !$ctrl.item.tag7}"
|
||||
title="{{::$ctrl.item.tag7}}: {{::$ctrl.item.value7}}">
|
||||
{{::$ctrl.item.value7}}
|
||||
</section>
|
||||
<section
|
||||
class="inline-tag ellipsize"
|
||||
ng-class="::{empty: !$ctrl.item.value8}"
|
||||
ng-class="::{empty: !$ctrl.item.tag8}"
|
||||
title="{{::$ctrl.item.tag8}}: {{::$ctrl.item.value8}}">
|
||||
{{::$ctrl.item.value8}}
|
||||
</section>
|
||||
<section
|
||||
class="inline-tag ellipsize"
|
||||
ng-class="::{empty: !$ctrl.item.value9}"
|
||||
ng-class="::{empty: !$ctrl.item.tag9}"
|
||||
title="{{::$ctrl.item.tag9}}: {{::$ctrl.item.value9}}">
|
||||
{{::$ctrl.item.value9}}
|
||||
</section>
|
||||
<section
|
||||
class="inline-tag ellipsize"
|
||||
ng-class="::{empty: !$ctrl.item.value10}"
|
||||
ng-class="::{empty: !$ctrl.item.tag10}"
|
||||
title="{{::$ctrl.item.tag10}}: {{::$ctrl.item.value10}}">
|
||||
{{::$ctrl.item.value10}}
|
||||
</section>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
vn-fetched-tags {
|
||||
& > vn-horizontal {
|
||||
align-items: center;
|
||||
|
||||
max-width: 210px;
|
||||
& > vn-auto {
|
||||
flex-wrap: wrap;
|
||||
|
||||
|
@ -43,17 +43,17 @@ vn-fetched-tags {
|
|||
& > .inline-tag {
|
||||
color: $color-font-secondary;
|
||||
text-align: center;
|
||||
font-size: .75rem;
|
||||
height: 12px;
|
||||
font-size: .8rem;
|
||||
height: 13px;
|
||||
padding: 1px;
|
||||
width: 64px;
|
||||
min-width: 64px;
|
||||
max-width: 64px;
|
||||
flex: 1;
|
||||
border: 1px solid $color-spacer;
|
||||
border: 1px solid $color-font-secondary;
|
||||
|
||||
&.empty {
|
||||
border: 1px solid $color-spacer-light;
|
||||
border: 1px solid darken($color-font-secondary, 30%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('cmr', {
|
||||
description: 'Returns the cmr',
|
||||
accessType: 'READ',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'id',
|
||||
type: 'number',
|
||||
required: true,
|
||||
description: 'The cmr id',
|
||||
http: {source: 'path'}
|
||||
}
|
||||
],
|
||||
returns: [
|
||||
{
|
||||
arg: 'body',
|
||||
type: 'file',
|
||||
root: true
|
||||
}, {
|
||||
arg: 'Content-Type',
|
||||
type: 'String',
|
||||
http: {target: 'header'}
|
||||
}, {
|
||||
arg: 'Content-Disposition',
|
||||
type: 'String',
|
||||
http: {target: 'header'}
|
||||
}
|
||||
],
|
||||
http: {
|
||||
path: '/:id/cmr',
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.cmr = (ctx, id) => Self.printReport(ctx, id, 'cmr');
|
||||
};
|
|
@ -14,6 +14,7 @@ module.exports = Self => {
|
|||
require('../methods/route/driverRouteEmail')(Self);
|
||||
require('../methods/route/sendSms')(Self);
|
||||
require('../methods/route/downloadZip')(Self);
|
||||
require('../methods/route/cmr')(Self);
|
||||
|
||||
Self.validate('kmStart', validateDistance, {
|
||||
message: 'Distance must be lesser than 1000'
|
||||
|
@ -28,5 +29,5 @@ module.exports = Self => {
|
|||
const routeMaxKm = 1000;
|
||||
if (routeTotalKm > routeMaxKm || this.kmStart > this.kmEnd)
|
||||
err();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -67,7 +67,7 @@ module.exports = function(Self) {
|
|||
throw new UserError(`This ticket is already invoiced`);
|
||||
|
||||
const priceZero = ticket.totalWithVat == 0;
|
||||
if (priceZero)
|
||||
if (ticketsIds.length == 1 && priceZero)
|
||||
throw new UserError(`A ticket with an amount of zero can't be invoiced`);
|
||||
});
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ module.exports = async function(ctx, Self, tickets, reqArgs = {}) {
|
|||
await Self.rawSql(`
|
||||
INSERT INTO clientSample (clientFk, typeFk, companyFk) VALUES(?, ?, ?)
|
||||
`, [ticket.clientFk, sample.id, ticket.companyFk], {userId});
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
// Domain not found
|
||||
if (error.responseCode == 450)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const loggable = require('vn-loopback/util/log');
|
||||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('componentUpdate', {
|
||||
|
@ -112,7 +113,6 @@ module.exports = Self => {
|
|||
}
|
||||
|
||||
try {
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const models = Self.app.models;
|
||||
const $t = ctx.req.__; // $translate
|
||||
await models.Ticket.isEditableOrThrow(ctx, args.id, myOptions);
|
||||
|
@ -127,11 +127,8 @@ module.exports = Self => {
|
|||
args.warehouseFk,
|
||||
myOptions);
|
||||
|
||||
if (!zoneShipped || zoneShipped.zoneFk != args.zoneFk) {
|
||||
const error = `You don't have privileges to change the zone`;
|
||||
|
||||
throw new UserError(error);
|
||||
}
|
||||
if (!zoneShipped || zoneShipped.zoneFk != args.zoneFk)
|
||||
throw new UserError(`You don't have privileges to change the zone`);
|
||||
}
|
||||
|
||||
if (args.isWithoutNegatives) {
|
||||
|
|
|
@ -248,6 +248,7 @@ module.exports = Self => {
|
|||
am.name AS agencyMode,
|
||||
am.id AS agencyModeFk,
|
||||
st.name AS state,
|
||||
st.classColor,
|
||||
wk.lastName AS salesPerson,
|
||||
ts.stateFk AS stateFk,
|
||||
ts.alertLevel AS alertLevel,
|
||||
|
@ -339,7 +340,8 @@ module.exports = Self => {
|
|||
{'tp.isFreezed': hasProblem},
|
||||
{'tp.risk': hasProblem},
|
||||
{'tp.hasTicketRequest': hasProblem},
|
||||
{'tp.itemShortage': range}
|
||||
{'tp.itemShortage': range},
|
||||
{'tp.hasRounding': hasProblem}
|
||||
]};
|
||||
|
||||
if (hasWhere)
|
||||
|
|
|
@ -194,7 +194,8 @@ module.exports = Self => {
|
|||
{'tp.hasTicketRequest': hasProblem},
|
||||
{'tp.itemShortage': range},
|
||||
{'tp.hasComponentLack': hasProblem},
|
||||
{'tp.isTooLittle': hasProblem}
|
||||
{'tp.isTooLittle': hasProblem},
|
||||
{'tp.hasRounding': hasProblem}
|
||||
]
|
||||
};
|
||||
|
||||
|
|
|
@ -27,6 +27,9 @@
|
|||
"code": {
|
||||
"type": "string",
|
||||
"required": false
|
||||
},
|
||||
"classColor": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,6 +123,12 @@
|
|||
class="bright"
|
||||
icon="icon-components">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
ng-show="::ticket.hasRounding"
|
||||
translate-attr="{title: 'Rounding'}"
|
||||
class="bright"
|
||||
icon="sync_problem">
|
||||
</vn-icon>
|
||||
</td>
|
||||
<td><span
|
||||
ng-click="ticketDescriptor.show($event, ticket.id)"
|
||||
|
|
|
@ -75,6 +75,12 @@
|
|||
class="bright"
|
||||
icon="icon-components">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
ng-show="::ticket.hasRounding"
|
||||
translate-attr="{title: 'Rounding'}"
|
||||
class="bright"
|
||||
icon="sync_problem">
|
||||
</vn-icon>
|
||||
</vn-td>
|
||||
<vn-td shrink>{{::ticket.id}}</vn-td>
|
||||
<vn-td class="expendable">
|
||||
|
|
|
@ -71,8 +71,9 @@ module.exports = Self => {
|
|||
'Stored on': 'created',
|
||||
'Document ID': 'id'
|
||||
};
|
||||
|
||||
workerDocuware =
|
||||
await models.Docuware.getById('hr', worker.lastName + worker.firstName, docuwareParse) ?? [];
|
||||
await models.Docuware.getById('hr', worker.lastName + ' ' + worker.firstName, docuwareParse) ?? [];
|
||||
for (document of workerDocuware) {
|
||||
const defaultData = {
|
||||
file: 'dw' + document.id + '.png',
|
||||
|
|
|
@ -36,9 +36,9 @@ module.exports = Self => {
|
|||
if (isSubordinate === false)
|
||||
throw new UserError(`You don't have enough privileges`);
|
||||
|
||||
const subordinate = await Worker.findById(ctx.args.workerFk);
|
||||
const subordinate = await Worker.findById(ctx.args.workerFk, {fields: ['id']});
|
||||
filter = mergeFilters(filter, {where: {
|
||||
userFk: subordinate.userFk
|
||||
userFk: subordinate.id
|
||||
}});
|
||||
|
||||
return Self.find(filter);
|
||||
|
|
|
@ -20,11 +20,11 @@ describe('Worker new', () => {
|
|||
const employeeId = 1;
|
||||
const defaultWorker = {
|
||||
fi: '78457139E',
|
||||
name: 'defaultWorker',
|
||||
firstName: 'default',
|
||||
lastNames: 'worker',
|
||||
name: 'DEFAULTERWORKER',
|
||||
firstName: 'DEFAULT',
|
||||
lastNames: 'WORKER',
|
||||
email: 'defaultWorker@mydomain.com',
|
||||
street: 'S/ defaultWorkerStreet',
|
||||
street: 'S/ DEFAULTWORKERSTREET',
|
||||
city: 'defaultWorkerCity',
|
||||
provinceFk: 1,
|
||||
companyFk: 442,
|
||||
|
|
|
@ -25,8 +25,7 @@
|
|||
"type" : "string"
|
||||
},
|
||||
"userFk": {
|
||||
"type" : "number",
|
||||
"required": true
|
||||
"type" : "number"
|
||||
},
|
||||
"bossFk": {
|
||||
"type" : "number"
|
||||
|
|
|
@ -32,6 +32,28 @@ class Controller extends Descriptor {
|
|||
this.vnApp.showSuccess(this.$t('Department deleted.'));
|
||||
});
|
||||
}
|
||||
|
||||
loadData() {
|
||||
const filter = {
|
||||
fields: ['id', 'name', 'code', 'workerFk', 'isProduction', 'chatName',
|
||||
'isTeleworking', 'notificationEmail', 'hasToRefill', 'hasToSendMail', 'hasToMistake', 'clientFk'],
|
||||
include: [
|
||||
{relation: 'client',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}},
|
||||
{
|
||||
relation: 'worker',
|
||||
scope: {
|
||||
fields: ['id', 'firstName', 'lastName']
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.getData(`Departments/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$element', '$scope', '$rootScope'];
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
filter="::$ctrl.filter"
|
||||
data="$ctrl.hours">
|
||||
</vn-crud-model>
|
||||
<div ng-if="$ctrl.card.hasWorkCenter">
|
||||
<div>
|
||||
<vn-card class="vn-pa-lg vn-w-lg">
|
||||
<vn-table model="model" auto-load="false">
|
||||
<vn-thead>
|
||||
|
@ -106,12 +106,6 @@
|
|||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</div>
|
||||
<div
|
||||
ng-if="!$ctrl.card.hasWorkCenter"
|
||||
class="bg-title"
|
||||
translate>
|
||||
Autonomous worker
|
||||
</div>
|
||||
|
||||
<vn-side-menu side="right">
|
||||
<div class="vn-pa-md">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "salix-back",
|
||||
"version": "23.32.01",
|
||||
"version": "23.34.01",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "salix-back",
|
||||
"version": "23.32.01",
|
||||
"version": "23.34.01",
|
||||
"author": "Verdnatura Levante SL",
|
||||
"description": "Salix backend",
|
||||
"license": "GPL-3.0",
|
||||
|
|
|
@ -539,9 +539,9 @@
|
|||
<Stroke>2</Stroke>
|
||||
<Width>4</Width>
|
||||
</GraphicShape>
|
||||
<GraphicShape xsi:type="WindowText" Style="Cross" IsPrint="true" PageAlignment="None" Locked="false" bStroke="true" bFill="true" Direction="Angle90" X="613" Y="24" Alignment="Left" AlignPointX="613" AlignPointY="24" FontScript="Default" FontCmd="Arial,118.2266,B
" FontHeight="1" FontWidth="1" TextSpace="0" bSpaceCropping="false">
|
||||
<GraphicShape xsi:type="WindowText" Style="Cross" IsPrint="true" PageAlignment="None" Locked="false" bStroke="true" bFill="true" Direction="Angle90" X="564" Y="32" Alignment="Left" AlignPointX="564" AlignPointY="32" FontScript="Default" FontCmd="Arial,118.2266,B
" FontHeight="1" FontWidth="1" TextSpace="0" bSpaceCropping="false">
|
||||
<qHitOnCircumferance>false</qHitOnCircumferance>
|
||||
<Selected>false</Selected>
|
||||
<Selected>true</Selected>
|
||||
<iBackground_color>4294967295</iBackground_color>
|
||||
<Id>5</Id>
|
||||
<ItemLabel>W5</ItemLabel>
|
||||
|
@ -571,15 +571,15 @@
|
|||
<BoundRectHeight>2896</BoundRectHeight>
|
||||
<BoundRect>
|
||||
<Location>
|
||||
<X>187</X>
|
||||
<Y>24</Y>
|
||||
<X>138</X>
|
||||
<Y>32</Y>
|
||||
</Location>
|
||||
<Size>
|
||||
<Width>426</Width>
|
||||
<Height>2896</Height>
|
||||
</Size>
|
||||
<X>187</X>
|
||||
<Y>24</Y>
|
||||
<X>138</X>
|
||||
<Y>32</Y>
|
||||
<Width>426</Width>
|
||||
<Height>2896</Height>
|
||||
</BoundRect>
|
||||
|
@ -621,14 +621,14 @@
|
|||
<Setup bInfinityPrint="false" LabelLength="610" LabelWidth="100" LeftMargin="0" TopMargin="0" LabelType="1" GapLength="3" FeedLength="0" ZSign="43" BlackMark="3" Position="0" Speed="2" Copy="1" bCopyDataBase="false" CopyField="None" Stripper="0" LabelsPerCut="0" DoubleCut_Enable="false" DoubleCut_OffsetLen="0" DoubleCut_FirstCutMode="1" Rotate180="200" Stop="35" Darkness="5" Number="1" bCutDataBase="false" bBatchCut="false" bNumberDataBase="false" NumberField="None" PageDirection="Portrait" PrintMode="0" PowerRFID="10" LengthRFID="0" RetryRFID="3" DrawMode="0">
|
||||
<Layout Shape="0" AcrossType="Copied" PageDirection="Portrait" HorAcross="1" VerAcross="1" HorGap="0" VerGap="0" HorAcrossMode1="1" VerAcrossMode1="1" LabelMode="0" HorGapMode1="0" VerGapMode1="0" BottomMargin="0" RightMargin="0" />
|
||||
<Description>New label
|
||||
Lang:(es-ES) OS:Microsoft Windows NT 10.0.22000.0(Win32NT)</Description>
|
||||
Lang:(es-ES) OS:Microsoft Windows NT 10.0.19045.0(Win32NT)</Description>
|
||||
<UnitType>Mm</UnitType>
|
||||
<Dpi>203</Dpi>
|
||||
</Setup>
|
||||
<PrinterModel />
|
||||
<PrinterLanguage>EZPL</PrinterLanguage>
|
||||
<USBName>GODEX G300#132207AB</USBName>
|
||||
<COMName>None</COMName>
|
||||
<USBName>00000000</USBName>
|
||||
<COMName>COM1</COMName>
|
||||
<CommunicationType>USB</CommunicationType>
|
||||
<NetworkIPAddress>2886794855</NetworkIPAddress>
|
||||
<NetworkPort>9100</NetworkPort>
|
|
@ -1,9 +1,9 @@
|
|||
[
|
||||
{
|
||||
"filename": "model.ezp",
|
||||
"filename": "model.ezpx",
|
||||
"component": "printer-setup",
|
||||
"path": "/assets/files/model.ezp",
|
||||
"cid": "model.ezp"
|
||||
"path": "/assets/files/model.ezpx",
|
||||
"cid": "model.ezpx"
|
||||
},
|
||||
{
|
||||
"filename": "port.png",
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
const Stylesheet = require(`vn-print/core/stylesheet`);
|
||||
|
||||
const path = require('path');
|
||||
const vnPrintPath = path.resolve('print');
|
||||
|
||||
module.exports = new Stylesheet([
|
||||
`${vnPrintPath}/common/css/spacing.css`,
|
||||
`${vnPrintPath}/common/css/misc.css`,
|
||||
`${vnPrintPath}/common/css/layout.css`,
|
||||
`${vnPrintPath}/common/css/report.css`,
|
||||
`${__dirname}/style.css`])
|
||||
.mergeStyles();
|
|
@ -0,0 +1,101 @@
|
|||
html {
|
||||
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
|
||||
margin: 10px;
|
||||
font-size: 22px;
|
||||
}
|
||||
.mainTable, .specialTable, .categoryTable {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: inherit;
|
||||
}
|
||||
.mainTable td {
|
||||
width: 50%;
|
||||
border: 1px solid black;
|
||||
vertical-align: top;
|
||||
padding: 15px;
|
||||
font-size: inherit;
|
||||
}
|
||||
.signTable {
|
||||
height: 12%;
|
||||
}
|
||||
.signTable td {
|
||||
width: calc(100% / 3);
|
||||
border: 1px solid black;
|
||||
vertical-align: top;
|
||||
font-size: inherit;
|
||||
padding: 15px;
|
||||
border-top: none;
|
||||
}
|
||||
#title {
|
||||
font-weight: bold;
|
||||
font-size: 85px;
|
||||
}
|
||||
hr {
|
||||
border: 1px solid #cccccc;
|
||||
height: 0px;
|
||||
border-radius: 25px;
|
||||
}
|
||||
#cellHeader {
|
||||
border: 0px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#label, #merchandiseLabels {
|
||||
font-size: 13px;
|
||||
}
|
||||
#merchandiseLabels {
|
||||
border: none;
|
||||
}
|
||||
.imgSection {
|
||||
text-align: center;
|
||||
height: 200px;
|
||||
overflow: hidden;
|
||||
}
|
||||
img {
|
||||
object-fit: contain;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
#lineBreak {
|
||||
white-space: pre-line;
|
||||
}
|
||||
.specialTable td {
|
||||
border: 1px solid black;
|
||||
vertical-align: top;
|
||||
padding: 15px;
|
||||
font-size: inherit;
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
}
|
||||
.specialTable #itemCategoryList {
|
||||
width: 70%;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.categoryTable {
|
||||
padding-bottom: none;
|
||||
}
|
||||
.categoryTable td {
|
||||
vertical-align: top;
|
||||
font-size: inherit;
|
||||
border: none;
|
||||
padding: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.categoryTable #merchandiseLabels {
|
||||
border-bottom: 4px solid #cccccc;
|
||||
padding: none;
|
||||
}
|
||||
#merchandiseDetail {
|
||||
font-weight: bold;
|
||||
padding-top: 10px;
|
||||
}
|
||||
#merchandiseData {
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
#merchandiseLabels td {
|
||||
padding-bottom: 11px;
|
||||
max-width: 300px;
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<body>
|
||||
<table class="mainTable">
|
||||
<tr>
|
||||
<td>
|
||||
<span id="label">1. Remitente / Expediteur / Sender</span>
|
||||
<hr>
|
||||
<b>{{data.senderName}}</b><br>
|
||||
{{data.senderStreet}}<br>
|
||||
{{data.senderPostCode}} {{data.senderCity}} {{(data.senderCountry) ? `(${data.senderCountry})` : null}}
|
||||
</td>
|
||||
<td id="cellHeader">
|
||||
<span id="title">CMR</span><br>
|
||||
{{data.cmrFk}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span id="label">2. Consignatario / Destinataire / Consignee</span>
|
||||
<hr>
|
||||
<b>{{data.deliveryAddressFk}}<br>
|
||||
{{data.deliveryName}}<br>
|
||||
{{data.deliveryPhone || data.clientPhone}}
|
||||
{{((data.deliveryPhone || data.clientPhone) && data.deliveryMobile) ? '/' : null}}
|
||||
{{data.deliveryMobile}}</b>
|
||||
</td>
|
||||
<td>
|
||||
<span id="label">16. Transportista / Transporteur / Carrier</span>
|
||||
<hr>
|
||||
<b>{{data.carrierName}}</b><br>
|
||||
{{data.carrierStreet}}<br>
|
||||
{{data.carrierPostalCode}} {{data.carrierCity}} {{(data.carrierCountry) ? `(${data.carrierCountry})` : null}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span id="label">
|
||||
3. Lugar y fecha de entrega /
|
||||
Lieu et date de livraison /
|
||||
Place and date of delivery
|
||||
</span>
|
||||
<hr>
|
||||
<b>{{data.deliveryStreet}}<br>
|
||||
{{data.deliveryPostalCode}} {{data.deliveryCity}} {{(data.deliveryCountry) ? `(${data.deliveryCountry})` : null}}<br>
|
||||
{{(data.ead) ? formatDate(data.ead, '%d/%m/%Y') : null}}</b>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
<span id="label">17. Porteadores sucesivos / Transporteurs succesifs / Succesive Carriers</span>
|
||||
<hr>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span id="label">
|
||||
4. Lugar y fecha de carga /
|
||||
Lieu et date del prise en charge de la merchandise /
|
||||
Place and date of taking over the goods
|
||||
</span>
|
||||
<hr>
|
||||
<b>{{data.loadStreet}}<br>
|
||||
{{data.loadPostalCode}} {{data.loadCity}} {{(data.loadCountry) ? `(${data.loadCountry})` : null}}<br>
|
||||
{{formatDate(data.created, '%d/%m/%Y')}}</b>
|
||||
</td>
|
||||
<td rowspan="2">
|
||||
<span id="label">
|
||||
18. Obervaciones del transportista /
|
||||
Reserves et observations du transporteur /
|
||||
Carrier's reservations and observations
|
||||
</span>
|
||||
<hr>
|
||||
<b>{{data.truckPlate}}</b><br>
|
||||
{{data.observations}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span id="label">5. Documentos anexos / Documents annexes / Documents attached</span>
|
||||
<hr>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="specialTable">
|
||||
<tr>
|
||||
<td>
|
||||
<span id="label">
|
||||
7 & 8. Número de bultos y clase de embalage /
|
||||
Number of packages and packaging class /
|
||||
Nombre de colis et classe d'emballage
|
||||
</span>
|
||||
<hr>
|
||||
<div id="lineBreak">
|
||||
<b>{{data.packagesList}}</b>
|
||||
</div>
|
||||
</td>
|
||||
<td id="itemCategoryList">
|
||||
<table class="categoryTable">
|
||||
<tr id="merchandiseLabels">
|
||||
<td>6. Marcas y números / Brands and numbers / Marques et numéros</td>
|
||||
<td>9. Naturaleza de la merc. / Nature of goods / Nature des marchandises</td>
|
||||
<td>10. nº Estadístico / Statistical no. / n° statistique</td>
|
||||
<td>11. Peso bruto / Gross weight / Poids brut (kg)</td>
|
||||
<td>12. Volumen / Volume (m3)</td>
|
||||
</tr>
|
||||
<tr v-for="merchandise in merchandises" id="merchandiseData">
|
||||
<td>{{merchandise.ticketFk}}</td>
|
||||
<td>{{merchandise.name}}</td>
|
||||
<td>N/A</td>
|
||||
<td>{{merchandise.weight}}</td>
|
||||
<td>{{merchandise.volume}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div v-if="!merchandises" id="merchandiseDetail">
|
||||
{{data.merchandiseDetail}}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="mainTable">
|
||||
<tr>
|
||||
<td>
|
||||
<span id="label">
|
||||
13. Instrucciones del remitente /
|
||||
Instrunstions de l'expèditeur / Sender
|
||||
instruccions
|
||||
</span>
|
||||
<hr>
|
||||
<b>{{data.senderInstruccions}}</b>
|
||||
</td>
|
||||
<td>
|
||||
<span id="label">
|
||||
19. Estipulaciones particulares /
|
||||
Conventions particulieres /
|
||||
Special agreements
|
||||
</span>
|
||||
<hr>
|
||||
<b>{{data.specialAgreements}}</b>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span id="label">
|
||||
14. Forma de pago /
|
||||
Prescriptions d'affranchissement /
|
||||
Instruction as to payment for carriage
|
||||
</span>
|
||||
<hr>
|
||||
<b>{{data.paymentInstruccions}}</b>
|
||||
</td>
|
||||
<td>
|
||||
<span id="label">20. A pagar por / Être payé pour / To be paid by</span>
|
||||
<hr>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<span id="label">21. Formalizado en / Etabile a / Estabilshed in</span>
|
||||
<hr>
|
||||
<b>{{data.loadStreet}}</b><br>
|
||||
{{data.loadPostalCode}} {{data.loadCity}} {{(data.loadCountry) ? `(${data.loadCountry})` : null}} <br>
|
||||
</td>
|
||||
<td>
|
||||
<span id="label">15. Reembolso / Remboursement / Cash on delivery</span>
|
||||
<hr>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
<table class="signTable">
|
||||
<tr>
|
||||
<td>
|
||||
<span id="label">
|
||||
22. Firma y sello del remitente /
|
||||
Signature et timbre de l'expèditeur /
|
||||
Signature and stamp of the sender
|
||||
</span>
|
||||
<hr>
|
||||
<div class="imgSection">
|
||||
<img :src="senderStamp"/>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span id="label">
|
||||
23. Firma y sello del transportista /
|
||||
Signature et timbre du transporteur /
|
||||
Signature and stamp of the carrier
|
||||
</span>
|
||||
<hr>
|
||||
<div class="imgSection">
|
||||
<img :src="deliveryStamp"/>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<span id="label">
|
||||
24. Firma y sello del consignatario /
|
||||
Signature et timbre du destinataire /
|
||||
Signature and stamp of the consignee
|
||||
</span>
|
||||
<hr>
|
||||
<div class="imgSection">
|
||||
<img :src="signPath"/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,45 @@
|
|||
const config = require(`vn-print/core/config`);
|
||||
const vnReport = require('../../../core/mixins/vn-report.js');
|
||||
const md5 = require('md5');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
const prefixBase64 = 'data:image/png;base64,';
|
||||
|
||||
module.exports = {
|
||||
name: 'cmr',
|
||||
mixins: [vnReport],
|
||||
async serverPrefetch() {
|
||||
this.data = await this.findOneFromDef('data', [this.id]);
|
||||
if (this.data.ticketFk) {
|
||||
this.merchandises = await this.rawSqlFromDef('merchandise', [this.data.ticketFk]);
|
||||
this.signature = await this.findOneFromDef('signature', [this.data.ticketFk]);
|
||||
} else
|
||||
this.merchandises = null;
|
||||
|
||||
this.senderStamp = (this.data.senderStamp)
|
||||
? `${prefixBase64} ${this.data.senderStamp.toString('base64')}`
|
||||
: null;
|
||||
this.deliveryStamp = (this.data.deliveryStamp)
|
||||
? `${prefixBase64} ${this.data.deliveryStamp.toString('base64')}`
|
||||
: null;
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
description: 'The cmr id'
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
signPath() {
|
||||
if (!this.signature) return;
|
||||
|
||||
const signatureName = this.signature.signature
|
||||
const hash = md5(signatureName.toString()).substring(0, 3);
|
||||
const file = `${config.storage.root}/${hash}/${signatureName}.png`;
|
||||
if (!fs.existsSync(file)) return null;
|
||||
|
||||
return `${prefixBase64} ${Buffer.from(fs.readFileSync(file), 'utf8').toString('base64')}`;
|
||||
},
|
||||
}
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
reportName: cmr
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"format": "A4"
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
SELECT c.id cmrFk,
|
||||
t.id ticketFk,
|
||||
c.truckPlate,
|
||||
c.observations,
|
||||
c.senderInstruccions,
|
||||
c.paymentInstruccions,
|
||||
c.specialAgreements,
|
||||
c.created,
|
||||
c.packagesList,
|
||||
c.merchandiseDetail,
|
||||
c.ead,
|
||||
s.name carrierName,
|
||||
s.street carrierStreet,
|
||||
s.postCode carrierPostCode,
|
||||
s.city carrierCity,
|
||||
cou.country carrierCountry,
|
||||
s2.name senderName,
|
||||
s2.street senderStreet,
|
||||
s2.postCode senderPostCode,
|
||||
s2.city senderCity,
|
||||
cou2.country senderCountry,
|
||||
a.street deliveryStreet,
|
||||
a.id deliveryAddressFk,
|
||||
a.postalCode deliveryPostalCode,
|
||||
a.city deliveryCity,
|
||||
a.nickname deliveryName,
|
||||
a.phone deliveryPhone,
|
||||
a.mobile deliveryMobile,
|
||||
cou3.country deliveryCountry,
|
||||
cl.phone clientPhone,
|
||||
a2.street loadStreet,
|
||||
a2.postalCode loadPostalCode,
|
||||
a2.city loadCity,
|
||||
cou4.country loadCountry,
|
||||
co.stamp senderStamp,
|
||||
s.stamp deliveryStamp
|
||||
FROM cmr c
|
||||
LEFT JOIN supplier s ON s.id = c.supplierFk
|
||||
LEFT JOIN country cou ON cou.id = s.countryFk
|
||||
LEFT JOIN company co ON co.id = c.companyFk
|
||||
LEFT JOIN supplierAccount sa ON sa.id = co.supplierAccountFk
|
||||
LEFT JOIN supplier s2 ON s2.id = sa.supplierFk
|
||||
LEFT JOIN country cou2 ON cou2.id = s2.countryFk
|
||||
LEFT JOIN `address` a ON a.id = c.addressToFk
|
||||
LEFT JOIN province p ON p.id = a.provinceFk
|
||||
LEFT JOIN country cou3 ON cou3.id = p.countryFk
|
||||
LEFT JOIN client cl ON cl.id = a.clientFk
|
||||
LEFT JOIN `address` a2 ON a2.id = c.addressFromFk
|
||||
LEFT JOIN province p2 ON p2.id = a2.provinceFk
|
||||
LEFT JOIN country cou4 ON cou4.id = p2.countryFk
|
||||
LEFT JOIN ticket t ON t.cmrFk = c.id
|
||||
WHERE c.id = ?
|
|
@ -0,0 +1,11 @@
|
|||
SELECT s.ticketFk,
|
||||
ic.name,
|
||||
CAST(SUM(sv.weight) AS DECIMAL(10,2)) `weight`,
|
||||
CAST(SUM(sv.volume) AS DECIMAL(10,3)) volume
|
||||
FROM sale s
|
||||
JOIN saleVolume sv ON sv.saleFk = s.id
|
||||
JOIN item i ON i.id = s.itemFk
|
||||
JOIN itemType it ON it.id = i.typeFk
|
||||
JOIN itemCategory ic ON ic.id = it.categoryFk
|
||||
WHERE sv.ticketFk = ?
|
||||
GROUP BY ic.id
|
|
@ -0,0 +1,5 @@
|
|||
SELECT dc.id `signature`
|
||||
FROM ticket t
|
||||
JOIN ticketDms dt ON dt.ticketFk = t.id
|
||||
LEFT JOIN dms dc ON dc.id = dt.dmsFk
|
||||
WHERE t.id = ?
|
Loading…
Reference in New Issue