diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index ad70912212..d07d215520 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -1,22 +1,35 @@ -name: Playwright E2E Tests +name: E2E Tests (Playwright + Fineract) on: push: - branches: [main, dev, dev-angular-19] + branches: [main, dev] pull_request: - branches: [main, dev, dev-angular-19] + branches: [main, dev] + +concurrency: + group: e2e-${{ github.ref }} + cancel-in-progress: true jobs: - playwright: - name: Run Playwright Tests + e2e: + name: Playwright E2E runs-on: ubuntu-latest - timeout-minutes: 30 + timeout-minutes: 45 + + env: + CI: true + E2E_BASE_URL: http://localhost:4200 + E2E_FINERACT_URL: https://localhost:8443 + E2E_USERNAME: mifos + E2E_PASSWORD: password + E2E_TENANT_ID: default + NODE_TLS_REJECT_UNAUTHORIZED: '0' steps: - name: Checkout code uses: actions/checkout@v6 - - name: Use Node.js 22x + - name: Use Node.js 24 uses: actions/setup-node@v6 with: node-version: '24.14.0' @@ -28,13 +41,65 @@ jobs: - name: Install Playwright browsers run: npx playwright install --with-deps chromium + - name: Start E2E infrastructure + run: docker compose -f docker-compose.e2e.yml up -d --build + + - name: Wait for PostgreSQL + run: | + timeout 60 bash -c ' + until docker exec e2e-postgres pg_isready -U postgres 2>/dev/null; do + sleep 2 + done + ' + echo "✅ PostgreSQL ready" + + - name: Wait for Fineract backend + run: | + timeout 300 bash -c ' + until docker ps --filter "health=healthy" --filter "name=e2e-fineract" | grep -q healthy; do + echo " … Fineract not healthy yet" + sleep 10 + done + ' + curl -fk --retry 30 --retry-all-errors --connect-timeout 10 --retry-delay 10 \ + https://localhost:8443/fineract-provider/actuator/health + echo "" + echo "✅ Fineract ready" + + - name: Verify Fineract initialization complete + run: | + AUTH_HEADER=$(echo -n "${E2E_USERNAME}:${E2E_PASSWORD}" | base64 | tr -d '\n') + timeout 120 bash -c " + until curl -fsk \ + -H 'Fineract-Platform-TenantId: ${E2E_TENANT_ID}' \ + -H 'Authorization: Basic ${AUTH_HEADER}' \ + https://localhost:8443/fineract-provider/api/v1/offices 2>/dev/null | grep -q 'Head Office'; do + echo ' … waiting for seed data' + sleep 5 + done + " + echo "✅ Fineract initialization complete" + + - name: Wait for web-app + run: | + curl -f --retry 20 --retry-all-errors --connect-timeout 5 --retry-delay 5 \ + http://localhost:4200 > /dev/null 2>&1 + echo "✅ Web-app ready" + - name: Run Playwright tests - run: npx playwright test --reporter=html,github - env: - CI: true - FINERACT_API_URL: https://demo.mifos.community - E2E_USERNAME: mifos - E2E_PASSWORD: password + run: npx playwright test --reporter=html,github --workers=1 + + - name: Dump Docker logs on failure + if: failure() + run: | + echo "=== Fineract ===" + docker logs e2e-fineract --tail 100 2>&1 || true + echo "=== PostgreSQL ===" + docker logs e2e-postgres --tail 50 2>&1 || true + echo "=== Web-App ===" + docker logs e2e-web-app --tail 50 2>&1 || true + echo "=== Memory ===" + docker stats --no-stream || true - name: Upload Playwright report uses: actions/upload-artifact@v7 @@ -51,3 +116,9 @@ jobs: name: test-results path: test-results/ retention-days: 7 + + - name: Tear down E2E infrastructure + if: always() + run: | + docker compose -f docker-compose.e2e.yml down -v --remove-orphans + docker system prune -f diff --git a/.gitignore b/.gitignore index 1d420630c5..95230e8fea 100644 --- a/.gitignore +++ b/.gitignore @@ -69,3 +69,4 @@ src/environments/.env.ts /playwright-report/ /blob-report/ /playwright/.cache/ +/playwright/.auth/ diff --git a/Dockerfile b/Dockerfile index 95c6b2cb5b..220209b564 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,6 +24,8 @@ ENV PATH=/usr/src/app/node_modules/.bin:$PATH ENV PUPPETEER_DOWNLOAD_HOST=$PUPPETEER_DOWNLOAD_HOST_ARG ENV PUPPETEER_CHROMIUM_REVISION=$PUPPETEER_CHROMIUM_REVISION_ARG ENV PUPPETEER_SKIP_DOWNLOAD=$PUPPETEER_SKIP_DOWNLOAD_ARG +ENV CYPRESS_INSTALL_BINARY=0 +ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 COPY ./ /usr/src/app/ diff --git a/config/e2e/fineract.env b/config/e2e/fineract.env new file mode 100644 index 0000000000..58bea3efdd --- /dev/null +++ b/config/e2e/fineract.env @@ -0,0 +1,40 @@ +# Fineract E2E Environment — PostgreSQL-only + +# ── Spring Profiles ── +SPRING_PROFILES_ACTIVE=test,diagnostics + +# ── PostgreSQL Connection (Docker service: "db") ── +FINERACT_HIKARI_DRIVER_SOURCE_CLASS_NAME=org.postgresql.Driver +FINERACT_HIKARI_JDBC_URL=jdbc:postgresql://db:5432/fineract_tenants +FINERACT_HIKARI_USERNAME=postgres +# Well-known Fineract E2E password — intentionally committed, not a secret. +FINERACT_HIKARI_PASSWORD=skdcnwauicn2ucnaecasdsajdnizucawencascdca + +# ── Tenant Database ── +FINERACT_DEFAULT_TENANTDB_HOSTNAME=db +FINERACT_DEFAULT_TENANTDB_PORT=5432 +FINERACT_DEFAULT_TENANTDB_UID=postgres +FINERACT_DEFAULT_TENANTDB_PWD=skdcnwauicn2ucnaecasdsajdnizucawencascdca +FINERACT_DEFAULT_TENANTDB_NAME=fineract_default + +# ── SSL & HTTP ── +FINERACT_SERVER_SSL_ENABLED=true +FINERACT_INSECURE_HTTP_CLIENT=true + +# ── Node Identity ── +FINERACT_NODE_ID=1 + +# ── External Events (no ActiveMQ in E2E) ── +FINERACT_EXTERNAL_EVENTS_ENABLED=false + +# ── HikariCP Pool (tuned for E2E) ── +FINERACT_HIKARI_MINIMUM_IDLE=3 +FINERACT_HIKARI_MAXIMUM_POOL_SIZE=10 + +# ── Data Seeding ── +# INITIALIZATION_ENABLED is NOT a Fineract server env var (it belongs to +# fineract-e2e-tests-runner's Gradle Cucumber runner). Do not set it here. +# +# Liquibase auto-seeds: Head Office, default tenant config, schema. +# Domain data (products, GL accounts, clients) must be seeded via the +# FineractApiClient fixture in test beforeAll hooks. diff --git a/config/e2e/nginx-e2e.conf.template b/config/e2e/nginx-e2e.conf.template new file mode 100644 index 0000000000..1c0459a534 --- /dev/null +++ b/config/e2e/nginx-e2e.conf.template @@ -0,0 +1,25 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + # ${E2E_PROXY_TARGET} is replaced by envsubst; $host/$scheme etc. are + # safe because NGINX_ENVSUBST_FILTER restricts to ^(FINERACT_|MIFOS_|...). + location /fineract-provider/ { + proxy_pass ${E2E_PROXY_TARGET}/fineract-provider/; + proxy_ssl_verify off; + proxy_connect_timeout 30s; + proxy_read_timeout 120s; + } + + location / { + try_files $uri $uri/ /index.html; + } + + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + } +} diff --git a/config/e2e/postgresql-init.sh b/config/e2e/postgresql-init.sh new file mode 100755 index 0000000000..cc29fbafd3 --- /dev/null +++ b/config/e2e/postgresql-init.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# Creates the two databases Fineract requires at first boot. +# POSTGRES_USER (postgres) is the default superuser — no CREATE USER needed. +set -e + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL + CREATE DATABASE fineract_tenants; + CREATE DATABASE fineract_default; +EOSQL + +echo "✓ E2E databases created: fineract_tenants, fineract_default" diff --git a/docker-compose.e2e.yml b/docker-compose.e2e.yml new file mode 100644 index 0000000000..46a8b317ac --- /dev/null +++ b/docker-compose.e2e.yml @@ -0,0 +1,95 @@ +services: + db: + image: postgres:18.3-alpine + container_name: e2e-postgres + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: skdcnwauicn2ucnaecasdsajdnizucawencascdca + PGDATA: /var/lib/postgresql/data/pgdata + volumes: + - ./config/e2e/postgresql-init.sh:/docker-entrypoint-initdb.d/01-init.sh:ro + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U postgres'] + interval: 5s + timeout: 5s + retries: 10 + ports: + - '5432:5432' + mem_limit: 768m + shm_size: 256m + tmpfs: + - /var/lib/postgresql/data + command: > + postgres + -c shared_buffers=128MB + -c work_mem=4MB + -c maintenance_work_mem=64MB + + fineract: + image: apache/fineract:latest + container_name: e2e-fineract + depends_on: + db: + condition: service_healthy + env_file: + - ./config/e2e/fineract.env + environment: + JAVA_TOOL_OPTIONS: >- + -Xmx1536m -Xms512m + -XX:+UseG1GC -XX:MaxGCPauseMillis=200 + -Djava.security.egd=file:/dev/./urandom + healthcheck: + test: + [ + 'CMD-SHELL', + 'wget -qO- --no-check-certificate https://localhost:8443/fineract-provider/actuator/health || exit 1' + ] + interval: 10s + timeout: 10s + retries: 60 + start_period: 120s + ports: + - '8443:8443' + mem_limit: 2g + + web-app: + build: + context: . + dockerfile: Dockerfile + args: + PUPPETEER_SKIP_DOWNLOAD_ARG: 'true' + container_name: e2e-web-app + depends_on: + fineract: + condition: service_healthy + environment: + # Nginx proxy target (internal docker DNS) + E2E_PROXY_TARGET: https://fineract:8443 + + # Angular app configuration (resolved by host browser via proxy) + FINERACT_API_URLS: '' + FINERACT_API_URL: '' + + FINERACT_API_PROVIDER: /fineract-provider/api + FINERACT_API_VERSION: /v1 + FINERACT_PLATFORM_TENANT_IDENTIFIER: default + MIFOS_DEFAULT_LANGUAGE: en-US + MIFOS_SUPPORTED_LANGUAGES: en-US + MIFOS_PRELOAD_CLIENTS: 'false' + MIFOS_DEFAULT_CHAR_DELIMITER: ',' + NGINX_ENVSUBST_FILTER: '^(FINERACT_|MIFOS_|ENABLE_|EXTERNAL_|E2E_PROXY_TARGET)' + volumes: + - ./config/e2e/nginx-e2e.conf.template:/etc/nginx/templates/default.conf.template:ro + ports: + - '4200:80' + mem_limit: 256m + # Override CMD: Dockerfile's /bin/sh CMD causes the nginx entrypoint to + # skip template processing (it checks $1 == "nginx"). Process both + # templates explicitly. Only substitute $E2E_PROXY_TARGET in the nginx + # template so $host, $scheme, $uri etc. are left for nginx. + command: >- + /bin/sh -c " + envsubst '$$E2E_PROXY_TARGET' < /etc/nginx/templates/default.conf.template > /etc/nginx/conf.d/default.conf && + envsubst < /usr/share/nginx/html/assets/env.template.js > /usr/share/nginx/html/assets/env.js && + nginx -g 'daemon off;' + " diff --git a/package-lock.json b/package-lock.json index fc4926f4bf..2523fd9f8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,7 +42,7 @@ "jspdf": "^4.2.1", "jspdf-autotable": "^5.0.2", "lightgallery": "^2.9.0", - "lodash": "4.17.23", + "lodash": "4.18.1", "minimatch": "^3.1.4", "moment": "^2.29.4", "ngx-mat-select-search": "^8.0.2", @@ -17690,9 +17690,9 @@ } }, "node_modules/lodash": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", - "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, "node_modules/lodash.debounce": { diff --git a/package.json b/package.json index 8e3657d62d..c9dbfbfaab 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,11 @@ "playwright:ui": "playwright test --ui", "playwright:headed": "playwright test --headed", "playwright:debug": "playwright test --debug", + "playwright:ci": "playwright test --reporter=html,github --workers=1", + "e2e:docker": "bash scripts/e2e-docker.sh", + "e2e:docker:up": "docker compose -f docker-compose.e2e.yml up -d --build", + "e2e:docker:down": "docker compose -f docker-compose.e2e.yml down -v --remove-orphans", + "e2e:docker:logs": "docker compose -f docker-compose.e2e.yml logs -f", "headers:check": "node scripts/check-file-headers.js", "headers:add": "node scripts/add-file-headers.js" }, @@ -69,7 +74,7 @@ "jspdf": "^4.2.1", "jspdf-autotable": "^5.0.2", "lightgallery": "^2.9.0", - "lodash": "4.17.23", + "lodash": "4.18.1", "minimatch": "^3.1.4", "moment": "^2.29.4", "ngx-mat-select-search": "^8.0.2", diff --git a/playwright.config.ts b/playwright.config.ts index 4336c65b77..9d088d4d8f 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -18,6 +18,7 @@ import { defineConfig, devices } from '@playwright/test'; * @see https://playwright.dev/docs/test-configuration */ export default defineConfig({ + globalSetup: process.env.CI ? './playwright/global-setup.ts' : undefined, // Test directory testDir: './playwright/tests', @@ -43,8 +44,8 @@ export default defineConfig({ // Global test settings use: { - // Base URL for the Angular app - baseURL: 'http://localhost:4200', + // Base URL for the Angular app (aligned with global-setup.ts and configurable via env for CI) + baseURL: process.env.E2E_BASE_URL || 'http://localhost:4200', // Handle self-signed certificates from Fineract backend ignoreHTTPSErrors: true, @@ -73,33 +74,34 @@ export default defineConfig({ // Global test timeout (per test) timeout: process.env.CI ? 180000 : 120000, - // Configure projects for different browsers + // Configure projects for authentication setup and browser testing projects: [ + { + name: 'setup', + testMatch: /.*\.setup\.ts/, + testDir: './playwright', + retries: process.env.CI ? 2 : 0 + }, { name: 'chromium', use: { ...devices['Desktop Chrome'], + storageState: 'playwright/.auth/user.json', // Launch options for handling SSL in headed mode launchOptions: { args: ['--ignore-certificate-errors'] } - } + }, + dependencies: ['setup'] } ], - // Web server configuration - // In CI: builds production bundle, then serves it with e2e-server.js - // (Express + http-proxy-middleware for /fineract-provider/* proxy) - // Locally: reuses existing ng serve if running - webServer: { - command: process.env.CI ? 'npm run build && node playwright/e2e-server.js' : 'npm run start', - url: 'http://localhost:4200', - reuseExistingServer: !process.env.CI, - timeout: 180000, - // Add retry logic for server startup - ...(process.env.CI && { - stdout: 'pipe', - stderr: 'pipe' - }) - } + webServer: process.env.CI + ? undefined + : { + command: 'npm run start', + url: 'http://localhost:4200', + reuseExistingServer: true, + timeout: 180000 + } }); diff --git a/playwright/README.md b/playwright/README.md index 3e474eb252..168a2bb4bc 100644 --- a/playwright/README.md +++ b/playwright/README.md @@ -1,44 +1,54 @@ -# Playwright E2E Testing +# Playwright E2E Testing Production-grade End-to-End testing infrastructure for Mifos® X Web App using [Playwright](https://playwright.dev/). -## Prerequisites +## Running E2E with Docker (Full Stack) -Before running the tests, ensure the local environment is running: +### One-command (recommended) -1. **Backend:** Ensure Apache Fineract® is running on `https://localhost:8443` -2. **Frontend:** Serve the Angular app: - ```bash - ng serve - ``` +```bash +npm run e2e:docker # All tests +npm run e2e:docker -- --grep login # Filter by name +npm run e2e:docker -- --headed # See the browser +npm run e2e:docker -- --debug # Step through +``` -## Quick Start +### Manual control (debugging infrastructure) ```bash -# Run all tests -npm run playwright - -# Run with UI mode (recommended for debugging) -npm run playwright:ui +npm run e2e:docker:up # Start stack (Postgres + Fineract + Nginx) +npm run e2e:docker:logs # Watch logs (separate terminal) +npm run playwright # Run tests +npm run e2e:docker:down # Tear down +``` -# Run with visible browser -npm run playwright:headed +## Running Locally (without Docker) -# Debug mode (step through tests) -npm run playwright:debug -``` +1. **Backend:** Ensure Apache Fineract® is running on `https://localhost:8443` +2. **Frontend:** Serve the Angular app: + ```bash + npm run start + ``` +3. **Run tests:** + ```bash + npm run playwright + ``` ## Architecture This framework follows the **Page Object Model (POM)** pattern: -``` +```text playwright/ +├── fixtures/ +│ ├── fineract-api.ts # Typed Fineract REST client for data seeding +│ └── test-fixtures.ts # test.extend with fineractApi fixture +├── global-setup.ts # CI-only: validates backend connectivity ├── pages/ -│ ├── BasePage.ts # Abstract base class with common utilities -│ └── LoginPage.ts # Login page object +│ ├── BasePage.ts # Abstract base class with common utilities +│ └── LoginPage.ts # Login page object └── tests/ - └── login.spec.ts # Login smoke tests + └── login.spec.ts # Login smoke tests ``` ### Design Principles @@ -50,6 +60,29 @@ playwright/ | **Maintainability** | Centralized locators per page | | **CI/CD Optimization** | Artifacts only on failure | +## Data Seeding Strategy + +Fineract auto-seeds via Liquibase at boot: + +- Head Office, default tenant config, schema structure + +For domain-specific test data (clients, loans, savings), seed via API fixtures: + +```typescript +import { test } from '../fixtures/test-fixtures'; + +test.beforeAll(async ({ fineractApi }) => { + await fineractApi.createClient({ + officeId: 1, + firstname: 'Test', + lastname: 'Client' + // ... required Fineract fields + }); +}); +``` + +See `playwright/fixtures/fineract-api.ts` for all available methods. + ## Configuration ### SSL Certificate Handling diff --git a/playwright/auth.setup.ts b/playwright/auth.setup.ts new file mode 100644 index 0000000000..c869df453e --- /dev/null +++ b/playwright/auth.setup.ts @@ -0,0 +1,53 @@ +/** + * Copyright since 2025 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +import { test as setup, expect } from '@playwright/test'; +import fs from 'fs'; +import path from 'path'; +import { LoginPage } from './pages/login.page'; + +const authFile = 'playwright/.auth/user.json'; + +setup('authenticate', async ({ page, browser }) => { + const authPath = path.resolve(authFile); + const authDir = path.dirname(authPath); + if (!fs.existsSync(authDir)) { + fs.mkdirSync(authDir, { recursive: true }); + } + if (fs.existsSync(authPath)) { + fs.unlinkSync(authPath); + } + + const username = process.env.E2E_USERNAME || 'mifos'; + const password = process.env.E2E_PASSWORD || 'password'; + + const loginPage = new LoginPage(page); + await loginPage.navigate(); + await loginPage.loginAndWaitForDashboard(username, password); + + console.log('Auth setup: copying mifosXCredentials from sessionStorage → localStorage'); + const credsCopied = await page.evaluate(() => { + const creds = sessionStorage.getItem('mifosXCredentials'); + if (!creds) return false; + localStorage.setItem('mifosXCredentials', creds); + return true; + }); + + if (!credsCopied) { + throw new Error('CRITICAL: mifosXCredentials not found in sessionStorage. ' + 'Did the auth storage key change?'); + } + + await page.context().storageState({ path: authFile }); + console.log('Auth setup: storageState saved to', authFile); + + const verifyContext = await browser.newContext({ storageState: authFile }); + const verifyPage = await verifyContext.newPage(); + await verifyPage.goto('/#/'); + await expect(verifyPage).not.toHaveURL(/.*login.*/, { timeout: 30000 }); + await verifyContext.close(); + console.log('Auth setup: storageState verification passed ✓'); +}); diff --git a/playwright/fixtures/fineract-api.ts b/playwright/fixtures/fineract-api.ts new file mode 100644 index 0000000000..aa0d21f0f2 --- /dev/null +++ b/playwright/fixtures/fineract-api.ts @@ -0,0 +1,76 @@ +/** + * Copyright since 2025 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { APIRequestContext, APIResponse, request } from '@playwright/test'; + +export class FineractApiClient { + private ctx!: APIRequestContext; + + constructor( + private baseUrl: string, + private tenantId: string, + private username: string, + private password: string + ) {} + + async init(): Promise { + this.ctx = await request.newContext({ + baseURL: this.baseUrl, + ignoreHTTPSErrors: true, + extraHTTPHeaders: { + 'Fineract-Platform-TenantId': this.tenantId, + Authorization: `Basic ${Buffer.from(`${this.username}:${this.password}`).toString('base64')}`, + 'Content-Type': 'application/json' + } + }); + } + + private async validateResponse(res: APIResponse, operation: string): Promise { + if (!res.ok()) { + throw new Error(`Fineract API error [${operation}]: ${res.status()} ${res.statusText()}`); + } + return res.json(); + } + + async healthCheck(): Promise { + const res = await this.ctx.get('/fineract-provider/actuator/health'); + return res.ok(); + } + + async getOffices(): Promise { + const res = await this.ctx.get('/fineract-provider/api/v1/offices'); + return this.validateResponse(res, 'getOffices'); + } + + async createClient(data: Record): Promise { + const res = await this.ctx.post('/fineract-provider/api/v1/clients', { data }); + return this.validateResponse(res, 'createClient'); + } + + /** + * Creates a savings account. + * @param overrides Must include mandatory Fineract fields: + * submittedOnDate, dateFormat, locale, nominalAnnualInterestRate, + * interestCompoundingPeriodType, interestPostingPeriodType, + * interestCalculationType, interestCalculationDaysInYearType + */ + async createSavingsAccount( + clientId: number, + productId: number, + overrides: Record = {} + ): Promise { + const res = await this.ctx.post('/fineract-provider/api/v1/savingsaccounts', { + data: { ...overrides, clientId, productId } + }); + return this.validateResponse(res, 'createSavingsAccount'); + } + + async dispose(): Promise { + await this.ctx?.dispose(); + } +} diff --git a/playwright/fixtures/test-fixtures.ts b/playwright/fixtures/test-fixtures.ts new file mode 100644 index 0000000000..fc01f35aab --- /dev/null +++ b/playwright/fixtures/test-fixtures.ts @@ -0,0 +1,31 @@ +/** + * Copyright since 2025 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { test as base } from '@playwright/test'; + +import { FineractApiClient } from './fineract-api'; + +type E2EFixtures = { + fineractApi: FineractApiClient; +}; + +export const test = base.extend({ + fineractApi: async ({}, use) => { + const api = new FineractApiClient( + process.env.E2E_FINERACT_URL || 'https://localhost:8443', + process.env.E2E_TENANT_ID || 'default', + process.env.E2E_USERNAME || 'mifos', + process.env.E2E_PASSWORD || 'password' + ); + await api.init(); + await use(api); + await api.dispose(); + } +}); + +export { expect } from '@playwright/test'; diff --git a/playwright/global-setup.ts b/playwright/global-setup.ts new file mode 100644 index 0000000000..264ef60d42 --- /dev/null +++ b/playwright/global-setup.ts @@ -0,0 +1,43 @@ +/** + * Copyright since 2025 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +import { request } from '@playwright/test'; + +async function globalSetup(): Promise { + const fineractUrl = process.env.E2E_FINERACT_URL || 'https://localhost:8443'; + const webAppUrl = process.env.E2E_BASE_URL || 'http://localhost:4200'; + + const ctx = await request.newContext({ ignoreHTTPSErrors: true }); + + try { + const fineractRes = await ctx.get(`${fineractUrl}/fineract-provider/actuator/health`, { + timeout: 15000 + }); + if (!fineractRes.ok()) { + throw new Error(`Fineract returned ${fineractRes.status()} at ${fineractUrl}`); + } + + const webAppRes = await ctx.get(webAppUrl, { timeout: 15000 }); + if (!webAppRes.ok()) { + throw new Error(`Web-app returned ${webAppRes.status()} at ${webAppUrl}`); + } + + console.log('✅ Global setup: Fineract + web-app verified'); + } catch (error) { + throw new Error( + `FATAL: E2E infrastructure unreachable.\n` + + `Fineract: ${fineractUrl}\nWeb-app: ${webAppUrl}\n` + + `Run: docker compose -f docker-compose.e2e.yml up -d\n` + + `Error: ${error}` + ); + } finally { + await ctx.dispose(); + } +} + +export default globalSetup; diff --git a/playwright/tests/authenticated-smoke.spec.ts b/playwright/tests/authenticated-smoke.spec.ts new file mode 100644 index 0000000000..03dcb892bd --- /dev/null +++ b/playwright/tests/authenticated-smoke.spec.ts @@ -0,0 +1,29 @@ +/** + * Copyright since 2025 Mifos Initiative + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +import { test, expect } from '@playwright/test'; +test.describe('Authenticated Smoke Tests', () => { + test.beforeEach(async ({ page }) => { + // Playwright storageState only restores localStorage and cookies. + // The Fineract web app expects credentials in sessionStorage. + // We injected credentials into localStorage during auth.setup.ts, + // so we must restore them to sessionStorage before the page runs. + await page.addInitScript(() => { + const creds = localStorage.getItem('mifosXCredentials'); + if (creds) { + sessionStorage.setItem('mifosXCredentials', creds); + } + }); + }); + + test('should load dashboard without login redirect', async ({ page }) => { + await page.goto('/#/'); + + await expect(page).not.toHaveURL(/.*login.*/, { timeout: 30000 }); + await expect(page.locator('mat-toolbar')).toBeVisible({ timeout: 10000 }); + }); +}); diff --git a/playwright/tests/login-responsive.spec.ts b/playwright/tests/login-responsive.spec.ts index 6e4ab1cde5..644fc68fbd 100644 --- a/playwright/tests/login-responsive.spec.ts +++ b/playwright/tests/login-responsive.spec.ts @@ -1,4 +1,4 @@ -/** +/** * Copyright since 2025 Mifos Initiative * * This Source Code Form is subject to the terms of the Mozilla Public @@ -8,6 +8,8 @@ import { test, expect } from '@playwright/test'; import { LoginPage } from 'playwright/pages/login.page'; +test.use({ storageState: { cookies: [], origins: [] } }); + /** * Login Responsive Layout Tests * @@ -209,7 +211,7 @@ test.describe('Login Page - Responsive Layout', () => { for (const viewport of viewports) { await page.setViewportSize(viewport); - await page.goto('http://localhost:4200/login'); + await page.goto('/#/login'); await page.waitForLoadState('networkidle'); // Check no horizontal scroll diff --git a/playwright/tests/login.spec.ts b/playwright/tests/login.spec.ts index adc25b2022..8b8b00cb45 100644 --- a/playwright/tests/login.spec.ts +++ b/playwright/tests/login.spec.ts @@ -8,6 +8,7 @@ import { test, expect } from '@playwright/test'; import { LoginPage } from '../pages/login.page'; +test.use({ storageState: { cookies: [], origins: [] } }); /** * Login Smoke Tests @@ -68,8 +69,6 @@ test.describe('Login Page', () => { }); test('should successfully login with valid credentials', async () => { - test.skip(!!process.env.CI, 'Production build auth interceptor skips tenant header for absolute URLs'); - // Perform login with valid credentials // This uses the login() method which follows the exact codegen sequence await loginPage.loginAndWaitForDashboard('mifos', 'password'); @@ -82,12 +81,8 @@ test.describe('Login Page', () => { // Attempt login with wrong password await loginPage.login('mifos', 'wrongpassword'); - // Wait for the login attempt to process and any error notification to appear - // The app shows a snackbar notification for authentication errors - await page.waitForTimeout(3000); - - // Should remain on login page after failed attempt (URL still contains /login) - await expect(page).toHaveURL(/.*login.*/); + // Should remain on login page after failed attempt + await expect(page).toHaveURL(/.*login.*/, { timeout: 10000 }); // Verify we're still on the login page by checking form elements are visible await expect(loginPage.usernameInput).toBeVisible(); @@ -99,8 +94,6 @@ test.describe('Login Page', () => { * This is the baseline test generated from codegen. */ test('codegen baseline: login with mifos credentials', async () => { - test.skip(!!process.env.CI, 'Production build auth interceptor skips tenant header for absolute URLs'); - // This test uses the exact codegen interaction sequence await loginPage.login('mifos', 'password'); diff --git a/scripts/e2e-docker.sh b/scripts/e2e-docker.sh new file mode 100755 index 0000000000..a0f6ae9db1 --- /dev/null +++ b/scripts/e2e-docker.sh @@ -0,0 +1,76 @@ +#!/usr/bin/env bash +# E2E Docker Runner — boots Fineract stack, runs Playwright, tears down. +# +# Usage: +# npm run e2e:docker # Run all tests +# npm run e2e:docker -- --grep login # Filter tests +# npm run e2e:docker -- --headed # See the browser +# npm run e2e:docker -- --debug # Step through +set -euo pipefail + +# GNU timeout is required (not available by default on macOS). +# Install via: brew install coreutils +if ! command -v timeout &>/dev/null; then + echo "❌ 'timeout' command not found. On macOS: brew install coreutils" >&2 + exit 1 +fi + +COMPOSE_FILE="docker-compose.e2e.yml" + +cleanup() { + local exit_code=$? + echo "" + echo "🧹 Tearing down E2E infrastructure..." + docker compose -f "$COMPOSE_FILE" down -v --remove-orphans 2>/dev/null || true + echo "✅ Cleanup complete" + exit $exit_code +} +trap cleanup EXIT + +echo "🚀 Starting E2E infrastructure..." +docker compose -f "$COMPOSE_FILE" up -d --build + +echo "⏳ Waiting for services..." + +# Phase 1: PostgreSQL +timeout 60 bash -c ' + until docker exec e2e-postgres pg_isready -U postgres 2>/dev/null; do sleep 2; done +' +echo "✅ PostgreSQL ready" + +# Phase 2: Fineract actuator +timeout 300 bash -c ' + until docker ps --filter "health=healthy" --filter "name=e2e-fineract" | grep -q healthy; do + echo " … waiting for Fineract" + sleep 10 + done +' +echo "✅ Fineract healthy" + +# Phase 2.5: Liquibase seeding (Head Office) +E2E_USERNAME="${E2E_USERNAME:-mifos}" +E2E_PASSWORD="${E2E_PASSWORD:-password}" +E2E_TENANT_ID="${E2E_TENANT_ID:-default}" +# Portable base64: tr -d '\n' handles macOS/Linux newline differences +AUTH_HEADER=$(echo -n "${E2E_USERNAME}:${E2E_PASSWORD}" | base64 | tr -d '\n') + +timeout 120 bash -c " + until curl -fsk \ + -H 'Fineract-Platform-TenantId: ${E2E_TENANT_ID}' \ + -H 'Authorization: Basic ${AUTH_HEADER}' \ + https://localhost:8443/fineract-provider/api/v1/offices 2>/dev/null | grep -q 'Head Office'; do + echo ' … waiting for Liquibase seed data' + sleep 5 + done +" +echo "✅ Liquibase seed data ready" + +# Phase 3: Web-app +curl -f --retry 20 --retry-all-errors --connect-timeout 5 --retry-delay 3 \ + http://localhost:4200 > /dev/null 2>&1 +echo "✅ Web-app ready" + +echo "" +echo "🧪 Running Playwright tests..." +# "$@" forwards flags from: npm run e2e:docker -- --grep login +npx playwright test --workers=1 "$@" diff --git a/src/app/clients/clients-view/general-tab/general-tab.component.html b/src/app/clients/clients-view/general-tab/general-tab.component.html index 17def703bb..dc79a22d26 100644 --- a/src/app/clients/clients-view/general-tab/general-tab.component.html +++ b/src/app/clients/clients-view/general-tab/general-tab.component.html @@ -35,7 +35,7 @@

