Skip to content

Commit

Permalink
feat: add total_billing_hours to Sales Invoice
Browse files Browse the repository at this point in the history
  • Loading branch information
sagarvora committed Oct 2, 2021
1 parent ece446f commit 9cfd1fd
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 189 deletions.
174 changes: 96 additions & 78 deletions erpnext/accounts/doctype/sales_invoice/sales_invoice.js
Original file line number Diff line number Diff line change
Expand Up @@ -725,19 +725,6 @@ frappe.ui.form.on('Sales Invoice', {
}
},

project: function(frm){
if (!frm.doc.is_return) {
frm.call({
method: "add_timesheet_data",
doc: frm.doc,
callback: function(r, rt) {
refresh_field(['timesheets'])
}
})
frm.refresh();
}
},

onload: function(frm) {
frm.redemption_conversion_factor = null;
},
Expand Down Expand Up @@ -848,25 +835,92 @@ frappe.ui.form.on('Sales Invoice', {
}
},

add_timesheet_row: function(frm, row, exchange_rate) {
frm.add_child('timesheets', {
'activity_type': row.activity_type,
'description': row.description,
'time_sheet': row.parent,
'billing_hours': row.billing_hours,
'billing_amount': flt(row.billing_amount) * flt(exchange_rate),
'timesheet_detail': row.name,
'project_name': row.project_name
project: function(frm) {
if (frm.doc.project) {
frm.events.add_timesheet_data(frm, {
project: frm.doc.project
});
}
},

async add_timesheet_data(frm, kwargs) {
if (kwargs === "Sales Invoice") {
// called via frm.trigger()
kwargs = Object();
}

if (!kwargs.hasOwnProperty("project") && frm.doc.project) {
kwargs.project = frm.doc.project;
}

const timesheets = await frm.events.get_timesheet_data(frm, kwargs);
return frm.events.set_timesheet_data(frm, timesheets);
},

async get_timesheet_data(frm, kwargs) {
return frappe.call({
method: "erpnext.projects.doctype.timesheet.timesheet.get_projectwise_timesheet_data",
args: kwargs
}).then(r => {
if (!r.exc && r.message.length > 0) {
return r.message
} else {
return []
}
});
},

set_timesheet_data: function(frm, timesheets) {
frm.clear_table("timesheets")
timesheets.forEach(timesheet => {
if (frm.doc.currency != timesheet.currency) {
frappe.call({
method: "erpnext.setup.utils.get_exchange_rate",
args: {
from_currency: timesheet.currency,
to_currency: frm.doc.currency
},
callback: function(r) {
if (r.message) {
exchange_rate = r.message;
frm.events.append_time_log(frm, timesheet, exchange_rate);
}
}
});
} else {
frm.events.append_time_log(frm, timesheet, 1.0);
}
});
frm.refresh_field('timesheets');
calculate_total_billing_amount(frm);
},

append_time_log: function(frm, time_log, exchange_rate) {
const row = frm.add_child("timesheets");
row.activity_type = time_log.activity_type;
row.description = time_log.description;
row.time_sheet = time_log.time_sheet;
row.from_time = time_log.from_time;
row.to_time = time_log.to_time;
row.billing_hours = time_log.billing_hours;
row.billing_amount = flt(time_log.billing_amount) * flt(exchange_rate);
row.timesheet_detail = time_log.name;
row.project_name = time_log.project_name;

frm.refresh_field("timesheets");
frm.trigger("calculate_timesheet_totals");
},

calculate_timesheet_totals: function(frm) {
frm.set_value("total_billing_amount",
frm.doc.timesheets.reduce((a, b) => a + (b["billing_amount"] || 0.0), 0.0));
frm.set_value("total_billing_hours",
frm.doc.timesheets.reduce((a, b) => a + (b["billing_hours"] || 0.0), 0.0));
},

refresh: function(frm) {
if (frm.doc.docstatus===0 && !frm.doc.is_return) {
frm.add_custom_button(__('Fetch Timesheet'), function() {
frm.add_custom_button(__("Fetch Timesheet"), function() {
let d = new frappe.ui.Dialog({
title: __('Fetch Timesheet'),
title: __("Fetch Timesheet"),
fields: [
{
"label" : __("From"),
Expand All @@ -875,8 +929,8 @@ frappe.ui.form.on('Sales Invoice', {
"reqd": 1,
},
{
fieldtype: 'Column Break',
fieldname: 'col_break_1',
fieldtype: "Column Break",
fieldname: "col_break_1",
},
{
"label" : __("To"),
Expand All @@ -893,48 +947,18 @@ frappe.ui.form.on('Sales Invoice', {
},
],
primary_action: function() {
let data = d.get_values();
frappe.call({
method: "erpnext.projects.doctype.timesheet.timesheet.get_projectwise_timesheet_data",
args: {
from_time: data.from_time,
to_time: data.to_time,
project: data.project
},
callback: function(r) {
if (!r.exc && r.message.length > 0) {
frm.clear_table('timesheets')
r.message.forEach((d) => {
let exchange_rate = 1.0;
if (frm.doc.currency != d.currency) {
frappe.call({
method: 'erpnext.setup.utils.get_exchange_rate',
args: {
from_currency: d.currency,
to_currency: frm.doc.currency
},
callback: function(r) {
if (r.message) {
exchange_rate = r.message;
frm.events.add_timesheet_row(frm, d, exchange_rate);
}
}
});
} else {
frm.events.add_timesheet_row(frm, d, exchange_rate);
}
});
} else {
frappe.msgprint(__('No Timesheets found with the selected filters.'))
}
d.hide();
}
const data = d.get_values();
frm.events.add_timesheet_data(frm, {
from_time: data.from_time,
to_time: data.to_time,
project: data.project
});
d.hide();
},
primary_action_label: __('Get Timesheets')
primary_action_label: __("Get Timesheets")
});
d.show();
})
});
}

if (frm.doc.is_debit_note) {
Expand Down Expand Up @@ -967,26 +991,20 @@ frappe.ui.form.on('Sales Invoice', {
frm: frm
});
},

create_dunning: function(frm) {
frappe.model.open_mapped_doc({
method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.create_dunning",
frm: frm
});
}
})

var calculate_total_billing_amount = function(frm) {
var doc = frm.doc;
});

doc.total_billing_amount = 0.0
if (doc.timesheets) {
doc.timesheets.forEach((d) => {
doc.total_billing_amount += flt(d.billing_amount)
});
frappe.ui.form.on("Sales Invoice Timesheet", {
timesheets_remove(frm, cdt, cdn) {
frm.trigger("calculate_timesheet_totals");
}

refresh_field('total_billing_amount')
}
});

var set_timesheet_detail_rate = function(cdt, cdn, currency, timelog) {
frappe.call({
Expand Down
12 changes: 10 additions & 2 deletions erpnext/accounts/doctype/sales_invoice/sales_invoice.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"time_sheet_list",
"timesheets",
"total_billing_amount",
"total_billing_hours",
"section_break_30",
"total_qty",
"base_total",
Expand Down Expand Up @@ -2011,6 +2012,13 @@
"hidden": 1,
"label": "Ignore Default Payment Terms Template",
"read_only": 1
},
{
"fieldname": "total_billing_hours",
"fieldtype": "Float",
"label": "Total Billing Hours",
"print_hide": 1,
"read_only": 1
}
],
"icon": "fa fa-file-text",
Expand All @@ -2023,7 +2031,7 @@
"link_fieldname": "consolidated_invoice"
}
],
"modified": "2021-09-28 13:09:34.391799",
"modified": "2021-09-29 13:09:34.391799",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",
Expand Down Expand Up @@ -2078,4 +2086,4 @@
"title_field": "title",
"track_changes": 1,
"track_seen": 1
}
}
11 changes: 5 additions & 6 deletions erpnext/accounts/doctype/sales_invoice/sales_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,7 @@ def add_timesheet_data(self):
if self.project:
for data in get_projectwise_timesheet_data(self.project):
self.append('timesheets', {
'time_sheet': data.parent,
'time_sheet': data.time_sheet,
'billing_hours': data.billing_hours,
'billing_amount': data.billing_amount,
'timesheet_detail': data.name,
Expand All @@ -783,12 +783,11 @@ def add_timesheet_data(self):
self.calculate_billing_amount_for_timesheet()

def calculate_billing_amount_for_timesheet(self):
total_billing_amount = 0.0
for data in self.timesheets:
if data.billing_amount:
total_billing_amount += data.billing_amount
def timesheet_sum(field):
return sum((ts.get(field) or 0.0) for ts in self.timesheets)

self.total_billing_amount = total_billing_amount
self.total_billing_amount = timesheet_sum("billing_amount")
self.total_billing_hours = timesheet_sum("billing_hours")

def get_warehouse(self):
user_pos_profile = frappe.db.sql("""select name, warehouse from `tabPOS Profile`
Expand Down
Loading

0 comments on commit 9cfd1fd

Please sign in to comment.