Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 3686-client_create
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
commit
b29261cb75
|
@ -1,2 +0,0 @@
|
|||
INSERT INTO salix.ACL (id, model, property, accessType, permission, principalType, principalId)
|
||||
VALUES(301, 'Agency', '*', 'READ', 'ALLOW', 'ROLE', 'employee');
|
|
@ -0,0 +1,2 @@
|
|||
INSERT INTO `salix`.`ACL` (`id`, `model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||
VALUES(304, 'Agency', '*', '*', 'ALLOW', 'ROLE', 'employee');
|
|
@ -0,0 +1,3 @@
|
|||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||
VALUES
|
||||
('SupplierAgencyTerm', '*', '*', 'ALLOW', 'ROLE', 'administrative');
|
|
@ -0,0 +1,48 @@
|
|||
ALTER TABLE `vn`.`agencyTerm` ADD `supplierFk` INT NULL;
|
||||
ALTER TABLE `vn`.`agencyTerm` CHANGE `supplierFk` `supplierFk` INT NULL AFTER `agencyFk`;
|
||||
|
||||
UPDATE `vn`.`agencyTerm` `at`
|
||||
JOIN `vn`.`agency` `a` ON `a`.`id` = `at`.`agencyFk`
|
||||
SET `at`.`supplierFk` = `a`.`supplierFk`;
|
||||
|
||||
ALTER TABLE `vn`.`agencyTerm` ADD CONSTRAINT `agencyTerm_FK` FOREIGN KEY (`agencyFk`) REFERENCES `vn`.`agency`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
ALTER TABLE `vn`.`agencyTerm` ADD CONSTRAINT `agencyTerm_FK_1` FOREIGN KEY (`supplierFk`) REFERENCES `vn`.`supplier`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
RENAME TABLE `vn`.`agencyTerm` TO `vn`.`supplierAgencyTerm`;
|
||||
|
||||
CREATE OR REPLACE
|
||||
ALGORITHM = UNDEFINED
|
||||
DEFINER=`root`@`localhost`
|
||||
VIEW `vn`.`agencyTerm` AS
|
||||
SELECT
|
||||
`sat`.`agencyFk` AS `agencyFk`,
|
||||
`sat`.`minimumPackages` AS `minimumPackages`,
|
||||
`sat`.`kmPrice` AS `kmPrice`,
|
||||
`sat`.`packagePrice` AS `packagePrice`,
|
||||
`sat`.`routePrice` AS `routePrice`,
|
||||
`sat`.`minimumKm` AS `minimumKm`,
|
||||
`sat`.`minimumM3` AS `minimumM3`,
|
||||
`sat`.`m3Price` AS `m3Price`
|
||||
FROM
|
||||
`vn`.`supplierAgencyTerm` `sat`;
|
||||
|
||||
ALTER TABLE `vn`.`agency` DROP FOREIGN KEY `agency_ibfk_4`;
|
||||
ALTER TABLE `vn`.`agency` CHANGE `supplierFk` `supplierFk__` int(11) DEFAULT NULL NULL;
|
||||
|
||||
CREATE OR REPLACE
|
||||
ALGORITHM = UNDEFINED
|
||||
DEFINER=`root`@`localhost`
|
||||
VIEW `vn2008`.`agency` AS
|
||||
SELECT
|
||||
`a`.`id` AS `agency_id`,
|
||||
`a`.`name` AS `name`,
|
||||
`a`.`warehouseFk` AS `warehouse_id`,
|
||||
`a`.`isVolumetric` AS `por_volumen`,
|
||||
`a`.`bankFk` AS `Id_Banco`,
|
||||
`a`.`warehouseAliasFk` AS `warehouse_alias_id`,
|
||||
`a`.`isOwn` AS `propios`,
|
||||
`a`.`labelZone` AS `zone_label`,
|
||||
`a`.`workCenterFk` AS `workCenterFk`,
|
||||
`a`.`supplierFk__` AS `supplierFk__`
|
||||
FROM
|
||||
`vn`.`agency` `a`;
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE `postgresql`.`business_labour_payroll` DROP FOREIGN KEY `business_labour_payroll_cod_contrato`;
|
||||
ALTER TABLE `vn`.`workerBusinessType` MODIFY COLUMN `id` int(11) NOT NULL;
|
||||
ALTER TABLE `postgresql`.`business_labour_payroll` ADD CONSTRAINT `business_labour_payroll_FK` FOREIGN KEY (cod_contrato) REFERENCES `vn`.`workerBusinessType`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
File diff suppressed because one or more lines are too long
|
@ -1902,14 +1902,29 @@ INSERT INTO `vn`.`workCenterHoliday` (`workCenterFk`, `days`, `year`)
|
|||
('1', '24.5', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 YEAR))),
|
||||
('5', '23', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 YEAR)));
|
||||
|
||||
INSERT INTO `postgresql`.`calendar_state` (`calendar_state_id`, `type`, `rgb`, `code`, `holidayEntitlementRate`)
|
||||
INSERT INTO `postgresql`.`calendar_state` (`calendar_state_id`, `type`, `rgb`, `code`, `holidayEntitlementRate`, `discountRate`)
|
||||
VALUES
|
||||
(1, 'Holidays', '#FF4444', 'holiday', 0),
|
||||
(2, 'Leave of absence', '#C71585', 'absence', 0),
|
||||
(6, 'Half holiday', '#E65F00', 'halfHoliday', 0),
|
||||
(15, 'Half Paid Leave', '#5151c0', 'halfPaidLeave', 0),
|
||||
(20, 'Furlough', '#97B92F', 'furlough', 1),
|
||||
(21, 'Furlough half day', '#778899', 'halfFurlough', 0.5);
|
||||
(1, 'Holidays', '#FF4444', 'holiday', 0, 0),
|
||||
(2, 'Leave of absence', '#C71585', 'absence', 0, 1),
|
||||
(6, 'Half holiday', '#E65F00', 'halfHoliday', 0, 0.5),
|
||||
(15, 'Half Paid Leave', '#5151c0', 'halfPaidLeave', 0, 1),
|
||||
(20, 'Furlough', '#97B92F', 'furlough', 1, 1),
|
||||
(21, 'Furlough half day', '#778899', 'halfFurlough', 0.5, 1);
|
||||
|
||||
ALTER TABLE `postgresql`.`business_labour_payroll` DROP FOREIGN KEY `business_labour_payroll_cod_categoria`;
|
||||
|
||||
INSERT INTO `vn`.`workerBusinessType` (`id`, `name`, `isFullTime`, `isPermanent`, `hasHolidayEntitlement`)
|
||||
VALUES
|
||||
(1, 'CONTRATO HOLANDA', 1, 0, 1),
|
||||
(100, 'INDEFINIDO A TIEMPO COMPLETO', 1, 1, 1),
|
||||
(109, 'CONVERSION DE TEMPORAL EN INDEFINIDO T.COMPLETO', 1, 1, 1);
|
||||
|
||||
INSERT INTO `postgresql`.`business_labour_payroll` (`business_id`, `cod_tarifa`, `cod_categoria`, `cod_contrato`, `importepactado`)
|
||||
VALUES
|
||||
(1, 7, 12, 100, 900.50),
|
||||
(1106, 7, 12, 100, 1263.03),
|
||||
(1107, 7, 12, 100, 2000),
|
||||
(1108, 7, 12, 100, 1500);
|
||||
|
||||
INSERT INTO `postgresql`.`calendar_employee` (`business_id`, `calendar_state_id`, `date`)
|
||||
VALUES
|
||||
|
@ -2462,28 +2477,25 @@ INSERT INTO `bs`.`defaulter` (`clientFk`, `amount`, `created`, `defaulterSinced`
|
|||
(1107, 500, CURDATE(), CURDATE()),
|
||||
(1109, 500, CURDATE(), CURDATE());
|
||||
|
||||
INSERT INTO `vn`.`agencyTerm` (`agencyFk`, `minimumPackages`, `kmPrice`, `packagePrice`, `routePrice`, `minimumKm`, `minimumM3`, `m3Price`)
|
||||
VALUES
|
||||
(1, 0, 0.00, 0.00, NULL, 0, 0.00, 0),
|
||||
(3, 0, 0.00, 3.05, NULL, 0, 0.00, 0),
|
||||
(2, 60, 0.00, 0.00, NULL, 0, 5.00, 33);
|
||||
UPDATE `vn`.`agency`
|
||||
SET `supplierFk`=1
|
||||
WHERE `id`=1;
|
||||
|
||||
UPDATE `vn`.`agency`
|
||||
SET `supplierFk`=1
|
||||
WHERE `id`=1;
|
||||
SET `supplierFk`=1
|
||||
WHERE `id`=2;
|
||||
|
||||
UPDATE `vn`.`agency`
|
||||
SET `supplierFk`=1
|
||||
WHERE `id`=2;
|
||||
UPDATE `vn`.`agency`
|
||||
SET `supplierFk`=2
|
||||
WHERE `id`=3;
|
||||
SET `supplierFk`=2
|
||||
WHERE `id`=3;
|
||||
|
||||
UPDATE `vn`.`route`
|
||||
SET `invoiceInFk`=1
|
||||
WHERE `id`=1;
|
||||
SET `invoiceInFk`=1
|
||||
WHERE `id`=1;
|
||||
|
||||
UPDATE `vn`.`route`
|
||||
SET `invoiceInFk`=2
|
||||
WHERE `id`=2;
|
||||
SET `invoiceInFk`=2
|
||||
WHERE `id`=2;
|
||||
INSERT INTO `bs`.`salesPerson` (`workerFk`, `year`, `month`, `portfolioWeight`)
|
||||
VALUES
|
||||
(18, YEAR(CURDATE()), MONTH(CURDATE()), 807.23),
|
||||
|
@ -2496,6 +2508,7 @@ INSERT INTO `bs`.`sale` (`saleFk`, `amount`, `dated`, `typeFk`, `clientFk`)
|
|||
(3, 200.78, CURDATE(), 2, 1101),
|
||||
(4, 33.8, CURDATE(), 1, 1101),
|
||||
(30, 34.4, CURDATE(), 1, 1108);
|
||||
|
||||
INSERT INTO `vn`.`docuware` (`code`, `fileCabinetName`, `dialogName` , `find`)
|
||||
VALUES
|
||||
('deliveryClientTest', 'deliveryClientTest', 'findTest', 'word');
|
||||
|
@ -2503,3 +2516,23 @@ INSERT INTO `vn`.`docuware` (`code`, `fileCabinetName`, `dialogName` , `find`)
|
|||
INSERT INTO `vn`.`docuwareConfig` (`url`)
|
||||
VALUES
|
||||
('https://verdnatura.docuware.cloud/docuware/platform');
|
||||
|
||||
INSERT INTO `vn`.`calendarHolidaysName` (`id`, `name`)
|
||||
VALUES
|
||||
(1, 'dayOfIT');
|
||||
|
||||
INSERT INTO `vn`.`calendarHolidaysType` (`id`, `name`, `hexColour`)
|
||||
VALUES
|
||||
(1, 'National', '#4169E1');
|
||||
|
||||
INSERT INTO `vn`.`calendarHolidays` (`id`, `calendarHolidaysTypeFk`, `dated`, `calendarHolidaysNameFk`, `workCenterFk`)
|
||||
VALUES
|
||||
(1, 1, CONCAT(YEAR(CURDATE()), '-12-09'), 1, 1);
|
||||
|
||||
INSERT INTO `vn`.`supplierAgencyTerm` (`agencyFk`, `supplierFk`, `minimumPackages`, `kmPrice`, `packagePrice`, `routePrice`, `minimumKm`, `minimumM3`, `m3Price`)
|
||||
VALUES
|
||||
(1, 1, 0, 0.00, 0.00, NULL, 0, 0.00, 23),
|
||||
(2, 1, 60, 0.00, 0.00, NULL, 0, 5.00, 33),
|
||||
(3, 2, 0, 15.00, 0.00, NULL, 0, 0.00, 0),
|
||||
(4, 2, 0, 20.00, 0.00, NULL, 0, 0.00, 0),
|
||||
(5, 442, 0, 0.00, 3.05, NULL, 0, 0.00, 0);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -66,7 +66,7 @@ describe('Claim development', () => {
|
|||
.waitToGetProperty(selectors.claimDevelopment.firstClaimRedelivery, 'value');
|
||||
|
||||
expect(reason).toEqual('Calor');
|
||||
expect(result).toEqual('Cocido');
|
||||
expect(result).toEqual('Baboso/Cocido');
|
||||
expect(responsible).toEqual('Calidad general');
|
||||
expect(worker).toEqual('adminAssistantNick');
|
||||
expect(redelivery).toEqual('Cliente');
|
||||
|
|
|
@ -50,7 +50,7 @@ describe('InvoiceOut manual invoice path', () => {
|
|||
});
|
||||
|
||||
it('should create an invoice from a client', async() => {
|
||||
await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceClient, 'Charles Xavier');
|
||||
await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceClient, 'Max Eisenhardt');
|
||||
await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceSerial, 'Global nacional');
|
||||
await page.autocompleteSearch(selectors.invoiceOutIndex.manualInvoiceTaxArea, 'national');
|
||||
await page.waitToClick(selectors.invoiceOutIndex.saveInvoice);
|
||||
|
|
|
@ -221,6 +221,7 @@
|
|||
"Can't transfer claimed sales": "No puedes transferir lineas reclamadas",
|
||||
"You don't have privileges to create pay back": "No tienes permisos para crear un abono",
|
||||
"The item is required": "El artículo es requerido",
|
||||
"The agency is already assigned to another autonomous": "La agencia ya está asignada a otro autónomo",
|
||||
"date in the future": "Fecha en el futuro",
|
||||
"reference duplicated": "Referencia duplicada"
|
||||
}
|
|
@ -52,10 +52,12 @@ class Controller extends Section {
|
|||
}
|
||||
|
||||
scrollToLine(lineFk) {
|
||||
const hashFk = this.lineFk || lineFk;
|
||||
const hash = `vnItemDiary-${hashFk}`;
|
||||
this.$location.hash(hash);
|
||||
this.$anchorScroll();
|
||||
this.$.$applyAsync(() => {
|
||||
const hashFk = this.lineFk || lineFk;
|
||||
const hash = `vnItemDiary-${hashFk}`;
|
||||
this.$location.hash(hash);
|
||||
this.$anchorScroll();
|
||||
});
|
||||
}
|
||||
|
||||
showDescriptor(event, sale) {
|
||||
|
|
|
@ -47,6 +47,8 @@ describe('Item', () => {
|
|||
controller.lineFk = 1;
|
||||
controller.scrollToLine('invalidValue');
|
||||
|
||||
$scope.$apply();
|
||||
|
||||
expect(controller.$location.hash()).toEqual(`vnItemDiary-${1}`);
|
||||
expect(controller.$anchorScroll).toHaveBeenCalledWith();
|
||||
});
|
||||
|
@ -56,6 +58,8 @@ describe('Item', () => {
|
|||
controller.lineFk = undefined;
|
||||
controller.scrollToLine(1);
|
||||
|
||||
$scope.$apply();
|
||||
|
||||
expect(controller.$location.hash()).toEqual(`vnItemDiary-${1}`);
|
||||
expect(controller.$anchorScroll).toHaveBeenCalledWith();
|
||||
});
|
||||
|
|
|
@ -222,8 +222,8 @@ describe('SalesMonitor salesFilter()', () => {
|
|||
const firstTicket = result.shift();
|
||||
const secondTicket = result.shift();
|
||||
|
||||
expect(firstTicket.totalProblems).toEqual(3);
|
||||
expect(secondTicket.totalProblems).toEqual(2);
|
||||
expect(firstTicket.totalProblems).toEqual(1);
|
||||
expect(secondTicket.totalProblems).toEqual(1);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
|
|
|
@ -87,21 +87,21 @@ module.exports = Self => {
|
|||
SUM(t.packages) packages,
|
||||
r.m3,
|
||||
r.kmEnd - r.kmStart kmTotal,
|
||||
CAST(IFNULL(ate.routePrice,
|
||||
(ate.kmPrice * (GREATEST(r.kmEnd - r.kmStart , ate.minimumKm))
|
||||
+ GREATEST(r.m3 , ate.minimumM3) * ate.m3Price)
|
||||
+ ate.packagePrice * SUM(t.packages) )
|
||||
CAST(IFNULL(sat.routePrice,
|
||||
(sat.kmPrice * (GREATEST(r.kmEnd - r.kmStart , sat.minimumKm))
|
||||
+ GREATEST(r.m3 , sat.minimumM3) * sat.m3Price)
|
||||
+ sat.packagePrice * SUM(t.packages) )
|
||||
AS DECIMAL(10,2)) price,
|
||||
r.invoiceInFk,
|
||||
a.supplierFk,
|
||||
sat.supplierFk,
|
||||
s.name supplierName
|
||||
FROM vn.route r
|
||||
LEFT JOIN vn.agencyMode am ON r.agencyModeFk = am.id
|
||||
LEFT JOIN vn.agency a ON am.agencyFk = a.id
|
||||
LEFT JOIN vn.ticket t ON t.routeFk = r.id
|
||||
LEFT JOIN vn.agencyTerm ate ON ate.agencyFk = a.id
|
||||
LEFT JOIN vn.supplier s ON s.id = a.supplierFk
|
||||
WHERE r.created > DATE_ADD(CURDATE(), INTERVAL -2 MONTH) AND a.supplierFk IS NOT NULL
|
||||
LEFT JOIN vn.supplierAgencyTerm sat ON sat.agencyFk = a.id
|
||||
LEFT JOIN vn.supplier s ON s.id = sat.supplierFk
|
||||
WHERE r.created > DATE_ADD(CURDATE(), INTERVAL -2 MONTH) AND sat.supplierFk IS NOT NULL
|
||||
GROUP BY r.id
|
||||
) a`
|
||||
);
|
||||
|
|
|
@ -18,7 +18,7 @@ describe('AgencyTerm filter()', () => {
|
|||
const firstAgencyTerm = agencyTerms[0];
|
||||
|
||||
expect(firstAgencyTerm.routeFk).toEqual(1);
|
||||
expect(agencyTerms.length).toEqual(3);
|
||||
expect(agencyTerms.length).toEqual(5);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
|
@ -72,7 +72,7 @@ describe('AgencyTerm filter()', () => {
|
|||
|
||||
const results = await models.AgencyTerm.filter(ctx, options);
|
||||
|
||||
expect(results.length).toBe(3);
|
||||
expect(results.length).toBe(5);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('freeAgencies', {
|
||||
description: 'Returns a list of agencies without a supplier assigned',
|
||||
accepts: [{
|
||||
arg: 'filter',
|
||||
type: 'object',
|
||||
description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string`
|
||||
}],
|
||||
returns: {
|
||||
type: ['object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/freeAgencies`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.freeAgencies = async(filter, options) => {
|
||||
const conn = Self.dataSource.connector;
|
||||
const where = {'sat.supplierFk': null};
|
||||
const myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
filter = mergeFilters(filter, {where});
|
||||
|
||||
let stmt = new ParameterizedSQL(
|
||||
`SELECT a.name, a.id
|
||||
FROM agency a
|
||||
LEFT JOIN supplierAgencyTerm sat ON sat.agencyFk = a.id`,
|
||||
null, myOptions);
|
||||
|
||||
stmt.merge(conn.makeSuffix(filter));
|
||||
|
||||
return conn.executeStmt(stmt);
|
||||
};
|
||||
};
|
|
@ -11,6 +11,9 @@
|
|||
"SupplierAccount": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"SupplierAgencyTerm": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"SupplierLog": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.rewriteDbError(function(err) {
|
||||
if (err.code === 'ER_DUP_ENTRY')
|
||||
return new UserError(`The agency is already assigned to another autonomous`);
|
||||
return err;
|
||||
});
|
||||
};
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"name": "SupplierAgencyTerm",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "supplierAgencyTerm"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"agencyFk": {
|
||||
"type": "number",
|
||||
"id": true
|
||||
},
|
||||
"supplierFk": {
|
||||
"type": "number"
|
||||
},
|
||||
"minimumPackages": {
|
||||
"type": "number"
|
||||
},
|
||||
"kmPrice": {
|
||||
"type": "number"
|
||||
},
|
||||
"packagePrice": {
|
||||
"type": "number"
|
||||
},
|
||||
"routePrice": {
|
||||
"type": "number"
|
||||
},
|
||||
"minimumKm": {
|
||||
"type": "number"
|
||||
},
|
||||
"minimumM3": {
|
||||
"type": "number"
|
||||
},
|
||||
"m3Price": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"agency": {
|
||||
"type": "belongsTo",
|
||||
"model": "Agency",
|
||||
"foreignKey": "agencyFk"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ module.exports = Self => {
|
|||
require('../methods/supplier/getSummary')(Self);
|
||||
require('../methods/supplier/updateFiscalData')(Self);
|
||||
require('../methods/supplier/consumption')(Self);
|
||||
require('../methods/supplier/freeAgencies')(Self);
|
||||
|
||||
Self.validatesPresenceOf('name', {
|
||||
message: 'The social name cannot be empty'
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
url="SupplierAgencyTerms"
|
||||
primary-key="agencyFk"
|
||||
data="$ctrl.supplierAgencyTerm"
|
||||
insert-mode="true"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Suppliers/freeAgencies"
|
||||
data="$ctrl.agencies">
|
||||
</vn-crud-model>
|
||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-one
|
||||
label="Agency"
|
||||
ng-model="$ctrl.supplierAgencyTerm.agencyFk"
|
||||
data="$ctrl.agencies"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
rule>
|
||||
</vn-autocomplete>
|
||||
<vn-input-number
|
||||
type="number"
|
||||
label="Minimum M3"
|
||||
ng-model="$ctrl.supplierAgencyTerm.minimumM3"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-input-number
|
||||
type="number"
|
||||
label="Package Price"
|
||||
ng-model="$ctrl.supplierAgencyTerm.packagePrice"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
type="number"
|
||||
label="Km Price"
|
||||
ng-model="$ctrl.supplierAgencyTerm.kmPrice"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
type="number"
|
||||
label="M3 Price"
|
||||
ng-model="$ctrl.supplierAgencyTerm.m3Price"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-input-number
|
||||
type="number"
|
||||
label="Route Price"
|
||||
ng-model="$ctrl.supplierAgencyTerm.routePrice"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
type="number"
|
||||
label="Minimum Km"
|
||||
ng-model="$ctrl.supplierAgencyTerm.minimumKm"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit label="Save"></vn-submit>
|
||||
<vn-button
|
||||
label="Cancel"
|
||||
ui-sref="supplier.card.agencyTerm.index">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
|
@ -0,0 +1,26 @@
|
|||
import ngModule from '../../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
|
||||
this.supplierAgencyTerm = {
|
||||
supplierFk: this.$params.id
|
||||
};
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.$.watcher.submit().then(res => {
|
||||
this.$state.go('supplier.card.agencyTerm.index');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnSupplierAgencyTermCreate', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
supplier: '<'
|
||||
}
|
||||
});
|
|
@ -0,0 +1,28 @@
|
|||
import './index';
|
||||
import watcher from 'core/mocks/watcher';
|
||||
|
||||
describe('Supplier', () => {
|
||||
describe('Component vnSupplierAddressCreate', () => {
|
||||
let $scope;
|
||||
let controller;
|
||||
let $element;
|
||||
|
||||
beforeEach(ngModule('supplier'));
|
||||
|
||||
beforeEach(inject(($componentController, $rootScope, _$state_) => {
|
||||
$scope = $rootScope.$new();
|
||||
$scope.watcher = watcher;
|
||||
$element = angular.element('<vn-supplier-agency-term-create></vn-supplier-agency-term-create>');
|
||||
controller = $componentController('vnSupplierAgencyTermCreate', {$element, $scope});
|
||||
}));
|
||||
|
||||
describe('onSubmit()', () => {
|
||||
it(`should redirect to 'supplier.card.agencyTerm.index' state`, () => {
|
||||
jest.spyOn(controller.$state, 'go');
|
||||
controller.onSubmit();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('supplier.card.agencyTerm.index');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,85 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="SupplierAgencyTerms"
|
||||
link="{supplierFk: $ctrl.$params.id}"
|
||||
primary-key="agencyFk"
|
||||
filter="$ctrl.filter"
|
||||
data="$ctrl.supplierAgencyTerms"
|
||||
auto-load="true">
|
||||
</vn-crud-model>
|
||||
<vn-watcher
|
||||
vn-id="watcher"
|
||||
data="$ctrl.supplierAgencyTerms"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-lg">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-horizontal ng-repeat="supplierAgencyTerm in $ctrl.supplierAgencyTerms">
|
||||
<vn-textfield
|
||||
disabled="true"
|
||||
vn-id="agency"
|
||||
label="Agency"
|
||||
ng-model="supplierAgencyTerm.agency.name"
|
||||
rule>
|
||||
</vn-textfield>
|
||||
<vn-input-number
|
||||
type="number"
|
||||
label="Minimum M3"
|
||||
ng-model="supplierAgencyTerm.minimumM3"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
type="number"
|
||||
label="Package Price"
|
||||
ng-model="supplierAgencyTerm.packagePrice"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
type="number"
|
||||
label="Km Price"
|
||||
ng-model="supplierAgencyTerm.kmPrice"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
type="number"
|
||||
label="M3 Price"
|
||||
ng-model="supplierAgencyTerm.m3Price"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
type="number"
|
||||
label="Route Price"
|
||||
ng-model="supplierAgencyTerm.routePrice"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-input-number
|
||||
type="number"
|
||||
label="Minimum Km"
|
||||
ng-model="supplierAgencyTerm.minimumKm"
|
||||
rule>
|
||||
</vn-input-number>
|
||||
<vn-none>
|
||||
<vn-icon-button
|
||||
vn-tooltip="Remove row"
|
||||
icon="delete"
|
||||
ng-click="model.remove($index)"
|
||||
tabindex="-1">
|
||||
</vn-icon-button>
|
||||
</vn-none>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
<vn-submit
|
||||
disabled="!watcher.dataChanged()"
|
||||
label="Save">
|
||||
</vn-submit>
|
||||
</vn-button-bar>
|
||||
</form>
|
||||
<vn-float-button
|
||||
vn-bind="+"
|
||||
fixed-bottom-right
|
||||
vn-tooltip="New row"
|
||||
ui-sref="supplier.card.agencyTerm.create"
|
||||
icon="add"
|
||||
label="Add">
|
||||
</vn-float-button>
|
|
@ -0,0 +1,36 @@
|
|||
import ngModule from '../../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
class Controller extends Section {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
this.filter = {
|
||||
include:
|
||||
{relation: 'agency',
|
||||
scope: {
|
||||
fields: ['id', 'name']
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
add() {
|
||||
this.$.model.insert({});
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.$.watcher.check();
|
||||
this.$.model.save().then(() => {
|
||||
this.$.watcher.notifySaved();
|
||||
this.$.watcher.updateOriginalData();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnSupplierAgencyTermIndex', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
supplier: '<'
|
||||
}
|
||||
});
|
|
@ -0,0 +1,37 @@
|
|||
import './index';
|
||||
import watcher from 'core/mocks/watcher';
|
||||
import crudModel from 'core/mocks/crud-model';
|
||||
|
||||
describe('Supplier', () => {
|
||||
describe('Component vnSupplierAddressCreate', () => {
|
||||
let $scope;
|
||||
let controller;
|
||||
let $element;
|
||||
|
||||
beforeEach(ngModule('supplier'));
|
||||
|
||||
beforeEach(inject(($componentController, $rootScope, _$state_) => {
|
||||
$scope = $rootScope.$new();
|
||||
$scope.model = crudModel;
|
||||
$scope.watcher = watcher;
|
||||
$element = angular.element('<vn-supplier-agency-term-index></vn-supplier-agency-term-index>');
|
||||
controller = $componentController('vnSupplierAgencyTermIndex', {$element, $scope});
|
||||
}));
|
||||
|
||||
describe('onSubmit()', () => {
|
||||
it('should make HTTP POST request to save values', () => {
|
||||
jest.spyOn($scope.watcher, 'check');
|
||||
jest.spyOn($scope.watcher, 'notifySaved');
|
||||
jest.spyOn($scope.watcher, 'updateOriginalData');
|
||||
jest.spyOn($scope.model, 'save');
|
||||
|
||||
controller.onSubmit();
|
||||
|
||||
expect($scope.model.save).toHaveBeenCalledWith();
|
||||
expect($scope.watcher.updateOriginalData).toHaveBeenCalledWith();
|
||||
expect($scope.watcher.check).toHaveBeenCalledWith();
|
||||
expect($scope.watcher.notifySaved).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
Minimum M3: M3 minimos
|
||||
Package Price: Precio bulto
|
||||
Km Price: Precio Km
|
||||
M3 Price: Precio M3
|
||||
Route Price: Precio ruta
|
||||
Minimum Km: Km minimos
|
||||
Remove row: Eliminar fila
|
||||
Add row: Añadir fila
|
|
@ -18,3 +18,5 @@ import './billing-data';
|
|||
import './address/index';
|
||||
import './address/create';
|
||||
import './address/edit';
|
||||
import './agency-term/index';
|
||||
import './agency-term/create';
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
{"state": "supplier.card.address.index", "icon": "icon-delivery"},
|
||||
{"state": "supplier.card.account", "icon": "icon-account"},
|
||||
{"state": "supplier.card.contact", "icon": "contact_phone"},
|
||||
{"state": "supplier.card.agencyTerm.index", "icon": "contact_support"},
|
||||
{"state": "supplier.card.log", "icon": "history"},
|
||||
{"state": "supplier.card.consumption", "icon": "show_chart"}
|
||||
]
|
||||
|
@ -86,6 +87,30 @@
|
|||
"supplier": "$ctrl.supplier"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "/agency-term",
|
||||
"state": "supplier.card.agencyTerm",
|
||||
"component": "ui-view",
|
||||
"abstract": true
|
||||
},
|
||||
{
|
||||
"url": "/index",
|
||||
"state": "supplier.card.agencyTerm.index",
|
||||
"component": "vn-supplier-agency-term-index",
|
||||
"description": "Autonomous",
|
||||
"params": {
|
||||
"supplier": "$ctrl.supplier"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "/create",
|
||||
"state": "supplier.card.agencyTerm.create",
|
||||
"component": "vn-supplier-agency-term-create",
|
||||
"description": "New autonomous",
|
||||
"params": {
|
||||
"supplier": "$ctrl.supplier"
|
||||
}
|
||||
},
|
||||
{
|
||||
"url": "/consumption?q",
|
||||
"state": "supplier.card.consumption",
|
||||
|
|
|
@ -28,16 +28,6 @@ module.exports = Self => {
|
|||
type: 'date',
|
||||
description: 'The shipped from date filter'
|
||||
},
|
||||
{
|
||||
arg: 'shippedTo',
|
||||
type: 'date',
|
||||
description: 'The shipped to date filter'
|
||||
},
|
||||
{
|
||||
arg: 'landedFrom',
|
||||
type: 'date',
|
||||
description: 'The landed from date filter'
|
||||
},
|
||||
{
|
||||
arg: 'landedTo',
|
||||
type: 'date',
|
||||
|
@ -101,10 +91,6 @@ module.exports = Self => {
|
|||
return {'t.ref': {like: `%${value}%`}};
|
||||
case 'shippedFrom':
|
||||
return {'t.shipped': {gte: value}};
|
||||
case 'shippedTo':
|
||||
return {'t.shipped': {lte: value}};
|
||||
case 'landedFrom':
|
||||
return {'t.landed': {gte: value}};
|
||||
case 'landedTo':
|
||||
return {'t.landed': {lte: value}};
|
||||
case 'continent':
|
||||
|
@ -162,6 +148,7 @@ module.exports = Self => {
|
|||
|
||||
stmt.merge(conn.makeWhere(filter.where));
|
||||
stmt.merge(conn.makeGroupBy('t.id'));
|
||||
stmt.merge(conn.makeOrderBy(filter.order));
|
||||
stmt.merge(conn.makeLimit(filter));
|
||||
stmts.push(stmt);
|
||||
|
||||
|
|
|
@ -46,15 +46,64 @@ describe('Travel extraCommunityFilter()', () => {
|
|||
expect(result.length).toEqual(3);
|
||||
});
|
||||
|
||||
it('should return the routes matching "landed from" and "landed to"', async() => {
|
||||
const from = new Date();
|
||||
const to = new Date();
|
||||
from.setHours(0, 0, 0, 0);
|
||||
to.setHours(23, 59, 59, 999);
|
||||
to.setDate(to.getDate() + 14);
|
||||
it('should return the travel matching "warehouse in"', async() => {
|
||||
const ctx = {
|
||||
args: {
|
||||
landedFrom: from,
|
||||
warehouseInFk: 1
|
||||
}
|
||||
};
|
||||
|
||||
const result = await app.models.Travel.extraCommunityFilter(ctx, filter);
|
||||
|
||||
expect(result.length).toEqual(4);
|
||||
});
|
||||
|
||||
it('should return the travel matching "continent"', async() => {
|
||||
const ctx = {
|
||||
args: {
|
||||
continent: 'AM'
|
||||
}
|
||||
};
|
||||
|
||||
const result = await app.models.Travel.extraCommunityFilter(ctx, filter);
|
||||
|
||||
expect(result.length).toEqual(3);
|
||||
});
|
||||
|
||||
it('should return the travel matching "agencyFk"', async() => {
|
||||
const ctx = {
|
||||
args: {
|
||||
agencyFk: 1
|
||||
}
|
||||
};
|
||||
|
||||
const result = await app.models.Travel.extraCommunityFilter(ctx, filter);
|
||||
|
||||
expect(result.length).toEqual(8);
|
||||
});
|
||||
|
||||
it('should return the travel matching "cargoSupplierFk"', async() => {
|
||||
const ctx = {
|
||||
args: {
|
||||
cargoSupplierFk: 1
|
||||
}
|
||||
};
|
||||
|
||||
const result = await app.models.Travel.extraCommunityFilter(ctx, filter);
|
||||
|
||||
expect(result.length).toEqual(4);
|
||||
});
|
||||
|
||||
it('should return the routes matching "shipped from" and "landed to"', async() => {
|
||||
const from = new Date();
|
||||
from.setDate(from.getDate() - 2);
|
||||
from.setHours(0, 0, 0, 0);
|
||||
const to = new Date();
|
||||
to.setHours(23, 59, 59, 999);
|
||||
to.setDate(to.getDate() + 7);
|
||||
const ctx = {
|
||||
args: {
|
||||
shippedFrom: from,
|
||||
landedTo: to
|
||||
}
|
||||
};
|
||||
|
|
|
@ -47,17 +47,6 @@
|
|||
ng-model="$ctrl.landedTo">
|
||||
</vn-date-picker>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="Shipped to"
|
||||
ng-model="$ctrl.shippedTo">
|
||||
</vn-date-picker>
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="Landed from"
|
||||
ng-model="$ctrl.landedFrom">
|
||||
</vn-date-picker>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-one
|
||||
|
|
|
@ -14,31 +14,6 @@ class Controller extends SearchPanel {
|
|||
|
||||
set shippedFrom(value) {
|
||||
this.filter.shippedFrom = value;
|
||||
|
||||
if (!this.filter.landedFrom)
|
||||
this.filter.landedFrom = value;
|
||||
}
|
||||
|
||||
get shippedTo() {
|
||||
return this.filter.shippedTo;
|
||||
}
|
||||
|
||||
set shippedTo(value) {
|
||||
this.filter.shippedTo = value;
|
||||
|
||||
if (!this.filter.landedTo)
|
||||
this.filter.landedTo = value;
|
||||
}
|
||||
|
||||
get landedFrom() {
|
||||
return this.filter.landedFrom;
|
||||
}
|
||||
|
||||
set landedFrom(value) {
|
||||
this.filter.landedFrom = value;
|
||||
|
||||
if (!this.filter.shippedFrom)
|
||||
this.filter.shippedFrom = value;
|
||||
}
|
||||
|
||||
get landedTo() {
|
||||
|
@ -47,9 +22,6 @@ class Controller extends SearchPanel {
|
|||
|
||||
set landedTo(value) {
|
||||
this.filter.landedTo = value;
|
||||
|
||||
if (!this.filter.shippedTo)
|
||||
this.filter.shippedTo = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
vn-id="model"
|
||||
url="Travels/extraCommunityFilter"
|
||||
data="travels"
|
||||
order="landed ASC, shipped ASC, travelFk, loadPriority, agencyModeFk, evaNotes"
|
||||
order="shipped ASC, landed ASC, travelFk, loadPriority, agencyModeFk, evaNotes"
|
||||
limit="20"
|
||||
auto-load="true">
|
||||
</vn-crud-model>
|
||||
|
|
|
@ -17,16 +17,18 @@ class Controller extends Section {
|
|||
this.draggableElement = 'a[draggable]';
|
||||
this.droppableElement = 'vn-tbody[vn-droppable]';
|
||||
|
||||
const scopeDays = 14;
|
||||
const landedFrom = new Date();
|
||||
landedFrom.setHours(0, 0, 0, 0);
|
||||
const twoDays = 2;
|
||||
const shippedFrom = new Date();
|
||||
shippedFrom.setDate(shippedFrom.getDate() - twoDays);
|
||||
shippedFrom.setHours(0, 0, 0, 0);
|
||||
|
||||
const sevenDays = 7;
|
||||
const landedTo = new Date();
|
||||
landedTo.setDate(landedTo.getDate() + scopeDays);
|
||||
landedTo.setDate(landedTo.getDate() + sevenDays);
|
||||
landedTo.setHours(23, 59, 59, 59);
|
||||
|
||||
this.defaultFilter = {
|
||||
landedFrom: landedFrom,
|
||||
shippedFrom: shippedFrom,
|
||||
landedTo: landedTo,
|
||||
continent: 'AM'
|
||||
};
|
||||
|
@ -34,10 +36,12 @@ class Controller extends Section {
|
|||
|
||||
get hasDateRange() {
|
||||
const userParams = this.$.model.userParams;
|
||||
const hasLanded = userParams.landedFrom || userParams.landedTo;
|
||||
const hasShipped = userParams.shippedFrom || userParams.shippedTo;
|
||||
const hasLanded = userParams.landedTo;
|
||||
const hasShipped = userParams.shippedFrom;
|
||||
const hasContinent = userParams.continent;
|
||||
const hasWarehouseOut = userParams.warehouseOutFk;
|
||||
|
||||
return hasLanded || hasShipped;
|
||||
return hasLanded || hasShipped || hasContinent || hasWarehouseOut;
|
||||
}
|
||||
|
||||
findDraggable($event) {
|
||||
|
|
|
@ -9,8 +9,8 @@ vn-travel-extra-community {
|
|||
padding-bottom: 7px;
|
||||
padding-bottom: 4px;
|
||||
font-weight: lighter;
|
||||
background-color: #fde6ca;
|
||||
color: $color-font-light;
|
||||
background-color: $color-bg;
|
||||
color: white;
|
||||
border-bottom: 1px solid #f7931e;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('holidays', {
|
||||
|
@ -33,7 +34,8 @@ module.exports = Self => {
|
|||
Self.holidays = async(ctx, id, options) => {
|
||||
const models = Self.app.models;
|
||||
const args = ctx.args;
|
||||
|
||||
const conn = Self.dataSource.connector;
|
||||
const stmts = [];
|
||||
const myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
|
@ -56,42 +58,6 @@ module.exports = Self => {
|
|||
ended.setHours(23, 59, 59, 59);
|
||||
|
||||
const filter = {
|
||||
include: [{
|
||||
relation: 'holidays',
|
||||
scope: {
|
||||
where: {year: args.year}
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'absences',
|
||||
scope: {
|
||||
include: {
|
||||
relation: 'absenceType',
|
||||
},
|
||||
where: {
|
||||
dated: {between: [started, ended]}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'workCenter',
|
||||
scope: {
|
||||
include: {
|
||||
relation: 'holidays',
|
||||
scope: {
|
||||
include: [{
|
||||
relation: 'detail'
|
||||
},
|
||||
{
|
||||
relation: 'type'
|
||||
}],
|
||||
where: {
|
||||
dated: {between: [started, ended]}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}],
|
||||
where: {
|
||||
and: [
|
||||
{workerFk: id},
|
||||
|
@ -107,76 +73,32 @@ module.exports = Self => {
|
|||
|
||||
}
|
||||
};
|
||||
if (args.businessFk)
|
||||
filter.where.and.push({businessFk: args.businessFk});
|
||||
|
||||
const contracts = await models.WorkerLabour.find(filter, myOptions);
|
||||
|
||||
let [firstContract] = contracts;
|
||||
let payedHolidays;
|
||||
const payedHolidays = firstContract.payedHolidays;
|
||||
|
||||
if (firstContract.payedHolidays)
|
||||
payedHolidays = firstContract.payedHolidays;
|
||||
else payedHolidays = 0;
|
||||
let queryIndex;
|
||||
const year = started.getFullYear();
|
||||
|
||||
let totalHolidays = 0;
|
||||
let holidaysEnjoyed = 0;
|
||||
|
||||
for (let contract of contracts) {
|
||||
const contractStarted = contract.started;
|
||||
contractStarted.setHours(0, 0, 0, 0);
|
||||
const contractEnded = contract.ended;
|
||||
if (contractEnded)
|
||||
contractEnded.setHours(23, 59, 59, 59);
|
||||
|
||||
let startedTime;
|
||||
if (contractStarted < started)
|
||||
startedTime = started.getTime();
|
||||
else startedTime = contractStarted.getTime();
|
||||
|
||||
let endedTime;
|
||||
if (!contractEnded || (contractEnded && contractEnded > ended))
|
||||
endedTime = ended.getTime();
|
||||
else endedTime = contractEnded.getTime();
|
||||
|
||||
const dayTimestamp = 1000 * 60 * 60 * 24;
|
||||
|
||||
// Get number of worked days between dates
|
||||
let workedDays = Math.floor((endedTime - startedTime) / dayTimestamp);
|
||||
workedDays += 1; // 1 day inclusion
|
||||
|
||||
// Calculates absences
|
||||
let entitlementRate = 0;
|
||||
for (let absence of contract.absences()) {
|
||||
const absenceType = absence.absenceType();
|
||||
const isHoliday = absenceType.code === 'holiday';
|
||||
const isHalfHoliday = absenceType.code === 'halfHoliday';
|
||||
|
||||
if (isHoliday) holidaysEnjoyed += 1;
|
||||
if (isHalfHoliday) holidaysEnjoyed += 0.5;
|
||||
|
||||
entitlementRate += absenceType.holidayEntitlementRate;
|
||||
}
|
||||
|
||||
workedDays -= entitlementRate;
|
||||
|
||||
// Max holidays for the selected year
|
||||
const maxHolidays = contract.holidays() && contract.holidays().days;
|
||||
|
||||
if (workedDays < daysInYear())
|
||||
totalHolidays += Math.round(2 * maxHolidays * (workedDays) / daysInYear()) / 2;
|
||||
else totalHolidays = maxHolidays;
|
||||
if (args.businessFk) {
|
||||
stmts.push(new ParameterizedSQL('CALL vn.workerCalendar_calculateBusiness(?,?)', [year, args.businessFk]));
|
||||
queryIndex = stmts.push('SELECT * FROM tmp.workerCalendarCalculateBusiness') - 1;
|
||||
stmts.push('DROP TEMPORARY TABLE tmp.workerCalendarCalculateBusiness');
|
||||
} else {
|
||||
stmts.push(new ParameterizedSQL('CALL vn.workerCalendar_calculateYear(?,?)', [year, id]));
|
||||
queryIndex = stmts.push('SELECT * FROM tmp.workerCalendarCalculateYear') - 1;
|
||||
stmts.push('DROP TEMPORARY TABLE tmp.workerCalendarCalculateYear');
|
||||
}
|
||||
|
||||
function daysInYear() {
|
||||
const year = started.getFullYear();
|
||||
const sql = ParameterizedSQL.join(stmts, ';');
|
||||
const result = await conn.executeStmt(sql, myOptions);
|
||||
const [holidays] = result[queryIndex];
|
||||
|
||||
return isLeapYear(year) ? 366 : 365;
|
||||
}
|
||||
return {totalHolidays, holidaysEnjoyed, payedHolidays};
|
||||
const totalHolidays = holidays.days;
|
||||
const holidaysEnjoyed = holidays.daysEnjoyed;
|
||||
const totalHours = holidays.hours;
|
||||
const hoursEnjoyed = holidays.hoursEnjoyed;
|
||||
|
||||
return {totalHolidays, holidaysEnjoyed, totalHours, hoursEnjoyed, payedHolidays};
|
||||
};
|
||||
|
||||
function isLeapYear(year) {
|
||||
return year % 400 === 0 || (year % 100 !== 0 && year % 4 === 0);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
},
|
||||
"notificationEmail": {
|
||||
"type": "string"
|
||||
},
|
||||
"hasToMistake": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,20 +25,28 @@
|
|||
<div class="totalBox vn-mb-sm" style="text-align: center;">
|
||||
<h6>{{'Contract' | translate}} #{{$ctrl.businessId}}</h6>
|
||||
<div>
|
||||
{{'Used' | translate}} {{$ctrl.contractHolidays.holidaysEnjoyed}}
|
||||
{{'Used' | translate}} {{$ctrl.contractHolidays.holidaysEnjoyed || 0}}
|
||||
{{'of' | translate}} {{$ctrl.contractHolidays.totalHolidays || 0}} {{'days' | translate}}
|
||||
</div>
|
||||
<div>
|
||||
{{'Paid holidays' | translate}} {{$ctrl.contractHolidays.payedHolidays}} {{'days' | translate}}
|
||||
{{'Spent' | translate}} {{$ctrl.contractHolidays.hoursEnjoyed || 0}}
|
||||
{{'of' | translate}} {{$ctrl.contractHolidays.totalHours || 0}} {{'hours' | translate}}
|
||||
</div>
|
||||
<div>
|
||||
{{'Paid holidays' | translate}} {{$ctrl.contractHolidays.payedHolidays || 0}} {{'days' | translate}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="totalBox" style="text-align: center;">
|
||||
<h6>{{'Year' | translate}} {{$ctrl.year}}</h6>
|
||||
<div>
|
||||
{{'Used' | translate}} {{$ctrl.yearHolidays.holidaysEnjoyed}}
|
||||
{{'Used' | translate}} {{$ctrl.yearHolidays.holidaysEnjoyed || 0}}
|
||||
{{'of' | translate}} {{$ctrl.yearHolidays.totalHolidays || 0}} {{'days' | translate}}
|
||||
</div>
|
||||
<div>
|
||||
{{'Spent' | translate}} {{$ctrl.yearHolidays.hoursEnjoyed || 0}}
|
||||
{{'of' | translate}} {{$ctrl.yearHolidays.totalHours || 0}} {{'hours' | translate}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="vn-pt-md">
|
||||
|
|
|
@ -198,7 +198,7 @@ class Controller extends Section {
|
|||
const event = this.events[stamp];
|
||||
const calendar = $event.target.closest('vn-calendar').$ctrl;
|
||||
|
||||
if (event) {
|
||||
if (event && event.absenceId) {
|
||||
if (event.type == this.absenceType.code)
|
||||
this.delete(calendar, day, event);
|
||||
else
|
||||
|
@ -230,6 +230,7 @@ class Controller extends Section {
|
|||
.then(calendar.repaint())
|
||||
.then(() => this.getContractHolidays())
|
||||
.then(() => this.getYearHolidays())
|
||||
.then(() => this.repaint())
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -266,6 +267,7 @@ class Controller extends Section {
|
|||
.then(calendar.repaint())
|
||||
.then(() => this.getContractHolidays())
|
||||
.then(() => this.getYearHolidays())
|
||||
.then(() => this.repaint())
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -191,7 +191,8 @@ describe('Worker', () => {
|
|||
const selectedDay = new Date();
|
||||
const expectedEvent = {
|
||||
dated: selectedDay,
|
||||
type: 'holiday'
|
||||
type: 'holiday',
|
||||
absenceId: 1
|
||||
};
|
||||
const $event = {
|
||||
target: {
|
||||
|
@ -214,7 +215,8 @@ describe('Worker', () => {
|
|||
const selectedDay = new Date();
|
||||
const expectedEvent = {
|
||||
dated: selectedDay,
|
||||
type: 'leaveOfAbsence'
|
||||
type: 'leaveOfAbsence',
|
||||
absenceId: 1
|
||||
};
|
||||
const $event = {
|
||||
target: {
|
||||
|
|
|
@ -2,9 +2,11 @@ Calendar: Calendario
|
|||
Contract: Contrato
|
||||
Festive: Festivo
|
||||
Used: Utilizados
|
||||
Spent: Utilizadas
|
||||
Year: Año
|
||||
of: de
|
||||
days: días
|
||||
hours: horas
|
||||
Choose an absence type from the right menu: Elige un tipo de ausencia desde el menú de la derecha
|
||||
To start adding absences, click an absence type from the right menu and then on the day you want to add an absence: Para empezar a añadir ausencias, haz clic en un tipo de ausencia desde el menu de la derecha y después en el día que quieres añadir la ausencia
|
||||
You can just add absences within the current year: Solo puedes añadir ausencias dentro del año actual
|
||||
|
|
|
@ -16,5 +16,12 @@
|
|||
"type": "string",
|
||||
"required": false
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"supplierAgencyTerm": {
|
||||
"type": "hasOne",
|
||||
"model": "SupplierAgencyTerm",
|
||||
"foreignKey": "agencyFk"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,11 +8,16 @@ module.exports = {
|
|||
async serverPrefetch() {
|
||||
this.filters = this.$options.filters;
|
||||
const args = {
|
||||
landedFrom: this.landedStart,
|
||||
landedTo: this.landedEnd,
|
||||
shippedFrom: this.shippedStart,
|
||||
shippedTo: this.shippedEnd,
|
||||
continent: this.continent
|
||||
continent: this.continent,
|
||||
id: this.id,
|
||||
agencyFk: this.agencyFk,
|
||||
warehouseInFk: this.warehouseInFk,
|
||||
warehouseOutFk: this.warehouseOutFk,
|
||||
totalEntries: this.totalEntries,
|
||||
ref: this.ref,
|
||||
cargoSupplierFk: this.cargoSupplierFk
|
||||
};
|
||||
|
||||
const travels = await this.fetchTravels(args);
|
||||
|
@ -38,11 +43,6 @@ module.exports = {
|
|||
dated: function() {
|
||||
return this.filters.date(new Date(), '%d-%m-%Y');
|
||||
},
|
||||
landedStart: function() {
|
||||
if (!this.landedFrom) return;
|
||||
|
||||
return this.filters.date(this.landedFrom, '%Y-%m-%d');
|
||||
},
|
||||
landedEnd: function() {
|
||||
if (!this.landedTo) return;
|
||||
|
||||
|
@ -52,11 +52,6 @@ module.exports = {
|
|||
if (!this.shippedFrom) return;
|
||||
|
||||
return this.filters.date(this.shippedFrom, '%Y-%m-%d');
|
||||
},
|
||||
shippedEnd: function() {
|
||||
if (!this.shippedTo) return;
|
||||
|
||||
return this.filters.date(this.shippedTo, '%Y-%m-%d');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -65,20 +60,29 @@ module.exports = {
|
|||
switch (key) {
|
||||
case 'shippedFrom':
|
||||
return `t.shipped >= ${value}`;
|
||||
case 'shippedTo':
|
||||
return `t.shipped <= ${value}`;
|
||||
case 'landedFrom':
|
||||
return `t.landed >= ${value}`;
|
||||
case 'landedTo':
|
||||
return `t.landed <= ${value}`;
|
||||
case 'continent':
|
||||
return `cnt.code = ${value}`;
|
||||
case 'ref':
|
||||
return {'t.ref': {like: `%${value}%`}};
|
||||
case 'id':
|
||||
return `t.id = ${value}`;
|
||||
case 'agencyFk':
|
||||
return `am.id = ${value}`;
|
||||
case 'warehouseOutFk':
|
||||
return `wo.id = ${value}`;
|
||||
case 'warehouseInFk':
|
||||
return `w.id = ${value}`;
|
||||
case 'cargoSupplierFk':
|
||||
return `s.id = ${value}`;
|
||||
}
|
||||
});
|
||||
|
||||
let query = this.getSqlFromDef('travels');
|
||||
query = db.merge(query, where);
|
||||
query = db.merge(query, 'GROUP BY t.id');
|
||||
query = db.merge(query, 'ORDER BY `shipped` ASC, `landed` ASC, `travelFk`, `loadPriority`, `agencyModeFk`, `evaNotes`');
|
||||
|
||||
return this.rawSql(query);
|
||||
},
|
||||
|
@ -92,10 +96,15 @@ module.exports = {
|
|||
'report-footer': reportFooter.build()
|
||||
},
|
||||
props: [
|
||||
'landedFrom',
|
||||
'landedTo',
|
||||
'shippedFrom',
|
||||
'shippedTo',
|
||||
'continent'
|
||||
'continent',
|
||||
'ref',
|
||||
'id',
|
||||
'agencyFk',
|
||||
'warehouseOutFk',
|
||||
'warehouseInFk',
|
||||
'totalEntries',
|
||||
'cargoSupplierFk'
|
||||
]
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@ SELECT
|
|||
t.shipped,
|
||||
t.landed,
|
||||
t.kg,
|
||||
am.id AS agencyModeFk,
|
||||
SUM(b.stickers) AS stickers,
|
||||
CAST(SUM(i.density * b.stickers * IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000 ) as DECIMAL(10,0)) as loadedKg,
|
||||
CAST(SUM(167.5 * b.stickers * IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000 ) as DECIMAL(10,0)) as volumeKg
|
||||
|
|
Loading…
Reference in New Issue