LP#1942220: implement Link Invoice
authorGalen Charlton <gmc@equinoxOLI.org>
Thu, 9 Dec 2021 20:33:38 +0000 (15:33 -0500)
committerGalen Charlton <gmc@equinoxOLI.org>
Thu, 9 Dec 2021 20:33:38 +0000 (15:33 -0500)
Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
Open-ILS/src/eg2/src/app/staff/acq/lineitem/lineitem-list.component.html
Open-ILS/src/eg2/src/app/staff/acq/lineitem/lineitem-list.component.ts
Open-ILS/src/eg2/src/app/staff/acq/lineitem/lineitem.module.ts
Open-ILS/src/eg2/src/app/staff/acq/lineitem/link-invoice-dialog.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/acq/lineitem/link-invoice-dialog.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/acq/po/summary.component.html
Open-ILS/src/eg2/src/app/staff/acq/po/summary.component.ts

index 09d42ea..8192118 100644 (file)
@@ -3,6 +3,7 @@
 <eg-acq-cancel-dialog recordType="li" #cancelDialog></eg-acq-cancel-dialog>
 <eg-acq-delete-lineitems-dialog #deleteLineitemsDialog></eg-acq-delete-lineitems-dialog>
 <eg-acq-add-copies-dialog #addCopiesDialog></eg-acq-add-copies-dialog>
+<eg-acq-link-invoice-dialog #linkInvoiceDialog></eg-acq-link-invoice-dialog>
 <eg-acq-claim-policy-dialog #claimPolicyDialog></eg-acq-claim-policy-dialog>
 <eg-acq-export-attributes-dialog #exportAttributesDialog></eg-acq-export-attributes-dialog>
 
@@ -21,7 +22,7 @@
         <button ngbDropdownItem (click)="deleteLineitems()" 
           [disabled]="!canDeleteLis() || !selectedIds().length" i18n>Delete Selected Lineitems</button>
         <button ngbDropdownItem (click)="addCopiesToLineitems()" 
-          [disabled]="!canAddLiCopies() || !selectedIds().length" i18n>Add Items to Selected Lineitems</button>
+          [disabled]="isActivatedPo() || !selectedIds().length" i18n>Add Items to Selected Lineitems</button>
         <button ngbDropdownItem (click)="exportSingleAttributeList()" 
           [disabled]="!selectedIds().length" i18n>Export Single Attribute List for Selected Lineitems</button>
         <div class="dropdown-divider"></div>
@@ -44,7 +45,9 @@
         <button ngbDropdownItem (click)="applyClaimPolicyToSelected()" 
           [disabled]="!poId || !selectedIds().length" i18n>Apply Claim Policy to Selected Lineitems</button>
         <button ngbDropdownItem (click)="createInvoiceFromSelected()" 
-          [disabled]="!poId || !selectedIds().length" i18n>Create Invoice from Selected Lineitems</button>
+          [disabled]="!isActivatedPo() || !selectedIds().length" i18n>Create Invoice from Selected Lineitems</button>
+        <button ngbDropdownItem (click)="linkInvoiceFromSelected()" 
+          [disabled]="!isActivatedPo() || !selectedIds().length" i18n>Link Selected Lineitems to Invoice</button>
       </div>
     </div>
   </div>
index 6ec4c53..2f49dfe 100644 (file)
@@ -15,6 +15,7 @@ import {HoldingsService} from '@eg/staff/share/holdings/holdings.service';
 import {CancelDialogComponent} from './cancel-dialog.component';
 import {DeleteLineitemsDialogComponent} from './delete-lineitems-dialog.component';
 import {AddCopiesDialogComponent} from './add-copies-dialog.component';
+import {LinkInvoiceDialogComponent} from './link-invoice-dialog.component';
 import {ExportAttributesDialogComponent} from './export-attributes-dialog.component';
 import {ClaimPolicyDialogComponent} from './claim-policy-dialog.component';
 import {saveAs} from 'file-saver';
@@ -48,7 +49,7 @@ export class LineitemListComponent implements OnInit {
 
     picklistId: number = null;
     poId: number = null;
-    poAllowsNewCopies = false;
+    poWasActivated = false;
     poSubscription: Subscription;
     recordId: number = null; // lineitems related to a bib.
 
@@ -117,6 +118,7 @@ export class LineitemListComponent implements OnInit {
     @ViewChild('cancelDialog') cancelDialog: CancelDialogComponent;
     @ViewChild('deleteLineitemsDialog') deleteLineitemsDialog: DeleteLineitemsDialogComponent;
     @ViewChild('addCopiesDialog') addCopiesDialog: AddCopiesDialogComponent;
+    @ViewChild('linkInvoiceDialog') linkInvoiceDialog: LinkInvoiceDialogComponent;
     @ViewChild('exportAttributesDialog') exportAttributesDialog: ExportAttributesDialogComponent;
     @ViewChild('claimPolicyDialog') claimPolicyDialog: ClaimPolicyDialogComponent;
 
@@ -173,7 +175,7 @@ export class LineitemListComponent implements OnInit {
         });
 
         this.poSubscription = this.poService.poRetrieved.subscribe(() => {
-            this.poAllowsNewCopies = this.po().order_date() ? false : true;
+            this.poWasActivated = this.po().order_date() ? true : false;
         });
     }
 
@@ -814,6 +816,21 @@ export class LineitemListComponent implements OnInit {
         window.location.href = path;
     }
 
+    linkInvoiceFromSelected() {
+        const liIds = this.selectedIds();
+        if (liIds.length === 0) { return; }
+
+        this.linkInvoiceDialog.liIds = liIds.map(i => Number(i));
+        this.linkInvoiceDialog.open().subscribe(invId => {
+            if (!invId) { return; }
+
+            const path = '/eg/staff/acq/legacy/invoice/view/' + invId + '?' +
+                     liIds.map(x => 'attach_li=' + x.toString()).join('&');
+            window.location.href = path;
+        });
+
+    }
+
     markReceived(liIds: number[]) {
         if (liIds.length === 0) { return; }
 
@@ -858,16 +875,15 @@ export class LineitemListComponent implements OnInit {
         });
     }
 
-    // can add lineitems unless the PO has been activated at some
-    // point in the past
-    canAddLiCopies(): boolean {
+    // order was activated as some point in past
+    isActivatedPo(): boolean {
         if (this.picklistId) {
-            return true;
+            return false; // not an order
         } else {
             if (this.po()) {
-                this.poAllowsNewCopies = this.po().order_date() ? false : true;
+                this.poWasActivated = this.po().order_date() ? true : false;
             }
-            return this.poAllowsNewCopies;
+            return this.poWasActivated;
         }
     }
 
index 2503ee8..f39c674 100644 (file)
@@ -20,6 +20,7 @@ import {CreateAssetsComponent} from './create-assets.component';
 import {CancelDialogComponent} from './cancel-dialog.component';
 import {DeleteLineitemsDialogComponent} from './delete-lineitems-dialog.component';
 import {AddCopiesDialogComponent} from './add-copies-dialog.component';
+import {LinkInvoiceDialogComponent} from './link-invoice-dialog.component';
 import {ExportAttributesDialogComponent} from './export-attributes-dialog.component';
 import {ClaimPolicyDialogComponent} from './claim-policy-dialog.component';
 import {MarcEditModule} from '@eg/staff/share/marc-edit/marc-edit.module';
@@ -39,6 +40,7 @@ import {UploadComponent} from '../picklist/upload.component';
     CancelDialogComponent,
     DeleteLineitemsDialogComponent,
     AddCopiesDialogComponent,
+    LinkInvoiceDialogComponent,
     ExportAttributesDialogComponent,
     ClaimPolicyDialogComponent,
     BriefRecordComponent,
@@ -51,6 +53,7 @@ import {UploadComponent} from '../picklist/upload.component';
     CancelDialogComponent,
     DeleteLineitemsDialogComponent,
     AddCopiesDialogComponent,
+    LinkInvoiceDialogComponent,
     ExportAttributesDialogComponent,
     ClaimPolicyDialogComponent
   ],
diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/link-invoice-dialog.component.html b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/link-invoice-dialog.component.html
new file mode 100644 (file)
index 0000000..aa736ba
--- /dev/null
@@ -0,0 +1,54 @@
+<ng-template #dialogContent>
+  <form class="form-validated">
+    <div class="modal-header bg-info">
+      <h3 class="modal-title" i18n>Link Invoice</h3>
+      <button type="button" class="close"
+        i18n-aria-label aria-label="Close" (click)="close()">
+        <span aria-hidden="true">&times;</span>
+      </button>
+    </div>
+    <div class="modal-body">
+      <h4 i18n *ngIf="liIds && liIds.length">Lineitem(s) selected:
+        <span *ngFor="let id of liIds; last as isLast">
+          {{id}}<span *ngIf="!isLast">,</span>
+        </span>
+      </h4>
+      <div class="d-flex">
+        <div class="flex-1">
+          <label for="provider-input" i18n>Provider</label>
+        </div>
+        <div class="flex-3">
+          <eg-combobox domId="provider-input" [(ngModel)]="provider" 
+            style="border-left-width: 0px"
+            name="provider-input"
+            [required]="true"
+            [idlQueryAnd]="{active: 't'}" idlClass="acqpro">
+          </eg-combobox>
+        </div>
+      </div>
+      <div class="d-flex mt-2">
+        <div class="flex-1">
+          <label for="invoice-input" i18n>Provider</label>
+        </div>
+        <div class="flex-3">
+          <eg-combobox domId="invoice-input" [(ngModel)]="invoice" 
+            style="border-left-width: 0px"
+            [readOnly]="!provider || !provider?.id"
+            name="invoice-input"
+            [required]="true"
+            idlField="inv_ident"
+            [idlQueryAnd]="{provider: provider?.id}" idlClass="acqinv">
+          </eg-combobox>
+        </div>
+      </div>
+    </div>
+    <div class="modal-footer">
+      <button type="button" class="btn btn-success"
+        [disabled]="!invoice || !invoice.id"
+        (click)="close(invoice.id)" i18n>Link Invoice</button>
+      <button type="button" class="btn btn-warning"
+        (click)="close()" i18n>Cancel</button>
+    </div>
+  </form>
+</ng-template>
+
diff --git a/Open-ILS/src/eg2/src/app/staff/acq/lineitem/link-invoice-dialog.component.ts b/Open-ILS/src/eg2/src/app/staff/acq/lineitem/link-invoice-dialog.component.ts
new file mode 100644 (file)
index 0000000..83b238c
--- /dev/null
@@ -0,0 +1,20 @@
+import {Component, Input, ViewChild, TemplateRef, OnInit} from '@angular/core';
+import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
+import {DialogComponent} from '@eg/share/dialog/dialog.component';
+import {IdlService, IdlObject} from '@eg/core/idl.service';
+import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
+
+@Component({
+  selector: 'eg-acq-link-invoice-dialog',
+  templateUrl: './link-invoice-dialog.component.html'
+})
+
+export class LinkInvoiceDialogComponent extends DialogComponent {
+    @Input() liIds: number[] = [];
+    @Input() poId: number = null;
+
+    provider: ComboboxEntry;
+    invoice: ComboboxEntry;
+
+    constructor(private modal: NgbModal) { super(modal); }
+}
index bf01a4c..14c44b5 100644 (file)
@@ -1,5 +1,6 @@
 
 <eg-acq-cancel-dialog recordType="po" #cancelDialog></eg-acq-cancel-dialog>
+<eg-acq-link-invoice-dialog #linkInvoiceDialog></eg-acq-link-invoice-dialog>
 <eg-progress-dialog #progressDialog></eg-progress-dialog>
 <eg-confirm-dialog #confirmFinalize
   i18n-dialogTitle i18n-dialogBody
         <span class="material-icons small mr-1">receipt</span>
         <span i18n>Create Invoice</span>
       </a>
+      <span class="pl-2 pr-2" i18n> | </span>
+      <a (click)="linkInvoiceFromPo()" href="javascript:;"
+        class="label-with-material-icon">
+        <span class="material-icons small mr-1">receipt</span>
+        <span i18n>Link Invoice</span>
+      </a>
       </ng-container> <!-- show invoice actions -->
       <span class="pl-2 pr-2" i18n> | </span>
       <a routerLink="./edi" i18n>EDI Messages ({{ediMessageCount}})</a>
index 5f2faa7..7467bc6 100644 (file)
@@ -15,7 +15,7 @@ import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
 import {PoService} from './po.service';
 import {LineitemService} from '../lineitem/lineitem.service';
 import {CancelDialogComponent} from '../lineitem/cancel-dialog.component';
-
+import {LinkInvoiceDialogComponent} from '../lineitem/link-invoice-dialog.component';
 
 @Component({
   templateUrl: 'summary.component.html',
@@ -47,6 +47,7 @@ export class PoSummaryComponent implements OnInit, OnDestroy {
     stateChangeSub: Subscription;
 
     @ViewChild('cancelDialog') cancelDialog: CancelDialogComponent;
+    @ViewChild('linkInvoiceDialog') linkInvoiceDialog: LinkInvoiceDialogComponent;
     @ViewChild('progressDialog') progressDialog: ProgressDialogComponent;
     @ViewChild('confirmFinalize') confirmFinalize: ConfirmDialogComponent;
 
@@ -164,6 +165,19 @@ export class PoSummaryComponent implements OnInit, OnDestroy {
         });
     }
 
+    linkInvoiceFromPo() {
+
+        this.linkInvoiceDialog.poId = this.poId;
+        this.linkInvoiceDialog.open().subscribe(invId => {
+            if (!invId) { return; }
+
+            const path = '/eg/staff/acq/legacy/invoice/view/' + invId + '?' +
+                     'attach_po=' + this.poId;
+            window.location.href = path;
+        });
+
+    }
+
     setCanActivate() {
         this.canActivate = null;
         this.activationBlocks = [];