Skip to content

Commit 9bf47e7

Browse files
authored
Update info of ad-hoc offers (#180)
* Update info of ad-hoc offers * Add minor comment * Add a link from the quote to the offer form
1 parent cfea266 commit 9bf47e7

6 files changed

Lines changed: 66 additions & 13 deletions

File tree

src/app/features/quotes/pages/quote-list/quote-list.component.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,19 @@ import { LoginInfo } from 'src/app/models/interfaces';
284284
[attr.d]="isQuoteCancelled(quote) ? 'M6 18L18 6M6 6l12 12' : 'M5 13l4 4L19 7'" />
285285
</svg>
286286
</button>
287+
288+
<!-- Create offer, Seller only when the quote is accepted -->
289+
<button
290+
*ngIf="selectedRole === 'seller' && getPrimaryState(quote) === 'accepted'"
291+
[disabled]="isActionDisabled(quote, 'createOffer')"
292+
(click)="createOffer(quote)"
293+
[class]="getIconButtonClass(quote, 'createOffer', 'text-emerald-600 hover:text-emerald-700')"
294+
title="Create Offer"
295+
>
296+
<svg class="h-5 w-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
297+
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h14m-7 7V5"/>
298+
</svg>
299+
</button>
287300
</ng-container>
288301
</div>
289302
</div>
@@ -848,6 +861,13 @@ export class QuoteListComponent implements OnInit {
848861
});
849862
}
850863

864+
createOffer(quote: Quote) {
865+
// we send the current quote ID to open the proper from
866+
this.router.navigate(['/my-offerings'], { state: {
867+
quoteId: quote.id
868+
} });
869+
}
870+
851871
// Utility methods (migrated from QuoteRow.js)
852872
extractShortId(id: string | undefined): string {
853873
if (!id) return 'N/A';

src/app/pages/seller-offerings/seller-offerings.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ <h1 class="mb-8 mt-4 text-4xl font-extrabold leading-none tracking-tight text-gr
107107
<update-catalog [cat]="catalog_to_update"></update-catalog>
108108
}
109109
@if(show_create_custom_offer){
110-
<app-custom-offer [offer]="offer_to_update"></app-custom-offer>
110+
<app-custom-offer [offer]="offer_to_update" [partyId]="custom_offer_partyId"></app-custom-offer>
111111
}
112112
</div>
113113
</div>

src/app/pages/seller-offerings/seller-offerings.component.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ import { LoginInfo } from 'src/app/models/interfaces';
1111
import { initFlowbite } from 'flowbite';
1212
import {EventMessageService} from "../../services/event-message.service";
1313
import * as moment from 'moment';
14-
import { Subject } from 'rxjs';
14+
import { firstValueFrom, Subject } from 'rxjs';
1515
import { takeUntil } from 'rxjs/operators';
16+
import { QuoteService } from 'src/app/features/quotes/services/quote.service';
1617

