yanweiyuan3
2023-08-09 588bc7829387dfc761cc25f06f77d4c81818bd10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
Quintiq file version 2.0
#parent: #root
Method SetAsBase
{
  Description: 'Set as base currency'
  TextBody:
  [*
    // Logic here to auto convert other currency rates to the new base.
    // Step 1: Compute rates of old base to new base
    // Step 2: Chain compute other currencies with the old base to new base rate
    // Note, 'this' denotes the new base
    oldBaseCurrency := this.MacroPlan().BaseCurrency();
    
    // Step 1, update old base rate to new base rate
    traverse( this, CurrencyRate_MP, cr )
    {
      CurrencyRate_MP::Create( oldBaseCurrency,
                               cr.Start(),
                               ConversionFactor::GetReverseFactor( cr.Rate() ),
                               false /*isfromdb*/ );
    }
    
    // Step 2, update other currencies to convert to new base
    traverse( this, MacroPlan.Currency_MP, c, c <> this and c <> oldBaseCurrency )
    {
      traverse( c, CurrencyRate_MP, cr )
      {
        // Terminology -> cr:                : This currency to old base rate
        //             -> latestOldBaseToNewBase: Old base to new base rate, for chain conversion, we gonna select the nearest time
        // Rate will then be cr x latestOldBaseToNewBase, logic, this_to_new_base_rate := this_to_old_base_rate x old_base_to_new_base_rate
        latestOldBaseToNewBase := maxselect( oldBaseCurrency, CurrencyRate_MP, oldCr, oldCr.Start() <= cr.Start(), oldCr.Start() )
        // If this is null, just get the earliest define
        if( isnull( latestOldBaseToNewBase ) )
        {
          latestOldBaseToNewBase := minselect( oldBaseCurrency, CurrencyRate_MP, oldCr, true, oldCr.Start() )
        }
        rate := guard( cr.Rate() * latestOldBaseToNewBase.Rate(), 1.0 )
        start := cr.Start();
        cr.Delete();
        CurrencyRate_MP::Create( c,
                                 start,
                                 rate,
                                 false /*isfromdb*/ );    
        
      }
    }
    
    
    
    traverse( this, MacroPlan.Currency_MP, currency, currency <> this and currency.IsBase() )
    {
      currency.IsBase( false );  
    }
    this.IsBase( true );
    
    // Flush this (new base currency) currency rate
    this.CurrencyRate_MP( relflush );
  *]
}