Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 6174_refactor_invoicePdfNotify
gitea/salix/pipeline/head There was a failure building this commit
Details
gitea/salix/pipeline/head There was a failure building this commit
Details
This commit is contained in:
commit
3564a77043
|
@ -35,10 +35,17 @@ module.exports = Self => {
|
||||||
let html = `<strong>Motivo</strong>:<br/>${reason}<br/>`;
|
let html = `<strong>Motivo</strong>:<br/>${reason}<br/>`;
|
||||||
html += `<strong>Usuario</strong>:<br/>${ctx.req.accessToken.userId} ${emailUser.email}<br/>`;
|
html += `<strong>Usuario</strong>:<br/>${ctx.req.accessToken.userId} ${emailUser.email}<br/>`;
|
||||||
|
|
||||||
|
delete additionalData.backError.config.headers.Authorization;
|
||||||
|
const httpRequest = JSON.parse(additionalData?.httpRequest);
|
||||||
|
|
||||||
|
if (httpRequest)
|
||||||
|
delete httpRequest.config.headers.Authorization;
|
||||||
|
additionalData.httpRequest = httpRequest;
|
||||||
|
|
||||||
for (const data in additionalData)
|
for (const data in additionalData)
|
||||||
html += `<strong>${data}</strong>:<br/>${tryParse(additionalData[data])}<br/>`;
|
html += `<strong>${data}</strong>:<br/>${tryParse(additionalData[data])}<br/>`;
|
||||||
|
|
||||||
const subjectReason = JSON.parse(additionalData?.httpRequest)?.data?.error;
|
const subjectReason = httpRequest?.data?.error;
|
||||||
smtp.send({
|
smtp.send({
|
||||||
to: `${config.app.reportEmail}, ${emailUser.email}`,
|
to: `${config.app.reportEmail}, ${emailUser.email}`,
|
||||||
subject:
|
subject:
|
||||||
|
|
|
@ -20,7 +20,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.internationalExpedition = async expeditionFk => {
|
Self.internationalExpedition = async (expeditionFk) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
|
||||||
const viaexpressConfig = await models.ViaexpressConfig.findOne({
|
const viaexpressConfig = await models.ViaexpressConfig.findOne({
|
||||||
|
|
|
@ -20,11 +20,11 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.renderer = async expeditionFk => {
|
Self.renderer = async (expeditionFk) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
|
||||||
const viaexpressConfig = await models.ViaexpressConfig.findOne({
|
const viaexpressConfig = await models.ViaexpressConfig.findOne({
|
||||||
fields: ['client', 'user', 'password', 'defaultWeight', 'deliveryType']
|
fields: ['client', 'user', 'password', 'defaultWeight', 'deliveryType', 'agencyModeFk']
|
||||||
});
|
});
|
||||||
|
|
||||||
const expedition = await models.Expedition.findOne({
|
const expedition = await models.Expedition.findOne({
|
||||||
|
@ -34,7 +34,7 @@ module.exports = Self => {
|
||||||
{
|
{
|
||||||
relation: 'ticket',
|
relation: 'ticket',
|
||||||
scope: {
|
scope: {
|
||||||
fields: ['shipped', 'addressFk', 'clientFk', 'companyFk'],
|
fields: ['shipped', 'addressFk', 'clientFk', 'companyFk', 'agencyModeFk'],
|
||||||
include: [
|
include: [
|
||||||
{
|
{
|
||||||
relation: 'client',
|
relation: 'client',
|
||||||
|
@ -102,7 +102,6 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
@ -110,13 +109,15 @@ module.exports = Self => {
|
||||||
const ticket = expedition.ticket();
|
const ticket = expedition.ticket();
|
||||||
const sender = ticket.company().client();
|
const sender = ticket.company().client();
|
||||||
const shipped = ticket.shipped.toISOString();
|
const shipped = ticket.shipped.toISOString();
|
||||||
|
const isInterdia = (ticket.agencyModeFk === viaexpressConfig.agencyModeFk)
|
||||||
const data = {
|
const data = {
|
||||||
viaexpressConfig,
|
viaexpressConfig,
|
||||||
sender,
|
sender,
|
||||||
senderAddress: sender.defaultAddress(),
|
senderAddress: sender.defaultAddress(),
|
||||||
client: ticket.client(),
|
client: ticket.client(),
|
||||||
address: ticket.address(),
|
address: ticket.address(),
|
||||||
shipped
|
shipped,
|
||||||
|
isInterdia
|
||||||
};
|
};
|
||||||
|
|
||||||
const template = fs.readFileSync(__dirname + '/template.ejs', 'utf-8');
|
const template = fs.readFileSync(__dirname + '/template.ejs', 'utf-8');
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<Asegurado>0</Asegurado>
|
<Asegurado>0</Asegurado>
|
||||||
<Imprimir>0</Imprimir>
|
<Imprimir>0</Imprimir>
|
||||||
<ConDevolucionAlbaran>0</ConDevolucionAlbaran>
|
<ConDevolucionAlbaran>0</ConDevolucionAlbaran>
|
||||||
<Intradia>0</Intradia>
|
<Intradia><%= isInterdia %></Intradia>
|
||||||
<Observaciones></Observaciones>
|
<Observaciones></Observaciones>
|
||||||
<AlbaranRemitente></AlbaranRemitente>
|
<AlbaranRemitente></AlbaranRemitente>
|
||||||
<Modo>0</Modo>
|
<Modo>0</Modo>
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
},
|
},
|
||||||
"deliveryType": {
|
"deliveryType": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"agencyModeFk": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE `vn`.`viaexpressConfig` ADD agencyModeFk int DEFAULT NULL NULL COMMENT 'Indica el agencyMode que es interdia';
|
||||||
|
ALTER TABLE `vn`.`viaexpressConfig` ADD CONSTRAINT viaexpressConfig_agencyMode_Fk FOREIGN KEY (agencyModeFK) REFERENCES vn.agencyMode(id) ON DELETE RESTRICT ON UPDATE RESTRICT;
|
|
@ -0,0 +1,4 @@
|
||||||
|
REVOKE UPDATE ON TABLE `vn`.`item` FROM `employee`;
|
||||||
|
|
||||||
|
|
||||||
|
GRANT UPDATE(id, equivalent, stems, minPrice, isToPrint, family, box, category, doPhoto, image, inkFk, intrastatFk, hasMinPrice, created, comment, typeFk, generic, producerFk, description, density, relevancy, expenseFk, isActive, subName, tag5, value5, tag6, value6, tag7, value7, tag8, value8, tag9, value9, tag10, value10, minimum, upToDown, supplyResponseFk, hasKgPrice, isFloramondo, isFragile, numberOfItemsPerCask, embalageCode, quality, stemMultiplier, itemPackingTypeFk, packingOut, genericFk, packingShelve, isLaid, lastUsed, weightByPiece, weightByPiece, editorFk, recycledPlastic, nonRecycledPlastic, minQuantity) ON TABLE vn.item TO employee;
|
|
@ -0,0 +1,12 @@
|
||||||
|
ALTER TABLE `vn`.`company` MODIFY COLUMN `supplierAccountFk` mediumint(8) unsigned DEFAULT NULL NULL COMMENT 'Cuenta por defecto para ingresos desde este pais';
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE `vn`.`supplierAccount`
|
||||||
|
ADD COLUMN `countryFk` mediumint(8) unsigned DEFAULT NULL,
|
||||||
|
ADD CONSTRAINT `fk_supplierAccount_country`
|
||||||
|
FOREIGN KEY (`countryFk`) REFERENCES `country` (`id`) ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
ALTER TABLE `vn`.`supplierAccount`
|
||||||
|
ADD UNIQUE KEY `uk_supplier_country` (`supplierFk`, `countryFk`);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE vn.productionConfig ADD itemPreviousDefaultSize int NULL COMMENT 'Altura por defecto para los artículos de previa';
|
||||||
|
UPDATE IGNORE vn.productionConfig SET itemPreviousDefaultSize = 40 WHERE id = 1;
|
|
@ -0,0 +1,9 @@
|
||||||
|
UPDATE vn.supplierAccount sa
|
||||||
|
JOIN vn.country c ON sa.countryFk = c.id AND c.code = 'FR'
|
||||||
|
SET countryFk = c.id
|
||||||
|
WHERE iban = 'FR7630003012690002801121597';
|
||||||
|
|
||||||
|
UPDATE vn.supplierAccount sa
|
||||||
|
JOIN vn.country c ON sa.countryFk = c.id AND c.code = 'PT'
|
||||||
|
SET countryFk = c.id
|
||||||
|
WHERE iban = 'PT50001000005813059150168';
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE vn.invoiceOutConfig
|
||||||
|
ADD IF NOT EXISTS refLen TINYINT UNSIGNED DEFAULT 5 NOT NULL COMMENT 'Invoice reference identifier length';
|
|
@ -4,17 +4,20 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`invoiceOut_beforeInse
|
||||||
FOR EACH ROW
|
FOR EACH ROW
|
||||||
BEGIN
|
BEGIN
|
||||||
/**
|
/**
|
||||||
|
* Generates the next reference for the invoice serial. There cannot be gaps
|
||||||
|
* between identifiers of the same serial!
|
||||||
|
*
|
||||||
* Reference format:
|
* Reference format:
|
||||||
* - 0: Serial [A-Z]
|
* {0} Invoice serial
|
||||||
* - 1: Sage company id
|
* {1} The company code
|
||||||
* - 2-3: Last two digits of issued year
|
* {2-3} Last two digits of issue year
|
||||||
* - 4-8: Autoincrement identifier
|
* {4-$} Autoincrement identifier
|
||||||
**/
|
*/
|
||||||
DECLARE vNewRef INT DEFAULT 0;
|
DECLARE vRef INT DEFAULT 0;
|
||||||
DECLARE vCompanyCode INT;
|
DECLARE vRefLen INT;
|
||||||
|
DECLARE vRefPrefix VARCHAR(255);
|
||||||
DECLARE vLastRef VARCHAR(255);
|
DECLARE vLastRef VARCHAR(255);
|
||||||
DECLARE vRefStr VARCHAR(255);
|
DECLARE vCompanyCode INT;
|
||||||
DECLARE vRefLen INT DEFAULT 5;
|
|
||||||
DECLARE vYearLen INT DEFAULT 2;
|
DECLARE vYearLen INT DEFAULT 2;
|
||||||
DECLARE vPrefixLen INT;
|
DECLARE vPrefixLen INT;
|
||||||
|
|
||||||
|
@ -23,36 +26,34 @@ BEGIN
|
||||||
WHERE id = NEW.companyFk;
|
WHERE id = NEW.companyFk;
|
||||||
|
|
||||||
IF vCompanyCode IS NULL THEN
|
IF vCompanyCode IS NULL THEN
|
||||||
CALL util.throw('sageCompanyNotDefined');
|
CALL util.throw('companyCodeNotDefined');
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
SELECT MAX(i.ref) INTO vLastRef
|
SELECT MAX(i.ref) INTO vLastRef
|
||||||
FROM invoiceOut i
|
FROM invoiceOut i
|
||||||
WHERE i.serial = NEW.serial
|
WHERE i.serial = NEW.serial
|
||||||
AND i.issued BETWEEN util.firstDayOfYear(NEW.issued) AND util.dayEnd(util.lastDayOfYear(NEW.issued))
|
AND i.issued BETWEEN util.firstDayOfYear(NEW.issued) AND util.lastDayOfYear(NEW.issued)
|
||||||
AND i.companyFk = NEW.companyFk;
|
AND i.companyFk = NEW.companyFk;
|
||||||
|
|
||||||
IF vLastRef IS NOT NULL THEN
|
IF vLastRef IS NOT NULL THEN
|
||||||
SET vPrefixLen = LENGTH(NEW.serial) + LENGTH(vCompanyCode) + vYearLen;
|
SET vPrefixLen = LENGTH(NEW.serial) + LENGTH(vCompanyCode) + vYearLen;
|
||||||
SET vRefLen = LENGTH(vLastRef) - vPrefixLen;
|
SET vRefLen = LENGTH(vLastRef) - vPrefixLen;
|
||||||
SET vRefStr = SUBSTRING(vLastRef, vPrefixLen + 1);
|
SET vRefPrefix = LEFT(vLastRef, vPrefixLen);
|
||||||
SET vNewRef = vRefStr + 1;
|
SET vRef = RIGHT(vLastRef, vRefLen);
|
||||||
|
|
||||||
IF LENGTH(vNewRef) > vRefLen THEN
|
|
||||||
CALL util.throw('refLenExceeded');
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
SET NEW.ref = CONCAT(
|
|
||||||
SUBSTRING(vLastRef, 1, vPrefixLen),
|
|
||||||
LPAD(vNewRef, LENGTH(vRefStr), '0')
|
|
||||||
);
|
|
||||||
ELSE
|
ELSE
|
||||||
SET NEW.ref = CONCAT(
|
SELECT refLen INTO vRefLen FROM invoiceOutConfig;
|
||||||
|
SET vRefPrefix = CONCAT(
|
||||||
NEW.serial,
|
NEW.serial,
|
||||||
vCompanyCode,
|
vCompanyCode,
|
||||||
RIGHT(YEAR(NEW.issued), vYearLen),
|
RIGHT(YEAR(NEW.issued), vYearLen)
|
||||||
LPAD(1, vRefLen, '0')
|
|
||||||
);
|
);
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
|
SET vRef = vRef + 1;
|
||||||
|
IF LENGTH(vRef) > vRefLen THEN
|
||||||
|
CALL util.throw('refIdLenExceeded');
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
SET NEW.ref = CONCAT(vRefPrefix, LPAD(vRef, vRefLen, '0'));
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
|
@ -600,6 +600,9 @@ INSERT INTO `vn`.`taxArea` (`code`, `claveOperacionFactura`, `CodigoTransaccion`
|
||||||
('NATIONAL', 0, 1),
|
('NATIONAL', 0, 1),
|
||||||
('WORLD', 2, 15);
|
('WORLD', 2, 15);
|
||||||
|
|
||||||
|
INSERT INTO vn.invoiceOutConfig
|
||||||
|
SET parallelism = 8;
|
||||||
|
|
||||||
INSERT INTO `vn`.`invoiceOutSerial` (`code`, `description`, `isTaxed`, `taxAreaFk`, `isCEE`, `type`)
|
INSERT INTO `vn`.`invoiceOutSerial` (`code`, `description`, `isTaxed`, `taxAreaFk`, `isCEE`, `type`)
|
||||||
VALUES
|
VALUES
|
||||||
('A', 'Global nacional', 1, 'NATIONAL', 0, 'global'),
|
('A', 'Global nacional', 1, 'NATIONAL', 0, 'global'),
|
||||||
|
@ -623,9 +626,6 @@ UPDATE `vn`.`invoiceOut` SET ref = 'T3333333' WHERE id = 3;
|
||||||
UPDATE `vn`.`invoiceOut` SET ref = 'T4444444' WHERE id = 4;
|
UPDATE `vn`.`invoiceOut` SET ref = 'T4444444' WHERE id = 4;
|
||||||
UPDATE `vn`.`invoiceOut` SET ref = 'A1111111' WHERE id = 5;
|
UPDATE `vn`.`invoiceOut` SET ref = 'A1111111' WHERE id = 5;
|
||||||
|
|
||||||
INSERT INTO vn.invoiceOutConfig
|
|
||||||
SET parallelism = 8;
|
|
||||||
|
|
||||||
INSERT INTO `vn`.`invoiceOutTax` (`invoiceOutFk`, `taxableBase`, `vat`, `pgcFk`)
|
INSERT INTO `vn`.`invoiceOutTax` (`invoiceOutFk`, `taxableBase`, `vat`, `pgcFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 895.76, 89.58, 4722000010),
|
(1, 895.76, 89.58, 4722000010),
|
||||||
|
|
|
@ -27,11 +27,8 @@ describe('Item Edit basic data path', () => {
|
||||||
|
|
||||||
it(`should edit the item basic data and confirm the item data was edited`, async() => {
|
it(`should edit the item basic data and confirm the item data was edited`, async() => {
|
||||||
const values = {
|
const values = {
|
||||||
name: 'Rose of Purity',
|
|
||||||
longName: 'RS Rose of Purity',
|
|
||||||
type: 'Anthurium',
|
type: 'Anthurium',
|
||||||
intrastat: 'Coral y materiales similares',
|
intrastat: 'Coral y materiales similares',
|
||||||
origin: 'Spain',
|
|
||||||
relevancy: 1,
|
relevancy: 1,
|
||||||
generic: 'Pallet',
|
generic: 'Pallet',
|
||||||
isActive: false,
|
isActive: false,
|
||||||
|
|
|
@ -225,7 +225,7 @@ describe('Ticket Edit sale path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show error trying to delete a ticket with a refund', async() => {
|
it('should show error trying to delete a ticket with a refund', async() => {
|
||||||
await page.accessToSearchResult('6');
|
await page.accessToSearchResult('7');
|
||||||
await page.waitToClick(selectors.ticketDescriptor.moreMenu);
|
await page.waitToClick(selectors.ticketDescriptor.moreMenu);
|
||||||
await page.waitToClick(selectors.ticketDescriptor.moreMenuDeleteTicket);
|
await page.waitToClick(selectors.ticketDescriptor.moreMenuDeleteTicket);
|
||||||
await page.waitToClick(selectors.globalItems.acceptButton);
|
await page.waitToClick(selectors.globalItems.acceptButton);
|
||||||
|
|
|
@ -18,22 +18,6 @@
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<form name="form" ng-submit="watcher.submit()" ng-cloak class="vn-w-md">
|
<form name="form" ng-submit="watcher.submit()" ng-cloak class="vn-w-md">
|
||||||
<vn-card class="vn-pa-lg">
|
<vn-card class="vn-pa-lg">
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textfield
|
|
||||||
label="Name"
|
|
||||||
ng-model="$ctrl.item.name"
|
|
||||||
vn-name="name"
|
|
||||||
rule
|
|
||||||
vn-focus>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield
|
|
||||||
label="Full name"
|
|
||||||
ng-model="$ctrl.item.longName"
|
|
||||||
vn-name="longName"
|
|
||||||
rule
|
|
||||||
info="Full name calculates based on tags 1-3. Is not recommended to change it manually">
|
|
||||||
</vn-textfield>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
url="ItemTypes"
|
url="ItemTypes"
|
||||||
|
@ -52,6 +36,34 @@
|
||||||
</div>
|
</div>
|
||||||
</tpl-item>
|
</tpl-item>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
|
<vn-textfield
|
||||||
|
label="Reference"
|
||||||
|
ng-model="$ctrl.item.comment"
|
||||||
|
vn-name="comment"
|
||||||
|
rule>
|
||||||
|
</vn-textfield>
|
||||||
|
<vn-input-number
|
||||||
|
min="0"
|
||||||
|
label="Relevancy"
|
||||||
|
ng-model="$ctrl.item.relevancy"
|
||||||
|
vn-name="relevancy"
|
||||||
|
rule>
|
||||||
|
</vn-input-number>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-input-number
|
||||||
|
min="0"
|
||||||
|
label="stems"
|
||||||
|
ng-model="$ctrl.item.stems"
|
||||||
|
vn-name="stems"
|
||||||
|
rule>
|
||||||
|
</vn-input-number>
|
||||||
|
<vn-input-number
|
||||||
|
min="0"
|
||||||
|
label="Multiplier"
|
||||||
|
ng-model="$ctrl.item.stemMultiplier"
|
||||||
|
vn-name="stemMultiplier">
|
||||||
|
</vn-input-number>
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
label="Generic"
|
label="Generic"
|
||||||
url="Items/withName"
|
url="Items/withName"
|
||||||
|
@ -105,63 +117,10 @@
|
||||||
url="Expenses"
|
url="Expenses"
|
||||||
label="Expense"
|
label="Expense"
|
||||||
ng-model="$ctrl.item.expenseFk"
|
ng-model="$ctrl.item.expenseFk"
|
||||||
vn-name="expense"
|
vn-name="expence"
|
||||||
initial-data="$ctrl.item.expense">
|
initial-data="$ctrl.item.expense">
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
|
||||||
<vn-autocomplete
|
|
||||||
data="originsData"
|
|
||||||
label="Origin"
|
|
||||||
show-field="name"
|
|
||||||
value-field="id"
|
|
||||||
ng-model="$ctrl.item.originFk"
|
|
||||||
vn-name="origin"
|
|
||||||
initial-data="$ctrl.item.origin">
|
|
||||||
</vn-autocomplete>
|
|
||||||
<vn-input-number
|
|
||||||
min="0"
|
|
||||||
label="Size"
|
|
||||||
ng-model="$ctrl.item.size"
|
|
||||||
vn-name="size"
|
|
||||||
rule>
|
|
||||||
</vn-input-number>
|
|
||||||
<vn-textfield
|
|
||||||
label="Reference"
|
|
||||||
ng-model="$ctrl.item.comment"
|
|
||||||
vn-name="comment"
|
|
||||||
rule>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-input-number
|
|
||||||
min="0"
|
|
||||||
label="Relevancy"
|
|
||||||
ng-model="$ctrl.item.relevancy"
|
|
||||||
vn-name="relevancy"
|
|
||||||
rule>
|
|
||||||
</vn-input-number>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
|
||||||
<vn-input-number
|
|
||||||
min="0"
|
|
||||||
label="stems"
|
|
||||||
ng-model="$ctrl.item.stems"
|
|
||||||
vn-name="stems"
|
|
||||||
rule>
|
|
||||||
</vn-input-number>
|
|
||||||
<vn-input-number
|
|
||||||
min="0"
|
|
||||||
label="Multiplier"
|
|
||||||
ng-model="$ctrl.item.stemMultiplier"
|
|
||||||
vn-name="stemMultiplier">
|
|
||||||
</vn-input-number>
|
|
||||||
<vn-input-number
|
|
||||||
min="1"
|
|
||||||
label="Minimum sales quantity"
|
|
||||||
ng-model="$ctrl.item.minQuantity"
|
|
||||||
vn-name="minQuantity"
|
|
||||||
rule>
|
|
||||||
</vn-input-number>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-input-number
|
<vn-input-number
|
||||||
min="0"
|
min="0"
|
||||||
|
@ -192,14 +151,6 @@
|
||||||
rule>
|
rule>
|
||||||
</vn-input-number>
|
</vn-input-number>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
|
||||||
<vn-textarea
|
|
||||||
label="Description"
|
|
||||||
ng-model="$ctrl.item.description"
|
|
||||||
vn-name="description"
|
|
||||||
rule>
|
|
||||||
</vn-textarea>
|
|
||||||
</vn-horizontal>
|
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-check
|
<vn-check
|
||||||
label="Active"
|
label="Active"
|
||||||
|
@ -224,6 +175,14 @@
|
||||||
info="This item does need a photo">
|
info="This item does need a photo">
|
||||||
</vn-check>
|
</vn-check>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textarea
|
||||||
|
label="Description"
|
||||||
|
ng-model="$ctrl.item.description"
|
||||||
|
vn-name="description"
|
||||||
|
rule>
|
||||||
|
</vn-textarea>
|
||||||
|
</vn-horizontal>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
<vn-button-bar>
|
<vn-button-bar>
|
||||||
<vn-submit
|
<vn-submit
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
{
|
{
|
||||||
"name": "RoutesMonitor",
|
"name": "RoutesMonitor",
|
||||||
"base": "Loggable",
|
"base": "VnModel",
|
||||||
|
"mixins": {
|
||||||
|
"Loggable": true
|
||||||
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "routesMonitor"
|
"table": "routesMonitor"
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
},
|
},
|
||||||
"beneficiary": {
|
"beneficiary": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"supplierFk": {
|
||||||
|
"type": "string"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
|
|
@ -14,17 +14,30 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const salesFilter = {
|
let sales;
|
||||||
where: {id: {inq: salesIds}},
|
let services;
|
||||||
include: {
|
|
||||||
relation: 'components',
|
if (salesIds && salesIds.length) {
|
||||||
scope: {
|
sales = await models.Sale.find({
|
||||||
fields: ['saleFk', 'componentFk', 'value']
|
where: {id: {inq: salesIds}},
|
||||||
|
include: {
|
||||||
|
relation: 'components',
|
||||||
|
scope: {
|
||||||
|
fields: ['saleFk', 'componentFk', 'value']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}, myOptions);
|
||||||
};
|
}
|
||||||
const sales = await models.Sale.find(salesFilter, myOptions);
|
|
||||||
let ticketsIds = [...new Set(sales.map(sale => sale.ticketFk))];
|
if (servicesIds && servicesIds.length) {
|
||||||
|
services = await models.TicketService.find({
|
||||||
|
where: {id: {inq: servicesIds}}
|
||||||
|
}, myOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
let ticketsIds = sales ?
|
||||||
|
[...new Set(sales.map(sale => sale.ticketFk))] :
|
||||||
|
[...new Set(services.map(service => service.ticketFk))];
|
||||||
|
|
||||||
const mappedTickets = new Map();
|
const mappedTickets = new Map();
|
||||||
|
|
||||||
|
@ -39,32 +52,28 @@ module.exports = Self => {
|
||||||
newTickets.push(newTicket);
|
newTickets.push(newTicket);
|
||||||
mappedTickets.set(ticketId, newTicket.id);
|
mappedTickets.set(ticketId, newTicket.id);
|
||||||
}
|
}
|
||||||
|
if (sales) {
|
||||||
|
for (const sale of sales) {
|
||||||
|
const newTicketId = mappedTickets.get(sale.ticketFk);
|
||||||
|
|
||||||
for (const sale of sales) {
|
const createdSale = await models.Sale.create({
|
||||||
const newTicketId = mappedTickets.get(sale.ticketFk);
|
ticketFk: newTicketId,
|
||||||
|
itemFk: sale.itemFk,
|
||||||
|
quantity: negative ? - sale.quantity : sale.quantity,
|
||||||
|
concept: sale.concept,
|
||||||
|
price: sale.price,
|
||||||
|
discount: sale.discount,
|
||||||
|
}, myOptions);
|
||||||
|
|
||||||
const createdSale = await models.Sale.create({
|
const components = sale.components();
|
||||||
ticketFk: newTicketId,
|
for (const component of components)
|
||||||
itemFk: sale.itemFk,
|
component.saleFk = createdSale.id;
|
||||||
quantity: negative ? - sale.quantity : sale.quantity,
|
|
||||||
concept: sale.concept,
|
|
||||||
price: sale.price,
|
|
||||||
discount: sale.discount,
|
|
||||||
}, myOptions);
|
|
||||||
|
|
||||||
const components = sale.components();
|
await models.SaleComponent.create(components, myOptions);
|
||||||
for (const component of components)
|
}
|
||||||
component.saleFk = createdSale.id;
|
|
||||||
|
|
||||||
await models.SaleComponent.create(components, myOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (servicesIds && servicesIds.length) {
|
if (services) {
|
||||||
const servicesFilter = {
|
|
||||||
where: {id: {inq: servicesIds}}
|
|
||||||
};
|
|
||||||
const services = await models.TicketService.find(servicesFilter, myOptions);
|
|
||||||
|
|
||||||
for (const service of services) {
|
for (const service of services) {
|
||||||
const newTicketId = mappedTickets.get(service.ticketFk);
|
const newTicketId = mappedTickets.get(service.ticketFk);
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ module.exports = Self => {
|
||||||
{
|
{
|
||||||
arg: 'salesIds',
|
arg: 'salesIds',
|
||||||
type: ['number'],
|
type: ['number'],
|
||||||
required: true
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'servicesIds',
|
arg: 'servicesIds',
|
||||||
|
|
|
@ -44,24 +44,7 @@ describe('Sale refund()', () => {
|
||||||
|
|
||||||
const tickets = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, options);
|
const tickets = await models.Sale.refund(ctx, salesIds, servicesIds, withWarehouse, options);
|
||||||
|
|
||||||
const refundedTicket = await models.Ticket.findOne({
|
const refundedTicket = await getTicketRefund(tickets[0].id, options);
|
||||||
where: {
|
|
||||||
id: tickets[0].id
|
|
||||||
},
|
|
||||||
include: [
|
|
||||||
{
|
|
||||||
relation: 'ticketSales',
|
|
||||||
scope: {
|
|
||||||
include: {
|
|
||||||
relation: 'components'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
relation: 'ticketServices',
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}, options);
|
|
||||||
const ticketsAfter = await models.Ticket.find({}, options);
|
const ticketsAfter = await models.Ticket.find({}, options);
|
||||||
const salesLength = refundedTicket.ticketSales().length;
|
const salesLength = refundedTicket.ticketSales().length;
|
||||||
const componentsLength = refundedTicket.ticketSales()[0].components().length;
|
const componentsLength = refundedTicket.ticketSales()[0].components().length;
|
||||||
|
@ -77,4 +60,42 @@ describe('Sale refund()', () => {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should create a ticket without sales', async() => {
|
||||||
|
const servicesIds = [4];
|
||||||
|
const tx = await models.Sale.beginTransaction({});
|
||||||
|
const options = {transaction: tx};
|
||||||
|
try {
|
||||||
|
const tickets = await models.Sale.refund(ctx, null, servicesIds, withWarehouse, options);
|
||||||
|
const refundedTicket = await getTicketRefund(tickets[0].id, options);
|
||||||
|
|
||||||
|
expect(refundedTicket).toBeDefined();
|
||||||
|
|
||||||
|
await tx.rollback();
|
||||||
|
} catch (e) {
|
||||||
|
await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function getTicketRefund(id, options) {
|
||||||
|
return models.Ticket.findOne({
|
||||||
|
where: {
|
||||||
|
id
|
||||||
|
},
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
relation: 'ticketSales',
|
||||||
|
scope: {
|
||||||
|
include: {
|
||||||
|
relation: 'components'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
relation: 'ticketServices',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}, options);
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ const UserError = require('vn-loopback/util/user-error');
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethodCtx('updateTimeEntry', {
|
Self.remoteMethodCtx('updateTimeEntry', {
|
||||||
description: 'Updates a time entry for a worker if the user role is above the worker',
|
description: 'Updates a time entry for a worker if the user role is above the worker',
|
||||||
accessType: 'READ',
|
accessType: 'WRITE',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'id',
|
arg: 'id',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
|
|
|
@ -45,4 +45,4 @@
|
||||||
</attachment>
|
</attachment>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</email-body>
|
</email-body>
|
||||||
|
|
|
@ -1,14 +1,33 @@
|
||||||
const Component = require(`vn-print/core/component`);
|
const Component = require(`vn-print/core/component`);
|
||||||
const emailBody = new Component('email-body');
|
const emailBody = new Component('email-body');
|
||||||
const attachment = new Component('attachment');
|
const attachment = new Component('attachment');
|
||||||
|
const db = require('../../../core/database');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'letter-debtor-nd',
|
name: 'letter-debtor-nd',
|
||||||
async serverPrefetch() {
|
async serverPrefetch() {
|
||||||
this.debtor = await this.fetchDebtor(this.id, this.companyId);
|
this.debtor = await db.findOne(`
|
||||||
|
SELECT sa.id,
|
||||||
if (!this.debtor)
|
sa.iban,
|
||||||
throw new Error('Something went wrong');
|
be.name bankName,
|
||||||
|
sa.countryFk,
|
||||||
|
c.countryFk
|
||||||
|
FROM supplierAccount sa
|
||||||
|
JOIN bankEntity be ON sa.bankEntityFk = be.id
|
||||||
|
LEFT JOIN company co ON co.supplierAccountFk = sa.id
|
||||||
|
JOIN client c ON c.countryFk = sa.countryFk
|
||||||
|
WHERE c.id = ?;
|
||||||
|
`, [this.id]);
|
||||||
|
if (!this.debtor) {
|
||||||
|
this.debtor = await db.findOne(`
|
||||||
|
SELECT sa.iban,
|
||||||
|
be.name bankName
|
||||||
|
FROM supplierAccount sa
|
||||||
|
JOIN bankEntity be ON sa.bankEntityFk = be.id
|
||||||
|
JOIN company co ON co.supplierAccountFk = sa.id
|
||||||
|
WHERE co.id = ?;
|
||||||
|
`, [this.companyId]);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
subject: Reminder of Outstanding Balance Notice
|
||||||
|
title: Reminder Notice
|
||||||
|
sections:
|
||||||
|
introduction:
|
||||||
|
title: Dear Customer
|
||||||
|
description: We are writing to you once again to inform you that your debt with our company remains unpaid, as you can verify in the attached statement.
|
||||||
|
terms: Since the agreed payment deadlines have significantly passed, there should be no further delay in settling the outstanding amount.
|
||||||
|
payMethod:
|
||||||
|
description: To do so, you have the following payment options
|
||||||
|
options:
|
||||||
|
- Online payment through our website.
|
||||||
|
- Deposit or transfer to the account number provided at the bottom of this letter, indicating your customer number.
|
||||||
|
legalAction:
|
||||||
|
description: If this payment reminder is not heeded, we will be compelled to initiate the necessary legal actions, which may include
|
||||||
|
options:
|
||||||
|
- Inclusion in negative credit and financial solvency records.
|
||||||
|
- Legal proceedings.
|
||||||
|
- Debt assignment to a debt collection agency.
|
||||||
|
contactPhone: For inquiries, you can reach us at <strong>96 324 21 00</strong>.
|
||||||
|
conclusion: We look forward to hearing from you. <br/> Thank you for your attention.
|
||||||
|
transferAccount: Bank Transfer Details
|
|
@ -0,0 +1,26 @@
|
||||||
|
subject: Réitération de l'avis de solde débiteur
|
||||||
|
title: Avis réitéré
|
||||||
|
sections:
|
||||||
|
introduction:
|
||||||
|
title: Cher client
|
||||||
|
description: Nous vous écrivons à nouveau pour vous informer qu'il est toujours en attente
|
||||||
|
votre dette envers notre société, comme vous pouvez le voir dans le relevé ci-joint.
|
||||||
|
terms: Étant donné que les délais de paiement convenus sont largement dépassés, il n'est pas approprié
|
||||||
|
retard plus important dans le règlement du montant dû.
|
||||||
|
payMethod:
|
||||||
|
description: Pour cela, vous disposez des modes de paiement suivants
|
||||||
|
options:
|
||||||
|
- Paiement en ligne depuis notre site internet.
|
||||||
|
- Revenu ou virement sur le numéro de compte que nous détaillons en bas de ce courrier,
|
||||||
|
indiquant le numéro de client.
|
||||||
|
legalAction:
|
||||||
|
description: Si cette obligation de paiement n'est pas remplie, nous serons contraints de
|
||||||
|
d'engager les actions judiciaires qui se déroulent, parmi lesquelles
|
||||||
|
options:
|
||||||
|
- Inclusion dans les dossiers négatifs sur la solvabilité financière et le crédit.
|
||||||
|
- Réclamation judiciaire.
|
||||||
|
- Cession de créance à une société de gestion de recouvrement.
|
||||||
|
contactPhone: Pour toute demande, vous pouvez nous contacter au <strong>96
|
||||||
|
324 21 00</strong>.
|
||||||
|
conclusion: En attente de vos nouvelles. <br/> Merci pour ton attention.
|
||||||
|
transferAccount: Données pour virement bancaire
|
|
@ -0,0 +1,26 @@
|
||||||
|
subject: Reiteração de aviso de saldo devedor
|
||||||
|
title: Aviso reiterado
|
||||||
|
sections:
|
||||||
|
introduction:
|
||||||
|
title: Estimado cliente
|
||||||
|
description: Estamos escrevendo para você novamente para informar que ainda está pendente
|
||||||
|
sua dívida para com nossa empresa, conforme demonstrativo anexo.
|
||||||
|
terms: Dado que os prazos de pagamento acordados são largamente excedidos, não é adequado
|
||||||
|
maior atraso na liquidação do valor devido.
|
||||||
|
payMethod:
|
||||||
|
description: Para isso você tem as seguintes formas de pagamento
|
||||||
|
options:
|
||||||
|
- Pagamento online em nosso site.
|
||||||
|
- Renda ou transferência para o número da conta que detalhamos no final desta carta,
|
||||||
|
indicando o número do cliente.
|
||||||
|
legalAction:
|
||||||
|
description: Se esta obrigação de pagamento não for cumprida, seremos obrigados a
|
||||||
|
para iniciar as ações legais que procedem, entre as quais estão
|
||||||
|
options:
|
||||||
|
- Inclusão em processos negativos de solvência financeira e de crédito.
|
||||||
|
- Reivindicação judicial.
|
||||||
|
- Cessão de dívida a uma empresa de gestão de cobranças.
|
||||||
|
contactPhone: Para consultas, você pode entrar em contato conosco em <strong>96
|
||||||
|
324 21 00</strong>.
|
||||||
|
conclusion: Aguardando suas notícias. <br/> Agradecimentos para sua atenção.
|
||||||
|
transferAccount: Dados para transferência bancária
|
|
@ -1,10 +1,9 @@
|
||||||
SELECT
|
SELECT c.dueDay,
|
||||||
c.dueDay,
|
sa.iban,
|
||||||
c.iban,
|
be.name bankName
|
||||||
sa.iban,
|
FROM client c
|
||||||
be.name AS bankName
|
JOIN supplierAccount sa ON sa.id = cny.supplierAccountFk
|
||||||
FROM client c
|
JOIN bankEntity be ON be.id = sa.bankEntityFk
|
||||||
JOIN company AS cny
|
JOIN company cny
|
||||||
JOIN supplierAccount AS sa ON sa.id = cny.supplierAccountFk
|
WHERE c.id = ?
|
||||||
JOIN bankEntity be ON be.id = sa.bankEntityFk
|
AND cny.id = ?
|
||||||
WHERE c.id = ? AND cny.id = ?
|
|
||||||
|
|
|
@ -28,4 +28,4 @@
|
||||||
</attachment>
|
</attachment>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</email-body>
|
</email-body>
|
||||||
|
|
|
@ -1,14 +1,33 @@
|
||||||
const Component = require(`vn-print/core/component`);
|
const Component = require(`vn-print/core/component`);
|
||||||
const emailBody = new Component('email-body');
|
const emailBody = new Component('email-body');
|
||||||
const attachment = new Component('attachment');
|
const attachment = new Component('attachment');
|
||||||
|
const db = require('../../../core/database');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'letter-debtor-st',
|
name: 'letter-debtor-st',
|
||||||
async serverPrefetch() {
|
async serverPrefetch() {
|
||||||
this.debtor = await this.fetchDebtor(this.id, this.companyId);
|
this.debtor = await db.findOne(`
|
||||||
|
SELECT sa.id,
|
||||||
if (!this.debtor)
|
sa.iban,
|
||||||
throw new Error('Something went wrong');
|
be.name bankName,
|
||||||
|
sa.countryFk,
|
||||||
|
c.countryFk
|
||||||
|
FROM supplierAccount sa
|
||||||
|
JOIN bankEntity be ON sa.bankEntityFk = be.id
|
||||||
|
LEFT JOIN company co ON co.supplierAccountFk = sa.id
|
||||||
|
JOIN client c ON c.countryFk = sa.countryFk
|
||||||
|
WHERE c.id = ?;
|
||||||
|
`, [this.id]);
|
||||||
|
if (!this.debtor) {
|
||||||
|
this.debtor = await db.findOne(`
|
||||||
|
SELECT sa.iban,
|
||||||
|
be.name bankName
|
||||||
|
FROM supplierAccount sa
|
||||||
|
JOIN bankEntity be ON sa.bankEntityFk = be.id
|
||||||
|
JOIN company co ON co.supplierAccountFk = sa.id
|
||||||
|
WHERE co.id = ?;
|
||||||
|
`, [this.companyId]);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
subject: Initial Notice for Outstanding Balance
|
||||||
|
title: Initial Notice for Outstanding Balance
|
||||||
|
sections:
|
||||||
|
introduction:
|
||||||
|
title: Dear Customer
|
||||||
|
description: Through this letter, we would like to inform you that, according to our accounting records, your account has an outstanding balance that needs to be settled.
|
||||||
|
checkExtract: We kindly request you to verify that the attached statement corresponds to the information you have. Our administration department will be happy to clarify any questions you may have and provide any documents you may request.
|
||||||
|
checkValidData: If, upon reviewing the provided information, everything appears to be accurate, we kindly ask you to proceed with rectifying your situation.
|
||||||
|
payMethod: If you prefer not to visit our offices in person, you can make the payment through a bank transfer to the account listed at the bottom of this communication, indicating your customer number. Alternatively, you can make the payment online through our website.
|
||||||
|
conclusion: We sincerely appreciate your kind cooperation.
|
||||||
|
transferAccount: Bank Transfer Details
|
|
@ -1,10 +1,9 @@
|
||||||
SELECT
|
SELECT c.dueDay,
|
||||||
c.dueDay,
|
sa.iban,
|
||||||
c.iban,
|
be.name bankName
|
||||||
sa.iban,
|
FROM client c
|
||||||
be.name AS bankName
|
JOIN supplierAccount sa ON sa.id = cny.supplierAccountFk
|
||||||
FROM client c
|
JOIN bankEntity be ON be.id = sa.bankEntityFk
|
||||||
JOIN company AS cny
|
JOIN company cny
|
||||||
JOIN supplierAccount AS sa ON sa.id = cny.supplierAccountFk
|
WHERE c.id = ?
|
||||||
JOIN bankEntity be ON be.id = sa.bankEntityFk
|
AND cny.id = ?
|
||||||
WHERE c.id = ? AND cny.id = ?
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<td id="outline" class="ellipsize">{{labelData.workerCode || '---'}}</td>
|
<td id="outline" class="ellipsize">{{labelData.workerCode || '---'}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td id="outline" class="ellipsize">{{labelCount || labelData.labelCount || 0}}</td>
|
<td id="outline" class="ellipsize">{{labelData.labelCount || 0}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td id="outline" class="ellipsize">{{labelData.code == 'V' ? (labelData.size || 0) + 'cm' : (labelData.volume || 0) + 'm³'}}</td>
|
<td id="outline" class="ellipsize">{{labelData.code == 'V' ? (labelData.size || 0) + 'cm' : (labelData.volume || 0) + 'm³'}}</td>
|
||||||
|
|
|
@ -18,9 +18,9 @@ module.exports = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async serverPrefetch() {
|
async serverPrefetch() {
|
||||||
|
await this.rawSql('SET @hasPrevia := 0');
|
||||||
let ticketIds;
|
let ticketIds;
|
||||||
const res = await this.rawSqlFromDef('tickets', [this.id]);
|
const res = await this.rawSqlFromDef('tickets', [this.id]);
|
||||||
|
|
||||||
if (res.length) {
|
if (res.length) {
|
||||||
ticketIds = [];
|
ticketIds = [];
|
||||||
for (const row of res)
|
for (const row of res)
|
||||||
|
|
|
@ -7,14 +7,16 @@ SELECT c.itemPackingTypeFk code,
|
||||||
cc.code color,
|
cc.code color,
|
||||||
t.clientFk,
|
t.clientFk,
|
||||||
CAST(SUM(sv.volume) AS DECIMAL(5, 2)) volume,
|
CAST(SUM(sv.volume) AS DECIMAL(5, 2)) volume,
|
||||||
MAX(i.`size`) `size`,
|
MAX(
|
||||||
|
IF(sgd.id, IFNULL(pc.itemPreviousDefaultSize, i.`size`), i.`size`)
|
||||||
|
) `size`,
|
||||||
w.code workerCode,
|
w.code workerCode,
|
||||||
TIME_FORMAT(t.shipped, '%H:%i') shippedHour,
|
TIME_FORMAT(t.shipped, '%H:%i') shippedHour,
|
||||||
TIME_FORMAT(zo.`hour`, '%H:%i') zoneHour,
|
TIME_FORMAT(zo.`hour`, '%H:%i') zoneHour,
|
||||||
DATE_FORMAT(t.shipped, '%d/%m/%y') shipped,
|
DATE_FORMAT(t.shipped, '%d/%m/%y') shipped,
|
||||||
tt.labelCount,
|
tt.labelCount,
|
||||||
t.nickName,
|
t.nickName,
|
||||||
COUNT(*) lineCount,
|
SUM(IF(sgd.id, IF(@hasPrevia, 0, @hasPrevia := 1), 1)) lineCount,
|
||||||
rm.routeFk
|
rm.routeFk
|
||||||
FROM vn.ticket t
|
FROM vn.ticket t
|
||||||
JOIN vn.ticketCollection tc ON tc.ticketFk = t.id
|
JOIN vn.ticketCollection tc ON tc.ticketFk = t.id
|
||||||
|
@ -23,7 +25,7 @@ SELECT c.itemPackingTypeFk code,
|
||||||
AND cc.wagon = tc.wagon
|
AND cc.wagon = tc.wagon
|
||||||
AND cc.trainFk = c.trainFk
|
AND cc.trainFk = c.trainFk
|
||||||
JOIN vn.sale s ON s.ticketFk = t.id
|
JOIN vn.sale s ON s.ticketFk = t.id
|
||||||
LEFT JOIN vn.saleVolume sv ON sv.saleFk = s.id
|
LEFT JOIN vn.saleVolume sv ON sv.saleFk = s.id
|
||||||
JOIN vn.item i ON i.id = s.itemFk
|
JOIN vn.item i ON i.id = s.itemFk
|
||||||
JOIN vn.itemType it ON it.id = i.typeFk
|
JOIN vn.itemType it ON it.id = i.typeFk
|
||||||
JOIN vn.itemCategory ic ON ic.id = it.categoryFk
|
JOIN vn.itemCategory ic ON ic.id = it.categoryFk
|
||||||
|
@ -32,7 +34,9 @@ SELECT c.itemPackingTypeFk code,
|
||||||
LEFT JOIN vn.ticketTrolley tt ON tt.ticket = t.id
|
LEFT JOIN vn.ticketTrolley tt ON tt.ticket = t.id
|
||||||
LEFT JOIN vn.`zone` zo ON t.zoneFk = zo.id
|
LEFT JOIN vn.`zone` zo ON t.zoneFk = zo.id
|
||||||
LEFT JOIN vn.routesMonitor rm ON rm.routeFk = t.routeFk
|
LEFT JOIN vn.routesMonitor rm ON rm.routeFk = t.routeFk
|
||||||
LEFT JOIN vn.expeditionTruck et ON et.id = rm.expeditionTruckFk
|
LEFT JOIN vn.expeditionTruck et ON et.id = rm.expeditionTruckFk
|
||||||
|
LEFT JOIN vn.saleGroupDetail sgd ON sgd.saleFk = s.id
|
||||||
|
JOIN vn.productionConfig pc
|
||||||
WHERE t.id IN (?)
|
WHERE t.id IN (?)
|
||||||
GROUP BY t.id
|
GROUP BY t.id
|
||||||
ORDER BY cc.`code`;
|
ORDER BY cc.`code`
|
|
@ -45,4 +45,4 @@ instructions:
|
||||||
title: Instrucciones
|
title: Instrucciones
|
||||||
accountFields: Rellenar los campos relativos a la cuenta bancaria
|
accountFields: Rellenar los campos relativos a la cuenta bancaria
|
||||||
signDocument: Firmar y sellar el documento. Para que tenga validez, en el sello debe aparecer el CIF/NIF. De no ser así, deberá acompañarse la solicitud de un certificado de titularidad de la cuenta.
|
signDocument: Firmar y sellar el documento. Para que tenga validez, en el sello debe aparecer el CIF/NIF. De no ser así, deberá acompañarse la solicitud de un certificado de titularidad de la cuenta.
|
||||||
thanks: ¡Gracias por su colaboración!
|
thanks: ¡Gracias por su colaboración!
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
reportName: direct-debit
|
reportName: direct-debit
|
||||||
title: Direct Debit
|
title: Direct Debit
|
||||||
description: En signant ce formulaire de mandat, vous autorisez VERDNATURA LEVANTE SL
|
description: En signant ce formulaire de mandat, vous autorisez VERDNATURA LEVANTE SL
|
||||||
à envoyer des instructions à votre banque pour débiter votre compte, et (B) votre banque
|
à envoyer des instructions à votre banque pour débiter votre compte, et (B) votre banque
|
||||||
à débiter votre compte conformément aux instructions de VERDNATURA LEVANTE SL.
|
à débiter votre compte conformément aux instructions de VERDNATURA LEVANTE SL.
|
||||||
Vous bénéficiez d’un droit au remboursement par votre banque selon les conditions décrites
|
Vous bénéficiez d’un droit au remboursement par votre banque selon les conditions décrites
|
||||||
dans la convention que vous avez passée avec elle. Toute demande de remboursement doit être
|
dans la convention que vous avez passée avec elle. Toute demande de remboursement doit être
|
||||||
présentée dans les 8 semaines suivant la date de débit de votre compte.
|
présentée dans les 8 semaines suivant la date de débit de votre compte.
|
||||||
Votre banque peut vous renseigner au sujet de vos droits relatifs à ce mandat.
|
Votre banque peut vous renseigner au sujet de vos droits relatifs à ce mandat.
|
||||||
documentCopy: Veuillez dater, signer et retourner ce document à votre banque.
|
documentCopy: Veuillez dater, signer et retourner ce document à votre banque.
|
||||||
mandatoryFields: TOUS LES CHAMPS DOIVENT ÊTRE REINSEGNÉS IMPÉRATIVEMENT.
|
mandatoryFields: TOUS LES CHAMPS DOIVENT ÊTRE REINSEGNÉS IMPÉRATIVEMENT.
|
||||||
|
@ -42,4 +42,4 @@ instructions:
|
||||||
title: instructions
|
title: instructions
|
||||||
accountFields: Remplissez les champs relatifs au compte bancaire
|
accountFields: Remplissez les champs relatifs au compte bancaire
|
||||||
signDocument: Signez et scellez le document. Pour être valide, le CIF / NIF doit apparaître sur le cachet. Sinon, la demande de certificat de propriété du compte doit être jointe.
|
signDocument: Signez et scellez le document. Pour être valide, le CIF / NIF doit apparaître sur le cachet. Sinon, la demande de certificat de propriété du compte doit être jointe.
|
||||||
thanks: Merci de votre collaboration!
|
thanks: Merci de votre collaboration!
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{$t('supplier.identifier')}}</td>
|
<td>{{$t('supplier.identifier')}}</td>
|
||||||
<th>
|
<th>
|
||||||
<div>ES89000B97367486</div>
|
<div>{{supplier.iban}}</div>
|
||||||
<div>B97367486-000</div>
|
<div>{{supplier.nif}}</div>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const vnReport = require('../../../core/mixins/vn-report.js');
|
const vnReport = require('../../../core/mixins/vn-report.js');
|
||||||
|
const db = require('../../../core/database');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'sepa-core',
|
name: 'sepa-core',
|
||||||
|
@ -18,5 +19,16 @@ module.exports = {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getSupplierCif() {
|
||||||
|
return db.findOne(`
|
||||||
|
SELECT sa.iban, s.nif
|
||||||
|
FROM supplierAccount sa
|
||||||
|
JOIN company co ON co.supplierAccountFk = sa.id
|
||||||
|
JOIN supplier s ON sa.supplierFk = s.id
|
||||||
|
WHERE co.id = ?`) [this.companyId];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,17 +1,27 @@
|
||||||
SELECT
|
SELECT
|
||||||
m.code mandateCode,
|
m.code mandateCode,
|
||||||
s.name,
|
s.name,
|
||||||
s.street,
|
s.street,
|
||||||
sc.country,
|
sc.country,
|
||||||
s.postCode,
|
s.postCode,
|
||||||
s.city,
|
s.city,
|
||||||
sp.name province
|
sp.name province,
|
||||||
FROM client c
|
s.nif,
|
||||||
LEFT JOIN mandate m ON m.clientFk = c.id
|
sa.iban,
|
||||||
AND m.companyFk = ? AND m.finished IS NULL
|
sa.supplierFk,
|
||||||
|
be.name bankName
|
||||||
|
FROM
|
||||||
|
client c
|
||||||
|
LEFT JOIN mandate m ON m.clientFk = c.id AND m.companyFk = ? AND m.finished IS NULL
|
||||||
LEFT JOIN supplier s ON s.id = m.companyFk
|
LEFT JOIN supplier s ON s.id = m.companyFk
|
||||||
LEFT JOIN country sc ON sc.id = s.countryFk
|
LEFT JOIN country sc ON sc.id = s.countryFk
|
||||||
LEFT JOIN province sp ON sp.id = s.provinceFk
|
LEFT JOIN province sp ON sp.id = s.provinceFk
|
||||||
LEFT JOIN province p ON p.id = c.provinceFk
|
LEFT JOIN province p ON p.id = c.provinceFk
|
||||||
WHERE (m.companyFk = ? OR m.companyFk IS NULL) AND c.id = ?
|
LEFT JOIN supplierAccount sa ON sa.supplierFk = s.id
|
||||||
ORDER BY m.created DESC LIMIT 1
|
LEFT JOIN bankEntity be ON sa.bankEntityFk = be.id
|
||||||
|
WHERE
|
||||||
|
(m.companyFk = ? OR m.companyFk IS NULL)
|
||||||
|
AND (c.id = ? OR (c.id IS NULL AND c.countryFk = sa.countryFk))
|
||||||
|
ORDER BY
|
||||||
|
m.created DESC
|
||||||
|
LIMIT 1;
|
||||||
|
|
Loading…
Reference in New Issue