Merge branch 'dev' into 4059-revocar-permisos-client-account
This commit is contained in:
commit
7ec47f0cc3
|
@ -6,10 +6,17 @@ 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).
|
||||
|
||||
|
||||
## [2340.01] - 2023-10-05
|
||||
|
||||
### Added
|
||||
### Changed
|
||||
|
||||
### Fixed
|
||||
|
||||
## [2338.01] - 2023-09-21
|
||||
|
||||
### Added
|
||||
|
||||
- (Ticket -> Servicios) Se pueden abonar servicios
|
||||
### Changed
|
||||
- (Trabajadores -> Calendario) Icono de check arreglado cuando pulsas un tipo de dia
|
||||
|
||||
|
|
|
@ -139,7 +139,7 @@ module.exports = Self => {
|
|||
ftpClient.exec((err, response) => {
|
||||
if (err || response.error) {
|
||||
console.debug(`Error downloading checksum file... ${response.error}`);
|
||||
return reject(err);
|
||||
return reject(response.error || err);
|
||||
}
|
||||
|
||||
resolve(response);
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
},
|
||||
"Bank": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"Buyer": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"Campaign": {
|
||||
"dataSource": "vn"
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "Buyer",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "buyer"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"userFk": {
|
||||
"type": "number",
|
||||
"required": true,
|
||||
"id": true
|
||||
},
|
||||
"nickname": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"acls": [
|
||||
{
|
||||
"accessType": "READ",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "employee",
|
||||
"permission": "ALLOW"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -3,11 +3,11 @@ INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `pri
|
|||
('Ticket', 'editDiscount', 'WRITE', 'ALLOW', 'ROLE', 'claimManager'),
|
||||
('Ticket', 'editDiscount', 'WRITE', 'ALLOW', 'ROLE', 'salesPerson'),
|
||||
('Ticket', 'isRoleAdvanced', '*', 'ALLOW', 'ROLE', 'salesAssistant'),
|
||||
('Ticket', 'isRoleAdvanced', '*', 'ALLOW', 'ROLE', 'deliveryBoss'),
|
||||
('Ticket', 'isRoleAdvanced', '*', 'ALLOW', 'ROLE', 'deliveryAssistant'),
|
||||
('Ticket', 'isRoleAdvanced', '*', 'ALLOW', 'ROLE', 'buyer'),
|
||||
('Ticket', 'isRoleAdvanced', '*', 'ALLOW', 'ROLE', 'claimManager'),
|
||||
('Ticket', 'deleteTicketWithPartPrepared', 'WRITE', 'ALLOW', 'ROLE', 'salesAssistant'),
|
||||
('Ticket', 'editZone', 'WRITE', 'ALLOW', 'ROLE', 'deliveryBoss'),
|
||||
('Ticket', 'editZone', 'WRITE', 'ALLOW', 'ROLE', 'deliveryAssistant'),
|
||||
('State', 'editableStates', 'READ', 'ALLOW', 'ROLE', 'employee'),
|
||||
('State', 'seeEditableStates', 'READ', 'ALLOW', 'ROLE', 'administrative'),
|
||||
('State', 'seeEditableStates', 'READ', 'ALLOW', 'ROLE', 'production'),
|
|
@ -1,4 +1,4 @@
|
|||
INSERT INTO `account`.`role` (`id`, `name`, `description`, `hasLogin`)
|
||||
INSERT INTO `account`.`role` (`name`, `description`, `hasLogin`)
|
||||
VALUES ('claimViewer','Trabajadores que consulta las reclamaciones ',1);
|
||||
|
||||
INSERT INTO `account`.`roleInherit` (`role`,`inheritsFrom`)
|
||||
|
@ -10,7 +10,7 @@ INSERT INTO `account`.`roleInherit` (`role`,`inheritsFrom`)
|
|||
'buyer',
|
||||
'deliveryBoss',
|
||||
'handmadeBoss'
|
||||
)
|
||||
);
|
||||
|
||||
DELETE FROM `salix`.`ACL`
|
||||
WHERE `model`= 'claim'
|
||||
|
@ -28,5 +28,4 @@ INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`princip
|
|||
INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalid`)
|
||||
VALUES ('Claim','findById','READ','ALLOW','ROLE','claimViewer');
|
||||
INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalid`)
|
||||
VALUES ('Claim','getSummary','READ','ALLOW','ROLE','claimViewer');
|
||||
|
||||
VALUES ('Claim','getSummary','READ','ALLOW','ROLE','claimViewer');
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE `vn`.`province` ADD CONSTRAINT `countryName_UN` UNIQUE KEY (`countryFk`,`name`);
|
|
@ -0,0 +1,62 @@
|
|||
|
||||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`item_setVisibleDiscard`(
|
||||
vItemFk INT,
|
||||
vWarehouseFk INT,
|
||||
vQuantity INT,
|
||||
vAddressFk INT)
|
||||
|
||||
BEGIN
|
||||
DECLARE vTicketFk INT;
|
||||
DECLARE vClientFk INT;
|
||||
DECLARE vCompanyVnlFk INT;
|
||||
DECLARE vCalc INT;
|
||||
|
||||
SELECT barcodeToItem(vItemFk) INTO vItemFk;
|
||||
|
||||
SELECT DEFAULT(companyFk) INTO vCompanyVnlFk
|
||||
FROM vn.ticket LIMIT 1;
|
||||
|
||||
SELECT a.clientFk INTO vClientFk
|
||||
FROM address a
|
||||
WHERE a.id = vAddressFk;
|
||||
|
||||
SELECT t.id INTO vTicketFk
|
||||
FROM ticket t
|
||||
JOIN address a ON a.id = t.addressFk
|
||||
WHERE t.warehouseFk = vWarehouseFk
|
||||
AND a.id = vAddressFk
|
||||
AND DATE(t.shipped) = util.VN_CURDATE();
|
||||
|
||||
CALL cache.visible_refresh(vCalc, TRUE, vWarehouseFk);
|
||||
|
||||
IF vTicketFk IS NULL THEN
|
||||
CALL ticket_add(
|
||||
vClientFk,
|
||||
util.VN_CURDATE(),
|
||||
vWarehouseFk,
|
||||
vCompanyVnlFk,
|
||||
vAddressFk,
|
||||
NULL,
|
||||
NULL,
|
||||
util.VN_CURDATE(),
|
||||
account.myUser_getId(),
|
||||
FALSE,
|
||||
vTicketFk);
|
||||
END IF;
|
||||
|
||||
INSERT INTO sale(ticketFk, itemFk, concept, quantity)
|
||||
SELECT vTicketFk,
|
||||
vItemFk,
|
||||
CONCAT(longName,' ', getWorkerCode(), ' ', LEFT(CAST(util.VN_NOW() AS TIME),5)),
|
||||
vQuantity
|
||||
FROM item
|
||||
WHERE id = vItemFk;
|
||||
|
||||
UPDATE cache.visible
|
||||
SET visible = visible - vQuantity
|
||||
WHERE calc_id = vCalc
|
||||
AND item_id = vItemFk;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
|
||||
VALUES('Item', 'setVisibleDiscard', 'WRITE', 'ALLOW', 'ROLE', 'employee');
|
||||
|
||||
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
|
||||
VALUES('Address', 'getAddress', 'READ', 'ALLOW', 'ROLE', 'employee');
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
-- Auto-generated SQL script. Actual values for binary/complex data types may differ - what you see is the default string representation of values.
|
||||
INSERT INTO `account`.`role` (name,description)
|
||||
VALUES ('deliveryAssistant','Jefe auxiliar repartos');
|
||||
|
||||
INSERT INTO `account`.`roleInherit` (role, inheritsFrom)
|
||||
SELECT (SELECT id FROM account.role r1 WHERE r1.name = 'deliveryAssistant'), ri.inheritsFrom
|
||||
FROM account.roleInherit ri
|
||||
JOIN account.role r2 ON r2.id = ri.`role`
|
||||
WHERE r2.name = 'deliveryBoss';
|
||||
|
||||
INSERT INTO `account`.`roleInherit` (role, inheritsFrom)
|
||||
SELECT (SELECT id FROM account.role WHERE name = 'deliveryBoss') role,
|
||||
(SELECT id FROM account.role WHERE name = 'deliveryAssistant') roleInherit;
|
||||
|
||||
|
||||
CALL `account`.`role_syncPrivileges`();
|
File diff suppressed because one or more lines are too long
|
@ -358,20 +358,20 @@ INSERT INTO `vn`.`contactChannel`(`id`, `name`)
|
|||
(4, 'GCN Channel'),
|
||||
(5, 'The Newspaper');
|
||||
|
||||
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`)
|
||||
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`,`typeFk`)
|
||||
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'),
|
||||
(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'),
|
||||
(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'),
|
||||
(1111, 'Missing', NULL, 'MISSING MAN', 'Anton', 'THE SPACE, UNIVERSE FAR AWAY', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, 'others'),
|
||||
(1112, 'Trash', NULL, 'GARBAGE MAN', 'Unknown name', 'NEW YORK CITY, UNDERGROUND', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, 'others');
|
||||
(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','loses'),
|
||||
(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','normal'),
|
||||
(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','normal'),
|
||||
(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','normal'),
|
||||
(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','normal'),
|
||||
(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','normal'),
|
||||
(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','normal'),
|
||||
(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','normal'),
|
||||
(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','normal'),
|
||||
(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','normal'),
|
||||
(1111, 'Missing', NULL, 'MISSING MAN', 'Anton', 'THE SPACE, UNIVERSE FAR AWAY', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, 'others','normal'),
|
||||
(1112, 'Trash', NULL, 'GARBAGE MAN', 'Unknown name', 'NEW YORK CITY, UNDERGROUND', 'Gotham', 46460, 1111111111, 222222222, 1, NULL, NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1, NULL, 10, 5, util.VN_CURDATE(), 1, 5, 1, 1, 1, '0000-00-00', 4, 0, 1, 0, NULL, 1, 0, NULL, 0, 1, 'others','normal');
|
||||
|
||||
INSERT INTO `vn`.`client`(`id`, `name`, `fi`, `socialName`, `contact`, `street`, `city`, `postcode`, `isRelevant`, `email`, `iban`,`dueDay`,`accountingAccount`, `isEqualizated`, `provinceFk`, `hasToInvoice`, `credit`, `countryFk`, `isActive`, `gestdocFk`, `quality`, `payMethodFk`,`created`, `isTaxDataChecked`)
|
||||
SELECT id, name, CONCAT(RPAD(CONCAT(id,9),8,id),'A'), CONCAT(name, 'Social'), CONCAT(name, 'Contact'), CONCAT(name, 'Street'), 'GOTHAM', 46460, 1, CONCAT(name,'@mydomain.com'), NULL, 0, 1234567890, 0, 1, 1, 300, 1, 1,NULL, 10, 5, util.VN_CURDATE(), 1
|
||||
|
@ -1013,7 +1013,7 @@ INSERT INTO `vn`.`sale`(`id`, `itemFk`, `ticketFk`, `concept`, `quantity`, `pric
|
|||
(4, 4, 1, 'Melee weapon heavy shield 100cm', 20, 1.69, 0, 0, 0, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)),
|
||||
(5, 1, 2, 'Ranged weapon longbow 200cm', 1, 110.33, 0, 0, 0, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH)),
|
||||
(6, 1, 3, 'Ranged weapon longbow 200cm', 1, 110.33, 0, 0, 0, DATE_ADD(util.VN_CURDATE(), INTERVAL -2 MONTH)),
|
||||
(7, 2, 11, 'Melee weapon combat fist 15cm', 15, 7.44, 0, 0, 0, util.VN_CURDATE()),
|
||||
(7, 2, 11, 'Melee weapon combat fist 15cm', 15, 7.74, 0, 0, 0, util.VN_CURDATE()),
|
||||
(8, 4, 11, 'Melee weapon heavy shield 100cm', 10, 1.79, 0, 0, 0, util.VN_CURDATE()),
|
||||
(9, 1, 16, 'Ranged weapon longbow 200cm', 1, 103.49, 0, 0, 0, util.VN_CURDATE()),
|
||||
(10, 2, 16, 'Melee weapon combat fist 15cm', 10, 7.09, 0, 0, 0, util.VN_CURDATE()),
|
||||
|
@ -2973,4 +2973,4 @@ INSERT INTO vn.XDiario (id, ASIEN, FECHA, SUBCTA, CONTRA, CONCEPTO, EURODEBE, EU
|
|||
(3, 1.0, util.VN_CURDATE(), '4770000010', '4300001104', 'Inmovilizado pendiente : n/fra T3333333 Tony Stark', NULL, 0.81, 8.07, 'T', '3333333', 10.00, NULL, NULL, NULL, NULL, NULL, '', '2', '', 1, 1, '06089160W', 'IRON MAN', 1, 1, 0, util.VN_CURDATE(), 0, 442, 0, 0, 0.00, NULL, NULL, util.VN_CURDATE(), NULL, 1, 1, 1, 1, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 1),
|
||||
(4, 2.0, util.VN_CURDATE(), '4300001104', NULL, 'n/fra T4444444', 8.88, NULL, NULL, NULL, '0', NULL, 0.00, NULL, NULL, NULL, NULL, NULL, '2', NULL, 1, 2, 'I.F.', 'Nombre Importador', 1, 0, 0, util.VN_CURDATE(), 0, 442, 0, 0, 0.00, NULL, NULL, util.VN_CURDATE(), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0),
|
||||
(5, 2.0, util.VN_CURDATE(), '2000000000', '4300001104', 'n/fra T4444444 Tony Stark', NULL, 8.07, NULL, NULL, '0', NULL, 0.00, NULL, NULL, NULL, NULL, NULL, '2', NULL, 1, 2, 'I.F.', 'Nombre Importador', 1, 0, 0, util.VN_CURDATE(), 0, 442, 0, 0, 0.00, NULL, NULL, util.VN_CURDATE(), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0),
|
||||
(6, 2.0, util.VN_CURDATE(), '4770000010', '4300001104', 'Inmovilizado pendiente : n/fra T4444444 Tony Stark', NULL, 0.81, 8.07, 'T', '4444444', 10.00, NULL, NULL, NULL, NULL, NULL, '', '2', '', 1, 1, '06089160W', 'IRON MAN', 1, 1, 0, util.VN_CURDATE(), 0, 442, 0, 0, 0.00, NULL, NULL, util.VN_CURDATE(), NULL, 1, 1, 1, 1, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0);
|
||||
(6, 2.0, util.VN_CURDATE(), '4770000010', '4300001104', 'Inmovilizado pendiente : n/fra T4444444 Tony Stark', NULL, 0.81, 8.07, 'T', '4444444', 10.00, NULL, NULL, NULL, NULL, NULL, '', '2', '', 1, 1, '06089160W', 'IRON MAN', 1, 1, 0, util.VN_CURDATE(), 0, 442, 0, 0, 0.00, NULL, NULL, util.VN_CURDATE(), NULL, 1, 1, 1, 1, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0);
|
||||
|
|
10282
db/dump/structure.sql
10282
db/dump/structure.sql
File diff suppressed because it is too large
Load Diff
|
@ -6,13 +6,13 @@ describe('item_getBalance()', () => {
|
|||
let stmts = [];
|
||||
|
||||
let params = {
|
||||
warehouseFk: 1,
|
||||
itemFk: 1
|
||||
itemFk: 1,
|
||||
warehouseFk: 1
|
||||
};
|
||||
|
||||
const conn = await app.models.Item.dataSource.connector;
|
||||
|
||||
stmts.push(new ParameterizedSQL('CALL vn.item_getBalance(?, ?)', [
|
||||
stmts.push(new ParameterizedSQL('CALL vn.item_getBalance(?, ?, NULL)', [
|
||||
params.warehouseFk,
|
||||
params.itemFk
|
||||
]));
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
|
||||
describe('logAddWithUser()', () => {
|
||||
it('should log any action taken by the user in a table ending in Log', async() => {
|
||||
let stmts = [];
|
||||
let stmt;
|
||||
|
||||
stmts.push('START TRANSACTION');
|
||||
|
||||
let params = {
|
||||
ticketFk: 1,
|
||||
userId: 9,
|
||||
actionCode: 'update',
|
||||
targetEntity: 'ticket',
|
||||
description: 'we are testing stuff'
|
||||
};
|
||||
|
||||
stmt = new ParameterizedSQL('CALL vn.logAddWithUser(?, ?, ?, ?, ?)', [
|
||||
params.ticketFk,
|
||||
params.userId,
|
||||
params.actionCode,
|
||||
params.targetEntity,
|
||||
params.description
|
||||
]);
|
||||
stmts.push(stmt);
|
||||
|
||||
stmt = new ParameterizedSQL('SELECT * FROM vn.ticketLog WHERE description = ?', [
|
||||
params.description
|
||||
]);
|
||||
let ticketLogIndex = stmts.push(stmt) - 1;
|
||||
|
||||
stmts.push('ROLLBACK');
|
||||
|
||||
let sql = ParameterizedSQL.join(stmts, ';');
|
||||
let result = await app.models.Ticket.rawStmt(sql);
|
||||
|
||||
savedDescription = result[ticketLogIndex][0].description;
|
||||
|
||||
expect(savedDescription).toEqual(params.description);
|
||||
});
|
||||
});
|
|
@ -14,14 +14,6 @@ describe('timeControl_calculateByUser()', () => {
|
|||
let stmts = [];
|
||||
let stmt;
|
||||
|
||||
stmts.push('START TRANSACTION');
|
||||
|
||||
stmts.push(`
|
||||
DROP TEMPORARY TABLE IF EXISTS
|
||||
tmp.timeControlCalculate,
|
||||
tmp.timeBusinessCalculate
|
||||
`);
|
||||
|
||||
let params = {
|
||||
workerID: 1106,
|
||||
start: start,
|
||||
|
@ -37,17 +29,15 @@ describe('timeControl_calculateByUser()', () => {
|
|||
|
||||
let tableIndex = stmts.push('SELECT * FROM tmp.timeControlCalculate') - 1;
|
||||
|
||||
stmts.push('ROLLBACK');
|
||||
|
||||
let sql = ParameterizedSQL.join(stmts, ';');
|
||||
let result = await app.models.Ticket.rawStmt(sql);
|
||||
|
||||
let [timeControlCalculateTable] = result[tableIndex];
|
||||
|
||||
expect(timeControlCalculateTable.timeWorkSeconds).toEqual(29400);
|
||||
expect(timeControlCalculateTable.timeWorkSeconds).toEqual(28200);
|
||||
});
|
||||
|
||||
it(`should return the worked hours between last sunday and monday`, async() => {
|
||||
// #2261
|
||||
xit(`should return the worked hours between last sunday and monday`, async() => {
|
||||
let lastSunday = Date.vnNew();
|
||||
let daysSinceSunday = lastSunday.getDay();
|
||||
if (daysSinceSunday === 0) // this means today is sunday but you need the previous sunday :)
|
||||
|
@ -65,13 +55,7 @@ describe('timeControl_calculateByUser()', () => {
|
|||
|
||||
stmts.push('START TRANSACTION');
|
||||
|
||||
stmts.push(`
|
||||
DROP TEMPORARY TABLE IF EXISTS
|
||||
tmp.timeControlCalculate,
|
||||
tmp.timeBusinessCalculate
|
||||
`);
|
||||
|
||||
const workerID = 1107;
|
||||
const workerID = 1108;
|
||||
|
||||
stmt = new ParameterizedSQL(`
|
||||
INSERT INTO vn.workerTimeControl(userFk, timed, manual, direction)
|
||||
|
|
|
@ -7,7 +7,7 @@ describe('zone zone_getFromGeo()', () => {
|
|||
let stmt;
|
||||
|
||||
stmts.push('START TRANSACTION');
|
||||
let geoFk = 17;
|
||||
let geoFk = 16;
|
||||
|
||||
stmt = new ParameterizedSQL('CALL zone_getFromGeo(?)', [
|
||||
geoFk,
|
||||
|
|
|
@ -671,8 +671,8 @@ export default {
|
|||
firstAddServiceTypeButton: 'vn-ticket-service vn-icon-button[vn-tooltip="New service type"]',
|
||||
firstServiceType: 'vn-ticket-service vn-autocomplete[ng-model="service.ticketServiceTypeFk"]',
|
||||
firstQuantity: 'vn-ticket-service vn-input-number[ng-model="service.quantity"]',
|
||||
firstPrice: 'vn-ticket-service vn-horizontal:nth-child(1) vn-input-number[ng-model="service.price"]',
|
||||
fistDeleteServiceButton: 'vn-ticket-service form vn-horizontal:nth-child(1) vn-icon-button[icon="delete"]',
|
||||
firstPrice: 'vn-ticket-service vn-horizontal:nth-child(2) vn-input-number[ng-model="service.price"]',
|
||||
fistDeleteServiceButton: 'vn-ticket-service form vn-horizontal:nth-child(2) vn-icon-button[icon="delete"]',
|
||||
newServiceTypeName: '.vn-dialog.shown vn-textfield[ng-model="newServiceType.name"]',
|
||||
serviceLine: 'vn-ticket-service > form > vn-card > vn-one:nth-child(2) > vn-horizontal',
|
||||
saveServiceButton: 'button[type=submit]',
|
||||
|
|
|
@ -8,7 +8,7 @@ describe('Client create path', () => {
|
|||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule(' deliveryBoss', 'client');
|
||||
await page.loginAndModule('deliveryAssistant', 'client');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
|
|
|
@ -45,7 +45,7 @@ describe('Worker create path', () => {
|
|||
|
||||
// should create a new worker and go to worker basic data'
|
||||
await page.pickDate(selectors.workerCreate.birth, new Date(1962, 8, 5));
|
||||
await page.autocompleteSearch(selectors.workerCreate.boss, 'deliveryBoss');
|
||||
await page.autocompleteSearch(selectors.workerCreate.boss, 'deliveryAssistant');
|
||||
await page.waitToClick(selectors.workerCreate.createButton);
|
||||
message = await page.waitForSnackbar();
|
||||
await page.waitForState('worker.card.basicData');
|
||||
|
|
|
@ -75,7 +75,7 @@ describe('Ticket Edit basic data path', () => {
|
|||
const result = await page
|
||||
.waitToGetProperty(selectors.ticketBasicData.stepTwoTotalPriceDif, 'innerText');
|
||||
|
||||
expect(result).toContain('-€232.75');
|
||||
expect(result).toContain('-€228.25');
|
||||
});
|
||||
|
||||
it(`should select a new reason for the changes made then click on finalize`, async() => {
|
||||
|
|
|
@ -82,32 +82,24 @@ describe('InvoiceIn basic data path', () => {
|
|||
await page.waitToClick(selectors.invoiceInBasicData.confirm);
|
||||
let message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('The company can\'t be empty');
|
||||
|
||||
await page.clearInput(selectors.invoiceInBasicData.companyId);
|
||||
await page.autocompleteSearch(selectors.invoiceInBasicData.companyId, 'VNL');
|
||||
|
||||
await page.waitToClick(selectors.invoiceInBasicData.confirm);
|
||||
message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('The warehouse can\'t be empty');
|
||||
|
||||
await page.clearInput(selectors.invoiceInBasicData.warehouseId);
|
||||
await page.autocompleteSearch(selectors.invoiceInBasicData.warehouseId, 'Warehouse One');
|
||||
|
||||
await page.waitToClick(selectors.invoiceInBasicData.confirm);
|
||||
message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('The DMS Type can\'t be empty');
|
||||
|
||||
await page.clearInput(selectors.invoiceInBasicData.dmsTypeId);
|
||||
await page.autocompleteSearch(selectors.invoiceInBasicData.dmsTypeId, 'Ticket');
|
||||
|
||||
await page.waitToClick(selectors.invoiceInBasicData.confirm);
|
||||
message = await page.waitForSnackbar();
|
||||
|
||||
expect(message.text).toContain('The description can\'t be empty');
|
||||
|
||||
await page.waitToClick(selectors.invoiceInBasicData.description);
|
||||
await page.write(selectors.invoiceInBasicData.description, 'Dms without edition.');
|
||||
|
||||
|
|
|
@ -8,7 +8,9 @@ describe('Zone basic data path', () => {
|
|||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('deliveryBoss', 'zone'); // turns up the zone module name and route aint the same lol
|
||||
|
||||
await page.loginAndModule('deliveryAssistant',
|
||||
'zone'); // turns up the zone module name and route aint the same lol
|
||||
await page.accessToSearchResult('10');
|
||||
await page.accessToSection('zone.card.basicData');
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@ describe('Zone descriptor path', () => {
|
|||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('deliveryBoss', 'zone');
|
||||
await page.loginAndModule('deliveryAssistant', 'zone');
|
||||
await page.accessToSearchResult('13');
|
||||
});
|
||||
|
||||
|
|
|
@ -5,6 +5,10 @@ export const validators = {
|
|||
if (validator.isEmpty(value ? String(value) : ''))
|
||||
throw new Error(_($translate, `Value can't be empty`));
|
||||
},
|
||||
negative: $translate => {
|
||||
if (validator < 0)
|
||||
throw new Error(_($translate, `Negative numbers are not allowed. Please enter a valid number.`));
|
||||
},
|
||||
absence: ($translate, value) => {
|
||||
if (!validator.isEmpty(value))
|
||||
throw new Error(_($translate, `Value should be empty`));
|
||||
|
@ -104,9 +108,8 @@ export function checkNull($translate, value, conf) {
|
|||
export function _($translate, text, params = []) {
|
||||
text = $translate.instant(text);
|
||||
|
||||
for (let i = 0; i < params.length; i++) {
|
||||
for (let i = 0; i < params.length; i++)
|
||||
text = text.replace('%s', params[i]);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ Value can't be empty: El valor no puede estar vacío
|
|||
Value should be empty: El valor debe estar vacío
|
||||
Value should be integer: El valor debe ser entero
|
||||
Value should be a number: El valor debe ser numérico
|
||||
Negative numbers are not allowed. Please enter a valid number: No se permiten números negativos. Por favor, ingrese un número válido
|
||||
Invalid value: Valor incorrecto
|
||||
Value can't be blank: El valor no puede estar en blanco
|
||||
Value can't be null: El valor no puede ser nulo
|
||||
|
|
|
@ -307,7 +307,7 @@
|
|||
"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",
|
||||
"This ticket cannot be left empty.": "Este ticket no se puede dejar vacío. %s",
|
||||
"The company has not informed the supplier account for bank transfers": "La empresa no tiene informado la cuenta de proveedor para transferencias bancarias",
|
||||
"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",
|
||||
"You don't have enough privileges.": "No tienes suficientes permisos.",
|
||||
|
@ -316,5 +316,6 @@
|
|||
"The ticket doesn't exist.": "No existe el ticket.",
|
||||
"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",
|
||||
"The response is not a PDF": "La respuesta no es un PDF",
|
||||
"Ticket without Route": "Ticket sin ruta"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('getAddress', {
|
||||
description: 'Get all activated address with loses client activated',
|
||||
accessType: 'READ',
|
||||
accepts: [],
|
||||
returns: {
|
||||
type: ['object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/getAddress`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
Self.getAddress = async() => {
|
||||
let getAddressQuery = `
|
||||
SELECT a.id, a.nickname
|
||||
FROM vn.address a
|
||||
JOIN vn.client c ON a.clientFk = c.id AND c.isActive <> FALSE
|
||||
WHERE c.typeFk = 'loses' AND a.isActive <> FALSE;`;
|
||||
|
||||
return result = await Self.rawSql(getAddressQuery);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
const {models} = require('vn-loopback/server/server');
|
||||
|
||||
describe('getAddress()', () => {
|
||||
it('return list of activated address with loses client activated', async() => {
|
||||
let response = await models.Address.getAddress();
|
||||
|
||||
expect(response.length).toEqual(2);
|
||||
});
|
||||
});
|
|
@ -80,10 +80,15 @@ module.exports = Self => {
|
|||
Object.assign(myOptions, options);
|
||||
|
||||
if (args.zoneFk) {
|
||||
query = `CALL vn.zone_getPostalCode(?)`;
|
||||
const [geos] = await Self.rawSql(query, [args.zoneFk]);
|
||||
for (let geo of geos)
|
||||
postalCode.push(geo.name);
|
||||
let stmts = [];
|
||||
stmts.push(new ParameterizedSQL('CALL vn.zone_getPostalCode(?)', [args.zoneFk]));
|
||||
stmts.push(`SELECT name FROM tmp.zoneNodes`);
|
||||
stmts.push(`DROP TEMPORARY TABLE tmp.zoneNodes`);
|
||||
const sql = ParameterizedSQL.join(stmts, ';');
|
||||
const [results] = await conn.executeStmt(sql);
|
||||
|
||||
for (let result of results)
|
||||
postalCode.push(result.name);
|
||||
}
|
||||
|
||||
const where = buildFilter(ctx.args, (param, value) => {
|
||||
|
|
|
@ -3,6 +3,8 @@ let getFinalState = require('vn-loopback/util/hook').getFinalState;
|
|||
let isMultiple = require('vn-loopback/util/hook').isMultiple;
|
||||
|
||||
module.exports = Self => {
|
||||
require('../methods/address/getAddress')(Self);
|
||||
|
||||
Self.validateAsync('isEqualizated', cannotHaveET, {
|
||||
message: 'Cannot check Equalization Tax in this NIF/CIF'
|
||||
});
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
<vn-check
|
||||
vn-one
|
||||
label="Default" ng-model="$ctrl.address.isDefaultAddress">
|
||||
</vn-check>
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
|
@ -60,7 +60,7 @@
|
|||
show-field="code"
|
||||
rule>
|
||||
<tpl-item>
|
||||
{{code}} - {{town.name}} ({{town.province.name}},
|
||||
{{code}} - {{town.name}} ({{town.province.name}},
|
||||
{{town.province.country.country}})
|
||||
</tpl-item>
|
||||
<append>
|
||||
|
@ -68,12 +68,12 @@
|
|||
icon="add_circle"
|
||||
vn-tooltip="New postcode"
|
||||
ng-click="postcode.open()"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove">
|
||||
</vn-icon-button>
|
||||
</append>
|
||||
</vn-datalist>
|
||||
<vn-datalist vn-id="town" vn-one
|
||||
<vn-datalist vn-id="town" vn-one
|
||||
label="City"
|
||||
ng-model="$ctrl.address.city"
|
||||
selection="$ctrl.town"
|
||||
|
@ -158,7 +158,7 @@
|
|||
</vn-geo-postcode>
|
||||
|
||||
<!-- Create custom agent dialog -->
|
||||
<vn-dialog class="edit"
|
||||
<vn-dialog class="edit"
|
||||
vn-id="customAgent"
|
||||
on-accept="$ctrl.onCustomAgentAccept()"
|
||||
message="New customs agent">
|
||||
|
@ -190,4 +190,4 @@
|
|||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||
<button response="accept" translate>Create</button>
|
||||
</tpl-buttons>
|
||||
</vn-dialog>
|
||||
</vn-dialog>
|
||||
|
|
|
@ -73,20 +73,20 @@
|
|||
show-field="code"
|
||||
rule>
|
||||
<tpl-item>
|
||||
{{code}} - {{town.name}} ({{town.province.name}},
|
||||
{{code}} - {{town.name}} ({{town.province.name}},
|
||||
{{town.province.country.country}})
|
||||
</tpl-item>
|
||||
<append>
|
||||
<vn-icon-button
|
||||
<vn-icon-button
|
||||
icon="add_circle"
|
||||
vn-tooltip="New postcode"
|
||||
ng-click="postcode.open()"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove">
|
||||
</vn-icon-button>
|
||||
</append>
|
||||
</vn-datalist>
|
||||
<vn-datalist vn-id="town" vn-one
|
||||
<vn-datalist vn-id="town" vn-one
|
||||
label="City"
|
||||
ng-model="$ctrl.address.city"
|
||||
selection="$ctrl.town"
|
||||
|
@ -178,14 +178,14 @@
|
|||
icon="delete"
|
||||
ng-click="$ctrl.removeObservation($index)"
|
||||
tabindex="-1">
|
||||
</vn-icon-button>
|
||||
</vn-icon-button>
|
||||
</vn-none>
|
||||
</vn-horizontal>
|
||||
<vn-icon-button
|
||||
vn-bind="+"
|
||||
vn-tooltip="Add note"
|
||||
icon="add_circle"
|
||||
ng-if="types.length > observations.length"
|
||||
ng-if="types.length > observations.length"
|
||||
ng-click="model.insert()">
|
||||
</vn-icon-button>
|
||||
</div>
|
||||
|
@ -197,12 +197,12 @@
|
|||
</form>
|
||||
|
||||
<!-- New postcode dialog -->
|
||||
<vn-geo-postcode vn-id="postcode"
|
||||
<vn-geo-postcode vn-id="postcode"
|
||||
on-response="$ctrl.onResponse($response)">
|
||||
</vn-geo-postcode>
|
||||
|
||||
<!-- Create custom agent dialog -->
|
||||
<vn-dialog class="edit"
|
||||
<vn-dialog class="edit"
|
||||
vn-id="customAgent"
|
||||
on-accept="$ctrl.onCustomAgentAccept()"
|
||||
message="New customs agent">
|
||||
|
@ -234,4 +234,4 @@
|
|||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||
<button response="accept" translate>Create</button>
|
||||
</tpl-buttons>
|
||||
</vn-dialog>
|
||||
</vn-dialog>
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
icon="add_circle"
|
||||
vn-tooltip="New postcode"
|
||||
ng-click="postcode.open()"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove">
|
||||
</vn-icon-button>
|
||||
</append>
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
icon="add_circle"
|
||||
vn-tooltip="New postcode"
|
||||
ng-click="postcode.open()"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove">
|
||||
</vn-icon-button>
|
||||
</append>
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
icon="add_circle"
|
||||
vn-tooltip="New city"
|
||||
ng-click="city.open($event)"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove">
|
||||
</vn-icon-button>
|
||||
</append>
|
||||
|
@ -45,7 +45,7 @@
|
|||
icon="add_circle"
|
||||
vn-tooltip="New province"
|
||||
ng-click="province.open($event)"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove">
|
||||
</vn-icon-button>
|
||||
</append>
|
||||
|
@ -73,4 +73,4 @@
|
|||
<vn-geo-city
|
||||
vn-id="city"
|
||||
on-response="$ctrl.onCityResponse($response)">
|
||||
</vn-geo-city>
|
||||
</vn-geo-city>
|
||||
|
|
|
@ -255,7 +255,7 @@
|
|||
value="{{$ctrl.summary.averageInvoiced.invoiced | currency: 'EUR':2}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Claims"
|
||||
value="{{$ctrl.claimingRate($ctrl.summary.claimsRatio.claimingRate) | percentage}}">
|
||||
value="{{$ctrl.claimingRate($ctrl.summary.claimsRatio.claimingRate / 100) | percentage}}">
|
||||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
|
|
|
@ -67,17 +67,22 @@ class Controller extends Section {
|
|||
}
|
||||
|
||||
openCreateDialog() {
|
||||
this.dms = {
|
||||
reference: null,
|
||||
warehouseId: null,
|
||||
companyId: null,
|
||||
dmsTypeId: null,
|
||||
description: null,
|
||||
hasFile: true,
|
||||
hasFileAttached: true,
|
||||
files: null
|
||||
};
|
||||
this.$.dmsCreateDialog.show();
|
||||
const params = {filter: {
|
||||
where: {code: 'invoiceIn'}
|
||||
}};
|
||||
this.$http.get('DmsTypes/findOne', {params}).then(res => {
|
||||
this.dms = {
|
||||
reference: this.invoiceIn.supplierRef,
|
||||
warehouseId: this.vnConfig.warehouseFk,
|
||||
companyId: this.vnConfig.companyFk,
|
||||
dmsTypeId: res.data.id,
|
||||
description: this.invoiceIn.supplier.name,
|
||||
hasFile: true,
|
||||
hasFileAttached: true,
|
||||
files: null
|
||||
};
|
||||
this.$.dmsCreateDialog.show();
|
||||
});
|
||||
}
|
||||
|
||||
downloadFile(dmsId) {
|
||||
|
|
|
@ -6,6 +6,7 @@ class Controller extends Section {
|
|||
this.invoiceIn = {};
|
||||
if (this.$params && this.$params.supplierFk)
|
||||
this.invoiceIn.supplierFk = this.$params.supplierFk;
|
||||
this.invoiceIn.issued = Date.vnNew();
|
||||
}
|
||||
|
||||
get companyFk() {
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
import './index.js';
|
||||
import watcher from 'core/mocks/watcher';
|
||||
|
||||
describe('InvoiceIn', () => {
|
||||
describe('Component vnInvoiceInCreate', () => {
|
||||
let controller;
|
||||
let $element;
|
||||
|
||||
beforeEach(ngModule('invoiceIn'));
|
||||
|
||||
beforeEach(inject(($componentController, $rootScope) => {
|
||||
const $scope = $rootScope.$new();
|
||||
$scope.watcher = watcher;
|
||||
$element = angular.element('<vn-invoice-in-create></vn-invoice-in-create>');
|
||||
controller = $componentController('vnInvoiceInCreate', {$element, $scope});
|
||||
controller.$params = {};
|
||||
}));
|
||||
|
||||
afterEach(() => {
|
||||
$element.remove();
|
||||
});
|
||||
|
||||
describe('onInit()', () => {
|
||||
it(`should defined the controller's invoiceIn property`, () => {
|
||||
expect(controller.invoiceIn).toBeUndefined();
|
||||
|
||||
controller.$onInit();
|
||||
|
||||
expect(controller.invoiceIn).toEqual({});
|
||||
});
|
||||
|
||||
it(`should define invoiceIn and it's supplierFk when received via params`, () => {
|
||||
controller.$params.supplierFk = 'supplierId';
|
||||
|
||||
controller.$onInit();
|
||||
|
||||
expect(controller.invoiceIn.supplierFk).toEqual('supplierId');
|
||||
});
|
||||
});
|
||||
|
||||
describe('onSubmit()', () => {
|
||||
it(`should redirect to basic data by calling the $state.go function`, () => {
|
||||
jest.spyOn(controller.$state, 'go');
|
||||
|
||||
controller.onSubmit();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('invoiceIn.card.basicData', {id: 1234});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('setVisibleDiscard', {
|
||||
description: 'Change visible for item',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'itemFk',
|
||||
type: 'Number',
|
||||
required: false,
|
||||
description: 'The item id'
|
||||
}, {
|
||||
arg: 'warehouseFk',
|
||||
type: 'Number',
|
||||
required: true,
|
||||
description: 'The warehouse of item'
|
||||
}, {
|
||||
arg: 'quantity',
|
||||
type: 'Number',
|
||||
required: true,
|
||||
description: 'The quantity to modify'
|
||||
},
|
||||
{
|
||||
arg: 'addressFk',
|
||||
type: 'Number',
|
||||
required: true,
|
||||
description: 'The address id'
|
||||
}],
|
||||
http: {
|
||||
path: `/setVisibleDiscard`,
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.setVisibleDiscard = async(ctx, itemFk, warehouseFk, quantity, addressFk) => {
|
||||
const query = `CALL vn.item_setVisibleDiscard(?, ?, ?, ?)`;
|
||||
await Self.rawSql(query, [itemFk, warehouseFk, quantity, addressFk]);
|
||||
};
|
||||
};
|
|
@ -16,6 +16,7 @@ module.exports = Self => {
|
|||
require('../methods/item/createIntrastat')(Self);
|
||||
require('../methods/item/buyerWasteEmail')(Self);
|
||||
require('../methods/item/labelPdf')(Self);
|
||||
require('../methods/item/setVisibleDiscard')(Self);
|
||||
|
||||
Self.validatesPresenceOf('originFk', {message: 'Cannot be blank'});
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ describe('SalesMonitor salesFilter()', () => {
|
|||
const filter = {};
|
||||
const result = await models.SalesMonitor.salesFilter(ctx, filter, options);
|
||||
|
||||
expect(result.length).toBeGreaterThan(15);
|
||||
expect(result.length).toBeGreaterThan(11);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
|
@ -151,7 +151,7 @@ describe('SalesMonitor salesFilter()', () => {
|
|||
const result = await models.SalesMonitor.salesFilter(ctx, filter, options);
|
||||
const firstRow = result[0];
|
||||
|
||||
expect(result.length).toEqual(12);
|
||||
expect(result.length).toEqual(15);
|
||||
expect(firstRow.alertLevel).not.toEqual(0);
|
||||
|
||||
await tx.rollback();
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
const JSZip = require('jszip');
|
||||
const axios = require('axios');
|
||||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('downloadCmrsZip', {
|
||||
description: 'Download a zip file with multiple cmrs pdfs',
|
||||
accessType: 'READ',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'ids',
|
||||
type: 'string',
|
||||
description: 'The cmrs ids',
|
||||
}
|
||||
],
|
||||
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: '/downloadCmrsZip',
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.downloadCmrsZip = async function(ctx, ids, options) {
|
||||
const models = Self.app.models;
|
||||
const myOptions = {};
|
||||
const token = ctx.req.accessToken;
|
||||
const zip = new JSZip();
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
const zipConfig = await models.ZipConfig.findOne(null, myOptions);
|
||||
let totalSize = 0;
|
||||
ids = ids.split(',');
|
||||
try {
|
||||
for (let id of ids) {
|
||||
if (zipConfig && totalSize > zipConfig.maxSize) throw new UserError('Files are too large');
|
||||
const response = await axios.get(
|
||||
`${ctx.req.headers.referer}api/Routes/${id}/cmr?access_token=${token.id}`, {
|
||||
...myOptions,
|
||||
responseType: 'arraybuffer',
|
||||
});
|
||||
|
||||
if (response.headers['content-type'] !== 'application/pdf')
|
||||
throw new UserError(`The response is not a PDF`);
|
||||
|
||||
zip.file(`${id}.pdf`, response.data, { binary: true });
|
||||
}
|
||||
|
||||
const zipStream = zip.generateNodeStream({ streamFiles: true });
|
||||
|
||||
return [zipStream, 'application/zip', `filename="cmrs.zip"`];
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -22,6 +22,11 @@ module.exports = Self => {
|
|||
type: 'integer',
|
||||
description: 'The worker id',
|
||||
},
|
||||
{
|
||||
arg: 'routeFk',
|
||||
type: 'integer',
|
||||
description: 'The route id',
|
||||
},
|
||||
{
|
||||
arg: 'country',
|
||||
type: 'string',
|
||||
|
@ -57,6 +62,7 @@ module.exports = Self => {
|
|||
filter,
|
||||
cmrFk,
|
||||
ticketFk,
|
||||
routeFk,
|
||||
country,
|
||||
clientFk,
|
||||
hasCmrDms,
|
||||
|
@ -66,6 +72,7 @@ module.exports = Self => {
|
|||
const params = {
|
||||
cmrFk,
|
||||
ticketFk,
|
||||
routeFk,
|
||||
country,
|
||||
clientFk,
|
||||
hasCmrDms,
|
||||
|
@ -89,37 +96,38 @@ module.exports = Self => {
|
|||
|
||||
let stmts = [];
|
||||
const stmt = new ParameterizedSQL(`
|
||||
SELECT *
|
||||
FROM (
|
||||
SELECT t.cmrFk,
|
||||
t.id ticketFk,
|
||||
co.country,
|
||||
t.clientFk,
|
||||
IF(sub.id, TRUE, FALSE) hasCmrDms,
|
||||
DATE(t.shipped) shipped
|
||||
FROM ticket t
|
||||
JOIN ticketState ts ON ts.ticketFk = t.id
|
||||
JOIN state s ON s.id = ts.stateFk
|
||||
JOIN alertLevel al ON al.id = s.alertLevel
|
||||
JOIN client c ON c.id = t.clientFk
|
||||
JOIN address a ON a.id = t.addressFk
|
||||
JOIN province p ON p.id = a.provinceFk
|
||||
JOIN country co ON co.id = p.countryFk
|
||||
JOIN agencyMode am ON am.id = t.agencyModeFk
|
||||
JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
|
||||
JOIN warehouse w ON w.id = t.warehouseFk
|
||||
LEFT JOIN (
|
||||
SELECT td.ticketFk, d.id
|
||||
FROM ticketDms td
|
||||
JOIN dms d ON d.id = td.dmsFk
|
||||
JOIN dmsType dt ON dt.id = d.dmsTypeFk
|
||||
WHERE dt.name = 'cmr'
|
||||
) sub ON sub.ticketFk = t.id
|
||||
WHERE co.code <> 'ES'
|
||||
AND am.name <> 'ABONO'
|
||||
AND w.code = 'ALG'
|
||||
AND dm.code = 'DELIVERY'
|
||||
AND t.cmrFk
|
||||
SELECT *
|
||||
FROM (
|
||||
SELECT t.cmrFk,
|
||||
t.id ticketFk,
|
||||
t.routeFk,
|
||||
co.country,
|
||||
t.clientFk,
|
||||
IF(sub.id, TRUE, FALSE) hasCmrDms,
|
||||
DATE(t.shipped) shipped
|
||||
FROM ticket t
|
||||
JOIN ticketState ts ON ts.ticketFk = t.id
|
||||
JOIN state s ON s.id = ts.stateFk
|
||||
JOIN alertLevel al ON al.id = s.alertLevel
|
||||
JOIN client c ON c.id = t.clientFk
|
||||
JOIN address a ON a.id = t.addressFk
|
||||
JOIN province p ON p.id = a.provinceFk
|
||||
JOIN country co ON co.id = p.countryFk
|
||||
JOIN agencyMode am ON am.id = t.agencyModeFk
|
||||
JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk
|
||||
JOIN warehouse w ON w.id = t.warehouseFk
|
||||
LEFT JOIN (
|
||||
SELECT td.ticketFk, d.id
|
||||
FROM ticketDms td
|
||||
JOIN dms d ON d.id = td.dmsFk
|
||||
JOIN dmsType dt ON dt.id = d.dmsTypeFk
|
||||
WHERE dt.name = 'cmr'
|
||||
) sub ON sub.ticketFk = t.id
|
||||
WHERE co.code <> 'ES'
|
||||
AND am.name <> 'ABONO'
|
||||
AND w.code = 'ALG'
|
||||
AND dm.code = 'DELIVERY'
|
||||
AND t.cmrFk
|
||||
) sub
|
||||
`);
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ module.exports = Self => {
|
|||
require('../methods/route/downloadZip')(Self);
|
||||
require('../methods/route/cmr')(Self);
|
||||
require('../methods/route/getExternalCmrs')(Self);
|
||||
require('../methods/route/downloadCmrsZip')(Self);
|
||||
|
||||
Self.validate('kmStart', validateDistance, {
|
||||
message: 'Distance must be lesser than 1000'
|
||||
|
|
|
@ -15,14 +15,14 @@
|
|||
</vn-item>
|
||||
<vn-item
|
||||
ng-click="updateVolumeConfirmation.show()"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove"
|
||||
translate>
|
||||
Update volume
|
||||
</vn-item>
|
||||
<vn-item
|
||||
ng-click="$ctrl.deleteCurrentRoute()"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove"
|
||||
translate>
|
||||
Delete route
|
||||
|
@ -31,23 +31,23 @@
|
|||
<slot-body>
|
||||
<div class="attributes">
|
||||
<vn-label-value
|
||||
label="Date"
|
||||
label="Date"
|
||||
value="{{$ctrl.route.created | date: 'dd/MM/yyyy'}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Agency"
|
||||
label="Agency"
|
||||
value="{{$ctrl.route.agencyMode.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Zone"
|
||||
label="Zone"
|
||||
value="{{$ctrl.route.zone.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Volume"
|
||||
label="Volume"
|
||||
value="{{$ctrl.route.m3 | dashIfEmpty}} / {{$ctrl.route.vehicle.m3 | dashIfEmpty}} m³">
|
||||
</vn-label-value>
|
||||
<vn-label-value
|
||||
label="Description"
|
||||
label="Description"
|
||||
value="{{$ctrl.route.description}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
|
@ -72,4 +72,4 @@
|
|||
</vn-confirm>
|
||||
<vn-popup vn-id="summary">
|
||||
<vn-route-summary route="$ctrl.route"></vn-route-summary>
|
||||
</vn-popup>
|
||||
</vn-popup>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
icon="format_list_numbered">
|
||||
</vn-button>
|
||||
<vn-button
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove"
|
||||
disabled="!$ctrl.isChecked"
|
||||
icon="sms"
|
||||
|
|
|
@ -13,7 +13,7 @@ module.exports = Self => {
|
|||
const bankEntity = await Self.app.models.BankEntity.findById(this.bankEntityFk);
|
||||
const filter = {
|
||||
fields: ['code'],
|
||||
where: {id: bankEntity.countryFk}
|
||||
where: {id: bankEntity?.countryFk}
|
||||
};
|
||||
|
||||
const country = await Self.app.models.Country.findOne(filter);
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
show-field="code"
|
||||
rule>
|
||||
<tpl-item>
|
||||
{{code}} - {{town.name}} ({{town.province.name}},
|
||||
{{code}} - {{town.name}} ({{town.province.name}},
|
||||
{{town.province.country.country}})
|
||||
</tpl-item>
|
||||
<append>
|
||||
|
@ -50,12 +50,12 @@
|
|||
icon="add_circle"
|
||||
vn-tooltip="New postcode"
|
||||
ng-click="postcode.open()"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove">
|
||||
</vn-icon-button>
|
||||
</append>
|
||||
</vn-datalist>
|
||||
<vn-datalist vn-id="town" vn-one
|
||||
<vn-datalist vn-id="town" vn-one
|
||||
label="City"
|
||||
ng-model="$ctrl.address.city"
|
||||
selection="$ctrl.town"
|
||||
|
@ -106,4 +106,4 @@
|
|||
<!-- New postcode dialog -->
|
||||
<vn-geo-postcode vn-id="postcode"
|
||||
on-response="$ctrl.onResponse($response)">
|
||||
</vn-geo-postcode>
|
||||
</vn-geo-postcode>
|
||||
|
|
|
@ -40,20 +40,20 @@
|
|||
show-field="code"
|
||||
rule>
|
||||
<tpl-item>
|
||||
{{code}} - {{town.name}} ({{town.province.name}},
|
||||
{{code}} - {{town.name}} ({{town.province.name}},
|
||||
{{town.province.country.country}})
|
||||
</tpl-item>
|
||||
<append>
|
||||
<vn-icon-button
|
||||
<vn-icon-button
|
||||
icon="add_circle"
|
||||
vn-tooltip="New postcode"
|
||||
ng-click="postcode.open()"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove">
|
||||
</vn-icon-button>
|
||||
</append>
|
||||
</vn-datalist>
|
||||
<vn-datalist vn-id="town" vn-one
|
||||
<vn-datalist vn-id="town" vn-one
|
||||
label="City"
|
||||
ng-model="$ctrl.address.city"
|
||||
selection="$ctrl.town"
|
||||
|
@ -99,6 +99,6 @@
|
|||
</form>
|
||||
|
||||
<!-- New postcode dialog -->
|
||||
<vn-geo-postcode vn-id="postcode"
|
||||
<vn-geo-postcode vn-id="postcode"
|
||||
on-response="$ctrl.onResponse($response)">
|
||||
</vn-geo-postcode>
|
||||
</vn-geo-postcode>
|
||||
|
|
|
@ -150,7 +150,7 @@
|
|||
icon="add_circle"
|
||||
vn-tooltip="New postcode"
|
||||
ng-click="postcode.open()"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove">
|
||||
</vn-icon-button>
|
||||
</append>
|
||||
|
|
|
@ -5,8 +5,7 @@ module.exports = Self => {
|
|||
accepts: [
|
||||
{
|
||||
arg: 'salesIds',
|
||||
type: ['number'],
|
||||
required: true
|
||||
type: ['number']
|
||||
},
|
||||
{
|
||||
arg: 'servicesIds',
|
||||
|
@ -41,6 +40,7 @@ module.exports = Self => {
|
|||
myOptions.transaction = tx;
|
||||
}
|
||||
|
||||
let refundTicket = null;
|
||||
try {
|
||||
const refundAgencyMode = await models.AgencyMode.findOne({
|
||||
include: {
|
||||
|
@ -55,42 +55,55 @@ module.exports = Self => {
|
|||
|
||||
const refoundZoneId = refundAgencyMode.zones()[0].id;
|
||||
|
||||
const salesFilter = {
|
||||
where: {id: {inq: salesIds}},
|
||||
include: {
|
||||
relation: 'components',
|
||||
scope: {
|
||||
fields: ['saleFk', 'componentFk', 'value']
|
||||
if (salesIds) {
|
||||
const salesFilter = {
|
||||
where: {id: {inq: salesIds}},
|
||||
include: {
|
||||
relation: 'components',
|
||||
scope: {
|
||||
fields: ['saleFk', 'componentFk', 'value']
|
||||
}
|
||||
}
|
||||
};
|
||||
const sales = await models.Sale.find(salesFilter, myOptions);
|
||||
const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))];
|
||||
|
||||
const now = Date.vnNew();
|
||||
const [firstTicketId] = ticketsIds;
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
refundTicket = await createTicketRefund(firstTicketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions);
|
||||
|
||||
for (const sale of sales) {
|
||||
const createdSale = await models.Sale.create({
|
||||
ticketFk: refundTicket.id,
|
||||
itemFk: sale.itemFk,
|
||||
quantity: - sale.quantity,
|
||||
concept: sale.concept,
|
||||
price: sale.price,
|
||||
discount: sale.discount,
|
||||
}, myOptions);
|
||||
|
||||
const components = sale.components();
|
||||
for (const component of components)
|
||||
component.saleFk = createdSale.id;
|
||||
|
||||
await models.SaleComponent.create(components, myOptions);
|
||||
}
|
||||
};
|
||||
const sales = await models.Sale.find(salesFilter, myOptions);
|
||||
const ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))];
|
||||
|
||||
let [firstTicketId] = ticketsIds;
|
||||
if (!firstTicketId) {
|
||||
[ticketServices] = await models.TicketService.find({where: {id: {inq: servicesIds}}}, myOptions);
|
||||
firstTicketId = ticketServices.ticketFk;
|
||||
}
|
||||
const now = Date.vnNew();
|
||||
|
||||
const refundTicket = await createTicketRefund(firstTicketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions);
|
||||
if (!refundTicket) {
|
||||
const servicesFilter = {
|
||||
where: {id: {inq: servicesIds}}
|
||||
};
|
||||
const services = await models.TicketService.find(servicesFilter, myOptions);
|
||||
const ticketsIds = [...new Set(services.map(service => service.ticketFk))];
|
||||
|
||||
for (const sale of sales) {
|
||||
const createdSale = await models.Sale.create({
|
||||
ticketFk: refundTicket.id,
|
||||
itemFk: sale.itemFk,
|
||||
quantity: - sale.quantity,
|
||||
concept: sale.concept,
|
||||
price: sale.price,
|
||||
discount: sale.discount,
|
||||
}, myOptions);
|
||||
const now = Date.vnNew();
|
||||
const [firstTicketId] = ticketsIds;
|
||||
|
||||
const components = sale.components();
|
||||
for (const component of components)
|
||||
component.saleFk = createdSale.id;
|
||||
|
||||
await models.SaleComponent.create(components, myOptions);
|
||||
// eslint-disable-next-line max-len
|
||||
refundTicket = await createTicketRefund(firstTicketId, now, refundAgencyMode, refoundZoneId, withWarehouse, myOptions);
|
||||
}
|
||||
|
||||
if (servicesIds && servicesIds.length > 0) {
|
||||
|
@ -101,8 +114,8 @@ module.exports = Self => {
|
|||
for (const service of services) {
|
||||
await models.TicketService.create({
|
||||
description: service.description,
|
||||
quantity: - service.quantity,
|
||||
price: service.price,
|
||||
quantity: service.quantity,
|
||||
price: - service.price,
|
||||
taxClassFk: service.taxClassFk,
|
||||
ticketFk: refundTicket.id,
|
||||
ticketServiceTypeFk: service.ticketServiceTypeFk,
|
||||
|
|
|
@ -108,7 +108,7 @@ describe('sale updatePrice()', () => {
|
|||
}}, options);
|
||||
|
||||
expect(updatedSale.price).toBe(price);
|
||||
expect(createdSaleComponent.value).toEqual(-2.04);
|
||||
expect(createdSaleComponent.value).toEqual(-2.34);
|
||||
|
||||
const updatedSalesPersonMana = await models.WorkerMana.findById(18, null, options);
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ describe('ticket filter()', () => {
|
|||
const filter = {};
|
||||
const result = await models.Ticket.filter(ctx, filter, options);
|
||||
|
||||
expect(result.length).toEqual(6);
|
||||
expect(result.length).toEqual(9);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
|
@ -154,7 +154,7 @@ describe('ticket filter()', () => {
|
|||
const secondRow = result[1];
|
||||
const thirdRow = result[2];
|
||||
|
||||
expect(result.length).toBeGreaterThan(15);
|
||||
expect(result.length).toBeGreaterThan(11);
|
||||
expect(firstRow.state).toEqual('Entregado');
|
||||
expect(secondRow.state).toEqual('Entregado');
|
||||
expect(thirdRow.state).toEqual('Entregado');
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<vn-crud-model
|
||||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="TicketServices"
|
||||
link="{ticketFk: $ctrl.$params.id}"
|
||||
|
@ -24,7 +24,21 @@
|
|||
</vn-watcher>
|
||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-horizontal ng-repeat="service in $ctrl.services track by $index">
|
||||
<vn-button-bar>
|
||||
<vn-button
|
||||
disabled="watcher.dataChanged() || !$ctrl.checkeds.length"
|
||||
label="Pay"
|
||||
ng-click="$ctrl.createRefund()"
|
||||
vn-acl="invoicing, claimManager, salesAssistant"
|
||||
vn-acl-action="remove">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
<vn-horizontal ng-repeat="service in $ctrl.services">
|
||||
<vn-check
|
||||
tabindex="1"
|
||||
on-change="$ctrl.addChecked(service.id)"
|
||||
disabled="!service.id">
|
||||
</vn-check>
|
||||
<vn-autocomplete vn-two vn-focus
|
||||
data="ticketServiceTypes"
|
||||
label="Description"
|
||||
|
@ -43,10 +57,12 @@
|
|||
</vn-autocomplete>
|
||||
<vn-input-number
|
||||
vn-one
|
||||
step="1"
|
||||
step="1"
|
||||
label="Quantity"
|
||||
info="To create services with negative amounts mark the service on the source ticket and press the pay button."
|
||||
ng-model="service.quantity"
|
||||
rule="TicketService">
|
||||
rule="TicketService"
|
||||
min="0">
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
vn-one
|
||||
|
@ -60,7 +76,7 @@
|
|||
vn-tooltip="Remove service"
|
||||
icon="delete"
|
||||
ng-click="model.remove($index)">
|
||||
</vn-icon-button>
|
||||
</vn-icon-button>
|
||||
</vn-auto>
|
||||
</vn-horizontal>
|
||||
<vn-icon-button
|
||||
|
@ -76,18 +92,11 @@
|
|||
disabled="!watcher.dataChanged()"
|
||||
label="Save">
|
||||
</vn-submit>
|
||||
<!-- # #2680 Undo changes button bugs -->
|
||||
<!-- <vn-button
|
||||
class="cancel"
|
||||
label="Undo changes"
|
||||
disabled="!watcher.dataChanged()"
|
||||
ng-click="watcher.loadOriginalData()">
|
||||
</vn-button> -->
|
||||
</vn-button-bar>
|
||||
</form>
|
||||
|
||||
<!-- Create service type dialog -->
|
||||
<vn-dialog class="edit"
|
||||
<vn-dialog class="edit"
|
||||
vn-id="newServiceTypeDialog"
|
||||
on-accept="$ctrl.onNewServiceTypeAccept($data)"
|
||||
on-close="newServiceType = null"
|
||||
|
@ -106,4 +115,4 @@
|
|||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||
<button response="accept" translate>Create</button>
|
||||
</tpl-buttons>
|
||||
</vn-dialog>
|
||||
</vn-dialog>
|
||||
|
|
|
@ -6,6 +6,8 @@ class Controller extends Section {
|
|||
$onInit() {
|
||||
this.services = [];
|
||||
this.getDefaultTaxClass();
|
||||
this.isDataSaved = false;
|
||||
this.checkeds = [];
|
||||
}
|
||||
|
||||
getDefaultTaxClass() {
|
||||
|
@ -49,6 +51,26 @@ class Controller extends Section {
|
|||
.then(() => this.$.model.refresh())
|
||||
.then(() => this.$.watcher.notifySaved());
|
||||
}
|
||||
|
||||
createRefund() {
|
||||
if (!this.checkeds.length) return;
|
||||
|
||||
const params = {servicesIds: this.checkeds, withWarehouse: false};
|
||||
const query = 'Sales/refund';
|
||||
this.$http.post(query, params).then(res => {
|
||||
const refundTicket = res.data;
|
||||
this.vnApp.showSuccess(this.$t('The following refund ticket have been created', {
|
||||
ticketId: refundTicket.id
|
||||
}));
|
||||
this.$state.go('ticket.card.sale', {id: refundTicket.id});
|
||||
});
|
||||
}
|
||||
|
||||
addChecked(id) {
|
||||
if (this.checkeds.includes(id))
|
||||
return this.checkeds = this.checkeds.filter(check => check != id);
|
||||
this.checkeds.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnTicketService', {
|
||||
|
|
|
@ -19,12 +19,11 @@ describe('Ticket component vnTicketService', () => {
|
|||
|
||||
describe('getDefaultTaxClass', () => {
|
||||
it('should set the default tax class in the controller', () => {
|
||||
$httpBackend.whenRoute('GET', `TaxClasses/findOne`)
|
||||
.respond({
|
||||
id: 4000,
|
||||
name: 'Whatever',
|
||||
code: 'GG'
|
||||
});
|
||||
$httpBackend.whenRoute('GET', `TaxClasses/findOne`).respond({
|
||||
id: 4000,
|
||||
name: 'Whatever',
|
||||
code: 'GG',
|
||||
});
|
||||
controller.getDefaultTaxClass();
|
||||
$httpBackend.flush();
|
||||
|
||||
|
@ -49,15 +48,15 @@ describe('Ticket component vnTicketService', () => {
|
|||
it('should set the description of the selected service upon service type creation', () => {
|
||||
const service = {
|
||||
id: 1,
|
||||
quantity: 10
|
||||
quantity: 10,
|
||||
};
|
||||
$scope.newServiceType = {
|
||||
name: 'Totally new stuff'
|
||||
name: 'Totally new stuff',
|
||||
};
|
||||
|
||||
$httpBackend.when('POST', 'TicketServiceTypes').respond({
|
||||
id: 4001,
|
||||
name: 'Totally new stuff'
|
||||
name: 'Totally new stuff',
|
||||
});
|
||||
controller.onNewServiceTypeAccept(service);
|
||||
$httpBackend.flush();
|
||||
|
@ -65,4 +64,20 @@ describe('Ticket component vnTicketService', () => {
|
|||
expect(service.ticketServiceTypeFk).toEqual(4001);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addChecked', () => {
|
||||
it('should add an item to the checkeds array', () => {
|
||||
controller.checkeds = [];
|
||||
controller.addChecked(1);
|
||||
|
||||
expect(controller.checkeds).toEqual([1]);
|
||||
});
|
||||
|
||||
it('should remove an item if it is already in the checkeds array', () => {
|
||||
controller.checkeds = [1, 2, 3];
|
||||
controller.addChecked(2);
|
||||
|
||||
expect(controller.checkeds).toEqual([1, 3]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,4 +2,6 @@ Service: Servicios
|
|||
Tax class: Tipo IVA
|
||||
Add service: Añadir servicio
|
||||
Remove service: Quitar servicio
|
||||
New service type: Nuevo tipo de servicio
|
||||
New service type: Nuevo tipo de servicio
|
||||
Pay: Abonar
|
||||
To create services with negative amounts mark the service on the source ticket and press the pay button.: Para crear sevicios con cantidades negativas marcar servicio en el ticket origen y apretar el boton abonar.
|
|
@ -72,7 +72,7 @@
|
|||
icon="add_circle"
|
||||
vn-tooltip="New postcode"
|
||||
ng-click="postcode.open()"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove">
|
||||
</vn-icon-button>
|
||||
</append>
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
<vn-card class="vn-pa-lg">
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
label="Name"
|
||||
label="Name"
|
||||
ng-model="$ctrl.zone.name"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
|
@ -26,7 +26,7 @@
|
|||
show-field="name"
|
||||
value-field="id"
|
||||
label="Agency"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-autocomplete>
|
||||
<vn-input-number
|
||||
|
@ -34,7 +34,7 @@
|
|||
label="Max m³"
|
||||
ng-model="$ctrl.zone.itemMaxSize"
|
||||
min="0"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
|
@ -42,7 +42,7 @@
|
|||
label="Maximum m³"
|
||||
ng-model="$ctrl.zone.m3Max"
|
||||
min="0"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
|
@ -52,13 +52,13 @@
|
|||
ng-model="$ctrl.zone.travelingDays"
|
||||
min="0"
|
||||
step="1"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-time
|
||||
label="Closing"
|
||||
ng-model="$ctrl.zone.hour"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-input-time>
|
||||
</vn-horizontal>
|
||||
|
@ -68,16 +68,16 @@
|
|||
ng-model="$ctrl.zone.price"
|
||||
min="0"
|
||||
step="0.01"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
label="Bonus"
|
||||
ng-model="$ctrl.zone.bonus"
|
||||
step="0.01"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-input-number
|
||||
|
@ -86,14 +86,14 @@
|
|||
ng-model="$ctrl.zone.inflation"
|
||||
min="0"
|
||||
step="0.01"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-check
|
||||
vn-one
|
||||
label="Volumetric"
|
||||
ng-model="$ctrl.zone.isVolumetric"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
rule>
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
|
@ -101,7 +101,7 @@
|
|||
<vn-button-bar>
|
||||
<vn-submit
|
||||
disabled="!watcher.dataChanged()"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
label="Save">
|
||||
</vn-submit>
|
||||
<vn-button
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
vn-click-stop="clone.show(zone)"
|
||||
vn-tooltip="Clone"
|
||||
icon="icon-clone"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove">
|
||||
</vn-icon-button>
|
||||
<vn-icon-button
|
||||
|
@ -50,7 +50,7 @@
|
|||
<vn-popup vn-id="summary">
|
||||
<vn-zone-summary zone="$ctrl.selectedZone"></vn-zone-summary>
|
||||
</vn-popup>
|
||||
<vn-confirm
|
||||
<vn-confirm
|
||||
vn-id="clone"
|
||||
on-accept="$ctrl.onCloneAccept($data)"
|
||||
question="Do you want to clone this zone?"
|
||||
|
@ -62,7 +62,7 @@
|
|||
fixed-bottom-right>
|
||||
<vn-float-button
|
||||
icon="add"
|
||||
vn-acl="deliveryBoss"
|
||||
vn-acl="deliveryAssistant"
|
||||
vn-acl-action="remove">
|
||||
</vn-float-button>
|
||||
</a>
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
root-label="Locations"
|
||||
fetch-func="$ctrl.onFetch($item)"
|
||||
sort-func="$ctrl.onSort($a, $b)">
|
||||
<vn-check acl-role="deliveryBoss"
|
||||
<vn-check acl-role="deliveryAssistant"
|
||||
ng-model="item.selected"
|
||||
on-change="$ctrl.onSelection(value, item)"
|
||||
on-change="$ctrl.onSelection(value, item)"
|
||||
triple-state="true"
|
||||
ng-click="$event.preventDefault()"
|
||||
label="{{::item.name}}">
|
||||
label="{{::item.name}}">
|
||||
</vn-check>
|
||||
</vn-treeview>
|
||||
</vn-card>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "salix-back",
|
||||
"version": "23.38.01",
|
||||
"version": "23.40.01",
|
||||
"author": "Verdnatura Levante SL",
|
||||
"description": "Salix backend",
|
||||
"license": "GPL-3.0",
|
||||
|
|
|
@ -8,8 +8,8 @@ description:
|
|||
<a href='https://www.youtube.com/watch?v=qhb0kgQF3o8' title='Youtube' target='_blank'
|
||||
style='color:#8dba25'>https://www.youtube.com/watch?v=qhb0kgQF3o8</a>. También
|
||||
necesitarás el GoLabel, el programa para imprimir las cintas.
|
||||
downloadFrom: Puedes descargarlo desde este enlace <a href='https://godex.s3-accelerate.amazonaws.com/_6f5glRrVhQAEBGhdUsqJA.file?v01'
|
||||
title='Descargar GoLabel' target='_blank' style='color:#8dba25'>https://godex.s3-accelerate.amazonaws.com/_6f5glRrVhQAEBGhdUsqJA.file?v01</a>
|
||||
downloadFrom: Puedes descargarlo desde este enlace <a href='https://cdn.verdnatura.es/public/GoLabel.zip'
|
||||
title='Descargar GoLabel' target='_blank' style='color:#8dba25'>https://cdn.verdnatura.es/public/GoLabel.zip</a>
|
||||
downloadDriver: En este enlace puedes descargar el driver de la impresora <a href='https://es.seagullscientific.com/support/downloads/drivers/godex/download/'
|
||||
title='Descargar driver' target='_blank' style='color:#8dba25'>https://es.seagullscientific.com/support/downloads/drivers/godex/download/</a>
|
||||
sections:
|
||||
|
@ -40,4 +40,4 @@ help: Cualquier duda que te surja, no dudes en consultarla, <strong>¡estamos pa
|
|||
atenderte!</strong>
|
||||
salesPersonName: Soy tu comercial y mi nombre es
|
||||
salesPersonPhone: Teléfono y whatsapp
|
||||
salesPersonEmail: Dirección de e-mail
|
||||
salesPersonEmail: Dirección de e-mail
|
||||
|
|
Loading…
Reference in New Issue