/* **************************************************************************** Component Name : ObjectMapping Created Date : 17/4/2024 @description : This component is responsible for handling the logic required to save the configuration of mapping different objects in Salesforce and Shopify that are synchronized with Shopify. @author : SME Team Modification Log: Ver Date Author 1.0 23/4/2024 SME Team **************************************************************************** */ import { LightningElement, track, api } from 'lwc'; // FETCHING RESOURCES FROM THE STATIC RESOURCES // import pageLoadingGif from "@salesforce/resourceUrl/SMEPageLoadingGif"; import Resources from "@salesforce/resourceUrl/Resources"; import SMEPageLoadingGIF2 from "@salesforce/resourceUrl/SMEPageLoadingGIF2"; // CREATING INSTANCES OF APEX METHODS import getConfigrationForDynamicRow from '@salesforce/apex/ShopifyController.getConfigrationForDynamicRow'; import saveConfigration from '@salesforce/apex/ShopifyController.saveConfigration'; import getIsPerson from '@salesforce/apex/ShopifyController.getIsPerson'; // Custom Labels import Salesforce from '@salesforce/label/c.Salesforce'; import Line_Item from '@salesforce/label/c.Line_Item'; import Shopify from '@salesforce/label/c.Shopify'; import Customer from '@salesforce/label/c.Customer'; import Location from '@salesforce/label/c.Location'; import Collection from '@salesforce/label/c.Collection'; import Person_Account from '@salesforce/label/c.Person_Account'; import Account from '@salesforce/label/c.Account'; import Contact from '@salesforce/label/c.Contact'; import Product from '@salesforce/label/c.Product'; import Order from '@salesforce/label/c.Order'; import Opportunity from '@salesforce/label/c.Opportunity'; import Draft_Order from '@salesforce/label/c.Draft_Order'; import Order_s_Fulfillment from '@salesforce/label/c.Order_s_Fulfillment'; import Inventory from '@salesforce/label/c.Inventory'; // SHOW TOAST import { ShowToastEvent } from "lightning/platformShowToastEvent"; export default class ObjectMapping extends LightningElement { // Custom in-component toast state (replaces ShowToastEvent) — see showNotification. @track toasts = []; _toastSeq = 0; @track disableOrderLineItemButton = false; @track disableOpportunityLineItemButton = false; @track configObject = {}; @track disableOrderButton = false; @api storeName = ''; @track disableOpportunityButton = false; @track disabledOrderFulfillment = false; @track AccountRecordTypeValue; @track personAccountStatus; @track disableDraftOrderButton = false; @track disableDraftOpportunityButton = false; @track options = []; @track isLoading = false; @track objectMappingChanged = false; @track isEditable=true; // pageLoadingGif = pageLoadingGif; pageLoadingGif = SMEPageLoadingGIF2; @track label = { Line_Item, Shopify, Salesforce, Person_Account, Account, Contact, Inventory, Product, Order, Opportunity, Draft_Order, Customer, Location, Collection, Order_s_Fulfillment } @track accountAndContactCustomer = this.label.Account + ' & ' + this.label.Contact; connectedCallback() { console.log('SYNC MADE EASY: Object Mapping Connected Callback'); this.showSpinnerHandler(); this.getIsPerson(); } //CHECKING IF PERSON ACCOUNT IS ENABLED OR NOT getIsPerson() { console.log('SYNC MADE EASY: Object Mapping => Checking Person Account'); getIsPerson() .then((result) => { this.personAccountStatus = result; if (this.personAccountStatus == true) { this.options = [ { label: this.accountAndContactCustomer, value: this.accountAndContactCustomer }, { label: this.label.Person_Account, value: this.label.Person_Account }] } else { this.options = [ { label: this.accountAndContactCustomer, value: this.accountAndContactCustomer }] } this.getStoreRows(); }).catch((error) => { this.closeSpinnerHandler(); }) } setOpportunityLineItemDisabled() { // disable when Opportunity is OFF this.disableOpportunityLineItemButton = !this.configObject.HIC_ShopifySync__Opportunity__c; } //DISABLING OPPORTUNITY TOGGLE IF ORDER TOGGLE IS CHANGED handleOrderChange(event) { this.objectMappingChanged = true; this.configObject.HIC_ShopifySync__Order__c = !this.configObject.HIC_ShopifySync__Order__c; // Disable Opportunity when Order is inactive this.disableOpportunityButton = !this.configObject.HIC_ShopifySync__Order__c; // NEW: Disable Order Line Item when Order is inactive this.disableOrderLineItemButton = !this.configObject.HIC_ShopifySync__Order__c; // When Order is inactive, also set Order Line Item to false if (!this.configObject.HIC_ShopifySync__Order__c) { this.configObject.HIC_ShopifySync__Order_Line_Item__c = false; } // WHEN ORDER IS INACTIVE THEN OPPORTUNITY AND OPPORTUNITY PRODUCT ARE ACTIVE this.configObject.HIC_ShopifySync__Opportunity_Line_Item__c = this.configObject.HIC_ShopifySync__Opportunity__c; this.syncChildWithParent(); } //DISABLING ORDER TOGGLE IF OPPORTUNITY TOGGLE IS CHANGED handleOpportunityChange(event) { this.objectMappingChanged = true; this.configObject.HIC_ShopifySync__Opportunity__c = !this.configObject.HIC_ShopifySync__Opportunity__c; this.disableOrderButton = !this.configObject.HIC_ShopifySync__Opportunity__c; // NEW – keep toggle visible but grayed out this.setOpportunityLineItemDisabled(); // auto-switch the line-item flag if (!this.configObject.HIC_ShopifySync__Opportunity__c) { this.configObject.HIC_ShopifySync__Opportunity_Line_Item__c = false; } this.handleOpportunityLineItems(); this.syncChildWithParent(); } handleDraftOpportunityChange() { this.objectMappingChanged = true; this.configObject.HIC_ShopifySync__Enable_Opportunity_for_SDO__c = !this.configObject.HIC_ShopifySync__Enable_Opportunity_for_SDO__c; this.normalizeDraftOrderState(); } handleOpportunityLineItems() { // if (this.configObject.HIC_ShopifySync__Enable_Opportunity_for_SDO__c || this.configObject.HIC_ShopifySync__Opportunity__c) { if (this.configObject.HIC_ShopifySync__Opportunity__c) { this.configObject.HIC_ShopifySync__Opportunity_Line_Item__c = true; } else { this.configObject.HIC_ShopifySync__Opportunity_Line_Item__c = false; } } //HANDLING ACCOUNT TOGGLE handleChange(event) { this.objectMappingChanged = true; this.AccountRecordTypeValue = event.detail.value; this.isEditable=false; } editCombo() { this.isEditable = true; // pill → combobox } //HANDLING OPPORTUNITY LINE ITEM TOGGLE handleOpportunityLineItemChange(event) { this.objectMappingChanged = true; this.configObject.HIC_ShopifySync__Opportunity_Line_Item__c = !this.configObject.HIC_ShopifySync__Opportunity_Line_Item__c; } //HANDLING ORDER FULFILLMENT TOGGLE onOrderFulfillmentChange(event) { this.objectMappingChanged = true; this.configObject.HIC_ShopifySync__Order_Fulfillment__c = !this.configObject.HIC_ShopifySync__Order_Fulfillment__c; } normalizeDraftOrderState() { const isdraftSyncOn=this.configObject.HIC_ShopifySync__Draft_Order_Sync__c; const isDraftOrderOn = this.configObject.HIC_ShopifySync__Enable_Draft_Order__c; const isDraftOppOn = this.configObject.HIC_ShopifySync__Enable_Opportunity_for_SDO__c; // Case 1: Draft Order OFF // → Opportunity ON but DISABLED if (!isDraftOrderOn && isdraftSyncOn) { this.configObject.HIC_ShopifySync__Enable_Opportunity_for_SDO__c = true; this.disableDraftOpportunityButton = true; this.disableDraftOrderButton = false; return; } // Case 2: Draft Order ON, Opportunity OFF // → Order must be ON but DISABLED if (isDraftOrderOn && !isDraftOppOn) { this.configObject.HIC_ShopifySync__Enable_Draft_Order__c = true; this.disableDraftOrderButton = true; this.disableDraftOpportunityButton = false; return; } // Case 3: Both ON this.disableDraftOrderButton = false; this.disableDraftOpportunityButton = false; } handleDraftOrderChange() { this.objectMappingChanged = true; this.configObject.HIC_ShopifySync__Enable_Draft_Order__c = !this.configObject.HIC_ShopifySync__Enable_Draft_Order__c; this.normalizeDraftOrderState(); } syncChildWithParent() { this.configObject.HIC_ShopifySync__Order_Item__c = this.configObject.HIC_ShopifySync__Order__c; this.configObject.HIC_ShopifySync__Opportunity_Line_Item__c = this.configObject.HIC_ShopifySync__Opportunity__c; } //Get Store configuration getStoreRows() { console.log('SYNC MADE EASY: Object Mapping => Fetching Store Details ' + this.storeName); getConfigrationForDynamicRow({ store: this.storeName }).then((result) => { this.configObject = JSON.parse(result); this.disableOpportunityButton = !this.configObject.HIC_ShopifySync__Order__c; // DRAFT ORDER OPPORTUNITY FALSE if (!this.configObject.HIC_ShopifySync__Draft_Order_Sync__c) { this.configObject.HIC_ShopifySync__Enable_Opportunity_for_SDO__c = false; } // COLLECTION HANDLER if ((this.configObject.hasOwnProperty('HIC_ShopifySync__Collection_Sync__c') == null || this.configObject.hasOwnProperty('HIC_ShopifySync__Collection_Sync__c') == false) && this.configObject.HIC_ShopifySync__Collection_Sync__c == false) { this.configObject.HIC_ShopifySync__Collection_Sync__c = false; } // This is the changes made to the Order and opportunity toggle if (this.configObject.HIC_ShopifySync__Order__c && !this.configObject.HIC_ShopifySync__Opportunity__c) { this.disableOrderButton = true; } if (!this.configObject.HIC_ShopifySync__Order_Sync__c) { // ??? Below condition handled in credential page this.disableOpportunityButton = true; this.disableOrderButton = true; this.disabledOrderFulfillment = true; } if (this.configObject.HIC_ShopifySync__Order_Sync__c) { this.disableOpportunityButton = !this.configObject.HIC_ShopifySync__Order__c; this.disableOrderButton = !this.configObject.HIC_ShopifySync__Opportunity__c; this.disableOrderLineItemButton = !this.configObject.HIC_ShopifySync__Order__c; } if (this.configObject.HIC_ShopifySync__Person_Account__c === true) { this.AccountRecordTypeValue = this.label.Person_Account; this.isEditable = false; } else if (this.configObject.HIC_ShopifySync__Account_Contact__c === true) { this.AccountRecordTypeValue = this.accountAndContactCustomer; this.isEditable = false; } else { this.isEditable = true; } // Added for draft order toggle if (!this.configObject.hasOwnProperty('HIC_ShopifySync__Draft_Order_Sync__c')) { this.configObject.HIC_ShopifySync__Draft_Order_Sync__c = false; } if (!this.configObject.hasOwnProperty('HIC_ShopifySync__Enable_Draft_Order__c')) { this.configObject.HIC_ShopifySync__Enable_Draft_Order__c = false; } this.setOpportunityLineItemDisabled(); this.syncChildWithParent(); this.normalizeDraftOrderState(); this.closeSpinnerHandler(); }).catch((error) => { this.closeSpinnerHandler(); }) } get isOrderSyncEnabled() { return this.configObject.HIC_ShopifySync__Order_Sync__c === true; } /* ── Toggle CSS class getters (custom HTML toggles) ── */ get draftOrderToggleClass() { return 'obj-toggle-track' + (this.configObject.HIC_ShopifySync__Enable_Draft_Order__c ? ' obj-toggle-track_on' : ''); } get draftOpportunityToggleClass() { return 'obj-toggle-track' + (this.configObject.HIC_ShopifySync__Enable_Opportunity_for_SDO__c ? ' obj-toggle-track_on' : ''); } get orderToggleClass() { return 'obj-toggle-track' + (this.configObject.HIC_ShopifySync__Order__c ? ' obj-toggle-track_on' : ''); } get opportunityToggleClass() { return 'obj-toggle-track' + (this.configObject.HIC_ShopifySync__Opportunity__c ? ' obj-toggle-track_on' : ''); } get fulfillmentToggleClass() { return 'obj-toggle-track' + (this.configObject.HIC_ShopifySync__Order_Fulfillment__c ? ' obj-toggle-track_on' : ''); } /* ── Footer button handlers ── */ handleBackStep() { this.dispatchEvent(new CustomEvent('back')); } handleSaveClick() { this.handleSave(); } //HANDLING SAVE BUTTON, SAVING CONFIGURATION @api handleSave() { // show spinner this.showSpinnerHandler(); if (this.AccountRecordTypeValue == this.accountAndContactCustomer) { this.configObject.HIC_ShopifySync__Person_Account__c = false; this.configObject.HIC_ShopifySync__Account_Contact__c = true; } else if (this.AccountRecordTypeValue == this.label.Person_Account) { this.configObject.HIC_ShopifySync__Person_Account__c = true; this.configObject.HIC_ShopifySync__Account_Contact__c = false; this.configObject.HIC_ShopifySync__Default_Account__c = false; } // CALLED WHEN CHANGES IN OBJECT MAPPING if (this.objectMappingChanged) { console.log('SYNC MADE EASY: Object Mapping => Saving Store Details '); saveConfigration({ configObj: JSON.stringify(this.configObject), check: 'False' }).then((result) => { this.savePage(); }).catch((error) => { this.closeSpinnerHandler(); }); } else { this.savePage(); } } /*********************************************************************** * Method is used to save page * ***********************************************************************/ savePage() { const selectStore = new CustomEvent('save', { detail: 'Saved' }); this.dispatchEvent(selectStore); } /*********************************************************************** * This Method is used to close spinner * ***********************************************************************/ closeSpinnerHandler() { this.isLoading = false; const stopSpinner = new CustomEvent('closespinner', { detail: 'Stop Spinner' }); this.dispatchEvent(stopSpinner); } /*********************************************************************** * This Method is used to show spinner * ***********************************************************************/ showSpinnerHandler() { this.isLoading = true; const startSpinner = new CustomEvent('showspinner', { detail: 'Start Spinner' }); this.dispatchEvent(startSpinner); } /* * Helps to Show a Toast Message */ // Custom gradient toast (success = green→teal, error = red) instead of // ShowToastEvent. Same (title, variant, message) signature/callers. showNotification(title, variant, message) { this.closeSpinnerHandler(); const v = (variant || '').toString().toLowerCase(); const kind = v === 'error' ? 'error' : v === 'success' ? 'success' : v === 'warning' ? 'warning' : 'info'; const id = 't' + (this._toastSeq++); this.toasts = [...this.toasts, { id, title, message, cssClass: 'sw-toast sw-toast-' + kind, iconLabel: kind === 'error' ? '⚠' : kind === 'success' ? '✓' : kind === 'warning' ? '!' : 'ℹ' }]; if (kind !== 'error') { // eslint-disable-next-line @lwc/lwc/no-async-operation setTimeout(() => this._dismissToast(id), 4000); } } _dismissToast(id) { this.toasts = this.toasts.filter((t) => t.id !== id); } handleToastClose(event) { this._dismissToast(event.currentTarget.dataset.id); } }