ci: add prettier to pre-commit (backport #40206) (#40362)

* ci: add prettier to pre-commit

(cherry picked from commit 2c16036ef3)

* style: format js files

---------

Co-authored-by: barredterra <14891507+barredterra@users.noreply.github.com>
Co-authored-by: Ankush Menat <ankush@frappe.io>
This commit is contained in:
mergify[bot]
2024-03-11 10:47:18 +05:30
committed by GitHub
parent 5f789d9abe
commit 7d3d2eb928
572 changed files with 24271 additions and 21331 deletions

View File

@@ -1 +1 @@
cur_frm.add_fetch('employee', 'employee_name', 'employee_name');
cur_frm.add_fetch("employee", "employee_name", "employee_name");

View File

@@ -1,12 +1,15 @@
frappe.ui.form.on("Activity Type", {
onload: function(frm) {
frm.set_currency_labels(["billing_rate", "costing_rate"], frappe.defaults.get_global_default('currency'));
onload: function (frm) {
frm.set_currency_labels(
["billing_rate", "costing_rate"],
frappe.defaults.get_global_default("currency")
);
},
refresh: function(frm) {
frm.add_custom_button(__("Activity Cost per Employee"), function() {
frappe.route_options = {"activity_type": frm.doc.name};
refresh: function (frm) {
frm.add_custom_button(__("Activity Cost per Employee"), function () {
frappe.route_options = { activity_type: frm.doc.name };
frappe.set_route("List", "Activity Cost");
});
}
},
});

View File

@@ -3,16 +3,16 @@
frappe.ui.form.on("Project", {
setup(frm) {
frm.make_methods = {
'Timesheet': () => {
Timesheet: () => {
open_form(frm, "Timesheet", "Timesheet Detail", "time_logs");
},
'Purchase Order': () => {
"Purchase Order": () => {
open_form(frm, "Purchase Order", "Purchase Order Item", "items");
},
'Purchase Receipt': () => {
"Purchase Receipt": () => {
open_form(frm, "Purchase Receipt", "Purchase Receipt Item", "items");
},
'Purchase Invoice': () => {
"Purchase Invoice": () => {
open_form(frm, "Purchase Invoice", "Purchase Invoice Item", "items");
},
};
@@ -22,31 +22,31 @@ frappe.ui.form.on("Project", {
so.get_route_options_for_new_doc = () => {
if (frm.is_new()) return {};
return {
"customer": frm.doc.customer,
"project_name": frm.doc.name
customer: frm.doc.customer,
project_name: frm.doc.name,
};
};
frm.set_query('customer', 'erpnext.controllers.queries.customer_query');
frm.set_query("customer", "erpnext.controllers.queries.customer_query");
frm.set_query("user", "users", function () {
return {
query: "erpnext.projects.doctype.project.project.get_users_for_project"
query: "erpnext.projects.doctype.project.project.get_users_for_project",
};
});
frm.set_query("department", function (doc) {
return {
filters: {
"company": doc.company,
}
company: doc.company,
},
};
});
// sales order
frm.set_query('sales_order', function () {
frm.set_query("sales_order", function () {
var filters = {
'project': ["in", frm.doc.__islocal ? [""] : [frm.doc.name, ""]]
project: ["in", frm.doc.__islocal ? [""] : [frm.doc.name, ""]],
};
if (frm.doc.customer) {
@@ -54,7 +54,7 @@ frappe.ui.form.on("Project", {
}
return {
filters: filters
filters: filters,
};
});
},
@@ -65,108 +65,133 @@ frappe.ui.form.on("Project", {
} else {
frm.add_web_link("/projects?project=" + encodeURIComponent(frm.doc.name));
frm.trigger('show_dashboard');
frm.trigger("show_dashboard");
}
frm.trigger("set_custom_buttons");
},
set_custom_buttons: function(frm) {
set_custom_buttons: function (frm) {
if (!frm.is_new()) {
frm.add_custom_button(__('Duplicate Project with Tasks'), () => {
frm.events.create_duplicate(frm);
}, __("Actions"));
frm.add_custom_button(
__("Duplicate Project with Tasks"),
() => {
frm.events.create_duplicate(frm);
},
__("Actions")
);
frm.add_custom_button(__('Update Total Purchase Cost'), () => {
frm.events.update_total_purchase_cost(frm);
}, __("Actions"));
frm.add_custom_button(
__("Update Total Purchase Cost"),
() => {
frm.events.update_total_purchase_cost(frm);
},
__("Actions")
);
frm.trigger("set_project_status_button");
if (frappe.model.can_read("Task")) {
frm.add_custom_button(__("Gantt Chart"), function () {
frappe.route_options = {
"project": frm.doc.name
};
frappe.set_route("List", "Task", "Gantt");
}, __("View"));
frm.add_custom_button(
__("Gantt Chart"),
function () {
frappe.route_options = {
project: frm.doc.name,
};
frappe.set_route("List", "Task", "Gantt");
},
__("View")
);
frm.add_custom_button(__("Kanban Board"), () => {
frappe.call('erpnext.projects.doctype.project.project.create_kanban_board_if_not_exists', {
project: frm.doc.name
}).then(() => {
frappe.set_route('List', 'Task', 'Kanban', frm.doc.project_name);
});
}, __("View"));
frm.add_custom_button(
__("Kanban Board"),
() => {
frappe
.call(
"erpnext.projects.doctype.project.project.create_kanban_board_if_not_exists",
{
project: frm.doc.name,
}
)
.then(() => {
frappe.set_route("List", "Task", "Kanban", frm.doc.project_name);
});
},
__("View")
);
}
}
},
update_total_purchase_cost: function(frm) {
update_total_purchase_cost: function (frm) {
frappe.call({
method: "erpnext.projects.doctype.project.project.recalculate_project_total_purchase_cost",
args: {project: frm.doc.name},
args: { project: frm.doc.name },
freeze: true,
freeze_message: __('Recalculating Purchase Cost against this Project...'),
callback: function(r) {
freeze_message: __("Recalculating Purchase Cost against this Project..."),
callback: function (r) {
if (r && !r.exc) {
frappe.msgprint(__('Total Purchase Cost has been updated'));
frappe.msgprint(__("Total Purchase Cost has been updated"));
frm.refresh();
}
}
},
});
},
set_project_status_button: function(frm) {
frm.add_custom_button(__('Set Project Status'), () => {
let d = new frappe.ui.Dialog({
"title": __("Set Project Status"),
"fields": [
{
"fieldname": "status",
"fieldtype": "Select",
"label": "Status",
"reqd": 1,
"options": "Completed\nCancelled",
set_project_status_button: function (frm) {
frm.add_custom_button(
__("Set Project Status"),
() => {
let d = new frappe.ui.Dialog({
title: __("Set Project Status"),
fields: [
{
fieldname: "status",
fieldtype: "Select",
label: "Status",
reqd: 1,
options: "Completed\nCancelled",
},
],
primary_action: function () {
frm.events.set_status(frm, d.get_values().status);
d.hide();
},
],
primary_action: function() {
frm.events.set_status(frm, d.get_values().status);
d.hide();
},
primary_action_label: __("Set Project Status")
}).show();
}, __("Actions"));
primary_action_label: __("Set Project Status"),
}).show();
},
__("Actions")
);
},
create_duplicate: function(frm) {
return new Promise(resolve => {
frappe.prompt('Project Name', (data) => {
frappe.xcall('erpnext.projects.doctype.project.project.create_duplicate_project',
{
create_duplicate: function (frm) {
return new Promise((resolve) => {
frappe.prompt("Project Name", (data) => {
frappe
.xcall("erpnext.projects.doctype.project.project.create_duplicate_project", {
prev_doc: frm.doc,
project_name: data.value
}).then(() => {
frappe.set_route('Form', "Project", data.value);
frappe.show_alert(__("Duplicate project has been created"));
});
project_name: data.value,
})
.then(() => {
frappe.set_route("Form", "Project", data.value);
frappe.show_alert(__("Duplicate project has been created"));
});
resolve();
});
});
},
set_status: function(frm, status) {
frappe.confirm(__('Set Project and all Tasks to status {0}?', [status.bold()]), () => {
frappe.xcall('erpnext.projects.doctype.project.project.set_project_status',
{project: frm.doc.name, status: status}).then(() => {
frm.reload_doc();
});
set_status: function (frm, status) {
frappe.confirm(__("Set Project and all Tasks to status {0}?", [status.bold()]), () => {
frappe
.xcall("erpnext.projects.doctype.project.project.set_project_status", {
project: frm.doc.name,
status: status,
})
.then(() => {
frm.reload_doc();
});
});
},
});
function open_form(frm, doctype, child_doctype, parentfield) {
@@ -184,5 +209,4 @@ function open_form(frm, doctype, child_doctype, parentfield) {
frappe.ui.form.make_quick_entry(doctype, null, null, new_doc);
});
}

View File

@@ -1,11 +1,11 @@
frappe.listview_settings['Project'] = {
frappe.listview_settings["Project"] = {
add_fields: ["status", "priority", "is_active", "percent_complete", "expected_end_date", "project_name"],
filters:[["status","=", "Open"]],
get_indicator: function(doc) {
if(doc.status=="Open" && doc.percent_complete) {
filters: [["status", "=", "Open"]],
get_indicator: function (doc) {
if (doc.status == "Open" && doc.percent_complete) {
return [__("{0}%", [cint(doc.percent_complete)]), "orange", "percent_complete,>,0|status,=,Open"];
} else {
return [__(doc.status), frappe.utils.guess_colour(doc.status), "status,=," + doc.status];
}
}
},
};

View File

@@ -1,53 +1,63 @@
QUnit.test("test project", function(assert) {
QUnit.test("test project", function (assert) {
assert.expect(6);
let done = assert.async();
var task_title = ["Documentation","Implementation","Testing"];
var task_title = ["Documentation", "Implementation", "Testing"];
// To create a timesheet with different tasks and costs
let timesheet = (title,start_time,end_time,bill_rate,cost_rate) => {
let timesheet = (title, start_time, end_time, bill_rate, cost_rate) => {
return frappe.run_serially([
() => frappe.db.get_value('Task', {'subject': title}, 'name'),
() => frappe.db.get_value("Task", { subject: title }, "name"),
(task) => {
// Creating timesheet for a project
return frappe.tests.make('Timesheet', [
{time_logs:[
[
{activity_type: 'Communication'},
{from_time: start_time},
{to_time: end_time},
{hours: 2},
{project: 'Test App'},
{task: task.name},
{billable: '1'},
{billing_rate: bill_rate},
{costing_rate: cost_rate}
]
]}
return frappe.tests.make("Timesheet", [
{
time_logs: [
[
{ activity_type: "Communication" },
{ from_time: start_time },
{ to_time: end_time },
{ hours: 2 },
{ project: "Test App" },
{ task: task.name },
{ billable: "1" },
{ billing_rate: bill_rate },
{ costing_rate: cost_rate },
],
],
},
]);
},
// To check if a correct billable and costing amount is calculated for every task
() => {
if(title=== 'Documentation')
{
assert.ok(cur_frm.get_field('total_billable_amount').get_value()==20,
'Billable amount for Documentation task is correctly calculated');
assert.ok(cur_frm.get_field('total_costing_amount').get_value()==16,
'Costing amount for Documentation task is correctly calculated');
if (title === "Documentation") {
assert.ok(
cur_frm.get_field("total_billable_amount").get_value() == 20,
"Billable amount for Documentation task is correctly calculated"
);
assert.ok(
cur_frm.get_field("total_costing_amount").get_value() == 16,
"Costing amount for Documentation task is correctly calculated"
);
}
if(title=== 'Implementation')
{
assert.ok(cur_frm.get_field('total_billable_amount').get_value()==40,
'Billable amount for Implementation task is correctly calculated');
assert.ok(cur_frm.get_field('total_costing_amount').get_value()==32,
'Costing amount for Implementation task is correctly calculated');
if (title === "Implementation") {
assert.ok(
cur_frm.get_field("total_billable_amount").get_value() == 40,
"Billable amount for Implementation task is correctly calculated"
);
assert.ok(
cur_frm.get_field("total_costing_amount").get_value() == 32,
"Costing amount for Implementation task is correctly calculated"
);
}
if(title=== 'Testing')
{
assert.ok(cur_frm.get_field('total_billable_amount').get_value()==60,
'Billable amount for Testing task correctly calculated');
assert.ok(cur_frm.get_field('total_costing_amount').get_value()==50,
'Costing amount for Testing task is correctly calculated');
if (title === "Testing") {
assert.ok(
cur_frm.get_field("total_billable_amount").get_value() == 60,
"Billable amount for Testing task correctly calculated"
);
assert.ok(
cur_frm.get_field("total_costing_amount").get_value() == 50,
"Costing amount for Testing task is correctly calculated"
);
}
},
]);
@@ -55,37 +65,39 @@ QUnit.test("test project", function(assert) {
frappe.run_serially([
() => {
// Creating project with task
return frappe.tests.make('Project', [
{ project_name: 'Test App'},
{ expected_start_date: '2017-07-22'},
{ expected_end_date: '2017-09-22'},
{ estimated_costing: '10,000.00'},
{ tasks:[
[
{title: 'Documentation'},
{start_date: '2017-07-24'},
{end_date: '2017-07-31'},
{description: 'To make a proper documentation defining requirements etc'}
return frappe.tests.make("Project", [
{ project_name: "Test App" },
{ expected_start_date: "2017-07-22" },
{ expected_end_date: "2017-09-22" },
{ estimated_costing: "10,000.00" },
{
tasks: [
[
{ title: "Documentation" },
{ start_date: "2017-07-24" },
{ end_date: "2017-07-31" },
{ description: "To make a proper documentation defining requirements etc" },
],
[
{ title: "Implementation" },
{ start_date: "2017-08-01" },
{ end_date: "2017-08-01" },
{ description: "Writing algorithms and to code the functionalities" },
],
[
{ title: "Testing" },
{ start_date: "2017-08-01" },
{ end_date: "2017-08-15" },
{ description: "To make the test cases and test the functionalities" },
],
],
[
{title: 'Implementation'},
{start_date: '2017-08-01'},
{end_date: '2017-08-01'},
{description: 'Writing algorithms and to code the functionalities'}
],
[
{title: 'Testing'},
{start_date: '2017-08-01'},
{end_date: '2017-08-15'},
{description: 'To make the test cases and test the functionalities'}
]
]}
},
]);
},
// Creating Timesheet with different tasks
() => timesheet(task_title[0],'2017-07-24 13:00:00','2017-07-24 13:00:00',10,8),
() => timesheet(task_title[1],'2017-07-25 13:00:00','2017-07-25 15:00:00',20,16),
() => timesheet(task_title[2],'2017-07-26 13:00:00','2017-07-26 15:00:00',30,25),
() => done()
() => timesheet(task_title[0], "2017-07-24 13:00:00", "2017-07-24 13:00:00", 10, 8),
() => timesheet(task_title[1], "2017-07-25 13:00:00", "2017-07-25 15:00:00", 20, 16),
() => timesheet(task_title[2], "2017-07-26 13:00:00", "2017-07-26 15:00:00", 30, 25),
() => done(),
]);
});

View File

@@ -1,7 +1,7 @@
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Project Template', {
frappe.ui.form.on("Project Template", {
// refresh: function(frm) {
// }
@@ -9,19 +9,19 @@ frappe.ui.form.on('Project Template', {
frm.set_query("task", "tasks", function () {
return {
filters: {
"is_template": 1
}
is_template: 1,
},
};
});
}
},
});
frappe.ui.form.on('Project Template Task', {
frappe.ui.form.on("Project Template Task", {
task: function (frm, cdt, cdn) {
var row = locals[cdt][cdn];
frappe.db.get_value("Task", row.task, "subject", (value) => {
row.subject = value.subject;
refresh_field("tasks");
});
}
},
});

View File

@@ -1,6 +1,4 @@
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Project Type', {
});
frappe.ui.form.on("Project Type", {});

View File

@@ -1,10 +1,8 @@
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Project Update', {
refresh: function() {
},
frappe.ui.form.on("Project Update", {
refresh: function () {},
onload: function (frm) {
frm.set_value("naming_series", "UPDATE-.project.-.YY.MM.DD.-.####");
@@ -13,5 +11,5 @@ frappe.ui.form.on('Project Update', {
validate: function (frm) {
frm.set_value("time", frappe.datetime.now_time());
frm.set_value("date", frappe.datetime.nowdate());
}
},
});

View File

@@ -1,8 +1,6 @@
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Projects Settings', {
refresh: function(frm) {
}
frappe.ui.form.on("Projects Settings", {
refresh: function (frm) {},
});

View File

@@ -6,33 +6,34 @@ frappe.provide("erpnext.projects");
frappe.ui.form.on("Task", {
setup: function (frm) {
frm.make_methods = {
'Timesheet': () => frappe.model.open_mapped_doc({
method: 'erpnext.projects.doctype.task.task.make_timesheet',
frm: frm
})
}
Timesheet: () =>
frappe.model.open_mapped_doc({
method: "erpnext.projects.doctype.task.task.make_timesheet",
frm: frm,
}),
};
},
onload: function (frm) {
frm.set_query("task", "depends_on", function () {
let filters = {
name: ["!=", frm.doc.name]
name: ["!=", frm.doc.name],
};
if (frm.doc.project) filters["project"] = frm.doc.project;
return {
filters: filters
filters: filters,
};
})
});
frm.set_query("parent_task", function () {
let filters = {
"is_group": 1,
"name": ["!=", frm.doc.name]
is_group: 1,
name: ["!=", frm.doc.name],
};
if (frm.doc.project) filters["project"] = frm.doc.project;
return {
filters: filters
}
filters: filters,
};
});
},
@@ -40,22 +41,22 @@ frappe.ui.form.on("Task", {
frappe.call({
method: "erpnext.projects.doctype.task.task.check_if_child_exists",
args: {
name: frm.doc.name
name: frm.doc.name,
},
callback: function (r) {
if (r.message.length > 0) {
let message = __('Cannot convert Task to non-group because the following child Tasks exist: {0}.',
let message = __(
"Cannot convert Task to non-group because the following child Tasks exist: {0}.",
[r.message.join(", ")]
);
frappe.msgprint(message);
frm.reload_doc();
}
}
})
},
});
},
validate: function (frm) {
frm.doc.project && frappe.model.remove_from_locals("Project",
frm.doc.project);
}
frm.doc.project && frappe.model.remove_from_locals("Project", frm.doc.project);
},
});

View File

@@ -3,21 +3,21 @@
frappe.views.calendar["Task"] = {
field_map: {
"start": "exp_start_date",
"end": "exp_end_date",
"id": "name",
"title": "subject",
"allDay": "allDay",
"progress": "progress"
start: "exp_start_date",
end: "exp_end_date",
id: "name",
title: "subject",
allDay: "allDay",
progress: "progress",
},
gantt: true,
filters: [
{
"fieldtype": "Link",
"fieldname": "project",
"options": "Project",
"label": __("Project")
}
fieldtype: "Link",
fieldname: "project",
options: "Project",
label: __("Project"),
},
],
get_events_method: "frappe.desk.calendar.get_events"
}
get_events_method: "frappe.desk.calendar.get_events",
};

View File

@@ -1,28 +1,36 @@
frappe.listview_settings['Task'] = {
add_fields: ["project", "status", "priority", "exp_start_date",
"exp_end_date", "subject", "progress", "depends_on_tasks"],
frappe.listview_settings["Task"] = {
add_fields: [
"project",
"status",
"priority",
"exp_start_date",
"exp_end_date",
"subject",
"progress",
"depends_on_tasks",
],
filters: [["status", "=", "Open"]],
onload: function(listview) {
onload: function (listview) {
var method = "erpnext.projects.doctype.task.task.set_multiple_status";
listview.page.add_menu_item(__("Set as Open"), function() {
listview.call_for_selected_items(method, {"status": "Open"});
listview.page.add_menu_item(__("Set as Open"), function () {
listview.call_for_selected_items(method, { status: "Open" });
});
listview.page.add_menu_item(__("Set as Completed"), function() {
listview.call_for_selected_items(method, {"status": "Completed"});
listview.page.add_menu_item(__("Set as Completed"), function () {
listview.call_for_selected_items(method, { status: "Completed" });
});
},
get_indicator: function(doc) {
get_indicator: function (doc) {
var colors = {
"Open": "orange",
"Overdue": "red",
Open: "orange",
Overdue: "red",
"Pending Review": "orange",
"Working": "orange",
"Completed": "green",
"Cancelled": "dark grey",
"Template": "blue"
}
Working: "orange",
Completed: "green",
Cancelled: "dark grey",
Template: "blue",
};
return [__(doc.status), colors[doc.status], "status,=," + doc.status];
},
gantt_custom_popup_html: function (ganttobj, task) {

View File

@@ -1,84 +1,88 @@
frappe.provide("frappe.treeview_settings");
frappe.treeview_settings['Task'] = {
frappe.treeview_settings["Task"] = {
get_tree_nodes: "erpnext.projects.doctype.task.task.get_children",
add_tree_node: "erpnext.projects.doctype.task.task.add_node",
filters: [
{
fieldname: "project",
fieldtype:"Link",
fieldtype: "Link",
options: "Project",
label: __("Project"),
},
{
fieldname: "task",
fieldtype:"Link",
fieldtype: "Link",
options: "Task",
label: __("Task"),
get_query: function() {
var me = frappe.treeview_settings['Task'];
get_query: function () {
var me = frappe.treeview_settings["Task"];
var project = me.page.fields_dict.project.get_value();
var args = [["Task", 'is_group', '=', 1]];
if(project){
args.push(["Task", 'project', "=", project]);
var args = [["Task", "is_group", "=", 1]];
if (project) {
args.push(["Task", "project", "=", project]);
}
return {
filters: args
filters: args,
};
}
}
},
},
],
breadcrumb: "Projects",
get_tree_root: false,
root_label: "All Tasks",
ignore_fields: ["parent_task"],
onload: function(me) {
frappe.treeview_settings['Task'].page = {};
$.extend(frappe.treeview_settings['Task'].page, me.page);
onload: function (me) {
frappe.treeview_settings["Task"].page = {};
$.extend(frappe.treeview_settings["Task"].page, me.page);
me.make_tree();
},
toolbar: [
{
label:__("Add Multiple"),
condition: function(node) {
label: __("Add Multiple"),
condition: function (node) {
return node.expandable;
},
click: function(node) {
click: function (node) {
this.data = [];
const dialog = new frappe.ui.Dialog({
title: __("Add Multiple Tasks"),
fields: [
{
fieldname: "multiple_tasks", fieldtype: "Table",
in_place_edit: true, data: this.data,
fieldname: "multiple_tasks",
fieldtype: "Table",
in_place_edit: true,
data: this.data,
get_data: () => {
return this.data;
},
fields: [{
fieldtype:'Data',
fieldname:"subject",
in_list_view: 1,
reqd: 1,
label: __("Subject")
}]
fields: [
{
fieldtype: "Data",
fieldname: "subject",
in_list_view: 1,
reqd: 1,
label: __("Subject"),
},
],
},
],
primary_action: function() {
primary_action: function () {
dialog.hide();
return frappe.call({
method: "erpnext.projects.doctype.task.task.add_multiple_tasks",
args: {
data: dialog.get_values()["multiple_tasks"],
parent: node.data.value
parent: node.data.value,
},
callback: function() { }
callback: function () {},
});
},
primary_action_label: __('Create')
primary_action_label: __("Create"),
});
dialog.show();
}
}
},
},
],
extend_toolbar: true
extend_toolbar: true,
};

View File

@@ -1,8 +1,7 @@
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on('Task Type', {
frappe.ui.form.on("Task Type", {
// refresh: function(frm) {
// }
});

View File

@@ -2,39 +2,39 @@
// License: GNU General Public License v3. See license.txt
frappe.ui.form.on("Timesheet", {
setup: function(frm) {
setup: function (frm) {
frappe.require("/assets/erpnext/js/projects/timer.js");
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice'];
frm.ignore_doctypes_on_cancel_all = ["Sales Invoice"];
frm.fields_dict.employee.get_query = function() {
frm.fields_dict.employee.get_query = function () {
return {
filters:{
'status': 'Active'
}
filters: {
status: "Active",
},
};
};
frm.fields_dict['time_logs'].grid.get_field('task').get_query = function(frm, cdt, cdn) {
frm.fields_dict["time_logs"].grid.get_field("task").get_query = function (frm, cdt, cdn) {
var child = locals[cdt][cdn];
return{
return {
filters: {
'project': child.project,
'status': ["!=", "Cancelled"]
}
project: child.project,
status: ["!=", "Cancelled"],
},
};
};
frm.fields_dict['time_logs'].grid.get_field('project').get_query = function() {
return{
frm.fields_dict["time_logs"].grid.get_field("project").get_query = function () {
return {
filters: {
'company': frm.doc.company
}
company: frm.doc.company,
},
};
};
},
onload: function(frm) {
onload: function (frm) {
if (frm.doc.__islocal && frm.doc.time_logs) {
calculate_time_and_amount(frm);
}
@@ -44,33 +44,32 @@ frappe.ui.form.on("Timesheet", {
}
},
refresh: function(frm) {
refresh: function (frm) {
if (frm.doc.docstatus == 1) {
if (
(frm.doc.per_billed < 100)
&& (frm.doc.total_billable_hours)
&& (frm.doc.total_billable_hours > frm.doc.total_billed_hours)
frm.doc.per_billed < 100 &&
frm.doc.total_billable_hours &&
frm.doc.total_billable_hours > frm.doc.total_billed_hours
) {
frm.add_custom_button(__("Create Sales Invoice"), function() {
frm.add_custom_button(__("Create Sales Invoice"), function () {
frm.trigger("make_invoice");
});
}
}
if (frm.doc.docstatus < 1) {
let button = 'Start Timer';
$.each(frm.doc.time_logs || [], function(i, row) {
if ((row.from_time <= frappe.datetime.now_datetime()) && !row.completed) {
button = 'Resume Timer';
let button = "Start Timer";
$.each(frm.doc.time_logs || [], function (i, row) {
if (row.from_time <= frappe.datetime.now_datetime() && !row.completed) {
button = "Resume Timer";
}
});
frm.add_custom_button(__(button), function() {
frm.add_custom_button(__(button), function () {
var flag = true;
$.each(frm.doc.time_logs || [], function(i, row) {
$.each(frm.doc.time_logs || [], function (i, row) {
// Fetch the row for which from_time is not present
if (flag && row.activity_type && !row.from_time){
if (flag && row.activity_type && !row.from_time) {
erpnext.timesheet.timer(frm, row);
row.from_time = frappe.datetime.now_datetime();
frm.refresh_fields("time_logs");
@@ -79,7 +78,10 @@ frappe.ui.form.on("Timesheet", {
}
// Fetch the row for timer where activity is not completed and from_time is before now_time
if (flag && row.from_time <= frappe.datetime.now_datetime() && !row.completed) {
let timestamp = moment(frappe.datetime.now_datetime()).diff(moment(row.from_time),"seconds");
let timestamp = moment(frappe.datetime.now_datetime()).diff(
moment(row.from_time),
"seconds"
);
erpnext.timesheet.timer(frm, row, timestamp);
flag = false;
}
@@ -90,152 +92,177 @@ frappe.ui.form.on("Timesheet", {
}
}).addClass("btn-primary");
}
if(frm.doc.per_billed > 0) {
if (frm.doc.per_billed > 0) {
frm.fields_dict["time_logs"].grid.toggle_enable("billing_hours", false);
frm.fields_dict["time_logs"].grid.toggle_enable("is_billable", false);
}
let filters = {
"status": "Open"
status: "Open",
};
if (frm.doc.customer) {
filters["customer"] = frm.doc.customer;
}
frm.set_query('parent_project', function(doc) {
frm.set_query("parent_project", function (doc) {
return {
filters: filters
filters: filters,
};
});
frm.trigger('setup_filters');
frm.trigger('set_dynamic_field_label');
frm.trigger('set_route_options_for_new_task');
frm.trigger("setup_filters");
frm.trigger("set_dynamic_field_label");
frm.trigger("set_route_options_for_new_task");
},
customer: function(frm) {
frm.set_query('project', 'time_logs', function(doc) {
customer: function (frm) {
frm.set_query("project", "time_logs", function (doc) {
return {
filters: {
"customer": doc.customer
}
customer: doc.customer,
},
};
});
frm.refresh();
},
currency: function(frm) {
let base_currency = frappe.defaults.get_global_default('currency');
if (frm.doc.currency && (base_currency != frm.doc.currency)) {
currency: function (frm) {
let base_currency = frappe.defaults.get_global_default("currency");
if (frm.doc.currency && base_currency != frm.doc.currency) {
frappe.call({
method: "erpnext.setup.utils.get_exchange_rate",
args: {
from_currency: frm.doc.currency,
to_currency: base_currency
to_currency: base_currency,
},
callback: function(r) {
callback: function (r) {
if (r.message) {
frm.set_value('exchange_rate', flt(r.message));
frm.set_df_property("exchange_rate", "description", "1 " + frm.doc.currency + " = [?] " + base_currency);
frm.set_value("exchange_rate", flt(r.message));
frm.set_df_property(
"exchange_rate",
"description",
"1 " + frm.doc.currency + " = [?] " + base_currency
);
}
}
},
});
}
frm.trigger('set_dynamic_field_label');
frm.trigger("set_dynamic_field_label");
},
exchange_rate: function(frm) {
$.each(frm.doc.time_logs, function(i, d) {
exchange_rate: function (frm) {
$.each(frm.doc.time_logs, function (i, d) {
calculate_billing_costing_amount(frm, d.doctype, d.name);
});
calculate_time_and_amount(frm);
},
set_dynamic_field_label: function(frm) {
let base_currency = frappe.defaults.get_global_default('currency');
frm.set_currency_labels(["base_total_costing_amount", "base_total_billable_amount", "base_total_billed_amount"], base_currency);
frm.set_currency_labels(["total_costing_amount", "total_billable_amount", "total_billed_amount"], frm.doc.currency);
set_dynamic_field_label: function (frm) {
let base_currency = frappe.defaults.get_global_default("currency");
frm.set_currency_labels(
["base_total_costing_amount", "base_total_billable_amount", "base_total_billed_amount"],
base_currency
);
frm.set_currency_labels(
["total_costing_amount", "total_billable_amount", "total_billed_amount"],
frm.doc.currency
);
frm.toggle_display(["base_total_costing_amount", "base_total_billable_amount", "base_total_billed_amount"],
frm.doc.currency != base_currency);
frm.toggle_display(
["base_total_costing_amount", "base_total_billable_amount", "base_total_billed_amount"],
frm.doc.currency != base_currency
);
if (frm.doc.time_logs.length > 0) {
frm.set_currency_labels(["base_billing_rate", "base_billing_amount", "base_costing_rate", "base_costing_amount"], base_currency, "time_logs");
frm.set_currency_labels(["billing_rate", "billing_amount", "costing_rate", "costing_amount"], frm.doc.currency, "time_logs");
frm.set_currency_labels(
["base_billing_rate", "base_billing_amount", "base_costing_rate", "base_costing_amount"],
base_currency,
"time_logs"
);
frm.set_currency_labels(
["billing_rate", "billing_amount", "costing_rate", "costing_amount"],
frm.doc.currency,
"time_logs"
);
let time_logs_grid = frm.fields_dict.time_logs.grid;
$.each(["base_billing_rate", "base_billing_amount", "base_costing_rate", "base_costing_amount"], function(i, d) {
if (frappe.meta.get_docfield(time_logs_grid.doctype, d))
time_logs_grid.set_column_disp(d, frm.doc.currency != base_currency);
});
$.each(
["base_billing_rate", "base_billing_amount", "base_costing_rate", "base_costing_amount"],
function (i, d) {
if (frappe.meta.get_docfield(time_logs_grid.doctype, d))
time_logs_grid.set_column_disp(d, frm.doc.currency != base_currency);
}
);
}
frm.refresh_fields();
},
set_route_options_for_new_task: (frm) => {
let task_field = frm.get_docfield('time_logs', 'task');
let task_field = frm.get_docfield("time_logs", "task");
if (task_field) {
task_field.get_route_options_for_new_doc = (row) => ({'project': row.doc.project});
task_field.get_route_options_for_new_doc = (row) => ({ project: row.doc.project });
}
},
make_invoice: function(frm) {
let fields = [{
"fieldtype": "Link",
"label": __("Item Code"),
"fieldname": "item_code",
"options": "Item"
}];
make_invoice: function (frm) {
let fields = [
{
fieldtype: "Link",
label: __("Item Code"),
fieldname: "item_code",
options: "Item",
},
];
if (!frm.doc.customer) {
fields.push({
"fieldtype": "Link",
"label": __("Customer"),
"fieldname": "customer",
"options": "Customer",
"default": frm.doc.customer
fieldtype: "Link",
label: __("Customer"),
fieldname: "customer",
options: "Customer",
default: frm.doc.customer,
});
}
let dialog = new frappe.ui.Dialog({
title: __("Create Sales Invoice"),
fields: fields
fields: fields,
});
dialog.set_primary_action(__('Create Sales Invoice'), () => {
dialog.set_primary_action(__("Create Sales Invoice"), () => {
var args = dialog.get_values();
if(!args) return;
if (!args) return;
dialog.hide();
return frappe.call({
type: "GET",
method: "erpnext.projects.doctype.timesheet.timesheet.make_sales_invoice",
args: {
"source_name": frm.doc.name,
"item_code": args.item_code,
"customer": frm.doc.customer || args.customer,
"currency": frm.doc.currency
source_name: frm.doc.name,
item_code: args.item_code,
customer: frm.doc.customer || args.customer,
currency: frm.doc.currency,
},
freeze: true,
callback: function(r) {
if(!r.exc) {
callback: function (r) {
if (!r.exc) {
frappe.model.sync(r.message);
frappe.set_route("Form", r.message.doctype, r.message.name);
}
}
},
});
});
dialog.show();
},
parent_project: function(frm) {
parent_project: function (frm) {
set_project_in_timelog(frm);
}
},
});
frappe.ui.form.on("Timesheet Detail", {
time_logs_remove: function(frm) {
time_logs_remove: function (frm) {
calculate_time_and_amount(frm);
},
@@ -248,47 +275,47 @@ frappe.ui.form.on("Timesheet Detail", {
}
},
from_time: function(frm, cdt, cdn) {
from_time: function (frm, cdt, cdn) {
calculate_end_time(frm, cdt, cdn);
},
to_time: function(frm, cdt, cdn) {
to_time: function (frm, cdt, cdn) {
var child = locals[cdt][cdn];
if(frm._setting_hours) return;
if (frm._setting_hours) return;
var hours = moment(child.to_time).diff(moment(child.from_time), "seconds") / 3600;
frappe.model.set_value(cdt, cdn, "hours", hours);
},
time_logs_add: function(frm, cdt, cdn) {
if(frm.doc.parent_project) {
frappe.model.set_value(cdt, cdn, 'project', frm.doc.parent_project);
time_logs_add: function (frm, cdt, cdn) {
if (frm.doc.parent_project) {
frappe.model.set_value(cdt, cdn, "project", frm.doc.parent_project);
}
},
hours: function(frm, cdt, cdn) {
hours: function (frm, cdt, cdn) {
calculate_end_time(frm, cdt, cdn);
calculate_billing_costing_amount(frm, cdt, cdn);
calculate_time_and_amount(frm);
},
billing_hours: function(frm, cdt, cdn) {
billing_hours: function (frm, cdt, cdn) {
calculate_billing_costing_amount(frm, cdt, cdn);
calculate_time_and_amount(frm);
},
billing_rate: function(frm, cdt, cdn) {
billing_rate: function (frm, cdt, cdn) {
calculate_billing_costing_amount(frm, cdt, cdn);
calculate_time_and_amount(frm);
},
costing_rate: function(frm, cdt, cdn) {
costing_rate: function (frm, cdt, cdn) {
calculate_billing_costing_amount(frm, cdt, cdn);
calculate_time_and_amount(frm);
},
is_billable: function(frm, cdt, cdn) {
is_billable: function (frm, cdt, cdn) {
update_billing_hours(frm, cdt, cdn);
update_time_rates(frm, cdt, cdn);
calculate_billing_costing_amount(frm, cdt, cdn);
@@ -303,7 +330,7 @@ frappe.ui.form.on("Timesheet Detail", {
args: {
employee: frm.doc.employee,
activity_type: frm.selected_doc.activity_type,
currency: frm.doc.currency
currency: frm.doc.currency,
},
callback: function (r) {
if (r.message) {
@@ -311,72 +338,71 @@ frappe.ui.form.on("Timesheet Detail", {
frappe.model.set_value(cdt, cdn, "costing_rate", r.message["costing_rate"]);
calculate_billing_costing_amount(frm, cdt, cdn);
}
}
},
});
}
},
});
var calculate_end_time = function(frm, cdt, cdn) {
var calculate_end_time = function (frm, cdt, cdn) {
let child = locals[cdt][cdn];
if(!child.from_time) {
if (!child.from_time) {
// if from_time value is not available then set the current datetime
frappe.model.set_value(cdt, cdn, "from_time", frappe.datetime.get_datetime_as_string());
}
let d = moment(child.from_time);
if(child.hours) {
if (child.hours) {
d.add(child.hours, "hours");
frm._setting_hours = true;
frappe.model.set_value(cdt, cdn, "to_time",
d.format(frappe.defaultDatetimeFormat)).then(() => {
frappe.model.set_value(cdt, cdn, "to_time", d.format(frappe.defaultDatetimeFormat)).then(() => {
frm._setting_hours = false;
});
}
};
var update_billing_hours = function(frm, cdt, cdn) {
var update_billing_hours = function (frm, cdt, cdn) {
let child = frappe.get_doc(cdt, cdn);
if (!child.is_billable) {
frappe.model.set_value(cdt, cdn, 'billing_hours', 0.0);
frappe.model.set_value(cdt, cdn, "billing_hours", 0.0);
} else {
// bill all hours by default
frappe.model.set_value(cdt, cdn, "billing_hours", child.hours);
}
};
var update_time_rates = function(frm, cdt, cdn) {
var update_time_rates = function (frm, cdt, cdn) {
let child = frappe.get_doc(cdt, cdn);
if (!child.is_billable) {
frappe.model.set_value(cdt, cdn, 'billing_rate', 0.0);
frappe.model.set_value(cdt, cdn, "billing_rate", 0.0);
}
};
var calculate_billing_costing_amount = function(frm, cdt, cdn) {
var calculate_billing_costing_amount = function (frm, cdt, cdn) {
let row = frappe.get_doc(cdt, cdn);
let billing_amount = 0.0;
let base_billing_amount = 0.0;
let exchange_rate = flt(frm.doc.exchange_rate);
frappe.model.set_value(cdt, cdn, 'base_billing_rate', flt(row.billing_rate) * exchange_rate);
frappe.model.set_value(cdt, cdn, 'base_costing_rate', flt(row.costing_rate) * exchange_rate);
frappe.model.set_value(cdt, cdn, "base_billing_rate", flt(row.billing_rate) * exchange_rate);
frappe.model.set_value(cdt, cdn, "base_costing_rate", flt(row.costing_rate) * exchange_rate);
if (row.billing_hours && row.is_billable) {
base_billing_amount = flt(row.billing_hours) * flt(row.base_billing_rate);
billing_amount = flt(row.billing_hours) * flt(row.billing_rate);
}
frappe.model.set_value(cdt, cdn, 'base_billing_amount', base_billing_amount);
frappe.model.set_value(cdt, cdn, 'base_costing_amount', flt(row.base_costing_rate) * flt(row.hours));
frappe.model.set_value(cdt, cdn, 'billing_amount', billing_amount);
frappe.model.set_value(cdt, cdn, 'costing_amount', flt(row.costing_rate) * flt(row.hours));
frappe.model.set_value(cdt, cdn, "base_billing_amount", base_billing_amount);
frappe.model.set_value(cdt, cdn, "base_costing_amount", flt(row.base_costing_rate) * flt(row.hours));
frappe.model.set_value(cdt, cdn, "billing_amount", billing_amount);
frappe.model.set_value(cdt, cdn, "costing_amount", flt(row.costing_rate) * flt(row.hours));
};
var calculate_time_and_amount = function(frm) {
var calculate_time_and_amount = function (frm) {
let tl = frm.doc.time_logs || [];
let total_working_hr = 0;
let total_billing_hr = 0;
let total_billable_amount = 0;
let total_costing_amount = 0;
for(var i=0; i<tl.length; i++) {
for (var i = 0; i < tl.length; i++) {
if (tl[i].hours) {
total_working_hr += tl[i].hours;
total_billable_amount += tl[i].billing_amount;
@@ -395,10 +421,10 @@ var calculate_time_and_amount = function(frm) {
};
// set employee (and company) to the one that's currently logged in
const set_employee_and_company = function(frm) {
const set_employee_and_company = function (frm) {
const options = { user_id: frappe.session.user };
const fields = ['name', 'company'];
frappe.db.get_value('Employee', options, fields).then(({ message }) => {
const fields = ["name", "company"];
frappe.db.get_value("Employee", options, fields).then(({ message }) => {
if (message) {
// there is an employee with the currently logged in user_id
frm.set_value("employee", message.name);
@@ -408,8 +434,8 @@ const set_employee_and_company = function(frm) {
};
function set_project_in_timelog(frm) {
if(frm.doc.parent_project) {
$.each(frm.doc.time_logs || [], function(i, item) {
if (frm.doc.parent_project) {
$.each(frm.doc.time_logs || [], function (i, item) {
frappe.model.set_value(item.doctype, item.name, "project", frm.doc.parent_project);
});
}

View File

@@ -1,32 +1,32 @@
frappe.views.calendar["Timesheet"] = {
field_map: {
"start": "start_date",
"end": "end_date",
"name": "parent",
"id": "name",
"allDay": "allDay",
"child_name": "name",
"title": "title"
start: "start_date",
end: "end_date",
name: "parent",
id: "name",
allDay: "allDay",
child_name: "name",
title: "title",
},
style_map: {
"0": "info",
"1": "standard",
"2": "danger"
0: "info",
1: "standard",
2: "danger",
},
gantt: true,
filters: [
{
"fieldtype": "Link",
"fieldname": "project",
"options": "Project",
"label": __("Project")
fieldtype: "Link",
fieldname: "project",
options: "Project",
label: __("Project"),
},
{
"fieldtype": "Link",
"fieldname": "employee",
"options": "Employee",
"label": __("Employee")
}
fieldtype: "Link",
fieldname: "employee",
options: "Employee",
label: __("Employee"),
},
],
get_events_method: "erpnext.projects.doctype.timesheet.timesheet.get_events"
}
get_events_method: "erpnext.projects.doctype.timesheet.timesheet.get_events",
};

View File

@@ -1,16 +1,16 @@
frappe.listview_settings['Timesheet'] = {
frappe.listview_settings["Timesheet"] = {
add_fields: ["status", "total_hours", "start_date", "end_date"],
get_indicator: function(doc) {
if (doc.status== "Billed") {
return [__("Billed"), "green", "status,=," + "Billed"]
get_indicator: function (doc) {
if (doc.status == "Billed") {
return [__("Billed"), "green", "status,=," + "Billed"];
}
if (doc.status== "Payslip") {
return [__("Payslip"), "green", "status,=," + "Payslip"]
if (doc.status == "Payslip") {
return [__("Payslip"), "green", "status,=," + "Payslip"];
}
if (doc.status== "Completed") {
return [__("Completed"), "green", "status,=," + "Completed"]
if (doc.status == "Completed") {
return [__("Completed"), "green", "status,=," + "Completed"];
}
}
},
};

View File

@@ -2,18 +2,18 @@
// For license information, please see license.txt
frappe.query_reports["Daily Timesheet Summary"] = {
"filters": [
filters: [
{
"fieldname":"from_date",
"label": __("From Date"),
"fieldtype": "Date",
"default": frappe.datetime.get_today()
fieldname: "from_date",
label: __("From Date"),
fieldtype: "Date",
default: frappe.datetime.get_today(),
},
{
"fieldname":"to_date",
"label": __("To Date"),
"fieldtype": "Date",
"default": frappe.datetime.get_today()
fieldname: "to_date",
label: __("To Date"),
fieldtype: "Date",
default: frappe.datetime.get_today(),
},
]
}
],
};

View File

@@ -1,33 +1,32 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.query_reports["Delayed Tasks Summary"] = {
"filters": [
filters: [
{
"fieldname": "from_date",
"label": __("From Date"),
"fieldtype": "Date"
fieldname: "from_date",
label: __("From Date"),
fieldtype: "Date",
},
{
"fieldname": "to_date",
"label": __("To Date"),
"fieldtype": "Date"
fieldname: "to_date",
label: __("To Date"),
fieldtype: "Date",
},
{
"fieldname": "priority",
"label": __("Priority"),
"fieldtype": "Select",
"options": ["", "Low", "Medium", "High", "Urgent"]
fieldname: "priority",
label: __("Priority"),
fieldtype: "Select",
options: ["", "Low", "Medium", "High", "Urgent"],
},
{
"fieldname": "status",
"label": __("Status"),
"fieldtype": "Select",
"options": ["", "Open", "Working","Pending Review","Overdue","Completed"]
fieldname: "status",
label: __("Status"),
fieldtype: "Select",
options: ["", "Open", "Working", "Pending Review", "Overdue", "Completed"],
},
],
"formatter": function(value, row, column, data, default_formatter) {
formatter: function (value, row, column, data, default_formatter) {
value = default_formatter(value, row, column, data);
if (column.id == "delay") {
if (data["delay"] > 0) {
@@ -36,6 +35,6 @@ frappe.query_reports["Delayed Tasks Summary"] = {
value = `<p style="color: green; font-weight: bold">${value}</p>`;
}
}
return value
}
return value;
},
};

View File

@@ -1,34 +1,33 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.query_reports["Employee Billing Summary"] = {
"filters": [
filters: [
{
fieldname: "employee",
label: __("Employee"),
fieldtype: "Link",
options: "Employee",
reqd: 1
reqd: 1,
},
{
fieldname:"from_date",
fieldname: "from_date",
label: __("From Date"),
fieldtype: "Date",
default: frappe.datetime.add_months(frappe.datetime.month_start(), -1),
reqd: 1
reqd: 1,
},
{
fieldname:"to_date",
fieldname: "to_date",
label: __("To Date"),
fieldtype: "Date",
default: frappe.datetime.add_days(frappe.datetime.month_start(), -1),
reqd: 1
reqd: 1,
},
{
fieldname:"include_draft_timesheets",
fieldname: "include_draft_timesheets",
label: __("Include Timesheets in Draft Status"),
fieldtype: "Check",
},
]
}
],
};

View File

@@ -1,34 +1,33 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.query_reports["Project Billing Summary"] = {
"filters": [
filters: [
{
fieldname: "project",
label: __("Project"),
fieldtype: "Link",
options: "Project",
reqd: 1
reqd: 1,
},
{
fieldname:"from_date",
fieldname: "from_date",
label: __("From Date"),
fieldtype: "Date",
default: frappe.datetime.add_months(frappe.datetime.month_start(), -1),
reqd: 1
reqd: 1,
},
{
fieldname:"to_date",
fieldname: "to_date",
label: __("To Date"),
fieldtype: "Date",
default: frappe.datetime.add_days(frappe.datetime.month_start(),-1),
reqd: 1
default: frappe.datetime.add_days(frappe.datetime.month_start(), -1),
reqd: 1,
},
{
fieldname:"include_draft_timesheets",
fieldname: "include_draft_timesheets",
label: __("Include Timesheets in Draft Status"),
fieldtype: "Check",
},
]
}
],
};

View File

@@ -1,42 +1,41 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.query_reports["Project Summary"] = {
"filters": [
filters: [
{
"fieldname": "company",
"label": __("Company"),
"fieldtype": "Link",
"options": "Company",
"default": frappe.defaults.get_user_default("Company"),
"reqd": 1
fieldname: "company",
label: __("Company"),
fieldtype: "Link",
options: "Company",
default: frappe.defaults.get_user_default("Company"),
reqd: 1,
},
{
"fieldname": "is_active",
"label": __("Is Active"),
"fieldtype": "Select",
"options": "\nYes\nNo",
"default": "Yes",
fieldname: "is_active",
label: __("Is Active"),
fieldtype: "Select",
options: "\nYes\nNo",
default: "Yes",
},
{
"fieldname": "status",
"label": __("Status"),
"fieldtype": "Select",
"options": "\nOpen\nCompleted\nCancelled",
"default": "Open"
fieldname: "status",
label: __("Status"),
fieldtype: "Select",
options: "\nOpen\nCompleted\nCancelled",
default: "Open",
},
{
"fieldname": "project_type",
"label": __("Project Type"),
"fieldtype": "Link",
"options": "Project Type"
fieldname: "project_type",
label: __("Project Type"),
fieldtype: "Link",
options: "Project Type",
},
{
"fieldname": "priority",
"label": __("Priority"),
"fieldtype": "Select",
"options": "\nLow\nMedium\nHigh"
}
]
fieldname: "priority",
label: __("Priority"),
fieldtype: "Select",
options: "\nLow\nMedium\nHigh",
},
],
};

View File

@@ -2,7 +2,5 @@
// For license information, please see license.txt
frappe.query_reports["Project wise Stock Tracking"] = {
"filters": [
]
}
filters: [],
};

View File

@@ -1,3 +1,3 @@
frappe.ready(function() {
frappe.ready(function () {
// bind events here
})
});