fix: create new contact from deals add contact
This commit is contained in:
parent
50fceef0c3
commit
d3d9caad5d
@ -9,7 +9,7 @@
|
|||||||
label: editMode ? 'Update' : 'Create',
|
label: editMode ? 'Update' : 'Create',
|
||||||
variant: 'solid',
|
variant: 'solid',
|
||||||
disabled: !dirty,
|
disabled: !dirty,
|
||||||
onClick: ({ close }) => updateContact(close),
|
onClick: ({ close }) => editMode ? updateContact(close) : callInsertDoc(close),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}"
|
}"
|
||||||
@ -42,11 +42,21 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<FormControl
|
<FormControl
|
||||||
type="text"
|
type="autocomplete"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="md"
|
size="md"
|
||||||
label="Organisation"
|
label="Organisation"
|
||||||
v-model="_contact.company_name"
|
:value="_contact.company_name"
|
||||||
|
:options="
|
||||||
|
organizations.data.map((d) => {
|
||||||
|
return {
|
||||||
|
label: d.name,
|
||||||
|
value: d.name,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
"
|
||||||
|
@change="(e) => (_contact.company_name = e.value)"
|
||||||
|
placeholder="Select organization"
|
||||||
/>
|
/>
|
||||||
<div class="flex gap-4">
|
<div class="flex gap-4">
|
||||||
<FormControl
|
<FormControl
|
||||||
@ -74,53 +84,72 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { FormControl, Dialog, call } from 'frappe-ui'
|
import { FormControl, Dialog, call } from 'frappe-ui'
|
||||||
import { ref, defineModel, nextTick, watch, computed } from 'vue'
|
import { ref, defineModel, nextTick, watch, computed } from 'vue'
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router'
|
||||||
|
import { organizationsStore } from '@/stores/organizations'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
contact: {
|
contact: {
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {},
|
default: {},
|
||||||
},
|
},
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
default: {
|
||||||
|
redirect: true,
|
||||||
|
afterInsert: () => {},
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const show = defineModel()
|
const show = defineModel()
|
||||||
const contacts = defineModel('reloadContacts')
|
const contacts = defineModel('reloadContacts')
|
||||||
|
|
||||||
|
const { organizations } = organizationsStore()
|
||||||
|
|
||||||
const editMode = ref(false)
|
const editMode = ref(false)
|
||||||
let _contact = ref({})
|
let _contact = ref({})
|
||||||
|
|
||||||
async function updateContact(close) {
|
async function updateContact(close) {
|
||||||
if (JSON.stringify(props.contact) === JSON.stringify(_contact.value)) {
|
if (!dirty.value) {
|
||||||
|
close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_contact.value.name) {
|
let name = await callSetValue(values)
|
||||||
let d = await call('frappe.client.set_value', {
|
|
||||||
|
handleContactUpdate({ name }, close)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function callSetValue(values) {
|
||||||
|
const d = await call('frappe.client.set_value', {
|
||||||
|
doctype: 'Contact',
|
||||||
|
name: _contact.value.name,
|
||||||
|
fieldname: values,
|
||||||
|
})
|
||||||
|
return d.name
|
||||||
|
}
|
||||||
|
|
||||||
|
async function callInsertDoc(close) {
|
||||||
|
const doc = await call('frappe.client.insert', {
|
||||||
|
doc: {
|
||||||
doctype: 'Contact',
|
doctype: 'Contact',
|
||||||
name: _contact.value.name,
|
..._contact.value,
|
||||||
fieldname: _contact.value,
|
},
|
||||||
|
})
|
||||||
|
doc.name && handleContactUpdate(doc, close)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleContactUpdate(doc, close) {
|
||||||
|
contacts.value?.reload()
|
||||||
|
if (doc.name && props.options.redirect) {
|
||||||
|
router.push({
|
||||||
|
name: 'Contact',
|
||||||
|
params: { contactId: doc.name },
|
||||||
})
|
})
|
||||||
if (d.name) {
|
|
||||||
contacts.value.reload()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let d = await call('frappe.client.insert', {
|
|
||||||
doc: {
|
|
||||||
doctype: 'Contact',
|
|
||||||
..._contact.value,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if (d.name) {
|
|
||||||
contacts.value.reload()
|
|
||||||
router.push({
|
|
||||||
name: 'Contact',
|
|
||||||
params: { contactId: d.name },
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
close()
|
close && close()
|
||||||
|
props.options.afterInsert && props.options.afterInsert(doc)
|
||||||
}
|
}
|
||||||
|
|
||||||
const dirty = computed(() => {
|
const dirty = computed(() => {
|
||||||
@ -134,7 +163,7 @@ watch(
|
|||||||
editMode.value = false
|
editMode.value = false
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
_contact.value = { ...props.contact }
|
_contact.value = { ...props.contact }
|
||||||
if (_contact.value.first_name) {
|
if (_contact.value.name) {
|
||||||
editMode.value = true
|
editMode.value = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -57,13 +57,13 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
const show = defineModel()
|
const show = defineModel()
|
||||||
const organizations = defineModel('reloadOrganizations')
|
const organizations = defineModel('reloadOrganizations')
|
||||||
|
|
||||||
const title = ref(null)
|
const title = ref(null)
|
||||||
const editMode = ref(false)
|
const editMode = ref(false)
|
||||||
let _organization = ref({})
|
let _organization = ref({})
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
async function updateOrganization(close) {
|
async function updateOrganization(close) {
|
||||||
const old = { ...props.organization }
|
const old = { ...props.organization }
|
||||||
|
|||||||
@ -125,7 +125,7 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
@change="(e) => addContact(e.value)"
|
@change="(e) => e.value && addContact(e.value)"
|
||||||
>
|
>
|
||||||
<template #target="{ togglePopover }">
|
<template #target="{ togglePopover }">
|
||||||
<Button
|
<Button
|
||||||
@ -138,6 +138,29 @@
|
|||||||
</template>
|
</template>
|
||||||
</Button>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
|
<template #footer="{ value, close }">
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
class="w-full !justify-start"
|
||||||
|
label="Create one"
|
||||||
|
@click="
|
||||||
|
() => {
|
||||||
|
_contact = {
|
||||||
|
first_name: value,
|
||||||
|
company_name: deal.data.organization,
|
||||||
|
}
|
||||||
|
showContactModal = true
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<FeatherIcon name="plus" class="h-4" />
|
||||||
|
</template>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</Autocomplete>
|
</Autocomplete>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -339,7 +362,10 @@
|
|||||||
class="mx-2 h-px border-t border-gray-200"
|
class="mx-2 h-px border-t border-gray-200"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="flex justify-center items-center text-base text-gray-600 h-20">
|
<div
|
||||||
|
v-else
|
||||||
|
class="flex h-20 items-center justify-center text-base text-gray-600"
|
||||||
|
>
|
||||||
No contacts added
|
No contacts added
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -359,6 +385,14 @@
|
|||||||
afterInsert: (doc) => updateField('organization', doc.name),
|
afterInsert: (doc) => updateField('organization', doc.name),
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
|
<ContactModal
|
||||||
|
v-model="showContactModal"
|
||||||
|
:contact="_contact"
|
||||||
|
:options="{
|
||||||
|
redirect: false,
|
||||||
|
afterInsert: (doc) => addContact(doc.name),
|
||||||
|
}"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import ActivityIcon from '@/components/Icons/ActivityIcon.vue'
|
import ActivityIcon from '@/components/Icons/ActivityIcon.vue'
|
||||||
@ -374,6 +408,7 @@ import Toggler from '@/components/Toggler.vue'
|
|||||||
import Activities from '@/components/Activities.vue'
|
import Activities from '@/components/Activities.vue'
|
||||||
import UserAvatar from '@/components/UserAvatar.vue'
|
import UserAvatar from '@/components/UserAvatar.vue'
|
||||||
import OrganizationModal from '@/components/Modals/OrganizationModal.vue'
|
import OrganizationModal from '@/components/Modals/OrganizationModal.vue'
|
||||||
|
import ContactModal from '@/components/Modals/ContactModal.vue'
|
||||||
import Autocomplete from '@/components/frappe-ui/Autocomplete.vue'
|
import Autocomplete from '@/components/frappe-ui/Autocomplete.vue'
|
||||||
import {
|
import {
|
||||||
dealStatuses,
|
dealStatuses,
|
||||||
@ -560,14 +595,17 @@ const detailSections = computed(() => {
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const showContactModal = ref(false)
|
||||||
|
const _contact = ref({})
|
||||||
|
|
||||||
async function addContact(value) {
|
async function addContact(value) {
|
||||||
let d = await call('crm.fcrm.doctype.crm_deal.crm_deal.add_contact', {
|
let d = await call('crm.fcrm.doctype.crm_deal.crm_deal.add_contact', {
|
||||||
deal: props.dealId,
|
deal: props.dealId,
|
||||||
contact: value,
|
contact: value,
|
||||||
})
|
})
|
||||||
if (d) {
|
if (d) {
|
||||||
|
await contacts.reload()
|
||||||
deal.reload()
|
deal.reload()
|
||||||
contacts.reload()
|
|
||||||
createToast({
|
createToast({
|
||||||
title: 'Contact added',
|
title: 'Contact added',
|
||||||
icon: 'check',
|
icon: 'check',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user