Skip to content

Commit

Permalink
Merge pull request #72 from xeptagondev/develop
Browse files Browse the repository at this point in the history
Sync
  • Loading branch information
mbelinsky committed May 31, 2023
2 parents 6d3bbdc + 1dbc981 commit c8b312b
Show file tree
Hide file tree
Showing 70 changed files with 2,375 additions and 957 deletions.
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ The below diagram demonstrates the the ledger behavior of programme create, auth
- Use `DB_PASSWORD` env variable to change PostgresSQL database password
- Configure system root account email by updating environment variable `ROOT EMAIL`. If the email service is enabled, on the first docker start, this email address will receive a new email with the root user password.
- By default frontend does not show map images on dashboard and programme view. To enable them please update `REACT_APP_MAP_TYPE` env variable to `Mapbox` and add new env variable `REACT_APP_MAPBOXGL_ACCESS_TOKEN` with [MapBox public access token](https://docs.mapbox.com/help/tutorials/get-started-tokens-api/) in web container.
- Add user data
- Update [organisations.csv](./organisations.csv) file to add organisations.
- Update [users.csv](./users.csv) file to add users.
- When updating files keep the header and replace existing dummy data with your data.
- These users and companys add to the system each docker restart.
- Run `docker-compose up -d --build`. This will build and start containers for following services,
- PostgresDB container
- National service
Expand All @@ -187,7 +192,7 @@ The below diagram demonstrates the the ledger behavior of programme create, auth
- Web frontend on http://localhost:3030/
- API Endpoints,
- http://localhost:3000/national#/
- http://localhost:3100/stats#/
- http://localhost:3100/stats#/

<a name="local"></a>
## Run Services Locally
Expand Down Expand Up @@ -293,8 +298,8 @@ Serial Number generation implemented in a separate node module. [Please refer th
| Credit Issuance Serial Number | | |
| Current Status | | Set default : Pending |
| Applicant Type | | Set default : Programme Developer |
| Sector (_sector_) | Yes | Sector |
| Sectoral Scope (_sectoralScope_) | Yes | Set default : 1 if ITMO term does not exist |
| Sector (_sector_) | Yes | [Sector](#itmo-sector-mapping) |
| Sectoral Scope (_sectoralScope_) | Yes | [Sector](#itmo-sector-mapping)|
| Programme Start Date (_startTime_) | Yes | createdAt |
| Programme End Date (_endTime_) | Yes | createdAt + 10 years |
| Geographical Location (Regional) (_geographicalLocation_) | Yes | country _(Name not mentioned as ISO3 or actual name)_ |
Expand All @@ -306,7 +311,7 @@ Serial Number generation implemented in a separate node module. [Please refer th
| Company | | company |
| Company Tax ID (_proponentTaxVatId_) | Yes | company |
| Company Percentage (_proponentPercentage_) | Yes | Set default : 100% |
| Type of Mitigation Action/Activity (_typeOfMitigation_) | Yes | |
| Type of Mitigation Action/Activity (_typeOfMitigation_) | Yes | [Sector](#itmo-sector-mapping) |
| GHGs Covered (_greenHouseGasses_) | Yes | Set default : CO2 |
| Credits Authorised | | Set default : 100 |
| Credits Issued | | Set default : 10 |
Expand All @@ -326,6 +331,15 @@ Serial Number generation implemented in a separate node module. [Please refer th
| energy generation unit | | |
| consumer group | | |

#### <b>ITMO Sector Mapping</b>
|ITMO Sector Field Value|Sector|Sectoral Scope|Type Of Mitigation|
| -- | -- | -- | -- |
|energy-distribution|Energy|Energy Distribution|Energy Distribution
|agriculture|Agriculture|Agriculture|Agriculture|
|energy-industries|Energy|Energy Industry|EE Industry
|Default|Other|Energy Industry|EE Industry


#### <b>Assumptions</b>
- Programme estimated credit amount is 100.
- Programme issued credit amount is always 10.
Expand Down
3 changes: 2 additions & 1 deletion backend/services/.env.dev
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ LOCATION_SERVICE=MAPBOX
ASYNC_OPERATIONS_TYPE=Queue
DISABLE_LOW_PRIORITY_EMAIL=true
ASYNC_QUEUE_NAME=https://sqs.us-east-1.amazonaws.com/302213478610/AsyncQueuedev.fifo
DOMAIN_MAP=true
DOMAIN_MAP=true
EXPIRES_IN=7200
3 changes: 2 additions & 1 deletion backend/services/.env.prod
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ LOCATION_SERVICE=MAPBOX
ASYNC_OPERATIONS_TYPE=Queue
DISABLE_LOW_PRIORITY_EMAIL=true
ASYNC_QUEUE_NAME=https://sqs.us-east-1.amazonaws.com/302213478610/AsyncQueueprod.fifo
DOMAIN_MAP=false
DOMAIN_MAP=false
EXPIRES_IN=7200
2 changes: 1 addition & 1 deletion backend/services/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
"jest": "28.1.3",
"prettier": "^2.3.2",
"serverless": "^3.25.1",
"serverless-offline": "^11.2.3",
"serverless-offline": "^12.0.4",
"serverless-plugin-optimize": "^4.2.1-rc.1",
"serverless-plugin-typescript": "^2.1.4",
"serverless-ssm-fetch": "^2.0.0",
Expand Down
11 changes: 10 additions & 1 deletion backend/services/src/analytics-api/aggregate.api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export class AggregateAPIService {
issuedCredits: [],
transferredCredits: [],
retiredCredits: [],
frozenCredits: [],
};
const groupedDataFiltered = passedResult?.filter(
(item) => String(item.time_group) !== "0"
Expand All @@ -134,6 +135,7 @@ export class AggregateAPIService {
let issuedCreditsSum = 0;
let transferredCreditsSum = 0;
let retiredCreditsSum = 0;
let frozenCreditsSum = 0;
let resultThere: StatusGroupedByTimedataThere = {
awaitingAuthorization: false,
authorised: false,
Expand All @@ -151,11 +153,17 @@ export class AggregateAPIService {
authorisedCreditsSum = authorisedCreditsSum + 0;
}
issuedCreditsSum =
issuedCreditsSum + parseFloat(timeGroupItem?.totalbalancecredit);
issuedCreditsSum +
parseFloat(timeGroupItem?.totalissuedcredit) -
parseFloat(timeGroupItem?.totalretiredcredit) -
parseFloat(timeGroupItem?.totaltxcredit) -
parseFloat(timeGroupItem?.totalfreezecredit);
transferredCreditsSum =
transferredCreditsSum + parseFloat(timeGroupItem?.totaltxcredit);
retiredCreditsSum =
retiredCreditsSum + parseFloat(timeGroupItem?.totalretiredcredit);
frozenCreditsSum =
frozenCreditsSum + parseFloat(timeGroupItem?.totalfreezecredit);
statusArray?.map((status) => {
if (timeGroupItem?.currentStage === status) {
resultThere[this.firstLower(timeGroupItem?.currentStage)] = true;
Expand All @@ -174,6 +182,7 @@ export class AggregateAPIService {
result["issuedCredits"]?.push(issuedCreditsSum);
result["transferredCredits"]?.push(transferredCreditsSum);
result["retiredCredits"]?.push(retiredCreditsSum);
result["frozenCredits"]?.push(frozenCreditsSum);
});

const resultS = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ export class AsyncOperationsDatabaseHandlerService
.select(['"actionId"', '"actionType"', '"actionProps"'])
.getRawMany();

if(notExecutedActions.length === 0)
return;

const startedSeq = lastSeq;
notExecutedActions.forEach((action: any) => {
if (action.actionType === AsyncActionType.Email.toString()) {
const emailBody = JSON.parse(action.actionProps);
Expand All @@ -50,12 +54,16 @@ export class AsyncOperationsDatabaseHandlerService
lastSeq = action.actionId;
});

await Promise.all(asyncPromises);

await this.counterRepo.save({
id: CounterType.ASYNC_OPERATIONS,
counter: lastSeq,
});
try {
await Promise.all(asyncPromises);
await this.counterRepo.save({
id: CounterType.ASYNC_OPERATIONS,
counter: lastSeq,
});
} catch (exception) {
this.logger.log("database asyncHandler failed", exception);
lastSeq = startedSeq;
}
}, 5000);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,19 @@ export class ITMOSystemImporter implements ImporterInterface {
const taxId = project.company;
const company = await this.companyService.findByTaxId(taxId);
if (!company) {

const email = `nce.digital+${project.company}@undp.org`.replace(' ', '');
await this.userService.create(
{
email: `nce.digital+${project.company}@undp.org`,
email: email,
role: Role.Admin,
name: project.company,
phoneNo: "00",
company: {
taxId: taxId,
companyId: undefined,
name: project.company,
email: `nce.digital+${project.company}@undp.org`,
email: email,
phoneNo: "00",
website: undefined,
address: this.configService.get("systemCountryName"),
Expand Down Expand Up @@ -197,9 +199,9 @@ export class ITMOSystemImporter implements ImporterInterface {
creditEst: 100,
};

if ( step.files && step.files.length > 0) {
pr.programmeProperties['programmeMaterials'] = step.files[0]
pr.programmeProperties['projectMaterial'] = step.files[0]
if (step.files && step.files.length > 0) {
pr.programmeProperties["programmeMaterials"] = step.files;
pr.programmeProperties["projectMaterial"] = step.files;
}

await this.programmeService.create(pr);
Expand Down
4 changes: 3 additions & 1 deletion backend/services/src/i18n/en/common.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"addAsyncActionDatabaseFailed": "{} functionality failed when adding to database",
"addAsyncActionQueueFailed": "{} functionality failed when adding to queue"
"addAsyncActionQueueFailed": "{} functionality failed when adding to queue",
"settingsSavedMsg": "Settings saved successfully",
"settingsSaveFailedMsg": "Settings saving failed"
}
4 changes: 3 additions & 1 deletion backend/services/src/i18n/en/programme.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,12 @@
"issuedCreditCantExceedEstCredit": "Programme issued credit amount can not exceed estimated credit amount",
"transferReqRejectSuccess": "The transfer request has been rejected successfully",
"transferReqCancelSuccess": "The international transfer retire request has been cancelled successfully",
"transferCancelSuccess": "The transfer request has been cancelled successfully",
"certifierCanOnlyCertifiy": "Programme certification can perform only by certifier",
"govOrProgrammeOwnerOnlyCreditRetirement": "Credit retirement can initiate only the government or programme owner",
"issuedCreditCannotExceedEstCredit": "Programme issue credit amount can not exceed estimated credit amount",
"organisationDeactivated": "This action is unauthorised due to the deactivation of your organisation. You will now be logged out of the system. Log in again to access the system with view-only permissions.",
"unAuth": "This action is unauthorised",
"companyIsNotTheOwnerOfProg": "Company {} is not an owner company of the programme"
"companyIsNotTheOwnerOfProg": "Company {} is not an owner company of the programme",
"internalErrorCreditFreezing": "Internal error on credit freezing"
}
3 changes: 2 additions & 1 deletion backend/services/src/i18n/en/user.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@
"resetPasswordReqExpired": "Your password resetting request has been expired",
"reqIdFound": "Reset request id found",
"resetEmailSent": "User found, An email was sent",
"invalidCountry": "Country is invalid"
"invalidCountry": "Country is invalid",
"editUserSuccess": "The user account has been updated successfully"
}
68 changes: 39 additions & 29 deletions backend/services/src/ledger-replicator/process.event.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Company } from "../shared/entities/company.entity";
import { Programme } from "../shared/entities/programme.entity";
import { CreditOverall } from "../shared/entities/credit.overall.entity";
import { LocationInterface } from "../shared/location/location.interface";
import { CompanyRole } from "src/shared/enum/company.role.enum";

@Injectable()
export class ProcessEventService {
Expand Down Expand Up @@ -69,7 +70,7 @@ export class ProcessEventService {
programme.statusUpdateTime = programme.txTime;
}
if (
[TxType.ISSUE, TxType.RETIRE, TxType.TRANSFER, TxType.AUTH].includes(
[TxType.ISSUE, TxType.RETIRE, TxType.TRANSFER, TxType.AUTH, TxType.FREEZE, TxType.UNFREEZE].includes(
programme.txType
)
) {
Expand Down Expand Up @@ -143,35 +144,44 @@ export class ProcessEventService {
// }
// }

let updateObj;
if (account) {
if (
company.secondaryAccountBalance &&
company.secondaryAccountBalance[account]
) {
company.secondaryAccountBalance[account]["total"] =
overall.credit;
company.secondaryAccountBalance[account]["count"] += 1;
} else {
company.secondaryAccountBalance = {
account: { total: overall.credit, count: 1 },
};
}
let updateObj;
if (account) {
if (
company.secondaryAccountBalance &&
company.secondaryAccountBalance[account]
) {
company.secondaryAccountBalance[account]["total"] = overall.credit;
company.secondaryAccountBalance[account]["count"] += 1;
} else {
company.secondaryAccountBalance = {
account: { total: overall.credit, count: 1 },
};
}

updateObj = {
secondaryAccountBalance: company.secondaryAccountBalance,
lastUpdateVersion: version,
};
} else {
updateObj = {
creditBalance: overall.credit,
programmeCount:
Number(company.programmeCount) +
(overall.txType == TxType.AUTH ? 1 : 0),
lastUpdateVersion: version,
creditTxTime: [ TxType.ISSUE, TxType.TRANSFER, TxType.RETIRE, TxType.FREEZE, TxType.UNFREEZE ].includes(overall.txType) ? txTime : undefined,
};
}
updateObj = {
secondaryAccountBalance: company.secondaryAccountBalance,
lastUpdateVersion: version,
};
} else {
updateObj = {
creditBalance: overall.credit,
programmeCount:
company.companyRole === CompanyRole.GOVERNMENT
? null
: Number(company.programmeCount) +
(overall.txType == TxType.AUTH ? 1 : 0),
lastUpdateVersion: version,
creditTxTime: [
TxType.ISSUE,
TxType.TRANSFER,
TxType.RETIRE,
TxType.FREEZE,
TxType.UNFREEZE,
].includes(overall.txType)
? txTime
: undefined,
};
}

const response = await this.companyRepo
.update(
Expand Down
14 changes: 14 additions & 0 deletions backend/services/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as setupHandler from "./setup/handler";
import { NationalAPIModule } from "./national-api/national.api.module";
import { buildNestApp } from "./shared/server";
import { join } from "path";
const fs = require("fs");

async function bootstrap() {
let module;
Expand Down Expand Up @@ -42,6 +43,19 @@ async function bootstrap() {

const app = await buildNestApp(module, "/" + httpPath);
if (moduleName == "national-api") {

if (fs.existsSync('organisations.csv')) {
const orgs = await fs.readFileSync("organisations.csv", "utf8");
console.log("Inserting orgs", orgs);
await setupHandler.handler({ type: "IMPORT_ORG", body: orgs });
}

if (fs.existsSync('users.csv')) {
const users = await fs.readFileSync("users.csv", "utf8");
console.log("Inserting users", users);
await setupHandler.handler({ type: "IMPORT_USERS", body: users });
}

const staticPath = join(__dirname, "..", "public");
console.log("Static file path:", staticPath);
app.useStaticAssets(staticPath);
Expand Down
3 changes: 2 additions & 1 deletion backend/services/src/national-api/national.api.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { UserController } from './user.controller';
import { AuthController } from './auth.controller';
import { ProgrammeController } from './programme.controller';
import { UtilModule } from '../shared/util/util.module';
import { SettingsController } from './settings.controller';

@Module({
imports: [
Expand All @@ -35,7 +36,7 @@ import { UtilModule } from '../shared/util/util.module';
CompanyModule,
UtilModule
],
controllers: [ NationalAPIController, UserController, AuthController, CompanyController, ProgrammeController ],
controllers: [ NationalAPIController, UserController, AuthController, CompanyController, ProgrammeController, SettingsController ],
providers: [
NationalAPIService,
Logger
Expand Down
Loading

0 comments on commit c8b312b

Please sign in to comment.