6745-2404_testToMaster #1950

Merged
alexm merged 191 commits from 6745-2404_testToMaster into master 2024-01-25 07:39:13 +00:00
40 changed files with 306 additions and 196 deletions
Showing only changes of commit 0f6718850f - Show all commits

View File

@ -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({

View File

@ -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');

View File

@ -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>

View File

@ -29,6 +29,9 @@
}, },
"deliveryType": { "deliveryType": {
"type": "string" "type": "string"
},
"agencyModeFk": {
"type": "number"
} }
} }
} }

View File

@ -258,18 +258,20 @@ module.exports = function(Self) {
class Mailer { class Mailer {
async send(verifyOptions, cb) { async send(verifyOptions, cb) {
try {
const url = new URL(verifyOptions.verifyHref); const url = new URL(verifyOptions.verifyHref);
if (process.env.NODE_ENV) url.port = ''; if (process.env.NODE_ENV) url.port = '';
const params = { const email = new Email('email-verify', {
url: url.href, url: url.href,
recipient: verifyOptions.to recipient: verifyOptions.to
}; });
await email.send();
const email = new Email('email-verify', params);
email.send();
cb(null, verifyOptions.to); cb(null, verifyOptions.to);
} catch (err) {
cb(err);
}
} }
} }

View File

@ -1 +0,0 @@
DELETE FROM `account`.`signInLog` where owner <> FALSE

View File

@ -0,0 +1,2 @@
DELETE FROM `account`.`signInLog` where owner <> FALSE;

View File

View File

@ -0,0 +1,14 @@
DELETE FROM salix.ACL
WHERE model = 'WorkerTimeControl'
AND property IN ('*','addTime');
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
VALUES
('WorkerTimeControl', 'addTimeEntry', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
('WorkerTimeControl', 'deleteTimeEntry', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
('WorkerTimeControl', 'updateTimeEntry', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
('WorkerTimeControl', 'sendMail', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
('WorkerTimeControl', 'updateWorkerTimeControlMail', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
('WorkerTimeControl', 'weeklyHourRecordEmail', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
('WorkerTimeControl', 'getMailStates', 'READ', 'ALLOW', 'ROLE', 'employee'),
('WorkerTimeControl', 'resendWeeklyHourEmail', 'WRITE', 'ALLOW', 'ROLE', 'employee');

View File

View File

@ -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;

View File

@ -735,7 +735,7 @@ export default {
}, },
createStateView: { createStateView: {
state: 'vn-autocomplete[ng-model="$ctrl.stateFk"]', state: 'vn-autocomplete[ng-model="$ctrl.stateFk"]',
worker: 'vn-worker-autocomplete[ng-model="$ctrl.workerFk"]', worker: 'vn-worker-autocomplete[ng-model="$ctrl.userFk"]',
saveStateButton: `button[type=submit]` saveStateButton: `button[type=submit]`
}, },
claimsIndex: { claimsIndex: {

View File

@ -203,5 +203,6 @@
"keepPrice": "keepPrice", "keepPrice": "keepPrice",
"Cannot past travels with entries": "Cannot past travels with entries", "Cannot past travels with entries": "Cannot past travels with entries",
"It was not able to remove the next expeditions:": "It was not able to remove the next expeditions: {{expeditions}}", "It was not able to remove the next expeditions:": "It was not able to remove the next expeditions: {{expeditions}}",
"Incorrect pin": "Incorrect pin." "Incorrect pin": "Incorrect pin.",
"The notification subscription of this worker cant be modified": "The notification subscription of this worker cant be modified"
} }

View File

@ -7,7 +7,8 @@ const execFile = require('child_process').execFile;
* https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/useraccountcontrol-manipulate-account-properties * https://docs.microsoft.com/en-us/troubleshoot/windows-server/identity/useraccountcontrol-manipulate-account-properties
*/ */
const UserAccountControlFlags = { const UserAccountControlFlags = {
ACCOUNTDISABLE: 2 ACCOUNTDISABLE: 0x2,
DONT_EXPIRE_PASSWD: 0x10000
}; };
module.exports = Self => { module.exports = Self => {
@ -118,7 +119,8 @@ module.exports = Self => {
} }
entry = { entry = {
userAccountControl: sambaUser.userAccountControl userAccountControl: (sambaUser.userAccountControl
| UserAccountControlFlags.DONT_EXPIRE_PASSWD)
& ~UserAccountControlFlags.ACCOUNTDISABLE, & ~UserAccountControlFlags.ACCOUNTDISABLE,
uidNumber: info.uidNumber, uidNumber: info.uidNumber,
accountExpires: 0, accountExpires: 0,

View File

@ -17,18 +17,3 @@ columns:
agencyModeFk: agency agencyModeFk: agency
routeFk: route routeFk: route
zoneFk: zone zoneFk: zone
name: name
beachFk: beach
ticketPacked: tickets packed
ticketFree: tickets free
ticketProduction: tickets production
packages: packages
note: note
dated: dated
dockFk: dock
priority: priority
etd: etd
expeditionTruckFk: truck
m3boxes: m3 boxes
bufferFk: buffer
isPickingAllowed: is picking allowed

View File

@ -17,18 +17,3 @@ columns:
agencyModeFk: agencia agencyModeFk: agencia
routeFk: ruta routeFk: ruta
zoneFk: zona zoneFk: zona
name: nombre
beachFk: playa
ticketPacked: tickets encajados
ticketFree: tickets libres
ticketProduction: tickets producción
packages: paquetes
note: nota
dated: fecha
dockFk: muelle
priority: prioridad
etd: etd
expeditionTruckFk: camión
m3boxes: m3 cajas
bufferFk: buffer
isPickingAllowed: está permitido recoger

View File

@ -0,0 +1,19 @@
name: routesMonitor
columns:
routeFk: route
name: name
beachFk: beach
ticketPacked: tickets packed
ticketFree: tickets free
ticketProduction: tickets production
packages: packages
note: note
dated: dated
dockFk: dock
m3: m3
priority: priority
etd: etd
expeditionTruckFk: truck
m3boxes: m3 boxes
bufferFk: buffer
isPickingAllowed: is picking allowed

View File

@ -0,0 +1,19 @@
name: monitorRutas
columns:
routeFk: ruta
name: nombre
beachFk: playa
ticketPacked: tickets encajados
ticketFree: tickets libres
ticketProduction: tickets producción
packages: paquetes
note: nota
dated: fecha
dockFk: muelle
m3: m3
priority: prioridad
etd: etd
expeditionTruckFk: camión
m3boxes: m3 cajas
bufferFk: buffer
isPickingAllowed: está permitido recoger

View File

@ -22,5 +22,8 @@
}, },
"Vehicle": { "Vehicle": {
"dataSource": "vn" "dataSource": "vn"
},
"RoutesMonitor": {
"dataSource": "vn"
} }
} }

View File

@ -0,0 +1,61 @@
{
"name": "RoutesMonitor",
"base": "Loggable",
"options": {
"mysql": {
"table": "routesMonitor"
}
},
"properties": {
"routeFk": {
"type": "number",
"id": true,
"description": "Identifier"
},
"name": {
"type": "string"
},
"beachFk": {
"type": "number"
},
"ticketPacked": {
"type": "number"
},
"ticketFree": {
"type": "number"
},
"ticketProduction": {
"type": "number"
},
"packages": {
"type": "number"
},
"note": {
"type": "string"
},
"dated": {
"type": "date"
},
"dockFk": {
"type": "number"
},
"m3": {
"type": "number"
},
"priority": {
"type": "number"
},
"expeditionTruckFk": {
"type": "number"
},
"m3boxes": {
"type": "number"
},
"bufferFk": {
"type": "number"
},
"isPickingAllowed": {
"type": "boolean"
}
}
}

View File

@ -14,7 +14,11 @@ module.exports = Self => {
} }
try { try {
const salesFilter = { let sales;
let services;
if (salesIds && salesIds.length) {
sales = await models.Sale.find({
where: {id: {inq: salesIds}}, where: {id: {inq: salesIds}},
include: { include: {
relation: 'components', relation: 'components',
@ -22,9 +26,18 @@ module.exports = Self => {
fields: ['saleFk', 'componentFk', 'value'] 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();
@ -41,7 +54,7 @@ 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) { for (const sale of sales) {
const newTicketId = mappedTickets.get(sale.ticketFk); const newTicketId = mappedTickets.get(sale.ticketFk);
@ -60,13 +73,9 @@ module.exports = Self => {
await models.SaleComponent.create(components, myOptions); 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);

View File

@ -6,7 +6,6 @@ module.exports = Self => {
{ {
arg: 'salesIds', arg: 'salesIds',
type: ['number'], type: ['number'],
required: true
}, },
{ {
arg: 'servicesIds', arg: 'servicesIds',

View File

@ -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);
}

View File

@ -49,7 +49,7 @@ module.exports = Self => {
for (const id of ticketIds) { for (const id of ticketIds) {
const promise = await models.Ticket.state(ctx, { const promise = await models.Ticket.state(ctx, {
stateFk: state.id, stateFk: state.id,
workerFk: worker.id, userFk: worker.id,
ticketFk: id ticketFk: id
}, myOptions); }, myOptions);
promises.push(promise); promises.push(promise);

View File

@ -21,7 +21,7 @@
</vn-autocomplete> </vn-autocomplete>
<vn-worker-autocomplete <vn-worker-autocomplete
vn-one vn-one
ng-model="$ctrl.workerFk"> ng-model="$ctrl.userFk">
</vn-worker-autocomplete> </vn-worker-autocomplete>
</vn-horizontal> </vn-horizontal>
</vn-card> </vn-card>

View File

@ -17,19 +17,19 @@ class Controller extends Section {
set stateFk(value) { set stateFk(value) {
this.params.stateFk = value; this.params.stateFk = value;
this.isPickerDesignedState = this.getIsPickerDesignedState(value); this.isPickerDesignedState = this.getIsPickerDesignedState(value);
this.workerFk = window.localStorage.currentUserWorkerId; this.userFk = window.localStorage.currentUserWorkerId;
} }
get stateFk() { get stateFk() {
return this.params.stateFk; return this.params.stateFk;
} }
set workerFk(value) { set userFk(value) {
this.params.workerFk = value; this.params.userFk = value;
} }
get workerFk() { get userFk() {
return this.params.workerFk; return this.params.userFk;
} }
getPickerDesignedState() { getPickerDesignedState() {

View File

@ -29,11 +29,11 @@ describe('Ticket', () => {
}); });
}); });
describe('workerFk setter', () => { describe('userFk setter', () => {
it('should set params.workerFk', () => { it('should set params.userFk', () => {
controller.workerFk = 1; controller.userFk = 1;
expect(controller.params.workerFk).toEqual(1); expect(controller.params.userFk).toEqual(1);
}); });
}); });

View File

@ -3,7 +3,7 @@ const UserError = require('vn-loopback/util/user-error');
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('deleteTimeEntry', { Self.remoteMethodCtx('deleteTimeEntry', {
description: 'Deletes a manual time entry for a worker if the user role is above the worker', description: 'Deletes a manual 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',

View File

@ -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',

View File

@ -7,7 +7,7 @@ module.exports = {
this.invoice = await this.findOneFromDef('invoice', [this.reference]); this.invoice = await this.findOneFromDef('invoice', [this.reference]);
this.checkMainEntity(this.invoice); this.checkMainEntity(this.invoice);
this.client = await this.findOneFromDef('client', [this.reference]); this.client = await this.findOneFromDef('client', [this.reference]);
this.incoterms = await this.findOneFromDef('incoterms', [this.reference, this.reference, this.reference]); this.incoterms = await this.findOneFromDef('incoterms', [this.reference, this.reference, this.reference, this.reference]);
}, },
props: { props: {
reference: { reference: {

View File

@ -1,13 +1,12 @@
SELECT SELECT c.id,
c.id,
c.socialName, c.socialName,
c.street AS postalAddress, c.street postalAddress,
IF (ios.taxAreaFk IS NOT NULL, CONCAT(cty.code, c.fi), c.fi) fi, IF (ios.taxAreaFk IS NOT NULL, CONCAT(cty.code, c.fi), c.fi) fi,
CONCAT(c.postcode, ' - ', c.city) postcodeCity CONCAT(c.postcode, ' - ', c.city) postcodeCity
FROM vn.invoiceOut io FROM vn.invoiceOut io
JOIN vn.client c ON c.id = io.clientFk JOIN vn.client c ON c.id = io.clientFk
JOIN vn.country cty ON cty.id = c.countryFk JOIN vn.country cty ON cty.id = c.countryFk
LEFT JOIN vn.invoiceOutSerial ios ON ios.code = io.serial LEFT JOIN vn.invoiceOutSerial ios ON ios.code = io.serial
AND ios.taxAreaFk = 'CEE' AND ios.taxAreaFk = 'CEE'
LEFT JOIN ticket t ON t.refFk = io.ref LEFT JOIN ticket t ON t.refFk = io.ref
WHERE t.refFk = ? WHERE t.refFk = ?

View File

@ -1,38 +1,14 @@
SELECT io.issued, SELECT pack.packages,
c.socialName,
c.street postalAddress,
c.fi,
io.clientFk,
c.postcode,
c.city,
io.companyFk,
io.ref,
tc.code,
s.concept,
s.quantity,
s.price,
s.discount,
s.ticketFk,
t.shipped,
t.refFk,
a.nickname,
s.itemFk,
s.id saleFk,
pm.name AS pmname,
sa.iban,
c.phone,
MAX(t.packages) packages,
a.incotermsFk, a.incotermsFk,
ic.name incotermsName , ic.name incotermsName,
t.weight, t.weight,
t.observations,
ca.fiscalName customsAgentName, ca.fiscalName customsAgentName,
ca.street customsAgentStreet, ca.street customsAgentStreet,
ca.nif customsAgentNif, ca.nif customsAgentNif,
ca.phone customsAgentPhone, ca.phone customsAgentPhone,
ca.email customsAgentEmail, ca.email customsAgentEmail,
CAST(sub2.volume AS DECIMAL (10,2)) volume, CAST(vol.volume AS DECIMAL (10,2)) volume,
sub3.intrastat intr.intrastat
FROM vn.invoiceOut io FROM vn.invoiceOut io
JOIN vn.supplier su ON su.id = io.companyFk JOIN vn.supplier su ON su.id = io.companyFk
JOIN vn.client c ON c.id = io.clientFk JOIN vn.client c ON c.id = io.clientFk
@ -42,26 +18,35 @@ SELECT io.issued,
LEFT JOIN vn.incoterms ic ON ic.code = a.incotermsFk LEFT JOIN vn.incoterms ic ON ic.code = a.incotermsFk
LEFT JOIN vn.customsAgent ca ON ca.id = a.customsAgentFk LEFT JOIN vn.customsAgent ca ON ca.id = a.customsAgentFk
JOIN vn.sale s ON s.ticketFk = t.id JOIN vn.sale s ON s.ticketFk = t.id
JOIN (SELECT SUM(volume) volume JOIN (
SELECT SUM(volume) volume, COUNT(*) packages
FROM vn.invoiceOut io FROM vn.invoiceOut io
JOIN vn.ticket t ON t.refFk = io.ref JOIN vn.ticket t ON t.refFk = io.ref
JOIN vn.saleVolume sv ON sv.ticketFk = t.id JOIN vn.saleVolume sv ON sv.ticketFk = t.id
WHERE t.refFk = ? WHERE t.refFk = ?
) sub2 ON TRUE ) vol
JOIN vn.itemTaxCountry itc ON itc.countryFk = su.countryFk AND itc.itemFk = s.itemFk JOIN vn.itemTaxCountry itc ON itc.countryFk = su.countryFk
AND itc.itemFk = s.itemFk
JOIN vn.taxClass tc ON tc.id = itc.taxClassFk JOIN vn.taxClass tc ON tc.id = itc.taxClassFk
JOIN vn.invoiceOutSerial ios ON ios.code = io.serial AND ios.taxAreaFk = 'WORLD' JOIN vn.invoiceOutSerial ios ON ios.code = io.serial
AND ios.taxAreaFk = 'WORLD'
JOIN vn.country cty ON cty.id = c.countryFk JOIN vn.country cty ON cty.id = c.countryFk
JOIN vn.payMethod pm ON pm.id = c .payMethodFk JOIN vn.payMethod pm ON pm.id = c .payMethodFk
JOIN vn.company co ON co.id=io.companyFk JOIN vn.company co ON co.id=io.companyFk
JOIN vn.supplierAccount sa ON sa.id=co.supplierAccountFk JOIN vn.supplierAccount sa ON sa.id=co.supplierAccountFk
LEFT JOIN (SELECT GROUP_CONCAT(DISTINCT ir.description ORDER BY ir.description SEPARATOR '. ' ) as intrastat JOIN (
SELECT GROUP_CONCAT(DISTINCT ir.description ORDER BY ir.description SEPARATOR '. ' ) intrastat
FROM vn.ticket t FROM vn.ticket t
JOIN vn.invoiceOut io ON io.ref = t.refFk JOIN vn.invoiceOut io ON io.ref = t.refFk
JOIN vn.sale s ON t.id = s.ticketFk JOIN vn.sale s ON t.id = s.ticketFk
JOIN vn.item i ON i.id = s.itemFk JOIN vn.item i ON i.id = s.itemFk
JOIN vn.intrastat ir ON ir.id = i.intrastatFk JOIN vn.intrastat ir ON ir.id = i.intrastatFk
WHERE t.refFk = ? WHERE t.refFk = ?
)sub3 ON TRUE ) intr
JOIN (
SELECT SUM(packages) packages
FROM ticket
WHERE refFk = ?
) pack
WHERE t.refFk = ? WHERE t.refFk = ?
LIMIT 1

View File

@ -1,18 +1,17 @@
SELECT SELECT io.id,
io.id,
io.issued, io.issued,
io.clientFk, io.clientFk,
io.companyFk, io.companyFk,
io.ref, io.ref,
pm.code AS payMethodCode, pm.code payMethodCode,
cny.code companyCode, cny.code companyCode,
sa.iban, sa.iban,
ios.footNotes ios.footNotes
FROM invoiceOut io FROM invoiceOut io
JOIN client c ON c.id = io.clientFk JOIN client c ON c.id = io.clientFk
JOIN payMethod pm ON pm.id = c.payMethodFk JOIN payMethod pm ON pm.id = c.payMethodFk
JOIN company cny ON cny.id = io.companyFk JOIN company cny ON cny.id = io.companyFk
JOIN supplierAccount sa ON sa.id = cny.supplierAccountFk JOIN supplierAccount sa ON sa.id = cny.supplierAccountFk
LEFT JOIN invoiceOutSerial ios ON ios.code = io.serial LEFT JOIN invoiceOutSerial ios ON ios.code = io.serial
LEFT JOIN ticket t ON t.refFk = io.ref LEFT JOIN ticket t ON t.refFk = io.ref
WHERE t.refFk = ? WHERE t.refFk = ?