update
This commit is contained in:
parent
84a91359d8
commit
6c703c2c3b
55 changed files with 1130 additions and 358 deletions
|
|
@ -69,6 +69,7 @@ const FRAPPE_GET_CLIENT_METHOD = "custom_ui.api.db.clients.get_client_v2";
|
|||
const FRAPPE_GET_CLIENT_NAMES_METHOD = "custom_ui.api.db.clients.get_client_names";
|
||||
const FRAPPE_CHECK_CLIENT_EXISTS_METHOD = "custom_ui.api.db.clients.check_client_exists";
|
||||
const FRAPPE_ADD_ADDRESSES_CONTACTS_METHOD = "custom_ui.api.db.clients.add_addresses_contacts";
|
||||
const FRAPPE_CREATE_CLIENT_CONTACTS_ADDRESSES_METHOD = "custom_ui.api.db.clients.create_client_contacts_addresses";
|
||||
// Employee methods
|
||||
const FRAPPE_GET_EMPLOYEES_METHOD = "custom_ui.api.db.employees.get_employees";
|
||||
const FRAPPE_GET_EMPLOYEES_ORGANIZED_METHOD = "custom_ui.api.db.employees.get_employees_organized";
|
||||
|
|
@ -188,6 +189,10 @@ class Api {
|
|||
return await this.request(FRAPPE_ADD_ADDRESSES_CONTACTS_METHOD, { clientName, companyName, addresses, contacts });
|
||||
}
|
||||
|
||||
static async createClientContactsAddresses(clientName, company, contacts = [], addresses = []) {
|
||||
return await this.request(FRAPPE_CREATE_CLIENT_CONTACTS_ADDRESSES_METHOD, { clientName, company, contacts, addresses });
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// ON-SITE MEETING METHODS
|
||||
// ============================================================================
|
||||
|
|
|
|||
|
|
@ -66,18 +66,23 @@ import Dialog from 'primevue/dialog';
|
|||
import Button from 'primevue/button';
|
||||
import ModalContactForm from './ModalContactForm.vue';
|
||||
import ModalAddressForm from './ModalAddressForm.vue';
|
||||
import Api from '../../api';
|
||||
import { useCompanyStore } from '../../stores/company';
|
||||
|
||||
const companyStore = useCompanyStore();
|
||||
|
||||
const props = defineProps({
|
||||
visible: Boolean,
|
||||
clientName: { type: String, default: '' },
|
||||
clientContacts: { type: Array, default: () => [] },
|
||||
existingContacts: { type: Array, default: () => [] },
|
||||
existingAddresses: { type: Array, default: () => [] },
|
||||
isSubmitting: { type: Boolean, default: false },
|
||||
});
|
||||
const emit = defineEmits(['update:visible', 'created']);
|
||||
|
||||
const showContacts = ref(false);
|
||||
const showAddresses = ref(false);
|
||||
const isSubmitting = ref(false);
|
||||
|
||||
// Direct arrays instead of wrapping in formData objects
|
||||
const newContacts = ref([
|
||||
|
|
@ -136,16 +141,57 @@ function close() {
|
|||
emit('update:visible', false);
|
||||
}
|
||||
|
||||
function create() {
|
||||
const payload = {};
|
||||
if (showContacts.value) {
|
||||
payload.contacts = newContacts.value;
|
||||
async function create() {
|
||||
isSubmitting.value = true;
|
||||
try {
|
||||
const contactsToSend = showContacts.value ? newContacts.value : [];
|
||||
const addressesToSend = showAddresses.value ? newAddresses.value : [];
|
||||
|
||||
// Check if any contacts or addresses already exist
|
||||
const existingMessages = [];
|
||||
|
||||
if (contactsToSend.length > 0) {
|
||||
const existingContactsResult = await Api.checkContactsExist(contactsToSend);
|
||||
if (existingContactsResult && existingContactsResult.length > 0) {
|
||||
const names = existingContactsResult.map(c => `${c.firstName || ''} ${c.lastName || ''}`.trim()).join(', ');
|
||||
existingMessages.push(`Contact(s) already exist: ${names}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (addressesToSend.length > 0) {
|
||||
const existingAddressesResult = await Api.checkAddressesExist(addressesToSend);
|
||||
if (existingAddressesResult && existingAddressesResult.length > 0) {
|
||||
const addrs = existingAddressesResult.map(a => `${a.addressLine1 || ''} ${a.city || ''}`).join(', ');
|
||||
existingMessages.push(`Address(es) already exist: ${addrs}`);
|
||||
}
|
||||
}
|
||||
|
||||
// If any exist, prompt the user for confirmation
|
||||
if (existingMessages.length > 0) {
|
||||
const message = existingMessages.join('\n') + '\n\nWould you like to proceed anyway? Existing records will be linked instead of duplicated.';
|
||||
if (!window.confirm(message)) {
|
||||
isSubmitting.value = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Call API to create/link contacts and addresses
|
||||
// Address contacts/primaryContact are dicts with firstName, lastName, email
|
||||
// that the backend matches against created/existing contact docs
|
||||
const result = await Api.createClientContactsAddresses(
|
||||
props.clientName,
|
||||
companyStore.currentCompany,
|
||||
contactsToSend,
|
||||
addressesToSend
|
||||
);
|
||||
|
||||
emit('created', result);
|
||||
close();
|
||||
} catch (error) {
|
||||
console.error('Error creating contacts/addresses:', error);
|
||||
} finally {
|
||||
isSubmitting.value = false;
|
||||
}
|
||||
if (showAddresses.value) {
|
||||
payload.addresses = newAddresses.value;
|
||||
}
|
||||
emit('created', payload);
|
||||
close();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -98,9 +98,11 @@
|
|||
<AddContactAddressModal
|
||||
:visible="showAddModal"
|
||||
@update:visible="showAddModal = $event"
|
||||
:clientName="clientData.customerName"
|
||||
:clientContacts="clientData.contacts || []"
|
||||
:existingContacts="clientData.contacts?.map(c => c.fullName || c.name) || []"
|
||||
:existingAddresses="clientData.addresses?.map(a => a.addressLine1) || []"
|
||||
@created="onContactsAddressesCreated"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -126,6 +128,8 @@ const props = defineProps({
|
|||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['refresh']);
|
||||
|
||||
// Check if client is a Lead
|
||||
const isLead = computed(() => props.clientData.doctype === "Lead");
|
||||
|
||||
|
|
@ -173,6 +177,11 @@ const formattedCreationDate = computed(() => {
|
|||
});
|
||||
});
|
||||
|
||||
// Handle successful contact/address creation - emit refresh so parent reloads client data
|
||||
const onContactsAddressesCreated = () => {
|
||||
emit('refresh');
|
||||
};
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
<GeneralClientInfo
|
||||
v-if="client.customerName"
|
||||
:client-data="client"
|
||||
@refresh="refreshClient"
|
||||
/>
|
||||
<AdditionalInfoBar :address="client.addresses[selectedAddressIdx]" v-if="client.customerName" />
|
||||
|
||||
|
|
@ -461,6 +462,12 @@ const handleCustomerSelected = (clientData) => {
|
|||
// Handle customer selected from search
|
||||
client.value = { ...client.value, ...clientData };
|
||||
};
|
||||
|
||||
const refreshClient = async () => {
|
||||
if (clientName) {
|
||||
await getClient(clientName);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="css">
|
||||
.tab-info-alert {
|
||||
|
|
|
|||
|
|
@ -390,7 +390,6 @@ const loadChartData = async() => {
|
|||
};
|
||||
|
||||
onMounted(async() => {
|
||||
notifications.addWarning("Dashboard metrics are based on dummy data for demonstration purposes. UPDATES COMING SOON!");
|
||||
await loadChartData();
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue