Skip to content

Instantly share code, notes, and snippets.

@emmahyde
Created August 17, 2022 17:58
Show Gist options
  • Save emmahyde/d1bcb8fe99494fcadf38b3ffd498c35e to your computer and use it in GitHub Desktop.
Save emmahyde/d1bcb8fe99494fcadf38b3ffd498c35e to your computer and use it in GitHub Desktop.
erDiagram
  ALLOCATION_LINE_ITEM {
    int id
    int line_item_id
    string line_item_field "[base_amount, discount_amount, tax_amount]"
    int amount "A positive or negative value"
    int unallocated_amount "initialized as `amount`"
    int allocated_amount "initialized as 0"
    
  }
  LINE_ITEM {
    int id
    string added_or_removed
    int base_amount
    int discount_amount
    int tax_amount
  }
  LINE_ITEM ||--|{ ALLOCATION_LINE_ITEM : "becomes exactly three of"
  PAYMENT_ALLOCATION_ATTRS {
    ref allocation_line_item
    float percentage_of_total
    float unrounded_allocation_amount
    int rounded_allocation_amount
    float dropped_allocation_amount
  }

TODO: Object with the tmp values that contains a reference to the allocation_line_item

Individual Line Item Attribute Value Calculation
flowchart TD
  li[line_item] --> aor{{line_item.added_or_removed}}
  aor --Added--> lifa{{line_item_field}}
  aor --Removed--> lifr{{line_item_field}}
  lifa --Base Amount--> 
    ab[value * 1]
  lifa --Discount Amount--> ad[value * -1]
  lifa --Tax Amount--> at[value * 1]
  lifr --Base Amount--> rb[value * -1]
  lifr --Discount Amount--> rd[value * 1]
  lifr --Tax Amount--> rt[value * -1]
  • Each line item becomes exactly three allocation line items (base, discount, and tax).
  • The amount and unallocated amount are line_item.value times the calculated sign.
Payment Loop
E --> F[]
F --> G[]
G --> H[]
flowchart TD
  ps[Payments] --each--> p[Payment]
  p --> A[[map: allocation_line_item]]
  A --> B
  subgraph Calculate Percentage of Total
    B{{payment.positive_or_negative?}} --positive --> C[line_item.unallocated_amount /<br/>sum of line_item.unallocated_amounts]
    B --negative--> D[line_item.allocated_amount /<br/>sum of line_item.allocated_amounts]
  D --> E[percentage_of_total]
  C --> E
  end
  E --> F[PAYMENT_ALLOCATION_ATTRS.new:<br/><b>allocation_line_item:</b><br/>allocation_line_item<br/><b>unrounded_allocation_amount:</b><br/>payment.amount * percentage_of_total<br/><b>rounded_allocation_amount:</b><br/>Math.floor of unrounded_allocation_amount<br/><b>dropped_allocation_amount:</b><br/>unrounded_allocation_amount - rounded_allocation_amount]
  F --> G[[map: output array of payment_allocation_attrs]]
  G --> H[sum_rounded: sum of rounded_allocation_amounts]
  H --> I[rounded_remainder: payment.amount - sum_rounded]
  I --rounded_remainder == 0--> J[[map over: array_of_payment_allocation_attrs]]
  I --rounded_remainder != 0--> K[[map over: array_of_payment_allocation_attrs]]
  J <--> L[final_allocation: rounded_allocation_amount]
  K --> M[sort DESC by dropped_allocation_amount]
  M --> N[for rounded_remainder]
  N --> O[ranking bit]

TODO: elaborate on sort details from excel spreadsheet - sort by TRUNC_AMOUNT desc, LINE_ITEM_ID asc, LINE_ITEM_FIELD asc - that gives us the rankings for allocation

TODO: accumulate cents to allocate

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment