on
Item availability - part 4
Part four is now available on Github and forked on Stackblitz.
Additions are, excluding tinkering with previous parts:
- ww-item-ledger. An An E1 request and response definition for ‘Work With Item Ledger’ form.
- store update. A new app-state variable for the ledger.
- e1/effects. Logic to map E1’s response to the new app-state variable.
- item-ledger.component. A component where we will draw our chart.
This should now start to sound familiar.
ww-item-ledger
The item ledger request is again slightly different from previous requests:
export class WWItemLedgerRequest extends FormRequest {
constructor(branch: string, item: string) {
super();
this.formName = 'P4111_W4111A';
this.formServiceAction = 'R';
this.maxPageSize = '1000';
this.returnControlIDs = '17|67|21|39|1[6,7,8,9,10,11,12,13,155]';
this.formInputs = [
{
id: '2',
value: branch
},
{
id: '5',
value: item
}
];
}
}
We are now passing the branch and item as formInputs
.
store update
We create new ledger
app-state variable.
export interface ILedger {
item: string;
branch: string;
transaction: Date;
quantity: number;
}
export interface IAppState {
items: IItem[];
available: IItem[];
quantities: IQuantity[];
ledger: ILedger[];
}
A new action for the ledger and also an action to remove a card.
export class RemoveAction implements Action {
readonly type = ActionTypes.REMOVE;
constructor(public item: string) { }
}
export class LedgerAction implements Action {
readonly type = ActionTypes.LEDGER;
constructor(public ledger: ILedger[]) { }
}
And reducer for the ledger and remove actions.
case ActionTypes.REMOVE:
return {
...state, ...{
available: state.available.filter(r => r.item !== action.item),
quantities: state.quantities.filter(r => r.item !== action.item)
}
}
case ActionTypes.LEDGER:
return {
...state, ...{
ledger: [...action.ledger]
}
};
e1/effects
We have two new effects. The first one, updateLedger$
is triggered by an update of the AvailableAction
and then submits ww-item-ledger
requests.
In other words, whenever the quantities
app-state variable is updated, go and fetch the ledger.
@Effect({ dispatch: false })
updateLedger$ = this.actions$.ofType<AppActions.AvailableAction>(ActionTypes.AVAILABLE)
.pipe(
map(action => action.quantities),
tap(qt => {
const ledgerRq = new BatchformRequest();
ledgerRq.formRequests = qt
.filter(r => r.branch !== 'TOTAL')
.map(r => new WWItemLedgerRequest(r.branch, r.item));
this.batch.request = ledgerRq;
this.e1.call(this.batch);
})
);
@Effect()
The second effect maps the ww-item-ledger
request to the ledger
app-state variable.
itemLedger$ = this.actions$.ofType<E1Actions.BatchformResponseAction>(E1ActionTypes.BATCHFORM_RESPONSE)
.pipe(
map(action => action.payload.batchformResponse),
filter(bf => bf[`fs_0_${W4111A}`]),
withLatestFrom(this.store),
switchMap(([bf, store]) => {
const ledger: ILedger[] = [];
for (let i = 0; bf[`fs_${i}_${W4111A}`]; i++) {
const form: IWWItemLedgerForm = bf[`fs_${i}_${W4111A}`];
ledger.push(...form.data.gridData.rowset.map<ILedger>(r => {
return {
item: form.data.txtItemNumber_17.value,
branch: r.sBranchPlant_9.value,
transaction: new Date(parseInt(r.dtTransactionDate_8.internalValue)),
quantity: r.mnQuantity_10.internalValue
}
}));
}
const existing = ledger.map(r => r.item);
ledger.push(...store.app.ledger.filter(r => !existing.includes(r.item)));
return OfObservable(new AppActions.LedgerAction(ledger));
})
);
item-ledger.component
For now, the item-ledger component is just a placeholder. Instead of giving it its own page, we want to place it onto the item’s card.
For this we use Angular Material’s Tabs Component on the card’s content so the user can tab between ‘Summary’ and ‘Ledger’ modes.
The other addition to the card are the two buttons at bottom. The left one refreshes the data and the red bin removes it. The refresh function would benefit by being on a timer. Updated every 15 minutes for example, something to look at in a later tutorial.
But now I need a refresh course on D3 before getting stuck into charting the ledger.