Analytics Catalog/Oracle Fusion ERP/Expenses/Track Germany Per Diem Report
Explore the catalogReportsModulesEnterprise modelOTBI subject areasBICC PVOs
Oracle Fusion · Expenses

Track Germany Per Diem Report

Expenses

Tracks per-diem expenses against German statutory rates — meal and accommodation allowances by trip and day, with the meal-provided deductions German tax rules require — so reimbursements stay compliant with local per-diem law.

Sample build of the Track Germany Per Diem Report — reconciled, and rendered tool-neutral so it runs in Power BI, ThoughtSpot, or Tableau.

Track Germany Per Diem Report
Sample build · illustrative
Filters
Extype
Standard
From Acct Date
2026-02-28
Merchant Name
Globex Holdings
Person Id
1003
To Acct Date
2026-02-28
218
Per-diem trips
97.7%
Within statutory rate
5
Over statutory
EmployeeTripDatePer Diem TypeStatutory RateClaimedMeal Deduction
SampleSample2026-04-30StandardSampleSampleSample
2026-03-31Corporate
SampleSample2026-02-28StandardSampleSampleSample
2026-01-31Default
SampleSample2025-12-31StandardSampleSampleSample
SampleSample2026-04-30StandardSampleSampleSample
AI Analyst · active
reading

The report reads EXM_EXPENSE_PERDIEM_DETAILS against the German rate tables, applying the meal-provided deductions per day.

flag

Five trips claim above the statutory per-diem rate — in Germany the excess is taxable to the employee, so it must go to payroll rather than be reimbursed tax-free.

root cause & next step

Route the over-rate amounts to payroll as taxable per-diem; recurring overages usually mean the rate table needs the current-year statutory update.

Illustrative data. The live interactive version — drill-through, filters, export, and the AI Analyst — runs on your warehouse. See it live →

This is the report's BI Publisher data model — the SQL data set BI Publisher runs against Oracle tables to produce the output. The same SQL becomes a dbt model in your warehouse, so one definition drives both the formatted report and the analytics layer.

Data sources

How it interconnects: this data set reads the physical tables above. Those same tables surface in OTBI as subject areas and in BICC as PVOs — three lenses on one source. Open any table to trace its subject areas and View Objects.
SQL data set · genericized · parameterized · no hardcoded segments
Show / hide SQL
SELECT 
 EMPLOYEE_ID
,ACC_STAT
,EMPLOYEE_NAME
,EXP_INVOICE_NUM
,INVOICE_DATE
,ACCOUNTING_DATE
,EXP_RECEIPT_DATE
,PERSON_ID
,RECEIPT_DATE
,EXPENSE_TYPE
,STATUS
,JUSTIFICATION
,MERCHANT_NAME
,LOCATION
,ATTENDEE_TYPE
,ATTENDEE_NAME
,EXP_AMOUNT
,PERDIEM_AMOUNT
,MEALS_AMT
,MEALS_REPORT
,MEALS_EXP_TYP
,PERDIEM_START_DATE
,PERDIEM_END_DATE
,PERDIEM_RATE
,EXPENSE_TYPE_CATEGORY_CODE
,EXTRA_MEALS
,MEALS_BREAKFAST_CODE
,MEALS_LUNCH_CODE
,MEALS_DINNER_CODE
,NON_MEAL_EXP_TYP
,PERDIEM_POLICY_ID
,DESCRIPTION
,DESCPERDIEM
,(NVL(EXTRA_MEALS,0)-(CASE WHEN upper(DESCPERDIEM) LIKE upper('%Breakfast%') THEN (PERDIEM_RATE*0.2)
     WHEN upper(DESCPERDIEM) LIKE upper('%Lunch%') THEN (PERDIEM_RATE*0.4)
     WHEN upper(DESCPERDIEM) LIKE upper('%Dinner%') THEN (PERDIEM_RATE*0.4)
     ELSE FREE_MEALS_DEDUCT_AMOUNT
END)) EXCEEDING_PERDIEM

FROM (

WITH NON_PERDIEM AS
(SELECT 
sum(EE.RECEIPT_AMOUNT) RECEIPT_AMOUNT,
TRUNC(EE.START_DATE) RECEIPT_DATE,
EE.person_id,
EE.EXPENSE_REPORT_ID,
EET.NAME Expense_type,

EER.EXPENSE_REPORT_NUM,
NVL((SELECT EET_Meal.DESCRIPTION  FROM exm_expense_types EET_Meal,exm_expenses Exp_Meal WHERE EET_Meal.EXPENSE_TYPE_ID = Exp_MEAL.EXPENSE_TYPE_ID AND Exp_Meal.EXPENSE_TYPE_CATEGORY_CODE = 'PER_DIEM' AND Exp_Meal.EXPENSE_REPORT_ID = EER.EXPENSE_REPORT_ID),EET.NAME) Non_Meal_Exp_Typ

FROM
exm_EXPENSES EE,
exm_expense_types EET,
EXM_EXPENSE_REPORTS EER
WHERE
EE.EXPENSE_TYPE_CATEGORY_CODE = 'MEALS'
--AND EET.NAME IN ('Breakfast','Lunch','Dinner')
AND EE.EXPENSE_REPORT_ID = EER.EXPENSE_REPORT_ID
AND EET.EXPENSE_TYPE_ID = EE.EXPENSE_TYPE_ID
GROUP BY
TRUNC(EE.START_DATE),
EE.person_id,
EE.EXPENSE_REPORT_ID,
EET.NAME,
EER.EXPENSE_REPORT_NUM,
EER.EXPENSE_REPORT_ID )

SELECT 
	PAPF.person_number EMPLOYEE_ID,
	AP_INVOICES_PKG.GET_POSTING_STATUS(AIA.INVOICE_ID) Acc_Stat,
	PPNFV.DISPLAY_NAME EMPLOYEE_NAME,
	NVL(AIA.INVOICE_NUM,EER.EXPENSE_REPORT_NUM) EXP_INVOICE_NUM,
	AIA.INVOICE_DATE,
	AIA.GL_DATE ACCOUNTING_DATE,
	EE.START_DATE EXP_RECEIPT_DATE,
	PAPF.PERSON_ID,
--DECODE(EE.EXPENSE_TYPE_CATEGORY_CODE,'MEALS',EE.START_DATE,'PER_DIEM',EEP.START_DATE) RECEIPT_DATE,
	DECODE(EE.EXPENSE_TYPE_CATEGORY_CODE,'PER_DIEM',EEP.START_DATE,EE.START_DATE) RECEIPT_DATE,
	EET.NAME Expense_type,
	EER.EXPENSE_STATUS_CODE STATUS,EPP.PERDIEM_POLICY_ID,
	EE.JUSTIFICATION JUSTIFICATION,
	EE.MERCHANT_NAME MERCHANT_NAME,
	EE.LOCATION ,
	EEA.ATTENDEE_TYPE ATTENDEE_TYPE,
	EEA.name ATTENDEE_NAME,
	NVL(EEP.MEALS_ALLOWANCE_AMOUNT,EE.RECEIPT_AMOUNT) EXP_AMOUNT,
	EEP.PERDIEM_AMOUNT PERDIEM_AMOUNT,
	MEALS.RECEIPT_AMOUNT Meals_AMT,
	MEALS.EXPENSE_REPORT_NUM Meals_Report,
	MEALS.Expense_type Meals_Exp_typ,
	EEP.START_DATE PERDIEM_START_DATE,
	EEP.END_DATE PERDIEM_END_DATE,
	EEP.PERDIEM_RATE,
        EET.DESCRIPTION ,
	EE.EXPENSE_TYPE_CATEGORY_CODE,
	(SELECT SUM(EE_MEALS.RECEIPT_AMOUNT)  FROM exm_EXPENSES EE_MEALS WHERE EE_MEALS.EXPENSE_REPORT_ID = EER.EXPENSE_REPORT_ID AND  EE_MEALS.person_id	= PAPF.person_id AND EE_MEALS.EXPENSE_TYPE_CATEGORY_CODE = 'MEALS'  AND TRUNC(EE_MEALS.START_DATE) = TRUNC(EEP.START_DATE)) Extra_Meals,

(SELECT DISTINCT EET1.DESCRIPTION
 FROM exm_EXPENSES EE_MEALS ,exm_expense_types EET1
WHERE 1=1
AND EE_MEALS.EXPENSE_REPORT_ID = EER.EXPENSE_REPORT_ID 
AND  EE_MEALS.person_id	= PAPF.person_id 
AND EET1.EXPENSE_TYPE_ID = EE_MEALS.EXPENSE_TYPE_ID
AND EE_MEALS.EXPENSE_TYPE_CATEGORY_CODE = 'MEALS'  
AND TRUNC(EE_MEALS.START_DATE) = TRUNC(EEP.START_DATE)
) DESCPERDIEM,
	EEP.MEALS_BREAKFAST_CODE,
	EEP.MEALS_LUNCH_CODE,
	EEP.MEALS_DINNER_CODE,
	EEP.FREE_MEALS_DEDUCT_AMOUNT,
	MEALS.Non_Meal_Exp_Typ
	
	FROM
	EXM_EXPENSE_REPORTS EER,
	exm_EXPENSES EE,
	PER_PERSON_NAMES_F PPNFV,
	PER_ALL_PEOPLE_F PAPF,
	AP_INVOICES_ALL AIA,
	EXM_EXPENSE_PERDIEM_DETAILS EEP,
	exm_expense_types EET,
	EXM_EXPENSE_ATTENDEES EEA,
	HR_OPERATING_UNITS HOU,
	EXM_POL_EXP_TYPE_MAP EPM,
	EXM_PERDIEM_POLICIES EPP,
	NON_PERDIEM MEALS
	WHERE 1=1 
	AND EE.EXPENSE_REPORT_ID = EER.EXPENSE_REPORT_ID
	AND TRUNC(SYSDATE) BETWEEN TRUNC(PPNFV.EFFECTIVE_START_DATE) AND TRUNC(PPNFV.EFFECTIVE_END_DATE)
	AND TRUNC(SYSDATE) BETWEEN TRUNC(PAPF.effective_start_date) AND TRUNC(PAPF.effective_end_date)
	AND EE.person_id	= PPNFV.person_id
	AND EE.person_id	= PAPF.person_id
	AND PAPF.person_id = PPNFV.person_Id
	AND AIA.INVOICE_NUM (+)= EER.EXPENSE_REPORT_NUM
	AND AP_INVOICES_PKG.GET_POSTING_STATUS(AIA.INVOICE_ID) = 'Y'
	AND EEP.EXPENSE_ID(+) = EE.EXPENSE_ID
	AND PPNFV.name_type = 'GLOBAL'
	AND EET.EXPENSE_TYPE_ID = EE.EXPENSE_TYPE_ID
	AND HOU.ORGANIZATION_ID = EE.ORG_ID
	AND UPPER(HOU.NAME) = 'DE BU EUR'--'DE BU EUR'
	AND EE.expense_id = EEA.expense_id(+)
	AND EET.EXPENSE_TYPE_ID = EPM.EXPENSE_TYPE_ID(+)
	AND EPM.POLICY_ID = EPP.PERDIEM_POLICY_ID(+)
	AND MEALS.RECEIPT_DATE(+)  = EEP.START_DATE
	AND MEALS.PERSON_ID(+)  = EE.person_id
	AND MEALS.EXPENSE_TYPE(+)  = DECODE(EEP.MEALS_BREAKFAST_CODE,'INCLUDE','Breakfast',EEP.MEALS_LUNCH_CODE,'INCLUDE','Lunch',EEP.MEALS_DINNER_CODE,'INCLUDE','Dinner')
	AND MEALS.EXPENSE_REPORT_NUM(+) <> EER.EXPENSE_REPORT_NUM
	--AND NVL(MEALS.Non_Meal_Exp_Typ,EET.NAME) = EET.NAME
	
	AND (CASE WHEN MEALS.Non_Meal_Exp_Typ LIKE 'PER DIEM%' THEN MEALS.Non_Meal_Exp_Typ ELSE EET.NAME end) = EET.NAME

	AND (EET.NAME IN (:P_EXP_TYPE) OR 'All' IN ('All'||:P_EXP_TYPE))
	AND (EE.MERCHANT_NAME IN (:P_MERCHANT_NAME) OR 'All' IN ('All'||:P_MERCHANT_NAME))
	AND (PPNFV.person_id IN (:P_PERSON_ID) OR 'All' IN ('All'||:P_PERSON_ID))
	AND TRUNC(AIA.GL_DATE) BETWEEN TRUNC(:P_FROM_ACCT_DATE) AND TRUNC(:P_TO_ACCT_DATE)
	ORDER BY EER.EXPENSE_REPORT_NUM, ACCOUNTING_DATE)
