WIP: #7134 SupplierBalance #3173
|
@ -2629,9 +2629,9 @@ REPLACE INTO `vn`.`invoiceIn`(`id`, `serialNumber`,`serial`, `supplierFk`, `issu
|
||||||
(9, 1009, 'R', 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1242, 0, 442, 1,util.VN_CURDATE()),
|
(9, 1009, 'R', 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1242, 0, 442, 1,util.VN_CURDATE()),
|
||||||
(10, 1010, 'R', 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1243, 0, 442, 1,util.VN_CURDATE());
|
(10, 1010, 'R', 2, DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), DATE_ADD(util.VN_CURDATE(), INTERVAL -1 MONTH), 1243, 0, 442, 1,util.VN_CURDATE());
|
||||||
|
|
||||||
INSERT INTO `vn`.`invoiceInConfig` (`id`, `retentionRate`, `retentionName`, `sageFarmerWithholdingFk`, `daysAgo`)
|
INSERT INTO `vn`.`invoiceInConfig` (`id`, `retentionRate`, `retentionName`, `sageFarmerWithholdingFk`, `daysAgo`, `balanceStartingDate`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, -2, '2% retention', 2, 45);
|
(1, -2, '2% retention', 2, 45, '2000-01-01');
|
||||||
|
|
||||||
INSERT INTO `vn`.`invoiceInDueDay`(`invoiceInFk`, `dueDated`, `bankFk`, `amount`)
|
INSERT INTO `vn`.`invoiceInDueDay`(`invoiceInFk`, `dueDated`, `bankFk`, `amount`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -4012,10 +4012,10 @@ INSERT INTO vn.routeAction (id, name, price, isMainlineDelivered) VALUES(1, 'Pin
|
||||||
INSERT INTO vn.routeComplement (id, dated, workerFk, price, routeActionFk) VALUES(1, util.VN_CURDATE(), 9, 50.00, 1);
|
INSERT INTO vn.routeComplement (id, dated, workerFk, price, routeActionFk) VALUES(1, util.VN_CURDATE(), 9, 50.00, 1);
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO srt.buffer (id, x, y, `size`, `length`, stateFk, typeFk, isActive, code, stratus, hasWorkerWaiting, reserve, routeFk, dayMinute, lastUnloaded, hasStrapper, typeDefaultFk, motors, editorFk)
|
INSERT INTO srt.buffer (id, x, y, `size`, `length`, stateFk, typeFk, isActive, code, stratus, hasWorkerWaiting, reserve, routeFk, dayMinute, lastUnloaded, hasStrapper, typeDefaultFk, motors, editorFk)
|
||||||
VALUES (0, 0, 0, 0, NULL, 3, 1, 0, 'ENT', 0, 0, NULL, NULL, NULL, NULL, 0, 1, 1, NULL),
|
VALUES (0, 0, 0, 0, NULL, 3, 1, 0, 'ENT', 0, 0, NULL, NULL, NULL, NULL, 0, 1, 1, NULL),
|
||||||
(1, 0, 9900, 0, NULL, 1, 0, 0, 'NOK', 0, 0, NULL, NULL, NULL, NULL, 0, 1, 1, NULL),
|
(1, 0, 9900, 0, NULL, 1, 0, 0, 'NOK', 0, 0, NULL, NULL, NULL, NULL, 0, 1, 1, NULL),
|
||||||
(2, 0, 0, 450, 13000, 1, 0, 1, '01A', 1, 1, NULL, NULL, NULL, NULL, 0, 1, 1, NULL),
|
(2, 0, 0, 450, 13000, 1, 0, 1, '01A', 1, 1, NULL, NULL, NULL, NULL, 0, 1, 1, NULL),
|
||||||
(3, 1400, 0, 450, 13000, 1, 0, 1, '01B', 1, 0, NULL, NULL, NULL, NULL, 0, 1, 1, NULL),
|
(3, 1400, 0, 450, 13000, 1, 0, 1, '01B', 1, 0, NULL, NULL, NULL, NULL, 0, 1, 1, NULL),
|
||||||
(4, 0, 500, 500, 13000, 1, 4, 1, '02A', 2, 1, NULL, NULL, NULL, NULL, 1, 4, 13, NULL),
|
(4, 0, 500, 500, 13000, 1, 4, 1, '02A', 2, 1, NULL, NULL, NULL, NULL, 1, 4, 13, NULL),
|
||||||
(5, 1400, 500, 500, 13000, 1, 4, 1, '02B', 2, 1, NULL, NULL, NULL, NULL, 1, 4, 13, NULL),
|
(5, 1400, 500, 500, 13000, 1, 4, 1, '02B', 2, 1, NULL, NULL, NULL, NULL, 1, 4, 13, NULL),
|
||||||
|
@ -4026,9 +4026,13 @@ INSERT INTO srt.buffer (id, x, y, `size`, `length`, stateFk, typeFk, isActive, c
|
||||||
(10, 0, 2000, 500, 13000, 1, 1, 1, '05A', 5, 0, NULL, NULL, NULL, NULL, 0, 1, 1, NULL);
|
(10, 0, 2000, 500, 13000, 1, 1, 1, '05A', 5, 0, NULL, NULL, NULL, NULL, 0, 1, 1, NULL);
|
||||||
|
|
||||||
|
|
||||||
INSERT IGNORE INTO vn.saySimpleCountry (countryFk, channel)
|
INSERT IGNORE INTO vn.saySimpleCountry (countryFk, channel)
|
||||||
VALUES (19, '1169'),
|
VALUES (19, '1169'),
|
||||||
(8, '1183');
|
(8, '1183');
|
||||||
|
|
||||||
INSERT IGNORE INTO vn.saySimpleConfig (url, defaultChannel)
|
INSERT IGNORE INTO vn.saySimpleConfig (url, defaultChannel)
|
||||||
VALUES ('saysimle-url-mock', 1320);
|
VALUES ('saysimle-url-mock', 1320);
|
||||||
|
|
||||||
|
|
||||||
|
INSERT INTO vn.payment (received,supplierFk,amount,currencyFk,divisa,bankFk,payMethodFk,bankingFees,concept,companyFk,created,isConciliated,dueDated,workerFk) VALUES
|
||||||
|
('2024-09-15',1,1000.00,1,NULL,1,1,0.0,'n/pago',442,'2024-11-20 13:06:02.000',1,'2024-09-15',9);
|
||||||
|
|
|
@ -154,7 +154,7 @@ BEGIN
|
||||||
JOIN travel tr ON tr.id = e.travelFk
|
JOIN travel tr ON tr.id = e.travelFk
|
||||||
JOIN currency c ON c.id = e.currencyFk
|
JOIN currency c ON c.id = e.currencyFk
|
||||||
WHERE e.supplierFk = vSupplierFk
|
WHERE e.supplierFk = vSupplierFk
|
||||||
AND tr.landed >= CURDATE()
|
AND tr.landed >= util.VN_CURDATE()
|
||||||
AND e.invoiceInFk IS NULL
|
AND e.invoiceInFk IS NULL
|
||||||
AND vHasEntries
|
AND vHasEntries
|
||||||
ORDER BY (dated IS NULL AND NOT isBooked),
|
ORDER BY (dated IS NULL AND NOT isBooked),
|
||||||
|
|
|
@ -0,0 +1,173 @@
|
||||||
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
// Insert payment
|
||||||
|
|
||||||
|
// divisa = solo en caso que la moneda sea distinta a €,
|
||||||
|
module.exports = function(Self) {
|
||||||
|
Self.remoteMethodCtx('createReceipt', {
|
||||||
|
description: 'Creates receipt and its compensation if necessary',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'supplierFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'The supplier id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'received',
|
||||||
|
type: 'Date',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'dueDate',
|
||||||
|
type: 'Date',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'companyFk',
|
||||||
|
type: 'number',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'currencyFk',
|
||||||
|
type: 'number',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'bankFk',
|
||||||
|
type: 'number',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'payMethodFk',
|
||||||
|
type: 'number',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'amount',
|
||||||
|
type: 'number',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'concept',
|
||||||
|
type: 'string',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'divisa',
|
||||||
|
type: 'number'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'compensationAccount',
|
||||||
|
type: 'any'
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
root: true,
|
||||||
|
type: 'Object'
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
verb: 'post',
|
||||||
|
path: '/:supplierFk/createReceipt'
|
||||||
|
},
|
||||||
|
accessScopes: ['DEFAULT', 'read:multimedia']
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.createReceipt = async(ctx, options) => {
|
||||||
|
const models = Self.app.models;
|
||||||
|
const args = ctx.args;
|
||||||
|
const date = Date.vnNew();
|
||||||
|
date.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
let tx;
|
||||||
|
const myOptions = {userId: ctx.req.accessToken.userId};
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
delete args.ctx; // Remove unwanted properties
|
||||||
|
|
||||||
|
const originalSupplier = await models.Supplier.findById(args.supplierFk, null, myOptions);
|
||||||
|
const bank = await models.Accounting.findById(args.bankFk, null, myOptions);
|
||||||
|
const accountingType = await models.AccountingType.findById(bank.accountingTypeFk, null, myOptions);
|
||||||
|
|
||||||
|
if (accountingType.code == 'compensation') {
|
||||||
|
if (!args.compensationAccount)
|
||||||
|
throw new UserError('Compensation account is empty');
|
||||||
|
|
||||||
|
// Check compensation account exists
|
||||||
|
await models.Supplier.getClientOrSupplierReference(args.compensationAccount, myOptions);
|
||||||
|
|
||||||
|
await Self.rawSql(
|
||||||
|
`CALL vn.ledger_doCompensation(?, ?, ?, ?, ?, ?, ?)`,
|
||||||
|
[
|
||||||
|
date,
|
||||||
|
args.compensationAccount,
|
||||||
|
args.bankFk,
|
||||||
|
accountingType.receiptDescription + originalSupplier.accountingAccount,
|
||||||
|
args.amountPaid,
|
||||||
|
args.companyFk,
|
||||||
|
originalSupplier.accountingAccount
|
||||||
|
],
|
||||||
|
myOptions
|
||||||
|
);
|
||||||
|
} else if (accountingType.isAutoConciliated == true) {
|
||||||
|
const description =
|
||||||
|
`${originalSupplier.id} : ${originalSupplier.socialName} - ${accountingType.receiptDescription}`;
|
||||||
|
const [, [xdiarioNew]] = await Self.rawSql(
|
||||||
|
`CALL xdiario_new(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, @xdiarioNew);
|
||||||
|
SELECT @xdiarioNew ledger;`,
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
date,
|
||||||
|
bank.account,
|
||||||
|
originalSupplier.accountingAccount,
|
||||||
|
description,
|
||||||
|
args.amountPaid,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
args.companyFk
|
||||||
|
],
|
||||||
|
myOptions
|
||||||
|
);
|
||||||
|
|
||||||
|
await Self.rawSql(
|
||||||
|
`CALL xdiario_new(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, @xdiarioNew);`,
|
||||||
|
[
|
||||||
|
xdiarioNew.ledger,
|
||||||
|
date,
|
||||||
|
originalSupplier.accountingAccount,
|
||||||
|
bank.account,
|
||||||
|
description,
|
||||||
|
0,
|
||||||
|
args.amountPaid,
|
||||||
|
0,
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
args.companyFk
|
||||||
|
],
|
||||||
|
myOptions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const newReceipt = await models.Receipt.create(args, myOptions);
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
|
return newReceipt;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,73 @@
|
||||||
|
|
||||||
|
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethodCtx('receipts', {
|
||||||
|
description: 'Find all clients matched by the filter',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [
|
||||||
|
{
|
||||||
|
arg: 'supplierId',
|
||||||
|
type: 'number',
|
||||||
|
description: 'The supplier id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'companyId',
|
||||||
|
type: 'number',
|
||||||
|
description: 'The company id',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'currencyFk',
|
||||||
|
type: 'number',
|
||||||
|
description: 'The currency',
|
||||||
|
default: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'orderBy',
|
||||||
|
type: 'string',
|
||||||
|
description: 'The client fiscal id',
|
||||||
|
enum: ['issued', ' bookEntried', ' booked', ' dueDate'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'isConciliated',
|
||||||
|
default: false,
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
returns: {
|
||||||
|
type: ['object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/receipts`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.receipts = async(ctx, filter, options) => {
|
||||||
|
const conn = Self.dataSource.connector;
|
||||||
|
const myOptions = {userId: ctx.req.accessToken.userId};
|
||||||
|
const args = ctx.args;
|
||||||
|
|
||||||
|
if (typeof options == 'object')
|
||||||
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
|
let stmts = [];
|
||||||
|
stmts.push(new ParameterizedSQL('CALL vn.supplier_statementWithEntries(?,?,?,?,?,?)', [
|
||||||
|
args.supplierId,
|
||||||
|
args.currencyFk ?? 1,
|
||||||
|
args.companyId,
|
||||||
|
args.orderBy ?? 'issued',
|
||||||
|
args.isConciliated ?? false,
|
||||||
|
false
|
||||||
|
]));
|
||||||
|
stmts.push(`
|
||||||
|
SELECT *
|
||||||
|
FROM tmp.supplierStatement`);
|
||||||
|
stmts.push(`DROP TEMPORARY TABLE tmp.supplierStatement`);
|
||||||
|
const sql = ParameterizedSQL.join(stmts, ';');
|
||||||
|
const results = await conn.executeStmt(sql);
|
||||||
|
const resultsIndex = stmts.length - 2;
|
||||||
|
const result = results[resultsIndex];
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
};
|
|
@ -8,6 +8,8 @@ module.exports = Self => {
|
||||||
require('../methods/supplier/updateFiscalData')(Self);
|
require('../methods/supplier/updateFiscalData')(Self);
|
||||||
require('../methods/supplier/consumption')(Self);
|
require('../methods/supplier/consumption')(Self);
|
||||||
require('../methods/supplier/freeAgencies')(Self);
|
require('../methods/supplier/freeAgencies')(Self);
|
||||||
|
require('../methods/supplier/createReceipt')(Self);
|
||||||
|
require('../methods/supplier/receipts')(Self);
|
||||||
require('../methods/supplier/campaignMetricsPdf')(Self);
|
require('../methods/supplier/campaignMetricsPdf')(Self);
|
||||||
require('../methods/supplier/campaignMetricsEmail')(Self);
|
require('../methods/supplier/campaignMetricsEmail')(Self);
|
||||||
require('../methods/supplier/newSupplier')(Self);
|
require('../methods/supplier/newSupplier')(Self);
|
||||||
|
|
Loading…
Reference in New Issue