58 Commits

Author SHA1 Message Date
db3afdd7c3 upd 2026-03-24 22:02:40 +07:00
65bcd4ffd4 upd 2026-03-24 21:35:20 +07:00
a93d3024ac upd 2026-03-24 21:30:18 +07:00
c86bad1770 upd 2026-03-24 21:12:42 +07:00
5d85d1d03e upd 2026-03-24 20:59:19 +07:00
cbe61ff23c upd 2026-03-24 19:39:17 +07:00
e97cfabb90 upd 2026-03-24 16:23:39 +07:00
7036f77895 upd 2026-03-24 16:09:34 +07:00
9ab852c4dd upd 2026-03-24 15:40:25 +07:00
b6378e66e6 upd 2026-03-24 14:03:18 +07:00
5a98eb97b3 upd 2026-03-24 13:18:50 +07:00
952f760b9b upd 2026-03-24 13:03:48 +07:00
39152d2d15 upd 2026-03-24 13:00:48 +07:00
31cd6e5b38 upd 2026-03-24 12:58:24 +07:00
cd71511404 upd 2026-03-24 12:52:18 +07:00
040d6b93bc upd 2026-03-24 11:31:26 +07:00
8cf15b2594 upd 2026-03-24 11:10:50 +07:00
462059519d upd 2026-03-24 10:06:47 +07:00
bab8faf3ad upd 2026-03-24 10:01:10 +07:00
075b51c4d5 add currency on budget list 2026-03-24 09:35:23 +07:00
9bb5278c4b add currency_id & rate_snapshot to document APIs (Phase 3)
- budgetadapter: list/detail queries JOIN tbl_currency; create/update budget and requestbudget store currency_id + rate_snapshot via subquery
- justificationadapter: create/update store currency_id + rate_snapshot
- pradapter: create/update store currency_id + rate_snapshot; list/detail JOIN tbl_currency
- poadapter: insert stores currency_id + rate_snapshot; list/detail queries JOIN tbl_currency

All currency_id fields are nullable - existing records unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 21:02:56 +07:00
26d22355fa add multi-currency master CRUD (Phase 2)
- add currencyadapter.js: list (with pagination+keyword), detail, history, create, update (auto-log rate change to tbl_currency_log), delete (soft), convertAmount helper
- add controllers/currency.js and routes/currency.js, auto-mounted at /currency
- update dbproc.js: configurable port via HOSTPORT env variable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 20:52:29 +07:00
b2c866d793 upd 2026-03-16 16:16:25 +07:00
2b63541bcc update 2026-03-16 15:37:20 +07:00
6c5c3ef280 upd 2026-03-16 13:53:28 +07:00
1b3a4b67f4 my task 2026-03-16 13:42:50 +07:00
2b34f15d4f upd 2026-03-16 11:36:05 +07:00
357b95774f add endpoint spend by unit 2026-03-16 11:17:50 +07:00
5335671e98 log 2026-03-13 16:15:26 +07:00
8973a1ace1 upd 2026-03-13 16:12:26 +07:00
d2364d0bb7 upd 2026-03-13 16:09:15 +07:00
7604f9cb44 upd 2026-03-13 16:07:28 +07:00
a8e0091267 upd 2026-03-12 14:30:15 +07:00
51f0c8fe67 upd 2026-03-12 14:28:53 +07:00
51af0e4889 feat: add pr approved by 2026-03-12 14:01:43 +07:00
4a75f278f7 upd 2026-03-12 10:11:48 +07:00
b59a9b830a feat: add route dashboard 2026-03-11 15:38:12 +07:00
8c7634298f feat: add route dashboard 2026-03-11 15:34:48 +07:00
fc74e23dbf upd 2026-03-11 15:28:58 +07:00
23ea31d78b feat: add route dashboard 2026-03-11 15:25:37 +07:00
446e32314e upd 2026-03-10 15:29:06 +07:00
17a2281f1a upd 2026-03-10 15:14:30 +07:00
9c5eb61240 update 2026-03-10 15:08:22 +07:00
6392d831d6 fix: group po management by nik 2026-03-10 14:53:20 +07:00
f6995e5b5b fix: group approval pr by nik 2026-03-10 14:49:58 +07:00
806a8c63ff show released PO 2026-03-10 14:44:20 +07:00
329da17cf4 feat: add po boq 2026-03-10 13:47:33 +07:00
e01b2706f3 upd 2026-03-10 10:17:52 +07:00
5c3be08142 log 2026-03-06 16:44:06 +07:00
6b1cccd90a log 2026-03-06 16:38:41 +07:00
93def2de57 upd 2026-03-06 16:30:49 +07:00
2e52f41daf upd 2026-03-06 16:28:22 +07:00
d03ee0aca0 upd 2026-03-06 16:27:11 +07:00
09875a61fa upd 2026-03-06 16:22:30 +07:00
c5b08ee099 upd 2026-03-06 16:16:40 +07:00
92be63ab02 upd 2026-03-06 16:13:32 +07:00
1f898d3977 upd 2026-03-06 16:10:32 +07:00
ee0cfda601 log 2026-03-06 16:10:15 +07:00
19 changed files with 2229 additions and 686 deletions

View File

@ -15,12 +15,12 @@ class BastAdapter extends Adapter {
let offset = req.query.offset; let offset = req.query.offset;
let keyword = req.query.keyword; let keyword = req.query.keyword;
let qry = "select * from vw_bastactivitylist "; let qry = "select v.*, COALESCE(c.currency, 'USD') AS currency_code, COALESCE(c.symbol, '$') AS currency_symbol, pr.rate_snapshot AS pr_rate_snapshot " +
qry = qry + "where activityname like '%" + keyword + "%' "; "from vw_bastactivitylist v " +
qry = qry + "order by idxbudget asc limit " + offset + ", " + limit; "left join tbl_pr pr on pr._idx = v.idxpr " +
// let qry = "select * from vw_basthandoverlist "; "left join tbl_currency c on c._idx = pr.currency_id ";
// qry = qry + "where bastnumber like '%" + keyword + "%' "; qry = qry + "where v.activityname like '%" + keyword + "%' ";
// qry = qry + "order by _idx asc limit " + offset + ", " + limit; qry = qry + "order by v.idxbudget asc limit " + offset + ", " + limit;
// console.log(qry); // console.log(qry);
db.query(qry, [], function (err, result, fields) { db.query(qry, [], function (err, result, fields) {
@ -40,9 +40,12 @@ class BastAdapter extends Adapter {
"totalpage": pagination, "totalpage": pagination,
"totalrows": result.length, "totalrows": result.length,
}); });
qry = "select * from vw_bastactivitylist "; qry = "select v.*, COALESCE(c.currency, 'USD') AS currency_code, COALESCE(c.symbol, '$') AS currency_symbol, pr.rate_snapshot AS pr_rate_snapshot " +
qry = qry + "where activityname like '%" + keyword + "%' "; "from vw_bastactivitylist v " +
qry = qry + "order by idxbudget asc limit " + offset + ", " + limit; "left join tbl_pr pr on pr._idx = v.idxpr " +
"left join tbl_currency c on c._idx = pr.currency_id ";
qry = qry + "where v.activityname like '%" + keyword + "%' ";
qry = qry + "order by v.idxbudget asc limit " + offset + ", " + limit;
// qry = "select * from vw_basthandoverlist "; // qry = "select * from vw_basthandoverlist ";
// qry = qry + "where bastnumber like '%" + keyword + "%' "; // qry = qry + "where bastnumber like '%" + keyword + "%' ";
// qry = qry + "order by _idx asc limit " + offset + ", " + limit; // qry = qry + "order by _idx asc limit " + offset + ", " + limit;
@ -82,9 +85,12 @@ class BastAdapter extends Adapter {
// let qry = "select * from vw_bastactivitylist "; // let qry = "select * from vw_bastactivitylist ";
// qry = qry + "where activityname like '%" + keyword + "%' "; // qry = qry + "where activityname like '%" + keyword + "%' ";
// qry = qry + "order by idxbudget asc limit " + offset + ", " + limit; // qry = qry + "order by idxbudget asc limit " + offset + ", " + limit;
let qry = "select * from vw_basthandoverlist "; let qry = "select v.*, COALESCE(c.currency, 'USD') AS currency_code, COALESCE(c.symbol, '$') AS currency_symbol, po.rate_snapshot " +
qry = qry + "where bastnumber like '%" + keyword + "%' "; "from vw_basthandoverlist v " +
qry = qry + "order by _idx asc"; "left join tbl_po po on po._idx = v.idxpo " +
"left join tbl_currency c on c._idx = po.currency_id ";
qry = qry + "where v.bastnumber like '%" + keyword + "%' ";
qry = qry + "order by v._idx asc";
// console.log(qry); // console.log(qry);
db.query(qry, [], function (err, result, fields) { db.query(qry, [], function (err, result, fields) {
@ -105,12 +111,12 @@ class BastAdapter extends Adapter {
"totalrows": result.length, "totalrows": result.length,
}); });
// qry = "select * from vw_bastactivitylist "; qry = "select v.*, COALESCE(c.currency, 'USD') AS currency_code, COALESCE(c.symbol, '$') AS currency_symbol, po.rate_snapshot " +
// qry = qry + "where activityname like '%" + keyword + "%' "; "from vw_basthandoverlist v " +
// qry = qry + "order by idxbudget asc limit " + offset + ", " + limit; "left join tbl_po po on po._idx = v.idxpo " +
qry = "select * from vw_basthandoverlist "; "left join tbl_currency c on c._idx = po.currency_id ";
qry = qry + "where bastnumber like '%" + keyword + "%' "; qry = qry + "where v.bastnumber like '%" + keyword + "%' ";
qry = qry + "order by _idx asc limit " + offset + ", " + limit; qry = qry + "order by v._idx asc limit " + offset + ", " + limit;
db.query(qry, [], function (err, result, fields) { db.query(qry, [], function (err, result, fields) {
if (err) { if (err) {
apires.meta["message"] = err.toString(); apires.meta["message"] = err.toString();
@ -142,8 +148,18 @@ class BastAdapter extends Adapter {
try { try {
let idxpr = req.query.idxpr; let idxpr = req.query.idxpr;
let qry = "select * from vw_bastactivitylistdetail "; let qry = "select v.*, po.rate_snapshot AS po_rate_snapshot, " +
qry = qry + "where idxpr='" + idxpr + "'"; "COALESCE(c.currency, 'USD') AS currency_code, COALESCE(c.symbol, '$') AS currency_symbol, " +
"COALESCE(pc.currency, 'USD') AS pr_currency_code, COALESCE(pc.symbol, '$') AS pr_currency_symbol, " +
"rb.amount AS request_budget_amount " +
"from vw_bastactivitylistdetail v " +
"left join tbl_po po on po._idx = v.idxpo " +
"left join tbl_currency c on c._idx = po.currency_id " +
"left join tbl_pr prr on prr._idx = v.idxpr " +
"left join tbl_currency pc on pc._idx = prr.currency_id " +
"left join tbl_justification j on j._idx = po.idxjustification " +
"left join tbl_requestbudget rb on rb._idx = j.idxrequestbudget " +
"where v.idxpr='" + idxpr + "'";
// console.log(qry); // console.log(qry);
db.query(qry, [], function (err, result, fields) { db.query(qry, [], function (err, result, fields) {
@ -398,8 +414,11 @@ class BastAdapter extends Adapter {
try { try {
let idxbast = req.query.idxbast; let idxbast = req.query.idxbast;
let qry = "select * from vw_bast "; let qry = "select v.*, COALESCE(c.currency, 'USD') AS currency_code, COALESCE(c.symbol, '$') AS currency_symbol, po.rate_snapshot " +
qry = qry + "where _idx='" + idxbast + "'"; "from vw_bast v " +
"left join tbl_po po on po._idx = v.idxpo " +
"left join tbl_currency c on c._idx = po.currency_id " +
"where v._idx='" + idxbast + "'";
// console.log(qry); // console.log(qry);
db.query(qry, [], function (err, result, fields) { db.query(qry, [], function (err, result, fields) {

View File

@ -16,8 +16,12 @@ class BudgetAdapter extends Adapter{
let offset = req.body.offset; let offset = req.body.offset;
let keyword = req.body.keyword; let keyword = req.body.keyword;
let qry = "select * from vw_budgetcapexinfo "; let qryBase = "select v.*, b.currency_id, b.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol ";
qry = qry +"where (trim(budgetid) like '%"+ keyword +"%' or trim(activityname) like '%"+ keyword +"%') order by id asc"; qryBase += "from vw_budgetcapexinfo v ";
qryBase += "left join tbl_budgetcapexinfo b on b._idx = v.id ";
qryBase += "left join tbl_currency c on c._idx = b.currency_id ";
qryBase += "where (trim(v.budgetid) like '%"+ keyword +"%' or trim(v.activityname) like '%"+ keyword +"%') ";
let qry = qryBase + "order by v.id asc";
// console.log(qry); // console.log(qry);
db.query(qry,[],function(err,result,fields){ db.query(qry,[],function(err,result,fields){
@ -39,8 +43,7 @@ class BudgetAdapter extends Adapter{
"totalpage": pagination, "totalpage": pagination,
"totalrows": result.length "totalrows": result.length
}); });
qry = "select * from vw_budgetcapexinfo "; qry = qryBase + "order by v.id asc limit " + offset + ", " + limit;
qry = qry +"where (trim(budgetid) like '%"+ keyword +"%' or trim(activityname) like '%"+ keyword +"%') order by id asc limit " + offset + ", " + limit;
db.query(qry,[],function(err,result,fields){ db.query(qry,[],function(err,result,fields){
if(err){ if(err){
apires.meta['message'] = err.toString(); apires.meta['message'] = err.toString();
@ -80,8 +83,11 @@ class BudgetAdapter extends Adapter{
let id = req.query.id; let id = req.query.id;
// console.log(req); // console.log(req);
let qry = "select * from vw_budgetcapexinfo "; let qry = "select v.*, b.currency_id, b.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol ";
qry = qry +"where id='"+id+"' order by id asc limit 1"; qry += "from vw_budgetcapexinfo v ";
qry += "left join tbl_budgetcapexinfo b on b._idx = v.id ";
qry += "left join tbl_currency c on c._idx = b.currency_id ";
qry += "where v.id='"+id+"' order by v.id asc limit 1";
// console.log(qry); // console.log(qry);
db.query(qry,[],function(err,result,fields){ db.query(qry,[],function(err,result,fields){
@ -190,10 +196,15 @@ class BudgetAdapter extends Adapter{
let months = req.body.months; let months = req.body.months;
let years = req.body.years; let years = req.body.years;
let nik = req.body.nik; let nik = req.body.nik;
let currency_id = req.body.currency_id ?? null;
let currencyFields = currency_id
? ",currency_id='"+currency_id+"',rate_snapshot=(select rate from tbl_currency where _idx='"+currency_id+"' and isdeleted=0 limit 1)"
: ",currency_id=NULL,rate_snapshot=NULL";
let qry = "insert into tbl_budgetcapexinfo "; let qry = "insert into tbl_budgetcapexinfo ";
qry = qry +"set idxbudgettype='"+idxbudgettype+"', budgetid='"+budgetid+"',activityname='"+activityname+"',amount='"+amount+"',months='"+months+"',"; qry = qry +"set idxbudgettype='"+idxbudgettype+"', budgetid='"+budgetid+"',activityname='"+activityname+"',amount='"+amount+"',months='"+months+"',";
qry = qry +"targetrfs='"+targetrfs+"',years='"+years+"', iby='"+nik+"',idt=now()"; qry = qry +"targetrfs='"+targetrfs+"',years='"+years+"'"+currencyFields+", iby='"+nik+"',idt=now()";
// console.log(qry); // console.log(qry);
db.query(qry,[],function(err,result,fields){ db.query(qry,[],function(err,result,fields){
@ -232,10 +243,15 @@ class BudgetAdapter extends Adapter{
let years = req.body.years; let years = req.body.years;
let nik = req.body.nik; let nik = req.body.nik;
let id = req.body.id; let id = req.body.id;
let currency_id = req.body.currency_id ?? null;
let currencyFields = currency_id
? ",currency_id='"+currency_id+"',rate_snapshot=(select rate from tbl_currency where _idx='"+currency_id+"' and isdeleted=0 limit 1)"
: ",currency_id=NULL,rate_snapshot=NULL";
let qry = "update tbl_budgetcapexinfo "; let qry = "update tbl_budgetcapexinfo ";
qry = qry +"set idxbudgettype='"+idxbudgettype+"', budgetid='"+budgetid+"',activityname='"+activityname+"',amount='"+amount+"',months='"+months+"',"; qry = qry +"set idxbudgettype='"+idxbudgettype+"', budgetid='"+budgetid+"',activityname='"+activityname+"',amount='"+amount+"',months='"+months+"',";
qry = qry +"targetrfs='"+targetrfs+"',years='"+years+"', uby='"+nik+"',udt=now() "; qry = qry +"targetrfs='"+targetrfs+"',years='"+years+"'"+currencyFields+", uby='"+nik+"',udt=now() ";
qry = qry +"where _idx='"+id+"'"; qry = qry +"where _idx='"+id+"'";
// console.log(qry); // console.log(qry);
@ -282,11 +298,16 @@ class BudgetAdapter extends Adapter{
let targetrfs = req.body.targetrfs; let targetrfs = req.body.targetrfs;
let crdb = "K"; let crdb = "K";
let nik = req.body.nik; let nik = req.body.nik;
let currency_id = req.body.currency_id ?? null;
let currencyFieldsReq = currency_id
? ",currency_id='"+currency_id+"',rate_snapshot=(select rate from tbl_currency where _idx='"+currency_id+"' and isdeleted=0 limit 1)"
: ",currency_id=NULL,rate_snapshot=NULL";
let qry = "insert into tbl_requestbudget "; let qry = "insert into tbl_requestbudget ";
qry = qry +"set trxid='"+trxid+"',justificationnumber='"+justificationnumber+"',yearstgt='"+yearstgt+"',transactiondate='"+transactiondate+"',idxbudgettype='"+idxbudgettype+"',budgettype='"+budgettype+"',"; qry = qry +"set trxid='"+trxid+"',justificationnumber='"+justificationnumber+"',yearstgt='"+yearstgt+"',transactiondate='"+transactiondate+"',idxbudgettype='"+idxbudgettype+"',budgettype='"+budgettype+"',";
qry = qry +"idxbudgetid='"+idxbudgetid+"',budgetid='"+budgetid+"',activityname='"+activityname+"',idcoa='"+idcoa+"',glacc='"+glacc+"',targetrfs='"+targetrfs+"',"; qry = qry +"idxbudgetid='"+idxbudgetid+"',budgetid='"+budgetid+"',activityname='"+activityname+"',idcoa='"+idcoa+"',glacc='"+glacc+"',targetrfs='"+targetrfs+"',";
qry = qry +"amount='"+amount+"',crdb='"+crdb+"',months=month(now()),years=year(now()), iby='"+nik+"',idt=now()"; qry = qry +"amount='"+amount+"',crdb='"+crdb+"'"+currencyFieldsReq+",months=month(now()),years=year(now()), iby='"+nik+"',idt=now()";
// console.log(qry); // console.log(qry);
db.query(qry,[],function(err,result,fields){ db.query(qry,[],function(err,result,fields){
@ -366,10 +387,15 @@ class BudgetAdapter extends Adapter{
let nik = req.body.nik; let nik = req.body.nik;
let idreqbudget = req.body.idreqbudget; let idreqbudget = req.body.idreqbudget;
let currency_id_upd = req.body.currency_id ?? null;
let currencyFieldsUpd = currency_id_upd
? ",currency_id='"+currency_id_upd+"',rate_snapshot=(select rate from tbl_currency where _idx='"+currency_id_upd+"' and isdeleted=0 limit 1)"
: ",currency_id=NULL,rate_snapshot=NULL";
let qry = "update tbl_requestbudget "; let qry = "update tbl_requestbudget ";
qry = qry +"set trxid='"+trxid+"',yearstgt='"+yearstgt+"',transactiondate='"+transactiondate+"',idxbudgettype='"+idxbudgettype+"',budgettype='"+budgettype+"',"; qry = qry +"set trxid='"+trxid+"',yearstgt='"+yearstgt+"',transactiondate='"+transactiondate+"',idxbudgettype='"+idxbudgettype+"',budgettype='"+budgettype+"',";
qry = qry +"idxbudgetid='"+idxbudgetid+"',budgetid='"+budgetid+"',activityname='"+activityname+"',idcoa='"+idcoa+"',glacc='"+glacc+"',targetrfs='"+targetrfs+"',"; qry = qry +"idxbudgetid='"+idxbudgetid+"',budgetid='"+budgetid+"',activityname='"+activityname+"',idcoa='"+idcoa+"',glacc='"+glacc+"',targetrfs='"+targetrfs+"',";
qry = qry +"amount='"+amount+"',crdb='"+crdb+"',uby='"+nik+"',udt=now() "; qry = qry +"amount='"+amount+"',crdb='"+crdb+"'"+currencyFieldsUpd+",uby='"+nik+"',udt=now() ";
qry = qry +"where _idx='"+idreqbudget+"'"; qry = qry +"where _idx='"+idreqbudget+"'";
// console.log(qry); // console.log(qry);
@ -435,9 +461,13 @@ class BudgetAdapter extends Adapter{
let keyword = req.body.keyword; let keyword = req.body.keyword;
let nik = req.body.nik; let nik = req.body.nik;
let qry = "select * from vw_requestbudget "; let qryBaseRb = "select v.*, r.currency_id, r.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol ";
qry = qry +"where (trim(budgetid) like '%"+ keyword +"%' or trim(activityname) like '%"+ keyword +"%') "; qryBaseRb += "from vw_requestbudget v ";
qry = qry +"and iby='"+nik+"' order by id asc"; qryBaseRb += "left join tbl_requestbudget r on r._idx = v.id ";
qryBaseRb += "left join tbl_currency c on c._idx = r.currency_id ";
qryBaseRb += "where (trim(v.budgetid) like '%"+ keyword +"%' or trim(v.activityname) like '%"+ keyword +"%') ";
qryBaseRb += "and v.iby='"+nik+"' ";
let qry = qryBaseRb + "order by v.id asc";
// console.log(qry); // console.log(qry);
db.query(qry,[],function(err,result,fields){ db.query(qry,[],function(err,result,fields){
@ -459,9 +489,7 @@ class BudgetAdapter extends Adapter{
"totalpage": pagination, "totalpage": pagination,
"totalrows": result.length "totalrows": result.length
}); });
qry = "select * from vw_requestbudget "; qry = qryBaseRb + "order by v.id asc limit " + offset + ", " + limit;
qry = qry +"where (trim(budgetid) like '%"+ keyword +"%' or trim(activityname) like '%"+ keyword +"%') ";
qry = qry +"and iby='"+nik+"' order by id asc limit " + offset + ", " + limit;
db.query(qry,[],function(err,result,fields){ db.query(qry,[],function(err,result,fields){
if(err){ if(err){
apires.meta['message'] = err.toString(); apires.meta['message'] = err.toString();
@ -500,8 +528,11 @@ class BudgetAdapter extends Adapter{
let id = req.query.id; let id = req.query.id;
// console.log(req); // console.log(req);
let qry = "select * from vw_requestbudget "; let qry = "select v.*, r.currency_id, r.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol ";
qry = qry +"where id='"+id+"' order by id asc limit 1"; qry += "from vw_requestbudget v ";
qry += "left join tbl_requestbudget r on r._idx = v.id ";
qry += "left join tbl_currency c on c._idx = r.currency_id ";
qry += "where v.id='"+id+"' order by v.id asc limit 1";
// console.log(qry); // console.log(qry);
db.query(qry,[],function(err,result,fields){ db.query(qry,[],function(err,result,fields){
@ -535,7 +566,26 @@ class BudgetAdapter extends Adapter{
var apires = this.getApiResultDefined(); var apires = this.getApiResultDefined();
try { try {
let qry = "select * from vw_budgetlistbyrequest order by _idx asc"; let qry = `SELECT v.*, b.currency_id, COALESCE(c.rate, 1) AS currency_rate,
c.currency AS currency_code, c.symbol AS currency_symbol,
(v.amount
- COALESCE((
SELECT SUM(rb.amount * COALESCE(rb.rate_snapshot, COALESCE(rc.rate, 1)) / NULLIF(COALESCE(c.rate, 1), 0))
FROM tbl_requestbudget rb
LEFT JOIN tbl_currency rc ON rc._idx = rb.currency_id
WHERE rb.idxbudgetid = v._idx AND rb.crdb = 'K' AND rb.isdeleted = 0
), 0)
+ COALESCE((
SELECT SUM(rb.amount * COALESCE(rb.rate_snapshot, COALESCE(rc.rate, 1)) / NULLIF(COALESCE(c.rate, 1), 0))
FROM tbl_requestbudget rb
LEFT JOIN tbl_currency rc ON rc._idx = rb.currency_id
WHERE rb.idxbudgetid = v._idx AND rb.crdb = 'D' AND rb.isdeleted = 0
), 0)
) AS due_converted
FROM vw_budgetlistbyrequest v
LEFT JOIN tbl_budgetcapexinfo b ON b._idx = v._idx
LEFT JOIN tbl_currency c ON c._idx = b.currency_id
ORDER BY v._idx ASC`;
// console.log(qry); // console.log(qry);
db.query(qry,[],function(err,result,fields){ db.query(qry,[],function(err,result,fields){

327
adapter/currencyadapter.js Normal file
View File

@ -0,0 +1,327 @@
const db = require('../config/dbproc.js');
const Adapter = require('./dbadapter.js');
class CurrencyAdapter extends Adapter {
constructor() {
super();
}
async queryCurrencyList(req, callback) {
var apires = this.getApiResultDefined();
try {
let limit = req.query.limit;
let offset = req.query.offset;
let keyword = req.query.keyword ?? '';
let qryBase = "select _idx, name, currency, symbol, rate from tbl_currency ";
qryBase += "where isdeleted=0 and (name like '%" + keyword + "%' or currency like '%" + keyword + "%') ";
// If no pagination params, return all records directly
if (!limit || !offset) {
db.query(qryBase + "order by currency asc", [], function (err, result, fields) {
if (err) {
apires.meta['message'] = err.toString();
apires.meta['code'] = 500;
callback('err', apires);
} else {
apires.success = true;
apires.data = JSON.parse(JSON.stringify(result));
callback(null, apires);
}
});
return;
}
db.query(qryBase + "order by currency asc", [], function (err, result, fields) {
if (err) {
apires.meta['message'] = err.toString();
apires.meta['code'] = 500;
callback('err', apires);
} else {
if (result.length > 0) {
let pagination = result.length / limit;
if (!Number.isInteger(pagination)) {
pagination = (Math.floor(result.length / limit)) + 1;
}
apires.success = true;
apires.data.push({
"totalpage": pagination,
"totalrows": result.length
});
let qryPage = qryBase + "order by currency asc limit " + offset + ", " + limit;
db.query(qryPage, [], function (err2, result2, fields2) {
if (err2) {
apires.meta['message'] = err2.toString();
apires.meta['code'] = 500;
callback('err', apires);
} else {
apires.data.push({
"results": JSON.parse(JSON.stringify(result2))
});
callback(null, apires);
}
});
} else {
apires.meta.code = 200;
apires.meta.message = "Record Not Found";
callback(null, apires);
}
}
});
} catch (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
callback('error', apires);
}
}
async queryCurrencyDetail(req, callback) {
var apires = this.getApiResultDefined();
try {
let id = req.params.id;
let qry = "select _idx, name, currency, symbol, rate, isdeleted, iby, idt, uby, udt from tbl_currency where _idx='" + id + "' and isdeleted=0";
db.query(qry, [], function (err, result, fields) {
if (err) {
apires.meta['message'] = err.toString();
apires.meta['code'] = 500;
callback('err', apires);
} else {
if (result.length > 0) {
apires.success = true;
apires.data.push({
"results": JSON.parse(JSON.stringify(result))
});
callback(null, apires);
} else {
apires.meta.code = 200;
apires.meta.message = "Record Not Found";
callback(null, apires);
}
}
});
} catch (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
callback('error', apires);
}
}
async queryCurrencyHistory(req, callback) {
var apires = this.getApiResultDefined();
try {
let id = req.params.id;
// get currency_code first, then fetch log
let qryCode = "select currency from tbl_currency where _idx='" + id + "'";
db.query(qryCode, [], function (err, result, fields) {
if (err) {
apires.meta['message'] = err.toString();
apires.meta['code'] = 500;
callback('err', apires);
} else {
if (result.length === 0) {
apires.meta.code = 200;
apires.meta.message = "Record Not Found";
callback(null, apires);
return;
}
let currencyCode = result[0].currency;
let qryLog = "select _idx, currency_code, old_rate, new_rate, source, remark, iby, idt from tbl_currency_log where currency_code='" + currencyCode + "' order by idt desc";
db.query(qryLog, [], function (err2, result2, fields2) {
if (err2) {
apires.meta['message'] = err2.toString();
apires.meta['code'] = 500;
callback('err', apires);
} else {
apires.success = true;
apires.data.push({
"results": JSON.parse(JSON.stringify(result2))
});
callback(null, apires);
}
});
}
});
} catch (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
callback('error', apires);
}
}
async queryCreateCurrency(req, callback) {
var apires = this.getApiResultDefined();
try {
let name = req.body.name;
let currency = req.body.currency;
let symbol = req.body.symbol;
let rate = req.body.rate;
let nik = req.nik;
let qry = "insert into tbl_currency set ";
qry += "name='" + name + "',";
qry += "currency='" + currency + "',";
qry += "symbol='" + symbol + "',";
qry += "rate='" + rate + "',";
qry += "isdeleted=0,";
qry += "iby='" + nik + "',idt=now()";
db.query(qry, [], function (err, result, fields) {
if (err) {
apires.meta['message'] = err.toString();
apires.meta['code'] = 500;
callback('err', apires);
} else {
apires.success = true;
apires.meta.message = "Saved Success";
apires.data = JSON.parse(JSON.stringify(result));
callback(null, apires);
}
});
} catch (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
callback('error', apires);
}
}
async queryUpdateCurrency(req, callback) {
var apires = this.getApiResultDefined();
try {
let id = req.params.id;
let name = req.body.name;
let currency = req.body.currency;
let symbol = req.body.symbol;
let newRate = req.body.rate;
let nik = req.nik;
// fetch current rate to detect change
let qryOld = "select rate, currency from tbl_currency where _idx='" + id + "' and isdeleted=0";
db.query(qryOld, [], function (err, oldResult, fields) {
if (err) {
apires.meta['message'] = err.toString();
apires.meta['code'] = 500;
callback('err', apires);
return;
}
if (oldResult.length === 0) {
apires.meta.code = 200;
apires.meta.message = "Record Not Found";
callback(null, apires);
return;
}
let oldRate = oldResult[0].rate;
let currencyCode = oldResult[0].currency;
let rateChanged = parseFloat(oldRate) !== parseFloat(newRate);
let qryUpdate = "update tbl_currency set ";
qryUpdate += "name='" + name + "',";
qryUpdate += "currency='" + currency + "',";
qryUpdate += "symbol='" + symbol + "',";
qryUpdate += "rate='" + newRate + "',";
qryUpdate += "uby='" + nik + "',udt=now() ";
qryUpdate += "where _idx='" + id + "'";
db.query(qryUpdate, [], function (err2, result2, fields2) {
if (err2) {
apires.meta['message'] = err2.toString();
apires.meta['code'] = 500;
callback('err', apires);
return;
}
if (!rateChanged) {
apires.success = true;
apires.meta.message = "Updated Success";
apires.data = JSON.parse(JSON.stringify(result2));
callback(null, apires);
return;
}
// log the rate change
let qryLog = "insert into tbl_currency_log set ";
qryLog += "currency_code='" + currencyCode + "',";
qryLog += "old_rate='" + oldRate + "',";
qryLog += "new_rate='" + newRate + "',";
qryLog += "source='manual',";
qryLog += "iby='" + nik + "',idt=now()";
db.query(qryLog, [], function (err3, result3, fields3) {
if (err3) {
apires.meta['message'] = err3.toString();
apires.meta['code'] = 500;
callback('err', apires);
} else {
apires.success = true;
apires.meta.message = "Updated Success";
apires.data = JSON.parse(JSON.stringify(result2));
callback(null, apires);
}
});
});
});
} catch (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
callback('error', apires);
}
}
async queryDeleteCurrency(req, callback) {
var apires = this.getApiResultDefined();
try {
let id = req.params.id;
let nik = req.nik;
let qry = "update tbl_currency set isdeleted=1,dby='" + nik + "',ddt=now() where _idx='" + id + "'";
db.query(qry, [], function (err, result, fields) {
if (err) {
apires.meta['message'] = err.toString();
apires.meta['code'] = 500;
callback('err', apires);
} else {
apires.success = true;
apires.meta.message = "Deleted Success";
apires.data = JSON.parse(JSON.stringify(result));
callback(null, apires);
}
});
} catch (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
callback('error', apires);
}
}
// fetch rates for two currency IDs — used for cross-currency conversion
queryCurrencyRates(fromId, toId, callback) {
var apires = this.getApiResultDefined();
let qry = "select _idx, rate from tbl_currency where _idx in ('" + fromId + "','" + toId + "') and isdeleted=0";
db.query(qry, [], function (err, result, fields) {
if (err) {
callback(err, null);
return;
}
var rates = {};
result.forEach(function (row) {
rates[row._idx] = parseFloat(row.rate);
});
if (rates[fromId] === undefined || rates[toId] === undefined) {
callback(new Error('Currency not found'), null);
return;
}
callback(null, { from: rates[fromId], to: rates[toId] });
});
}
// convert amount from one currency to another using USD as pivot
convertAmount(amount, rateFrom, rateTo, callback) {
if (!rateTo || rateTo === 0) {
callback(new Error('Invalid target rate: rate cannot be zero'), null);
return;
}
callback(null, parseFloat(amount) * (rateFrom / rateTo));
}
}
module.exports = CurrencyAdapter;

542
adapter/dashboardadapter.js Normal file
View File

@ -0,0 +1,542 @@
const db = require("../config/dbproc.js");
const Adapter = require("./dbadapter.js");
const libre = require("libreoffice-convert");
libre.convertAsync = require("util").promisify(libre.convert);
class DashboardAdapter extends Adapter {
constructor() {
super();
}
async queryDashboardSummary(req, callback) {
var apires = this.getApiResultDefined();
try {
let nik = req.query.nik || "";
let year = req.query.year || new Date().getFullYear();
let startDate = year + "-01-01";
let endDate = parseInt(year) + 1 + "-01-01";
let qry = `
SELECT
(
SELECT COALESCE(SUM(amount),0)
FROM tbl_requestbudget
WHERE isdeleted = 0 AND years = ? AND tbl_requestbudget.isused = 0
${nik != "" ? " AND iby=?" : ""}
) AS total_requested_budget,
(
SELECT COALESCE(SUM(amount),0)
FROM tbl_budgetcapexinfo
WHERE isdeleted = 0 AND years = ?
${nik != "" ? " AND iby=?" : ""}
) AS total_remaining_budget,
(
SELECT COALESCE(SUM(amount),0)
FROM tbl_justification
WHERE isdeleted = 0
AND idt >= ?
AND idt < ?
${nik != "" ? " AND iby=?" : ""}
) AS total_used_budget
`;
const params = [year];
if (nik != "") {
params.push(nik);
}
params.push(year);
if (nik != "") {
params.push(nik);
}
params.push(startDate);
params.push(endDate);
if (nik != "") {
params.push(nik);
}
db.query(qry, params, (err, budgetResult) => {
if (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
return callback("err", apires);
}
let budget = budgetResult[0];
budget.total_budget =
parseFloat(budget.total_remaining_budget) +
parseFloat(budget.total_requested_budget) +
+parseFloat(budget.total_used_budget);
/* JUSTIFICATION */
let qryJustification = `
SELECT
SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) AS total_approved,
SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) AS total_submitted,
SUM(CASE WHEN status = -1 THEN 1 ELSE 0 END) AS total_draft,
SUM(CASE WHEN status = 2 AND iscreatepr = 1 THEN 1 ELSE 0 END) AS total_created_pr
FROM tbl_justification
WHERE isdeleted = 0
AND idt >= ?
AND idt < ?
${nik != "" ? " AND iby=?" : ""}
`;
const params = [startDate, endDate];
if (nik != "") params.push(nik);
db.query(qryJustification, params, (err, justificationResult) => {
if (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
return callback("err", apires);
}
/* PURCHASE REQUEST */
let qryPR = `
SELECT
SUM(CASE WHEN status in (2,4,5,6,7) THEN 1 ELSE 0 END) AS total_approved,
SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) AS total_submitted
FROM tbl_pr
WHERE isdeleted = 0
AND idt >= ?
AND idt < ?
${nik != "" ? " AND iby=?" : ""}
`;
const params = [startDate, endDate];
if (nik != "") params.push(nik);
db.query(qryPR, params, (err, prResult) => {
if (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
return callback("err", apires);
}
/* PURCHASE ORDER */
let qryPO = `
SELECT
SUM(CASE WHEN status in (3,4,5,6,7) THEN 1 ELSE 0 END) AS total_approved,
SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) AS total_created,
SUM(CASE WHEN status = 2 THEN 1 ELSE 0 END) AS total_bast
FROM tbl_po
WHERE isdeleted = 0
AND idt >= ?
AND idt < ?
${nik != "" ? " AND iby=?" : ""}
`;
const params = [startDate, endDate];
if (nik != "") params.push(nik);
db.query(qryPO, params, (err, poResult) => {
if (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
return callback("err", apires);
}
/* BAST */
let qryBast = `
SELECT
SUM(CASE WHEN (status = 1 and filehandoversign is NOT NULL) THEN 1 ELSE 0 END) AS total_approved_handover,
SUM(CASE WHEN (status = 1 and filehandoversign is NULL) THEN 1 ELSE 0 END) AS total_handovered,
SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) AS total_submitted
FROM tbl_bast
WHERE isdeleted = 0
AND idt >= ?
AND idt < ?
${nik != "" ? " AND iby=?" : ""}
`;
const params = [startDate, endDate];
if (nik != "") params.push(nik);
db.query(qryBast, params, (err, bastResult) => {
if (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
return callback("err", apires);
}
apires.success = true;
apires.data = {
year: year,
justification: justificationResult[0],
purchase_request: prResult[0],
purchase_order: poResult[0],
bast: bastResult[0],
};
if (nik == "") {
apires.data.budget = budget
}
callback(null, apires);
});
});
});
});
});
} catch (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
callback("error", apires);
}
}
async queryBudgetLineChart(req, callback) {
var apires = this.getApiResultDefined();
try {
let year = req.query.year || new Date().getFullYear();
let qry = `
SELECT
SUM(amount) as used_budget,
MONTH(idt) as month
FROM tbl_justification
WHERE isdeleted=0
AND YEAR(idt)=?
GROUP BY MONTH(idt)
`;
db.query(qry, [year], function (err, result) {
if (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
return callback("err", apires);
}
let months = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
let used = new Array(12).fill(0);
result.forEach((r) => {
used[r.month - 1] = r.used_budget;
});
apires.success = true;
apires.data = {
year: year,
months: months,
series: [
{
name: "Used Budget",
data: used,
},
],
};
callback(null, apires);
});
} catch (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
callback("error", apires);
}
}
async queryProcurementStackedChart(req, callback) {
var apires = this.getApiResultDefined();
try {
let nik = req.query.nik || "";
let year = req.query.year || new Date().getFullYear();
let start = year + "-01-01";
let end = parseInt(year) + 1 + "-01-01";
let months = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
let justification = new Array(12).fill(0);
let pr = new Array(12).fill(0);
let po = new Array(12).fill(0);
let bast = new Array(12).fill(0);
// JUSTIFICATION
let qryJustification = `
SELECT MONTH(idt) as month, COUNT(*) total
FROM tbl_justification
WHERE isdeleted=0
AND idt>=? AND idt<? ${nik != "" ? " AND iby=?" : ""}
GROUP BY MONTH(idt)
`;
const params = [start, end];
if (nik != "") params.push(nik);
db.query(qryJustification, params, function (err, result) {
if (result) {
result.forEach((r) => {
justification[r.month - 1] = r.total;
});
}
// PR
let qryPR = `
SELECT MONTH(idt) as month, COUNT(*) total
FROM tbl_pr
WHERE isdeleted=0
AND idt>=? AND idt<? ${nik != "" ? " AND iby=?" : ""}
GROUP BY MONTH(idt)
`;
db.query(qryPR, params, function (err, result) {
if (result) {
result.forEach((r) => {
pr[r.month - 1] = r.total;
});
}
// PO
let qryPO = `
SELECT MONTH(idt) as month, COUNT(*) total
FROM tbl_po
WHERE isdeleted=0
AND idt>=? AND idt<? ${nik != "" ? " AND iby=?" : ""}
GROUP BY MONTH(idt)
`;
db.query(qryPO, params, function (err, result) {
if (result) {
result.forEach((r) => {
po[r.month - 1] = r.total;
});
}
// BAST
let qryBAST = `
SELECT MONTH(idt) as month, COUNT(*) total
FROM tbl_bast
WHERE isdeleted=0
AND idt>=? AND idt<? ${nik != "" ? " AND iby=?" : ""}
GROUP BY MONTH(idt)
`;
db.query(qryBAST, params, function (err, result) {
if (result) {
result.forEach((r) => {
bast[r.month - 1] = r.total;
});
}
apires.success = true;
apires.data = {
year: year,
months: months,
series: [
{name: "Justification", data: justification},
{name: "PR", data: pr},
{name: "PO", data: po},
{name: "BAST", data: bast},
],
};
callback(null, apires);
});
});
});
});
} catch (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
callback("error", apires);
}
}
async queryMonthlyBudgetUtilization(req, callback) {
var apires = this.getApiResultDefined();
try {
let year = req.query.year || new Date().getFullYear();
let qry = `
SELECT
MONTH(idt) as month,
SUM(amount) as used_budget
FROM tbl_justification
WHERE isdeleted=0
AND YEAR(idt)=?
GROUP BY MONTH(idt)
`;
db.query(qry, [year], function (err, result) {
if (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
return callback("err", apires);
}
let months = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
let used = new Array(12).fill(0);
result.forEach((r) => {
used[r.month - 1] = r.used_budget;
});
apires.success = true;
apires.data = {
year: year,
months: months,
series: [
{
name: "Budget Utilization",
data: used,
},
],
};
callback(null, apires);
});
} catch (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
callback("error", apires);
}
}
async querySpendByUnitChart(req, callback) {
var apires = this.getApiResultDefined();
try {
let year = req.query.year || new Date().getFullYear();
let qry = `
SELECT
division,
SUM(amount) as total_used_budget
FROM tbl_justification
WHERE isdeleted = 0
AND idt >= CONCAT(?, '-01-01 00:00:00')
AND idt < CONCAT(? + 1, '-01-01 00:00:00')
AND division IN ('FBP','MarSal','MNO')
GROUP BY division
`;
db.query(qry, [year, year], function (err, result) {
if (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
return callback("err", apires);
}
let divisions = ["MNO", "MarSal", "FBP"];
let values = {
MNO: 0,
MarSal: 0,
FBP: 0,
};
result.forEach((r) => {
values[r.division] = r.total_used_budget;
});
let data = divisions.map((d) => values[d]);
let total = data.reduce((a, b) => a + b, 0);
apires.success = true;
apires.data = {
categories: divisions,
series: [
{
name: "Spend",
data: data,
},
],
total: total,
};
callback(null, apires);
});
} catch (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
callback("error", apires);
}
}
async queryMyTask(req, callback) {
var apires = this.getApiResultDefined();
try {
let nik = req.query.nik;
let qry = `
SELECT *
FROM vw_my_task
WHERE nik = ?
ORDER BY date DESC
LIMIT 50
`;
db.query(qry, [nik], function (err, result) {
if (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
return callback("err", apires);
}
apires.success = true;
apires.data = result;
callback(null, apires);
});
} catch (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
callback("error", apires);
}
}
}
module.exports = DashboardAdapter;

View File

@ -56,7 +56,11 @@ class JustificationAdapter extends Adapter{
let id = req.query.id; let id = req.query.id;
// console.log(req); // console.log(req);
let qry = "select * from vw_requestbudget order by id asc"; let qry = "select v.*, r.currency_id, r.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol, c.name AS currency_name ";
qry += "from vw_requestbudget v ";
qry += "left join tbl_requestbudget r on r._idx = v.id ";
qry += "left join tbl_currency c on c._idx = r.currency_id ";
qry += "order by v.id asc";
// console.log(qry); // console.log(qry);
db.query(qry,[],function(err,result,fields){ db.query(qry,[],function(err,result,fields){
@ -114,12 +118,17 @@ class JustificationAdapter extends Adapter{
let ttd = JSON.parse(req.body.ttd); let ttd = JSON.parse(req.body.ttd);
let status = -1; let status = -1;
let statusdescription = "draft"; let statusdescription = "draft";
let currency_id = req.body.currency_id ?? null;
let currencyFieldsJ = currency_id
? ",currency_id='"+currency_id+"',rate_snapshot=(select rate from tbl_currency where _idx='"+currency_id+"' and isdeleted=0 limit 1)"
: ",currency_id=NULL,rate_snapshot=NULL";
let qry = "insert into tbl_justification "; let qry = "insert into tbl_justification ";
qry = qry +"set idxrequestbudget='"+idxrequestbudget+"', trxid='"+trxid+"',justificationnumber='"+justificationnumber+"',title='"+title+"',division='"+division+"',"; qry = qry +"set idxrequestbudget='"+idxrequestbudget+"', trxid='"+trxid+"',justificationnumber='"+justificationnumber+"',title='"+title+"',division='"+division+"',";
qry = qry +"glacc='"+glacc+"',description='"+description+"',budgettype='"+budgettype+"',amount='"+amount+"',useddate='"+useddate+"',textpurpose='"+textpurpose+"',textintroduce='"+textintroduce+"',"; qry = qry +"glacc='"+glacc+"',description='"+description+"',budgettype='"+budgettype+"',amount='"+amount+"',useddate='"+useddate+"',textpurpose='"+textpurpose+"',textintroduce='"+textintroduce+"',";
qry = qry +"textstrategic='"+textstrategic+"',textbussiness='"+textbussiness+"',textrisk='"+textrisk+"',textfund='"+textfund+"',textrecomendation='"+textrecomendation+"',"; qry = qry +"textstrategic='"+textstrategic+"',textbussiness='"+textbussiness+"',textrisk='"+textrisk+"',textfund='"+textfund+"',textrecomendation='"+textrecomendation+"',";
qry = qry +"textschedule='"+textschedule+"',status='"+status+"',statusdescription='"+statusdescription+"',filedoc='"+filedoc+"',iby='"+nik+"',idt=now()"; qry = qry +"textschedule='"+textschedule+"',status='"+status+"',statusdescription='"+statusdescription+"',filedoc='"+filedoc+"'"+currencyFieldsJ+",iby='"+nik+"',idt=now()";
// console.log(qry); // console.log(qry);
db.query(qry,[],function(err,result,fields){ db.query(qry,[],function(err,result,fields){
if(err){ if(err){
@ -240,12 +249,17 @@ class JustificationAdapter extends Adapter{
let filedocqry = "filedoc='"+filedoc+"',"; let filedocqry = "filedoc='"+filedoc+"',";
if(filename==""){filedocqry="";} if(filename==""){filedocqry="";}
let currency_id_ju = req.body.currency_id ?? null;
let currencyFieldsJU = currency_id_ju
? ",currency_id='"+currency_id_ju+"',rate_snapshot=(select rate from tbl_currency where _idx='"+currency_id_ju+"' and isdeleted=0 limit 1)"
: ",currency_id=NULL,rate_snapshot=NULL";
// console.log(filedocqry); // console.log(filedocqry);
let qry = "update tbl_justification "; let qry = "update tbl_justification ";
qry = qry +"set idxrequestbudget='"+idxrequestbudget+"', trxid='"+trxid+"',justificationnumber='"+justificationnumber+"',title='"+title+"',division='"+division+"',"; qry = qry +"set idxrequestbudget='"+idxrequestbudget+"', trxid='"+trxid+"',justificationnumber='"+justificationnumber+"',title='"+title+"',division='"+division+"',";
qry = qry +"glacc='"+glacc+"',description='"+description+"',budgettype='"+budgettype+"',amount='"+amount+"',useddate='"+useddate+"',textpurpose='"+textpurpose+"',textintroduce='"+textintroduce+"',"; qry = qry +"glacc='"+glacc+"',description='"+description+"',budgettype='"+budgettype+"',amount='"+amount+"',useddate='"+useddate+"',textpurpose='"+textpurpose+"',textintroduce='"+textintroduce+"',";
qry = qry +"textstrategic='"+textstrategic+"',textbussiness='"+textbussiness+"',textrisk='"+textrisk+"',textfund='"+textfund+"',textrecomendation='"+textrecomendation+"',"; qry = qry +"textstrategic='"+textstrategic+"',textbussiness='"+textbussiness+"',textrisk='"+textrisk+"',textfund='"+textfund+"',textrecomendation='"+textrecomendation+"',";
qry = qry +"textschedule='"+textschedule+"',"+filedocqry+"uby='"+nik+"',udt=now() "; qry = qry +"textschedule='"+textschedule+"',"+filedocqry+currencyFieldsJU.substring(1)+",uby='"+nik+"',udt=now() ";
qry = qry +"where _idx='"+idxjustification+"'"; qry = qry +"where _idx='"+idxjustification+"'";
// console.log(qry); // console.log(qry);
@ -687,6 +701,41 @@ class JustificationAdapter extends Adapter{
} }
} }
async queryListCheckedAndApprovedBy(req,callback){
var apires = this.getApiResultDefined();
try {
let qry = "select * from vw_checked_and_approved_by order by id asc";
// console.log(qry);
db.query(qry,[],function(err,result,fields){
if(err){
apires.meta['message'] = err.toString();
apires.meta['code'] = 500;
callback('err',apires);
}
else
{
if(result.length>0){
apires.success = true;
apires.data = JSON.parse(JSON.stringify(result));
}
else{
apires.meta.code = 200;
apires.meta.message = "Record Not Found";
}
callback(null, apires);
}
});
} catch (err) {
apires.meta.code = 500;
apires.meta.message = err.toString();
callback('error',apires);
}
}
async queryJustificationDetail(req,callback){ async queryJustificationDetail(req,callback){
var apires = this.getApiResultDefined(); var apires = this.getApiResultDefined();
@ -694,7 +743,15 @@ class JustificationAdapter extends Adapter{
let _idx= req.query.id; let _idx= req.query.id;
let qry = "select * from vw_justificationdetail where id='"+_idx+"'"; let qry = `SELECT v.*,
r.currency_id AS effective_currency_id,
c.currency AS currency_code,
c.symbol AS currency_symbol,
c.name AS currency_name
FROM vw_justificationdetail v
LEFT JOIN tbl_requestbudget r ON r._idx = v.idxrequestbudget
LEFT JOIN tbl_currency c ON c._idx = r.currency_id
WHERE v.id = '${_idx}'`;
// console.log(qry); // console.log(qry);
db.query(qry,[],function(err,result,fields){ db.query(qry,[],function(err,result,fields){

View File

@ -65,7 +65,14 @@ class PoAdapter extends Adapter {
var apires = this.getApiResultDefined(); var apires = this.getApiResultDefined();
try { try {
let idxpr = req.query.idxpr; let idxpr = req.query.idxpr;
let qry = "select * from vw_poboq where idxpr='" + idxpr + "'"; let qry = "select v.*, " +
"COALESCE(c1.currency, c2.currency, 'USD') AS pr_currency_code, " +
"COALESCE(c1.symbol, c2.symbol, '$') AS pr_currency_symbol " +
"from vw_poboq v " +
"left join tbl_pr p on p._idx = v.idxpr " +
"left join tbl_currency c1 on c1._idx = p.currency_id and c1.isdeleted = 0 " +
"left join tbl_currency c2 on c2.currency = p.curr and c2.isdeleted = 0 " +
"where v.idxpr='" + idxpr + "'";
// console.log(qry); // console.log(qry);
db.query(qry, [], function (err, result, fields) { db.query(qry, [], function (err, result, fields) {
@ -169,6 +176,10 @@ class PoAdapter extends Adapter {
let ratepo = req.body.ratepo; let ratepo = req.body.ratepo;
let migo = req.body.migo; let migo = req.body.migo;
let idxpoold = req.body.idxpoold; let idxpoold = req.body.idxpoold;
let currencyFieldsPo = curr
? ",currency_id=(SELECT _idx FROM tbl_currency WHERE currency='" + curr + "' AND isdeleted=0 LIMIT 1)" +
",rate_snapshot=(SELECT rate FROM tbl_currency WHERE currency='" + curr + "' AND isdeleted=0 LIMIT 1)"
: "";
let qry = ""; let qry = "";
if (idxpoold != idxpo && idxpoold != 0) { if (idxpoold != idxpo && idxpoold != 0) {
@ -231,7 +242,7 @@ class PoAdapter extends Adapter {
status + status +
"',statusdescription='" + "',statusdescription='" +
statusdescription + statusdescription +
"',iby='" + "'" + currencyFieldsPo + ",iby='" +
nik + nik +
"',idt=now()"; "',idt=now()";
if (result.length > 0) { if (result.length > 0) {
@ -245,7 +256,7 @@ class PoAdapter extends Adapter {
vendorid + vendorid +
"',vendorname='" + "',vendorname='" +
vendorname + vendorname +
"',uby='" + "'" + currencyFieldsPo + ",uby='" +
nik + nik +
"',udt=now() "; "',udt=now() ";
qry = qry =
@ -258,7 +269,7 @@ class PoAdapter extends Adapter {
vendorid + vendorid +
"',vendorname='" + "',vendorname='" +
vendorname + vendorname +
"',uby='" + "'" + currencyFieldsPo + ",uby='" +
nik + nik +
"',udt=now() "; "',udt=now() ";
qry = qry + "where _idx='" + idxpo + "' and isdeleted=0"; qry = qry + "where _idx='" + idxpo + "' and isdeleted=0";
@ -561,7 +572,10 @@ class PoAdapter extends Adapter {
apires.meta["code"] = 500; apires.meta["code"] = 500;
callback("err", apires); callback("err", apires);
} else { } else {
qry = "select * from vw_po where _idx='" + idxpo + "'"; qry = "select v.*, po.currency_id, po.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol "
+ "from vw_po v left join tbl_po po on po._idx = v._idx "
+ "left join tbl_currency c on c._idx = po.currency_id "
+ "where v._idx='" + idxpo + "'";
db.query(qry, [], function (err, result1, fields) { db.query(qry, [], function (err, result1, fields) {
if (err) { if (err) {
apires.meta["message"] = err.toString(); apires.meta["message"] = err.toString();
@ -688,7 +702,10 @@ class PoAdapter extends Adapter {
return result3; return result3;
}); });
}); });
qry = "select * from vw_po where _idx='" + idxpo + "'"; qry = "select v.*, po.currency_id, po.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol "
+ "from vw_po v left join tbl_po po on po._idx = v._idx "
+ "left join tbl_currency c on c._idx = po.currency_id "
+ "where v._idx='" + idxpo + "'";
db.query(qry, [], function (err, result1, fields) { db.query(qry, [], function (err, result1, fields) {
if (err) { if (err) {
apires.meta["message"] = err.toString(); apires.meta["message"] = err.toString();
@ -1025,6 +1042,14 @@ class PoAdapter extends Adapter {
"',idxpoboq='" + "',idxpoboq='" +
idxpoboq + idxpoboq +
"',"; "',";
qry += "currency_id=(SELECT COALESCE(c1._idx,c2._idx) FROM tbl_pr p "
+ "LEFT JOIN tbl_currency c1 ON c1._idx=p.currency_id AND c1.isdeleted=0 "
+ "LEFT JOIN tbl_currency c2 ON c2.currency=p.curr AND c2.isdeleted=0 "
+ "WHERE p._idx='" + idxpr + "' LIMIT 1),"
+ "rate_snapshot=(SELECT COALESCE(c1.rate,c2.rate) FROM tbl_pr p "
+ "LEFT JOIN tbl_currency c1 ON c1._idx=p.currency_id AND c1.isdeleted=0 "
+ "LEFT JOIN tbl_currency c2 ON c2.currency=p.curr AND c2.isdeleted=0 "
+ "WHERE p._idx='" + idxpr + "' LIMIT 1),";
qry += "iby='" + nik + "',idt=now()"; qry += "iby='" + nik + "',idt=now()";
// console.log(qry); // console.log(qry);
@ -1053,7 +1078,10 @@ class PoAdapter extends Adapter {
apires.meta["code"] = 500; apires.meta["code"] = 500;
callback("err", apires); callback("err", apires);
} else { } else {
qry = "select * from vw_po where _idx='" + idxpo + "'"; qry = "select v.*, po.currency_id, po.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol "
+ "from vw_po v left join tbl_po po on po._idx = v._idx "
+ "left join tbl_currency c on c._idx = po.currency_id "
+ "where v._idx='" + idxpo + "'";
db.query(qry, [], function (err, result1, fields) { db.query(qry, [], function (err, result1, fields) {
if (err) { if (err) {
apires.meta["message"] = err.toString(); apires.meta["message"] = err.toString();
@ -1112,7 +1140,10 @@ class PoAdapter extends Adapter {
apires.meta["code"] = 500; apires.meta["code"] = 500;
callback("err", apires); callback("err", apires);
} else { } else {
qry = "select * from vw_po where _idx='" + idxpo + "'"; qry = "select v.*, po.currency_id, po.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol "
+ "from vw_po v left join tbl_po po on po._idx = v._idx "
+ "left join tbl_currency c on c._idx = po.currency_id "
+ "where v._idx='" + idxpo + "'";
db.query(qry, [], function (err, result1, fields) { db.query(qry, [], function (err, result1, fields) {
if (err) { if (err) {
apires.meta["message"] = err.toString(); apires.meta["message"] = err.toString();
@ -1180,7 +1211,10 @@ class PoAdapter extends Adapter {
apires.meta["code"] = 500; apires.meta["code"] = 500;
callback("err", apires); callback("err", apires);
} else { } else {
qry = "select * from vw_po where _idx='" + idxpo + "'"; qry = "select v.*, po.currency_id, po.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol "
+ "from vw_po v left join tbl_po po on po._idx = v._idx "
+ "left join tbl_currency c on c._idx = po.currency_id "
+ "where v._idx='" + idxpo + "'";
db.query(qry, [], function (err, result1, fields) { db.query(qry, [], function (err, result1, fields) {
if (err) { if (err) {
apires.meta["message"] = err.toString(); apires.meta["message"] = err.toString();
@ -1316,7 +1350,7 @@ class PoAdapter extends Adapter {
setvalues += setvalues +=
"po.ponumber='" + "po.ponumber='" +
posapnumber + posapnumber +
"po.identifyprojectnumber='" + "',po.identifyprojectnumber='" +
sp3number + sp3number +
"',po.status='" + "',po.status='" +
status + status +
@ -1348,12 +1382,17 @@ class PoAdapter extends Adapter {
console.log(qry); console.log(qry);
db.query(qry, [], function (err, result, fields) { db.query(qry, [], function (err, result, fields) {
console.log("result =>", result);
if (err) { if (err) {
apires.meta["message"] = err.toString(); apires.meta["message"] = err.toString();
apires.meta["code"] = 500; apires.meta["code"] = 500;
callback("err", apires); callback("err", apires);
} else { } else {
qry = "select idxpoboq,ponumber from vw_poboq where idxpoboq in(" + idxpoboq + ")"; qry =
"select idxpoboq,ponumber,identifyprojectnumber from vw_poboq where idxpoboq in(" +
idxpoboq +
")";
console.log("qry", qry);
db.query(qry, [], function (err, result1, fields) { db.query(qry, [], function (err, result1, fields) {
if (err) { if (err) {
apires.meta["message"] = err.toString(); apires.meta["message"] = err.toString();
@ -1361,6 +1400,7 @@ class PoAdapter extends Adapter {
callback("err", apires); callback("err", apires);
} else { } else {
apires.success = true; apires.success = true;
console.log("result1 =>", result1);
apires.data = JSON.parse(JSON.stringify(result1)); apires.data = JSON.parse(JSON.stringify(result1));
callback(null, apires); callback(null, apires);
} }
@ -1643,13 +1683,29 @@ class PoAdapter extends Adapter {
async queryPoManagementList(req, callback) { async queryPoManagementList(req, callback) {
var apires = this.getApiResultDefined(); var apires = this.getApiResultDefined();
try { try {
const proc_nik = process.env.PROC_USER_NIK ?? "";
const proc_users = proc_nik.split(",");
let limit = req.query.limit; let limit = req.query.limit;
let offset = req.query.offset; let offset = req.query.offset;
let keyword = req.query.keyword; let keyword = req.query.keyword;
// let nik = req.body.nik; let nik = req.body.nik;
let qry = "select * from vw_po "; let qryBase = "select v.*, po.currency_id, po.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol ";
qry = qry + "where trim(ponumber) like '%" + keyword + "%' and ponumber<>'000'"; qryBase += "from vw_po v left join tbl_po po on po._idx = v._idx ";
qryBase += "left join tbl_currency c on c._idx = po.currency_id ";
let qry = qryBase;
qry =
qry +
"where trim(v.ponumber) like '%" +
keyword +
"%' and v.ponumber<>'000' and v.status in (2,3,4,5,6)";
if (nik) {
if (!proc_users.includes(nik)) {
qry += ' and (iby="' + nik + ' or nikapproval="' + nik + '")';
}
}
// qry = qry +"order by _idx asc limit " + offset + ", " + limit; // qry = qry +"order by _idx asc limit " + offset + ", " + limit;
// console.log(qry); // console.log(qry);
@ -1670,9 +1726,14 @@ class PoAdapter extends Adapter {
"totalpage": pagination, "totalpage": pagination,
"totalrows": result.length, "totalrows": result.length,
}); });
qry = "select * from vw_po "; qry = qryBase;
qry = qry + "where trim(ponumber) like '%" + keyword + "%' and ponumber<>'000'"; qry = qry + "where trim(v.ponumber) like '%" + keyword + "%' and v.ponumber<>'000' and v.status in (2,3,4,5,6)";
qry = qry + "order by _idx asc limit " + offset + ", " + limit; if (nik) {
if (!proc_users.includes(nik)) {
qry += ' and (iby="' + nik + ' or nikapproval="' + nik + '") ';
}
}
qry = qry + "order by v._idx asc limit " + offset + ", " + limit;
db.query(qry, [], function (err, result, fields) { db.query(qry, [], function (err, result, fields) {
if (err) { if (err) {
apires.meta["message"] = err.toString(); apires.meta["message"] = err.toString();
@ -1702,20 +1763,31 @@ class PoAdapter extends Adapter {
async queryPottdList(req, callback) { async queryPottdList(req, callback) {
var apires = this.getApiResultDefined(); var apires = this.getApiResultDefined();
try { try {
const proc_nik = process.env.PROC_USER_NIK ?? "";
const proc_users = proc_nik.split(",");
let limit = req.query.limit; let limit = req.query.limit;
let offset = req.query.offset; let offset = req.query.offset;
let keyword = req.query.keyword; let keyword = req.query.keyword;
let nik = req.query.nik;
// let nik = req.body.nik; // let nik = req.body.nik;
let qry = "select * from vw_po "; let qryBase = "select v.*, po.currency_id, po.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol ";
qryBase += "from vw_po v left join tbl_po po on po._idx = v._idx ";
qryBase += "left join tbl_currency c on c._idx = po.currency_id ";
let qry = qryBase;
qry = qry =
qry + qry +
"where trim(ponumber) like '%" + "where trim(v.ponumber) like '%" +
keyword + keyword +
"%' and status in(1,6) and ponumber<>'000' and ponumber<>'' "; "%' and v.status in(1,2,3,4,5,6) and v.ponumber<>'000' and v.ponumber<>'' ";
// qry = qry +"order by _idx asc limit " + offset + ", " + limit;
if (nik) {
if (!proc_users.includes(nik)) {
qry += 'and (iby="' + nik + ' or nikapproval="' + nik + '")';
}
}
console.log(qry);
db.query(qry, [], function (err, result, fields) { db.query(qry, [], function (err, result, fields) {
if (err) { if (err) {
apires.meta["message"] = err.toString(); apires.meta["message"] = err.toString();
@ -1733,13 +1805,19 @@ class PoAdapter extends Adapter {
"totalpage": pagination, "totalpage": pagination,
"totalrows": result.length, "totalrows": result.length,
}); });
qry = "select * from vw_po "; qry = qryBase;
qry = qry =
qry + qry +
"where trim(ponumber) like '%" + "where trim(v.ponumber) like '%" +
keyword + keyword +
"%' and status in(1,6) and ponumber<>'000' and ponumber<>'' "; "%' and v.status in(1,2,3,4,5,6) and v.ponumber<>'000' and v.ponumber<>'' ";
qry = qry + "order by _idx asc limit " + offset + ", " + limit; if (nik) {
if (!proc_users.includes(nik)) {
qry += 'and (iby="' + nik + ' or nikapproval="' + nik + '") ';
}
}
qry = qry + "order by v._idx asc limit " + offset + ", " + limit;
db.query(qry, [], function (err, result, fields) { db.query(qry, [], function (err, result, fields) {
if (err) { if (err) {
apires.meta["message"] = err.toString(); apires.meta["message"] = err.toString();
@ -1771,7 +1849,12 @@ class PoAdapter extends Adapter {
try { try {
let _idx = req.query.idxpo; let _idx = req.query.idxpo;
let qry = "select * from vw_po where _idx='" + _idx + "'"; let qry = "select v.*, po.currency_id, po.rate_snapshot, " +
"c.currency AS currency_code, c.symbol AS currency_symbol " +
"from vw_po v " +
"left join tbl_po po on po._idx = v._idx " +
"left join tbl_currency c on c._idx = po.currency_id " +
"where v._idx='" + _idx + "'";
// console.log(qry); // console.log(qry);
db.query(qry, [], function (err, result, fields) { db.query(qry, [], function (err, result, fields) {
@ -1786,12 +1869,36 @@ class PoAdapter extends Adapter {
} else { } else {
let resultJson = JSON.stringify(result); let resultJson = JSON.stringify(result);
resultJson = JSON.parse(resultJson); resultJson = JSON.parse(resultJson);
// PO BOQ
let qry = "select * from vw_poboq where idxpo='" + resultJson[0]._idx + "'";
db.query(qry, [], function (err, result, fields) {
if (err) {
apires.meta["message"] = err.toString();
apires.meta["code"] = 500;
callback("err", apires);
} else {
if (result.length <= 0) {
apires.meta.message = "Record not found";
callback("", apires);
} else {
let resultJsonBoq = JSON.stringify(result);
resultJsonBoq = JSON.parse(resultJsonBoq);
resultJson[0]["boq"] = resultJsonBoq;
apires.success = true; apires.success = true;
apires.data = resultJson; apires.data = resultJson;
callback(null, apires); callback(null, apires);
} }
} }
}); });
// apires.success = true;
// apires.data = resultJson;
// callback(null, apires);
}
}
});
} catch (err) { } catch (err) {
apires.meta.code = 500; apires.meta.code = 500;
apires.meta.message = err.toString(); apires.meta.message = err.toString();
@ -1807,12 +1914,15 @@ class PoAdapter extends Adapter {
let keyword = req.query.keyword; let keyword = req.query.keyword;
// let nik = req.body.nik; // let nik = req.body.nik;
let qry = "select * from vw_po "; let qryBase = "select v.*, po.currency_id, po.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol ";
qryBase += "from vw_po v left join tbl_po po on po._idx = v._idx ";
qryBase += "left join tbl_currency c on c._idx = po.currency_id ";
let qry = qryBase;
qry = qry =
qry + qry +
"where trim(ponumber) like '%" + "where trim(v.ponumber) like '%" +
keyword + keyword +
"%' and status in(2,4) and ponumber<>'000' and ponumber<>'' "; "%' and v.status in(2,4) and v.ponumber<>'000' and v.ponumber<>'' ";
// qry = qry +"order by _idx asc limit " + offset + ", " + limit; // qry = qry +"order by _idx asc limit " + offset + ", " + limit;
// console.log(qry); // console.log(qry);
@ -1833,13 +1943,13 @@ class PoAdapter extends Adapter {
"totalpage": pagination, "totalpage": pagination,
"totalrows": result.length, "totalrows": result.length,
}); });
qry = "select * from vw_po "; qry = qryBase;
qry = qry =
qry + qry +
"where trim(ponumber) like '%" + "where trim(v.ponumber) like '%" +
keyword + keyword +
"%' and status in(2,4) and ponumber<>'000' and ponumber<>'' "; "%' and v.status in(2,4) and v.ponumber<>'000' and v.ponumber<>'' ";
qry = qry + "order by _idx asc limit " + offset + ", " + limit; qry = qry + "order by v._idx asc limit " + offset + ", " + limit;
db.query(qry, [], function (err, result, fields) { db.query(qry, [], function (err, result, fields) {
if (err) { if (err) {
apires.meta["message"] = err.toString(); apires.meta["message"] = err.toString();
@ -1966,7 +2076,10 @@ class PoAdapter extends Adapter {
try { try {
let idxpo = req.query.idxpo || req.body.idxpo; let idxpo = req.query.idxpo || req.body.idxpo;
let qry = "select * from vw_po where _idx='" + idxpo + "'"; let qry = "select v.*, po.currency_id, po.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol "
+ "from vw_po v left join tbl_po po on po._idx = v._idx "
+ "left join tbl_currency c on c._idx = po.currency_id "
+ "where v._idx='" + idxpo + "'";
// console.log(qry); // console.log(qry);
db.query(qry, [], function (err, result, fields) { db.query(qry, [], function (err, result, fields) {
@ -2293,7 +2406,10 @@ class PoAdapter extends Adapter {
let keyword = req.query.keyword; let keyword = req.query.keyword;
let nik = req.query.nik; let nik = req.query.nik;
let qry = "select * from vw_po "; let qryBase = "select v.*, po.currency_id, po.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol ";
qryBase += "from vw_po v left join tbl_po po on po._idx = v._idx ";
qryBase += "left join tbl_currency c on c._idx = po.currency_id ";
let qry = qryBase;
qry = qry =
qry + qry +
"where (trim(ponumber) like '%" + "where (trim(ponumber) like '%" +
@ -2584,6 +2700,8 @@ class PoAdapter extends Adapter {
// var podescription = req.body.podescription; // var podescription = req.body.podescription;
var idxapproval = req.body.idxapproval; var idxapproval = req.body.idxapproval;
var nikapproval = req.body.nikapproval; var nikapproval = req.body.nikapproval;
var approvalname = req.body.approvalname;
var podesc = req.body.podesc;
var nik = req.body.nik; var nik = req.body.nik;
var po_file = filename; var po_file = filename;
// var ttd = JSON.parse(req.body.ttd); // var ttd = JSON.parse(req.body.ttd);
@ -2599,8 +2717,10 @@ class PoAdapter extends Adapter {
"',"; "',";
qry = qry =
qry + qry +
"podescription=contractdescription,idxpoboq='" + "idxpoboq='" +
idxpoboq + idxpoboq +
"',podescription='" +
podesc +
"',units='" + "',units='" +
units + units +
"',totalqty='" + "',totalqty='" +
@ -2629,6 +2749,8 @@ class PoAdapter extends Adapter {
qry + qry +
"nikapproval='" + "nikapproval='" +
nikapproval + nikapproval +
"',approvalname='" +
approvalname +
"',approveddate='" + "',approveddate='" +
podatettd + podatettd +
"',uby='" + "',uby='" +
@ -2636,14 +2758,17 @@ class PoAdapter extends Adapter {
"',udt=now() "; "',udt=now() ";
qry = qry + "where _idx='" + idxpo + "'"; qry = qry + "where _idx='" + idxpo + "'";
// console.log(qry); console.log(qry);
db.query(qry, [], function (err, result, fields) { db.query(qry, [], function (err, result, fields) {
if (err) { if (err) {
apires.meta["message"] = err.toString(); apires.meta["message"] = err.toString();
apires.meta["code"] = 500; apires.meta["code"] = 500;
callback("err", apires); callback("err", apires);
} else { } else {
qry = "select * from vw_po where _idx='" + idxpo + "'"; qry = "select v.*, po.currency_id, po.rate_snapshot, c.currency AS currency_code, c.symbol AS currency_symbol "
+ "from vw_po v left join tbl_po po on po._idx = v._idx "
+ "left join tbl_currency c on c._idx = po.currency_id "
+ "where v._idx='" + idxpo + "'";
db.query(qry, [], function (err, result1, fields) { db.query(qry, [], function (err, result1, fields) {
if (err) { if (err) {
apires.meta["message"] = err.toString(); apires.meta["message"] = err.toString();

File diff suppressed because it is too large Load Diff

View File

@ -211,6 +211,7 @@ class ProcJustificationAdapter extends Adapter {
qryVendor += "name='" + vendor.vendorname + "',"; qryVendor += "name='" + vendor.vendorname + "',";
qryVendor += "address='" + vendor.address + "',"; qryVendor += "address='" + vendor.address + "',";
qryVendor += "phone='" + vendor.phone + "',"; qryVendor += "phone='" + vendor.phone + "',";
qryVendor += vendor.currency_id ? "currency_id='" + vendor.currency_id + "'," : "";
qryVendor += "iby='" + nik + "',idt=now()"; qryVendor += "iby='" + nik + "',idt=now()";
db.query(qryVendor, [], function (errVendor, resultVendor) { db.query(qryVendor, [], function (errVendor, resultVendor) {

View File

@ -7,7 +7,8 @@ const dbcon = mysql.createConnection({
database : process.env.DBHOST, database : process.env.DBHOST,
acquireTimeout: 30000, acquireTimeout: 30000,
insecureAuth: true, insecureAuth: true,
timezone: 'utc' timezone: 'utc',
port : process.env.HOSTPORT ?? 3306
}); });
dbcon.connect(function(err) { dbcon.connect(function(err) {

89
controllers/currency.js Normal file
View File

@ -0,0 +1,89 @@
const CurrencyAdapter = require('../adapter/currencyadapter.js');
const currencyadapter = new CurrencyAdapter();
const Controllers = require('./controller.js');
const controllers = new Controllers();
var apireshandler = controllers.getApiResultDefined();
exports.getCurrencyList = (req, res) => {
try {
currencyadapter.queryCurrencyList(req, function (err, data) {
let statusCode = data != null ? data.meta.code : 200;
if (err) statusCode = 500;
currencyadapter.sendResponse(statusCode, data, res);
});
} catch (err) {
apireshandler.meta.code = 502;
apireshandler.meta.message = "[getCurrencyList] : Currency controller, " + err.toString();
currencyadapter.sendResponse(502, apireshandler, res);
}
}
exports.getCurrencyDetail = (req, res) => {
try {
currencyadapter.queryCurrencyDetail(req, function (err, data) {
let statusCode = data != null ? data.meta.code : 200;
if (err) statusCode = 500;
currencyadapter.sendResponse(statusCode, data, res);
});
} catch (err) {
apireshandler.meta.code = 502;
apireshandler.meta.message = "[getCurrencyDetail] : Currency controller, " + err.toString();
currencyadapter.sendResponse(502, apireshandler, res);
}
}
exports.getCurrencyHistory = (req, res) => {
try {
currencyadapter.queryCurrencyHistory(req, function (err, data) {
let statusCode = data != null ? data.meta.code : 200;
if (err) statusCode = 500;
currencyadapter.sendResponse(statusCode, data, res);
});
} catch (err) {
apireshandler.meta.code = 502;
apireshandler.meta.message = "[getCurrencyHistory] : Currency controller, " + err.toString();
currencyadapter.sendResponse(502, apireshandler, res);
}
}
exports.createCurrency = (req, res) => {
try {
currencyadapter.queryCreateCurrency(req, function (err, data) {
let statusCode = data != null ? data.meta.code : 200;
if (err) statusCode = 500;
currencyadapter.sendResponse(statusCode, data, res);
});
} catch (err) {
apireshandler.meta.code = 502;
apireshandler.meta.message = "[createCurrency] : Currency controller, " + err.toString();
currencyadapter.sendResponse(502, apireshandler, res);
}
}
exports.updateCurrency = (req, res) => {
try {
currencyadapter.queryUpdateCurrency(req, function (err, data) {
let statusCode = data != null ? data.meta.code : 200;
if (err) statusCode = 500;
currencyadapter.sendResponse(statusCode, data, res);
});
} catch (err) {
apireshandler.meta.code = 502;
apireshandler.meta.message = "[updateCurrency] : Currency controller, " + err.toString();
currencyadapter.sendResponse(502, apireshandler, res);
}
}
exports.deleteCurrency = (req, res) => {
try {
currencyadapter.queryDeleteCurrency(req, function (err, data) {
let statusCode = data != null ? data.meta.code : 200;
if (err) statusCode = 500;
currencyadapter.sendResponse(statusCode, data, res);
});
} catch (err) {
apireshandler.meta.code = 502;
apireshandler.meta.message = "[deleteCurrency] : Currency controller, " + err.toString();
currencyadapter.sendResponse(502, apireshandler, res);
}
}

95
controllers/dashboard.js Normal file
View File

@ -0,0 +1,95 @@
const DashboardAdapter = require("../adapter/dashboardadapter.js");
const dashboardAdapter = new DashboardAdapter();
const Controllers = require("../controllers/controller.js");
const controllers = new Controllers();
var apireshandler = controllers.getApiResultDefined();
// var docxConverter = require('docx-pdf');
exports.getDashboardSummary = (req, res) => {
try {
dashboardAdapter.queryDashboardSummary(req, function (err, data) {
let statusCode = data != null ? data.meta.code : 200;
if (err) statusCode = 500;
dashboardAdapter.sendResponse(statusCode, data, res);
});
} catch (err) {
apireshandler.meta.code = 502;
apireshandler.meta.message = "[31] : Dashboard controller, " + err.toString();
dashboardAdapter.sendResponse(502, apireshandler, res);
}
};
exports.getBudgetLineChart = (req, res) => {
try {
dashboardAdapter.queryBudgetLineChart(req, function (err, data) {
let statusCode = data != null ? data.meta.code : 200;
if (err) statusCode = 500;
dashboardAdapter.sendResponse(statusCode, data, res);
});
} catch (err) {
apireshandler.meta.code = 502;
apireshandler.meta.message = "Dashboard controller error : " + err.toString();
dashboardAdapter.sendResponse(502, apireshandler, res);
}
};
exports.getProcurementStackedChart = (req, res) => {
try {
dashboardAdapter.queryProcurementStackedChart(req, function (err, data) {
let statusCode = data != null ? data.meta.code : 200;
if (err) statusCode = 500;
dashboardAdapter.sendResponse(statusCode, data, res);
});
} catch (err) {
apireshandler.meta.code = 502;
apireshandler.meta.message = "Dashboard controller error : " + err.toString();
dashboardAdapter.sendResponse(502, apireshandler, res);
}
};
exports.getMonthlyBudgetUtilization = (req, res) => {
try {
dashboardAdapter.queryMonthlyBudgetUtilization(req, function (err, data) {
let statusCode = data != null ? data.meta.code : 200;
if (err) statusCode = 500;
dashboardAdapter.sendResponse(statusCode, data, res);
});
} catch (err) {
apireshandler.meta.code = 502;
apireshandler.meta.message = "Dashboard controller error : " + err.toString();
dashboardAdapter.sendResponse(502, apireshandler, res);
}
};
exports.getSpendByUnitChart = (req, res) => {
try {
dashboardAdapter.querySpendByUnitChart(req, function (err, data) {
let statusCode = data != null ? data.meta.code : 200;
if (err) statusCode = 500;
dashboardAdapter.sendResponse(statusCode, data, res);
});
} catch (err) {
apireshandler.meta.code = 502;
apireshandler.meta.message = "Dashboard controller error : " + err.toString();
dashboardAdapter.sendResponse(502, apireshandler, res);
}
};
exports.getMyTask = (req, res) => {
try {
dashboardAdapter.queryMyTask(req, function (err, data) {
let statusCode = data != null ? data.meta.code : 200;
if (err) statusCode = 500;
dashboardAdapter.sendResponse(statusCode, data, res);
});
} catch (err) {
apireshandler.meta.code = 502;
apireshandler.meta.message = "Dashboard controller error : " + err.toString();
dashboardAdapter.sendResponse(502, apireshandler, res);
}
};

View File

@ -123,6 +123,21 @@ exports.getListApprovedBy = ( req, res ) => {
} }
} }
exports.getListCheckedAndApprovedBy = ( req, res ) => {
try{
justificationadapter.queryListCheckedAndApprovedBy(req,function(err,data){
let statusCode = data!=null ? data.meta.code : 200 ;
if(err) statusCode = 500;
justificationadapter.sendResponse(statusCode,data, res);
});
}
catch(err){
apireshandler.meta.code = 502;
apireshandler.meta.message = " [75] : Justification controller, " + err.toString();
justificationadapter.sendResponse(502, apireshandler, res);
}
}
exports.deleteJustification = ( req, res ) => { exports.deleteJustification = ( req, res ) => {
try{ try{
justificationadapter.queryDeleteJustification(req,function(err,data){ justificationadapter.queryDeleteJustification(req,function(err,data){

View File

@ -1253,6 +1253,7 @@ exports.submitpoadj = (req, res) => {
exports.uploadPOSAP = (req, res) => { exports.uploadPOSAP = (req, res) => {
try { try {
let status = req.body.status; let status = req.body.status;
console.log('req.body.filename =>', req.body.filename)
let ext = req.body.filename.split(".")[1]; let ext = req.body.filename.split(".")[1];
let filename = req.body.filename + "_" + req.nik + "_" + Date.now() + "." + ext; let filename = req.body.filename + "_" + req.nik + "_" + Date.now() + "." + ext;
@ -1263,14 +1264,12 @@ exports.uploadPOSAP = (req, res) => {
if (err) { if (err) {
poadapter.sendResponse(500, err, res); poadapter.sendResponse(500, err, res);
} else { } else {
console.log('filename', filename)
poadapter.queryUpdatePoHeaderWithFile(req, filename, function (err, resdata) { poadapter.queryUpdatePoHeaderWithFile(req, filename, function (err, resdata) {
console.log("err upload PO =>", err); console.log("err upload PO =>", err);
let statusCode = resdata != null ? resdata.meta.code : 200; let statusCode = resdata != null ? resdata.meta.code : 200;
if (err) { if (err) {
statusCode = 500; statusCode = 500;
poadapter.sendResponse(statusCode, data, res); poadapter.sendResponse(statusCode, resdata, res);
} else { } else {
poadapter.queryUpdateUploadPoNumber(req, "Success Bypass", function (err, data) { poadapter.queryUpdateUploadPoNumber(req, "Success Bypass", function (err, data) {
console.log("err queryUpdateUploadPoNumber =>", err); console.log("err queryUpdateUploadPoNumber =>", err);

View File

@ -107,6 +107,21 @@ exports.getListPr = (req, res) => {
} }
}; };
exports.getListApprovedBy = ( req, res ) => {
try{
pradapter.queryListApprovedBy(req,function(err,data){
let statusCode = data!=null ? data.meta.code : 200 ;
if(err) statusCode = 500;
pradapter.sendResponse(statusCode,data, res);
});
}
catch(err){
apireshandler.meta.code = 502;
apireshandler.meta.message = " [167] : PR controller, " + err.toString();
pradapter.sendResponse(502, apireshandler, res);
}
}
exports.setNewPr = (req, res) => { exports.setNewPr = (req, res) => {
try { try {
pradapter.queryNewPr(req, function (err, data) { pradapter.queryNewPr(req, function (err, data) {

View File

@ -38,7 +38,7 @@ var imageUpload = multer({
cb(null, true); cb(null, true);
} }
} }
}).single("file-doc"); }).single("file");
module.exports = (req, res, next) => { module.exports = (req, res, next) => {
try { try {
imageUpload(req,res, function(err){ imageUpload(req,res, function(err){

13
routes/currency.js Normal file
View File

@ -0,0 +1,13 @@
const express = require('express');
const currencycontroller = require('../controllers/currency');
const jwtauth = require('../middlewares/auth.js');
const router = express.Router();
router.get('/list', [jwtauth], currencycontroller.getCurrencyList);
router.get('/detail/:id', [jwtauth], currencycontroller.getCurrencyDetail);
router.get('/history/:id', [jwtauth], currencycontroller.getCurrencyHistory);
router.post('/create', [jwtauth], currencycontroller.createCurrency);
router.put('/update/:id', [jwtauth], currencycontroller.updateCurrency);
router.delete('/delete/:id', [jwtauth], currencycontroller.deleteCurrency);
module.exports = router;

15
routes/dashboard.js Normal file
View File

@ -0,0 +1,15 @@
const express = require('express');
// const { body } = require('express-validator');
const dashboardController = require('../controllers/dashboard.js');
const jwtauth = require('../middlewares/auth.js');
const router=express.Router();
//=== POST & get METHOD
router.get('/summary',[jwtauth], dashboardController.getDashboardSummary);
router.get('/budget-line',[jwtauth], dashboardController.getBudgetLineChart);
router.get('/procurement-chart',[jwtauth], dashboardController.getProcurementStackedChart);
router.get('/budget-utilization',[jwtauth], dashboardController.getMonthlyBudgetUtilization);
router.get('/spend-by-unit',[jwtauth], dashboardController.getSpendByUnitChart);
router.get("/my-task", dashboardController.getMyTask);
module.exports = router;

View File

@ -10,6 +10,7 @@ router.get('/getlistbudgetrequest',[jwtauth], justificationcontroller.getListBud
router.get('/getlistcreatedby',[jwtauth], justificationcontroller.getListCreatedBy); router.get('/getlistcreatedby',[jwtauth], justificationcontroller.getListCreatedBy);
router.get('/getlistcheckedby',[jwtauth], justificationcontroller.getListCheckedBy); router.get('/getlistcheckedby',[jwtauth], justificationcontroller.getListCheckedBy);
router.get('/getlistapprovedby',[jwtauth], justificationcontroller.getListApprovedBy); router.get('/getlistapprovedby',[jwtauth], justificationcontroller.getListApprovedBy);
router.get('/getlistcheckedandapprovedby',[jwtauth], justificationcontroller.getListCheckedAndApprovedBy);
router.post('/setnewjustification',[jwtauth, uploadfile], justificationcontroller.newJustification); router.post('/setnewjustification',[jwtauth, uploadfile], justificationcontroller.newJustification);
router.post('/deletejustification',[jwtauth], justificationcontroller.deleteJustification); router.post('/deletejustification',[jwtauth], justificationcontroller.deleteJustification);
router.post('/updatejustification',[jwtauth, uploadfile], justificationcontroller.updateJustification); router.post('/updatejustification',[jwtauth, uploadfile], justificationcontroller.updateJustification);

View File

@ -11,6 +11,8 @@ router.get('/getdetailpr',[jwtauth], prcontroller.getDetailPr);
router.get('/getprmanagementlist',[jwtauth], prcontroller.getprmanagementlist); router.get('/getprmanagementlist',[jwtauth], prcontroller.getprmanagementlist);
router.get('/getprmanagementlistdetail',[jwtauth], prcontroller.getprmanagementlistdetail); router.get('/getprmanagementlistdetail',[jwtauth], prcontroller.getprmanagementlistdetail);
router.post('/prlist',[jwtauth], prcontroller.getListPr); router.post('/prlist',[jwtauth], prcontroller.getListPr);
router.get('/getlistapprovedby',[jwtauth], prcontroller.getListApprovedBy);
router.post('/setnewpr',[jwtauth], prcontroller.setNewPr); router.post('/setnewpr',[jwtauth], prcontroller.setNewPr);
router.post('/updatepr',[jwtauth], prcontroller.setUpdatePr); router.post('/updatepr',[jwtauth], prcontroller.setUpdatePr);
router.post('/approvedpr',[jwtauth], prcontroller.approvedPR); router.post('/approvedpr',[jwtauth], prcontroller.approvedPR);