:P_EXP_TYPE :P_FROM_ACCT_DATE :P_MERCHANT_NAME :P_PERSON_ID :P_TO_ACCT_DATE

The data-warehouse model — one fact surrounded by conformed dimensions (what you slice by) and measures (what you aggregate), expressed as dbt so it migrates with you. Grain: one row per source transaction.

EXM_EXPENSESdimensionEXM_EXPENSE_REPORTSdimensionPER_PERSON_NAMES_FdimensionPER_ALL_PEOPLE_FdimensionEXM_EXPENSE_TYPESfact · one row per source transactionAmount
●— fact → dimension join
ElementTypeDefinition
EXM_EXPENSESdimensiondimension
EXM_EXPENSE_REPORTSdimensiondimension
PER_PERSON_NAMES_Fdimensiondimension
PER_ALL_PEOPLE_Fdimensiondimension
Amountmeasuremeasure
Runs on your cloud warehouse — Snowflake, BigQuery, Redshift, or Synapse on AWS, Google Cloud, Azure, or any provider. Reconciled to the source control total — 0% variance by design. You own the code, the model, and the data.
How the data gets here: a BICC bulk extract of the source tables above, on the same pattern for every report. See the extraction pattern & data flow →
See the complete model
How this report's fact and dimensions fit the full picture, via conformed keys.
Expenses data model →Enterprise model →

Every source object behind this report. Each linked table has its own page with full column descriptions, drawn from the Oracle BICC lineage and articulated for practitioners.

TableReporting columnsSubject areas
EXM_EXPENSE_TYPES12
EXM_EXPENSES361
EXM_EXPENSE_REPORTS161
PER_PERSON_NAMES_F1600
PER_ALL_PEOPLE_F10526
AP_INVOICES_ALL6315
EXM_EXPENSE_PERDIEM_DETAILSSetup / configuration table — joined for reference, not exposed for analytics
EXM_EXPENSE_ATTENDEESSetup / configuration table — joined for reference, not exposed for analytics
HR_OPERATING_UNITSSetup / configuration table — joined for reference, not exposed for analytics
EXM_POL_EXP_TYPE_MAPSetup / configuration table — joined for reference, not exposed for analytics
EXM_PERDIEM_POLICIESSetup / configuration table — joined for reference, not exposed for analytics
NON_PERDIEMSetup / configuration table — joined for reference, not exposed for analytics
Reporting columns = fields the report selects that are exposed as analytics attributes; subject areas = the OTBI subject areas the table appears in. Setup and configuration tables (master data, ledger and book setup, lookups) are referenced by the report's joins but aren't exposed as analytics columns or subject areas — that's expected, not a gap.