WIP: Arabic localization.|

This commit is contained in:
a.bouhuolia
2021-06-10 12:51:00 +02:00
parent 4fc7c37260
commit 1ea32884c2
465 changed files with 3299 additions and 2109 deletions

View File

@@ -27,8 +27,10 @@ export default class AccountsTypesController extends BaseController {
* @return {Response}
*/
getAccountTypesList(req: Request, res: Response, next: NextFunction) {
const { tenantId } = req;
try {
const accountTypes = this.accountsTypesService.getAccountsTypes();
const accountTypes = this.accountsTypesService.getAccountsTypes(tenantId);
return res.status(200).send({
account_types: this.transfromToResponse(accountTypes, ['label'], req),

View File

@@ -11,12 +11,16 @@ import BaseFinancialReportController from '../BaseFinancialReportController';
import CashFlowStatementService from 'services/FinancialStatements/CashFlow/CashFlowService';
import { ICashFlowStatementDOO, ICashFlowStatement } from 'interfaces';
import CashFlowTable from 'services/FinancialStatements/CashFlow/CashFlowTable';
import HasTenancyService from 'services/Tenancy/TenancyService';
@Service()
export default class CashFlowController extends BaseFinancialReportController {
@Inject()
cashFlowService: CashFlowStatementService;
@Inject()
tenancy: HasTenancyService;
/**
* Router constructor.
*/
@@ -69,8 +73,9 @@ export default class CashFlowController extends BaseFinancialReportController {
* @param {ITransactionsByVendorsStatement} statement -
*
*/
private transformToTableRows(cashFlowDOO: ICashFlowStatementDOO) {
const cashFlowTable = new CashFlowTable(cashFlowDOO);
private transformToTableRows(cashFlowDOO: ICashFlowStatementDOO, tenantId: number) {
const i18n = this.tenancy.i18n(tenantId);
const cashFlowTable = new CashFlowTable(cashFlowDOO, i18n);
return {
table: {
@@ -103,7 +108,7 @@ export default class CashFlowController extends BaseFinancialReportController {
switch (acceptType) {
case 'application/json+table':
return res.status(200).send(this.transformToTableRows(cashFlow));
return res.status(200).send(this.transformToTableRows(cashFlow, tenantId));
case 'json':
default:
return res.status(200).send(this.transformJsonResponse(cashFlow));

View File

@@ -10,12 +10,16 @@ import {
import BaseController from 'api/controllers/BaseController';
import InventoryDetailsService from 'services/FinancialStatements/InventoryDetails/InventoryDetailsService';
import InventoryDetailsTable from 'services/FinancialStatements/InventoryDetails/InventoryDetailsTable';
import HasTenancyService from 'services/Tenancy/TenancyService';
@Service()
export default class InventoryDetailsController extends BaseController {
@Inject()
inventoryDetailsService: InventoryDetailsService;
@Inject()
tenancy: HasTenancyService;
/**
* Router constructor.
*/
@@ -71,8 +75,9 @@ export default class InventoryDetailsController extends BaseController {
/**
* Transformes the report statement to table rows.
*/
private transformToTableRows(inventoryDetails) {
const inventoryDetailsTable = new InventoryDetailsTable(inventoryDetails);
private transformToTableRows(inventoryDetails, tenantId: number) {
const i18n = this.tenancy.i18n(tenantId);
const inventoryDetailsTable = new InventoryDetailsTable(inventoryDetails, i18n);
return {
table: {
@@ -108,7 +113,7 @@ export default class InventoryDetailsController extends BaseController {
case 'application/json+table':
return res
.status(200)
.send(this.transformToTableRows(inventoryDetails));
.send(this.transformToTableRows(inventoryDetails, tenantId));
case 'json':
default:
return res

View File

@@ -1,5 +1,6 @@
import { Router } from 'express';
import { Container } from 'typedi';
import i18n from 'i18n';
// Middlewares
import JWTAuth from 'api/middleware/jwtAuth';
@@ -47,6 +48,7 @@ export default () => {
// - Global routes.
// ---------------------------
app.use(i18n.init);
app.use(I18nMiddleware);
app.use('/auth', Container.get(Authentication).router());

View File

@@ -11,5 +11,6 @@ export default (req: Request, res: Response, next: NextFunction) => {
}
Logger.info('[i18n_middleware] set locale language to i18n.', { language, user: req.user });
i18n.setLocale(req, language);
next();
};

View File

@@ -6,6 +6,7 @@ import TenantsManagerService from 'services/Tenancy/TenantsManager';
export default (req: Request, tenant: ITenant) => {
const { id: tenantId, organizationId } = tenant;
const tenantServices = Container.get(TenancyService);
const tenantsManager = Container.get(TenantsManagerService);
@@ -17,7 +18,9 @@ export default (req: Request, tenant: ITenant) => {
const repositories = tenantServices.repositories(tenantId)
const cacheInstance = tenantServices.cache(tenantId);
tenantServices.setI18nLocals(tenantId, { __: req.__ });
const tenantContainer = tenantServices.tenantContainer(tenantId);
tenantContainer.set('i18n', { __: req.__ });
req.knex = knexInstance;
req.organizationId = organizationId;

View File

@@ -1,15 +1,24 @@
import Container from 'typedi';
import { get } from 'lodash';
import TenancyService from 'services/Tenancy/TenancyService'
import { get } from 'lodash';
import TenancyService from 'services/Tenancy/TenancyService';
import AccountsData from '../data/accounts';
exports.up = function (knex) {
const tenancyService = Container.get(TenancyService);
const i18n = tenancyService.i18n(knex.userParams.tenantId);
const data = AccountsData.map((account) => {
return {
...account,
name: i18n.__(account.name),
description: i18n.__(account.description),
};
});
return knex('accounts').then(async () => {
// Inserts seed entries.
return knex('accounts').insert([ ...AccountsData ]);
return knex('accounts').insert(data);
});
};
exports.down = function (knex) {
};
exports.down = function (knex) {};

View File

@@ -33,44 +33,44 @@ exports.up = (knex) => {
{ id: 13, name: i18n.__('Published'), slug: 'published', roles_logic_expression: '1', resource_model: 'Expense', predefined: true, },
// Sales invoices.
{ id: 16, name: 'Draft', slug: 'draft', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true, },
{ id: 17, name: 'Delivered', slug: 'delivered', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true },
{ id: 18, name: 'Unpaid', slug: 'unpaid', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true },
{ id: 19, name: 'Overdue', slug: 'overdue', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true },
{ id: 20, name: 'Partially paid', slug: 'partially-paid', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true },
{ id: 21, name: 'Paid', slug: 'paid', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true },
{ id: 16, name: i18n.__('Draft'), slug: 'draft', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true, },
{ id: 17, name: i18n.__('Delivered'), slug: 'delivered', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true },
{ id: 18, name: i18n.__('Unpaid'), slug: 'unpaid', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true },
{ id: 19, name: i18n.__('Overdue'), slug: 'overdue', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true },
{ id: 20, name: i18n.__('Partially paid'), slug: 'partially-paid', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true },
{ id: 21, name: i18n.__('Paid'), slug: 'paid', roles_logic_expression: '1', resource_model: 'SaleInvoice', predefined: true },
// Bills.
{ id: 22, name: 'Draft', slug: 'draft', roles_logic_expression: '1', resource_model: 'Bill', predefined: true, },
{ id: 23, name: 'Opened', slug: 'opened', roles_logic_expression: '1', resource_model: 'Bill', predefined: true },
{ id: 24, name: 'Unpaid', slug: 'unpaid', roles_logic_expression: '1', resource_model: 'Bill', predefined: true },
{ id: 25, name: 'Overdue', slug: 'overdue', roles_logic_expression: '1', resource_model: 'Bill', predefined: true },
{ id: 26, name: 'Partially paid', slug: 'partially-paid', roles_logic_expression: '1', resource_model: 'Bill', predefined: true },
{ id: 27, name: 'Paid', slug: 'paid', roles_logic_expression: '1', resource_model: 'Bill', predefined: true },
{ id: 22, name: i18n.__('Draft'), slug: 'draft', roles_logic_expression: '1', resource_model: 'Bill', predefined: true, },
{ id: 23, name: i18n.__('Opened'), slug: 'opened', roles_logic_expression: '1', resource_model: 'Bill', predefined: true },
{ id: 24, name: i18n.__('Unpaid'), slug: 'unpaid', roles_logic_expression: '1', resource_model: 'Bill', predefined: true },
{ id: 25, name: i18n.__('Overdue'), slug: 'overdue', roles_logic_expression: '1', resource_model: 'Bill', predefined: true },
{ id: 26, name: i18n.__('Partially paid'), slug: 'partially-paid', roles_logic_expression: '1', resource_model: 'Bill', predefined: true },
{ id: 27, name: i18n.__('Paid'), slug: 'paid', roles_logic_expression: '1', resource_model: 'Bill', predefined: true },
// Sale estimate.
{ id: 28, name: 'Draft', slug: 'draft', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
{ id: 29, name: 'Delivered', slug: 'delivered', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
{ id: 30, name: 'Approved', slug: 'approved', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
{ id: 31, name: 'Rejected', slug: 'rejected', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
{ id: 32, name: 'Invoiced', slug: 'invoiced', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
{ id: 33, name: 'Expired', slug: 'expired', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
{ id: 28, name: i18n.__('Draft'), slug: 'draft', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
{ id: 29, name: i18n.__('Delivered'), slug: 'delivered', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
{ id: 30, name: i18n.__('Approved'), slug: 'approved', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
{ id: 31, name: i18n.__('Rejected'), slug: 'rejected', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
{ id: 32, name: i18n.__('Invoiced'), slug: 'invoiced', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
{ id: 33, name: i18n.__('Expired'), slug: 'expired', roles_logic_expression: '1', resource_model: 'SaleEstimate', predefined: true },
// Sale receipts.
{ id: 34, name: 'Draft', slug: 'draft', roles_logic_expression: '1', resource_model: 'SaleReceipt', predefined: true },
{ id: 35, name: 'Closed', slug: 'closed', roles_logic_expression: '1', resource_model: 'SaleReceipt', predefined: true },
{ id: 34, name: i18n.__('Draft'), slug: 'draft', roles_logic_expression: '1', resource_model: 'SaleReceipt', predefined: true },
{ id: 35, name: i18n.__('Closed'), slug: 'closed', roles_logic_expression: '1', resource_model: 'SaleReceipt', predefined: true },
// Customers
{ id: 36, name: 'Active', slug: 'active', roles_logic_expression: '1', resource_model: 'Customer', predefined: true },
{ id: 37, name: 'Inactive', slug: 'inactive', roles_logic_expression: '1', resource_model: 'Customer', predefined: true },
{ id: 38, name: 'Overdue', slug: 'overdue', roles_logic_expression: '1', resource_model: 'Customer', predefined: true },
{ id: 39, name: 'Unpaid', slug: 'inpaid', roles_logic_expression: '1', resource_model: 'Customer', predefined: true },
{ id: 36, name: i18n.__('Active'), slug: 'active', roles_logic_expression: '1', resource_model: 'Customer', predefined: true },
{ id: 37, name: i18n.__('Inactive'), slug: 'inactive', roles_logic_expression: '1', resource_model: 'Customer', predefined: true },
{ id: 38, name: i18n.__('Overdue'), slug: 'overdue', roles_logic_expression: '1', resource_model: 'Customer', predefined: true },
{ id: 39, name: i18n.__('Unpaid'), slug: 'inpaid', roles_logic_expression: '1', resource_model: 'Customer', predefined: true },
// Vendors
{ id: 40, name: 'Active', slug: 'active', roles_logic_expression: '1', resource_model: 'Vendor', predefined: true },
{ id: 41, name: 'Inactive', slug: 'inactive', roles_logic_expression: '1', resource_model: 'Vendor', predefined: true },
{ id: 42, name: 'Overdue', slug: 'overdue', roles_logic_expression: '1', resource_model: 'Vendor', predefined: true },
{ id: 43, name: 'Unpaid', slug: 'overdue', roles_logic_expression: '1', resource_model: 'Vendor', predefined: true },
{ id: 40, name: i18n.__('Active'), slug: 'active', roles_logic_expression: '1', resource_model: 'Vendor', predefined: true },
{ id: 41, name: i18n.__('Inactive'), slug: 'inactive', roles_logic_expression: '1', resource_model: 'Vendor', predefined: true },
{ id: 42, name: i18n.__('Overdue'), slug: 'overdue', roles_logic_expression: '1', resource_model: 'Vendor', predefined: true },
{ id: 43, name: i18n.__('Unpaid'), slug: 'overdue', roles_logic_expression: '1', resource_model: 'Vendor', predefined: true },
]);
});
};

View File

@@ -53,3 +53,7 @@ export * from './Table';
export * from './Ledger';
export * from './CashFlow';
export * from './InventoryDetails';
export interface I18nService {
__: (input: string) => string;
}

View File

@@ -1,4 +1,128 @@
{
"Empty": "",
"Hello": "مرحبا"
"Petty Cash": "العهدة",
"Cash": "النقدية",
"Bank": "المصرف",
"Other Income": "إيرادات اخري",
"Interest Income": "إيرادات الفوائد",
"Opening Balance": "رصيد",
"Depreciation Expense": "مصاريف الاهلاك",
"Interest Expense": "مصروفات الفوائد",
"Sales of Product Income": "مبيعات دخل المنتجات",
"Inventory Asset": "المخزون",
"Cost of Goods Sold (COGS)": "تكلفة البضائع المباعة (COGS)",
"Cost of Goods Sold": "تكلفة البضاعة المباعة",
"Accounts Payable": "حسابات قابلة للدفع",
"Other Expense": "نفقات أخرى",
"Payroll Expenses": "نفقات الأجور",
"Fixed Asset": "أصول ثابتة",
"Credit Card": "بطاقة إئتمان",
"Non-Current Asset": "أصول غير متداولة",
"Current Asset": "أصول متداولة",
"Other Asset": "أصول اخري",
"Long Term Liability": "التزامات طويلة الاجل",
"Current Liability": "التزامات قصيرة الاجل",
"Other Liability": "التزمات اخري",
"Equity": "حقوق الملكية",
"Expense": "مصروف",
"Income": "دخل",
"Accounts Receivable (A/R)": "حسابات القبض (A / R)",
"Accounts Receivable": "الذمم المدينة",
"Accounts Payable (A/P)": "الحسابات الدائنة (A / P)",
"Inactive": "غير نشط",
"Other Current Asset": "اثار حالية اخري",
"Tax Payable": "الضريبة المستحقة",
"Other Current Liability": "مطلوبات متداولة أخرى",
"Non-Current Liability": "المسؤولية غير المتداولة",
"Assets": "أصول",
"Liabilities": "الالتزمات",
"Account name": "أسم الحساب",
"Account type": "نوع الحساب",
"Account normal": "حساب عادي",
"Description": "وصف",
"Account code": "رمز الحساب",
"Currency": "عملة",
"Balance": "توازن",
"Active": "نشيط",
"Created at": "أنشئت في",
"fixed_asset": "أصل ثابت",
"Journal": "مجلة",
"Reconciliation": "تصالح",
"Credit": "تنسب إليه",
"Debit": "دين",
"Interest": "فائدة",
"Depreciation": "الاستهلاك",
"Payroll": "كشف رواتب",
"Type": "نوع",
"Name": "اسم",
"Sellable": "قابل للبيع",
"Purchasable": "قابل للشراء",
"Sell price": "سعر البيع",
"Cost price": "سعر الكلفة",
"User": "المستخدم",
"Category": "تصنيف",
"Note": "ملحوظة",
"Quantity on hand": "كمية في اليد",
"Quantity": "الكمية",
"Purchase description": "وصف الشراء",
"Sell description": "وصف البيع",
"Sell account": "بيع حساب",
"Cost account": "حساب التكلفة",
"Inventory account": "حساب الجرد",
"Payment date": "تاريخ الدفع",
"Payment account": "حساب الدفع",
"Amount": "كمية",
"Reference No.": "رقم المرجع.",
"Published": "نشرت",
"Journal number": "رقم المجلة",
"Status": "حالة",
"Journal type": "نوع المجلة",
"Date": "تاريخ",
"Asset": "أصل",
"Liability": "مسؤلية",
"First-in first-out (FIFO)": "الوارد أولاً يصرف أولاً (FIFO)",
"Last-in first-out (LIFO)": "الوارد أخيرًا يصرف أولاً (LIFO)",
"Average rate": "المعدل المتوسط",
"Total": "مجموع",
"Transaction type": "نوع المعاملة",
"Transaction #": "عملية #",
"Running Value": "القيمة الجارية",
"Running quantity": "الكمية الجارية",
"Profit Margin": "هامش الربح",
"Value": "قيمة",
"Rate": "معدل",
"OPERATING ACTIVITIES": "أنشطة التشغيل",
"FINANCIAL ACTIVITIES": "الأنشطة المالية",
"Net income": "صافي الدخل",
"Adjustments net income by operating activities.": "تعديلات صافي الدخل حسب الأنشطة التشغيلية.",
"Net cash provided by operating activities": "صافي النقد الناتج من أنشطة التشغيل",
"Net cash provided by investing activities": "صافي النقد المقدم من أنشطة الاستثمار",
"Net cash provided by financing activities": "صافي النقد الناتج عن أنشطة التمويل",
"Cash at beginning of period": "النقدية في بداية الفترة",
"NET CASH INCREASE FOR PERIOD": "زيادة صافي النقد للفترة",
"CASH AT END OF PERIOD": "النقد في نهاية الفترة",
"Expenses": "نفقات",
"Services": "خدمات",
"Inventory": "المخزون",
"Non-Inventory": "غير الجرد",
"Draft": "مسودة",
"Delivered": "تم التوصيل",
"Overdue": "متأخر",
"Partially paid": "المدفوعة جزئيا",
"Paid": "مدفوع",
"Opened": "افتتح",
"Unpaid": "غير مدفوعة",
"Approved": "وافق",
"Rejected": "مرفوض",
"Invoiced": "مفوترة",
"Expired": "منتهي الصلاحية",
"Closed": "مغلق",
"Manual journal": "مجلة يدوية",
"Inventory adjustment": "ضبط المخزون",
"Customer opening balance": "الرصيد الافتتاحي للعميل",
"Vendor opening balance": "رصيد افتتاح البائع",
"Payment made": "تم الدفع",
"Bill": "مشروع قانون",
"Payment receive": "استلام الدفع",
"Sale receipt": "إيصال البيع",
"Sale invoice": "فاتورة البيع"
}

View File

@@ -62,6 +62,7 @@
"Category": "Category",
"Note": "Note",
"Quantity on hand": "Quantity on hand",
"Quantity": "Quantity",
"Purchase description": "Purchase description",
"Sell description": "Sell description",
"Sell account": "Sell account",
@@ -71,7 +72,6 @@
"Payment account": "Payment account",
"Amount": "Amount",
"Reference No.": "Reference No.",
"Published": "Published",
"Journal number": "Journal number",
"Status": "Status",
"Journal type": "Journal type",
@@ -80,5 +80,74 @@
"Liability": "Liability",
"First-in first-out (FIFO)": "First-in first-out (FIFO)",
"Last-in first-out (LIFO)": "Last-in first-out (LIFO)",
"Average rate": "Average rate"
"Average rate": "Average rate",
"Total": "Total",
"Transaction type": "Transaction type",
"Transaction #": "Transaction #",
"Running Value": "Running Value",
"Running quantity": "Running quantity",
"Profit Margin": "Profit Margin",
"Value": "Value",
"Rate": "Rate",
"OPERATING ACTIVITIES": "OPERATING ACTIVITIES",
"FINANCIAL ACTIVITIES": "FINANCIAL ACTIVITIES",
"Net income": "Net income",
"Adjustments net income by operating activities.": "Adjustments net income by operating activities.",
"Net cash provided by operating activities": "Net cash provided by operating activities",
"Net cash provided by investing activities": "Net cash provided by investing activities",
"Net cash provided by financing activities": "Net cash provided by financing activities",
"Cash at beginning of period": "Cash at beginning of period",
"NET CASH INCREASE FOR PERIOD": "NET CASH INCREASE FOR PERIOD",
"CASH AT END OF PERIOD": "CASH AT END OF PERIOD",
"Expenses": "Expenses",
"Services": "Services",
"Inventory": "Inventory",
"Non-Inventory": "Non-Inventory",
"Draft": "Draft",
"Published": "Published",
"Delivered": "Delivered",
"Overdue": "Overdue",
"Partially paid": "Partially paid",
"Paid": "Paid",
"Opened": "Opened",
"Unpaid": "Unpaid",
"Approved": "Approved",
"Rejected": "Rejected",
"Invoiced": "Invoiced",
"Expired": "Expired",
"Closed": "Closed",
"Manual journal": "Manual journal",
"Inventory adjustment": "Inventory adjustment",
"Customer opening balance": "Customer opening balance",
"Vendor opening balance": "Vendor opening balance",
"Payment made": "Payment made",
"Bill": "Bill",
"Payment receive": "Payment receive",
"Sale receipt": "Sale receipt",
"Sale invoice": "Sale invoice",
"Bank Account": "Bank Account",
"Saving Bank Account": "Saving Bank Account",
"Undeposited Funds": "Undeposited Funds",
"Computer Equipment": "Computer Equipment",
"Office Equipment": "Office Equipment",
"Uncategorized Income": "Uncategorized Income",
"Sales of Service Income": "Sales of Service Income",
"Bank Fees and Charges": "Bank Fees and Charges",
"Exchange Gain or Loss": "Exchange Gain or Loss",
"Rent": "Rent",
"Office expenses": "Office expenses",
"Other Expenses": "Other Expenses",
"Drawings": "Drawings",
"Owner's Equity": "Owner's Equity",
"Opening Balance Equity": "Opening Balance Equity",
"Retained Earnings": "Retained Earnings",
"Sales Tax Payable": "Sales Tax Payable",
"Revenue Received in Advance": "Revenue Received in Advance",
"Opening Balance Liabilities": "Opening Balance Liabilities",
"Loan": "Loan",
"Owner A Drawings": "Owner A Drawings",
"An account that holds valuation of products or goods that availiable for sale.": "An account that holds valuation of products or goods that availiable for sale.",
"Tracks the gain and losses of the exchange differences.": "Tracks the gain and losses of the exchange differences.",
"Any bank fees levied is recorded into the bank fees and charges account. A bank account maintenance fee, transaction charges, a late payment fee are some examples.": "Any bank fees levied is recorded into the bank fees and charges account. A bank account maintenance fee, transaction charges, a late payment fee are some examples.",
"The income activities are not associated to the core business.": "The income activities are not associated to the core business."
}

View File

@@ -1,14 +1,22 @@
import { Service } from 'typedi';
import { Inject, Service } from 'typedi';
import { IAccountsTypesService, IAccountType } from 'interfaces';
import AccountTypesUtils from 'lib/AccountTypes';
import I18nService from 'services/I18n/I18nService';
@Service()
export default class AccountsTypesService implements IAccountsTypesService {
@Inject()
i18nService: I18nService;
/**
* Retrieve all accounts types.
* @param {number} tenantId -
* @return {IAccountType}
*/
getAccountsTypes(): IAccountType[] {
return AccountTypesUtils.getList();
public getAccountsTypes(tenantId: number): IAccountType[] {
const accountTypes = AccountTypesUtils.getList();
return this.i18nService.i18nMapper(accountTypes, ['name'], tenantId);
}
}

View File

@@ -37,6 +37,7 @@ import {
} from 'utils/deepdash';
import { ACCOUNT_ROOT_TYPE } from 'data/AccountTypes';
import CashFlowDatePeriods from './CashFlowDatePeriods';
import I18nService from 'services/I18n/I18nService';
const MAP_CONFIG = { childrenPath: 'children', pathFormat: 'array' };
@@ -47,6 +48,7 @@ const DISPLAY_COLUMNS_BY = {
class CashFlowStatement extends FinancialSheet implements ICashFlowStatement {
readonly baseCurrency: string;
readonly i18n: I18nService;
readonly sectionsByIds = {};
readonly cashFlowSchemaMap: Map<string, ICashFlowSchemaSection>;
readonly cashFlowSchemaSeq: Array<string>;
@@ -58,7 +60,6 @@ class CashFlowStatement extends FinancialSheet implements ICashFlowStatement {
readonly schemaSectionParserIteratee: any;
readonly query: ICashFlowStatementQuery;
readonly numberFormat: INumberFormatQuery;
readonly comparatorDateType: string;
readonly dateRangeSet: { fromDate: Date; toDate: Date }[];
@@ -72,11 +73,13 @@ class CashFlowStatement extends FinancialSheet implements ICashFlowStatement {
cashLedger: ILedger,
netIncomeLedger: ILedger,
query: ICashFlowStatementQuery,
baseCurrency: string
baseCurrency: string,
i18n
) {
super();
this.baseCurrency = baseCurrency;
this.i18n = i18n;
this.ledger = ledger;
this.cashLedger = cashLedger;
this.netIncomeLedger = netIncomeLedger;
@@ -87,8 +90,8 @@ class CashFlowStatement extends FinancialSheet implements ICashFlowStatement {
this.numberFormat = this.query.numberFormat;
this.dateRangeSet = [];
this.comparatorDateType =
query.displayColumnsType === 'total' ? 'day' : query.displayColumnsBy;
this.comparatorDateType = query.displayColumnsType === 'total'
? 'day' : query.displayColumnsBy;
this.initDateRangeCollection();
}
@@ -177,7 +180,7 @@ class CashFlowStatement extends FinancialSheet implements ICashFlowStatement {
)
)({
id: sectionSchema.id,
label: sectionSchema.label,
label: this.i18n.__(sectionSchema.label),
total: this.getAmountMeta(netIncome),
sectionType: ICashFlowStatementSectionType.NET_INCOME,
});
@@ -283,8 +286,8 @@ class CashFlowStatement extends FinancialSheet implements ICashFlowStatement {
)({
sectionType: ICashFlowStatementSectionType.ACCOUNTS,
id: sectionSchema.id,
label: sectionSchema.label,
footerLabel: sectionSchema.footerLabel,
label: this.i18n.__(sectionSchema.label),
footerLabel: this.i18n.__(sectionSchema.footerLabel),
children: accounts,
total: this.getTotalAmountMeta(total),
});
@@ -317,8 +320,8 @@ class CashFlowStatement extends FinancialSheet implements ICashFlowStatement {
): ICashFlowStatementSection {
return {
id: schemaSection.id,
label: schemaSection.label,
footerLabel: schemaSection.footerLabel,
label: this.i18n.__(schemaSection.label),
footerLabel: this.i18n.__(schemaSection.footerLabel),
sectionType: ICashFlowStatementSectionType.REGULAR,
};
}
@@ -383,7 +386,7 @@ class CashFlowStatement extends FinancialSheet implements ICashFlowStatement {
)({
sectionType: ICashFlowStatementSectionType.TOTAL,
id: sectionSchema.id,
label: sectionSchema.label,
label: this.i18n.__(sectionSchema.label),
total: this.getTotalAmountMeta(total),
});
}
@@ -477,7 +480,7 @@ class CashFlowStatement extends FinancialSheet implements ICashFlowStatement {
)({
sectionType: ICashFlowStatementSectionType.CASH_AT_BEGINNING,
id: sectionSchema.id,
label: sectionSchema.label,
label: this.i18n.__(sectionSchema.label),
children,
total: this.getTotalAmountMeta(total),
});

View File

@@ -94,6 +94,8 @@ export default class CashFlowStatementService
tenantId: number,
query: ICashFlowStatementQuery
): Promise<ICashFlowStatementDOO> {
const i18n = this.tenancy.i18n(tenantId);
// Retrieve all accounts on the storage.
const accounts = await this.cashFlowRepo.cashFlowAccounts(tenantId);
@@ -135,7 +137,8 @@ export default class CashFlowStatementService
cashLedger,
netIncomeLedger,
filter,
baseCurrency
baseCurrency,
i18n
);
return {

View File

@@ -1,5 +1,5 @@
import * as R from 'ramda';
import { isEmpty } from 'lodash';
import { isEmpty, times } from 'lodash';
import moment from 'moment';
import {
ICashFlowStatementSection,
@@ -9,7 +9,7 @@ import {
ITableColumn,
ICashFlowStatementQuery,
IDateRange,
ICashFlowStatementDOO
ICashFlowStatementDOO,
} from 'interfaces';
import { dateRangeFromToCollection, tableRowMapper } from 'utils';
import { mapValuesDeep } from 'utils/deepdash';
@@ -27,29 +27,30 @@ const DISPLAY_COLUMNS_BY = {
TOTAL: 'total',
};
export default class CashFlowTable implements ICashFlowTable {
private report: ICashFlowStatementDOO;
private i18n;
private dateRangeSet: IDateRange[];
/**
* Constructor method.
* @param {ICashFlowStatement} reportStatement
*/
constructor(reportStatement: ICashFlowStatementDOO) {
constructor(reportStatement: ICashFlowStatementDOO, i18n) {
this.report = reportStatement;
this.i18n = i18n;
this.dateRangeSet = [];
this.initDateRangeCollection();
}
/**
/**
* Initialize date range set.
*/
private initDateRangeCollection() {
this.dateRangeSet = dateRangeFromToCollection(
this.report.query.fromDate,
this.report.query.toDate,
this.report.query.displayColumnsBy,
this.report.query.displayColumnsBy
);
}
@@ -78,9 +79,9 @@ export default class CashFlowTable implements ICashFlowTable {
R.concat([{ key: 'label', accessor: 'label' }]),
R.when(
R.always(this.isDisplayColumnsBy(DISPLAY_COLUMNS_BY.DATE_PERIODS)),
R.concat(this.datePeriodsColumnsAccessors()),
R.concat(this.datePeriodsColumnsAccessors())
),
R.concat(this.totalColumnAccessor()),
R.concat(this.totalColumnAccessor())
)([]);
}
@@ -230,7 +231,7 @@ export default class CashFlowTable implements ICashFlowTable {
): ICashFlowStatementSection {
const label = section.footerLabel
? section.footerLabel
: `Total ${section.label}`;
: this.i18n.__('Total {{accountName}}', { accountName: section.label });
section.children.push({
sectionType: ICashFlowStatementSectionType.TOTAL,
@@ -288,12 +289,12 @@ export default class CashFlowTable implements ICashFlowTable {
* @returns {ITableColumn}
*/
private totalColumns(): ITableColumn[] {
return [{ key: 'total', label: 'Total' }];
return [{ key: 'total', label: this.i18n.__('Total') }];
}
/**
* Retrieve the formatted column label from the given date range.
* @param {ICashFlowDateRange} dateRange -
* @param {ICashFlowDateRange} dateRange -
* @return {string}
*/
private formatColumnLabel(dateRange: ICashFlowDateRange) {
@@ -308,9 +309,13 @@ export default class CashFlowTable implements ICashFlowTable {
['quarter', monthFormat],
['week', dayFormat],
];
const conditionsPairs = R.map(([type, formatFn]) => ([
R.always(this.isDisplayColumnsType(type)), formatFn,
]), conditions);
const conditionsPairs = R.map(
([type, formatFn]) => [
R.always(this.isDisplayColumnsType(type)),
formatFn,
],
conditions
);
return R.compose(R.cond(conditionsPairs))(dateRange);
}
@@ -336,11 +341,11 @@ export default class CashFlowTable implements ICashFlowTable {
/**
* Detarmines whether the given display columns type is the current.
* @param {string} displayColumnsBy
* @param {string} displayColumnsBy
* @returns {boolean}
*/
private isDisplayColumnsType(displayColumnsBy: string): Boolean {
return this.report.query.displayColumnsBy === displayColumnsBy;
return this.report.query.displayColumnsBy === displayColumnsBy;
}
/**
@@ -349,7 +354,7 @@ export default class CashFlowTable implements ICashFlowTable {
*/
public tableColumns(): ITableColumn[] {
return R.compose(
R.concat([{ key: 'name', label: 'Account name' }]),
R.concat([{ key: 'name', label: this.i18n.__('Account name') }]),
R.when(
R.always(this.isDisplayColumnsBy(DISPLAY_COLUMNS_BY.DATE_PERIODS)),
R.concat(this.datePeriodsColumns())

View File

@@ -22,6 +22,7 @@ export default class GeneralLedgerSheet extends FinancialSheet {
transactions: IJournalPoster;
contactsMap: Map<number, IContact>;
baseCurrency: string;
i18n: any;
/**
* Constructor method.
@@ -38,8 +39,8 @@ export default class GeneralLedgerSheet extends FinancialSheet {
contactsByIdMap: Map<number, IContact>,
transactions: IJournalPoster,
openingBalancesJournal: IJournalPoster,
baseCurrency: string
baseCurrency: string,
i18n
) {
super();
@@ -51,6 +52,7 @@ export default class GeneralLedgerSheet extends FinancialSheet {
this.transactions = transactions;
this.openingBalancesJournal = openingBalancesJournal;
this.baseCurrency = baseCurrency;
this.i18n = i18n;
}
/**
@@ -90,7 +92,7 @@ export default class GeneralLedgerSheet extends FinancialSheet {
referenceType: entry.referenceType,
referenceId: entry.referenceId,
referenceTypeFormatted: entry.referenceTypeFormatted,
referenceTypeFormatted: this.i18n.__(entry.referenceTypeFormatted),
contactName: get(contact, 'displayName'),
contactType: get(contact, 'contactService'),

View File

@@ -106,6 +106,7 @@ export default class GeneralLedgerService {
contactRepository
} = this.tenancy.repositories(tenantId);
const settings = this.tenancy.settings(tenantId);
const i18n = this.tenancy.i18n(tenantId);
const filter = {
...this.defaultQuery,
@@ -157,7 +158,8 @@ export default class GeneralLedgerService {
contactsByIdMap,
transactionsJournal,
openingTransJournal,
baseCurrency
baseCurrency,
i18n
);
// Retrieve general ledger report data.
const reportData = generalLedgerInstance.reportData();

View File

@@ -21,12 +21,16 @@ enum IROW_TYPE {
const MAP_CONFIG = { childrenPath: 'children', pathFormat: 'array' };
export default class InventoryDetailsTable {
i18n: any;
report: any;
/**
* Constructor method.
* @param {ICashFlowStatement} reportStatement - Report statement.
*/
constructor(reportStatement) {
constructor(reportStatement, i18n) {
this.report = reportStatement;
this.i18n = i18n;
}
/**
@@ -63,7 +67,10 @@ export default class InventoryDetailsTable {
{ key: 'value', accessor: 'valueMovement.formattedNumber' },
{ key: 'profit_margin', accessor: 'profitMargin.formattedNumber' },
{ key: 'running_quantity', accessor: 'runningQuantity.formattedNumber' },
{ key: 'running_valuation', accessor: 'runningValuation.formattedNumber' },
{
key: 'running_valuation',
accessor: 'runningValuation.formattedNumber',
},
];
return tableRowMapper(transaction, columns, {
rowTypes: [IROW_TYPE.TRANSACTION],
@@ -168,16 +175,16 @@ export default class InventoryDetailsTable {
*/
public tableColumns(): ITableColumn[] {
return [
{ key: 'date', label: 'Date' },
{ key: 'transaction_type', label: 'Transaction type' },
{ key: 'transaction_id', label: 'Transaction #' },
{ key: 'quantity', label: 'Quantity' },
{ key: 'rate', label: 'Rate' },
{ key: 'total', label: 'Total' },
{ key: 'value', label: 'Value' },
{ key: 'profit_margin', label: 'Profit Margin' },
{ key: 'running_quantity', label: 'Running quantity' },
{ key: 'running_value', label: 'Running Value' },
{ key: 'date', label: this.i18n.__('Date') },
{ key: 'transaction_type', label: this.i18n.__('Transaction type') },
{ key: 'transaction_id', label: this.i18n.__('Transaction #') },
{ key: 'quantity', label: this.i18n.__('Quantity') },
{ key: 'rate', label: this.i18n.__('Rate') },
{ key: 'total', label: this.i18n.__('Total') },
{ key: 'value', label: this.i18n.__('Value') },
{ key: 'profit_margin', label: this.i18n.__('Profit Margin') },
{ key: 'running_quantity', label: this.i18n.__('Running quantity') },
{ key: 'running_value', label: this.i18n.__('Running Value') },
];
}
}

View File

@@ -27,7 +27,8 @@ export default class JournalSheet extends FinancialSheet {
journal: IJournalPoster,
accountsGraph: any,
contactsById: Map<number | string, IContact>,
baseCurrency: string
baseCurrency: string,
i18n
) {
super();
@@ -38,6 +39,7 @@ export default class JournalSheet extends FinancialSheet {
this.accountsGraph = accountsGraph;
this.contactsById = contactsById;
this.baseCurrency = baseCurrency;
this.i18n = i18n;
}
/**
@@ -96,7 +98,7 @@ export default class JournalSheet extends FinancialSheet {
date: groupEntry.date,
referenceType: groupEntry.referenceType,
referenceId: groupEntry.referenceId,
referenceTypeFormatted: groupEntry.referenceTypeFormatted,
referenceTypeFormatted: this.i18n.__(groupEntry.referenceTypeFormatted),
entries: this.entriesMapper(entriesGroup),

View File

@@ -70,6 +70,7 @@ export default class JournalSheetService {
* @param {IJournalSheetFilterQuery} query
*/
async journalSheet(tenantId: number, query: IJournalReportQuery) {
const i18n = this.tenancy.i18n(tenantId);
const {
accountRepository,
transactionsRepository,
@@ -120,7 +121,8 @@ export default class JournalSheetService {
transactionsJournal,
accountsGraph,
contactsByIdMap,
baseCurrency
baseCurrency,
i18n
);
// Retrieve journal report columns.
const journalSheetData = journalSheetInstance.reportData();

View File

@@ -0,0 +1,29 @@
import HasTenancyService from 'services/Tenancy/TenancyService';
import { Service, Inject } from 'typedi';
@Service()
export default class I18nService {
@Inject()
tenancy: HasTenancyService;
/**
* Mappes array collection to i18n localization based in given attributes.
* @param {Array<any>} data - Array collection.
* @param {string[]} attributes - Attributes.
* @param {number} tenantId - Tenant id.
*/
public i18nMapper(
data: Array<any>,
attributes: string[] = [],
tenantId: number
) {
const i18n = this.tenancy.i18n(tenantId);
return data.map((_data) => {
return {
label: i18n.__(_data.label),
..._data,
};
});
}
}