" DCI program: BB6aPayBills "

" Exported from Squeak 7179-basic.76.image on: 18 December 2011 by: Trygve "

" Data perspective "

" Class BB6aBill "

" A bill to be payed.

Instance variables:
    fromAccount (Object) account name
    toAccount (Object) account name
    bank (BB5Bank) Bothe accounts are in the same bank.
    amount (Integer) amount to be payed.

For further information, see Data>BB6aBillCollection. "

Object subclass: #BB6aBill
    instanceVariableNames: 'bank fromAccount toAccount amount'
    classVariableNames: ''
    poolDictionaries: ''
    category: 'BB6aPayBills-Data'

" BB6aBill instance methods in category: access "

amount
    ^amount

amount: money
    amount:= money.

bank
    ^bank

bank: bnk
    bank := bnk.

fromAccount
    ^fromAccount

fromAccount: accNo
    fromAccount := accNo.

toAccount
    ^toAccount

toAccount: accNo
    toAccount := accNo.

" Class BB6aBillCollection "

" In the BB6xPayBills example, the BB6xBillCollection has a list of bills that shall be payed. Each bill has a fromAccount, a toAccount and an amount. There are two solutions; BB6aPayBills and BB6bPayBills. Both reuse the BB5Bank for the actual money transfer.

In the first, BB6aPayBills, the BB5MoneyTransferContext is playing a role in the PayBills Interaction.

In the second, BB6bPayBills, the BB5MoneyTransferContext is merged into the PayBills Context by constraining roles in the merged Context (BB5MoneyTransferContext) to be played by the same objects as roles in the current Context (BB6bPayBillsCtx). (The terminology needs to be cleaned up here).

Instance variables:
    bank (BB5Bank) All accounts are in the same bank.
     "

Object subclass: #BB6aBillCollection
    instanceVariableNames: 'billCollection'
    classVariableNames: ''
    poolDictionaries: ''
    category: 'BB6aPayBills-Data'

" BB6aBillCollection instance methods in category: access "

addBill: aBill
    billCollection add: aBill.

billCollection
    ^billCollection

" BB6aBillCollection instance methods in category: private "

initialize
    super initialize.
    billCollection := OrderedCollection new.

" Context perspective "

" Context: BB6aPayBillsCtx "

" Class BB6aPayBillsCtx "

" Implements the system operation bank: bnk payBills: billCollection. (The bank variable is redundant; all bills are payed by transferring money between accounts in the same bank. Needs cleaning up.)

Instance variables:
    bank (BB5Bank) The transfer is within a single bank.
    billCollection (A Collection of BB6aBill) bills to be payed.
    fromAccountNumber (Object) account name
    toAccountNumber (Object) account name
    
Roles:
    BillPayer Responsible for providing bills and pay them.
    Teller Responsible for performing the actual transfer of money.
        This role is played by the BB5MoneyTransferContext in this version.

For further information, see Data>BB6aBillCollection. "

BB1Context subclass: #BB6aPayBillsCtx
    instanceVariableNames: 'billCollection fromAccountNumber toAccountNumber'
    classVariableNames: ''
    poolDictionaries: ''
    category: 'BB6aPayBills-Context'

" BB6aPayBillsCtx instance methods in category: access "

billCollection: bColl
    billCollection := bColl.

fromAccountNumber: from
    fromAccountNumber := from.

toAccountNumber: to
    toAccountNumber := to.

" BB6aPayBillsCtx instance methods in category: role binding "

BillPayer
    ^billCollection

Teller
    ^BB5aMoneyTransferContext new

" BB6aPayBillsCtx instance methods in category: triggers "

payBills: billColl
    self billCollection: billColl.
    self runInteractionFromRoleNamed: #BillPayer.

" BB6aPayBillsCtx class class methods in category: context diagram "

linkBreakPoints
    | dict |
    (dict := Dictionary new)
        yourself.
    ^dict.

rolePositions
    | dict |
    (dict := Dictionary new)
        at: #BillPayer put: 10@5;
        at: #Teller put: 165@115;
        yourself.
    ^dict.

" BB6aPayBillsCtx class class methods in category: role structure "

roleNames
    " BB6aPayBillsCtx roleNames "
    ^ self roleStructure keys

roleStructure
    ^super roleStructure
    at: #BillPayer put: #(#Teller );
    at: #Teller put: #();
        yourself.

No diagram

" Methodful Role BillPayer "

payBills
    " There is a single role with a single role method in this Context. "
    " A real program would keep the method in the BB6aBillCollection class. "
    " but we keep it here to illustrate that a role method "
    " may call a system operation realized by another Context. "
    self billCollection do:
        [:bill |
            Teller
                transfer: bill amount
                fromAccountNumber: bill fromAccount
                toAccountNumber: bill toAccount
                inBank: bill bank].

run
    BillPayer payBills

" Methodless Role Teller "


" Testing perspective "

" Class BB6aTesting "

Object subclass: #BB6aTesting
    instanceVariableNames: ''
    classVariableNames: ''
    poolDictionaries: ''
    category: 'BB6aPayBills-Testing'

" BB6aTesting class class methods in category: class initialization "

initialize
    " BB6aTesting initialize "
    TheWorldMenu unregisterOpenCommand: 'BB6b: Pay bills'.
    TheWorldMenu
        registerOpenCommand:
            {'BB6a: Pay bills'. { BB6aTesting. #testPayBills1.}. 'Pay bills according to predefined list.\Call BB5MoneyTransferContext as a subroutine.' withCRs. }.

" BB6aTesting class class methods in category: triggers "

testPayBills1
    " BB6aTesting testPayBills1. "
    | bank billCollection |
    bank := BB5aBank new.
    (bank addCheckingAccountNumbered: 1111) increase: 2000.
    bank addSavingsAccountNumbered: 2222.
    self assert:
            [(bank findAccount: 1111) balance = 2000.
            (bank findAccount: 2222) balance = 0].
    billCollection := BB6aBillCollection new.
    billCollection addBill: (BB6aBill new bank: bank; fromAccount: 1111; toAccount: 2222; amount: 500).
    billCollection addBill: (BB6aBill new bank: bank; fromAccount: 2222; toAccount: 1111; amount: 200).
    billCollection addBill: (BB6aBill new bank: bank; fromAccount: 1111; toAccount: 2222; amount: 500).
    BB6aPayBillsCtx new payBills: billCollection.
    self assert:
            [(bank findAccount: 1111) balance = 1200.
            (bank findAccount: 2222) balance = 800].
    self inform: 'Test OK'.