1718
@Component({
1819
selector: 'app-seller-offerings',
@@ -41,6 +42,7 @@ export class SellerOfferingsComponent implements OnInit, OnDestroy {
4142
serv_to_update:any;
4243
res_to_update:any;
4344
offer_to_update:any;
45+
custom_offer_partyId:any=null;
4446
catalog_to_update:any;
4547
feedback:boolean=false;
4648
userInfo:any;
@@ -59,7 +61,10 @@ export class SellerOfferingsComponent implements OnInit, OnDestroy {
5961
constructor(
6062
private localStorage: LocalStorageService,
6163
private cdr: ChangeDetectorRef,
62-
private eventMessage: EventMessageService
64+
private eventMessage: EventMessageService,
65+
private router: Router,
66+
private quoteService: QuoteService,
67+
private api: ApiServiceService
6368
) {
6469
this.eventMessage.messages$
6570
.pipe(takeUntil(this.destroy$))
@@ -114,7 +119,9 @@ export class SellerOfferingsComponent implements OnInit, OnDestroy {
114119
this.goToUpdateOffer();
115120
}
116121
if(ev.type === 'SellerCreateCustomOffer') {
117-
this.offer_to_update=ev.value;
122+
const evValue = ev.value as {offer: any, partyId?: string};
123+
this.offer_to_update = evValue.offer;
124+
this.custom_offer_partyId = evValue.partyId || null;
118125
this.goToCreateCustomOffer();
119126
}
120127
if(ev.type === 'SellerCatalogUpdate') {
@@ -127,14 +134,31 @@ export class SellerOfferingsComponent implements OnInit, OnDestroy {
127134
})
128135
}
129136

130-
ngOnInit() {
137+
async ngOnInit() {
131138
this.userInfo = this.localStorage.getObject('login_items') as LoginInfo;
132139
const saved = localStorage.getItem('activeSection');
133140
console.log(saved)
134141
if (saved) this.activeSection = saved;
135142
if (saved && this.sectionActions[saved]) {
136143
this.sectionActions[saved].call(this); // bind `this` context
137144
}
145+
146+
const state = history.state as { quoteId?: string };
147+
console.log('Checking state')
148+
console.log(state)
149+
150+
if (state && state.quoteId) {
151+
// If there's a quoteId in the state, open the offers section
152+
const quote = await firstValueFrom(this.quoteService.getQuoteById(state.quoteId));
153+
const offerId = quote?.quoteItem?.[0]?.productOffering?.id;
154+
let offer:any = null;
155+
if (offerId) {
156+
offer = await this.api.getProductById(offerId);
157+
}
158+
159+
const quoteBuyer = quote?.relatedParty?.find((party: any) => party.role.toLowerCase() === environment.BUYER_ROLE.toLowerCase());
160+
this.eventMessage.emitSellerCreateCustomOffer(offer, quoteBuyer?.id);
161+
}
138162
}
139163

140164
ngOnDestroy(){

src/app/services/event-message.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ export class EventMessageService {
109109
this.eventMessageSubject.next({ type: 'SellerUpdateOffer', value: offer });
110110
}
111111

112-
emitSellerCreateCustomOffer(offer:any){
113-
this.eventMessageSubject.next({type: 'SellerCreateCustomOffer', value: offer})
112+
emitSellerCreateCustomOffer(offer:any, partyId?:string){
113+
this.eventMessageSubject.next({type: 'SellerCreateCustomOffer', value: {offer, partyId}})
114114
}
115115

116116
emitSellerCatalog(show:boolean){

src/app/shared/forms/offer/custom-offer/custom-offer.component.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ import {PricePlansComponent} from "../price-plans/price-plans.component";
88
import {ProcurementModeComponent} from "../procurement-mode/procurement-mode.component"
99
import {RelatedPartyIdComponent} from "../related-party-id/related-party-id.component"
1010
import {OfferSummaryComponent} from "../offer-summary/offer-summary.component"
11-
import { lastValueFrom } from 'rxjs';
11+
import { lastValueFrom, firstValueFrom } from 'rxjs';
1212
import {components} from "src/app/models/product-catalog";
1313
import {EventMessageService} from "src/app/services/event-message.service";
1414
import {FormChangeState, PricePlanChangeState} from "../../../../models/interfaces";
1515
import {Subscription} from "rxjs";
1616
import * as moment from 'moment';
1717
import { environment } from 'src/environments/environment';
18+
import { QuoteService } from 'src/app/features/quotes/services/quote.service';
1819

1920
type ProductOffering_Create = components["schemas"]["ProductOffering_Create"];
2021
type ProductOfferingPrice = components["schemas"]["ProductOfferingPrice"]
@@ -62,7 +63,7 @@ export class CustomOfferComponent implements OnInit {
6263

6364
constructor(private api: ApiServiceService,
6465
private eventMessage: EventMessageService,
65-
private fb: FormBuilder) {
66+
private fb: FormBuilder, private quoteService: QuoteService) {
6667

6768
this.productOfferForm = this.fb.group({
6869
prodSpec: new FormControl(null, [Validators.required]),
@@ -78,8 +79,9 @@ export class CustomOfferComponent implements OnInit {
7879
console.log(this.offer)
7980
console.log(this.partyId)
8081
console.log('-------------------------------')
82+
8183
await this.loadOfferData();
82-
this.loadingData=false;
84+
this.loadingData = false;
8385
}
8486

8587
async loadOfferData() {
@@ -170,12 +172,19 @@ export class CustomOfferComponent implements OnInit {
170172
}));
171173

172174
const license = this.offer.productOfferingTerm.find((t: { name: string; }) => t.name === 'License');
173-
175+
176+
// Add the name of the organization/trading name to the offer name
177+
let offerName = this.offer.name;
178+
if (this.productOfferForm.get('partyInfo')?.value.tradingName) {
179+
offerName = `${this.offer.name} - ${this.productOfferForm.get('partyInfo')?.value.tradingName}`;
180+
}
181+
174182
const offer: any = {
175-
name: this.offer.name,
183+
name: offerName,
176184
description: this.offer?.description || '',
177185
lifecycleStatus: 'Active',
178186
isBundle: this.bundleChecked,
187+
isSellable: false, // Ad-Hoc offer cannot be generally purchased
179188
bundledProductOffering: this.offersBundle,
180189
place: [],
181190
version: this.offer.version,

src/app/shared/quote-request-modal/quote-request-modal.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { FormsModule, ReactiveFormsModule, FormBuilder, FormGroup, Validators }
44
import {components} from "../../models/product-catalog";
55
type Product = components["schemas"]["ProductOffering"];
66
type ProductSpecification = components["schemas"]["ProductSpecification"];
7-
import { QuoteService } from 'src/app/services/quote.service';
7+
import { QuoteService } from 'src/app/features/quotes/services/quote.service';
88
import { EventMessageService } from 'src/app/services/event-message.service';
99

1010
export interface QuoteRequestData {

0 commit comments

Comments
 (0)