diff --git a/models/baseModels/Lead/Lead.ts b/models/baseModels/Lead/Lead.ts index 3037ab46..a45cdcb4 100644 --- a/models/baseModels/Lead/Lead.ts +++ b/models/baseModels/Lead/Lead.ts @@ -11,6 +11,7 @@ import { validateEmail, validatePhoneNumber, } from 'fyo/model/validationFunction'; +import { ModelNameEnum } from 'models/types'; export class Lead extends Doc { status?: LeadStatus; @@ -20,6 +21,24 @@ export class Lead extends Doc { mobile: validatePhoneNumber, }; + createCustomer() { + return this.fyo.doc.getNewDoc(ModelNameEnum.Party, { + ...this.getValidDict(), + fromLead: this.name, + phone: this.mobile as string, + role: 'Customer', + }); + } + + createSalesQuote() { + const data: { party: string | undefined; referenceType: string } = { + party: this.name, + referenceType: ModelNameEnum.Lead, + }; + + return this.fyo.doc.getNewDoc(ModelNameEnum.SalesQuote, data); + } + static getActions(fyo: Fyo): Action[] { return getLeadActions(fyo); } diff --git a/models/baseModels/tests/testLead.spec.ts b/models/baseModels/tests/testLead.spec.ts index 846b63ff..e28332c7 100644 --- a/models/baseModels/tests/testLead.spec.ts +++ b/models/baseModels/tests/testLead.spec.ts @@ -11,7 +11,7 @@ const leadData = { name: 'name2', status: 'Open', email: 'sample@gmail.com', - mobile: '1231233545', + mobile: '7356203811', }; const itemData: { name: string; rate: number } = { @@ -40,29 +40,24 @@ test('create a Lead doc', async (t) => { test('create Customer from Lead', async (t) => { const leadDoc = (await fyo.doc.getDoc(ModelNameEnum.Lead, 'name2')) as Lead; - const newPartyDoc = fyo.doc.getNewDoc(ModelNameEnum.Party, { - ...leadDoc.getValidDict(), - fromLead: leadData.name, - role: 'Customer', - phone: leadData.mobile as string, - }); + const newCustomer = leadDoc.createCustomer(); t.equals( leadDoc.status, 'Open', - 'Before Customer created the status must be Open' + 'status must be Open before Customer is created' ); - await newPartyDoc.sync(); + await newCustomer.sync(); t.equals( leadDoc.status, 'Converted', - 'After Customer created the status change to Converted' + 'status should change to Converted after Customer is created' ); t.ok( - await fyo.db.exists(ModelNameEnum.Party, newPartyDoc.name), + await fyo.db.exists(ModelNameEnum.Party, newCustomer.name), 'Customer created from Lead' ); }); @@ -70,26 +65,23 @@ test('create Customer from Lead', async (t) => { test('create SalesQuote', async (t) => { const leadDoc = (await fyo.doc.getDoc(ModelNameEnum.Lead, 'name2')) as Lead; - const docData = leadDoc.getValidDict(true, true); - const newSalesQuoteDoc = fyo.doc.getNewDoc(ModelNameEnum.SalesQuote, { - ...docData, - party: docData.name, - referenceType: ModelNameEnum.Lead, - items: [ - { - item: itemData.name, - rate: itemData.rate, - }, - ], - }) as Lead; + const newSalesQuote = leadDoc.createSalesQuote(); + + newSalesQuote.items = []; + newSalesQuote.append('items', { + item: itemData.name, + quantity: 1, + rate: itemData.rate, + }); t.equals( leadDoc.status, 'Converted', 'status must be Open before SQUOT is created' ); - await newSalesQuoteDoc.sync(); - await newSalesQuoteDoc.submit(); + + await newSalesQuote.sync(); + await newSalesQuote.submit(); t.equals( leadDoc.status, @@ -98,7 +90,7 @@ test('create SalesQuote', async (t) => { ); t.ok( - await fyo.db.exists(ModelNameEnum.SalesQuote, newSalesQuoteDoc.name), + await fyo.db.exists(ModelNameEnum.SalesQuote, newSalesQuote.name), 'SalesQuote Created from Lead' ); }); @@ -108,6 +100,7 @@ test('delete Customer then lead status changes to Interested', async (t) => { ModelNameEnum.Party, 'name2' )) as Party; + await partyDoc.delete(); t.equals( @@ -115,12 +108,13 @@ test('delete Customer then lead status changes to Interested', async (t) => { false, 'Customer deleted' ); + const leadDoc = (await fyo.doc.getDoc(ModelNameEnum.Lead, 'name2')) as Lead; t.equals( leadDoc.status, 'Interested', - 'After Customer deleted the status changed to Interested' + 'status should change to Interested after Customer is deleted' ); }); diff --git a/models/helpers.ts b/models/helpers.ts index de8ecb90..ad46ca3d 100644 --- a/models/helpers.ts +++ b/models/helpers.ts @@ -124,16 +124,12 @@ export function getCreateCustomerAction(fyo: Fyo): Action { group: fyo.t`Create`, label: fyo.t`Customer`, action: async (doc: Doc, router) => { - const partyDoc = fyo.doc.getNewDoc(ModelNameEnum.Party, { - ...doc.getValidDict(), - fromLead: doc.name, - phone: doc.mobile as string, - role: 'Customer', - }); - if (!partyDoc.name) { + const customerData = (doc as Lead).createCustomer(); + + if (!customerData.name) { return; } - await router.push(`/edit/Party/${partyDoc.name}`); + await router.push(`/edit/Party/${customerData.name}`); }, }; } @@ -143,15 +139,11 @@ export function getSalesQuoteAction(fyo: Fyo): Action { group: fyo.t`Create`, label: fyo.t`Sales Quote`, action: async (doc, router) => { - const data: { party: string | undefined; referenceType: string } = { - party: doc.name, - referenceType: ModelNameEnum.Lead, - }; - const salesQuoteDoc = fyo.doc.getNewDoc(ModelNameEnum.SalesQuote, data); - if (!salesQuoteDoc.name) { + const salesQuoteData = (doc as Lead).createSalesQuote(); + if (!salesQuoteData.name) { return; } - await router.push(`/edit/SalesQuote/${salesQuoteDoc.name}`); + await router.push(`/edit/SalesQuote/${salesQuoteData.name}`); }, }; } @@ -295,6 +287,16 @@ export function getLeadStatusColumn(): ColumnConfig { }; } +// export async function createCustomer(fyo: Fyo, doc: Doc) { +// const partyDoc = fyo.doc.getNewDoc(ModelNameEnum.Party, { +// ...doc.getValidDict(), +// fromLead: doc.name, +// phone: doc.mobile as string, +// role: 'Customer', +// }); +// return partyDoc; +// } + export const statusColor: Record< DocStatus | InvoiceStatus | LeadStatus, string | undefined