Merge pull request #862 from frappe/main-hotfix

This commit is contained in:
Shariq Ansari 2025-05-26 13:59:50 +05:30 committed by GitHub
commit e6c4075ece
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 431 additions and 338 deletions

View File

@ -190,11 +190,20 @@ def get_call_log(name):
@frappe.whitelist() @frappe.whitelist()
def create_lead_from_call_log(call_log): def create_lead_from_call_log(call_log, lead_details=None):
lead = frappe.new_doc("CRM Lead") lead = frappe.new_doc("CRM Lead")
lead.first_name = "Lead from call " + call_log.get("from") lead_details = frappe.parse_json(lead_details or "{}")
lead.mobile_no = call_log.get("from")
lead.lead_owner = frappe.session.user if not lead_details.get("lead_owner"):
lead_details["lead_owner"] = frappe.session.user
if not lead_details.get("mobile_no"):
lead_details["mobile_no"] = call_log.get("from") or ""
if not lead_details.get("first_name"):
lead_details["first_name"] = "Lead from call " + (
lead_details.get("mobile_no") or call_log.get("name")
)
lead.update(lead_details)
lead.save(ignore_permissions=True) lead.save(ignore_permissions=True)
# link call log with lead # link call log with lead

File diff suppressed because it is too large Load Diff

View File

@ -64,7 +64,10 @@ const emit = defineEmits(['change'])
const { getFields } = getMeta(props.doctype) const { getFields } = getMeta(props.doctype)
const values = defineModel() const values = defineModel({
type: Array,
default: () => [],
})
const valuesRef = ref([]) const valuesRef = ref([])
const error = ref(null) const error = ref(null)

View File

@ -206,7 +206,7 @@
v-else v-else
type="text" type="text"
:placeholder="getPlaceholder(field)" :placeholder="getPlaceholder(field)"
:value="data[field.fieldname]" :value="getDataValue(data[field.fieldname], field)"
:disabled="Boolean(field.read_only)" :disabled="Boolean(field.read_only)"
:description="field.description" :description="field.description"
@change="fieldChange($event.target.value, field)" @change="fieldChange($event.target.value, field)"
@ -340,6 +340,13 @@ function fieldChange(value, df) {
triggerOnChange(df.fieldname) triggerOnChange(df.fieldname)
} }
} }
function getDataValue(value, field) {
if (field.fieldtype === 'Duration') {
return value || 0
}
return value
}
</script> </script>
<style scoped> <style scoped>
:deep(.form-control.prefix select) { :deep(.form-control.prefix select) {

View File

@ -126,7 +126,7 @@
<div class="flex items-center justify-between gap-2"> <div class="flex items-center justify-between gap-2">
<Autocomplete <Autocomplete
value="" value=""
:options="filterableFields.data" :options="availableFilters"
@change="(e) => setfilter(e)" @change="(e) => setfilter(e)"
:placeholder="__('First name')" :placeholder="__('First name')"
> >
@ -217,6 +217,19 @@ const filters = computed(() => {
return convertFilters(filterableFields.data, allFilters) return convertFilters(filterableFields.data, allFilters)
}) })
const availableFilters = computed(() => {
if (!filterableFields.data) return []
const selectedFieldNames = new Set()
for (const filter of filters.value) {
selectedFieldNames.add(filter.fieldname)
}
return filterableFields.data.filter(
(field) => !selectedFieldNames.has(field.fieldname),
)
})
function removeCommonFilters(commonFilters, allFilters) { function removeCommonFilters(commonFilters, allFilters) {
for (const key in commonFilters) { for (const key in commonFilters) {
if (commonFilters.hasOwnProperty(key) && allFilters.hasOwnProperty(key)) { if (commonFilters.hasOwnProperty(key) && allFilters.hasOwnProperty(key)) {

View File

@ -172,8 +172,9 @@ import FadedScrollableDiv from '@/components/FadedScrollableDiv.vue'
import { getCallLogDetail } from '@/utils/callLog' import { getCallLogDetail } from '@/utils/callLog'
import { usersStore } from '@/stores/users' import { usersStore } from '@/stores/users'
import { isMobileView } from '@/composables/settings' import { isMobileView } from '@/composables/settings'
import { useDocument } from '@/data/document'
import { FeatherIcon, Dropdown, Avatar, Tooltip, call } from 'frappe-ui' import { FeatherIcon, Dropdown, Avatar, Tooltip, call } from 'frappe-ui'
import { ref, computed, h, nextTick } from 'vue' import { ref, computed, h, nextTick, watch } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
const { isManager } = usersStore() const { isManager } = usersStore()
@ -289,9 +290,19 @@ const detailFields = computed(() => {
.filter((detail) => (detail.condition ? detail.condition() : true)) .filter((detail) => (detail.condition ? detail.condition() : true))
}) })
function createLead() { const d = ref({})
const leadDetails = ref({})
async function createLead() {
await d.value.triggerOnCreateLead?.(
callLog.value?.data,
leadDetails.value,
() => (show.value = false),
)
call('crm.fcrm.doctype.crm_call_log.crm_call_log.create_lead_from_call_log', { call('crm.fcrm.doctype.crm_call_log.crm_call_log.create_lead_from_call_log', {
call_log: callLog.value?.data, call_log: callLog.value?.data,
lead_details: leadDetails.value,
}).then((d) => { }).then((d) => {
if (d) { if (d) {
router.push({ name: 'Lead', params: { leadId: d } }) router.push({ name: 'Lead', params: { leadId: d } })
@ -351,6 +362,14 @@ async function addTaskToCallLog(_task, insert_mode = false) {
}) })
} }
} }
watch(
() => callLog.value?.data?.name,
(value) => {
if (!value) return
d.value = useDocument('CRM Call Log', value)
},
)
</script> </script>
<style scoped> <style scoped>

View File

@ -752,6 +752,7 @@ const quickFilterOptions = computed(() => {
let fields = getFields() let fields = getFields()
if (!fields) return [] if (!fields) return []
let existingQuickFilters = newQuickFilters.value.map((f) => f.fieldname)
let restrictedFieldtypes = [ let restrictedFieldtypes = [
'Tab Break', 'Tab Break',
'Section Break', 'Section Break',
@ -766,6 +767,7 @@ const quickFilterOptions = computed(() => {
] ]
let options = fields let options = fields
.filter((f) => f.label && !restrictedFieldtypes.includes(f.fieldtype)) .filter((f) => f.label && !restrictedFieldtypes.includes(f.fieldtype))
.filter((f) => !existingQuickFilters.includes(f.fieldname))
.map((field) => ({ .map((field) => ({
label: field.label, label: field.label,
value: field.fieldname, value: field.fieldname,

View File

@ -97,6 +97,14 @@ export function useDocument(doctype, docname) {
await trigger(handler, rows[0]) await trigger(handler, rows[0])
} }
async function triggerOnCreateLead() {
const args = Array.from(arguments)
const handler = async function () {
await this.on_create_lead(...args)
}
await trigger(handler)
}
async function trigger(taskFn, row = null) { async function trigger(taskFn, row = null) {
const controllers = getControllers(row) const controllers = getControllers(row)
if (!controllers.length) return if (!controllers.length) return
@ -130,5 +138,6 @@ export function useDocument(doctype, docname) {
triggerOnRowRemove, triggerOnRowRemove,
triggerOnRefresh, triggerOnRefresh,
setupFormScript, setupFormScript,
triggerOnCreateLead,
} }
} }