fixes #5655 Afinar login #1516
17
CHANGELOG.md
17
CHANGELOG.md
|
@ -5,11 +5,12 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [2320.01] - 2023-05-25
|
||||
## [2322.01] - 2023-06-08
|
||||
|
||||
### Added
|
||||
-
|
||||
|
||||
|
||||
### Changed
|
||||
-
|
||||
|
||||
|
@ -18,6 +19,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
|
||||
|
||||
## [2320.01] - 2023-05-25
|
||||
|
||||
### Added
|
||||
- (Tickets -> Crear Factura) Al facturar se envia automáticamente el pdf al cliente
|
||||
|
||||
|
||||
### Changed
|
||||
- (Trabajadores -> Nuevo trabajador) Los clientes se crean sin 'TR' pero se añade tipo de negocio 'Trabajador'
|
||||
|
||||
### Fixed
|
||||
-
|
||||
|
||||
|
||||
|
||||
## [2318.01] - 2023-05-08
|
||||
|
||||
### Added
|
||||
|
|
|
@ -55,7 +55,7 @@ async function test() {
|
|||
const JunitReporter = require('jasmine-reporters');
|
||||
jasmine.addReporter(new JunitReporter.JUnitXmlReporter());
|
||||
|
||||
jasmine.jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
|
||||
jasmine.jasmine.DEFAULT_TIMEOUT_INTERVAL = 90000;
|
||||
jasmine.exitOnCompletion = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
-- vn.companyL10n source
|
||||
|
||||
CREATE OR REPLACE
|
||||
ALGORITHM = UNDEFINED VIEW `vn`.`companyL10n` AS
|
||||
select
|
||||
`c`.`id` AS `id`,
|
||||
ifnull(`ci`.`footnotes`, `c`.`footnotes`) AS `footnotes`
|
||||
from
|
||||
(`vn`.`company` `c`
|
||||
left join `vn`.`companyI18n` `ci` on
|
||||
(`ci`.`companyFk` = `c`.`id`
|
||||
and `ci`.`lang` = `util`.`LANG`()));
|
|
@ -0,0 +1,73 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`clientCreate`(
|
||||
vFirstname VARCHAR(50),
|
||||
vSurnames VARCHAR(50),
|
||||
vFi VARCHAR(9),
|
||||
vAddress TEXT,
|
||||
vPostcode CHAR(5),
|
||||
vCity VARCHAR(25),
|
||||
vProvinceFk SMALLINT(5),
|
||||
vCompanyFk SMALLINT(5),
|
||||
vPhone VARCHAR(11),
|
||||
vEmail VARCHAR(255),
|
||||
vUserFk INT)
|
||||
BEGIN
|
||||
/**
|
||||
* Create new client
|
||||
*
|
||||
*/
|
||||
DECLARE vPayMethodFk INT DEFAULT 4;
|
||||
DECLARE vDueDay INT DEFAULT 5;
|
||||
DECLARE vDefaultCredit DECIMAL(10, 2) DEFAULT 300.00;
|
||||
DECLARE vIsTaxDataChecked TINYINT(1) DEFAULT 1;
|
||||
DECLARE vHasCoreVnl BOOLEAN DEFAULT TRUE;
|
||||
DECLARE vMandateTypeFk INT DEFAULT 2;
|
||||
|
||||
INSERT INTO `client` (
|
||||
id,
|
||||
name,
|
||||
street,
|
||||
fi,
|
||||
phone,
|
||||
email,
|
||||
provinceFk,
|
||||
city,
|
||||
postcode,
|
||||
socialName,
|
||||
payMethodFk,
|
||||
dueDay,
|
||||
credit,
|
||||
isTaxDataChecked,
|
||||
hasCoreVnl,
|
||||
isEqualizated)
|
||||
VALUES (
|
||||
vUserFk,
|
||||
CONCAT(vFirstname, ' ', vSurnames),
|
||||
vAddress,
|
||||
TRIM(vFi),
|
||||
vPhone,
|
||||
vEmail,
|
||||
vProvinceFk,
|
||||
vCity,
|
||||
vPostcode,
|
||||
CONCAT(vSurnames, ' ', vFirstname),
|
||||
vPayMethodFk,
|
||||
vDueDay,
|
||||
vDefaultCredit,
|
||||
vIsTaxDataChecked,
|
||||
vHasCoreVnl,
|
||||
FALSE
|
||||
) ON duplicate key update
|
||||
payMethodFk = vPayMethodFk,
|
||||
dueDay = vDueDay,
|
||||
credit = vDefaultCredit,
|
||||
isTaxDataChecked = vIsTaxDataChecked,
|
||||
hasCoreVnl = vHasCoreVnl,
|
||||
isActive = TRUE;
|
||||
|
||||
IF (SELECT COUNT(*) FROM mandate WHERE clientFk = vUserFk AND companyFk = vCompanyFk AND mandateTypeFk = vMandateTypeFk) = 0 THEN
|
||||
INSERT INTO mandate (clientFk, companyFk, mandateTypeFk)
|
||||
VALUES (vUserFk, vCompanyFk, vMandateTypeFk);
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -0,0 +1,14 @@
|
|||
INSERT INTO `vn`.`businessType` (`code`, `description`)
|
||||
VALUES ('worker','Trabajador');
|
||||
|
||||
ALTER TABLE `vn`.`workerConfig` ADD businessTypeFk varchar(100) NULL
|
||||
COMMENT 'Tipo de negocio por defecto al dar de alta un trabajador nuevo';
|
||||
|
||||
UPDATE `vn`.`workerConfig`
|
||||
SET businessTypeFk = 'worker'
|
||||
WHERE id = 1;
|
||||
|
||||
UPDATE `vn`.`client` c
|
||||
JOIN `vn`.`worker` w ON w.id = c.id
|
||||
SET c.name = REPLACE(c.name, 'TR ', ''),
|
||||
c.businessTypeFk = 'worker';
|
|
@ -0,0 +1,254 @@
|
|||
DROP PROCEDURE IF EXISTS `vn`.`invoiceOut_new`;
|
||||
|
||||
DELIMITER $$
|
||||
$$
|
||||
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`invoiceOut_new`(
|
||||
vSerial VARCHAR(255),
|
||||
vInvoiceDate DATE,
|
||||
vTaxArea VARCHAR(25),
|
||||
OUT vNewInvoiceId INT)
|
||||
BEGIN
|
||||
/**
|
||||
* Creación de facturas emitidas.
|
||||
* requiere previamente tabla tmp.ticketToInvoice(id).
|
||||
*
|
||||
* @param vSerial serie a la cual se hace la factura
|
||||
* @param vInvoiceDate fecha de la factura
|
||||
* @param vTaxArea tipo de iva en relacion a la empresa y al cliente
|
||||
* @param vNewInvoiceId id de la factura que se acaba de generar
|
||||
* @return vNewInvoiceId
|
||||
*/
|
||||
DECLARE vIsAnySaleToInvoice BOOL;
|
||||
DECLARE vIsAnyServiceToInvoice BOOL;
|
||||
DECLARE vNewRef VARCHAR(255);
|
||||
DECLARE vWorker INT DEFAULT account.myUser_getId();
|
||||
DECLARE vCompanyFk INT;
|
||||
DECLARE vInterCompanyFk INT;
|
||||
DECLARE vClientFk INT;
|
||||
DECLARE vCplusStandardInvoiceTypeFk INT DEFAULT 1;
|
||||
DECLARE vCplusCorrectingInvoiceTypeFk INT DEFAULT 6;
|
||||
DECLARE vCplusSimplifiedInvoiceTypeFk INT DEFAULT 2;
|
||||
DECLARE vCorrectingSerial VARCHAR(1) DEFAULT 'R';
|
||||
DECLARE vSimplifiedSerial VARCHAR(1) DEFAULT 'S';
|
||||
DECLARE vNewInvoiceInFk INT;
|
||||
DECLARE vIsInterCompany BOOL DEFAULT FALSE;
|
||||
DECLARE vIsCEESerial BOOL DEFAULT FALSE;
|
||||
DECLARE vIsCorrectInvoiceDate BOOL;
|
||||
DECLARE vMaxShipped DATE;
|
||||
|
||||
SET vInvoiceDate = IFNULL(vInvoiceDate, util.VN_CURDATE());
|
||||
|
||||
SELECT t.clientFk,
|
||||
t.companyFk,
|
||||
MAX(DATE(t.shipped)),
|
||||
DATE(vInvoiceDate) >= invoiceOut_getMaxIssued(
|
||||
vSerial,
|
||||
t.companyFk,
|
||||
YEAR(vInvoiceDate))
|
||||
INTO vClientFk,
|
||||
vCompanyFk,
|
||||
vMaxShipped,
|
||||
vIsCorrectInvoiceDate
|
||||
FROM tmp.ticketToInvoice tt
|
||||
JOIN ticket t ON t.id = tt.id;
|
||||
|
||||
IF(vMaxShipped > vInvoiceDate) THEN
|
||||
CALL util.throw("Invoice date can't be less than max date");
|
||||
END IF;
|
||||
|
||||
IF NOT vIsCorrectInvoiceDate THEN
|
||||
CALL util.throw('Exists an invoice with a previous date');
|
||||
END IF;
|
||||
|
||||
-- Eliminem de tmp.ticketToInvoice els tickets que no han de ser facturats
|
||||
DELETE ti.*
|
||||
FROM tmp.ticketToInvoice ti
|
||||
JOIN ticket t ON t.id = ti.id
|
||||
JOIN sale s ON s.ticketFk = t.id
|
||||
JOIN item i ON i.id = s.itemFk
|
||||
JOIN supplier su ON su.id = t.companyFk
|
||||
JOIN client c ON c.id = t.clientFk
|
||||
LEFT JOIN itemTaxCountry itc ON itc.itemFk = i.id AND itc.countryFk = su.countryFk
|
||||
WHERE (YEAR(t.shipped) < 2001 AND t.isDeleted)
|
||||
OR c.isTaxDataChecked = FALSE
|
||||
OR t.isDeleted
|
||||
OR c.hasToInvoice = FALSE
|
||||
OR itc.id IS NULL;
|
||||
|
||||
SELECT SUM(s.quantity * s.price * (100 - s.discount)/100) <> 0
|
||||
INTO vIsAnySaleToInvoice
|
||||
FROM tmp.ticketToInvoice t
|
||||
JOIN sale s ON s.ticketFk = t.id;
|
||||
|
||||
SELECT COUNT(*) > 0 INTO vIsAnyServiceToInvoice
|
||||
FROM tmp.ticketToInvoice t
|
||||
JOIN ticketService ts ON ts.ticketFk = t.id;
|
||||
|
||||
IF (vIsAnySaleToInvoice OR vIsAnyServiceToInvoice)
|
||||
AND (vCorrectingSerial = vSerial OR NOT hasAnyNegativeBase())
|
||||
THEN
|
||||
|
||||
-- el trigger añade el siguiente Id_Factura correspondiente a la vSerial
|
||||
INSERT INTO invoiceOut(
|
||||
ref,
|
||||
serial,
|
||||
issued,
|
||||
clientFk,
|
||||
dued,
|
||||
companyFk,
|
||||
cplusInvoiceType477Fk
|
||||
)
|
||||
SELECT
|
||||
1,
|
||||
vSerial,
|
||||
vInvoiceDate,
|
||||
vClientFk,
|
||||
getDueDate(vInvoiceDate, dueDay),
|
||||
vCompanyFk,
|
||||
IF(vSerial = vCorrectingSerial,
|
||||
vCplusCorrectingInvoiceTypeFk,
|
||||
IF(vSerial = vSimplifiedSerial,
|
||||
vCplusSimplifiedInvoiceTypeFk,
|
||||
vCplusStandardInvoiceTypeFk))
|
||||
FROM client
|
||||
WHERE id = vClientFk;
|
||||
|
||||
SET vNewInvoiceId = LAST_INSERT_ID();
|
||||
|
||||
SELECT `ref`
|
||||
INTO vNewRef
|
||||
FROM invoiceOut
|
||||
WHERE id = vNewInvoiceId;
|
||||
|
||||
UPDATE ticket t
|
||||
JOIN tmp.ticketToInvoice ti ON ti.id = t.id
|
||||
SET t.refFk = vNewRef;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.updateInter;
|
||||
CREATE TEMPORARY TABLE tmp.updateInter ENGINE = MEMORY
|
||||
SELECT s.id,ti.id ticket_id,vWorker Id_Trabajador
|
||||
FROM tmp.ticketToInvoice ti
|
||||
LEFT JOIN ticketState ts ON ti.id = ts.ticket
|
||||
JOIN state s
|
||||
WHERE IFNULL(ts.alertLevel,0) < 3 and s.`code` = getAlert3State(ti.id);
|
||||
|
||||
INSERT INTO ticketTracking(stateFk,ticketFk,workerFk)
|
||||
SELECT * FROM tmp.updateInter;
|
||||
|
||||
CALL invoiceExpenceMake(vNewInvoiceId);
|
||||
CALL invoiceTaxMake(vNewInvoiceId,vTaxArea);
|
||||
|
||||
UPDATE invoiceOut io
|
||||
JOIN (
|
||||
SELECT SUM(amount) total
|
||||
FROM invoiceOutExpence
|
||||
WHERE invoiceOutFk = vNewInvoiceId
|
||||
) base
|
||||
JOIN (
|
||||
SELECT SUM(vat) total
|
||||
FROM invoiceOutTax
|
||||
WHERE invoiceOutFk = vNewInvoiceId
|
||||
) vat
|
||||
SET io.amount = base.total + vat.total
|
||||
WHERE io.id = vNewInvoiceId;
|
||||
|
||||
DROP TEMPORARY TABLE tmp.updateInter;
|
||||
|
||||
SELECT COUNT(*), id
|
||||
INTO vIsInterCompany, vInterCompanyFk
|
||||
FROM company
|
||||
WHERE clientFk = vClientFk;
|
||||
|
||||
IF (vIsInterCompany) THEN
|
||||
|
||||
INSERT INTO invoiceIn(supplierFk, supplierRef, issued, companyFk)
|
||||
SELECT vCompanyFk, vNewRef, vInvoiceDate, vInterCompanyFk;
|
||||
|
||||
SET vNewInvoiceInFk = LAST_INSERT_ID();
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.ticket;
|
||||
CREATE TEMPORARY TABLE tmp.ticket
|
||||
(KEY (ticketFk))
|
||||
ENGINE = MEMORY
|
||||
SELECT id ticketFk
|
||||
FROM tmp.ticketToInvoice;
|
||||
|
||||
CALL `ticket_getTax`('NATIONAL');
|
||||
|
||||
SET @vTaxableBaseServices := 0.00;
|
||||
SET @vTaxCodeGeneral := NULL;
|
||||
|
||||
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk)
|
||||
SELECT vNewInvoiceInFk,
|
||||
@vTaxableBaseServices,
|
||||
sub.expenceFk,
|
||||
sub.taxTypeSageFk,
|
||||
sub.transactionTypeSageFk
|
||||
FROM (
|
||||
SELECT @vTaxableBaseServices := SUM(tst.taxableBase) taxableBase,
|
||||
i.expenceFk,
|
||||
i.taxTypeSageFk,
|
||||
i.transactionTypeSageFk,
|
||||
@vTaxCodeGeneral := i.taxClassCodeFk
|
||||
FROM tmp.ticketServiceTax tst
|
||||
JOIN invoiceOutTaxConfig i ON i.taxClassCodeFk = tst.code
|
||||
WHERE i.isService
|
||||
HAVING taxableBase
|
||||
) sub;
|
||||
|
||||
INSERT INTO invoiceInTax(invoiceInFk, taxableBase, expenceFk, taxTypeSageFk, transactionTypeSageFk)
|
||||
SELECT vNewInvoiceInFk,
|
||||
SUM(tt.taxableBase) - IF(tt.code = @vTaxCodeGeneral,
|
||||
@vTaxableBaseServices, 0) taxableBase,
|
||||
i.expenceFk,
|
||||
i.taxTypeSageFk ,
|
||||
i.transactionTypeSageFk
|
||||
FROM tmp.ticketTax tt
|
||||
JOIN invoiceOutTaxConfig i ON i.taxClassCodeFk = tt.code
|
||||
WHERE !i.isService
|
||||
GROUP BY tt.pgcFk
|
||||
HAVING taxableBase
|
||||
ORDER BY tt.priority;
|
||||
|
||||
CALL invoiceInDueDay_calculate(vNewInvoiceInFk);
|
||||
|
||||
SELECT COUNT(*) INTO vIsCEESerial
|
||||
FROM invoiceOutSerial
|
||||
WHERE code = vSerial;
|
||||
|
||||
IF vIsCEESerial THEN
|
||||
|
||||
INSERT INTO invoiceInIntrastat (
|
||||
invoiceInFk,
|
||||
intrastatFk,
|
||||
amount,
|
||||
stems,
|
||||
countryFk,
|
||||
net)
|
||||
SELECT
|
||||
vNewInvoiceInFk,
|
||||
i.intrastatFk,
|
||||
SUM(CAST((s.quantity * s.price * (100 - s.discount) / 100 ) AS DECIMAL(10, 2))),
|
||||
SUM(CAST(IFNULL(i.stems, 1) * s.quantity AS DECIMAL(10, 2))),
|
||||
su.countryFk,
|
||||
CAST(SUM(IFNULL(i.stems, 1)
|
||||
* s.quantity
|
||||
* IF(ic.grams, ic.grams, IFNULL(i.weightByPiece, 0)) / 1000) AS DECIMAL(10, 2))
|
||||
FROM sale s
|
||||
JOIN ticket t ON s.ticketFk = t.id
|
||||
JOIN supplier su ON su.id = t.companyFk
|
||||
JOIN item i ON i.id = s.itemFk
|
||||
LEFT JOIN itemCost ic ON ic.itemFk = i.id AND ic.warehouseFk = t.warehouseFk
|
||||
WHERE t.refFk = vNewRef
|
||||
GROUP BY i.intrastatFk;
|
||||
|
||||
END IF;
|
||||
DROP TEMPORARY TABLE tmp.ticket;
|
||||
DROP TEMPORARY TABLE tmp.ticketAmount;
|
||||
DROP TEMPORARY TABLE tmp.ticketTax;
|
||||
DROP TEMPORARY TABLE tmp.ticketServiceTax;
|
||||
END IF;
|
||||
END IF;
|
||||
DROP TEMPORARY TABLE `tmp`.`ticketToInvoice`;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -2801,9 +2801,9 @@ INSERT INTO `vn`.`payDemDetail` (`id`, `detail`)
|
|||
VALUES
|
||||
(1, 1);
|
||||
|
||||
INSERT INTO `vn`.`workerConfig` (`id`, `businessUpdated`, `roleFk`)
|
||||
INSERT INTO `vn`.`workerConfig` (`id`, `businessUpdated`, `roleFk`, `businessTypeFk`)
|
||||
VALUES
|
||||
(1, NULL, 1);
|
||||
(1, NULL, 1, 'worker');
|
||||
|
||||
INSERT INTO `vn`.`ticketRefund`(`refundTicketFk`, `originalTicketFk`)
|
||||
VALUES
|
||||
|
|
|
@ -50,6 +50,7 @@ describe('Item Edit basic data path', () => {
|
|||
|
||||
it(`should create a new intrastat and save it`, async() => {
|
||||
await page.click($.newIntrastatButton);
|
||||
await page.waitForSelector($.intrastatForm);
|
||||
await page.fillForm($.intrastatForm, {
|
||||
id: '588420239',
|
||||
description: 'Tropical Flowers'
|
||||
|
|
|
@ -139,7 +139,7 @@ export default class CrudModel extends ModelProxy {
|
|||
filter.limit = this.page * this.limit;
|
||||
}
|
||||
|
||||
return this.sendRequest(filter, append, true);
|
||||
return this.sendRequest(filter, append);
|
||||
}
|
||||
|
||||
clear() {
|
||||
|
@ -231,12 +231,12 @@ export default class CrudModel extends ModelProxy {
|
|||
return params;
|
||||
}
|
||||
|
||||
sendRequest(filter, append, loadMore) {
|
||||
sendRequest(filter, append) {
|
||||
this.cancelRequest();
|
||||
this.canceler = this.$q.defer();
|
||||
this.isPaging = append;
|
||||
|
||||
if (!loadMore)
|
||||
if (!append && this.status != 'ready')
|
||||
this.status = 'loading';
|
||||
|
||||
let params = Object.assign(
|
||||
|
|
|
@ -150,7 +150,7 @@ describe('Component vnCrudModel', () => {
|
|||
|
||||
controller.loadMore(true);
|
||||
|
||||
expect(controller.sendRequest).toHaveBeenCalledWith({'skip': 2}, true, true);
|
||||
expect(controller.sendRequest).toHaveBeenCalledWith({'skip': 2}, true);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -7,11 +7,10 @@ export default class DataViewer {
|
|||
}
|
||||
|
||||
get status() {
|
||||
if (this.model)
|
||||
return this.model.status;
|
||||
|
||||
if (this.isLoading)
|
||||
return 'loading';
|
||||
if (this.model)
|
||||
return this.model.status;
|
||||
if (!this.data)
|
||||
return 'clear';
|
||||
if (this.data.length)
|
||||
|
|
|
@ -14,9 +14,12 @@
|
|||
order="changedModel"
|
||||
auto-load="true">
|
||||
</vn-crud-model>
|
||||
<vn-data-viewer model="model" class="vn-w-md vn-px-sm">
|
||||
<vn-data-viewer
|
||||
model="model"
|
||||
is-loading="model.isLoading"
|
||||
class="vn-w-md vn-px-sm">
|
||||
<div class="change vn-mb-sm" ng-repeat="log in $ctrl.logs">
|
||||
<div class="user-wrapper">
|
||||
<div class="left">
|
||||
<vn-avatar class="vn-mt-xs"
|
||||
ng-class="::{system: !log.user}"
|
||||
val="{{::log.user ? log.user.nickname : 'System'}}"
|
||||
|
@ -33,7 +36,7 @@
|
|||
<div class="header vn-mb-sm">
|
||||
<div
|
||||
class="date text-secondary text-caption"
|
||||
title="{{::log.creationDate | date:'dd/MM/yyyy HH:mm'}}">
|
||||
title="{{::log.creationDate | date:'dd/MM/yyyy HH:mm:ss'}}">
|
||||
{{::$ctrl.relativeDate(log.creationDate)}}
|
||||
</div>
|
||||
<span class="chip" ng-class="::$ctrl.actionsClass[log.action]" translate>
|
||||
|
|
|
@ -4,7 +4,7 @@ vn-log {
|
|||
.change {
|
||||
display: flex;
|
||||
|
||||
& > .user-wrapper {
|
||||
& > .left {
|
||||
position: relative;
|
||||
padding-right: 10px;
|
||||
|
||||
|
@ -34,7 +34,7 @@ vn-log {
|
|||
bottom: -8px;
|
||||
}
|
||||
}
|
||||
&:last-child > .user-wrapper > .line {
|
||||
&:last-child > .left > .line {
|
||||
display: none;
|
||||
}
|
||||
.detail {
|
||||
|
|
|
@ -172,4 +172,4 @@
|
|||
"Comment added to client": "Comment added to client",
|
||||
"This ticket is already a refund": "This ticket is already a refund",
|
||||
"A claim with that sale already exists": "A claim with that sale already exists"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ module.exports = Self => {
|
|||
Object.assign(myOptions, options);
|
||||
|
||||
const summaryObj = await getSummary(models.Client, clientFk, myOptions);
|
||||
|
||||
summaryObj.mana = await models.Client.getMana(clientFk, myOptions);
|
||||
summaryObj.debt = await models.Client.getDebt(clientFk, myOptions);
|
||||
summaryObj.averageInvoiced = await models.Client.getAverageInvoiced(clientFk, myOptions);
|
||||
|
@ -115,6 +114,12 @@ module.exports = Self => {
|
|||
fields: ['claimingRate', 'priceIncreasing'],
|
||||
limit: 1
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'businessType',
|
||||
scope: {
|
||||
fields: ['description']
|
||||
}
|
||||
}
|
||||
],
|
||||
where: {id: clientId}
|
||||
|
|
|
@ -64,6 +64,9 @@
|
|||
<vn-label-value label="Channel"
|
||||
value="{{$ctrl.summary.contactChannel.name}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Business type"
|
||||
value="{{$ctrl.summary.businessType.description}}">
|
||||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<h4 ng-show="$ctrl.isEmployee">
|
||||
|
|
|
@ -23,3 +23,4 @@ Latest tickets: Últimos tickets
|
|||
Rating: Clasificación
|
||||
Value from 1 to 20. The higher the better value: Valor del 1 al 20. Cuanto más alto mejor valoración
|
||||
Go to grafana: Ir a grafana
|
||||
Business type: Tipo de negocio
|
|
@ -2,8 +2,8 @@
|
|||
vn-fixed-price{
|
||||
smart-table table{
|
||||
[shrink-field]{
|
||||
width: 80px;
|
||||
max-width: 80px;
|
||||
width: 90px;
|
||||
max-width: 90px;
|
||||
}
|
||||
[shrink-field-expand]{
|
||||
width: 150px;
|
||||
|
@ -15,8 +15,8 @@ vn-fixed-price{
|
|||
align-items: center;
|
||||
text-align: center;
|
||||
vn-input-number {
|
||||
width: 90px;
|
||||
max-width: 90px;
|
||||
width: 75px;
|
||||
max-width: 75px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('editableStates', {
|
||||
description: 'Gets the editable states according the user role ',
|
||||
|
@ -19,25 +20,16 @@ module.exports = Self => {
|
|||
Self.editableStates = async(ctx, filter, options) => {
|
||||
const models = Self.app.models;
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const myOptions = {};
|
||||
const myOptions = {...(options || {})};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
let statesList = await models.State.find(filter, myOptions);
|
||||
const isProduction = await models.VnUser.hasRole(userId, 'production', myOptions);
|
||||
const isSalesPerson = await models.VnUser.hasRole(userId, 'salesPerson', myOptions);
|
||||
const isAdministrative = await models.VnUser.hasRole(userId, 'administrative', myOptions);
|
||||
|
||||
if (isProduction || isAdministrative)
|
||||
return statesList;
|
||||
if (!isProduction && !isAdministrative)
|
||||
filter = mergeFilters(filter, {where: {alertLevel: 0}});
|
||||
|
||||
if (isSalesPerson) {
|
||||
return statesList = statesList.filter(stateList =>
|
||||
stateList.alertLevel === 0 || stateList.code === 'PICKER_DESIGNED'
|
||||
);
|
||||
}
|
||||
const states = await models.State.find(filter, myOptions);
|
||||
|
||||
return statesList.filter(stateList => stateList.alertLevel === 0);
|
||||
return states;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -24,31 +24,6 @@ describe('ticket editableStates()', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it(`should return the expected states by a specific role`, async() => {
|
||||
const tx = await models.State.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const productionRole = 18;
|
||||
const ctx = {req: {accessToken: {userId: productionRole}}};
|
||||
|
||||
const editableStates = await models.State.editableStates(ctx, filter, options);
|
||||
|
||||
const deliveredState = editableStates.some(state => state.code == 'DELIVERED');
|
||||
|
||||
const pickerDesignedState = editableStates.some(state => state.code == 'PICKER_DESIGNED');
|
||||
|
||||
expect(deliveredState).toBeFalsy();
|
||||
expect(pickerDesignedState).toBeTruthy();
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it(`should return again the expected state by a specific role`, async() => {
|
||||
const tx = await models.State.beginTransaction({});
|
||||
|
||||
|
@ -70,4 +45,25 @@ describe('ticket editableStates()', () => {
|
|||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it(`should return the expected state matching with the name`, async() => {
|
||||
const tx = await models.State.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const employeeRole = 1;
|
||||
const ctx = {req: {accessToken: {userId: employeeRole}}};
|
||||
const filter = {where: {name: {like: '%Previa OK%'}}};
|
||||
|
||||
const [editableStates] = await models.State.editableStates(ctx, filter, options);
|
||||
|
||||
expect(editableStates.name).toBe('Previa OK');
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -124,6 +124,7 @@ module.exports = Self => {
|
|||
const isDeliveryBoss = await models.VnUser.hasRole(userId, 'deliveryBoss', myOptions);
|
||||
if (!isDeliveryBoss) {
|
||||
const zoneShipped = await models.Agency.getShipped(
|
||||
ctx,
|
||||
args.landed,
|
||||
args.addressFk,
|
||||
args.agencyModeFk,
|
||||
|
|
|
@ -24,7 +24,6 @@ module.exports = function(Self) {
|
|||
});
|
||||
|
||||
Self.makeInvoice = async(ctx, ticketsIds, options) => {
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const models = Self.app.models;
|
||||
const date = Date.vnNew();
|
||||
date.setHours(0, 0, 0, 0);
|
||||
|
@ -42,6 +41,7 @@ module.exports = function(Self) {
|
|||
|
||||
let serial;
|
||||
let invoiceId;
|
||||
let invoiceOut;
|
||||
try {
|
||||
const tickets = await models.Ticket.find({
|
||||
where: {
|
||||
|
@ -89,24 +89,14 @@ module.exports = function(Self) {
|
|||
|
||||
invoiceId = resultInvoice.id;
|
||||
|
||||
for (let ticket of tickets) {
|
||||
const ticketInvoice = await models.Ticket.findById(ticket.id, {
|
||||
fields: ['refFk']
|
||||
}, myOptions);
|
||||
|
||||
await models.TicketLog.create({
|
||||
originFk: ticket.id,
|
||||
userFk: userId,
|
||||
action: 'insert',
|
||||
changedModel: 'Ticket',
|
||||
changedModelId: ticket.id,
|
||||
newInstance: ticketInvoice
|
||||
}, myOptions);
|
||||
}
|
||||
|
||||
if (serial != 'R' && invoiceId)
|
||||
await Self.rawSql('CALL invoiceOutBooking(?)', [invoiceId], myOptions);
|
||||
|
||||
invoiceOut = await models.InvoiceOut.findById(invoiceId, {
|
||||
include: {
|
||||
relation: 'client'
|
||||
}
|
||||
}, myOptions);
|
||||
if (tx) await tx.commit();
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
|
@ -116,6 +106,15 @@ module.exports = function(Self) {
|
|||
if (serial != 'R' && invoiceId)
|
||||
await models.InvoiceOut.createPdf(ctx, invoiceId);
|
||||
|
||||
if (invoiceId) {
|
||||
ctx.args = {
|
||||
reference: invoiceOut.ref,
|
||||
recipientId: invoiceOut.clientFk,
|
||||
recipient: invoiceOut.client().email
|
||||
};
|
||||
await models.InvoiceOut.invoiceEmail(ctx, invoiceOut.ref);
|
||||
}
|
||||
|
||||
return {invoiceFk: invoiceId, serial: serial};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -100,7 +100,7 @@ module.exports = Self => {
|
|||
}
|
||||
|
||||
if (!args.shipped && args.landed) {
|
||||
const shippedResult = await models.Agency.getShipped(args.landed,
|
||||
const shippedResult = await models.Agency.getShipped(ctx, args.landed,
|
||||
address.id, args.agencyModeId, args.warehouseId, myOptions);
|
||||
args.shipped = (shippedResult && shippedResult.shipped) || args.landed;
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ module.exports = Self => {
|
|||
const isDeliveryBoss = await models.VnUser.hasRole(userId, 'deliveryBoss', myOptions);
|
||||
if (!isDeliveryBoss) {
|
||||
const zoneShipped = await models.Agency.getShipped(
|
||||
ctx,
|
||||
args.landed,
|
||||
args.addressId,
|
||||
args.agencyModeId,
|
||||
|
|
|
@ -6,6 +6,9 @@ describe('ticket makeInvoice()', () => {
|
|||
const ticketId = 11;
|
||||
const clientId = 1102;
|
||||
const activeCtx = {
|
||||
getLocale: () => {
|
||||
return 'en';
|
||||
},
|
||||
accessToken: {userId: userId},
|
||||
headers: {origin: 'http://localhost:5000'},
|
||||
};
|
||||
|
@ -67,6 +70,7 @@ describe('ticket makeInvoice()', () => {
|
|||
it('should invoice a ticket, then try again to fail', async() => {
|
||||
const invoiceOutModel = models.InvoiceOut;
|
||||
spyOn(invoiceOutModel, 'createPdf');
|
||||
spyOn(invoiceOutModel, 'invoiceEmail');
|
||||
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
|
@ -90,6 +94,7 @@ describe('ticket makeInvoice()', () => {
|
|||
it('should success to invoice a ticket', async() => {
|
||||
const invoiceOutModel = models.InvoiceOut;
|
||||
spyOn(invoiceOutModel, 'createPdf');
|
||||
spyOn(invoiceOutModel, 'invoiceEmail');
|
||||
|
||||
const tx = await models.Ticket.beginTransaction({});
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* eslint max-len: ["error", { "code": 130 }]*/
|
||||
/* eslint max-len: ["error", { "code": 150 }]*/
|
||||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
|
@ -139,7 +139,7 @@ module.exports = Self => {
|
|||
|
||||
if (!client) {
|
||||
const nickname = args.firstName.concat(' ', args.lastNames);
|
||||
const workerConfig = await models.WorkerConfig.findOne({fields: ['roleFk']});
|
||||
const workerConfig = await models.WorkerConfig.findOne({fields: ['roleFk', 'businessTypeFk']});
|
||||
const [randomPassword] = await models.Worker.rawSql(
|
||||
'SELECT account.passwordGenerate() as password;'
|
||||
);
|
||||
|
@ -196,7 +196,7 @@ module.exports = Self => {
|
|||
|
||||
client = await models.Client.findById(
|
||||
user.id,
|
||||
{fields: ['id', 'name', 'socialName', 'street', 'city', 'iban', 'bankEntityFk', 'defaultAddressFk', 'fi']},
|
||||
{fields: ['id', 'name', 'socialName', 'street', 'city', 'iban', 'bankEntityFk', 'defaultAddressFk', 'businessTypeFk', 'fi']},
|
||||
myOptions
|
||||
);
|
||||
|
||||
|
@ -205,6 +205,7 @@ module.exports = Self => {
|
|||
iban: args.iban,
|
||||
bankEntityFk: args.bankEntityFk,
|
||||
defaultAddressFk: address.id,
|
||||
businessTypeFk: workerConfig.businessTypeFk,
|
||||
},
|
||||
myOptions
|
||||
);
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
},
|
||||
"roleFk": {
|
||||
"type": "number"
|
||||
},
|
||||
"businessTypeFk": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"acls": [
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('getShipped', {
|
||||
Self.remoteMethodCtx('getShipped', {
|
||||
description: 'Returns the first shipped possible for params',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
|
@ -34,18 +34,22 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.getShipped = async(landed, addressFk, agencyModeFk, warehouseFk, options) => {
|
||||
Self.getShipped = async(ctx, landed, addressFk, agencyModeFk, warehouseFk, options) => {
|
||||
const myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
const stmts = [];
|
||||
const userId = ctx.req.accessToken.userId;
|
||||
const models = Self.app.models;
|
||||
const isProductionAssistant = await models.VnUser.hasRole(userId, 'productionAssi', myOptions);
|
||||
stmts.push(new ParameterizedSQL(
|
||||
`CALL vn.zone_getShipped(?, ?, ?, TRUE)`, [
|
||||
`CALL vn.zone_getShipped(?, ?, ?, ?)`, [
|
||||
landed,
|
||||
addressFk,
|
||||
agencyModeFk
|
||||
agencyModeFk,
|
||||
isProductionAssistant
|
||||
]
|
||||
));
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
const {models} = require('vn-loopback/server/server');
|
||||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('agency getShipped()', () => {
|
||||
const employeeId = 1;
|
||||
const ctx = {req: {accessToken: {userId: employeeId}}};
|
||||
|
||||
it('should return a shipment date', async() => {
|
||||
const landed = Date.vnNew();
|
||||
landed.setDate(landed.getDate() + 1);
|
||||
|
@ -12,8 +15,7 @@ describe('agency getShipped()', () => {
|
|||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const result = await models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk, options);
|
||||
const result = await models.Agency.getShipped(ctx, landed, addressFk, agencyModeFk, warehouseFk, options);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
|
||||
|
@ -37,7 +39,7 @@ describe('agency getShipped()', () => {
|
|||
try {
|
||||
const options = {transaction: tx};
|
||||
|
||||
const result = await models.Agency.getShipped(landed, addressFk, agencyModeFk, warehouseFk, options);
|
||||
const result = await models.Agency.getShipped(ctx, landed, addressFk, agencyModeFk, warehouseFk, options);
|
||||
|
||||
expect(result).toBeUndefined();
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "salix-back",
|
||||
"version": "23.18.01",
|
||||
"version": "23.22.01",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "salix-back",
|
||||
"version": "23.20.01",
|
||||
"version": "23.22.01",
|
||||
"author": "Verdnatura Levante SL",
|
||||
"description": "Salix backend",
|
||||
"license": "GPL-3.0",
|
||||
|
|
|
@ -4,13 +4,14 @@ const db = require('../../database');
|
|||
module.exports = {
|
||||
name: 'report-footer',
|
||||
async serverPrefetch() {
|
||||
this.company = await db.findOne(
|
||||
`SELECT
|
||||
ci.footnotes
|
||||
FROM companyI18n ci
|
||||
JOIN company c ON c.id = ci.companyFk
|
||||
WHERE c.code = ? AND ci.lang = (SELECT lang FROM account.user WHERE id = ?)`,
|
||||
[this.companyCode, this.recipientId]);
|
||||
this.company = await db.findOne(`
|
||||
SELECT IFNULL(ci.footnotes, cl.footnotes) as footnotes
|
||||
FROM company c
|
||||
LEFT JOIN companyL10n cl ON c.id = cl.id
|
||||
LEFT JOIN companyI18n ci ON ci.companyFk = cl.id
|
||||
AND ci.lang = (SELECT lang FROM account.user where id = ?)
|
||||
WHERE c.code = ?`,
|
||||
[this.recipientId, this.companyCode]);
|
||||
},
|
||||
|
||||
props: ['leftText', 'companyCode', 'recipientId', 'centerText']
|
||||
|
|
Loading…
Reference in New Issue