From c674d9732468ca61ae1e302b1b6e09815bdc1c93 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Mon, 8 Mar 2021 14:50:49 -0500 Subject: [PATCH] LP1904036 Billing; credit card form Signed-off-by: Bill Erickson Signed-off-by: Jane Sandberg Signed-off-by: Galen Charlton --- .../src/app/staff/circ/patron/bills.component.html | 6 +- .../src/app/staff/circ/patron/bills.component.ts | 30 ++++-- .../eg2/src/app/staff/share/circ/circ.module.ts | 5 +- .../share/circ/credit-card-dialog.component.html | 115 +++++++++++++++++++++ .../share/circ/credit-card-dialog.component.ts | 107 +++++++++++++++++++ 5 files changed, 253 insertions(+), 10 deletions(-) create mode 100644 Open-ILS/src/eg2/src/app/staff/share/circ/credit-card-dialog.component.html create mode 100644 Open-ILS/src/eg2/src/app/staff/share/circ/credit-card-dialog.component.ts diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/bills.component.html b/Open-ILS/src/eg2/src/app/staff/circ/patron/bills.component.html index 13697c6b6d..8ab8da883b 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/bills.component.html +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/bills.component.html @@ -7,9 +7,11 @@ + dialogBody="Are you sure you want to apply a payment of {{paymentAmount | currency}}?"> + + @@ -106,7 +108,7 @@
-
diff --git a/Open-ILS/src/eg2/src/app/staff/circ/patron/bills.component.ts b/Open-ILS/src/eg2/src/app/staff/circ/patron/bills.component.ts index 8279c016ca..bea0bf25e4 100644 --- a/Open-ILS/src/eg2/src/app/staff/circ/patron/bills.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/circ/patron/bills.component.ts @@ -18,6 +18,8 @@ import {CircService, CircDisplayInfo} from '@eg/staff/share/circ/circ.service'; import {PromptDialogComponent} from '@eg/share/dialog/prompt.component'; import {AlertDialogComponent} from '@eg/share/dialog/alert.component'; import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component'; +import {CreditCardDialogComponent, CreditCardPaymentParams + } from '@eg/staff/share/circ/credit-card-dialog.component'; interface BillGridEntry extends CircDisplayInfo { xact: IdlObject // mbt @@ -57,12 +59,13 @@ export class BillsComponent implements OnInit, AfterViewInit { sessionVoided = 0; paymentType = 'cash_payment'; checkNumber: string; - payAmount: number; + paymentAmount: number; annotatePayment = false; annotation: string; entries: BillGridEntry[]; convertChangeToCredit = false; receiptOnPayment = false; + ccPaymentParams: CreditCardPaymentParams; maxPayAmount = 100000; warnPayAmount = 1000; @@ -74,6 +77,7 @@ export class BillsComponent implements OnInit, AfterViewInit { @ViewChild('annotateDialog') private annotateDialog: PromptDialogComponent; @ViewChild('maxPayDialog') private maxPayDialog: AlertDialogComponent; @ViewChild('warnPayDialog') private warnPayDialog: ConfirmDialogComponent; + @ViewChild('creditCardDialog') private creditCardDialog: CreditCardDialogComponent; constructor( private router: Router, @@ -212,7 +216,7 @@ export class BillsComponent implements OnInit, AfterViewInit { pendingPaymentInfo(): {payment: number, change: number} { - const amt = this.payAmount || 0; + const amt = this.paymentAmount || 0; if (amt >= this.paidSelected()) { const owedSelected = this.owedSelected(); @@ -229,8 +233,8 @@ export class BillsComponent implements OnInit, AfterViewInit { if (!this.billGrid) { return true; } // still loading return ( - this.payAmount === 0 || - (this.payAmount < 0 && this.paymentType !== 'refund') || + this.paymentAmount === 0 || + (this.paymentAmount < 0 && this.paymentType !== 'refund') || this.billGrid.context.rowSelector.selected().length === 0 ); } @@ -279,17 +283,29 @@ export class BillsComponent implements OnInit, AfterViewInit { } amountExceedsMax(): boolean { - if (this.payAmount < this.maxPayAmount) { return false; } + if (this.paymentAmount < this.maxPayAmount) { return false; } this.maxPayDialog.open().toPromise().then(_ => this.focusPayAmount()); return true; } addCcArgs(): Promise { - return null; + this.ccPaymentParams = {}; + + if (this.paymentType !== 'credit_card_payment') { + return Promise.resolve(); + } + + return this.creditCardDialog.open().toPromise().then(ccArgs => { + if (ccArgs) { + this.ccPaymentParams = ccArgs; + } else { + return Promise.reject('CC dialog canceled'); + } + }); } verifyPayAmount(): Promise { - if (this.payAmount < this.warnPayAmount) { + if (this.paymentAmount < this.warnPayAmount) { return Promise.resolve(); } diff --git a/Open-ILS/src/eg2/src/app/staff/share/circ/circ.module.ts b/Open-ILS/src/eg2/src/app/staff/share/circ/circ.module.ts index 3cf3790d16..20fc9b965e 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/circ/circ.module.ts +++ b/Open-ILS/src/eg2/src/app/staff/share/circ/circ.module.ts @@ -9,6 +9,7 @@ import {ClaimsReturnedDialogComponent} from './claims-returned-dialog.component' import {CircComponentsComponent} from './components.component'; import {CircEventsComponent} from './events-dialog.component'; import {AddBillingDialogComponent} from './billing-dialog.component'; +import {CreditCardDialogComponent} from './credit-card-dialog.component'; @NgModule({ declarations: [ @@ -18,6 +19,7 @@ import {AddBillingDialogComponent} from './billing-dialog.component'; PrecatCheckoutDialogComponent, ClaimsReturnedDialogComponent, CircEventsComponent, + CreditCardDialogComponent, AddBillingDialogComponent ], imports: [ @@ -27,7 +29,8 @@ import {AddBillingDialogComponent} from './billing-dialog.component'; exports: [ CircGridComponent, CircComponentsComponent, - AddBillingDialogComponent + AddBillingDialogComponent, + CreditCardDialogComponent ], providers: [ CircService diff --git a/Open-ILS/src/eg2/src/app/staff/share/circ/credit-card-dialog.component.html b/Open-ILS/src/eg2/src/app/staff/share/circ/credit-card-dialog.component.html new file mode 100644 index 0000000000..9176a4f6ee --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/share/circ/credit-card-dialog.component.html @@ -0,0 +1,115 @@ + + + + + diff --git a/Open-ILS/src/eg2/src/app/staff/share/circ/credit-card-dialog.component.ts b/Open-ILS/src/eg2/src/app/staff/share/circ/credit-card-dialog.component.ts new file mode 100644 index 0000000000..70965a7dac --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/share/circ/credit-card-dialog.component.ts @@ -0,0 +1,107 @@ +import {Component, OnInit, Input, ViewChild} from '@angular/core'; +import {Observable} from 'rxjs'; +import {switchMap} from 'rxjs/operators'; +import {IdlObject, IdlService} from '@eg/core/idl.service'; +import {NetService} from '@eg/core/net.service'; +import {EventService} from '@eg/core/event.service'; +import {ToastService} from '@eg/share/toast/toast.service'; +import {PcrudService} from '@eg/core/pcrud.service'; +import {AuthService} from '@eg/core/auth.service'; +import {OrgService} from '@eg/core/org.service'; +import {ServerStoreService} from '@eg/core/server-store.service'; +import {DialogComponent} from '@eg/share/dialog/dialog.component'; +import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap'; +import {StringComponent} from '@eg/share/string/string.component'; +import {ComboboxEntry, ComboboxComponent} from '@eg/share/combobox/combobox.component'; +import {CircService} from './circ.service'; + +export interface CreditCardPaymentParams { + where_process?: 0 | 1, + approval_code?: string, + expire_month?: number, + expire_year?: number, + billing_first?: string, + billing_last?: string, + billing_address?: string, + billing_city?: string, + billing_state?: string, + billing_zip?: string, + note?: string +} + +/* Dialog for collecting credit card payment information */ + +@Component({ + selector: 'eg-credit-card-dialog', + templateUrl: 'credit-card-dialog.component.html' +}) + +export class CreditCardDialogComponent + extends DialogComponent implements OnInit { + + @Input() patron: IdlObject; // au, fleshed with billing address + args: CreditCardPaymentParams; + supportsExternal: boolean; + thisYear = new Date().getFullYear(); + + constructor( + private modal: NgbModal, + private toast: ToastService, + private net: NetService, + private idl: IdlService, + private evt: EventService, + private pcrud: PcrudService, + private circ: CircService, + private org: OrgService, + private serverStore: ServerStoreService, + private auth: AuthService) { + super(modal); + } + + ngOnInit() { + + this.onOpen$.subscribe(_ => { + + this.args = { + billing_first: this.patron.first_given_name(), + billing_last: this.patron.family_name(), + }; + + const addr = + this.patron.billing_address() || this.patron.mailing_address(); + + if (addr) { + this.args.billing_address = addr.street1() + + (addr.street2() ? ' ' + addr.street2() : ''); + this.args.billing_city = addr.city(); + this.args.billing_state = addr.state(); + this.args.billing_zip = addr.post_code(); + } + + this.supportsExternal = false; + + this.serverStore.getItem('credit.processor.default') + .then(processor => { + if (processor && processor !== 'Stripe') { + this.supportsExternal = true; + this.args.where_process = 1; + } + }) + }); + } + + saveable(): boolean { + if (!this.args) { return false; } + + if (this.args.where_process === 0) { + return Boolean(this.args.approval_code); + } + + return Boolean(this.args.expire_month) && Boolean(this.args.expire_year); + } + + + submit() { + } +} + -- 2.11.0