[Devis] MĂ©thode de chiffrage pour entreprise de service / installateur

Bonjour,
ça y est, j’ai mis le choses en place, voila le rendu:


A chaque fois on a les couts qui se rajoutent au fur et a mesure au PR. La marge est progressivement rognĂ© jusqu’à la marge totale.
On peut ainsi modifier les PV des articles pour ajuster cette marge (idĂ©alement il faudrait pouvoir indiquer pour la MO le PV souhaitĂ© et mettre Ă  jour automatiquement tous les articles de MO et de mĂȘme sur la marge matĂ©riel)

Je vous joint les différents blocs au cas ou ça peu intéresser et développer la solution de chiffrage.

Ci-dessous aussi le script clients adapté:

frappe.ui.form.on('Quotation Item', {
	pl_selected_supplier(frm, cdt, cdn) {
	    const item = locals[cdt][cdn]
		frappe.call({
			method: "erpnext.stock.get_item_details.get_item_details",
			args: {
				doc: frm.doc,
				args: {
					item_code: item.item_code,
					barcode: item.barcode,
					serial_no: item.serial_no,
					batch_no: item.batch_no,
					warehouse: item.warehouse,
					supplier: item.pl_selected_supplier,
					currency: frm.doc.currency,
					update_stock: 0,
					conversion_rate: frm.doc.conversion_rate,
					price_list: "Achat Standard",
					price_list_currency: frm.doc.price_list_currency,
					plc_conversion_rate: frm.doc.plc_conversion_rate,
					company: frm.doc.company,
					ignore_pricing_rule: frm.doc.ignore_pricing_rule,
					doctype: frm.doc.doctype,
					name: frm.doc.name,
					project: item.project || frm.doc.project,
					qty: item.qty || 1,
					net_rate: item.rate,
					stock_qty: item.stock_qty,
					conversion_factor: item.conversion_factor,
					weight_per_unit: item.weight_per_unit,
					uom: item.uom,
					weight_uom: item.weight_uom,
					manufacturer: item.manufacturer,
					stock_uom: item.stock_uom,
					cost_center: item.cost_center,
					tax_category: frm.doc.tax_category,
					item_tax_template: item.item_tax_template,
					child_docname: item.name,
					transaction_type: "buying"
				}
			}
		}).then(r => {
		    //console.log(r)
	        frappe.model.set_value(item.doctype, item.name, "pl_supplier_price_list_rate", flt(r.message.price_list_rate))
	        frappe.model.set_value(item.doctype, item.name, "pl_supplier_discount_percentage", flt(r.message.discount_percentage || 0))
	        frappe.model.set_value(item.doctype, item.name, "pl_unit_cost", flt(r.message.price_list_rate  - (r.message.price_list_rate * (r.message.discount_percentage || 0) / 100)))
		})
	},
	
	pl_set_selling_rate(frm, cdt, cdn) {
	    const item = locals[cdt][cdn]
	    frappe.model.set_value(item.doctype, item.name, "rate", flt(item.pl_unit_cost))
	}
})

function update_cout_total(frm, cdt, cdn){
    // frm: current ToDo form
    // cdt: child DocType 'Dynamic Link'
    // cdn: child docname (something like 'a6dfk76')
    // cdt and cdn are useful for identifying which row triggered this event
	console.log(frm, cdt, cdn)
	const item=locals[cdt][cdn]
	frappe.model.set_value(item.doctype, item.name, "cout_total", flt(item.cout_horaire*item.nb_heures))
}

frappe.ui.form.on('PL_items_etudes', {
    cout_horaire(frm, cdt, cdn) {
        update_cout_total(frm, cdt, cdn)
	},
	nb_heures(frm, cdt, cdn) {
        update_cout_total(frm, cdt, cdn)
	}
})

frappe.ui.form.on('PL_frais_devis_suppl', {
    pourcentage_pri(frm, cdt, cdn) {
        const item=locals[cdt][cdn]
	    frappe.model.set_value(item.doctype, item.name, "montant_total", flt(frm.doc.pl_pri*item.pourcentage_pri)/100)
	}
})

et le script python:

doc.pl_prc = 0.0
for item in doc.items:
    doc.pl_prc = frappe.utils.flt(doc.pl_prc) + frappe.utils.flt(item.pl_unit_cost or item.rate) * frappe.utils.flt(item.qty)

doc.pl_pri = frappe.utils.flt(doc.pl_prc)
for item in doc.pl_couts_etudes:
    doc.pl_pri = frappe.utils.flt(doc.pl_pri) + frappe.utils.flt(item.cout_total)

doc.pl_prt = frappe.utils.flt(doc.pl_pri)
for item in doc.pl_frais_devis_suppl:
    item.montant_total=doc.pl_pri*item.pourcentage_pri/100
    doc.pl_prt = frappe.utils.flt(doc.pl_prt) + frappe.utils.flt(item.montant_total)
  
doc.pl_margin_rate = frappe.utils.flt(doc.net_total) - frappe.utils.flt(doc.pl_prt)  
doc.pl_total_margin_percentage = frappe.utils.flt(doc.pl_margin_rate) / frappe.utils.flt(doc.net_total) * 100

Et les doctypes personnalisés:


et les 2 nouveaux doctypes:

J’ai une question, pour le moment, les lignes des Ă©tudes et des frais supplĂ©mentaires sont rajoutĂ© Ă  la main dans les tableaux. Comment faire pour avoir les lignes prĂ©remplies Ă  la crĂ©ation d’un devis. Peut-on faire des modĂšles de devis types ?

A trĂšs vite