diff --git a/Admin/Install/Coa/SKR03_DE_GAAP_SALES_COST.json b/Admin/Install/Coa/SKR03_DE_GAAP_SALES_COST.json new file mode 100644 index 0000000..43e6fab --- /dev/null +++ b/Admin/Install/Coa/SKR03_DE_GAAP_SALES_COST.json @@ -0,0 +1,271 @@ +[ + { + "name": "1", + "l11n": { + "en": "Turnover", + "de": "Umsatzerlöse" + }, + "account": [2750,2751,2752,2753,2754,2764], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "2", + "l11n": { + "en": "Cost of sales for services rendered to generate revenue", + "de": "Herstellungskosten der zur Erzielung der Umsatzerlöse erbrachten Leistungen" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "3", + "l11n": { + "en": "Gross profit on sales", + "de": "Bruttoergebnis vom Umsatz" + }, + "account": [], + "type": "formula", + "formula": "1-2", + "style": "subtotal", + "children": [] + }, + { + "name": "4", + "l11n": { + "en": "Distribution costs", + "de": "Vertriebskosten" + }, + "account": [2315,2316,2317,2318,2500,2501,2504,2508,2510,2520,2590,2594,2660,2661,2666,2700,2705,2707,2709,2710,2711,2712,2713,2714,2715,2716,2720,2723,2725,2726,2727,2728,2729,2730,2731,2732,2735,2736,2737,2740,2741,2742,2743,2744,2746,2747,2749,2760,2762,2790,2745,2746,2747,2749], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "5", + "l11n": { + "en": "General administrative expenses", + "de": "Allgemeine Verwaltungskosten" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "6", + "l11n": { + "en": "Other operating earnings", + "de": "Sonstige betriebliche Erträge" + }, + "account": [2315,2316,2317,2318,2500,2501,2504,2508,2510,2520,2590,2594,2660,2661,2666,2700,2705,2707,2709,2710,2711,2712,2713,2714,2715,2716,2720,2723,2725,2726,2727,2728,2729,2730,2731,2732,2735,2736,2737,2740,2741,2742,2743,2744,2746,2747,2749,2760,2762,2790,2745,2746,2747,2749], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "7", + "l11n": { + "en": "Other operating expenses", + "de": "Sonstige betriebliche Aufwendungen" + }, + "account": [2150,2151,2166,2170,2171,2174,2175,2176,2300,2307,2308,2309,2310,2311,2312,2313,2320,2323,2325,2326,2327,2328,2339,2342,2343,2344,2345,2347,2350,2380,2381,2382,2383,2384,2385,2386,2387,2389,2390,2400,2401,2402,2403,2404,2405,2406,2407,2408,2409,2450,2451,2490,2890,2891,2892,2893,2894,2895,2900], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "8", + "l11n": { + "en": "Income from participating interests", + "de": "Erträge aus Beteiligungen" + }, + "account": [2480,2491,2492,2493,2494,2495,2496,2497,2498,2499,2600,2603,2613,2614,2615,2616,2618,2619,2792,2794], + "type": "category", + "formula": "", + "style": "category", + "children": [ + { + "name": "9thereof", + "l11n": { + "en": "thereof derived from affiliated undertakings", + "de": "davon aus verbundenen Unternehmen" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + } + ] + }, + { + "name": "9", + "l11n": { + "en": "Income from other investments and loans forming part of the financial assets", + "de": "Erträge aus anderen Wertpapieren und Ausleihungen des Finanzanlagevermögens" + }, + "account": [2620,2621,2622,2623,2625,2626,2640,2641,2646,2647,2648,2649], + "type": "category", + "formula": "", + "style": "category", + "children": [ + { + "name": "10thereof", + "l11n": { + "en": "thereof derived from affiliated undertakings", + "de": "davon aus verbundenen Unternehmen" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + } + ] + }, + { + "name": "10", + "l11n": { + "en": "Other interest receivable and similar income", + "de": "Sonstige Zinsen und ähnliche Erträge" + }, + "account": [2650,2653,2654,2655,2656,2657,2658,2659,2670,2679,2680,2682,2683,2684,2685,2686,2687,2688,2689], + "type": "category", + "formula": "", + "style": "category", + "children": [ + { + "name": "11thereof", + "l11n": { + "en": "thereof derived from affiliated undertakings", + "de": "davon aus verbundenen Unternehmen" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + } + ] + }, + { + "name": "11", + "l11n": { + "en": "Depreciations of financial assets and of investment securities forming part of the current assets", + "de": "Abschreibungen auf Finanzanlagen und auf Wertpapiere des Umlaufvermögens" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "12", + "l11n": { + "en": "Interest payable and similar expenses", + "de": "Zinsen und ähnliche Aufwendungen," + }, + "account": [2105,2106,2107,2108,2109,2110,2111,2113,2114,2115,2116,2117,2118,2119,2120,2123,2124,2125,2126,2127,2128,2129,2130,2139,2140,2141,2142,2143,2144,2145,2146,2147,2148,2149], + "type": "category", + "formula": "", + "style": "category", + "children": [ + { + "name": "13thereof", + "l11n": { + "en": "thereof derived from affiliated undertakings", + "de": "davon aus verbundenen Unternehmen" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + } + ] + }, + { + "name": "13", + "l11n": { + "en": "Taxes on income and earnings", + "de": "Steuern vom Einkommen und vom Ertrag" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [ + { + "name": "13a", + "l11n": { + "en": "Current", + "de": "Tatsächliche Steuern" + }, + "account": [2200,2203,2204,2208,2209,2210,2213,2216,2218,2219,2250,2255,2260,2265,2281,2283], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "13b", + "l11n": { + "en": "Deferred", + "de": "Latente Steuern" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + } + ] + }, + { + "name": "14", + "l11n": { + "en": "Profit or loss after taxes", + "de": "Ergebnis nach Steuern" + }, + "account": [], + "type": "formula", + "formula": "1+2+3+4+5+6+7+8+9+10+11+12+13", + "style": "subtotal", + "children": [] + }, + { + "name": "15", + "l11n": { + "en": "Other taxes", + "de": "Sonstige Steuern" + }, + "account": [2285,2287,2289,2375], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "16", + "l11n": { + "en": "Net income for the year / net loss for the year", + "de": "Jahresüberschuss/Jahresfehlbetrag" + }, + "account": [], + "type": "formula", + "formula": "14+15", + "style": "total", + "children": [] + } +] \ No newline at end of file diff --git a/Admin/Install/Coa/SKR03_DE_GAAP_TOTAL_COST.json b/Admin/Install/Coa/SKR03_DE_GAAP_TOTAL_COST.json new file mode 100644 index 0000000..06e1188 --- /dev/null +++ b/Admin/Install/Coa/SKR03_DE_GAAP_TOTAL_COST.json @@ -0,0 +1,395 @@ +[ + { + "name": "1", + "l11n": { + "en": "Turnover", + "de": "Umsatzerlöse" + }, + "account": [2750,2751,2752,2753,2754,2764], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "2", + "l11n": { + "en": "Increase or reduction of stocks of finished goods and work in progress", + "de": "Erhöhung oder Verminderung des Bestands an fertigen und unfertigen Erzeugnissen" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "3", + "l11n": { + "en": "Work performed by the undertaking for its own purposes and carried as an asset", + "de": "Andere aktivierte Eigenleistungen" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "4", + "l11n": { + "en": "Other operating earnings", + "de": "Sonstige betriebliche Erträge" + }, + "account": [2315,2316,2317,2318,2500,2501,2504,2508,2510,2520,2590,2594,2660,2661,2666,2700,2705,2707,2709,2710,2711,2712,2713,2714,2715,2716,2720,2723,2725,2726,2727,2728,2729,2730,2731,2732,2735,2736,2737,2740,2741,2742,2743,2744,2746,2747,2749,2760,2762,2790,2745,2746,2747,2749], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "5", + "l11n": { + "en": "Expenditures on materials", + "de": "Materialaufwand" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [ + { + "name": "5a", + "l11n": { + "en": "Expenditures for raw materials, auxiliary supplies and consumables and for purchased goods", + "de": "Aufwendungen für Roh-, Hilfs- und Betriebsstoffe und für bezogene Waren" + }, + "account": [3000,3010,3011,3012,3013,3014,3015,3016,3017,3018,3019,3020,3021,3022,3023,3024,3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037,3038,3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,3051,3052,3053,3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066,3067,3068,3069,3070,3071,3072,3073,3074,3075,3076,3077,3078,3079,3080,3081,3082,3083,3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095,3096,3097,3098,3200,3300,3301,3302,3303,3304,3305,3306,3307,3308,3309,3310,3311,3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323,3324,3325,3326,3327,3328,3329,3330,3331,3332,3333,3334,3335,3336,3337,3338,3339,3340,3341,3342,3343,3344,3345,3346,3347,3348,3349,3400,3401,3402,3403,3404,3405,3406,3407,3408,3409,3410,3411,3412,3413,3414,3415,3416,3417,3418,3419,3420,3421,3422,3423,3424,3425,3426,3427,3428,3429,3430,3431,3432,3433,3434,3435], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "5b", + "l11n": { + "en": "Expenditures for purchased services", + "de": "Aufwendungen für bezogene Leistungen" + }, + "account": [3100,3106,3107,3108,3109,3110,3111,3112,3113,3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3124,3125,3126,3127,3128,3129,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140,3141,3142,3143,3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156,3157,3158,3159,3160,3165,3170,3175,3180,3185], + "type": "category", + "formula": "", + "style": "category", + "children": [] + } + ] + }, + { + "name": "GP", + "l11n": { + "en": "Gross profit", + "de": "Rohertrag" + }, + "account": [], + "type": "formula", + "formula": "1+2+3+4+5", + "style": "subtotal", + "children": [] + }, + { + "name": "GPratio", + "l11n": { + "en": "Gross profit ratio", + "de": "Rohertragsmarge" + }, + "account": [], + "type": "formula", + "formula": "GP/(1+2+3+4)", + "style": "ratio", + "children": [] + }, + { + "name": "6", + "l11n": { + "en": "Staff costs", + "de": "Personalaufwand" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [ + { + "name": "6a", + "l11n": { + "en": "Wages and salaries", + "de": "Löhne und Gehälter" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "6b", + "l11n": { + "en": "Social security contributions and expenditures for old-age pension schemes and for support", + "de": "soziale Abgaben und Aufwendungen für Altersversorgung und für Unterstützung" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [ + { + "name": "6bthereof", + "l11n": { + "en": "thereof relating to the old-age pension scheme", + "de": "davon für Altersversorgung" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + } + ] + } + ] + }, + { + "name": "7", + "l11n": { + "en": "Amortisations / depreciations", + "de": "Abschreibungen" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [ + { + "name": "7a", + "l11n": { + "en": "Intangible assets forming part of the fixed assets and of tangible fixed assets", + "de": "auf immaterielle Vermögensgegenstände des Anlagevermögens und Sachanlage" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "7b", + "l11n": { + "en": "Assets reported as part of the current assets, to the extent that they exceed the depreciations customarily stated for the share capital company", + "de": "auf Vermögensgegenstände des Umlaufvermögens, soweit diese die in der Kapitalgesellschaft üblichen Abschreibungen überschreiten" + }, + "account": [2430,2431,2432,2433,2434,2345,2436,2437,2438,2440,2441], + "type": "category", + "formula": "", + "style": "category", + "children": [] + } + ] + }, + { + "name": "8", + "l11n": { + "en": "Other operating expenses", + "de": "Sonstige betriebliche Aufwendungen" + }, + "account": [2150,2151,2166,2170,2171,2174,2175,2176,2300,2307,2308,2309,2310,2311,2312,2313,2320,2323,2325,2326,2327,2328,2339,2342,2343,2344,2345,2347,2350,2380,2381,2382,2383,2384,2385,2386,2387,2389,2390,2400,2401,2402,2403,2404,2405,2406,2407,2408,2409,2450,2451,2490,2890,2891,2892,2893,2894,2895,2900], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "9", + "l11n": { + "en": "Income from participating interests", + "de": "Erträge aus Beteiligungen" + }, + "account": [2480,2491,2492,2493,2494,2495,2496,2497,2498,2499,2600,2603,2613,2614,2615,2616,2618,2619,2792,2794], + "type": "category", + "formula": "", + "style": "category", + "children": [ + { + "name": "9thereof", + "l11n": { + "en": "thereof derived from affiliated undertakings", + "de": "davon aus verbundenen Unternehmen" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + } + ] + }, + { + "name": "10", + "l11n": { + "en": "Income from other investments and loans forming part of the financial assets", + "de": "Erträge aus anderen Wertpapieren und Ausleihungen des Finanzanlagevermögens" + }, + "account": [2620,2621,2622,2623,2625,2626,2640,2641,2646,2647,2648,2649], + "type": "category", + "formula": "", + "style": "category", + "children": [ + { + "name": "10thereof", + "l11n": { + "en": "thereof derived from affiliated undertakings", + "de": "davon aus verbundenen Unternehmen" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + } + ] + }, + { + "name": "11", + "l11n": { + "en": "Other interest receivable and similar income", + "de": "Sonstige Zinsen und ähnliche Erträge" + }, + "account": [2650,2653,2654,2655,2656,2657,2658,2659,2670,2679,2680,2682,2683,2684,2685,2686,2687,2688,2689], + "type": "category", + "formula": "", + "style": "category", + "children": [ + { + "name": "11thereof", + "l11n": { + "en": "thereof derived from affiliated undertakings", + "de": "davon aus verbundenen Unternehmen" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + } + ] + }, + { + "name": "12", + "l11n": { + "en": "Depreciations of financial assets and of investment securities forming part of the current assets", + "de": "Abschreibungen auf Finanzanlagen und auf Wertpapiere des Umlaufvermögens" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "13", + "l11n": { + "en": "Interest payable and similar expenses", + "de": "Zinsen und ähnliche Aufwendungen," + }, + "account": [2105,2106,2107,2108,2109,2110,2111,2113,2114,2115,2116,2117,2118,2119,2120,2123,2124,2125,2126,2127,2128,2129,2130,2139,2140,2141,2142,2143,2144,2145,2146,2147,2148,2149], + "type": "category", + "formula": "", + "style": "category", + "children": [ + { + "name": "13thereof", + "l11n": { + "en": "thereof derived from affiliated undertakings", + "de": "davon aus verbundenen Unternehmen" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + } + ] + }, + { + "name": "14", + "l11n": { + "en": "Taxes on income and earnings", + "de": "Steuern vom Einkommen und vom Ertrag" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [ + { + "name": "14a", + "l11n": { + "en": "Current", + "de": "Tatsächliche Steuern" + }, + "account": [2200,2203,2204,2208,2209,2210,2213,2216,2218,2219,2250,2255,2260,2265,2281,2283], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "14b", + "l11n": { + "en": "Deferred", + "de": "Latente Steuern" + }, + "account": [], + "type": "category", + "formula": "", + "style": "category", + "children": [] + } + ] + }, + { + "name": "15", + "l11n": { + "en": "Profit or loss after taxes", + "de": "Ergebnis nach Steuern" + }, + "account": [], + "type": "formula", + "formula": "1+2+3+4+5+6+7+8+9+10+11+12+13+14", + "style": "subtotal", + "children": [] + }, + { + "name": "16", + "l11n": { + "en": "Other taxes", + "de": "Sonstige Steuern" + }, + "account": [2285,2287,2289,2375], + "type": "category", + "formula": "", + "style": "category", + "children": [] + }, + { + "name": "17", + "l11n": { + "en": "Net income for the year / net loss for the year", + "de": "Jahresüberschuss/Jahresfehlbetrag" + }, + "account": [], + "type": "formula", + "formula": "15+16", + "style": "total", + "children": [] + } +] \ No newline at end of file diff --git a/Admin/Install/db.json b/Admin/Install/db.json new file mode 100644 index 0000000..6ab2ed9 --- /dev/null +++ b/Admin/Install/db.json @@ -0,0 +1,91 @@ +{ + "incomestmt_pl": { + "name": "incomestmt_pl", + "fields": { + "incomestmt_pl_id": { + "name": "incomestmt_pl_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "incomestmt_pl_code": { + "name": "incomestmt_pl_code", + "type": "VARCHAR(255)", + "null": false + }, + "incomestmt_pl_name": { + "name": "incomestmt_pl_name", + "type": "VARCHAR(255)", + "null": false + } + } + }, + "incomestmt_pl_element": { + "name": "incomestmt_pl_element", + "fields": { + "incomestmt_pl_element_id": { + "name": "incomestmt_pl_element_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "incomestmt_pl_element_code": { + "name": "incomestmt_pl_element_code", + "type": "VARCHAR(255)", + "null": false + }, + "incomestmt_pl_element_order": { + "name": "incomestmt_pl_element_order", + "type": "INT", + "null": false + }, + "incomestmt_pl_element_parent": { + "name": "incomestmt_pl_element_parent", + "type": "INT", + "null": true, + "foreignTable": "incomestmt_pl_element", + "foreignKey": "incomestmt_pl_element_id" + }, + "incomestmt_pl_element_pl": { + "name": "incomestmt_pl_element_pl", + "type": "INT", + "null": false, + "foreignTable": "incomestmt_pl", + "foreignKey": "incomestmt_pl_id" + } + } + }, + "incomestmt_pl_element_l11n": { + "name": "incomestmt_pl_element_l11n", + "fields": { + "incomestmt_pl_element_l11n_id": { + "name": "incomestmt_pl_element_l11n_id", + "type": "INT", + "null": false, + "primary": true, + "autoincrement": true + }, + "incomestmt_pl_element_l11n_title": { + "name": "incomestmt_pl_element_l11n_title", + "type": "VARCHAR(255)", + "null": false + }, + "incomestmt_pl_element_l11n_element": { + "name": "incomestmt_pl_element_l11n_element", + "type": "INT(11)", + "null": false, + "foreignTable": "incomestmt_pl_element", + "foreignKey": "incomestmt_pl_element_id" + }, + "incomestmt_pl_element_l11n_lang": { + "name": "incomestmt_pl_element_l11n_lang", + "type": "VARCHAR(2)", + "null": false, + "foreignTable": "language", + "foreignKey": "language_639_1" + } + } + } +} \ No newline at end of file diff --git a/Admin/Installer.php b/Admin/Installer.php index 2fe095a..d14a294 100644 --- a/Admin/Installer.php +++ b/Admin/Installer.php @@ -14,7 +14,14 @@ declare(strict_types=1); namespace Modules\IncomeStatement\Admin; +use Modules\IncomeStatement\Controller\ApiController; +use phpOMS\Application\ApplicationAbstract; +use phpOMS\Config\SettingsInterface; +use phpOMS\Message\Http\HttpRequest; +use phpOMS\Message\Http\HttpResponse; use phpOMS\Module\InstallerAbstract; +use phpOMS\Module\ModuleInfo; +use phpOMS\Uri\HttpUri; /** * Installer class. @@ -33,4 +40,110 @@ final class Installer extends InstallerAbstract * @since 1.0.0 */ public const PATH = __DIR__; + + /** + * {@inheritdoc} + */ + public static function install(ApplicationAbstract $app, ModuleInfo $info, SettingsInterface $cfgHandler) : void + { + parent::install($app, $info, $cfgHandler); + + self::importStructures($app); + } + + /** + * Import accounts + * + * @param ApplicationAbstract $app Application + * + * @return void + * + * @since 1.0.0 + */ + private static function importStructures(ApplicationAbstract $app) : void + { + /** @var \Modules\IncomeStatement\Controller\ApiController $module */ + $module = $app->moduleManager->getModuleInstance('IncomeStatement', 'Api'); + + $structures = \scandir(__DIR__ . '/Install/Coa'); + foreach ($structures as $file) { + if ($file === '..' || $file === '.') { + continue; + } + + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('code', \strtolower(\basename($file))); + $request->setData('name', \strtr(\basename($file), '_', ' ')); + + $module->apiIncomeStatementCreate($request, $response); + $responseData = $response->getData(''); + + $incomeStatement = \is_array($responseData['response']) + ? $responseData['response'] + : $responseData['response']->toArray(); + + $json = \json_decode(\file_get_contents(__DIR__ . '/Install/Coa/' . $file), true); + + foreach ($json as $element) { + self::createElement($module, [$element], (int) $incomeStatement['id'], null); + } + } + } + + private static function createElement(ApiController $module, array $elements, int $structure, int $parent = null) + { + $order = 0; + foreach ($elements as $element) { + ++$order; + + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('code', $element['name']); + $request->setData('content', \reset($element['l11n'])); + $request->setData('language', \array_keys($element['l11n'])[0] ?? 'en'); + $request->setData('accounts', \implode(',', $element['account'])); + $request->setData('formula', $element['formula']); + $request->setData('type', $element['type']); + $request->setData('pl', $structure); + $request->setData('order', $order); + + if ($parent !== null) { + $request->setData('parent', $parent); + } + + $module->apiIncomeStatementElementCreate($request, $response); + $responseData = $response->getData(''); + + $incomeStatementElement = \is_array($responseData['response']) + ? $responseData['response'] + : $responseData['response']->toArray(); + + $isFirst = true; + foreach ($element['l11n'] as $language => $l11n) { + if ($isFirst) { + $isFirst = false; + continue; + } + + $response = new HttpResponse(); + $request = new HttpRequest(new HttpUri('')); + + $request->header->account = 1; + $request->setData('title', $l11n); + $request->setData('language', $language); + $request->setData('ref', $incomeStatementElement['id']); + + $module->apiIncomeStatementElementL11nCreate($request, $response); + } + + if (!empty($element['children'])) { + self::createElement($module, $element['children'], $structure, $incomeStatementElement['id']); + } + } + } } diff --git a/Controller/ApiController.php b/Controller/ApiController.php new file mode 100644 index 0000000..af6c225 --- /dev/null +++ b/Controller/ApiController.php @@ -0,0 +1,243 @@ +validateIncomeStatementCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); + + return; + } + + $pl = $this->createIncomeStatementFromRequest($request); + $this->createModel($request->header->account, $pl, IncomeStatementMapper::class, 'pl', $request->getOrigin()); + $this->createStandardCreateResponse($request, $response, $pl); + } + + /** + * Validate pl create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateIncomeStatementCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['code'] = !$request->hasData('code')) + || ($val['name'] = !$request->hasData('name')) + ) { + return $val; + } + + return []; + } + + /** + * Method to create pl from request. + * + * @param RequestAbstract $request Request + * + * @return IncomeStatement + * + * @since 1.0.0 + */ + private function createIncomeStatementFromRequest(RequestAbstract $request) : IncomeStatement + { + $pl = new IncomeStatement(); + $pl->code = (string) $request->getData('code'); + $pl->name = (string) $request->getData('name'); + + return $pl; + } + + /** + * Api method to create an account + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param array $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiIncomeStatementElementCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void + { + if (!empty($val = $this->validateIncomeStatementElementCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); + + return; + } + + $element = $this->createIncomeStatementElementFromRequest($request); + $this->createModel($request->header->account, $element, IncomeStatementElementMapper::class, 'pl_element', $request->getOrigin()); + $this->createStandardCreateResponse($request, $response, $element); + } + + /** + * Validate account create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateIncomeStatementElementCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['pl'] = !$request->hasData('pl')) + || ($val['code'] = !$request->hasData('code')) + || ($val['content'] = !$request->hasData('content')) + ) { + return $val; + } + + return []; + } + + /** + * Method to create account from request. + * + * @param RequestAbstract $request Request + * + * @return IncomeStatementElement + * + * @since 1.0.0 + */ + private function createIncomeStatementElementFromRequest(RequestAbstract $request) : IncomeStatementElement + { + $element = new IncomeStatementElement(); + $element->code = $request->getDataString('code') ?? ''; + $element->incomeStatement = $request->getDataInt('pl') ?? 0; + $element->order = $request->getDataInt('order') ?? 0; + + $element->setL11n($request->getDataString('content') ?? '', $request->getDataString('language') ?? ISO639x1Enum::_EN); + + return $element; + } + + /** + * Api method to create item attribute l11n + * + * @param RequestAbstract $request Request + * @param ResponseAbstract $response Response + * @param array $data Generic data + * + * @return void + * + * @api + * + * @since 1.0.0 + */ + public function apiIncomeStatementElementL11nCreate(RequestAbstract $request, ResponseAbstract $response, array $data = []) : void + { + if (!empty($val = $this->validateIncomeStatementElementL11nCreate($request))) { + $response->header->status = RequestStatusCode::R_400; + $this->createInvalidCreateResponse($request, $response, $val); + + return; + } + + $elementL11n = $this->createIncomeStatementElementL11nFromRequest($request); + $this->createModel($request->header->account, $elementL11n, IncomeStatementElementL11nMapper::class, 'pl_element_l11n', $request->getOrigin()); + $this->createStandardCreateResponse($request, $response, $elementL11n); + } + + /** + * Method to create item attribute l11n from request. + * + * @param RequestAbstract $request Request + * + * @return BaseStringL11n + * + * @since 1.0.0 + */ + private function createIncomeStatementElementL11nFromRequest(RequestAbstract $request) : BaseStringL11n + { + $elementL11n = new BaseStringL11n(); + $elementL11n->ref = $request->getDataInt('ref') ?? 0; + $elementL11n->setLanguage( + $request->getDataString('language') ?? $request->header->l11n->language + ); + $elementL11n->content = $request->getDataString('content') ?? ''; + + return $elementL11n; + } + + /** + * Validate item attribute l11n create request + * + * @param RequestAbstract $request Request + * + * @return array + * + * @since 1.0.0 + */ + private function validateIncomeStatementElementL11nCreate(RequestAbstract $request) : array + { + $val = []; + if (($val['content'] = !$request->hasData('content')) + || ($val['ref'] = !$request->hasData('ref')) + ) { + return $val; + } + + return []; + } +} \ No newline at end of file diff --git a/Controller/BackendController.php b/Controller/BackendController.php index c9304b3..08347ad 100644 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -14,7 +14,9 @@ declare(strict_types=1); namespace Modules\IncomeStatement\Controller; +use Modules\IncomeStatement\Models\IncomeStatementElementMapper; use phpOMS\Contract\RenderableInterface; +use phpOMS\DataStorage\Database\Query\OrderType; use phpOMS\Message\RequestAbstract; use phpOMS\Message\ResponseAbstract; use phpOMS\Views\View; @@ -44,9 +46,18 @@ final class BackendController extends Controller public function viewPLDashboard(RequestAbstract $request, ResponseAbstract $response, $data = null) : RenderableInterface { $view = new View($this->app->l11nManager, $request, $response); - $view->setTemplate('/Modules/PL/Theme/Backend/pl-dashboard'); + $view->setTemplate('/Modules/IncomeStatement/Theme/Backend/pl-dashboard'); $view->data['nav'] = $this->app->moduleManager->get('Navigation')->createNavigationMid(1006401001, $request, $response); + $elements = IncomeStatementElementMapper::getAll() + ->with('l11n') + ->where('incomeStatement', $request->getDataInt('pl') ?? 1) + ->where('l11n/language', $response->header->l11n->language) + ->sort('order', OrderType::ASC) + ->execute(); + + $view->data['elements'] = $elements; + return $view; } } diff --git a/Models/IncomeStatement.php b/Models/IncomeStatement.php new file mode 100644 index 0000000..98d93a0 --- /dev/null +++ b/Models/IncomeStatement.php @@ -0,0 +1,56 @@ + $this->id, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } +} diff --git a/Models/IncomeStatementElement.php b/Models/IncomeStatementElement.php new file mode 100644 index 0000000..b48a7fa --- /dev/null +++ b/Models/IncomeStatementElement.php @@ -0,0 +1,111 @@ +l11n = $l11n; + } elseif (isset($this->l11n) && $this->l11n instanceof BaseStringL11n) { + $this->l11n->content = $l11n; + $this->l11n->setLanguage($lang); + } else { + $this->l11n = new BaseStringL11n(); + $this->l11n->content = $l11n; + $this->l11n->setLanguage($lang); + } + } + + /** + * @return string + * + * @since 1.0.0 + */ + public function getL11n() : string + { + if (!isset($this->l11n)) { + return ''; + } + + return $this->l11n instanceof BaseStringL11n ? $this->l11n->content : $this->l11n; + } + + /** + * {@inheritdoc} + */ + public function toArray() : array + { + return [ + 'id' => $this->id, + ]; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return $this->toArray(); + } +} diff --git a/Models/IncomeStatementElementL11nMapper.php b/Models/IncomeStatementElementL11nMapper.php new file mode 100644 index 0000000..3698177 --- /dev/null +++ b/Models/IncomeStatementElementL11nMapper.php @@ -0,0 +1,69 @@ + + */ +final class IncomeStatementElementL11nMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'incomestmt_pl_element_l11n_id' => ['name' => 'incomestmt_pl_element_l11n_id', 'type' => 'int', 'internal' => 'id'], + 'incomestmt_pl_element_l11n_title' => ['name' => 'incomestmt_pl_element_l11n_title', 'type' => 'string', 'internal' => 'content', 'autocomplete' => true], + 'incomestmt_pl_element_l11n_element' => ['name' => 'incomestmt_pl_element_l11n_element', 'type' => 'int', 'internal' => 'ref'], + 'incomestmt_pl_element_l11n_lang' => ['name' => 'incomestmt_pl_element_l11n_lang', 'type' => 'string', 'internal' => 'language'], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'incomestmt_pl_element_l11n'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'incomestmt_pl_element_l11n_id'; + + /** + * Model to use by the mapper. + * + * @var class-string + * @since 1.0.0 + */ + public const MODEL = BaseStringL11n::class; +} diff --git a/Models/IncomeStatementElementMapper.php b/Models/IncomeStatementElementMapper.php new file mode 100644 index 0000000..30597de --- /dev/null +++ b/Models/IncomeStatementElementMapper.php @@ -0,0 +1,78 @@ + + */ +final class IncomeStatementElementMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'incomestmt_pl_element_id' => ['name' => 'incomestmt_pl_element_id', 'type' => 'int', 'internal' => 'id'], + 'incomestmt_pl_element_code' => ['name' => 'incomestmt_pl_element_code', 'type' => 'string', 'internal' => 'code', 'autocomplete' => true], + 'incomestmt_pl_element_order' => ['name' => 'incomestmt_pl_element_order', 'type' => 'int', 'internal' => 'order'], + 'incomestmt_pl_element_parent' => ['name' => 'incomestmt_pl_element_parent', 'type' => 'int', 'internal' => 'parent'], + 'incomestmt_pl_element_pl' => ['name' => 'incomestmt_pl_element_pl', 'type' => 'int', 'internal' => 'incomeStatement'], + ]; + + /** + * Has many relation. + * + * @var array + * @since 1.0.0 + */ + public const HAS_MANY = [ + 'l11n' => [ + 'mapper' => IncomeStatementElementL11nMapper::class, + 'table' => 'incomestmt_pl_element_l11n', + 'self' => 'incomestmt_pl_element_l11n_element', + 'column' => 'content', + 'external' => null, + ] + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'incomestmt_pl_element'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'incomestmt_pl_element_id'; +} diff --git a/Models/IncomeStatementMapper.php b/Models/IncomeStatementMapper.php new file mode 100644 index 0000000..277995b --- /dev/null +++ b/Models/IncomeStatementMapper.php @@ -0,0 +1,60 @@ + + */ +final class IncomeStatementMapper extends DataMapperFactory +{ + /** + * Columns. + * + * @var array + * @since 1.0.0 + */ + public const COLUMNS = [ + 'incomestmt_pl_id' => ['name' => 'incomestmt_pl_id', 'type' => 'int', 'internal' => 'id'], + 'incomestmt_pl_code' => ['name' => 'incomestmt_pl_code', 'type' => 'string', 'internal' => 'code', 'autocomplete' => true], + 'incomestmt_pl_name' => ['name' => 'incomestmt_pl_name', 'type' => 'string', 'internal' => 'name', 'autocomplete' => true], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + public const TABLE = 'incomestmt_pl'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + public const PRIMARYFIELD = 'incomestmt_pl_id'; +} diff --git a/Models/NullIncomeStatement.php b/Models/NullIncomeStatement.php new file mode 100644 index 0000000..5d7080e --- /dev/null +++ b/Models/NullIncomeStatement.php @@ -0,0 +1,46 @@ +id = $id; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return ['id' => $this->id]; + } +} diff --git a/Models/NullIncomeStatementElement.php b/Models/NullIncomeStatementElement.php new file mode 100644 index 0000000..2faaa4b --- /dev/null +++ b/Models/NullIncomeStatementElement.php @@ -0,0 +1,46 @@ +id = $id; + } + + /** + * {@inheritdoc} + */ + public function jsonSerialize() : mixed + { + return ['id' => $this->id]; + } +} diff --git a/Theme/Backend/pl-dashboard.tpl.php b/Theme/Backend/pl-dashboard.tpl.php index ddcd786..1aeb6a5 100644 --- a/Theme/Backend/pl-dashboard.tpl.php +++ b/Theme/Backend/pl-dashboard.tpl.php @@ -4,7 +4,7 @@ * * PHP Version 8.1 * - * @package Modules\PL + * @package Modules\IncomeStatement * @copyright Dennis Eichhorn * @license OMS License 2.0 * @version 1.0.0 @@ -13,3 +13,89 @@ declare(strict_types=1); echo $this->data['nav']->render(); +?> +
+
+
+
+
+
Category
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
12
+
12
+
Diff %
+
Diff USD
+
+
+
+
+ +data['elements'] as $element) : + if ($element->parent !== null) { + continue; + } +?> +
+
+
+
+
printHtml($element->getL11n()); ?>
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+0.00%
+
+ + + +
+
+