{{ 'labels.heading.Performance History' | translate }}

-
+

{{ 'labels.heading.Upcoming Charges' | translate }}

diff --git a/src/app/loans/loans-routing.module.ts b/src/app/loans/loans-routing.module.ts index c6270046ba..fe7cc878c5 100644 --- a/src/app/loans/loans-routing.module.ts +++ b/src/app/loans/loans-routing.module.ts @@ -112,7 +112,7 @@ const routes: Routes = [ { path: 'general', component: GeneralTabComponent, - data: { title: 'General', breadcrumb: 'General', routeParamBreadcrumb: false }, + data: { title: 'Loan Account Details', breadcrumb: 'General', routeParamBreadcrumb: false }, resolve: {} }, { @@ -279,7 +279,7 @@ const routes: Routes = [ }, { path: 'originators', - data: { title: 'Loans Originators', breadcrumb: 'Originators', routeParamBreadcrumb: false }, + data: { title: 'Loan Originators', breadcrumb: 'Originators', routeParamBreadcrumb: false }, resolve: { loanOriginatorsData: LoanOriginatorsResolver }, diff --git a/src/app/shares/shares-routing.module.ts b/src/app/shares/shares-routing.module.ts index 4a9fc4072f..27826566ac 100644 --- a/src/app/shares/shares-routing.module.ts +++ b/src/app/shares/shares-routing.module.ts @@ -59,7 +59,7 @@ const routes: Routes = [ { path: 'general', component: GeneralTabComponent, - data: { title: 'Shares Account General', breadcrumb: 'General', routeParamBreadcrumb: false }, + data: { title: 'Shares Account Details', breadcrumb: 'General', routeParamBreadcrumb: false }, resolve: { sharesAccountData: SharesAccountViewResolver } diff --git a/src/assets/translations/cs-CS.json b/src/assets/translations/cs-CS.json index 57c47c5f9e..91002afff7 100644 --- a/src/assets/translations/cs-CS.json +++ b/src/assets/translations/cs-CS.json @@ -3347,6 +3347,7 @@ "Fixed Deposit Account Interest Rate Chart": "Tabulka úrokových sazeb na účtu s pevným vkladem", "Fixed Deposit Account Standing Instructions": "Pokyny k trvalému vkladovému účtu", "Fixed Deposit Account Transactions": "Transakce na pevném vkladovém účtu", + "Fixed Deposit Account Details": "Detaily účtu terminovaného vkladu", "Fixed Deposit Account View": "Pohled na účet s pevným vkladem", "Fixed Deposit Products": "Produkty s pevným vkladem", "Fixed Deposit Products defines the rules, default settings": "Produkty s pevným vkladem definují pravidla, výchozí nastavení a omezení pro nabídky finančních
pevných vkladů (také označované jako termínované vklady). Produkt s pevným vkladem poskytuje pro klienty finanční instituce šablonu pro více účtů s pevným vkladem.", @@ -3402,6 +3403,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccount DelikvencePauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Detaily úvěrového účtu", "Loan Account Actions": "Akce na úvěrovém účtu", "Loan Collateral Details": "Podrobnosti o zajištění úvěru", "Loan Disbursal": "Vyplacení půjčky", @@ -3526,6 +3528,7 @@ "Provisioning criteria definitions": "Vyplňte všechny definice kritérií poskytování.", "Precedes of": "Předchází", "Recurring Deposit Account Charges": "Opakované poplatky za vkladový účet", + "Recurring Deposit Account Details": "Detaily účtu opakovaného vkladu", "Recurring Deposit Account Interest Rate Chart": "Graf úrokových sazeb pro opakující se vkladový účet", "Recurring Deposit Account Standing Instructions": "Pokyny k trvalému vkladovému účtu", "Recurring Deposit Account Transactions": "Opakující se transakce na vkladovém účtu", @@ -3591,6 +3594,7 @@ "Share Products Dividends": "Sdílejte produkty Dividendy", "Share products define the rules, default settings": "Sdílené produkty definují pravidla, výchozí nastavení a omezení pro akcie a dividendy finanční instituce. Sdílený produkt poskytuje šablonu pro více účtů, které jsou nebo budou drženy klienty finanční instituce.", "Shares": "akcie", + "Shares Account Details": "Detaily účtu akcií", "Shares Account Actions": "Akce na účtu akcií", "Shares Account Charges": "Poplatky na účtu akcií", "Shares Account Dividends": "Akcie Účet Dividendy", @@ -3756,7 +3760,8 @@ "Failed to update payment type. Please try again.": "Aktualizace typu platby se nezdařila. Zkuste to prosím znovu.", "Search and assign this beneficiary to an existing Mifos client account": "Vyhledejte a přiřaďte tohoto příjemce k existujícímu účtu klienta Mifos", "Failed to search clients. Please try again.": "Hledání klientů se nezdařilo. Zkuste to prosím znovu.", - "Process Remittance": "Zpracovat remitenci" + "Process Remittance": "Zpracovat remitenci", + "Loan Originators": "Poskytovatelé úvěrů" }, "permissions": { "actions": { diff --git a/src/assets/translations/de-DE.json b/src/assets/translations/de-DE.json index 3480977de6..3c191cbf5b 100644 --- a/src/assets/translations/de-DE.json +++ b/src/assets/translations/de-DE.json @@ -3348,6 +3348,7 @@ "Fineract": "Apache Fineract®", "Fixed Deposit Account Standing Instructions": "Anweisungen zum Festgeldkonto", "Fixed Deposit Account Transactions": "Transaktionen mit Festgeldkonten", + "Fixed Deposit Account Details": "Festgeldkonto-Details", "Fixed Deposit Account View": "Ansicht Festgeldkonto", "Fixed Deposit Products": "Festgeldprodukte", "Fixed Deposit Products defines the rules, default settings": "Festgeldprodukte definiert die Regeln, Standardeinstellungen und Einschränkungen für die Festgeldangebote eines Finanzinstituts (auch als Termineinlagen bezeichnet). Ein Festgeldprodukt bietet eine Vorlage für mehrere Festgeldkonten für die Kunden des Finanzinstituts.", @@ -3403,6 +3404,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Details zum Kreditkonto", "Loan Account Actions": "Aktionen zum Kreditkonto", "Loan Collateral Details": "Details zur Kreditsicherheit", "Loan Disbursal": "Kreditauszahlung", @@ -3527,6 +3529,7 @@ "Provisioning criteria definitions": "Bitte füllen Sie alle Definitionen der Bereitstellungskriterien aus.", "Precedes of": "Präzedenzfälle von", "Recurring Deposit Account Charges": "Wiederkehrende Kontogebühren", + "Recurring Deposit Account Details": "Details zum wiederkehrenden Einzahlungskonto", "Recurring Deposit Account Interest Rate Chart": "Zinssatztabelle für wiederkehrende Einlagenkonten", "Recurring Deposit Account Standing Instructions": "Anweisungen zum Kontostand für wiederkehrende Einlagen", "Recurring Deposit Account Transactions": "Wiederkehrende Transaktionen auf dem Einlagenkonto", @@ -3592,6 +3595,7 @@ "Share Products Dividends": "Dividenden für Aktienprodukte", "Share products define the rules, default settings": "Aktienprodukte definieren die Regeln, Standardeinstellungen und Einschränkungen für die Aktien und Dividenden eines Finanzinstituts. Ein Aktienprodukt bietet eine Vorlage für mehrere Konten, die von den Kunden des Finanzinstituts geführt werden oder werden.", "Shares": "Anteile", + "Shares Account Details": "Details zum Aktienkonto", "Shares Account Actions": "Gibt Kontoaktionen frei", "Shares Account Charges": "Gebühren für das Aktienkonto", "Shares Account Dividends": "Dividenden auf dem Aktienkonto", @@ -3757,7 +3761,8 @@ "Failed to update payment type. Please try again.": "Aktualisierung des Zahlungstyps fehlgeschlagen. Bitte versuchen Sie es erneut.", "Search and assign this beneficiary to an existing Mifos client account": "Suchen und weisen Sie diesen Begünstigten einem bestehenden Mifos-Kundenkonto zu", "Failed to search clients. Please try again.": "Kundensuche fehlgeschlagen. Bitte versuchen Sie es erneut.", - "Process Remittance": "Überweisung bearbeiten" + "Process Remittance": "Überweisung bearbeiten", + "Loan Originators": "Kreditvermittler" }, "permissions": { "actions": { diff --git a/src/assets/translations/en-US.json b/src/assets/translations/en-US.json index ada00c97bb..7d8fc6eca8 100644 --- a/src/assets/translations/en-US.json +++ b/src/assets/translations/en-US.json @@ -3382,6 +3382,7 @@ "FilterByLoanIdOrError": "Filter by loan Id or error", "Fineract": "Apache Fineract®", "Fixed Deposit Account Charges": "Fixed Deposit Account Charges", + "Fixed Deposit Account Details": "Fixed Deposit Account Details", "Fixed Deposit Account Interest Rate Chart": "Fixed Deposit Account Interest Rate Chart", "Fixed Deposit Account Standing Instructions": "Fixed Deposit Account Standing Instructions", "Fixed Deposit Account Transactions": "Fixed Deposit Account Transactions", @@ -3536,6 +3537,7 @@ "LoanWithdrawnByApplicantBusinessEvent": "Loan Withdrawn By Applicant Business Event", "LoanWrittenOffPostBusinessEvent": "Loan Written Off Post Business Event", "LoanWrittenOffPreBusinessEvent": "Loan Written Off Pre Business Event", + "Loan Account Details": "Loan Account Details", "Loan Account Actions": "Loan Account Actions", "Loan Collateral Details": "Loan Collateral Details", "Loan Disbursal": "Loan Disbursal", @@ -3546,6 +3548,7 @@ "Loan Tranche Details": "Loan Tranche Details", "Loan Term Variations": "Loan Term Variations", "Loan View": "Loan View", + "Loan Originators": "Loan Originators", "Loan products define the rules, default settings": "Loan products define the rules, default settings, and constraints for a financial institution's lending offerings. A loan product provides a template for multiple loan accounts for the financial institution's clients.", "Loan": "Loan", "Loans": "Loans", @@ -3648,6 +3651,7 @@ "Precedes of": "Precedes of", "RecurringDepositAccountCreateBusinessEvent": "Recurring Deposit Account Create Business Event", "Recurring Deposit Account Charges": "Recurring Deposit Account Charges", + "Recurring Deposit Account Details": "Recurring Deposit Account Details", "Recurring Deposit Account Interest Rate Chart": "Recurring Deposit Account Interest Rate Chart", "Recurring Deposit Account Standing Instructions": "Recurring Deposit Account Standing Instructions", "Recurring Deposit Account Transactions": "Recurring Deposit Account Transactions", @@ -3726,6 +3730,7 @@ "Share Products Dividends": "Share Products Dividends", "Share products define the rules, default settings": "Share products define the rules, default settings, and constraints for a financial institution's Shares and dividends. A share product provides a template for multiple accounts that are or will be held by the financial institution's clients.", "Shares": "Shares", + "Shares Account Details": "Shares Account Details", "Shares Account Actions": "Shares Account Actions", "Shares Account Charges": "Shares Account Charges", "Shares Account Dividends": "Shares Account Dividends", diff --git a/src/assets/translations/es-CL.json b/src/assets/translations/es-CL.json index 1358687fd6..a2568cc216 100644 --- a/src/assets/translations/es-CL.json +++ b/src/assets/translations/es-CL.json @@ -3348,6 +3348,7 @@ "Fixed Deposit Account Interest Rate Chart": "Tabla de tasas de interés de cuentas de Depósito Fijo", "Fixed Deposit Account Standing Instructions": "Instrucciones para la situación de la cuenta de Depósito Fijo", "Fixed Deposit Account Transactions": "Transacciones de cuenta de Depósito Fijo", + "Fixed Deposit Account Details": "Detalles de cuenta de depósito a plazo", "Fixed Deposit Account View": "Vista de cuenta de Depósito Fijo", "Fixed Deposit Products": "Productos de Depósito Fijo", "Fixed Deposit Products defines the rules, default settings": "Los productos de Depósito Fijo definen las reglas, la configuración predeterminada y las restricciones para las ofertas de Depósito Fijo de una institución financiera (también conocidos como depósitos a plazo). Un producto de Depósito Fijo proporciona una plantilla para múltiples cuentas de Depósito Fijo para los clientes de la institución financiera.", @@ -3403,6 +3404,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "PréstamoCuentaPersonalizadoInstantáneaNegocioEvento", "LoanAccountDelinquencyPauseChangedBusinessEvent": "PréstamoCuentaMorosidadPausaCambiadoNegocioEvento", "LoanAccountSnapshotBusinessEvent": "PréstamoCuentaInstantáneaNegocioEvento", + "Loan Account Details": "Detalles de la cuenta de Crédito", "Loan Account Actions": "Acciones de la cuenta de Crédito", "Loan Collateral Details": "Detalles de la garantía del Crédito", "Loan Disbursal": "Curso del Crédito", @@ -3528,6 +3530,7 @@ "Provisioning criteria definitions": "Complete todas las definiciones de criterios de aprovisionamiento.", "Precedes of": "Precede de", "Recurring Deposit Account Charges": "Comisiones recurrentes de la cuenta de depósito", + "Recurring Deposit Account Details": "Detalles de la cuenta de depósito recurrente", "Recurring Deposit Account Interest Rate Chart": "Tabla de tasas de interés de cuentas de Depósito Recurrentes", "Recurring Deposit Account Standing Instructions": "Instrucciones para la situación de la cuenta de Depósito Recurrente", "Recurring Deposit Account Transactions": "Transacciones recurrentes en cuentas de depósito", @@ -3593,6 +3596,7 @@ "Share Products Dividends": "Dividendos de Productos de Acciones", "Share products define the rules, default settings": "Los productos de acciones definen las reglas, la configuración predeterminada y las restricciones para las acciones y los dividendos de una institución financiera. Un producto de acciones proporciona una plantilla para múltiples cuentas que son o serán propiedad de los clientes de la institución financiera.", "Shares": "Acciones", + "Shares Account Details": "Detalles de la cuenta de acciones", "Shares Account Actions": "Acciones de la cuenta de acciones", "Shares Account Charges": "Comisiones de la cuenta de acciones", "Shares Account Dividends": "Dividendos de cuentas de acciones", @@ -3760,7 +3764,8 @@ "Failed to update payment type. Please try again.": "Error al actualizar el tipo de pago. Intente de nuevo.", "Search and assign this beneficiary to an existing Mifos client account": "Buscar y asignar este beneficiario a una cuenta de cliente Mifos existente", "Failed to search clients. Please try again.": "Error al buscar clientes. Intente de nuevo.", - "Process Remittance": "Procesar Remesa" + "Process Remittance": "Procesar Remesa", + "Loan Originators": "Originadores de créditos" }, "permissions": { "actions": { diff --git a/src/assets/translations/es-MX.json b/src/assets/translations/es-MX.json index 6bac81bca0..487908ed83 100644 --- a/src/assets/translations/es-MX.json +++ b/src/assets/translations/es-MX.json @@ -3381,6 +3381,7 @@ "Fixed Deposit Account Interest Rate Chart": "Tabla de tasas de interés de cuentas de Depósito Fijo", "Fixed Deposit Account Standing Instructions": "Instrucciones para la situación de la cuenta de Depósito Fijo", "Fixed Deposit Account Transactions": "Transacciones de cuenta de Depósito Fijo", + "Fixed Deposit Account Details": "Detalles de cuenta de depósito a plazo", "Fixed Deposit Account View": "Vista de cuenta de Depósito Fijo", "Fixed Deposit Products": "Productos de Depósito Fijo", "Fixed Deposit Products defines the rules, default settings": "Los productos de Depósito Fijo definen las reglas, la configuración predeterminada y las restricciones para las ofertas de Depósito Fijo de una institución financiera (también conocidos como depósitos a plazo). Un producto de Depósito Fijo proporciona una plantilla para múltiples cuentas de Depósito Fijo para los clientes de la institución financiera.", @@ -3436,6 +3437,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "PréstamoCuentaPersonalizadoInstantáneaNegocioEvento", "LoanAccountDelinquencyPauseChangedBusinessEvent": "PréstamoCuentaMorosidadPausaCambiadoNegocioEvento", "LoanAccountSnapshotBusinessEvent": "PréstamoCuentaInstantáneaNegocioEvento", + "Loan Account Details": "Detalles de la cuenta de préstamo", "Loan Account Actions": "Acciones de la cuenta de Crédito", "Loan Collateral Details": "Detalles de la garantía del Crédito", "Loan Disbursal": "Dispersión del Crédito", @@ -3561,6 +3563,7 @@ "Provisioning criteria definitions": "Complete todas las definiciones de criterios de aprovisionamiento.", "Precedes of": "Precede de", "Recurring Deposit Account Charges": "Comisiones recurrentes de la cuenta de depósito", + "Recurring Deposit Account Details": "Detalles de la cuenta de depósito recurrente", "Recurring Deposit Account Interest Rate Chart": "Tabla de tasas de interés de cuentas de Depósito Recurrentes", "Recurring Deposit Account Standing Instructions": "Instrucciones para la situación de la cuenta de Depósito Recurrente", "Recurring Deposit Account Transactions": "Transacciones recurrentes en cuentas de depósito", @@ -3626,6 +3629,7 @@ "Share Products Dividends": "Dividendos de Productos de Acciones", "Share products define the rules, default settings": "Los productos de acciones definen las reglas, la configuración predeterminada y las restricciones para las acciones y los dividendos de una institución financiera. Un producto de acciones proporciona una plantilla para múltiples cuentas que son o serán propiedad de los clientes de la institución financiera.", "Shares": "Acciones", + "Shares Account Details": "Detalles de la cuenta de acciones", "Shares Account Actions": "Acciones de la cuenta de acciones", "Shares Account Charges": "Comisiones de la cuenta de acciones", "Shares Account Dividends": "Dividendos de cuentas de acciones", @@ -3776,7 +3780,8 @@ "“Maker-Checker” principle requires every tasks": "El principio \"Maker-Checker\" requiere que dos personas completen cada tarea para reducir la posibilidad de errores y uso indebido. Una persona inicia el proceso y la segunda lo completa.", "Buy Down Fees": "Tarifas de compra", "UploadDocumentHint": "Suba un PDF o imagen para generar una vista previa.", - "Process Remittance": "Procesar Remesa" + "Process Remittance": "Procesar Remesa", + "Loan Originators": "Comisionistas de créditos" }, "permissions": { "actions": { diff --git a/src/assets/translations/fr-FR.json b/src/assets/translations/fr-FR.json index 3ae1be0819..4fc2cfa171 100644 --- a/src/assets/translations/fr-FR.json +++ b/src/assets/translations/fr-FR.json @@ -3350,6 +3350,7 @@ "Fixed Deposit Account Interest Rate Chart": "Tableau des taux d’intérêt des comptes de dépôt fixe", "Fixed Deposit Account Standing Instructions": "Instructions permanentes pour les comptes de dépôt à terme", "Fixed Deposit Account Transactions": "Opérations sur compte de dépôt fixe", + "Fixed Deposit Account Details": "Détails du compte de dépôt à terme", "Fixed Deposit Account View": "Vue du compte de dépôt fixe", "Fixed Deposit Products": "Produits de dépôt fixe", "Fixed Deposit Products defines the rules, default settings": "Les produits de dépôt fixe définissent les règles, les paramètres par défaut et les contraintes pour les offres de dépôt fixe d'une institution financière (également appelées dépôts à terme). Un produit de dépôt à terme fournit un modèle pour plusieurs comptes de dépôt à terme pour les clients de l'institution financière.", @@ -3404,6 +3405,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Détails du compte de prêt", "Loan Account Actions": "Actions sur le compte de prêt", "Loan Collateral Details": "Détails de la garantie de prêt", "Loan Disbursal": "Décaissement du prêt", @@ -3529,6 +3531,7 @@ "Provisioning criteria definitions": "Veuillez remplir toutes les définitions des critères de provisionnement.", "Precedes of": "Précède de", "Recurring Deposit Account Charges": "Frais de compte de dépôt récurrents", + "Recurring Deposit Account Details": "Détails du compte de dépôt récurrent", "Recurring Deposit Account Interest Rate Chart": "Tableau des taux d’intérêt des comptes de dépôt récurrents", "Recurring Deposit Account Standing Instructions": "Instructions permanentes pour les comptes de dépôt récurrents", "Recurring Deposit Account Transactions": "Opérations récurrentes sur le compte de dépôt", @@ -3594,6 +3597,7 @@ "Share Products Dividends": "Partager les dividendes des produits", "Share products define the rules, default settings": "Les produits d'actions définissent les règles, les paramètres par défaut et les contraintes applicables aux actions et aux dividendes d'une institution financière. Un produit d'actions fournit un modèle pour plusieurs comptes qui sont ou seront détenus par les clients de l'institution financière.", "Shares": "Actions", + "Shares Account Details": "Détails du compte d'actions", "Shares Account Actions": "Actions sur le compte de partage", "Shares Account Charges": "Frais de compte d’actions", "Shares Account Dividends": "Dividendes du compte d'actions", @@ -3761,7 +3765,8 @@ "Failed to update payment type. Please try again.": "Échec de la mise à jour du type de paiement. Veuillez réessayer.", "Search and assign this beneficiary to an existing Mifos client account": "Rechercher et attribuer ce bénéficiaire à un compte client Mifos existant", "Failed to search clients. Please try again.": "Échec de la recherche de clients. Veuillez réessayer.", - "Process Remittance": "Traiter le transfert" + "Process Remittance": "Traiter le transfert", + "Loan Originators": "Les courtiers en prêts" }, "permissions": { "actions": { diff --git a/src/assets/translations/it-IT.json b/src/assets/translations/it-IT.json index e452fde1b9..fd68a47ee1 100644 --- a/src/assets/translations/it-IT.json +++ b/src/assets/translations/it-IT.json @@ -3345,6 +3345,7 @@ "Fixed Deposit Account Interest Rate Chart": "Grafico dei tassi di interesse del conto di deposito fisso", "Fixed Deposit Account Standing Instructions": "Istruzioni per la permanenza del Conto di Deposito Fisso", "Fixed Deposit Account Transactions": "Operazioni di Conto Deposito Fisso", + "Fixed Deposit Account Details": "Dettagli conto deposito vincolato", "Fixed Deposit Account View": "Visualizzazione del conto di deposito fisso", "Fixed Deposit Products": "Prodotti a deposito fisso", "Fixed Deposit Products defines the rules, default settings": "Prodotti a deposito fisso definisce le regole, le impostazioni predefinite e i vincoli per le offerte di deposito fisso di un istituto finanziario (noti anche come depositi a termine). Un prodotto di deposito fisso fornisce un modello per più conti di deposito fisso per i clienti dell'istituto finanziario.", @@ -3400,6 +3401,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Dettagli del conto di prestito", "Loan Account Actions": "Azioni del conto di prestito", "Loan Collateral Details": "Dettagli della garanzia del prestito", "Loan Disbursal": "Erogazione del prestito", @@ -3525,6 +3527,7 @@ "Provisioning criteria definitions": "Compila tutte le definizioni dei criteri di provisioning.", "Precedes of": "Precede di", "Recurring Deposit Account Charges": "Spese ricorrenti sul conto di deposito", + "Recurring Deposit Account Details": "Dettagli del conto di deposito ricorrente", "Recurring Deposit Account Interest Rate Chart": "Grafico del tasso di interesse del conto di deposito ricorrente", "Recurring Deposit Account Standing Instructions": "Istruzioni per la permanenza del conto di deposito ricorrente", "Recurring Deposit Account Transactions": "Transazioni ricorrenti del conto di deposito", @@ -3590,6 +3593,7 @@ "Share Products Dividends": "Condividi i dividendi dei prodotti", "Share products define the rules, default settings": "I prodotti azionari definiscono le regole, le impostazioni predefinite e i vincoli per le azioni e i dividendi di un istituto finanziario. Un prodotto azionario fornisce un modello per più conti che sono o saranno detenuti dai clienti dell'istituto finanziario.", "Shares": "Azioni", + "Shares Account Details": "Dettagli del conto azioni", "Shares Account Actions": "Condivide le azioni dell'account", "Shares Account Charges": "Condivide le spese del conto", "Shares Account Dividends": "Dividendi del conto azionario", @@ -3757,7 +3761,8 @@ "Failed to update payment type. Please try again.": "Aggiornamento del tipo di pagamento non riuscito. Si prega di riprovare.", "Search and assign this beneficiary to an existing Mifos client account": "Cerca e assegna questo beneficiario a un conto cliente Mifos esistente", "Failed to search clients. Please try again.": "Ricerca clienti non riuscita. Si prega di riprovare.", - "Process Remittance": "Elabora rimessa" + "Process Remittance": "Elabora rimessa", + "Loan Originators": "Originatori di prestiti" }, "permissions": { "actions": { diff --git a/src/assets/translations/ko-KO.json b/src/assets/translations/ko-KO.json index 29e7628d68..becdfa6b20 100644 --- a/src/assets/translations/ko-KO.json +++ b/src/assets/translations/ko-KO.json @@ -3346,6 +3346,7 @@ "Fixed Deposit Account Interest Rate Chart": "정기예금 이자율 차트", "Fixed Deposit Account Standing Instructions": "정기예금 계좌 예금 안내", "Fixed Deposit Account Transactions": "정기예금 거래", + "Fixed Deposit Account Details": "정기 예금 계좌 세부 정보", "Fixed Deposit Account View": "정기예금계좌조회", "Fixed Deposit Products": "정기예금 상품", "Fixed Deposit Products defines the rules, default settings": "정기 예금 상품은 금융 기관의
정기 예금 상품(정기 예금이라고도 함)에 대한 규칙, 기본 설정 및 제약 조건을 정의합니다. 정기 예금 상품은 금융 기관의 고객을 위해 여러 정기 예금 계좌에 대한 템플릿을 제공합니다.", @@ -3401,6 +3402,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "대출계정CustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "대출계정연체 일시중지ChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "대출계정스냅샷비즈니스이벤트", + "Loan Account Details": "대출 계좌 세부 정보", "Loan Account Actions": "대출 계정 작업", "Loan Collateral Details": "대출 담보 세부정보", "Loan Disbursal": "대출금 지급", @@ -3526,6 +3528,7 @@ "Provisioning criteria definitions": "모든 프로비저닝 기준 정의를 입력하세요.", "Precedes of": "앞선", "Recurring Deposit Account Charges": "반복 예금 계좌 수수료", + "Recurring Deposit Account Details": "정기 적금 계좌 세부 정보", "Recurring Deposit Account Interest Rate Chart": "정기예금 계좌 이자율 차트", "Recurring Deposit Account Standing Instructions": "정기예금 계좌 유지 지침", "Recurring Deposit Account Transactions": "반복 예금 계좌 거래", @@ -3591,6 +3594,7 @@ "Share Products Dividends": "제품 배당금 공유", "Share products define the rules, default settings": "주식 상품은 금융 기관의 주식 및 배당금에 대한 규칙, 기본 설정 및 제약 조건을 정의합니다. 공유 상품은 금융 기관의 고객이 보유하고 있거나 보유하게 될 여러 계좌에 대한 템플릿을 제공합니다.", "Shares": "주식", + "Shares Account Details": "주식 계좌 세부 정보", "Shares Account Actions": "공유 계정 작업", "Shares Account Charges": "주식 계정 비용", "Shares Account Dividends": "주식 계좌 배당금", @@ -3758,7 +3762,8 @@ "Failed to update payment type. Please try again.": "결제 유형 업데이트에 실패했습니다. 다시 시도하세요.", "Search and assign this beneficiary to an existing Mifos client account": "이 수취인을 검색하여 기존 Mifos 고객 계정에 배정하세요", "Failed to search clients. Please try again.": "고객 검색에 실패했습니다. 다시 시도하세요.", - "Process Remittance": "송금 처리" + "Process Remittance": "송금 처리", + "Loan Originators": "대출 담당자" }, "permissions": { "actions": { diff --git a/src/assets/translations/lt-LT.json b/src/assets/translations/lt-LT.json index fd9461aedf..ec949c96e3 100644 --- a/src/assets/translations/lt-LT.json +++ b/src/assets/translations/lt-LT.json @@ -3347,6 +3347,7 @@ "Fixed Deposit Account Interest Rate Chart": "Fiksuoto indėlio sąskaitos palūkanų normos diagrama", "Fixed Deposit Account Standing Instructions": "Fiksuoto indėlio sąskaitos nuolatinės instrukcijos", "Fixed Deposit Account Transactions": "Fiksuoto indėlio sąskaitos operacijos", + "Fixed Deposit Account Details": "Terminuotojo indėlio sąskaitos rekvizitai", "Fixed Deposit Account View": "Fiksuoto indėlio sąskaitos vaizdas", "Fixed Deposit Products": "Fiksuoto indėlio produktai", "Fixed Deposit Products defines the rules, default settings": "Terminuotųjų indėlių produktai apibrėžia finansų įstaigos
terminuotųjų indėlių pasiūlymų (taip pat vadinamų terminuotais indėliais) taisykles, numatytuosius nustatymus ir apribojimus. Terminuoto indėlio produktas suteikia šabloną kelioms terminuoto indėlio sąskaitoms finansų įstaigos klientams.", @@ -3402,6 +3403,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Paskolos sąskaitos rekvizitai", "Loan Account Actions": "Paskolos sąskaitos veiksmai", "Loan Collateral Details": "Paskolos užstato informacija", "Loan Disbursal": "Paskolos išmokėjimas", @@ -3527,6 +3529,7 @@ "Provisioning criteria definitions": "Užpildykite visus teikimo kriterijų apibrėžimus.", "Precedes of": "Prieštaravimai", "Recurring Deposit Account Charges": "Pasikartojantys indėlio sąskaitos mokesčiai", + "Recurring Deposit Account Details": "Reguliariųjų indėlių sąskaitos rekvizitai", "Recurring Deposit Account Interest Rate Chart": "Periodinio indėlio sąskaitos palūkanų normų diagrama", "Recurring Deposit Account Standing Instructions": "Periodinio indėlio sąskaitos nuolatinės instrukcijos", "Recurring Deposit Account Transactions": "Periodinės indėlio sąskaitos operacijos", @@ -3592,6 +3595,7 @@ "Share Products Dividends": "Dalintis produktais dividendais", "Share products define the rules, default settings": "Bendrinimo produktai apibrėžia taisykles, numatytuosius nustatymus ir apribojimus finansų įstaigos akcijoms ir dividendams. Dalijimosi produktas suteikia šabloną kelioms paskyroms, kurias turi arba turės finansų įstaigos klientai.", "Shares": "Akcijos", + "Shares Account Details": "Akcijų sąskaitos informacija", "Shares Account Actions": "Bendrina paskyros veiksmus", "Shares Account Charges": "Dalijasi sąskaitos mokesčiais", "Shares Account Dividends": "Dalina sąskaitos dividendus", @@ -3759,7 +3763,8 @@ "Failed to update payment type. Please try again.": "Nepavyko atnaujinti mokėjimo tipo. Bandykite dar kartą.", "Search and assign this beneficiary to an existing Mifos client account": "Ieškokite ir priskirkite šį gavėją esamai Mifos kliento paskyrai", "Failed to search clients. Please try again.": "Nepavyko ieškoti klientų. Bandykite dar kartą.", - "Process Remittance": "Apdoroti pervedimą" + "Process Remittance": "Apdoroti pervedimą", + "Loan Originators": "Paskolų teikėjai" }, "permissions": { "actions": { diff --git a/src/assets/translations/lv-LV.json b/src/assets/translations/lv-LV.json index 15b253d3f3..7f73c14735 100644 --- a/src/assets/translations/lv-LV.json +++ b/src/assets/translations/lv-LV.json @@ -3346,6 +3346,7 @@ "Fixed Deposit Account Interest Rate Chart": "Fiksētā depozīta konta procentu likmju diagramma", "Fixed Deposit Account Standing Instructions": "Fiksētā depozīta konta pastāvēšanas instrukcijas", "Fixed Deposit Account Transactions": "Fiksētā depozīta konta darījumi", + "Fixed Deposit Account Details": "Termiņnoguldījuma konta informācija", "Fixed Deposit Account View": "Fiksētā depozīta konta skats", "Fixed Deposit Products": "Fiksētā depozīta produkti", "Fixed Deposit Products defines the rules, default settings": "Fiksēto depozītu produkti definē noteikumus, noklusējuma iestatījumus un ierobežojumus finanšu iestādes
fiksēto noguldījumu piedāvājumiem (saukti arī par termiņnoguldījumiem). Fiksētā depozīta produkts nodrošina veidni vairākiem fiksēto depozītu kontiem finanšu iestādes klientiem.", @@ -3401,6 +3402,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Kredītkonta informācija", "Loan Account Actions": "Aizdevuma konta darbības", "Loan Collateral Details": "Sīkāka informācija par aizdevuma nodrošinājumu", "Loan Disbursal": "Aizdevuma izsniegšana", @@ -3526,6 +3528,7 @@ "Provisioning criteria definitions": "Lūdzu, aizpildiet visas nodrošināšanas kritēriju definīcijas.", "Precedes of": "Iepriekšējie", "Recurring Deposit Account Charges": "Periodiskas depozīta konta izmaksas", + "Recurring Deposit Account Details": "Regulārā noguldījuma konta informācija", "Recurring Deposit Account Interest Rate Chart": "Atkārtota depozīta konta procentu likmju diagramma", "Recurring Deposit Account Standing Instructions": "Atkārtota depozīta konta pastāvīgās lietošanas instrukcijas", "Recurring Deposit Account Transactions": "Atkārtoti depozīta konta darījumi", @@ -3591,6 +3594,7 @@ "Share Products Dividends": "Dalieties Produkti Dividendes", "Share products define the rules, default settings": "Kopīgošanas produkti nosaka noteikumus, noklusējuma iestatījumus un ierobežojumus finanšu iestādes akcijām un dividendēm. Dalīšanas produkts nodrošina veidni vairākiem kontiem, kas pieder vai būs finanšu iestādes klientiem.", "Shares": "Akcijas", + "Shares Account Details": "Akciju konta informācija", "Shares Account Actions": "Kopīgošanas konta darbības", "Shares Account Charges": "Akciju konta izmaksas", "Shares Account Dividends": "Akciju konta dividendes", @@ -3758,7 +3762,8 @@ "Failed to update payment type. Please try again.": "Neizdevās atjaunināt maksājuma veidu. Lūdzu, mēģiniet vēlreiz.", "Search and assign this beneficiary to an existing Mifos client account": "Meklējiet un piešķiriet šo saņēmēju esošam Mifos klienta kontam", "Failed to search clients. Please try again.": "Neizdevās meklēt klientus. Lūdzu, mēģiniet vēlreiz.", - "Process Remittance": "Apstrādāt pārvedumu" + "Process Remittance": "Apstrādāt pārvedumu", + "Loan Originators": "Aizdevumu izsniedzēji" }, "permissions": { "actions": { diff --git a/src/assets/translations/ne-NE.json b/src/assets/translations/ne-NE.json index e5c737704f..ff4995ed8e 100644 --- a/src/assets/translations/ne-NE.json +++ b/src/assets/translations/ne-NE.json @@ -3344,6 +3344,7 @@ "Fixed Deposit Account Interest Rate Chart": "फिक्स्ड डिपोजिट खाता ब्याज दर चार्ट", "Fixed Deposit Account Standing Instructions": "फिक्स्ड डिपोजिट खाता स्थायी निर्देशनहरू", "Fixed Deposit Account Transactions": "फिक्स्ड डिपोजिट खाता लेनदेन", + "Fixed Deposit Account Details": "मुद्दती निक्षेप खाता विवरण", "Fixed Deposit Account View": "फिक्स्ड डिपोजिट खाता दृश्य", "Fixed Deposit Products": "फिक्स्ड डिपोजिट उत्पादनहरू", "Fixed Deposit Products defines the rules, default settings": "फिक्स्ड डिपोजिट उत्पादनहरूले नियमहरू, पूर्वनिर्धारित सेटिङहरू, र वित्तीय संस्थाको
फिक्स्ड डिपोजिट प्रस्तावहरू (समय निक्षेपहरू पनि भनिन्छ) को लागि बाधाहरू परिभाषित गर्दछ। एक फिक्स्ड डिपोजिट उत्पादनले वित्तीय संस्थाका ग्राहकहरूको लागि बहु मुद्दती निक्षेप खाताहरूको लागि टेम्प्लेट प्रदान गर्दछ।", @@ -3399,6 +3400,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "ऋण खाता विवरण", "Loan Account Actions": "ऋण खाता कार्यहरू", "Loan Collateral Details": "ऋण संपार्श्विक विवरण", "Loan Disbursal": "ऋण वितरण", @@ -3524,6 +3526,7 @@ "Provisioning criteria definitions": "कृपया सबै प्रावधान मापदण्ड परिभाषाहरू भर्नुहोस्।", "Precedes of": "को पूर्ववर्ती", "Recurring Deposit Account Charges": "आवर्ती जम्मा खाता शुल्कहरू", + "Recurring Deposit Account Details": "आवर्ती निक्षेप खाता विवरण", "Recurring Deposit Account Interest Rate Chart": "आवर्ती जम्मा खाता ब्याज दर चार्ट", "Recurring Deposit Account Standing Instructions": "आवर्ती जम्मा खाता स्थायी निर्देशनहरू", "Recurring Deposit Account Transactions": "आवर्ती जम्मा खाता लेनदेन", @@ -3589,6 +3592,7 @@ "Share Products Dividends": "शेयर उत्पादन लाभांश", "Share products define the rules, default settings": "शेयर उत्पादनहरूले वित्तीय संस्थाको शेयर र लाभांशका लागि नियमहरू, पूर्वनिर्धारित सेटिङहरू, र अवरोधहरू परिभाषित गर्दछ। एक सेयर उत्पादनले वित्तीय संस्थाका ग्राहकहरूद्वारा आयोजित वा राख्ने बहु खाताहरूको लागि टेम्प्लेट प्रदान गर्दछ।", "Shares": "सेयरहरू", + "Shares Account Details": "सेयर खाता विवरण", "Shares Account Actions": "साझेदारी खाता कार्यहरू", "Shares Account Charges": "शेयर खाता शुल्कहरू", "Shares Account Dividends": "शेयर खाता लाभांश", @@ -3756,7 +3760,8 @@ "Failed to update payment type. Please try again.": "भुक्तानी प्रकार अद्यावधिक गर्न असफल भयो। कृपया पुनः प्रयास गर्नुहोस्।", "Search and assign this beneficiary to an existing Mifos client account": "यो लाभग्राहीलाई खोजेर अवस्थित Mifos ग्राहक खातामा तोक्नुहोस्", "Failed to search clients. Please try again.": "ग्राहकहरू खोज्न असफल भयो। कृपया पुनः प्रयास गर्नुहोस्।", - "Process Remittance": "रेमिट्यान्स प्रक्रिया गर्नुहोस्" + "Process Remittance": "रेमिट्यान्स प्रक्रिया गर्नुहोस्", + "Loan Originators": "ऋण सुरुवातकर्ताहरू" }, "permissions": { "actions": { diff --git a/src/assets/translations/pt-PT.json b/src/assets/translations/pt-PT.json index 8fa2fcbfd7..53f2349bc4 100644 --- a/src/assets/translations/pt-PT.json +++ b/src/assets/translations/pt-PT.json @@ -3346,6 +3346,7 @@ "Fixed Deposit Account Interest Rate Chart": "Gráfico de taxas de juros de contas de depósito fixo", "Fixed Deposit Account Standing Instructions": "Instruções permanentes da conta de depósito fixo", "Fixed Deposit Account Transactions": "Transações de conta de depósito fixo", + "Fixed Deposit Account Details": "Detalhes da conta de depósito a prazo", "Fixed Deposit Account View": "Visualização de conta de depósito fixo", "Fixed Deposit Products": "Produtos de Depósito Fixo", "Fixed Deposit Products defines the rules, default settings": "Produtos de Depósito Fixo definem as regras, configurações padrão e restrições para as ofertas de depósito fixo de uma instituição financeira (também chamados de depósitos a prazo). Um produto de depósito fixo fornece um modelo para múltiplas contas de depósito fixo para os clientes da instituição financeira.", @@ -3401,6 +3402,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Detalhes da conta de empréstimo", "Loan Account Actions": "Ações de conta de empréstimo", "Loan Collateral Details": "Detalhes da garantia do empréstimo", "Loan Disbursal": "Desembolso de empréstimo", @@ -3526,6 +3528,7 @@ "Provisioning criteria definitions": "Preencha todas as definições de critérios de provisionamento.", "Precedes of": "Precede de", "Recurring Deposit Account Charges": "Cobranças recorrentes da conta de depósito", + "Recurring Deposit Account Details": "Detalhes da conta de depósito recorrente", "Recurring Deposit Account Interest Rate Chart": "Gráfico de taxas de juros de contas de depósito recorrente", "Recurring Deposit Account Standing Instructions": "Instruções sobre a situação da conta de depósito recorrente", "Recurring Deposit Account Transactions": "Transações recorrentes em contas de depósito", @@ -3591,6 +3594,7 @@ "Share Products Dividends": "Compartilhe dividendos de produtos", "Share products define the rules, default settings": "Os produtos de ações definem as regras, configurações padrão e restrições para as ações e dividendos de uma instituição financeira. Um produto de ações fornece um modelo para várias contas que são ou serão mantidas pelos clientes da instituição financeira.", "Shares": "Ações", + "Shares Account Details": "Detalhes da conta de ações", "Shares Account Actions": "Compartilha ações da conta", "Shares Account Charges": "Encargos da conta de ações", "Shares Account Dividends": "Dividendos da conta de ações", @@ -3758,7 +3762,8 @@ "Failed to update payment type. Please try again.": "Falha ao atualizar o tipo de pagamento. Tente novamente.", "Search and assign this beneficiary to an existing Mifos client account": "Pesquise e atribua este beneficiário a uma conta de cliente Mifos existente", "Failed to search clients. Please try again.": "Falha ao pesquisar clientes. Tente novamente.", - "Process Remittance": "Processar remessa" + "Process Remittance": "Processar remessa", + "Loan Originators": "Agentes de Crédito" }, "permissions": { "actions": { diff --git a/src/assets/translations/sw-SW.json b/src/assets/translations/sw-SW.json index ee0e47ce6d..f651cbeb12 100644 --- a/src/assets/translations/sw-SW.json +++ b/src/assets/translations/sw-SW.json @@ -3342,6 +3342,7 @@ "Fixed Deposit Account Interest Rate Chart": "Chati ya Kiwango cha Riba cha Akaunti ya Amana isiyobadilika", "Fixed Deposit Account Standing Instructions": "Maelekezo ya Kudumu ya Akaunti ya Amana", "Fixed Deposit Account Transactions": "Miamala ya Akaunti ya Amana isiyobadilika", + "Fixed Deposit Account Details": "Maelezo ya Akaunti ya Amana ya Kudumu", "Fixed Deposit Account View": "Mtazamo wa Akaunti ya Amana isiyobadilika", "Fixed Deposit Products": "Bidhaa za Amana zisizohamishika", "Fixed Deposit Products defines the rules, default settings": "Bidhaa za Amana Isiyobadilika hufafanua sheria, mipangilio chaguo-msingi na vikwazo kwa
matoleo ya amana isiyobadilika ya taasisi ya fedha (pia hujulikana kama amana za muda). Bidhaa ya amana isiyobadilika hutoa kiolezo cha akaunti nyingi za amana zisizobadilika kwa wateja wa taasisi ya fedha.", @@ -3397,6 +3398,7 @@ "LoanAccountCustomSnapshotBusinessEvent": "LoanAccountCustomSnapshotBusinessEvent", "LoanAccountDelinquencyPauseChangedBusinessEvent": "LoanAccountDelinquencyPauseChangedBusinessEvent", "LoanAccountSnapshotBusinessEvent": "LoanAccountSnapshotBusinessEvent", + "Loan Account Details": "Maelezo ya Akaunti ya Mkopo", "Loan Account Actions": "Vitendo vya Akaunti ya Mkopo", "Loan Collateral Details": "Maelezo ya Dhamana ya Mkopo", "Loan Disbursal": "Utoaji wa mkopo", @@ -3522,6 +3524,7 @@ "Provisioning criteria definitions": "Tafadhali jaza ufafanuzi wa vigezo vyote vya utoaji.", "Precedes of": "Hutangulia", "Recurring Deposit Account Charges": "Malipo ya Akaunti ya Amana ya Mara kwa Mara", + "Recurring Deposit Account Details": "Maelezo ya Akaunti ya Amana Inayojirudia", "Recurring Deposit Account Interest Rate Chart": "Chati ya Kiwango cha Riba cha Akaunti ya Amana ya Mara kwa Mara", "Recurring Deposit Account Standing Instructions": "Maagizo ya Kudumu ya Akaunti ya Amana", "Recurring Deposit Account Transactions": "Miamala ya Akaunti ya Amana ya Mara kwa Mara", @@ -3587,6 +3590,7 @@ "Share Products Dividends": "Shiriki Gawio la Bidhaa", "Share products define the rules, default settings": "Bidhaa zinazoshirikiwa hufafanua sheria, mipangilio chaguo-msingi na vikwazo vya Hisa na gawio la taasisi ya fedha. Bidhaa inayoshirikiwa hutoa kiolezo cha akaunti nyingi ambazo zinashikiliwa au zitashikiliwa na wateja wa taasisi ya fedha.", "Shares": "Hisa", + "Shares Account Details": "Maelezo ya Akaunti ya Hisa", "Shares Account Actions": "Vitendo vya Akaunti ya Hisa", "Shares Account Charges": "Inashiriki Malipo ya Akaunti", "Shares Account Dividends": "Gawio la Akaunti ya Hisa", @@ -3754,7 +3758,8 @@ "Failed to update payment type. Please try again.": "Imeshindwa kusasisha aina ya malipo. Tafadhali jaribu tena.", "Search and assign this beneficiary to an existing Mifos client account": "Tafuta na uweke mpokeaji huyu kwenye akaunti ya mteja wa Mifos iliyopo", "Failed to search clients. Please try again.": "Imeshindwa kutafuta wateja. Tafadhali jaribu tena.", - "Process Remittance": "Chakata uhawilishaji" + "Process Remittance": "Chakata uhawilishaji", + "Loan Originators": "Waanzilishi wa Mikopo" }, "permissions": { "actions": {