请注意,您收到的答案将是主观的。在此免责声明之后,这是我建立这样一个系统的方法。
TL;DR:使用货币汇率表来存储不同货币以及适用日期的货币汇率。同时将金额存储为本地货币和计算出的美元价值。
货币汇率表
创建一个形式为FX汇率的货币表:
FX_RATES
SOURCE_CURRENCY
TARGET_CURRENCY
EXCHANGE_RATE
VALID_FROM_DATE
VALID_TO_DATE
- 前4列的组合将表示唯一记录。
- 建议每当输入货币对(USD->GBP)的记录时,也插入等价的反向记录(GBP->USD),可以使用真实汇率(单向转换可能使用不同的汇率),也可以使用原始记录的倒数。
- 对于一对货币,连续的行必须展示日期的连贯性(即对于一对货币,永远不应该存在一个日期既不在
VALID_FROM_DATE
和VALID_TO_DATE
之间的行)。
- 为了方便起见,还要输入一行
('USD','USD',1,smallest_date,largest_date)
,其中包含数据库支持的最小和最大日期。这样可以更容易地处理以基础货币本身进行的输入情况。
- 您需要确定一个货币汇率源,用于向该表提供信息,并确定更新频率。例如,即使货币市场上的值每天都会发生变化,您的财务团队也可能发布每周的外汇汇率表。
示例表如下所示。尽管看起来有重叠的部分,但查找操作仅在一列上检查相等性(即>= VALID_FROM_DATE AND < VALID_TO_DATE
)
SOURCE_CURRENCY TARGET_CURRENCY EXCHANGE_RATE VALID_FROM_DATE VALID_TO_DATE
GBP USD 1.250000 06-Mar-2017 13-Mar-2017
GBP USD 1.260000 13-Mar-2017 20-Mar-2017
GBP USD 1.240000 20-Mar-2017 27-Mar-2017
GBP USD 1.250000 27-Mar-2017 03-Apr-2017
USD GBP 0.800000 06-Mar-2017 13-Mar-2017
USD GBP 0.793651 13-Mar-2017 20-Mar-2017
USD GBP 0.806452 20-Mar-2017 27-Mar-2017
USD GBP 0.800000 27-Mar-2017 03-Apr-2017
USD USD 1.000000 01-Jan-1900 31-Dec-9999
PO表中的列
在采购订单表中,保留以下字段:
PURCHASE_ORDERS
... other fields
PO_TXN_DATE
ORDER_VALUE_LOC
ORDER_CURRENCY_LOC
ORDER_VALUE_USD
... other fields
填充采购单列
已经有一个填充采购单表的流程,需要进行扩展以填充以下字段:
PO_TXN_DATE
代表采购单上的财务交易日期。根据您的业务规则,这可能是创建/提出采购单的日期,也可能不是。
ORDER_VALUE_LOC
是本地货币中交易的价值。
ORDER_CURRENCY_LOC
是本地货币的货币代码。
- 这三个字段将用于查找外汇汇率表。
ORDER_VALUE_USD
的填充是通过在 FX_RATES
表中查找汇率来完成的:
通过以下伪代码演示了填充 ORDER_VALUE_USD
:
ORDER_VALUE_USD = PURCHASE_ORDERS.ORDER_VALUE_LOC * FX_RATES.EXCHANGE_RATE
WHERE
FX_RATES.SOURCE_CURRENCY = PURCHASE_ORDERS.ORDER_CURRENCY_LOC
AND FX_RATES.TARGET_CURRENCY = 'USD'
AND PURCHASE_ORDERS.PO_TXN_DATE >= FX_RATES.VALID_FROM_DATE
AND PURCHASE_ORDERS.PO_TXN_DATE < FX_RATES.VALID_TO_DATE
OP问题的答案
Q1:应当在采购订单/订单项目数据表中存储什么信息——分店位置货币和当前汇率,还是转换后的美元基础货币金额?请记住,汇率必须为创建PO时的汇率。
如上所述,在采购订单表格中存储本地货币价值、交易日期、本地货币名称;同时计算并存储基础货币(美元)的价值。如果需要,可以再次查找汇率,不需要在此处冗余存储。
存储USD值是为了更方便地在单一货币下进行聚合(例如生成显示总未结PO值的报告发送到总部)。如果用例不需要此类使用场景,则无需存储USD值,它可以根据FX汇率表在需要时进行计算。然而,下一个问题暗示会有相当大的需要在基础货币(USD)中获得价值。
Q2:要转换什么内容以及何时才能生成以美元/基础货币计价的报告?
通过将数值存储在基础货币和USD中,可以大大简化此类报表的生成。这就是我们采取一次性成本计算和存储USD值的原因,因此它可以被多次读取。
Q3:如果有人——比如在两年后——将基础货币从美元更改为澳大利亚元,对现有数据的影响是什么?
从技术上讲,如果预计会进行这种更改,请不要使用“USD”命名任何数据库结构,而应使用一些通用名称,例如“BASE”:-)
如果进行此类更改,公司财务部门将指示您如何重新表述财务数据-例如,是否应根据交易时的实际汇率重新计算基础价值,还是只使用一个固定转换因子?无论哪种情况,一旦给您提供了这个决策,您只需要将适当的转换因子输入FX_RATES表格,并运行一次性过程以重新填充PURCHASE_ORDERS.ORDER_VALUE_BASE列。除了汇率之外,此查找所需的所有其他信息已经存在于PURCHASE_ORDERS表中且没有更改。
Q4:处理多种货币的最佳方法是什么,以便应用程序处理最少量的转换?
这又将由您的业务需求驱动,而不是技术决策。如果经常需要报告本地货币以及基础(USD)货币,则存储相关交易值的两种货币将有所帮助。通过计算并存储一次,您可以从此后访问存储的数据获益。
此外,由于您没有丢弃任何数据,如果需要,您可以随时重新计算财务数据。一些可能需要重新计算的情况包括:
- 公司决定基准货币使用提出采购订单时的汇率,但在关闭或开具发票时应重新计算基准(美元)货币。在这种情况下,您将使用不同的日期查找FX_RATES表以关闭PO。
- 如果英镑突然暴跌,从1 GBP=1.25 USD变为1.5 GBP=1 USD,则可能需要计算此类变化对美元的影响。然后,您可以获取存储的ORDER_VALUE_USD值与使用FX_RATES表中今天的汇率重新计算的值之间的差异,以确定此类变化的美元影响。
Q5:无法将交易时的汇率存储在采购订单表中吗?这样,系统就不需要在FX汇率表中查找汇率了。(通过后续评论提出)
交易时的汇率肯定可以存储在PO表中,而不是USD金额。在PO表中存储汇率本质上没有什么“错误”,也没有存储美元金额是“正确”的。
当然,这将引出一个问题:如果您不首先将其存储在某个查找表中,那么从哪里获取汇率以填充到PO表中。请记住,在大型/全球性公司中,FX汇率很可能不是通过LOB应用程序本身填充的,它将是一些外部来源,例如确定跨公司使用的FX汇率的FX汇率团队。这种情况下,将FX汇率存储在单独的表格中更加方便。
我在下面列出了不同方法的一些好处。您需要根据自己的需求选择使用哪种方法。
- 在PO表中存储USD的好处: USD金额可以直接使用,无需进行进一步计算(即在运行报告时,不需要计算
ORDER_VALUE_LOC x EXCHANGE_RATE
)。
- 单独FX汇率表的好处: FX汇率集中存储在一个单独的表中,更容易更新和审核(请记住,大型企业可能会有一个专门的团队负责修复整个公司的FX汇率),以及验证(例如,检查FX汇率的连续性——在上面的例子中,通过串联连续行上的有效日期来检查FX汇率是否存在空缺非常简单)。FX汇率不会分散在多个表中。
- 在PO表中存储FX汇率的好处: 无需单独的
FX_RATES
表。
当然,你可以冗余地存储额外的信息(牺牲存储空间)来获得好处(例如,在PO表中存储本地货币金额、FX汇率和USD金额,并保持单独的FX汇率表。这使得您可以轻松打印出显示本地货币金额以及用于将其转换为USD金额的FX汇率的PO文档。同时,FX汇率表仍然是汇率的权威来源)。
请记住,这个问题及其答案都是主观的,所以没有对错之分。将所有这些建议调整为符合您的要求和公司标准。