mirror of
https://github.com/frappe/erpnext.git
synced 2026-09-01 15:47:06 +00:00
* 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:
@@ -2,24 +2,23 @@
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on("Address", {
|
||||
is_your_company_address: function(frm) {
|
||||
frm.clear_table('links');
|
||||
if(frm.doc.is_your_company_address) {
|
||||
frm.add_child('links', {
|
||||
link_doctype: 'Company',
|
||||
link_name: frappe.defaults.get_user_default('Company')
|
||||
is_your_company_address: function (frm) {
|
||||
frm.clear_table("links");
|
||||
if (frm.doc.is_your_company_address) {
|
||||
frm.add_child("links", {
|
||||
link_doctype: "Company",
|
||||
link_name: frappe.defaults.get_user_default("Company"),
|
||||
});
|
||||
frm.set_query('link_doctype', 'links', () => {
|
||||
frm.set_query("link_doctype", "links", () => {
|
||||
return {
|
||||
filters: {
|
||||
name: 'Company'
|
||||
}
|
||||
name: "Company",
|
||||
},
|
||||
};
|
||||
});
|
||||
frm.refresh_field('links');
|
||||
frm.refresh_field("links");
|
||||
} else {
|
||||
frm.trigger("refresh");
|
||||
}
|
||||
else {
|
||||
frm.trigger('refresh');
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -18,12 +18,11 @@ erpnext.accounts.bank_reconciliation.DataTableManager = class DataTableManager {
|
||||
make_dt() {
|
||||
var me = this;
|
||||
frappe.call({
|
||||
method:
|
||||
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_bank_transactions",
|
||||
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_bank_transactions",
|
||||
args: {
|
||||
bank_account: this.bank_account,
|
||||
from_date: this.bank_statement_from_date,
|
||||
to_date: this.bank_statement_to_date
|
||||
to_date: this.bank_statement_to_date,
|
||||
},
|
||||
callback: function (response) {
|
||||
me.format_data(response.message);
|
||||
@@ -62,18 +61,14 @@ erpnext.accounts.bank_reconciliation.DataTableManager = class DataTableManager {
|
||||
editable: false,
|
||||
width: 100,
|
||||
format: (value) =>
|
||||
"<span style='color:green;'>" +
|
||||
format_currency(value, this.currency) +
|
||||
"</span>",
|
||||
"<span style='color:green;'>" + format_currency(value, this.currency) + "</span>",
|
||||
},
|
||||
{
|
||||
name: __("Withdrawal"),
|
||||
editable: false,
|
||||
width: 100,
|
||||
format: (value) =>
|
||||
"<span style='color:red;'>" +
|
||||
format_currency(value, this.currency) +
|
||||
"</span>",
|
||||
"<span style='color:red;'>" + format_currency(value, this.currency) + "</span>",
|
||||
},
|
||||
{
|
||||
name: __("Unallocated Amount"),
|
||||
@@ -117,13 +112,15 @@ erpnext.accounts.bank_reconciliation.DataTableManager = class DataTableManager {
|
||||
return [
|
||||
row["date"],
|
||||
row["party_type"],
|
||||
frappe.form.formatters.Link(row["party"], {options: row["party_type"]}),
|
||||
frappe.form.formatters.Link(row["party"], { options: row["party_type"] }),
|
||||
row["description"],
|
||||
row["deposit"],
|
||||
row["withdrawal"],
|
||||
row["unallocated_amount"],
|
||||
row["reference_number"],
|
||||
`<button class="btn btn-primary btn-xs center" data-name="${row["name"]}">${__("Actions")}</button>`
|
||||
`<button class="btn btn-primary btn-xs center" data-name="${row["name"]}">${__(
|
||||
"Actions"
|
||||
)}</button>`,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -135,14 +132,8 @@ erpnext.accounts.bank_reconciliation.DataTableManager = class DataTableManager {
|
||||
checkboxColumn: false,
|
||||
inlineFilters: true,
|
||||
};
|
||||
this.datatable = new frappe.DataTable(
|
||||
this.$reconciliation_tool_dt.get(0),
|
||||
datatable_options
|
||||
);
|
||||
$(`.${this.datatable.style.scopeClass} .dt-scrollable`).css(
|
||||
"max-height",
|
||||
"calc(100vh - 400px)"
|
||||
);
|
||||
this.datatable = new frappe.DataTable(this.$reconciliation_tool_dt.get(0), datatable_options);
|
||||
$(`.${this.datatable.style.scopeClass} .dt-scrollable`).css("max-height", "calc(100vh - 400px)");
|
||||
|
||||
if (this.transactions.length > 0) {
|
||||
this.$reconciliation_tool_dt.show();
|
||||
@@ -155,27 +146,18 @@ erpnext.accounts.bank_reconciliation.DataTableManager = class DataTableManager {
|
||||
|
||||
set_listeners() {
|
||||
var me = this;
|
||||
$(`.${this.datatable.style.scopeClass} .dt-scrollable`).on(
|
||||
"click",
|
||||
`.btn`,
|
||||
function () {
|
||||
me.dialog_manager.show_dialog(
|
||||
$(this).attr("data-name"),
|
||||
(bank_transaction) => me.update_dt_cards(bank_transaction)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
$(`.${this.datatable.style.scopeClass} .dt-scrollable`).on("click", `.btn`, function () {
|
||||
me.dialog_manager.show_dialog($(this).attr("data-name"), (bank_transaction) =>
|
||||
me.update_dt_cards(bank_transaction)
|
||||
);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
update_dt_cards(bank_transaction) {
|
||||
const transaction_index = this.transaction_dt_map[
|
||||
bank_transaction.name
|
||||
];
|
||||
const transaction_index = this.transaction_dt_map[bank_transaction.name];
|
||||
if (bank_transaction.unallocated_amount > 0) {
|
||||
this.transactions[transaction_index] = this.format_row(
|
||||
bank_transaction
|
||||
);
|
||||
this.transactions[transaction_index] = this.format_row(bank_transaction);
|
||||
} else {
|
||||
this.transactions.splice(transaction_index, 1);
|
||||
for (const [k, v] of Object.entries(this.transaction_dt_map)) {
|
||||
@@ -191,14 +173,9 @@ erpnext.accounts.bank_reconciliation.DataTableManager = class DataTableManager {
|
||||
|
||||
// this.make_dt();
|
||||
this.get_cleared_balance().then(() => {
|
||||
this.cards_manager.$cards[1].set_value(
|
||||
format_currency(this.cleared_balance),
|
||||
this.currency
|
||||
);
|
||||
this.cards_manager.$cards[1].set_value(format_currency(this.cleared_balance), this.currency);
|
||||
this.cards_manager.$cards[2].set_value(
|
||||
format_currency(
|
||||
this.bank_statement_closing_balance - this.cleared_balance
|
||||
),
|
||||
format_currency(this.bank_statement_closing_balance - this.cleared_balance),
|
||||
this.currency
|
||||
);
|
||||
this.cards_manager.$cards[2].set_value_color(
|
||||
@@ -212,14 +189,12 @@ erpnext.accounts.bank_reconciliation.DataTableManager = class DataTableManager {
|
||||
get_cleared_balance() {
|
||||
if (this.bank_account && this.bank_statement_to_date) {
|
||||
return frappe.call({
|
||||
method:
|
||||
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_account_balance",
|
||||
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_account_balance",
|
||||
args: {
|
||||
bank_account: this.bank_account,
|
||||
till_date: this.bank_statement_to_date,
|
||||
},
|
||||
callback: (response) =>
|
||||
(this.cleared_balance = response.message),
|
||||
callback: (response) => (this.cleared_balance = response.message),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
frappe.provide("erpnext.accounts.bank_reconciliation");
|
||||
|
||||
erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
constructor(company, bank_account, bank_statement_from_date, bank_statement_to_date, filter_by_reference_date, from_reference_date, to_reference_date) {
|
||||
constructor(
|
||||
company,
|
||||
bank_account,
|
||||
bank_statement_from_date,
|
||||
bank_statement_to_date,
|
||||
filter_by_reference_date,
|
||||
from_reference_date,
|
||||
to_reference_date
|
||||
) {
|
||||
this.bank_account = bank_account;
|
||||
this.company = company;
|
||||
this.make_dialog();
|
||||
@@ -61,16 +69,15 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
|
||||
get_linked_vouchers(document_types) {
|
||||
frappe.call({
|
||||
method:
|
||||
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_linked_payments",
|
||||
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_linked_payments",
|
||||
args: {
|
||||
bank_transaction_name: this.bank_transaction_name,
|
||||
document_types: document_types,
|
||||
from_date: this.bank_statement_from_date,
|
||||
to_date: this.bank_statement_to_date,
|
||||
filter_by_reference_date: this.filter_by_reference_date,
|
||||
from_reference_date:this.from_reference_date,
|
||||
to_reference_date:this.to_reference_date
|
||||
from_reference_date: this.from_reference_date,
|
||||
to_reference_date: this.to_reference_date,
|
||||
},
|
||||
|
||||
callback: (result) => {
|
||||
@@ -105,7 +112,7 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
editable: false,
|
||||
width: 1,
|
||||
format: (value, row) => {
|
||||
return frappe.form.formatters.Link(value, {options: row[2].content});
|
||||
return frappe.form.formatters.Link(value, { options: row[2].content });
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -152,10 +159,7 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
checkboxColumn: true,
|
||||
inlineFilters: true,
|
||||
};
|
||||
this.datatable = new frappe.DataTable(
|
||||
proposals_wrapper.get(0),
|
||||
datatable_options
|
||||
);
|
||||
this.datatable = new frappe.DataTable(proposals_wrapper.get(0), datatable_options);
|
||||
} else {
|
||||
this.datatable.refresh(this.data, this.columns);
|
||||
this.datatable.rowmanager.checkMap = [];
|
||||
@@ -217,10 +221,9 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
title: __("Reconcile the Bank Transaction"),
|
||||
fields: fields,
|
||||
size: "large",
|
||||
primary_action: (values) =>
|
||||
this.reconciliation_dialog_primary_action(values),
|
||||
primary_action: (values) => this.reconciliation_dialog_primary_action(values),
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -255,7 +258,9 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
{
|
||||
fieldtype: "HTML",
|
||||
fieldname: "no_matching_vouchers",
|
||||
options: __("<div class=\"text-muted text-center\">{0}</div>", [__("No Matching Vouchers Found")])
|
||||
options: __('<div class="text-muted text-center">{0}</div>', [
|
||||
__("No Matching Vouchers Found"),
|
||||
]),
|
||||
},
|
||||
{
|
||||
fieldtype: "Section Break",
|
||||
@@ -299,8 +304,7 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
click: () => {
|
||||
this.edit_in_full_page();
|
||||
},
|
||||
depends_on:
|
||||
"eval:doc.action=='Create Voucher'",
|
||||
depends_on: "eval:doc.action=='Create Voucher'",
|
||||
},
|
||||
{
|
||||
fieldname: "column_break_7",
|
||||
@@ -313,8 +317,7 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
label: "Journal Entry Type",
|
||||
options:
|
||||
"Journal Entry\nInter Company Journal Entry\nBank Entry\nCash Entry\nCredit Card Entry\nDebit Note\nCredit Note\nContra Entry\nExcise Entry\nWrite Off Entry\nOpening Entry\nDepreciation Entry\nExchange Rate Revaluation\nDeferred Revenue\nDeferred Expense",
|
||||
depends_on:
|
||||
"eval:doc.action=='Create Voucher' && doc.document_type=='Journal Entry'",
|
||||
depends_on: "eval:doc.action=='Create Voucher' && doc.document_type=='Journal Entry'",
|
||||
mandatory_depends_on:
|
||||
"eval:doc.action=='Create Voucher' && doc.document_type=='Journal Entry'",
|
||||
},
|
||||
@@ -323,8 +326,7 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
fieldtype: "Link",
|
||||
label: "Account",
|
||||
options: "Account",
|
||||
depends_on:
|
||||
"eval:doc.action=='Create Voucher' && doc.document_type=='Journal Entry'",
|
||||
depends_on: "eval:doc.action=='Create Voucher' && doc.document_type=='Journal Entry'",
|
||||
mandatory_depends_on:
|
||||
"eval:doc.action=='Create Voucher' && doc.document_type=='Journal Entry'",
|
||||
get_query: () => {
|
||||
@@ -342,14 +344,11 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
label: "Party Type",
|
||||
options: "DocType",
|
||||
mandatory_depends_on:
|
||||
"eval:doc.action=='Create Voucher' && doc.document_type=='Payment Entry'",
|
||||
"eval:doc.action=='Create Voucher' && doc.document_type=='Payment Entry'",
|
||||
get_query: function () {
|
||||
return {
|
||||
filters: {
|
||||
name: [
|
||||
"in",
|
||||
Object.keys(frappe.boot.party_account_types),
|
||||
],
|
||||
name: ["in", Object.keys(frappe.boot.party_account_types)],
|
||||
},
|
||||
};
|
||||
},
|
||||
@@ -367,16 +366,14 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
fieldtype: "Link",
|
||||
label: "Project",
|
||||
options: "Project",
|
||||
depends_on:
|
||||
"eval:doc.action=='Create Voucher' && doc.document_type=='Payment Entry'",
|
||||
depends_on: "eval:doc.action=='Create Voucher' && doc.document_type=='Payment Entry'",
|
||||
},
|
||||
{
|
||||
fieldname: "cost_center",
|
||||
fieldtype: "Link",
|
||||
label: "Cost Center",
|
||||
options: "Cost Center",
|
||||
depends_on:
|
||||
"eval:doc.action=='Create Voucher' && doc.document_type=='Payment Entry'",
|
||||
depends_on: "eval:doc.action=='Create Voucher' && doc.document_type=='Payment Entry'",
|
||||
},
|
||||
{
|
||||
fieldtype: "Section Break",
|
||||
@@ -435,7 +432,7 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
options: "Currency",
|
||||
read_only: 1,
|
||||
hidden: 1,
|
||||
}
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@@ -457,18 +454,11 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
|
||||
reconciliation_dialog_primary_action(values) {
|
||||
if (values.action == "Match Against Voucher") this.match(values);
|
||||
if (
|
||||
values.action == "Create Voucher" &&
|
||||
values.document_type == "Payment Entry"
|
||||
)
|
||||
if (values.action == "Create Voucher" && values.document_type == "Payment Entry")
|
||||
this.add_payment_entry(values);
|
||||
if (
|
||||
values.action == "Create Voucher" &&
|
||||
values.document_type == "Journal Entry"
|
||||
)
|
||||
if (values.action == "Create Voucher" && values.document_type == "Journal Entry")
|
||||
this.add_journal_entry(values);
|
||||
else if (values.action == "Update Bank Transaction")
|
||||
this.update_transaction(values);
|
||||
else if (values.action == "Update Bank Transaction") this.update_transaction(values);
|
||||
}
|
||||
|
||||
match() {
|
||||
@@ -486,8 +476,7 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
});
|
||||
});
|
||||
frappe.call({
|
||||
method:
|
||||
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.reconcile_vouchers",
|
||||
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.reconcile_vouchers",
|
||||
args: {
|
||||
bank_transaction_name: this.bank_transaction.name,
|
||||
vouchers: vouchers,
|
||||
@@ -503,8 +492,7 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
|
||||
add_payment_entry(values) {
|
||||
frappe.call({
|
||||
method:
|
||||
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.create_payment_entry_bts",
|
||||
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.create_payment_entry_bts",
|
||||
args: {
|
||||
bank_transaction_name: this.bank_transaction.name,
|
||||
reference_number: values.reference_number,
|
||||
@@ -517,7 +505,9 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
cost_center: values.cost_center,
|
||||
},
|
||||
callback: (response) => {
|
||||
const alert_string = __("Bank Transaction {0} added as Payment Entry", [this.bank_transaction.name]);
|
||||
const alert_string = __("Bank Transaction {0} added as Payment Entry", [
|
||||
this.bank_transaction.name,
|
||||
]);
|
||||
frappe.show_alert(alert_string);
|
||||
this.update_dt_cards(response.message);
|
||||
this.dialog.hide();
|
||||
@@ -527,8 +517,7 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
|
||||
add_journal_entry(values) {
|
||||
frappe.call({
|
||||
method:
|
||||
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.create_journal_entry_bts",
|
||||
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.create_journal_entry_bts",
|
||||
args: {
|
||||
bank_transaction_name: this.bank_transaction.name,
|
||||
reference_number: values.reference_number,
|
||||
@@ -541,7 +530,9 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
second_account: values.second_account,
|
||||
},
|
||||
callback: (response) => {
|
||||
const alert_string = __("Bank Transaction {0} added as Journal Entry", [this.bank_transaction.name]);
|
||||
const alert_string = __("Bank Transaction {0} added as Journal Entry", [
|
||||
this.bank_transaction.name,
|
||||
]);
|
||||
frappe.show_alert(alert_string);
|
||||
this.update_dt_cards(response.message);
|
||||
this.dialog.hide();
|
||||
@@ -551,8 +542,7 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
|
||||
update_transaction(values) {
|
||||
frappe.call({
|
||||
method:
|
||||
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.update_bank_transaction",
|
||||
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.update_bank_transaction",
|
||||
args: {
|
||||
bank_transaction_name: this.bank_transaction.name,
|
||||
reference_number: values.reference_number,
|
||||
@@ -572,8 +562,7 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
const values = this.dialog.get_values(true);
|
||||
if (values.document_type == "Payment Entry") {
|
||||
frappe.call({
|
||||
method:
|
||||
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.create_payment_entry_bts",
|
||||
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.create_payment_entry_bts",
|
||||
args: {
|
||||
bank_transaction_name: this.bank_transaction.name,
|
||||
reference_number: values.reference_number,
|
||||
@@ -584,7 +573,7 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
mode_of_payment: values.mode_of_payment,
|
||||
project: values.project,
|
||||
cost_center: values.cost_center,
|
||||
allow_edit: true
|
||||
allow_edit: true,
|
||||
},
|
||||
callback: (r) => {
|
||||
const doc = frappe.model.sync(r.message);
|
||||
@@ -593,8 +582,7 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
});
|
||||
} else {
|
||||
frappe.call({
|
||||
method:
|
||||
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.create_journal_entry_bts",
|
||||
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.create_journal_entry_bts",
|
||||
args: {
|
||||
bank_transaction_name: this.bank_transaction.name,
|
||||
reference_number: values.reference_number,
|
||||
@@ -605,7 +593,7 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
mode_of_payment: values.mode_of_payment,
|
||||
entry_type: values.journal_entry_type,
|
||||
second_account: values.second_account,
|
||||
allow_edit: true
|
||||
allow_edit: true,
|
||||
},
|
||||
callback: (r) => {
|
||||
var doc = frappe.model.sync(r.message);
|
||||
@@ -614,5 +602,4 @@ erpnext.accounts.bank_reconciliation.DialogManager = class DialogManager {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -26,8 +26,7 @@ erpnext.accounts.bank_reconciliation.NumberCardManager = class NumberCardManager
|
||||
currency: this.currency,
|
||||
},
|
||||
{
|
||||
value:
|
||||
this.bank_statement_closing_balance - this.cleared_balance,
|
||||
value: this.bank_statement_closing_balance - this.cleared_balance,
|
||||
label: __("Difference"),
|
||||
datatype: "Currency",
|
||||
currency: this.currency,
|
||||
@@ -41,11 +40,9 @@ erpnext.accounts.bank_reconciliation.NumberCardManager = class NumberCardManager
|
||||
number_card.$card.appendTo(this.$summary);
|
||||
});
|
||||
this.$cards[2].set_value_color(
|
||||
this.bank_statement_closing_balance - this.cleared_balance == 0
|
||||
? "text-success"
|
||||
: "text-danger"
|
||||
this.bank_statement_closing_balance - this.cleared_balance == 0 ? "text-success" : "text-danger"
|
||||
);
|
||||
this.$summary.css({"border-bottom": "0px", "margin-left": "0px", "margin-right": "0px"});
|
||||
this.$summary.css({ "border-bottom": "0px", "margin-left": "0px", "margin-right": "0px" });
|
||||
this.$summary.show();
|
||||
}
|
||||
};
|
||||
@@ -60,16 +57,10 @@ erpnext.accounts.NumberCard = class NumberCard {
|
||||
}
|
||||
|
||||
set_value_color(color) {
|
||||
this.$card
|
||||
.find("div")
|
||||
.removeClass("text-danger text-success")
|
||||
.addClass(`${color}`);
|
||||
this.$card.find("div").removeClass("text-danger text-success").addClass(`${color}`);
|
||||
}
|
||||
|
||||
set_indicator(color) {
|
||||
this.$card
|
||||
.find("span")
|
||||
.removeClass("indicator red green")
|
||||
.addClass(`indicator ${color}`);
|
||||
this.$card.find("span").removeClass("indicator red green").addClass(`indicator ${color}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -39,14 +39,14 @@ class BOMConfigurator {
|
||||
edit_qty: this.edit_qty,
|
||||
load_tree: this.load_tree,
|
||||
set_default_qty: this.set_default_qty,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
tree_options() {
|
||||
return {
|
||||
parent: this.$wrapper.get(0),
|
||||
body: this.$wrapper.get(0),
|
||||
doctype: 'BOM Configurator',
|
||||
doctype: "BOM Configurator",
|
||||
page: this.page,
|
||||
expandable: true,
|
||||
title: __("Configure Product Assembly"),
|
||||
@@ -59,7 +59,7 @@ class BOMConfigurator {
|
||||
extend_toolbar: false,
|
||||
do_not_make_page: true,
|
||||
do_not_setup_menu: true,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
tree_methods() {
|
||||
@@ -67,7 +67,7 @@ class BOMConfigurator {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
|
||||
return {
|
||||
onload: function(me) {
|
||||
onload: function (me) {
|
||||
me.args["parent_id"] = frm_obj.frm.doc.name;
|
||||
me.args["parent"] = frm_obj.frm.doc.item_code;
|
||||
me.parent = frm_obj.$wrapper.get(0);
|
||||
@@ -103,126 +103,133 @@ class BOMConfigurator {
|
||||
|
||||
`).insertBefore(node.$ul);
|
||||
},
|
||||
toolbar: this.frm?.doc.docstatus === 0 ? [
|
||||
{
|
||||
label:__(frappe.utils.icon('edit', 'sm') + " Qty"),
|
||||
click: function(node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
view.events.edit_qty(node, view);
|
||||
},
|
||||
btnClass: "hidden-xs"
|
||||
},
|
||||
{
|
||||
label:__(frappe.utils.icon('add', 'sm') + " Raw Material"),
|
||||
click: function(node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
view.events.add_item(node, view);
|
||||
},
|
||||
condition: function(node) {
|
||||
return node.expandable;
|
||||
},
|
||||
btnClass: "hidden-xs"
|
||||
},
|
||||
{
|
||||
label:__(frappe.utils.icon('add', 'sm') + " Sub Assembly"),
|
||||
click: function(node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
view.events.add_sub_assembly(node, view);
|
||||
},
|
||||
condition: function(node) {
|
||||
return node.expandable;
|
||||
},
|
||||
btnClass: "hidden-xs"
|
||||
},
|
||||
{
|
||||
label:__("Expand All"),
|
||||
click: function(node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
toolbar:
|
||||
this.frm?.doc.docstatus === 0
|
||||
? [
|
||||
{
|
||||
label: __(frappe.utils.icon("edit", "sm") + " Qty"),
|
||||
click: function (node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
view.events.edit_qty(node, view);
|
||||
},
|
||||
btnClass: "hidden-xs",
|
||||
},
|
||||
{
|
||||
label: __(frappe.utils.icon("add", "sm") + " Raw Material"),
|
||||
click: function (node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
view.events.add_item(node, view);
|
||||
},
|
||||
condition: function (node) {
|
||||
return node.expandable;
|
||||
},
|
||||
btnClass: "hidden-xs",
|
||||
},
|
||||
{
|
||||
label: __(frappe.utils.icon("add", "sm") + " Sub Assembly"),
|
||||
click: function (node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
view.events.add_sub_assembly(node, view);
|
||||
},
|
||||
condition: function (node) {
|
||||
return node.expandable;
|
||||
},
|
||||
btnClass: "hidden-xs",
|
||||
},
|
||||
{
|
||||
label: __("Expand All"),
|
||||
click: function (node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
|
||||
if (!node.expanded) {
|
||||
view.tree.load_children(node, true);
|
||||
$(node.parent[0]).find(".tree-children").show();
|
||||
node.$toolbar.find(".expand-all-btn").html("Collapse All");
|
||||
} else {
|
||||
node.$tree_link.trigger("click");
|
||||
node.$toolbar.find(".expand-all-btn").html("Expand All");
|
||||
}
|
||||
},
|
||||
condition: function(node) {
|
||||
return node.expandable && node.is_root;
|
||||
},
|
||||
btnClass: "hidden-xs expand-all-btn"
|
||||
},
|
||||
{
|
||||
label:__(frappe.utils.icon('move', 'sm') + " Sub Assembly"),
|
||||
click: function(node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
view.events.convert_to_sub_assembly(node, view);
|
||||
},
|
||||
condition: function(node) {
|
||||
return !node.expandable;
|
||||
},
|
||||
btnClass: "hidden-xs"
|
||||
},
|
||||
{
|
||||
label:__(frappe.utils.icon('delete', 'sm') + __(" Item")),
|
||||
click: function(node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
view.events.delete_node(node, view);
|
||||
},
|
||||
condition: function(node) {
|
||||
return !node.is_root;
|
||||
},
|
||||
btnClass: "hidden-xs"
|
||||
},
|
||||
] : [{
|
||||
label:__("Expand All"),
|
||||
click: function(node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
if (!node.expanded) {
|
||||
view.tree.load_children(node, true);
|
||||
$(node.parent[0]).find(".tree-children").show();
|
||||
node.$toolbar.find(".expand-all-btn").html("Collapse All");
|
||||
} else {
|
||||
node.$tree_link.trigger("click");
|
||||
node.$toolbar.find(".expand-all-btn").html("Expand All");
|
||||
}
|
||||
},
|
||||
condition: function (node) {
|
||||
return node.expandable && node.is_root;
|
||||
},
|
||||
btnClass: "hidden-xs expand-all-btn",
|
||||
},
|
||||
{
|
||||
label: __(frappe.utils.icon("move", "sm") + " Sub Assembly"),
|
||||
click: function (node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
view.events.convert_to_sub_assembly(node, view);
|
||||
},
|
||||
condition: function (node) {
|
||||
return !node.expandable;
|
||||
},
|
||||
btnClass: "hidden-xs",
|
||||
},
|
||||
{
|
||||
label: __(frappe.utils.icon("delete", "sm") + __(" Item")),
|
||||
click: function (node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
view.events.delete_node(node, view);
|
||||
},
|
||||
condition: function (node) {
|
||||
return !node.is_root;
|
||||
},
|
||||
btnClass: "hidden-xs",
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
label: __("Expand All"),
|
||||
click: function (node) {
|
||||
let view = frappe.views.trees["BOM Configurator"];
|
||||
|
||||
if (!node.expanded) {
|
||||
view.tree.load_children(node, true);
|
||||
$(node.parent[0]).find(".tree-children").show();
|
||||
node.$toolbar.find(".expand-all-btn").html("Collapse All");
|
||||
} else {
|
||||
node.$tree_link.trigger("click");
|
||||
node.$toolbar.find(".expand-all-btn").html("Expand All");
|
||||
}
|
||||
},
|
||||
condition: function(node) {
|
||||
return node.expandable && node.is_root;
|
||||
},
|
||||
btnClass: "hidden-xs expand-all-btn"
|
||||
}],
|
||||
}
|
||||
if (!node.expanded) {
|
||||
view.tree.load_children(node, true);
|
||||
$(node.parent[0]).find(".tree-children").show();
|
||||
node.$toolbar.find(".expand-all-btn").html("Collapse All");
|
||||
} else {
|
||||
node.$tree_link.trigger("click");
|
||||
node.$toolbar.find(".expand-all-btn").html("Expand All");
|
||||
}
|
||||
},
|
||||
condition: function (node) {
|
||||
return node.expandable && node.is_root;
|
||||
},
|
||||
btnClass: "hidden-xs expand-all-btn",
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
add_item(node, view) {
|
||||
frappe.prompt([
|
||||
{ label: __("Item"), fieldname: "item_code", fieldtype: "Link", options: "Item", reqd: 1 },
|
||||
{ label: __("Qty"), fieldname: "qty", default: 1.0, fieldtype: "Float", reqd: 1 },
|
||||
],
|
||||
(data) => {
|
||||
if (!node.data.parent_id) {
|
||||
node.data.parent_id = this.frm.doc.name;
|
||||
}
|
||||
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.bom_creator.bom_creator.add_item",
|
||||
args: {
|
||||
parent: node.data.parent_id,
|
||||
fg_item: node.data.value,
|
||||
item_code: data.item_code,
|
||||
fg_reference_id: node.data.name || this.frm.doc.name,
|
||||
qty: data.qty,
|
||||
},
|
||||
callback: (r) => {
|
||||
view.events.load_tree(r, node);
|
||||
frappe.prompt(
|
||||
[
|
||||
{ label: __("Item"), fieldname: "item_code", fieldtype: "Link", options: "Item", reqd: 1 },
|
||||
{ label: __("Qty"), fieldname: "qty", default: 1.0, fieldtype: "Float", reqd: 1 },
|
||||
],
|
||||
(data) => {
|
||||
if (!node.data.parent_id) {
|
||||
node.data.parent_id = this.frm.doc.name;
|
||||
}
|
||||
});
|
||||
},
|
||||
__("Add Item"),
|
||||
__("Add"));
|
||||
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.bom_creator.bom_creator.add_item",
|
||||
args: {
|
||||
parent: node.data.parent_id,
|
||||
fg_item: node.data.value,
|
||||
item_code: data.item_code,
|
||||
fg_reference_id: node.data.name || this.frm.doc.name,
|
||||
qty: data.qty,
|
||||
},
|
||||
callback: (r) => {
|
||||
view.events.load_tree(r, node);
|
||||
},
|
||||
});
|
||||
},
|
||||
__("Add Item"),
|
||||
__("Add")
|
||||
);
|
||||
}
|
||||
|
||||
add_sub_assembly(node, view) {
|
||||
@@ -251,27 +258,58 @@ class BOMConfigurator {
|
||||
},
|
||||
callback: (r) => {
|
||||
view.events.load_tree(r, node);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
dialog.hide();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
get_sub_assembly_modal_fields(read_only=false) {
|
||||
get_sub_assembly_modal_fields(read_only = false) {
|
||||
return [
|
||||
{ label: __("Sub Assembly Item"), fieldname: "item_code", fieldtype: "Link", options: "Item", reqd: 1, read_only: read_only },
|
||||
{ fieldtype: "Column Break" },
|
||||
{ label: __("Qty"), fieldname: "qty", default: 1.0, fieldtype: "Float", reqd: 1, read_only: read_only },
|
||||
{ fieldtype: "Section Break" },
|
||||
{ label: __("Raw Materials"), fieldname: "items", fieldtype: "Table", reqd: 1,
|
||||
fields: [
|
||||
{ label: __("Item"), fieldname: "item_code", fieldtype: "Link", options: "Item", reqd: 1, in_list_view: 1 },
|
||||
{ label: __("Qty"), fieldname: "qty", default: 1.0, fieldtype: "Float", reqd: 1, in_list_view: 1 },
|
||||
]
|
||||
{
|
||||
label: __("Sub Assembly Item"),
|
||||
fieldname: "item_code",
|
||||
fieldtype: "Link",
|
||||
options: "Item",
|
||||
reqd: 1,
|
||||
read_only: read_only,
|
||||
},
|
||||
]
|
||||
{ fieldtype: "Column Break" },
|
||||
{
|
||||
label: __("Qty"),
|
||||
fieldname: "qty",
|
||||
default: 1.0,
|
||||
fieldtype: "Float",
|
||||
reqd: 1,
|
||||
read_only: read_only,
|
||||
},
|
||||
{ fieldtype: "Section Break" },
|
||||
{
|
||||
label: __("Raw Materials"),
|
||||
fieldname: "items",
|
||||
fieldtype: "Table",
|
||||
reqd: 1,
|
||||
fields: [
|
||||
{
|
||||
label: __("Item"),
|
||||
fieldname: "item_code",
|
||||
fieldtype: "Link",
|
||||
options: "Item",
|
||||
reqd: 1,
|
||||
in_list_view: 1,
|
||||
},
|
||||
{
|
||||
label: __("Qty"),
|
||||
fieldname: "qty",
|
||||
default: 1.0,
|
||||
fieldtype: "Float",
|
||||
reqd: 1,
|
||||
in_list_view: 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
convert_to_sub_assembly(node, view) {
|
||||
@@ -303,7 +341,7 @@ class BOMConfigurator {
|
||||
callback: (r) => {
|
||||
node.expandable = true;
|
||||
view.events.load_tree(r, node);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
dialog.hide();
|
||||
@@ -313,12 +351,12 @@ class BOMConfigurator {
|
||||
set_default_qty(dialog) {
|
||||
dialog.fields_dict.items.grid.fields_map.item_code.onchange = function (event) {
|
||||
if (event) {
|
||||
let name = $(event.currentTarget).closest('.grid-row').attr("data-name")
|
||||
let name = $(event.currentTarget).closest(".grid-row").attr("data-name");
|
||||
let item_row = dialog.fields_dict.items.grid.grid_rows_by_docname[name].doc;
|
||||
item_row.qty = 1;
|
||||
dialog.fields_dict.items.grid.refresh()
|
||||
dialog.fields_dict.items.grid.refresh();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
delete_node(node, view) {
|
||||
@@ -333,38 +371,40 @@ class BOMConfigurator {
|
||||
},
|
||||
callback: (r) => {
|
||||
view.events.load_tree(r, node.parent_node);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
edit_qty(node, view) {
|
||||
let qty = node.data.qty || this.frm.doc.qty;
|
||||
frappe.prompt([
|
||||
{ label: __("Qty"), fieldname: "qty", default: qty, fieldtype: "Float", reqd: 1 },
|
||||
],
|
||||
(data) => {
|
||||
let doctype = node.data.doctype || this.frm.doc.doctype;
|
||||
let docname = node.data.name || this.frm.doc.name;
|
||||
frappe.prompt(
|
||||
[{ label: __("Qty"), fieldname: "qty", default: qty, fieldtype: "Float", reqd: 1 }],
|
||||
(data) => {
|
||||
let doctype = node.data.doctype || this.frm.doc.doctype;
|
||||
let docname = node.data.name || this.frm.doc.name;
|
||||
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.bom_creator.bom_creator.edit_qty",
|
||||
args: {
|
||||
doctype: doctype,
|
||||
docname: docname,
|
||||
qty: data.qty,
|
||||
parent: node.data.parent_id,
|
||||
},
|
||||
callback: (r) => {
|
||||
node.data.qty = data.qty;
|
||||
let uom = node.data.uom || this.frm.doc.uom;
|
||||
$(node.parent.get(0)).find(`[data-bom-qty-docname='${docname}']`).html(data.qty + " " + uom);
|
||||
view.events.load_tree(r, node);
|
||||
}
|
||||
});
|
||||
},
|
||||
__("Edit Qty"),
|
||||
__("Update"));
|
||||
frappe.call({
|
||||
method: "erpnext.manufacturing.doctype.bom_creator.bom_creator.edit_qty",
|
||||
args: {
|
||||
doctype: doctype,
|
||||
docname: docname,
|
||||
qty: data.qty,
|
||||
parent: node.data.parent_id,
|
||||
},
|
||||
callback: (r) => {
|
||||
node.data.qty = data.qty;
|
||||
let uom = node.data.uom || this.frm.doc.uom;
|
||||
$(node.parent.get(0))
|
||||
.find(`[data-bom-qty-docname='${docname}']`)
|
||||
.html(data.qty + " " + uom);
|
||||
view.events.load_tree(r, node);
|
||||
},
|
||||
});
|
||||
},
|
||||
__("Edit Qty"),
|
||||
__("Update")
|
||||
);
|
||||
}
|
||||
|
||||
prepare_layout() {
|
||||
@@ -378,35 +418,31 @@ class BOMConfigurator {
|
||||
|
||||
load_tree(response, node) {
|
||||
let item_row = "";
|
||||
let parent_dom = ""
|
||||
let parent_dom = "";
|
||||
let total_amount = response.message.raw_material_cost;
|
||||
|
||||
frappe.views.trees["BOM Configurator"].tree.load_children(node);
|
||||
|
||||
while (node) {
|
||||
item_row = response.message.items.filter(item => item.name === node.data.name);
|
||||
item_row = response.message.items.filter((item) => item.name === node.data.name);
|
||||
|
||||
if (item_row?.length) {
|
||||
node.data.amount = item_row[0].amount;
|
||||
total_amount = node.data.amount
|
||||
total_amount = node.data.amount;
|
||||
} else {
|
||||
total_amount = response.message.raw_material_cost;
|
||||
}
|
||||
|
||||
parent_dom = $(node.parent.get(0));
|
||||
total_amount = frappe.format(
|
||||
total_amount, {
|
||||
fieldtype: "Currency",
|
||||
currency: this.frm.doc.currency
|
||||
}
|
||||
);
|
||||
total_amount = frappe.format(total_amount, {
|
||||
fieldtype: "Currency",
|
||||
currency: this.frm.doc.currency,
|
||||
});
|
||||
|
||||
$($(parent_dom).find(".fg-item-amt")[0]).html(total_amount);
|
||||
node = node.parent_node;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
frappe.ui.BOMConfigurator = BOMConfigurator;
|
||||
frappe.ui.BOMConfigurator = BOMConfigurator;
|
||||
|
||||
@@ -1,30 +1,33 @@
|
||||
frappe.provide("erpnext.bulk_transaction_processing");
|
||||
|
||||
$.extend(erpnext.bulk_transaction_processing, {
|
||||
create: function(listview, from_doctype, to_doctype) {
|
||||
create: function (listview, from_doctype, to_doctype) {
|
||||
let checked_items = listview.get_checked_items();
|
||||
const doc_name = [];
|
||||
checked_items.forEach((Item)=> {
|
||||
checked_items.forEach((Item) => {
|
||||
if (Item.docstatus == 0) {
|
||||
doc_name.push(Item.name);
|
||||
}
|
||||
});
|
||||
|
||||
let count_of_rows = checked_items.length;
|
||||
frappe.confirm(__("Create {0} {1} ?", [count_of_rows, __(to_doctype)]), ()=>{
|
||||
frappe.confirm(__("Create {0} {1} ?", [count_of_rows, __(to_doctype)]), () => {
|
||||
if (doc_name.length == 0) {
|
||||
frappe.call({
|
||||
method: "erpnext.utilities.bulk_transaction.transaction_processing",
|
||||
args: {data: checked_items, from_doctype: from_doctype, to_doctype: to_doctype}
|
||||
}).then(()=> {
|
||||
|
||||
});
|
||||
frappe
|
||||
.call({
|
||||
method: "erpnext.utilities.bulk_transaction.transaction_processing",
|
||||
args: { data: checked_items, from_doctype: from_doctype, to_doctype: to_doctype },
|
||||
})
|
||||
.then(() => {});
|
||||
if (count_of_rows > 10) {
|
||||
frappe.show_alert("Starting a background job to create {0} {1}", [count_of_rows, __(to_doctype)]);
|
||||
frappe.show_alert("Starting a background job to create {0} {1}", [
|
||||
count_of_rows,
|
||||
__(to_doctype),
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
frappe.msgprint(__("Selected document must be in submitted state"));
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -7,17 +7,17 @@ class CallPopup {
|
||||
}
|
||||
|
||||
make() {
|
||||
frappe.utils.play_sound('incoming-call');
|
||||
frappe.utils.play_sound("incoming-call");
|
||||
this.dialog = new frappe.ui.Dialog({
|
||||
'static': true,
|
||||
'minimizable': true
|
||||
static: true,
|
||||
minimizable: true,
|
||||
});
|
||||
this.dialog.get_close_btn().show();
|
||||
this.setup_dialog();
|
||||
this.set_call_status();
|
||||
frappe.utils.bind_actions_with_object(this.dialog.$body, this);
|
||||
this.dialog.$wrapper.addClass('call-popup');
|
||||
this.dialog.get_close_btn().unbind('click').click(this.close_modal.bind(this));
|
||||
this.dialog.$wrapper.addClass("call-popup");
|
||||
this.dialog.get_close_btn().unbind("click").click(this.close_modal.bind(this));
|
||||
this.dialog.show();
|
||||
}
|
||||
|
||||
@@ -26,28 +26,28 @@ class CallPopup {
|
||||
this.dialog.$body.empty().append(this.caller_info);
|
||||
}
|
||||
|
||||
set_indicator(color, blink=false) {
|
||||
let classes = `indicator ${color} ${blink ? 'blink': ''}`;
|
||||
this.dialog.header.find('.indicator').attr('class', classes);
|
||||
set_indicator(color, blink = false) {
|
||||
let classes = `indicator ${color} ${blink ? "blink" : ""}`;
|
||||
this.dialog.header.find(".indicator").attr("class", classes);
|
||||
}
|
||||
|
||||
set_call_status(call_status) {
|
||||
let title = '';
|
||||
let title = "";
|
||||
call_status = call_status || this.call_log.status;
|
||||
if (['Ringing'].includes(call_status) || !call_status) {
|
||||
title = __('Incoming call from {0}', [this.get_caller_name() || this.caller_number]);
|
||||
this.set_indicator('blue', true);
|
||||
} else if (call_status === 'In Progress') {
|
||||
title = __('Call Connected');
|
||||
this.set_indicator('green');
|
||||
} else if (['No Answer', 'Missed'].includes(call_status)) {
|
||||
this.set_indicator('yellow');
|
||||
title = __('Call Missed');
|
||||
} else if (['Completed', 'Busy', 'Failed'].includes(call_status)) {
|
||||
this.set_indicator('red');
|
||||
title = __('Call Ended');
|
||||
if (["Ringing"].includes(call_status) || !call_status) {
|
||||
title = __("Incoming call from {0}", [this.get_caller_name() || this.caller_number]);
|
||||
this.set_indicator("blue", true);
|
||||
} else if (call_status === "In Progress") {
|
||||
title = __("Call Connected");
|
||||
this.set_indicator("green");
|
||||
} else if (["No Answer", "Missed"].includes(call_status)) {
|
||||
this.set_indicator("yellow");
|
||||
title = __("Call Missed");
|
||||
} else if (["Completed", "Busy", "Failed"].includes(call_status)) {
|
||||
this.set_indicator("red");
|
||||
title = __("Call Ended");
|
||||
} else {
|
||||
this.set_indicator('blue');
|
||||
this.set_indicator("blue");
|
||||
title = call_status;
|
||||
}
|
||||
this.dialog.set_title(title);
|
||||
@@ -55,7 +55,7 @@ class CallPopup {
|
||||
|
||||
update_call_log(call_log, missed) {
|
||||
this.call_log = call_log;
|
||||
this.set_call_status(missed ? 'Missed': null);
|
||||
this.set_call_status(missed ? "Missed" : null);
|
||||
}
|
||||
|
||||
close_modal() {
|
||||
@@ -64,10 +64,10 @@ class CallPopup {
|
||||
}
|
||||
|
||||
call_ended(call_log, missed) {
|
||||
frappe.utils.play_sound('call-disconnect');
|
||||
frappe.utils.play_sound("call-disconnect");
|
||||
this.update_call_log(call_log, missed);
|
||||
setTimeout(() => {
|
||||
if (!this.dialog.get_value('call_summary')) {
|
||||
if (!this.dialog.get_value("call_summary")) {
|
||||
this.close_modal();
|
||||
}
|
||||
}, 60000);
|
||||
@@ -81,16 +81,16 @@ class CallPopup {
|
||||
|
||||
get_contact_link() {
|
||||
let log = this.call_log;
|
||||
let contact_link = log.links.find(d => d.link_doctype === 'Contact');
|
||||
let contact_link = log.links.find((d) => d.link_doctype === "Contact");
|
||||
return contact_link || {};
|
||||
}
|
||||
|
||||
setup_listener() {
|
||||
frappe.realtime.on(`call_${this.call_log.id}_ended`, call_log => {
|
||||
frappe.realtime.on(`call_${this.call_log.id}_ended`, (call_log) => {
|
||||
this.call_ended(call_log);
|
||||
});
|
||||
|
||||
frappe.realtime.on(`call_${this.call_log.id}_missed`, call_log => {
|
||||
frappe.realtime.on(`call_${this.call_log.id}_missed`, (call_log) => {
|
||||
this.call_ended(call_log, true);
|
||||
});
|
||||
}
|
||||
@@ -103,84 +103,102 @@ class CallPopup {
|
||||
setup_call_details() {
|
||||
this.caller_info = $(`<div></div>`);
|
||||
this.call_details = new frappe.ui.FieldGroup({
|
||||
fields: [{
|
||||
'fieldname': 'name',
|
||||
'label': 'Name',
|
||||
'default': this.get_caller_name() || __('Unknown Caller'),
|
||||
'fieldtype': 'Data',
|
||||
'read_only': 1
|
||||
}, {
|
||||
'fieldtype': 'Button',
|
||||
'label': __('Open Contact'),
|
||||
'click': () => frappe.set_route('Form', 'Contact', this.get_contact_link().link_name),
|
||||
'depends_on': () => this.get_caller_name()
|
||||
}, {
|
||||
'fieldtype': 'Button',
|
||||
'label': __('Create New Contact'),
|
||||
'click': this.create_new_contact.bind(this),
|
||||
'depends_on': () => !this.get_caller_name()
|
||||
}, {
|
||||
'fieldtype': 'Button',
|
||||
'label': __('Create New Customer'),
|
||||
'click': this.create_new_customer.bind(this),
|
||||
'depends_on': () => !this.get_caller_name()
|
||||
}, {
|
||||
'fieldtype': 'Button',
|
||||
'label': __('Create New Lead'),
|
||||
'click': () => frappe.new_doc('Lead', { 'mobile_no': this.caller_number }),
|
||||
'depends_on': () => !this.get_caller_name()
|
||||
}, {
|
||||
'fieldtype': 'Column Break',
|
||||
}, {
|
||||
'fieldname': 'number',
|
||||
'label': 'Phone Number',
|
||||
'fieldtype': 'Data',
|
||||
'default': this.caller_number,
|
||||
'read_only': 1
|
||||
}, {
|
||||
'fieldtype': 'Section Break',
|
||||
'hide_border': 1,
|
||||
}, {
|
||||
'fieldname': 'call_type',
|
||||
'label': 'Call Type',
|
||||
'fieldtype': 'Link',
|
||||
'options': 'Telephony Call Type',
|
||||
}, {
|
||||
'fieldtype': 'Section Break',
|
||||
'hide_border': 1,
|
||||
}, {
|
||||
'fieldtype': 'Small Text',
|
||||
'label': __('Call Summary'),
|
||||
'fieldname': 'call_summary',
|
||||
}, {
|
||||
'fieldtype': 'Button',
|
||||
'label': __('Save'),
|
||||
'click': () => {
|
||||
const call_summary = this.call_details.get_value('call_summary');
|
||||
const call_type = this.call_details.get_value('call_type');
|
||||
if (!call_summary) return;
|
||||
frappe.xcall('erpnext.telephony.doctype.call_log.call_log.add_call_summary_and_call_type', {
|
||||
'call_log': this.call_log.name,
|
||||
'summary': call_summary,
|
||||
'call_type': call_type,
|
||||
}).then(() => {
|
||||
this.close_modal();
|
||||
frappe.show_alert({
|
||||
message: `
|
||||
${__('Call Summary Saved')}
|
||||
fields: [
|
||||
{
|
||||
fieldname: "name",
|
||||
label: "Name",
|
||||
default: this.get_caller_name() || __("Unknown Caller"),
|
||||
fieldtype: "Data",
|
||||
read_only: 1,
|
||||
},
|
||||
{
|
||||
fieldtype: "Button",
|
||||
label: __("Open Contact"),
|
||||
click: () => frappe.set_route("Form", "Contact", this.get_contact_link().link_name),
|
||||
depends_on: () => this.get_caller_name(),
|
||||
},
|
||||
{
|
||||
fieldtype: "Button",
|
||||
label: __("Create New Contact"),
|
||||
click: this.create_new_contact.bind(this),
|
||||
depends_on: () => !this.get_caller_name(),
|
||||
},
|
||||
{
|
||||
fieldtype: "Button",
|
||||
label: __("Create New Customer"),
|
||||
click: this.create_new_customer.bind(this),
|
||||
depends_on: () => !this.get_caller_name(),
|
||||
},
|
||||
{
|
||||
fieldtype: "Button",
|
||||
label: __("Create New Lead"),
|
||||
click: () => frappe.new_doc("Lead", { mobile_no: this.caller_number }),
|
||||
depends_on: () => !this.get_caller_name(),
|
||||
},
|
||||
{
|
||||
fieldtype: "Column Break",
|
||||
},
|
||||
{
|
||||
fieldname: "number",
|
||||
label: "Phone Number",
|
||||
fieldtype: "Data",
|
||||
default: this.caller_number,
|
||||
read_only: 1,
|
||||
},
|
||||
{
|
||||
fieldtype: "Section Break",
|
||||
hide_border: 1,
|
||||
},
|
||||
{
|
||||
fieldname: "call_type",
|
||||
label: "Call Type",
|
||||
fieldtype: "Link",
|
||||
options: "Telephony Call Type",
|
||||
},
|
||||
{
|
||||
fieldtype: "Section Break",
|
||||
hide_border: 1,
|
||||
},
|
||||
{
|
||||
fieldtype: "Small Text",
|
||||
label: __("Call Summary"),
|
||||
fieldname: "call_summary",
|
||||
},
|
||||
{
|
||||
fieldtype: "Button",
|
||||
label: __("Save"),
|
||||
click: () => {
|
||||
const call_summary = this.call_details.get_value("call_summary");
|
||||
const call_type = this.call_details.get_value("call_type");
|
||||
if (!call_summary) return;
|
||||
frappe
|
||||
.xcall(
|
||||
"erpnext.telephony.doctype.call_log.call_log.add_call_summary_and_call_type",
|
||||
{
|
||||
call_log: this.call_log.name,
|
||||
summary: call_summary,
|
||||
call_type: call_type,
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
this.close_modal();
|
||||
frappe.show_alert({
|
||||
message: `
|
||||
${__("Call Summary Saved")}
|
||||
<br>
|
||||
<a
|
||||
class="text-small text-muted"
|
||||
href="/app/call-log/${this.call_log.name}">
|
||||
${__('View call log')}
|
||||
${__("View call log")}
|
||||
</a>
|
||||
`,
|
||||
indicator: 'green'
|
||||
});
|
||||
});
|
||||
}
|
||||
}],
|
||||
body: this.caller_info
|
||||
indicator: "green",
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
],
|
||||
body: this.caller_info,
|
||||
});
|
||||
this.call_details.make();
|
||||
}
|
||||
@@ -191,23 +209,23 @@ class CallPopup {
|
||||
|
||||
create_new_customer() {
|
||||
// to avoid quick entry form
|
||||
const new_customer = frappe.model.get_new_doc('Customer');
|
||||
const new_customer = frappe.model.get_new_doc("Customer");
|
||||
new_customer.mobile_no = this.caller_number;
|
||||
frappe.set_route('Form', new_customer.doctype, new_customer.name);
|
||||
frappe.set_route("Form", new_customer.doctype, new_customer.name);
|
||||
}
|
||||
|
||||
create_new_contact() {
|
||||
// TODO: fix new_doc, it should accept child table values
|
||||
const new_contact = frappe.model.get_new_doc('Contact');
|
||||
const phone_no = frappe.model.add_child(new_contact, 'Contact Phone', 'phone_nos');
|
||||
const new_contact = frappe.model.get_new_doc("Contact");
|
||||
const phone_no = frappe.model.add_child(new_contact, "Contact Phone", "phone_nos");
|
||||
phone_no.phone = this.caller_number;
|
||||
phone_no.is_primary_mobile_no = 1;
|
||||
frappe.set_route('Form', new_contact.doctype, new_contact.name);
|
||||
frappe.set_route("Form", new_contact.doctype, new_contact.name);
|
||||
}
|
||||
}
|
||||
|
||||
$(document).on('app_ready', function () {
|
||||
frappe.realtime.on('show_call_popup', call_log => {
|
||||
$(document).on("app_ready", function () {
|
||||
frappe.realtime.on("show_call_popup", (call_log) => {
|
||||
let call_popup = erpnext.call_popup;
|
||||
if (call_popup && call_log.name === call_popup.call_log.name) {
|
||||
call_popup.update_call_log(call_log);
|
||||
|
||||
@@ -1,33 +1,45 @@
|
||||
frappe.ui.form.on("Communication", {
|
||||
refresh: (frm) => {
|
||||
// setup custom Make button only if Communication is Email
|
||||
if(frm.doc.communication_medium == "Email" && frm.doc.sent_or_received == "Received") {
|
||||
if (frm.doc.communication_medium == "Email" && frm.doc.sent_or_received == "Received") {
|
||||
frm.events.setup_custom_buttons(frm);
|
||||
}
|
||||
},
|
||||
|
||||
setup_custom_buttons: (frm) => {
|
||||
let confirm_msg = "Are you sure you want to create {0} from this email?";
|
||||
if(frm.doc.reference_doctype !== "Issue") {
|
||||
frm.add_custom_button(__("Issue"), () => {
|
||||
frappe.confirm(__(confirm_msg, [__("Issue")]), () => {
|
||||
frm.trigger('make_issue_from_communication');
|
||||
})
|
||||
}, __("Create"));
|
||||
if (frm.doc.reference_doctype !== "Issue") {
|
||||
frm.add_custom_button(
|
||||
__("Issue"),
|
||||
() => {
|
||||
frappe.confirm(__(confirm_msg, [__("Issue")]), () => {
|
||||
frm.trigger("make_issue_from_communication");
|
||||
});
|
||||
},
|
||||
__("Create")
|
||||
);
|
||||
}
|
||||
|
||||
if(!in_list(["Lead", "Opportunity"], frm.doc.reference_doctype)) {
|
||||
frm.add_custom_button(__("Lead"), () => {
|
||||
frappe.confirm(__(confirm_msg, [__("Lead")]), () => {
|
||||
frm.trigger('make_lead_from_communication');
|
||||
})
|
||||
}, __('Create'));
|
||||
if (!in_list(["Lead", "Opportunity"], frm.doc.reference_doctype)) {
|
||||
frm.add_custom_button(
|
||||
__("Lead"),
|
||||
() => {
|
||||
frappe.confirm(__(confirm_msg, [__("Lead")]), () => {
|
||||
frm.trigger("make_lead_from_communication");
|
||||
});
|
||||
},
|
||||
__("Create")
|
||||
);
|
||||
|
||||
frm.add_custom_button(__("Opportunity"), () => {
|
||||
frappe.confirm(__(confirm_msg, [__("Opportunity")]), () => {
|
||||
frm.trigger('make_opportunity_from_communication');
|
||||
})
|
||||
}, __('Create'));
|
||||
frm.add_custom_button(
|
||||
__("Opportunity"),
|
||||
() => {
|
||||
frappe.confirm(__(confirm_msg, [__("Opportunity")]), () => {
|
||||
frm.trigger("make_opportunity_from_communication");
|
||||
});
|
||||
},
|
||||
__("Create")
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -35,63 +47,69 @@ frappe.ui.form.on("Communication", {
|
||||
return frappe.call({
|
||||
method: "erpnext.crm.doctype.lead.lead.make_lead_from_communication",
|
||||
args: {
|
||||
communication: frm.doc.name
|
||||
communication: frm.doc.name,
|
||||
},
|
||||
freeze: true,
|
||||
callback: (r) => {
|
||||
if(r.message) {
|
||||
frm.reload_doc()
|
||||
if (r.message) {
|
||||
frm.reload_doc();
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
make_issue_from_communication: (frm) => {
|
||||
return frappe.call({
|
||||
method: "erpnext.support.doctype.issue.issue.make_issue_from_communication",
|
||||
args: {
|
||||
communication: frm.doc.name
|
||||
communication: frm.doc.name,
|
||||
},
|
||||
freeze: true,
|
||||
callback: (r) => {
|
||||
if(r.message) {
|
||||
frm.reload_doc()
|
||||
if (r.message) {
|
||||
frm.reload_doc();
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
make_opportunity_from_communication: (frm) => {
|
||||
const fields = [{
|
||||
fieldtype: 'Link',
|
||||
label: __('Select a Company'),
|
||||
fieldname: 'company',
|
||||
options: 'Company',
|
||||
reqd: 1,
|
||||
default: frappe.defaults.get_user_default("Company")
|
||||
}];
|
||||
const fields = [
|
||||
{
|
||||
fieldtype: "Link",
|
||||
label: __("Select a Company"),
|
||||
fieldname: "company",
|
||||
options: "Company",
|
||||
reqd: 1,
|
||||
default: frappe.defaults.get_user_default("Company"),
|
||||
},
|
||||
];
|
||||
|
||||
frappe.prompt(fields, data => {
|
||||
frappe.call({
|
||||
method: "erpnext.crm.doctype.opportunity.opportunity.make_opportunity_from_communication",
|
||||
args: {
|
||||
communication: frm.doc.name,
|
||||
company: data.company
|
||||
},
|
||||
freeze: true,
|
||||
callback: (r) => {
|
||||
if(r.message) {
|
||||
frm.reload_doc();
|
||||
frappe.show_alert({
|
||||
message: __("Opportunity {0} created",
|
||||
['<a href="/app/opportunity/'+r.message+'">' + r.message + '</a>']),
|
||||
indicator: 'green'
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
'Create an Opportunity',
|
||||
'Create');
|
||||
}
|
||||
frappe.prompt(
|
||||
fields,
|
||||
(data) => {
|
||||
frappe.call({
|
||||
method: "erpnext.crm.doctype.opportunity.opportunity.make_opportunity_from_communication",
|
||||
args: {
|
||||
communication: frm.doc.name,
|
||||
company: data.company,
|
||||
},
|
||||
freeze: true,
|
||||
callback: (r) => {
|
||||
if (r.message) {
|
||||
frm.reload_doc();
|
||||
frappe.show_alert({
|
||||
message: __("Opportunity {0} created", [
|
||||
'<a href="/app/opportunity/' + r.message + '">' + r.message + "</a>",
|
||||
]),
|
||||
indicator: "green",
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
"Create an Opportunity",
|
||||
"Create"
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.provide('erpnext');
|
||||
frappe.provide("erpnext");
|
||||
|
||||
// preferred modules for breadcrumbs
|
||||
$.extend(frappe.breadcrumbs.preferred, {
|
||||
"Item Group": "Stock",
|
||||
"Customer Group": "Selling",
|
||||
"Supplier Group": "Buying",
|
||||
"Territory": "Selling",
|
||||
Territory: "Selling",
|
||||
"Sales Person": "Selling",
|
||||
"Sales Partner": "Selling",
|
||||
"Brand": "Stock",
|
||||
Brand: "Stock",
|
||||
"Maintenance Schedule": "Support",
|
||||
"Maintenance Visit": "Support"
|
||||
"Maintenance Visit": "Support",
|
||||
});
|
||||
|
||||
$.extend(frappe.breadcrumbs.module_map, {
|
||||
'ERPNext Integrations': 'Integrations',
|
||||
'Geo': 'Settings',
|
||||
'Portal': 'Website',
|
||||
'Utilities': 'Settings',
|
||||
'E-commerce': 'Website',
|
||||
'Contacts': 'CRM'
|
||||
"ERPNext Integrations": "Integrations",
|
||||
Geo: "Settings",
|
||||
Portal: "Website",
|
||||
Utilities: "Settings",
|
||||
"E-commerce": "Website",
|
||||
Contacts: "CRM",
|
||||
});
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
|
||||
|
||||
frappe.ui.form.on("Contact", {
|
||||
refresh(frm) {
|
||||
frm.set_query('link_doctype', "links", function() {
|
||||
frm.set_query("link_doctype", "links", function () {
|
||||
return {
|
||||
query: "frappe.contacts.address_and_contact.filter_dynamic_link_doctypes",
|
||||
filters: {
|
||||
fieldtype: ["in", ["HTML", "Text Editor"]],
|
||||
fieldname: ["in", ["contact_html", "company_description"]],
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
frm.refresh_field("links");
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ import "./bulk_transaction_processing";
|
||||
import "./utils/crm_activities";
|
||||
import "./templates/crm_activities.html";
|
||||
import "./templates/crm_notes.html";
|
||||
import "./controllers/accounts.js"
|
||||
import "./controllers/accounts.js";
|
||||
import "./utils/landed_taxes_and_charges_common.js";
|
||||
import "./utils/sales_common.js";
|
||||
import "./controllers/buying.js";
|
||||
|
||||
@@ -3,33 +3,53 @@
|
||||
frappe.provide("frappe.desk");
|
||||
|
||||
frappe.ui.form.on("Event", {
|
||||
refresh: function(frm) {
|
||||
frm.set_query('reference_doctype', "event_participants", function() {
|
||||
refresh: function (frm) {
|
||||
frm.set_query("reference_doctype", "event_participants", function () {
|
||||
return {
|
||||
"filters": {
|
||||
"name": ["in", ["Contact", "Lead", "Customer", "Supplier", "Employee", "Sales Partner"]]
|
||||
}
|
||||
filters: {
|
||||
name: ["in", ["Contact", "Lead", "Customer", "Supplier", "Employee", "Sales Partner"]],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
frm.add_custom_button(__('Add Leads'), function() {
|
||||
new frappe.desk.eventParticipants(frm, "Lead");
|
||||
}, __("Add Participants"));
|
||||
frm.add_custom_button(
|
||||
__("Add Leads"),
|
||||
function () {
|
||||
new frappe.desk.eventParticipants(frm, "Lead");
|
||||
},
|
||||
__("Add Participants")
|
||||
);
|
||||
|
||||
frm.add_custom_button(__('Add Customers'), function() {
|
||||
new frappe.desk.eventParticipants(frm, "Customer");
|
||||
}, __("Add Participants"));
|
||||
frm.add_custom_button(
|
||||
__("Add Customers"),
|
||||
function () {
|
||||
new frappe.desk.eventParticipants(frm, "Customer");
|
||||
},
|
||||
__("Add Participants")
|
||||
);
|
||||
|
||||
frm.add_custom_button(__('Add Suppliers'), function() {
|
||||
new frappe.desk.eventParticipants(frm, "Supplier");
|
||||
}, __("Add Participants"));
|
||||
frm.add_custom_button(
|
||||
__("Add Suppliers"),
|
||||
function () {
|
||||
new frappe.desk.eventParticipants(frm, "Supplier");
|
||||
},
|
||||
__("Add Participants")
|
||||
);
|
||||
|
||||
frm.add_custom_button(__('Add Employees'), function() {
|
||||
new frappe.desk.eventParticipants(frm, "Employee");
|
||||
}, __("Add Participants"));
|
||||
frm.add_custom_button(
|
||||
__("Add Employees"),
|
||||
function () {
|
||||
new frappe.desk.eventParticipants(frm, "Employee");
|
||||
},
|
||||
__("Add Participants")
|
||||
);
|
||||
|
||||
frm.add_custom_button(__('Add Sales Partners'), function() {
|
||||
new frappe.desk.eventParticipants(frm, "Sales Partners");
|
||||
}, __("Add Participants"));
|
||||
}
|
||||
frm.add_custom_button(
|
||||
__("Add Sales Partners"),
|
||||
function () {
|
||||
new frappe.desk.eventParticipants(frm, "Sales Partners");
|
||||
},
|
||||
__("Add Participants")
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,60 +1,58 @@
|
||||
frappe.provide("erpnext.financial_statements");
|
||||
|
||||
erpnext.financial_statements = {
|
||||
"filters": get_filters(),
|
||||
"baseData": null,
|
||||
"formatter": function(value, row, column, data, default_formatter, filter) {
|
||||
if(frappe.query_report.get_filter_value("selected_view") == "Growth" && data && column.colIndex >= 3){
|
||||
filters: get_filters(),
|
||||
baseData: null,
|
||||
formatter: function (value, row, column, data, default_formatter, filter) {
|
||||
if (
|
||||
frappe.query_report.get_filter_value("selected_view") == "Growth" &&
|
||||
data &&
|
||||
column.colIndex >= 3
|
||||
) {
|
||||
//Assuming that the first three columns are s.no, account name and the very first year of the accounting values, to calculate the relative percentage values of the successive columns.
|
||||
const lastAnnualValue = row[column.colIndex - 1].content;
|
||||
const currentAnnualvalue = data[column.fieldname];
|
||||
if(currentAnnualvalue == undefined) return 'NA'; //making this not applicable for undefined/null values
|
||||
if (currentAnnualvalue == undefined) return "NA"; //making this not applicable for undefined/null values
|
||||
let annualGrowth = 0;
|
||||
if(lastAnnualValue == 0 && currentAnnualvalue > 0){
|
||||
if (lastAnnualValue == 0 && currentAnnualvalue > 0) {
|
||||
//If the previous year value is 0 and the current value is greater than 0
|
||||
annualGrowth = 1;
|
||||
}
|
||||
else if(lastAnnualValue > 0){
|
||||
annualGrowth = (currentAnnualvalue - lastAnnualValue) / lastAnnualValue;
|
||||
} else if (lastAnnualValue > 0) {
|
||||
annualGrowth = (currentAnnualvalue - lastAnnualValue) / lastAnnualValue;
|
||||
}
|
||||
|
||||
const growthPercent = (Math.round(annualGrowth*10000)/100); //calculating the rounded off percentage
|
||||
const growthPercent = Math.round(annualGrowth * 10000) / 100; //calculating the rounded off percentage
|
||||
|
||||
value = $(`<span>${((growthPercent >=0)? '+':'' )+growthPercent+'%'}</span>`);
|
||||
if(growthPercent < 0){
|
||||
value = $(`<span>${(growthPercent >= 0 ? "+" : "") + growthPercent + "%"}</span>`);
|
||||
if (growthPercent < 0) {
|
||||
value = $(value).addClass("text-danger");
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
value = $(value).addClass("text-success");
|
||||
}
|
||||
value = $(value).wrap("<p></p>").parent().html();
|
||||
|
||||
return value;
|
||||
}
|
||||
else if(frappe.query_report.get_filter_value("selected_view") == "Margin" && data){
|
||||
if(column.fieldname =="account" && data.account_name == __("Income")){
|
||||
} else if (frappe.query_report.get_filter_value("selected_view") == "Margin" && data) {
|
||||
if (column.fieldname == "account" && data.account_name == __("Income")) {
|
||||
//Taking the total income from each column (for all the financial years) as the base (100%)
|
||||
this.baseData = row;
|
||||
}
|
||||
if(column.colIndex >= 2){
|
||||
if (column.colIndex >= 2) {
|
||||
//Assuming that the first two columns are s.no and account name, to calculate the relative percentage values of the successive columns.
|
||||
const currentAnnualvalue = data[column.fieldname];
|
||||
const baseValue = this.baseData[column.colIndex].content;
|
||||
if(currentAnnualvalue == undefined || baseValue <= 0) return 'NA';
|
||||
const marginPercent = Math.round((currentAnnualvalue/baseValue)*10000)/100;
|
||||
if (currentAnnualvalue == undefined || baseValue <= 0) return "NA";
|
||||
const marginPercent = Math.round((currentAnnualvalue / baseValue) * 10000) / 100;
|
||||
|
||||
value = $(`<span>${marginPercent+'%'}</span>`);
|
||||
if(marginPercent < 0)
|
||||
value = $(value).addClass("text-danger");
|
||||
else
|
||||
value = $(value).addClass("text-success");
|
||||
value = $(`<span>${marginPercent + "%"}</span>`);
|
||||
if (marginPercent < 0) value = $(value).addClass("text-danger");
|
||||
else value = $(value).addClass("text-success");
|
||||
value = $(value).wrap("<p></p>").parent().html();
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (data && column.fieldname=="account") {
|
||||
if (data && column.fieldname == "account") {
|
||||
value = data.account_name || value;
|
||||
|
||||
if (filter && filter?.text && filter?.type == "contains") {
|
||||
@@ -85,16 +83,18 @@ erpnext.financial_statements = {
|
||||
|
||||
return value;
|
||||
},
|
||||
"open_general_ledger": function(data) {
|
||||
open_general_ledger: function (data) {
|
||||
if (!data.account) return;
|
||||
let project = $.grep(frappe.query_report.filters, function(e){ return e.df.fieldname == 'project'; });
|
||||
let project = $.grep(frappe.query_report.filters, function (e) {
|
||||
return e.df.fieldname == "project";
|
||||
});
|
||||
|
||||
frappe.route_options = {
|
||||
"account": data.account,
|
||||
"company": frappe.query_report.get_filter_value('company'),
|
||||
"from_date": data.from_date || data.year_start_date,
|
||||
"to_date": data.to_date || data.year_end_date,
|
||||
"project": (project && project.length > 0) ? project[0].$input.val() : ""
|
||||
account: data.account,
|
||||
company: frappe.query_report.get_filter_value("company"),
|
||||
from_date: data.from_date || data.year_start_date,
|
||||
to_date: data.to_date || data.year_end_date,
|
||||
project: project && project.length > 0 ? project[0].$input.val() : "",
|
||||
};
|
||||
|
||||
let report = "General Ledger";
|
||||
@@ -107,159 +107,172 @@ erpnext.financial_statements = {
|
||||
|
||||
frappe.set_route("query-report", report);
|
||||
},
|
||||
"tree": true,
|
||||
"name_field": "account",
|
||||
"parent_field": "parent_account",
|
||||
"initial_depth": 3,
|
||||
onload: function(report) {
|
||||
tree: true,
|
||||
name_field: "account",
|
||||
parent_field: "parent_account",
|
||||
initial_depth: 3,
|
||||
onload: function (report) {
|
||||
// dropdown for links to other financial statements
|
||||
erpnext.financial_statements.filters = get_filters()
|
||||
erpnext.financial_statements.filters = get_filters();
|
||||
|
||||
let fiscal_year = erpnext.utils.get_fiscal_year(frappe.datetime.get_today());
|
||||
|
||||
frappe.model.with_doc("Fiscal Year", fiscal_year, function(r) {
|
||||
frappe.model.with_doc("Fiscal Year", fiscal_year, function (r) {
|
||||
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
|
||||
frappe.query_report.set_filter_value({
|
||||
period_start_date: fy.year_start_date,
|
||||
period_end_date: fy.year_end_date
|
||||
period_end_date: fy.year_end_date,
|
||||
});
|
||||
});
|
||||
|
||||
if (report.page){
|
||||
const views_menu = report.page.add_custom_button_group(__('Financial Statements'));
|
||||
if (report.page) {
|
||||
const views_menu = report.page.add_custom_button_group(__("Financial Statements"));
|
||||
|
||||
report.page.add_custom_menu_item(views_menu, __("Balance Sheet"), function() {
|
||||
report.page.add_custom_menu_item(views_menu, __("Balance Sheet"), function () {
|
||||
var filters = report.get_values();
|
||||
frappe.set_route('query-report', 'Balance Sheet', {company: filters.company});
|
||||
frappe.set_route("query-report", "Balance Sheet", { company: filters.company });
|
||||
});
|
||||
|
||||
report.page.add_custom_menu_item(views_menu, __("Profit and Loss"), function() {
|
||||
report.page.add_custom_menu_item(views_menu, __("Profit and Loss"), function () {
|
||||
var filters = report.get_values();
|
||||
frappe.set_route('query-report', 'Profit and Loss Statement', {company: filters.company});
|
||||
frappe.set_route("query-report", "Profit and Loss Statement", { company: filters.company });
|
||||
});
|
||||
|
||||
report.page.add_custom_menu_item(views_menu, __("Cash Flow Statement"), function() {
|
||||
report.page.add_custom_menu_item(views_menu, __("Cash Flow Statement"), function () {
|
||||
var filters = report.get_values();
|
||||
frappe.set_route('query-report', 'Cash Flow', {company: filters.company});
|
||||
frappe.set_route("query-report", "Cash Flow", { company: filters.company });
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function get_filters() {
|
||||
let 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":"finance_book",
|
||||
"label": __("Finance Book"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Finance Book"
|
||||
fieldname: "finance_book",
|
||||
label: __("Finance Book"),
|
||||
fieldtype: "Link",
|
||||
options: "Finance Book",
|
||||
},
|
||||
{
|
||||
"fieldname":"filter_based_on",
|
||||
"label": __("Filter Based On"),
|
||||
"fieldtype": "Select",
|
||||
"options": ["Fiscal Year", "Date Range"],
|
||||
"default": ["Fiscal Year"],
|
||||
"reqd": 1,
|
||||
on_change: function() {
|
||||
let filter_based_on = frappe.query_report.get_filter_value('filter_based_on');
|
||||
frappe.query_report.toggle_filter_display('from_fiscal_year', filter_based_on === 'Date Range');
|
||||
frappe.query_report.toggle_filter_display('to_fiscal_year', filter_based_on === 'Date Range');
|
||||
frappe.query_report.toggle_filter_display('period_start_date', filter_based_on === 'Fiscal Year');
|
||||
frappe.query_report.toggle_filter_display('period_end_date', filter_based_on === 'Fiscal Year');
|
||||
fieldname: "filter_based_on",
|
||||
label: __("Filter Based On"),
|
||||
fieldtype: "Select",
|
||||
options: ["Fiscal Year", "Date Range"],
|
||||
default: ["Fiscal Year"],
|
||||
reqd: 1,
|
||||
on_change: function () {
|
||||
let filter_based_on = frappe.query_report.get_filter_value("filter_based_on");
|
||||
frappe.query_report.toggle_filter_display(
|
||||
"from_fiscal_year",
|
||||
filter_based_on === "Date Range"
|
||||
);
|
||||
frappe.query_report.toggle_filter_display("to_fiscal_year", filter_based_on === "Date Range");
|
||||
frappe.query_report.toggle_filter_display(
|
||||
"period_start_date",
|
||||
filter_based_on === "Fiscal Year"
|
||||
);
|
||||
frappe.query_report.toggle_filter_display(
|
||||
"period_end_date",
|
||||
filter_based_on === "Fiscal Year"
|
||||
);
|
||||
|
||||
frappe.query_report.refresh();
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname":"period_start_date",
|
||||
"label": __("Start Date"),
|
||||
"fieldtype": "Date",
|
||||
"reqd": 1,
|
||||
"depends_on": "eval:doc.filter_based_on == 'Date Range'"
|
||||
fieldname: "period_start_date",
|
||||
label: __("Start Date"),
|
||||
fieldtype: "Date",
|
||||
reqd: 1,
|
||||
depends_on: "eval:doc.filter_based_on == 'Date Range'",
|
||||
},
|
||||
{
|
||||
"fieldname":"period_end_date",
|
||||
"label": __("End Date"),
|
||||
"fieldtype": "Date",
|
||||
"reqd": 1,
|
||||
"depends_on": "eval:doc.filter_based_on == 'Date Range'"
|
||||
fieldname: "period_end_date",
|
||||
label: __("End Date"),
|
||||
fieldtype: "Date",
|
||||
reqd: 1,
|
||||
depends_on: "eval:doc.filter_based_on == 'Date Range'",
|
||||
},
|
||||
{
|
||||
"fieldname":"from_fiscal_year",
|
||||
"label": __("Start Year"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Fiscal Year",
|
||||
"reqd": 1,
|
||||
"depends_on": "eval:doc.filter_based_on == 'Fiscal Year'"
|
||||
fieldname: "from_fiscal_year",
|
||||
label: __("Start Year"),
|
||||
fieldtype: "Link",
|
||||
options: "Fiscal Year",
|
||||
reqd: 1,
|
||||
depends_on: "eval:doc.filter_based_on == 'Fiscal Year'",
|
||||
},
|
||||
{
|
||||
"fieldname":"to_fiscal_year",
|
||||
"label": __("End Year"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Fiscal Year",
|
||||
"reqd": 1,
|
||||
"depends_on": "eval:doc.filter_based_on == 'Fiscal Year'"
|
||||
fieldname: "to_fiscal_year",
|
||||
label: __("End Year"),
|
||||
fieldtype: "Link",
|
||||
options: "Fiscal Year",
|
||||
reqd: 1,
|
||||
depends_on: "eval:doc.filter_based_on == 'Fiscal Year'",
|
||||
},
|
||||
{
|
||||
"fieldname": "periodicity",
|
||||
"label": __("Periodicity"),
|
||||
"fieldtype": "Select",
|
||||
"options": [
|
||||
{ "value": "Monthly", "label": __("Monthly") },
|
||||
{ "value": "Quarterly", "label": __("Quarterly") },
|
||||
{ "value": "Half-Yearly", "label": __("Half-Yearly") },
|
||||
{ "value": "Yearly", "label": __("Yearly") }
|
||||
fieldname: "periodicity",
|
||||
label: __("Periodicity"),
|
||||
fieldtype: "Select",
|
||||
options: [
|
||||
{ value: "Monthly", label: __("Monthly") },
|
||||
{ value: "Quarterly", label: __("Quarterly") },
|
||||
{ value: "Half-Yearly", label: __("Half-Yearly") },
|
||||
{ value: "Yearly", label: __("Yearly") },
|
||||
],
|
||||
"default": "Yearly",
|
||||
"reqd": 1
|
||||
default: "Yearly",
|
||||
reqd: 1,
|
||||
},
|
||||
// Note:
|
||||
// If you are modifying this array such that the presentation_currency object
|
||||
// is no longer the last object, please make adjustments in cash_flow.js
|
||||
// accordingly.
|
||||
{
|
||||
"fieldname": "presentation_currency",
|
||||
"label": __("Currency"),
|
||||
"fieldtype": "Select",
|
||||
"options": erpnext.get_presentation_currency_list()
|
||||
fieldname: "presentation_currency",
|
||||
label: __("Currency"),
|
||||
fieldtype: "Select",
|
||||
options: erpnext.get_presentation_currency_list(),
|
||||
},
|
||||
{
|
||||
"fieldname": "cost_center",
|
||||
"label": __("Cost Center"),
|
||||
"fieldtype": "MultiSelectList",
|
||||
get_data: function(txt) {
|
||||
return frappe.db.get_link_options('Cost Center', txt, {
|
||||
company: frappe.query_report.get_filter_value("company")
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldname": "project",
|
||||
"label": __("Project"),
|
||||
"fieldtype": "MultiSelectList",
|
||||
get_data: function(txt) {
|
||||
return frappe.db.get_link_options('Project', txt, {
|
||||
company: frappe.query_report.get_filter_value("company")
|
||||
fieldname: "cost_center",
|
||||
label: __("Cost Center"),
|
||||
fieldtype: "MultiSelectList",
|
||||
get_data: function (txt) {
|
||||
return frappe.db.get_link_options("Cost Center", txt, {
|
||||
company: frappe.query_report.get_filter_value("company"),
|
||||
});
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
fieldname: "project",
|
||||
label: __("Project"),
|
||||
fieldtype: "MultiSelectList",
|
||||
get_data: function (txt) {
|
||||
return frappe.db.get_link_options("Project", txt, {
|
||||
company: frappe.query_report.get_filter_value("company"),
|
||||
});
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// Dynamically set 'default' values for fiscal year filters
|
||||
let fy_filters = filters.filter(x=>{return ["from_fiscal_year", "to_fiscal_year"].includes(x.fieldname);})
|
||||
let fy_filters = filters.filter((x) => {
|
||||
return ["from_fiscal_year", "to_fiscal_year"].includes(x.fieldname);
|
||||
});
|
||||
let fiscal_year = erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), false, true);
|
||||
if (fiscal_year) {
|
||||
let fy = erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), false, false);
|
||||
fy_filters.forEach(x=>{x.default = fy;})
|
||||
fy_filters.forEach((x) => {
|
||||
x.default = fy;
|
||||
});
|
||||
}
|
||||
|
||||
return filters;
|
||||
|
||||
@@ -332,13 +332,9 @@ frappe.help.help_links["Form/Selling Settings"] = [
|
||||
|
||||
//Buying
|
||||
|
||||
frappe.help.help_links["List/Supplier"] = [
|
||||
{ label: "Supplier", url: docsUrl + "user/manual/en/supplier" },
|
||||
];
|
||||
frappe.help.help_links["List/Supplier"] = [{ label: "Supplier", url: docsUrl + "user/manual/en/supplier" }];
|
||||
|
||||
frappe.help.help_links["Form/Supplier"] = [
|
||||
{ label: "Supplier", url: docsUrl + "user/manual/en/supplier" },
|
||||
];
|
||||
frappe.help.help_links["Form/Supplier"] = [{ label: "Supplier", url: docsUrl + "user/manual/en/supplier" }];
|
||||
|
||||
frappe.help.help_links["Form/Request for Quotation"] = [
|
||||
{
|
||||
@@ -441,9 +437,7 @@ frappe.help.help_links["Tree/Territory"] = [
|
||||
},
|
||||
];
|
||||
|
||||
frappe.help.help_links["List/Workflow"] = [
|
||||
{ label: "Workflow", url: docsUrl + "user/manual/en/workflows" },
|
||||
];
|
||||
frappe.help.help_links["List/Workflow"] = [{ label: "Workflow", url: docsUrl + "user/manual/en/workflows" }];
|
||||
|
||||
frappe.help.help_links["List/Company"] = [
|
||||
{
|
||||
@@ -620,9 +614,7 @@ frappe.help.help_links["List/Item"] = [
|
||||
},
|
||||
{
|
||||
label: "Item Valuation",
|
||||
url:
|
||||
docsUrl +
|
||||
"user/manual/en/calculation-of-valuation-rate-in-fifo-and-moving-average",
|
||||
url: docsUrl + "user/manual/en/calculation-of-valuation-rate-in-fifo-and-moving-average",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -706,9 +698,7 @@ frappe.help.help_links["List/Installation Note"] = [
|
||||
},
|
||||
];
|
||||
|
||||
frappe.help.help_links["List/Budget"] = [
|
||||
{ label: "Budgeting", url: docsUrl + "user/manual/en/budgeting" },
|
||||
];
|
||||
frappe.help.help_links["List/Budget"] = [{ label: "Budgeting", url: docsUrl + "user/manual/en/budgeting" }];
|
||||
|
||||
frappe.help.help_links["List/Material Request"] = [
|
||||
{
|
||||
@@ -768,13 +758,9 @@ frappe.help.help_links["Form/Serial No"] = [
|
||||
{ label: "Serial No", url: docsUrl + "user/manual/en/serial-no" },
|
||||
];
|
||||
|
||||
frappe.help.help_links["List/Batch"] = [
|
||||
{ label: "Batch", url: docsUrl + "user/manual/en/batch" },
|
||||
];
|
||||
frappe.help.help_links["List/Batch"] = [{ label: "Batch", url: docsUrl + "user/manual/en/batch" }];
|
||||
|
||||
frappe.help.help_links["Form/Batch"] = [
|
||||
{ label: "Batch", url: docsUrl + "user/manual/en/batch" },
|
||||
];
|
||||
frappe.help.help_links["Form/Batch"] = [{ label: "Batch", url: docsUrl + "user/manual/en/batch" }];
|
||||
|
||||
frappe.help.help_links["Form/Packing Slip"] = [
|
||||
{
|
||||
@@ -827,29 +813,21 @@ frappe.help.help_links["Form/Stock Reconciliation"] = [
|
||||
|
||||
//CRM
|
||||
|
||||
frappe.help.help_links["Form/Lead"] = [
|
||||
{ label: "Lead", url: docsUrl + "user/manual/en/lead" },
|
||||
];
|
||||
frappe.help.help_links["Form/Lead"] = [{ label: "Lead", url: docsUrl + "user/manual/en/lead" }];
|
||||
|
||||
frappe.help.help_links["Form/Opportunity"] = [
|
||||
{ label: "Opportunity", url: docsUrl + "user/manual/en/opportunity" },
|
||||
];
|
||||
|
||||
frappe.help.help_links["Form/Address"] = [
|
||||
{ label: "Address", url: docsUrl + "user/manual/en/address" },
|
||||
];
|
||||
frappe.help.help_links["Form/Address"] = [{ label: "Address", url: docsUrl + "user/manual/en/address" }];
|
||||
|
||||
frappe.help.help_links["Form/Contact"] = [
|
||||
{ label: "Contact", url: docsUrl + "user/manual/en/contact" },
|
||||
];
|
||||
frappe.help.help_links["Form/Contact"] = [{ label: "Contact", url: docsUrl + "user/manual/en/contact" }];
|
||||
|
||||
frappe.help.help_links["Form/Newsletter"] = [
|
||||
{ label: "Newsletter", url: docsUrl + "user/manual/en/newsletter" },
|
||||
];
|
||||
|
||||
frappe.help.help_links["Form/Campaign"] = [
|
||||
{ label: "Campaign", url: docsUrl + "user/manual/en/campaign" },
|
||||
];
|
||||
frappe.help.help_links["Form/Campaign"] = [{ label: "Campaign", url: docsUrl + "user/manual/en/campaign" }];
|
||||
|
||||
frappe.help.help_links["Tree/Sales Person"] = [
|
||||
{
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.ui.form.on('Newsletter', {
|
||||
frappe.ui.form.on("Newsletter", {
|
||||
refresh() {
|
||||
erpnext.toggle_naming_series();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@ erpnext.payments = class payments extends erpnext.stock.StockController {
|
||||
var me = this;
|
||||
|
||||
this.dialog = new frappe.ui.Dialog({
|
||||
title: 'Payment'
|
||||
title: "Payment",
|
||||
});
|
||||
|
||||
this.dialog.show();
|
||||
@@ -17,15 +17,17 @@ erpnext.payments = class payments extends erpnext.stock.StockController {
|
||||
}
|
||||
|
||||
select_text() {
|
||||
$(this.$body).find('.form-control').click(function() {
|
||||
$(this).select();
|
||||
});
|
||||
$(this.$body)
|
||||
.find(".form-control")
|
||||
.click(function () {
|
||||
$(this).select();
|
||||
});
|
||||
}
|
||||
|
||||
set_payment_primary_action() {
|
||||
var me = this;
|
||||
|
||||
this.dialog.set_primary_action(__("Submit"), function() {
|
||||
this.dialog.set_primary_action(__("Submit"), function () {
|
||||
// Allow no ZERO payment
|
||||
$.each(me.frm.doc.payments, function (index, data) {
|
||||
if (data.amount != 0) {
|
||||
@@ -34,131 +36,147 @@ erpnext.payments = class payments extends erpnext.stock.StockController {
|
||||
return;
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
make_keyboard(){
|
||||
make_keyboard() {
|
||||
var me = this;
|
||||
$(this.$body).empty();
|
||||
$(this.$body).html(frappe.render_template('pos_payment', this.frm.doc))
|
||||
$(this.$body).html(frappe.render_template("pos_payment", this.frm.doc));
|
||||
this.show_payment_details();
|
||||
this.bind_keyboard_event()
|
||||
this.clear_amount()
|
||||
this.bind_keyboard_event();
|
||||
this.clear_amount();
|
||||
}
|
||||
|
||||
make_multimode_payment(){
|
||||
make_multimode_payment() {
|
||||
var me = this;
|
||||
|
||||
if (this.frm.doc.change_amount > 0) {
|
||||
me.payment_val = me.doc.outstanding_amount;
|
||||
}
|
||||
|
||||
this.payments = frappe.model.add_child(this.frm.doc, 'Multi Mode Payment', "payments");
|
||||
this.payments = frappe.model.add_child(this.frm.doc, "Multi Mode Payment", "payments");
|
||||
this.payments.mode_of_payment = this.dialog.fields_dict.mode_of_payment.get_value();
|
||||
this.payments.amount = flt(this.payment_val);
|
||||
}
|
||||
|
||||
show_payment_details(){
|
||||
show_payment_details() {
|
||||
var me = this;
|
||||
var multimode_payments = $(this.$body).find('.multimode-payments').empty();
|
||||
var multimode_payments = $(this.$body).find(".multimode-payments").empty();
|
||||
if (this.frm.doc.payments.length) {
|
||||
$.each(this.frm.doc.payments, function(index, data) {
|
||||
$(frappe.render_template('payment_details', {
|
||||
mode_of_payment: data.mode_of_payment,
|
||||
amount: data.amount,
|
||||
idx: data.idx,
|
||||
currency: me.frm.doc.currency,
|
||||
type: data.type
|
||||
})).appendTo(multimode_payments)
|
||||
$.each(this.frm.doc.payments, function (index, data) {
|
||||
$(
|
||||
frappe.render_template("payment_details", {
|
||||
mode_of_payment: data.mode_of_payment,
|
||||
amount: data.amount,
|
||||
idx: data.idx,
|
||||
currency: me.frm.doc.currency,
|
||||
type: data.type,
|
||||
})
|
||||
).appendTo(multimode_payments);
|
||||
|
||||
if (data.type == 'Cash' && data.amount == me.frm.doc.paid_amount) {
|
||||
if (data.type == "Cash" && data.amount == me.frm.doc.paid_amount) {
|
||||
me.idx = data.idx;
|
||||
me.selected_mode = $(me.$body).find(repl("input[idx='%(idx)s']",{'idx': me.idx}));
|
||||
me.selected_mode = $(me.$body).find(repl("input[idx='%(idx)s']", { idx: me.idx }));
|
||||
me.highlight_selected_row();
|
||||
me.bind_amount_change_event();
|
||||
}
|
||||
})
|
||||
}else{
|
||||
$("<p>No payment mode selected in pos profile</p>").appendTo(multimode_payments)
|
||||
});
|
||||
} else {
|
||||
$("<p>No payment mode selected in pos profile</p>").appendTo(multimode_payments);
|
||||
}
|
||||
}
|
||||
|
||||
set_outstanding_amount(){
|
||||
this.selected_mode = $(this.$body).find(repl("input[idx='%(idx)s']",{'idx': this.idx}));
|
||||
set_outstanding_amount() {
|
||||
this.selected_mode = $(this.$body).find(repl("input[idx='%(idx)s']", { idx: this.idx }));
|
||||
this.highlight_selected_row();
|
||||
this.payment_val = 0.0;
|
||||
if (this.frm.doc.outstanding_amount > 0 && flt(this.selected_mode.val()) == 0.0) {
|
||||
//When user first time click on row
|
||||
this.payment_val = flt(this.frm.doc.outstanding_amount / this.frm.doc.conversion_rate, precision("outstanding_amount"))
|
||||
this.payment_val = flt(
|
||||
this.frm.doc.outstanding_amount / this.frm.doc.conversion_rate,
|
||||
precision("outstanding_amount")
|
||||
);
|
||||
this.selected_mode.val(format_currency(this.payment_val, this.frm.doc.currency));
|
||||
this.update_payment_amount();
|
||||
} else if (flt(this.selected_mode.val()) > 0) {
|
||||
//If user click on existing row which has value
|
||||
this.payment_val = flt(this.selected_mode.val());
|
||||
}
|
||||
this.selected_mode.select()
|
||||
this.selected_mode.select();
|
||||
this.bind_amount_change_event();
|
||||
}
|
||||
|
||||
bind_keyboard_event(){
|
||||
bind_keyboard_event() {
|
||||
var me = this;
|
||||
this.payment_val = '';
|
||||
this.payment_val = "";
|
||||
this.bind_form_control_event();
|
||||
this.bind_numeric_keys_event();
|
||||
}
|
||||
|
||||
bind_form_control_event() {
|
||||
var me = this;
|
||||
$(this.$body).find('.pos-payment-row').click(function() {
|
||||
me.idx = $(this).attr("idx");
|
||||
me.set_outstanding_amount();
|
||||
});
|
||||
$(this.$body)
|
||||
.find(".pos-payment-row")
|
||||
.click(function () {
|
||||
me.idx = $(this).attr("idx");
|
||||
me.set_outstanding_amount();
|
||||
});
|
||||
|
||||
$(this.$body).find('.form-control').click(function() {
|
||||
me.idx = $(this).attr("idx");
|
||||
me.set_outstanding_amount();
|
||||
me.update_paid_amount(true);
|
||||
});
|
||||
$(this.$body)
|
||||
.find(".form-control")
|
||||
.click(function () {
|
||||
me.idx = $(this).attr("idx");
|
||||
me.set_outstanding_amount();
|
||||
me.update_paid_amount(true);
|
||||
});
|
||||
|
||||
$(this.$body).find('.write_off_amount').change(function() {
|
||||
me.write_off_amount(flt($(this).val()), precision("write_off_amount"));
|
||||
});
|
||||
$(this.$body)
|
||||
.find(".write_off_amount")
|
||||
.change(function () {
|
||||
me.write_off_amount(flt($(this).val()), precision("write_off_amount"));
|
||||
});
|
||||
|
||||
$(this.$body).find('.change_amount').change(function() {
|
||||
me.change_amount(flt($(this).val()), precision("change_amount"));
|
||||
});
|
||||
$(this.$body)
|
||||
.find(".change_amount")
|
||||
.change(function () {
|
||||
me.change_amount(flt($(this).val()), precision("change_amount"));
|
||||
});
|
||||
}
|
||||
|
||||
highlight_selected_row() {
|
||||
var selected_row = $(this.$body).find(repl(".pos-payment-row[idx='%(idx)s']", {'idx': this.idx}));
|
||||
$(this.$body).find('.pos-payment-row').removeClass('selected-payment-mode');
|
||||
selected_row.addClass('selected-payment-mode');
|
||||
$(this.$body).find('.amount').attr('disabled', true);
|
||||
this.selected_mode.attr('disabled', false);
|
||||
var selected_row = $(this.$body).find(repl(".pos-payment-row[idx='%(idx)s']", { idx: this.idx }));
|
||||
$(this.$body).find(".pos-payment-row").removeClass("selected-payment-mode");
|
||||
selected_row.addClass("selected-payment-mode");
|
||||
$(this.$body).find(".amount").attr("disabled", true);
|
||||
this.selected_mode.attr("disabled", false);
|
||||
}
|
||||
|
||||
bind_numeric_keys_event() {
|
||||
var me = this;
|
||||
$(this.$body).find('.pos-keyboard-key').click(function(){
|
||||
me.payment_val += $(this).text();
|
||||
me.selected_mode.val(format_currency(me.payment_val, me.frm.doc.currency));
|
||||
me.idx = me.selected_mode.attr("idx");
|
||||
me.update_paid_amount();
|
||||
});
|
||||
|
||||
$(this.$body).find('.delete-btn').click(function() {
|
||||
me.payment_val = cstr(flt(me.selected_mode.val())).slice(0, -1);
|
||||
me.selected_mode.val(format_currency(me.payment_val, me.frm.doc.currency));
|
||||
me.idx = me.selected_mode.attr("idx");
|
||||
me.update_paid_amount();
|
||||
})
|
||||
$(this.$body)
|
||||
.find(".pos-keyboard-key")
|
||||
.click(function () {
|
||||
me.payment_val += $(this).text();
|
||||
me.selected_mode.val(format_currency(me.payment_val, me.frm.doc.currency));
|
||||
me.idx = me.selected_mode.attr("idx");
|
||||
me.update_paid_amount();
|
||||
});
|
||||
|
||||
$(this.$body)
|
||||
.find(".delete-btn")
|
||||
.click(function () {
|
||||
me.payment_val = cstr(flt(me.selected_mode.val())).slice(0, -1);
|
||||
me.selected_mode.val(format_currency(me.payment_val, me.frm.doc.currency));
|
||||
me.idx = me.selected_mode.attr("idx");
|
||||
me.update_paid_amount();
|
||||
});
|
||||
}
|
||||
|
||||
bind_amount_change_event() {
|
||||
var me = this;
|
||||
this.selected_mode.change(function() {
|
||||
me.payment_val = flt($(this).val()) || 0.0;
|
||||
this.selected_mode.change(function () {
|
||||
me.payment_val = flt($(this).val()) || 0.0;
|
||||
me.selected_mode.val(format_currency(me.payment_val, me.frm.doc.currency));
|
||||
me.idx = me.selected_mode.attr("idx");
|
||||
me.update_payment_amount();
|
||||
@@ -167,21 +185,25 @@ erpnext.payments = class payments extends erpnext.stock.StockController {
|
||||
|
||||
clear_amount() {
|
||||
var me = this;
|
||||
$(this.$body).find('.clr').click(function(e) {
|
||||
e.stopPropagation();
|
||||
me.idx = $(this).attr("idx");
|
||||
me.selected_mode = $(me.$body).find(repl("input[idx='%(idx)s']",{'idx': me.idx}));
|
||||
me.payment_val = 0.0;
|
||||
me.selected_mode.val(0.0);
|
||||
me.highlight_selected_row();
|
||||
me.update_payment_amount();
|
||||
});
|
||||
$(this.$body)
|
||||
.find(".clr")
|
||||
.click(function (e) {
|
||||
e.stopPropagation();
|
||||
me.idx = $(this).attr("idx");
|
||||
me.selected_mode = $(me.$body).find(repl("input[idx='%(idx)s']", { idx: me.idx }));
|
||||
me.payment_val = 0.0;
|
||||
me.selected_mode.val(0.0);
|
||||
me.highlight_selected_row();
|
||||
me.update_payment_amount();
|
||||
});
|
||||
}
|
||||
|
||||
write_off_amount(write_off_amount) {
|
||||
this.frm.doc.write_off_amount = flt(write_off_amount, precision("write_off_amount"));
|
||||
this.frm.doc.base_write_off_amount = flt(this.frm.doc.write_off_amount * this.frm.doc.conversion_rate,
|
||||
precision("base_write_off_amount"));
|
||||
this.frm.doc.base_write_off_amount = flt(
|
||||
this.frm.doc.write_off_amount * this.frm.doc.conversion_rate,
|
||||
precision("base_write_off_amount")
|
||||
);
|
||||
this.calculate_outstanding_amount(false);
|
||||
this.show_amounts();
|
||||
}
|
||||
@@ -196,13 +218,16 @@ erpnext.payments = class payments extends erpnext.stock.StockController {
|
||||
|
||||
update_paid_amount(update_write_off) {
|
||||
var me = this;
|
||||
if (in_list(['change_amount', 'write_off_amount'], this.idx)) {
|
||||
if (in_list(["change_amount", "write_off_amount"], this.idx)) {
|
||||
var value = me.selected_mode.val();
|
||||
if (me.idx == 'change_amount') {
|
||||
if (me.idx == "change_amount") {
|
||||
me.change_amount(value);
|
||||
} else {
|
||||
if(flt(value) == 0 && update_write_off && me.frm.doc.outstanding_amount > 0) {
|
||||
value = flt(me.frm.doc.outstanding_amount / me.frm.doc.conversion_rate, precision(me.idx));
|
||||
if (flt(value) == 0 && update_write_off && me.frm.doc.outstanding_amount > 0) {
|
||||
value = flt(
|
||||
me.frm.doc.outstanding_amount / me.frm.doc.conversion_rate,
|
||||
precision(me.idx)
|
||||
);
|
||||
}
|
||||
me.write_off_amount(value);
|
||||
}
|
||||
@@ -211,25 +236,38 @@ erpnext.payments = class payments extends erpnext.stock.StockController {
|
||||
}
|
||||
}
|
||||
|
||||
update_payment_amount(){
|
||||
update_payment_amount() {
|
||||
var me = this;
|
||||
|
||||
$.each(this.frm.doc.payments, function(index, data) {
|
||||
$.each(this.frm.doc.payments, function (index, data) {
|
||||
if (cint(me.idx) == cint(data.idx)) {
|
||||
data.amount = flt(me.selected_mode.val(), 2);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
this.calculate_outstanding_amount(false);
|
||||
this.show_amounts();
|
||||
}
|
||||
|
||||
show_amounts(){
|
||||
show_amounts() {
|
||||
var me = this;
|
||||
$(this.$body).find(".write_off_amount").val(format_currency(this.frm.doc.write_off_amount, this.frm.doc.currency));
|
||||
$(this.$body).find('.paid_amount').text(format_currency(this.frm.doc.paid_amount, this.frm.doc.currency));
|
||||
$(this.$body).find('.change_amount').val(format_currency(this.frm.doc.change_amount, this.frm.doc.currency));
|
||||
$(this.$body).find('.outstanding_amount').text(format_currency(this.frm.doc.outstanding_amount, frappe.get_doc(":Company", this.frm.doc.company).default_currency));
|
||||
$(this.$body)
|
||||
.find(".write_off_amount")
|
||||
.val(format_currency(this.frm.doc.write_off_amount, this.frm.doc.currency));
|
||||
$(this.$body)
|
||||
.find(".paid_amount")
|
||||
.text(format_currency(this.frm.doc.paid_amount, this.frm.doc.currency));
|
||||
$(this.$body)
|
||||
.find(".change_amount")
|
||||
.val(format_currency(this.frm.doc.change_amount, this.frm.doc.currency));
|
||||
$(this.$body)
|
||||
.find(".outstanding_amount")
|
||||
.text(
|
||||
format_currency(
|
||||
this.frm.doc.outstanding_amount,
|
||||
frappe.get_doc(":Company", this.frm.doc.company).default_currency
|
||||
)
|
||||
);
|
||||
this.update_invoice();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class VisualPlantFloor {
|
||||
constructor({wrapper, skip_filters=false, plant_floor=null}, page=null) {
|
||||
constructor({ wrapper, skip_filters = false, plant_floor = null }, page = null) {
|
||||
this.wrapper = wrapper;
|
||||
this.plant_floor = plant_floor;
|
||||
this.skip_filters = skip_filters;
|
||||
@@ -23,67 +23,67 @@ class VisualPlantFloor {
|
||||
`);
|
||||
|
||||
if (!this.skip_filters) {
|
||||
this.filter_wrapper = this.wrapper.find('.plant-floor-filter');
|
||||
this.visualization_wrapper = this.wrapper.find('.plant-floor-visualization');
|
||||
} else if(this.plant_floor) {
|
||||
this.wrapper.find('.plant-floor').css('border', 'none');
|
||||
this.filter_wrapper = this.wrapper.find(".plant-floor-filter");
|
||||
this.visualization_wrapper = this.wrapper.find(".plant-floor-visualization");
|
||||
} else if (this.plant_floor) {
|
||||
this.wrapper.find(".plant-floor").css("border", "none");
|
||||
this.prepare_data();
|
||||
}
|
||||
}
|
||||
|
||||
prepare_data() {
|
||||
frappe.call({
|
||||
method: 'erpnext.manufacturing.doctype.workstation.workstation.get_workstations',
|
||||
method: "erpnext.manufacturing.doctype.workstation.workstation.get_workstations",
|
||||
args: {
|
||||
plant_floor: this.plant_floor,
|
||||
},
|
||||
callback: (r) => {
|
||||
this.workstations = r.message;
|
||||
this.render_workstations();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
add_filter() {
|
||||
this.plant_floor = frappe.ui.form.make_control({
|
||||
df: {
|
||||
fieldtype: 'Link',
|
||||
options: 'Plant Floor',
|
||||
fieldname: 'plant_floor',
|
||||
label: __('Plant Floor'),
|
||||
fieldtype: "Link",
|
||||
options: "Plant Floor",
|
||||
fieldname: "plant_floor",
|
||||
label: __("Plant Floor"),
|
||||
reqd: 1,
|
||||
onchange: () => {
|
||||
this.render_plant_visualization();
|
||||
}
|
||||
},
|
||||
},
|
||||
parent: this.filter_wrapper,
|
||||
render_input: true,
|
||||
});
|
||||
|
||||
this.plant_floor.$wrapper.addClass('form-column col-sm-2');
|
||||
this.plant_floor.$wrapper.addClass("form-column col-sm-2");
|
||||
|
||||
this.workstation_type = frappe.ui.form.make_control({
|
||||
df: {
|
||||
fieldtype: 'Link',
|
||||
options: 'Workstation Type',
|
||||
fieldname: 'workstation_type',
|
||||
label: __('Machine Type'),
|
||||
fieldtype: "Link",
|
||||
options: "Workstation Type",
|
||||
fieldname: "workstation_type",
|
||||
label: __("Machine Type"),
|
||||
onchange: () => {
|
||||
this.render_plant_visualization();
|
||||
}
|
||||
},
|
||||
},
|
||||
parent: this.filter_wrapper,
|
||||
render_input: true,
|
||||
});
|
||||
|
||||
this.workstation_type.$wrapper.addClass('form-column col-sm-2');
|
||||
this.workstation_type.$wrapper.addClass("form-column col-sm-2");
|
||||
|
||||
this.workstation = frappe.ui.form.make_control({
|
||||
df: {
|
||||
fieldtype: 'Link',
|
||||
options: 'Workstation',
|
||||
fieldname: 'workstation',
|
||||
label: __('Machine'),
|
||||
fieldtype: "Link",
|
||||
options: "Workstation",
|
||||
fieldname: "workstation",
|
||||
label: __("Machine"),
|
||||
onchange: () => {
|
||||
this.render_plant_visualization();
|
||||
},
|
||||
@@ -91,24 +91,24 @@ class VisualPlantFloor {
|
||||
if (this.workstation_type.get_value()) {
|
||||
return {
|
||||
filters: {
|
||||
'workstation_type': this.workstation_type.get_value() || ''
|
||||
}
|
||||
}
|
||||
workstation_type: this.workstation_type.get_value() || "",
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
parent: this.filter_wrapper,
|
||||
render_input: true,
|
||||
});
|
||||
|
||||
this.workstation.$wrapper.addClass('form-column col-sm-2');
|
||||
this.workstation.$wrapper.addClass("form-column col-sm-2");
|
||||
|
||||
this.workstation_status = frappe.ui.form.make_control({
|
||||
df: {
|
||||
fieldtype: 'Select',
|
||||
options: '\nProduction\nOff\nIdle\nProblem\nMaintenance\nSetup',
|
||||
fieldname: 'workstation_status',
|
||||
label: __('Status'),
|
||||
fieldtype: "Select",
|
||||
options: "\nProduction\nOff\nIdle\nProblem\nMaintenance\nSetup",
|
||||
fieldname: "workstation_status",
|
||||
label: __("Status"),
|
||||
onchange: () => {
|
||||
this.render_plant_visualization();
|
||||
},
|
||||
@@ -123,35 +123,35 @@ class VisualPlantFloor {
|
||||
|
||||
if (plant_floor) {
|
||||
frappe.call({
|
||||
method: 'erpnext.manufacturing.doctype.workstation.workstation.get_workstations',
|
||||
method: "erpnext.manufacturing.doctype.workstation.workstation.get_workstations",
|
||||
args: {
|
||||
plant_floor: plant_floor,
|
||||
workstation_type: this.workstation_type.get_value(),
|
||||
workstation: this.workstation.get_value(),
|
||||
workstation_status: this.workstation_status.get_value()
|
||||
workstation_status: this.workstation_status.get_value(),
|
||||
},
|
||||
callback: (r) => {
|
||||
this.workstations = r.message;
|
||||
this.render_workstations();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render_workstations() {
|
||||
this.wrapper.find('.plant-floor-container').empty();
|
||||
let template = frappe.render_template("visual_plant_floor_template", {
|
||||
workstations: this.workstations
|
||||
this.wrapper.find(".plant-floor-container").empty();
|
||||
let template = frappe.render_template("visual_plant_floor_template", {
|
||||
workstations: this.workstations,
|
||||
});
|
||||
|
||||
$(template).appendTo(this.wrapper.find('.plant-floor-container'));
|
||||
$(template).appendTo(this.wrapper.find(".plant-floor-container"));
|
||||
}
|
||||
|
||||
prepare_menu() {
|
||||
this.page.add_menu_item(__('Refresh'), () => {
|
||||
this.page.add_menu_item(__("Refresh"), () => {
|
||||
this.render_plant_visualization();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
frappe.ui.VisualPlantFloor = VisualPlantFloor;
|
||||
frappe.ui.VisualPlantFloor = VisualPlantFloor;
|
||||
|
||||
@@ -1,26 +1,30 @@
|
||||
frappe.provide("erpnext.timesheet");
|
||||
|
||||
erpnext.timesheet.timer = function(frm, row, timestamp=0) {
|
||||
erpnext.timesheet.timer = function (frm, row, timestamp = 0) {
|
||||
let dialog = new frappe.ui.Dialog({
|
||||
title: __("Timer"),
|
||||
fields:
|
||||
[
|
||||
{"fieldtype": "Link", "label": __("Activity Type"), "fieldname": "activity_type",
|
||||
"reqd": 1, "options": "Activity Type"},
|
||||
{"fieldtype": "Link", "label": __("Project"), "fieldname": "project", "options": "Project"},
|
||||
{"fieldtype": "Link", "label": __("Task"), "fieldname": "task", "options": "Task"},
|
||||
{"fieldtype": "Float", "label": __("Expected Hrs"), "fieldname": "expected_hours"},
|
||||
{"fieldtype": "Section Break"},
|
||||
{"fieldtype": "HTML", "fieldname": "timer_html"}
|
||||
]
|
||||
fields: [
|
||||
{
|
||||
fieldtype: "Link",
|
||||
label: __("Activity Type"),
|
||||
fieldname: "activity_type",
|
||||
reqd: 1,
|
||||
options: "Activity Type",
|
||||
},
|
||||
{ fieldtype: "Link", label: __("Project"), fieldname: "project", options: "Project" },
|
||||
{ fieldtype: "Link", label: __("Task"), fieldname: "task", options: "Task" },
|
||||
{ fieldtype: "Float", label: __("Expected Hrs"), fieldname: "expected_hours" },
|
||||
{ fieldtype: "Section Break" },
|
||||
{ fieldtype: "HTML", fieldname: "timer_html" },
|
||||
],
|
||||
});
|
||||
|
||||
if (row) {
|
||||
dialog.set_values({
|
||||
'activity_type': row.activity_type,
|
||||
'project': row.project,
|
||||
'task': row.task,
|
||||
'expected_hours': row.expected_hours
|
||||
activity_type: row.activity_type,
|
||||
project: row.project,
|
||||
task: row.task,
|
||||
expected_hours: row.expected_hours,
|
||||
});
|
||||
}
|
||||
dialog.get_field("timer_html").$wrapper.append(get_timer_html());
|
||||
@@ -34,8 +38,8 @@ erpnext.timesheet.timer = function(frm, row, timestamp=0) {
|
||||
<span class="seconds">00</span>
|
||||
</div>
|
||||
<div class="playpause text-center">
|
||||
<button class= "btn btn-primary btn-start"> ${ __("Start") } </button>
|
||||
<button class= "btn btn-primary btn-complete"> ${ __("Complete") } </button>
|
||||
<button class= "btn btn-primary btn-start"> ${__("Start")} </button>
|
||||
<button class= "btn btn-primary btn-complete"> ${__("Complete")} </button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -43,7 +47,7 @@ erpnext.timesheet.timer = function(frm, row, timestamp=0) {
|
||||
dialog.show();
|
||||
};
|
||||
|
||||
erpnext.timesheet.control_timer = function(frm, dialog, row, timestamp=0) {
|
||||
erpnext.timesheet.control_timer = function (frm, dialog, row, timestamp = 0) {
|
||||
var $btn_start = dialog.$wrapper.find(".playpause .btn-start");
|
||||
var $btn_complete = dialog.$wrapper.find(".playpause .btn-complete");
|
||||
var interval = null;
|
||||
@@ -63,12 +67,16 @@ erpnext.timesheet.control_timer = function(frm, dialog, row, timestamp=0) {
|
||||
$btn_complete.hide();
|
||||
}
|
||||
|
||||
$btn_start.click(function(e) {
|
||||
$btn_start.click(function (e) {
|
||||
if (!initialized) {
|
||||
// New activity if no activities found
|
||||
var args = dialog.get_values();
|
||||
if(!args) return;
|
||||
if (frm.doc.time_logs.length == 1 && !frm.doc.time_logs[0].activity_type && !frm.doc.time_logs[0].from_time) {
|
||||
if (!args) return;
|
||||
if (
|
||||
frm.doc.time_logs.length == 1 &&
|
||||
!frm.doc.time_logs[0].activity_type &&
|
||||
!frm.doc.time_logs[0].from_time
|
||||
) {
|
||||
frm.doc.time_logs = [];
|
||||
}
|
||||
row = frappe.model.add_child(frm.doc, "Timesheet Detail", "time_logs");
|
||||
@@ -79,7 +87,7 @@ erpnext.timesheet.control_timer = function(frm, dialog, row, timestamp=0) {
|
||||
row.expected_hours = args.expected_hours;
|
||||
row.completed = 0;
|
||||
let d = moment(row.from_time);
|
||||
if(row.expected_hours) {
|
||||
if (row.expected_hours) {
|
||||
d.add(row.expected_hours, "hours");
|
||||
row.to_time = d.format(frappe.defaultDatetimeFormat);
|
||||
}
|
||||
@@ -101,8 +109,8 @@ erpnext.timesheet.control_timer = function(frm, dialog, row, timestamp=0) {
|
||||
});
|
||||
|
||||
// Stop the timer and update the time logged by the timer on click of 'Complete' button
|
||||
$btn_complete.click(function() {
|
||||
var grid_row = cur_frm.fields_dict['time_logs'].grid.get_row(row.idx - 1);
|
||||
$btn_complete.click(function () {
|
||||
var grid_row = cur_frm.fields_dict["time_logs"].grid.get_row(row.idx - 1);
|
||||
var args = dialog.get_values();
|
||||
grid_row.doc.completed = 1;
|
||||
grid_row.doc.activity_type = args.activity_type;
|
||||
@@ -119,7 +127,7 @@ erpnext.timesheet.control_timer = function(frm, dialog, row, timestamp=0) {
|
||||
});
|
||||
|
||||
function initializeTimer() {
|
||||
interval = setInterval(function() {
|
||||
interval = setInterval(function () {
|
||||
var current = setCurrentIncrement();
|
||||
updateStopwatch(current);
|
||||
}, 1000);
|
||||
@@ -127,25 +135,24 @@ erpnext.timesheet.control_timer = function(frm, dialog, row, timestamp=0) {
|
||||
|
||||
function updateStopwatch(increment) {
|
||||
var hours = Math.floor(increment / 3600);
|
||||
var minutes = Math.floor((increment - (hours * 3600)) / 60);
|
||||
var seconds = increment - (hours * 3600) - (minutes * 60);
|
||||
var minutes = Math.floor((increment - hours * 3600) / 60);
|
||||
var seconds = increment - hours * 3600 - minutes * 60;
|
||||
|
||||
// If modal is closed by clicking anywhere outside, reset the timer
|
||||
if (!$('.modal-dialog').is(':visible')) {
|
||||
if (!$(".modal-dialog").is(":visible")) {
|
||||
reset();
|
||||
}
|
||||
if(hours > 99999)
|
||||
reset();
|
||||
if(cur_dialog && cur_dialog.get_value('expected_hours') > 0) {
|
||||
if(flag && (currentIncrement >= (cur_dialog.get_value('expected_hours') * 3600))) {
|
||||
if (hours > 99999) reset();
|
||||
if (cur_dialog && cur_dialog.get_value("expected_hours") > 0) {
|
||||
if (flag && currentIncrement >= cur_dialog.get_value("expected_hours") * 3600) {
|
||||
frappe.utils.play_sound("alert");
|
||||
frappe.msgprint(__("Timer exceeded the given hours."));
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
$(".hours").text(hours < 10 ? ("0" + hours.toString()) : hours.toString());
|
||||
$(".minutes").text(minutes < 10 ? ("0" + minutes.toString()) : minutes.toString());
|
||||
$(".seconds").text(seconds < 10 ? ("0" + seconds.toString()) : seconds.toString());
|
||||
$(".hours").text(hours < 10 ? "0" + hours.toString() : hours.toString());
|
||||
$(".minutes").text(minutes < 10 ? "0" + minutes.toString() : minutes.toString());
|
||||
$(".seconds").text(seconds < 10 ? "0" + seconds.toString() : seconds.toString());
|
||||
}
|
||||
|
||||
function setCurrentIncrement() {
|
||||
|
||||
@@ -1,71 +1,67 @@
|
||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
erpnext.get_purchase_trends_filters = function() {
|
||||
erpnext.get_purchase_trends_filters = function () {
|
||||
return [
|
||||
{
|
||||
"fieldname":"company",
|
||||
"label": __("Company"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Company",
|
||||
"reqd": 1,
|
||||
"default": frappe.defaults.get_user_default("Company")
|
||||
fieldname: "company",
|
||||
label: __("Company"),
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
reqd: 1,
|
||||
default: frappe.defaults.get_user_default("Company"),
|
||||
},
|
||||
{
|
||||
"fieldname":"period",
|
||||
"label": __("Period"),
|
||||
"fieldtype": "Select",
|
||||
"options": [
|
||||
{ "value": "Monthly", "label": __("Monthly") },
|
||||
{ "value": "Quarterly", "label": __("Quarterly") },
|
||||
{ "value": "Half-Yearly", "label": __("Half-Yearly") },
|
||||
{ "value": "Yearly", "label": __("Yearly") }
|
||||
fieldname: "period",
|
||||
label: __("Period"),
|
||||
fieldtype: "Select",
|
||||
options: [
|
||||
{ value: "Monthly", label: __("Monthly") },
|
||||
{ value: "Quarterly", label: __("Quarterly") },
|
||||
{ value: "Half-Yearly", label: __("Half-Yearly") },
|
||||
{ value: "Yearly", label: __("Yearly") },
|
||||
],
|
||||
"default": "Monthly"
|
||||
default: "Monthly",
|
||||
},
|
||||
{
|
||||
"fieldname":"fiscal_year",
|
||||
"label": __("Fiscal Year"),
|
||||
"fieldtype": "Link",
|
||||
"options":'Fiscal Year',
|
||||
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today())
|
||||
fieldname: "fiscal_year",
|
||||
label: __("Fiscal Year"),
|
||||
fieldtype: "Link",
|
||||
options: "Fiscal Year",
|
||||
default: erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||
},
|
||||
{
|
||||
"fieldname":"period_based_on",
|
||||
"label": __("Period based On"),
|
||||
"fieldtype": "Select",
|
||||
"options": [
|
||||
{ "value": "posting_date", "label": __("Posting Date") },
|
||||
{ "value": "bill_date", "label": __("Billing Date") },
|
||||
fieldname: "period_based_on",
|
||||
label: __("Period based On"),
|
||||
fieldtype: "Select",
|
||||
options: [
|
||||
{ value: "posting_date", label: __("Posting Date") },
|
||||
{ value: "bill_date", label: __("Billing Date") },
|
||||
],
|
||||
"default": "posting_date"
|
||||
default: "posting_date",
|
||||
},
|
||||
{
|
||||
"fieldname":"based_on",
|
||||
"label": __("Based On"),
|
||||
"fieldtype": "Select",
|
||||
"options": [
|
||||
{ "value": "Item", "label": __("Item") },
|
||||
{ "value": "Item Group", "label": __("Item Group") },
|
||||
{ "value": "Supplier", "label": __("Supplier") },
|
||||
{ "value": "Supplier Group", "label": __("Supplier Group") },
|
||||
{ "value": "Project", "label": __("Project") }
|
||||
fieldname: "based_on",
|
||||
label: __("Based On"),
|
||||
fieldtype: "Select",
|
||||
options: [
|
||||
{ value: "Item", label: __("Item") },
|
||||
{ value: "Item Group", label: __("Item Group") },
|
||||
{ value: "Supplier", label: __("Supplier") },
|
||||
{ value: "Supplier Group", label: __("Supplier Group") },
|
||||
{ value: "Project", label: __("Project") },
|
||||
],
|
||||
"default": "Item",
|
||||
"dashboard_config": {
|
||||
"read_only": 1
|
||||
}
|
||||
default: "Item",
|
||||
dashboard_config: {
|
||||
read_only: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname":"group_by",
|
||||
"label": __("Group By"),
|
||||
"fieldtype": "Select",
|
||||
"options": [
|
||||
"",
|
||||
{ "value": "Item", "label": __("Item") },
|
||||
{ "value": "Supplier", "label": __("Supplier") }
|
||||
],
|
||||
"default": ""
|
||||
fieldname: "group_by",
|
||||
label: __("Group By"),
|
||||
fieldtype: "Select",
|
||||
options: ["", { value: "Item", label: __("Item") }, { value: "Supplier", label: __("Supplier") }],
|
||||
default: "",
|
||||
},
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,129 +4,139 @@
|
||||
// searches for enabled users
|
||||
frappe.provide("erpnext.queries");
|
||||
$.extend(erpnext.queries, {
|
||||
user: function() {
|
||||
user: function () {
|
||||
return { query: "frappe.core.doctype.user.user.user_query" };
|
||||
},
|
||||
|
||||
lead: function() {
|
||||
lead: function () {
|
||||
return { query: "erpnext.controllers.queries.lead_query" };
|
||||
},
|
||||
|
||||
customer: function() {
|
||||
customer: function () {
|
||||
return { query: "erpnext.controllers.queries.customer_query" };
|
||||
},
|
||||
|
||||
supplier: function() {
|
||||
supplier: function () {
|
||||
return { query: "erpnext.controllers.queries.supplier_query" };
|
||||
},
|
||||
|
||||
item: function(filters) {
|
||||
item: function (filters) {
|
||||
var args = { query: "erpnext.controllers.queries.item_query" };
|
||||
if(filters) args["filters"] = filters;
|
||||
if (filters) args["filters"] = filters;
|
||||
return args;
|
||||
},
|
||||
|
||||
bom: function() {
|
||||
bom: function () {
|
||||
return { query: "erpnext.controllers.queries.bom" };
|
||||
},
|
||||
|
||||
task: function() {
|
||||
task: function () {
|
||||
return { query: "erpnext.projects.utils.query_task" };
|
||||
},
|
||||
|
||||
customer_filter: function(doc) {
|
||||
if(!doc.customer) {
|
||||
frappe.throw(__("Please set {0}", [__(frappe.meta.get_label(doc.doctype, "customer", doc.name))]));
|
||||
customer_filter: function (doc) {
|
||||
if (!doc.customer) {
|
||||
frappe.throw(
|
||||
__("Please set {0}", [__(frappe.meta.get_label(doc.doctype, "customer", doc.name))])
|
||||
);
|
||||
}
|
||||
|
||||
return { filters: { customer: doc.customer } };
|
||||
},
|
||||
|
||||
contact_query: function(doc) {
|
||||
if(frappe.dynamic_link) {
|
||||
if(!doc[frappe.dynamic_link.fieldname]) {
|
||||
frappe.throw(__("Please set {0}",
|
||||
[__(frappe.meta.get_label(doc.doctype, frappe.dynamic_link.fieldname, doc.name))]));
|
||||
contact_query: function (doc) {
|
||||
if (frappe.dynamic_link) {
|
||||
if (!doc[frappe.dynamic_link.fieldname]) {
|
||||
frappe.throw(
|
||||
__("Please set {0}", [
|
||||
__(frappe.meta.get_label(doc.doctype, frappe.dynamic_link.fieldname, doc.name)),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
query: 'frappe.contacts.doctype.contact.contact.contact_query',
|
||||
query: "frappe.contacts.doctype.contact.contact.contact_query",
|
||||
filters: {
|
||||
link_doctype: frappe.dynamic_link.doctype,
|
||||
link_name: doc[frappe.dynamic_link.fieldname]
|
||||
}
|
||||
link_name: doc[frappe.dynamic_link.fieldname],
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
address_query: function(doc) {
|
||||
if(frappe.dynamic_link) {
|
||||
if(!doc[frappe.dynamic_link.fieldname]) {
|
||||
frappe.throw(__("Please set {0}",
|
||||
[__(frappe.meta.get_label(doc.doctype, frappe.dynamic_link.fieldname, doc.name))]));
|
||||
address_query: function (doc) {
|
||||
if (frappe.dynamic_link) {
|
||||
if (!doc[frappe.dynamic_link.fieldname]) {
|
||||
frappe.throw(
|
||||
__("Please set {0}", [
|
||||
__(frappe.meta.get_label(doc.doctype, frappe.dynamic_link.fieldname, doc.name)),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
query: 'frappe.contacts.doctype.address.address.address_query',
|
||||
query: "frappe.contacts.doctype.address.address.address_query",
|
||||
filters: {
|
||||
link_doctype: frappe.dynamic_link.doctype,
|
||||
link_name: doc[frappe.dynamic_link.fieldname]
|
||||
}
|
||||
link_name: doc[frappe.dynamic_link.fieldname],
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
company_address_query: function(doc) {
|
||||
company_address_query: function (doc) {
|
||||
return {
|
||||
query: 'frappe.contacts.doctype.address.address.address_query',
|
||||
filters: { is_your_company_address: 1, link_doctype: 'Company', link_name: doc.company || '' }
|
||||
query: "frappe.contacts.doctype.address.address.address_query",
|
||||
filters: { is_your_company_address: 1, link_doctype: "Company", link_name: doc.company || "" },
|
||||
};
|
||||
},
|
||||
|
||||
dispatch_address_query: function(doc) {
|
||||
dispatch_address_query: function (doc) {
|
||||
return {
|
||||
query: 'frappe.contacts.doctype.address.address.address_query',
|
||||
filters: { link_doctype: 'Company', link_name: doc.company || '' }
|
||||
query: "frappe.contacts.doctype.address.address.address_query",
|
||||
filters: { link_doctype: "Company", link_name: doc.company || "" },
|
||||
};
|
||||
},
|
||||
|
||||
supplier_filter: function(doc) {
|
||||
if(!doc.supplier) {
|
||||
frappe.throw(__("Please set {0}", [__(frappe.meta.get_label(doc.doctype, "supplier", doc.name))]));
|
||||
supplier_filter: function (doc) {
|
||||
if (!doc.supplier) {
|
||||
frappe.throw(
|
||||
__("Please set {0}", [__(frappe.meta.get_label(doc.doctype, "supplier", doc.name))])
|
||||
);
|
||||
}
|
||||
|
||||
return { filters: { supplier: doc.supplier } };
|
||||
},
|
||||
|
||||
lead_filter: function(doc) {
|
||||
if(!doc.lead) {
|
||||
frappe.throw(__("Please specify a {0}",
|
||||
[__(frappe.meta.get_label(doc.doctype, "lead", doc.name))]));
|
||||
lead_filter: function (doc) {
|
||||
if (!doc.lead) {
|
||||
frappe.throw(
|
||||
__("Please specify a {0}", [__(frappe.meta.get_label(doc.doctype, "lead", doc.name))])
|
||||
);
|
||||
}
|
||||
|
||||
return { filters: { lead: doc.lead } };
|
||||
},
|
||||
|
||||
not_a_group_filter: function() {
|
||||
not_a_group_filter: function () {
|
||||
return { filters: { is_group: 0 } };
|
||||
},
|
||||
|
||||
employee: function() {
|
||||
return { query: "erpnext.controllers.queries.employee_query" }
|
||||
employee: function () {
|
||||
return { query: "erpnext.controllers.queries.employee_query" };
|
||||
},
|
||||
|
||||
warehouse: function(doc) {
|
||||
warehouse: function (doc) {
|
||||
return {
|
||||
filters: [
|
||||
["Warehouse", "company", "in", ["", cstr(doc.company)]],
|
||||
["Warehouse", "is_group", "=",0]
|
||||
|
||||
]
|
||||
["Warehouse", "is_group", "=", 0],
|
||||
],
|
||||
};
|
||||
},
|
||||
|
||||
get_filtered_dimensions: function(doc, child_fields, dimension, company) {
|
||||
let account = '';
|
||||
get_filtered_dimensions: function (doc, child_fields, dimension, company) {
|
||||
let account = "";
|
||||
|
||||
child_fields.forEach((field) => {
|
||||
if (!account) {
|
||||
@@ -137,21 +147,23 @@ $.extend(erpnext.queries, {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.get_filtered_dimensions",
|
||||
filters: {
|
||||
'dimension': dimension,
|
||||
'account': account,
|
||||
'company': company
|
||||
}
|
||||
dimension: dimension,
|
||||
account: account,
|
||||
company: company,
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
erpnext.queries.setup_queries = function(frm, options, query_fn) {
|
||||
erpnext.queries.setup_queries = function (frm, options, query_fn) {
|
||||
var me = this;
|
||||
var set_query = function(doctype, parentfield) {
|
||||
var link_fields = frappe.meta.get_docfields(doctype, frm.doc.name,
|
||||
{"fieldtype": "Link", "options": options});
|
||||
$.each(link_fields, function(i, df) {
|
||||
if(parentfield) {
|
||||
var set_query = function (doctype, parentfield) {
|
||||
var link_fields = frappe.meta.get_docfields(doctype, frm.doc.name, {
|
||||
fieldtype: "Link",
|
||||
options: options,
|
||||
});
|
||||
$.each(link_fields, function (i, df) {
|
||||
if (parentfield) {
|
||||
frm.set_query(df.fieldname, parentfield, query_fn);
|
||||
} else {
|
||||
frm.set_query(df.fieldname, query_fn);
|
||||
@@ -162,24 +174,26 @@ erpnext.queries.setup_queries = function(frm, options, query_fn) {
|
||||
set_query(frm.doc.doctype);
|
||||
|
||||
// warehouse field in tables
|
||||
$.each(frappe.meta.get_docfields(frm.doc.doctype, frm.doc.name, {"fieldtype": "Table"}),
|
||||
function(i, df) {
|
||||
$.each(
|
||||
frappe.meta.get_docfields(frm.doc.doctype, frm.doc.name, { fieldtype: "Table" }),
|
||||
function (i, df) {
|
||||
set_query(df.options, df.fieldname);
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/* if item code is selected in child table
|
||||
then list down warehouses with its quantity
|
||||
else apply default filters.
|
||||
*/
|
||||
erpnext.queries.setup_warehouse_query = function(frm){
|
||||
frm.set_query('warehouse', 'items', function(doc, cdt, cdn) {
|
||||
var row = locals[cdt][cdn];
|
||||
erpnext.queries.setup_warehouse_query = function (frm) {
|
||||
frm.set_query("warehouse", "items", function (doc, cdt, cdn) {
|
||||
var row = locals[cdt][cdn];
|
||||
var filters = erpnext.queries.warehouse(frm.doc);
|
||||
if(row.item_code){
|
||||
$.extend(filters, {"query":"erpnext.controllers.queries.warehouse_query"});
|
||||
if (row.item_code) {
|
||||
$.extend(filters, { query: "erpnext.controllers.queries.warehouse_query" });
|
||||
filters["filters"].push(["Bin", "item_code", "=", row.item_code]);
|
||||
}
|
||||
return filters
|
||||
return filters;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,61 +1,57 @@
|
||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
erpnext.get_sales_trends_filters = function() {
|
||||
return[
|
||||
erpnext.get_sales_trends_filters = function () {
|
||||
return [
|
||||
{
|
||||
"fieldname":"period",
|
||||
"label": __("Period"),
|
||||
"fieldtype": "Select",
|
||||
"options": [
|
||||
{ "value": "Monthly", "label": __("Monthly") },
|
||||
{ "value": "Quarterly", "label": __("Quarterly") },
|
||||
{ "value": "Half-Yearly", "label": __("Half-Yearly") },
|
||||
{ "value": "Yearly", "label": __("Yearly") }
|
||||
fieldname: "period",
|
||||
label: __("Period"),
|
||||
fieldtype: "Select",
|
||||
options: [
|
||||
{ value: "Monthly", label: __("Monthly") },
|
||||
{ value: "Quarterly", label: __("Quarterly") },
|
||||
{ value: "Half-Yearly", label: __("Half-Yearly") },
|
||||
{ value: "Yearly", label: __("Yearly") },
|
||||
],
|
||||
"default": "Monthly"
|
||||
default: "Monthly",
|
||||
},
|
||||
{
|
||||
"fieldname":"based_on",
|
||||
"label": __("Based On"),
|
||||
"fieldtype": "Select",
|
||||
"options": [
|
||||
{ "value": "Item", "label": __("Item") },
|
||||
{ "value": "Item Group", "label": __("Item Group") },
|
||||
{ "value": "Customer", "label": __("Customer") },
|
||||
{ "value": "Customer Group", "label": __("Customer Group") },
|
||||
{ "value": "Territory", "label": __("Territory") },
|
||||
{ "value": "Project", "label": __("Project") }
|
||||
fieldname: "based_on",
|
||||
label: __("Based On"),
|
||||
fieldtype: "Select",
|
||||
options: [
|
||||
{ value: "Item", label: __("Item") },
|
||||
{ value: "Item Group", label: __("Item Group") },
|
||||
{ value: "Customer", label: __("Customer") },
|
||||
{ value: "Customer Group", label: __("Customer Group") },
|
||||
{ value: "Territory", label: __("Territory") },
|
||||
{ value: "Project", label: __("Project") },
|
||||
],
|
||||
"default": "Item",
|
||||
"dashboard_config": {
|
||||
"read_only": 1,
|
||||
}
|
||||
default: "Item",
|
||||
dashboard_config: {
|
||||
read_only: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
"fieldname":"group_by",
|
||||
"label": __("Group By"),
|
||||
"fieldtype": "Select",
|
||||
"options": [
|
||||
"",
|
||||
{ "value": "Item", "label": __("Item") },
|
||||
{ "value": "Customer", "label": __("Customer") }
|
||||
],
|
||||
"default": ""
|
||||
fieldname: "group_by",
|
||||
label: __("Group By"),
|
||||
fieldtype: "Select",
|
||||
options: ["", { value: "Item", label: __("Item") }, { value: "Customer", label: __("Customer") }],
|
||||
default: "",
|
||||
},
|
||||
{
|
||||
"fieldname":"fiscal_year",
|
||||
"label": __("Fiscal Year"),
|
||||
"fieldtype": "Link",
|
||||
"options":'Fiscal Year',
|
||||
"default": erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||
fieldname: "fiscal_year",
|
||||
label: __("Fiscal Year"),
|
||||
fieldtype: "Link",
|
||||
options: "Fiscal Year",
|
||||
default: erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
|
||||
},
|
||||
{
|
||||
"fieldname":"company",
|
||||
"label": __("Company"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Company",
|
||||
"default": frappe.defaults.get_user_default("Company")
|
||||
fieldname: "company",
|
||||
label: __("Company"),
|
||||
fieldtype: "Link",
|
||||
options: "Company",
|
||||
default: frappe.defaults.get_user_default("Company"),
|
||||
},
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
frappe.provide("erpnext.setup");
|
||||
|
||||
frappe.pages['setup-wizard'].on_page_load = function(wrapper) {
|
||||
if(frappe.sys_defaults.company) {
|
||||
frappe.pages["setup-wizard"].on_page_load = function (wrapper) {
|
||||
if (frappe.sys_defaults.company) {
|
||||
frappe.set_route("desk");
|
||||
return;
|
||||
}
|
||||
@@ -14,38 +14,42 @@ frappe.setup.on("before_load", function () {
|
||||
erpnext.setup.slides_settings = [
|
||||
{
|
||||
// Organization
|
||||
name: 'organization',
|
||||
name: "organization",
|
||||
title: __("Setup your organization"),
|
||||
icon: "fa fa-building",
|
||||
fields: [
|
||||
{
|
||||
fieldname: 'company_name',
|
||||
label: __('Company Name'),
|
||||
fieldtype: 'Data',
|
||||
reqd: 1
|
||||
fieldname: "company_name",
|
||||
label: __("Company Name"),
|
||||
fieldtype: "Data",
|
||||
reqd: 1,
|
||||
},
|
||||
{ fieldtype: "Column Break" },
|
||||
{
|
||||
fieldname: 'company_abbr',
|
||||
label: __('Company Abbreviation'),
|
||||
fieldtype: 'Data',
|
||||
reqd: 1
|
||||
fieldname: "company_abbr",
|
||||
label: __("Company Abbreviation"),
|
||||
fieldtype: "Data",
|
||||
reqd: 1,
|
||||
},
|
||||
{ fieldtype: "Section Break" },
|
||||
{
|
||||
fieldname: 'chart_of_accounts', label: __('Chart of Accounts'),
|
||||
options: "", fieldtype: 'Select'
|
||||
fieldname: "chart_of_accounts",
|
||||
label: __("Chart of Accounts"),
|
||||
options: "",
|
||||
fieldtype: "Select",
|
||||
},
|
||||
{ fieldname: 'view_coa', label: __('View Chart of Accounts'), fieldtype: 'Button' },
|
||||
{ fieldname: 'fy_start_date', label: __('Financial Year Begins On'), fieldtype: 'Date', reqd: 1 },
|
||||
{ fieldname: "view_coa", label: __("View Chart of Accounts"), fieldtype: "Button" },
|
||||
{ fieldname: "fy_start_date", label: __("Financial Year Begins On"), fieldtype: "Date", reqd: 1 },
|
||||
// end date should be hidden (auto calculated)
|
||||
{ fieldname: 'fy_end_date', label: __('End Date'), fieldtype: 'Date', reqd: 1, hidden: 1 },
|
||||
{ fieldname: "fy_end_date", label: __("End Date"), fieldtype: "Date", reqd: 1, hidden: 1 },
|
||||
{ fieldtype: "Section Break" },
|
||||
{
|
||||
fieldname: 'setup_demo',
|
||||
label: __('Generate Demo Data for Exploration'),
|
||||
fieldtype: 'Check',
|
||||
description: __('If checked, we will create demo data for you to explore the system. This demo data can be erased later.')
|
||||
fieldname: "setup_demo",
|
||||
label: __("Generate Demo Data for Exploration"),
|
||||
fieldtype: "Check",
|
||||
description: __(
|
||||
"If checked, we will create demo data for you to explore the system. This demo data can be erased later."
|
||||
),
|
||||
},
|
||||
],
|
||||
|
||||
@@ -73,10 +77,10 @@ erpnext.setup.slides_settings = [
|
||||
return true;
|
||||
},
|
||||
|
||||
validate_fy_dates: function() {
|
||||
validate_fy_dates: function () {
|
||||
// validate fiscal year start and end dates
|
||||
const invalid = this.values.fy_start_date == 'Invalid date' ||
|
||||
this.values.fy_end_date == 'Invalid date';
|
||||
const invalid =
|
||||
this.values.fy_start_date == "Invalid date" || this.values.fy_end_date == "Invalid date";
|
||||
const start_greater_than_end = this.values.fy_start_date > this.values.fy_end_date;
|
||||
|
||||
if (invalid || start_greater_than_end) {
|
||||
@@ -104,26 +108,24 @@ erpnext.setup.slides_settings = [
|
||||
next_year = current_year;
|
||||
current_year -= 1;
|
||||
}
|
||||
slide.get_field("fy_start_date").set_value(current_year + '-' + fy[0]);
|
||||
slide.get_field("fy_end_date").set_value(next_year + '-' + fy[1]);
|
||||
slide.get_field("fy_start_date").set_value(current_year + "-" + fy[0]);
|
||||
slide.get_field("fy_end_date").set_value(next_year + "-" + fy[1]);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
load_chart_of_accounts: function (slide) {
|
||||
let country = frappe.wizard.values.country;
|
||||
|
||||
if (country) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts.get_charts_for_country",
|
||||
args: { "country": country, with_standard: true },
|
||||
args: { country: country, with_standard: true },
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
slide.get_input("chart_of_accounts").empty()
|
||||
.add_options(r.message);
|
||||
slide.get_input("chart_of_accounts").empty().add_options(r.message);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -131,56 +133,74 @@ erpnext.setup.slides_settings = [
|
||||
let me = this;
|
||||
slide.get_input("fy_start_date").on("change", function () {
|
||||
var start_date = slide.form.fields_dict.fy_start_date.get_value();
|
||||
var year_end_date =
|
||||
frappe.datetime.add_days(frappe.datetime.add_months(start_date, 12), -1);
|
||||
var year_end_date = frappe.datetime.add_days(frappe.datetime.add_months(start_date, 12), -1);
|
||||
slide.form.fields_dict.fy_end_date.set_value(year_end_date);
|
||||
});
|
||||
|
||||
slide.get_input("view_coa").on("click", function() {
|
||||
slide.get_input("view_coa").on("click", function () {
|
||||
let chart_template = slide.form.fields_dict.chart_of_accounts.get_value();
|
||||
if(!chart_template) return;
|
||||
if (!chart_template) return;
|
||||
|
||||
me.charts_modal(slide, chart_template);
|
||||
});
|
||||
|
||||
slide.get_input("company_name").on("input", function () {
|
||||
let parts = slide.get_input("company_name").val().split(" ");
|
||||
let abbr = $.map(parts, function (p) { return p ? p.substr(0, 1) : null }).join("");
|
||||
slide.get_field("company_abbr").set_value(abbr.slice(0, 10).toUpperCase());
|
||||
}).val(frappe.boot.sysdefaults.company_name || "").trigger("change");
|
||||
slide
|
||||
.get_input("company_name")
|
||||
.on("input", function () {
|
||||
let parts = slide.get_input("company_name").val().split(" ");
|
||||
let abbr = $.map(parts, function (p) {
|
||||
return p ? p.substr(0, 1) : null;
|
||||
}).join("");
|
||||
slide.get_field("company_abbr").set_value(abbr.slice(0, 10).toUpperCase());
|
||||
})
|
||||
.val(frappe.boot.sysdefaults.company_name || "")
|
||||
.trigger("change");
|
||||
|
||||
slide.get_input("company_abbr").on("change", function () {
|
||||
let abbr = slide.get_input("company_abbr").val();
|
||||
if (abbr.length > 10) {
|
||||
frappe.msgprint(__("Company Abbreviation cannot have more than 5 characters"));
|
||||
abbr = abbr.slice(0, 10);
|
||||
}
|
||||
slide.get_field("company_abbr").set_value(abbr);
|
||||
}).val(frappe.boot.sysdefaults.company_abbr || "").trigger("change");
|
||||
slide
|
||||
.get_input("company_abbr")
|
||||
.on("change", function () {
|
||||
let abbr = slide.get_input("company_abbr").val();
|
||||
if (abbr.length > 10) {
|
||||
frappe.msgprint(__("Company Abbreviation cannot have more than 5 characters"));
|
||||
abbr = abbr.slice(0, 10);
|
||||
}
|
||||
slide.get_field("company_abbr").set_value(abbr);
|
||||
})
|
||||
.val(frappe.boot.sysdefaults.company_abbr || "")
|
||||
.trigger("change");
|
||||
},
|
||||
|
||||
charts_modal: function(slide, chart_template) {
|
||||
let parent = __('All Accounts');
|
||||
charts_modal: function (slide, chart_template) {
|
||||
let parent = __("All Accounts");
|
||||
|
||||
let dialog = new frappe.ui.Dialog({
|
||||
title: chart_template,
|
||||
fields: [
|
||||
{'fieldname': 'expand_all', 'label': __('Expand All'), 'fieldtype': 'Button',
|
||||
click: function() {
|
||||
{
|
||||
fieldname: "expand_all",
|
||||
label: __("Expand All"),
|
||||
fieldtype: "Button",
|
||||
click: function () {
|
||||
// expand all nodes on button click
|
||||
coa_tree.load_children(coa_tree.root_node, true);
|
||||
}
|
||||
},
|
||||
},
|
||||
{'fieldname': 'collapse_all', 'label': __('Collapse All'), 'fieldtype': 'Button',
|
||||
click: function() {
|
||||
{
|
||||
fieldname: "collapse_all",
|
||||
label: __("Collapse All"),
|
||||
fieldtype: "Button",
|
||||
click: function () {
|
||||
// collapse all nodes
|
||||
coa_tree.get_all_nodes(coa_tree.root_node.data.value, coa_tree.root_node.is_root)
|
||||
.then(data_list => {
|
||||
data_list.map(d => { coa_tree.toggle_node(coa_tree.nodes[d.parent]); });
|
||||
coa_tree
|
||||
.get_all_nodes(coa_tree.root_node.data.value, coa_tree.root_node.is_root)
|
||||
.then((data_list) => {
|
||||
data_list.map((d) => {
|
||||
coa_tree.toggle_node(coa_tree.nodes[d.parent]);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// render tree structure in the dialog modal
|
||||
@@ -188,49 +208,49 @@ erpnext.setup.slides_settings = [
|
||||
parent: $(dialog.body),
|
||||
label: parent,
|
||||
expandable: true,
|
||||
method: 'erpnext.accounts.utils.get_coa',
|
||||
method: "erpnext.accounts.utils.get_coa",
|
||||
args: {
|
||||
chart: chart_template,
|
||||
parent: parent,
|
||||
doctype: 'Account'
|
||||
doctype: "Account",
|
||||
},
|
||||
onclick: function(node) {
|
||||
onclick: function (node) {
|
||||
parent = node.value;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// add class to show buttons side by side
|
||||
const form_container = $(dialog.body).find('form');
|
||||
const buttons = $(form_container).find('.frappe-control');
|
||||
form_container.addClass('flex');
|
||||
const form_container = $(dialog.body).find("form");
|
||||
const buttons = $(form_container).find(".frappe-control");
|
||||
form_container.addClass("flex");
|
||||
buttons.map((index, button) => {
|
||||
$(button).css({"margin-right": "1em"});
|
||||
})
|
||||
$(button).css({ "margin-right": "1em" });
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
coa_tree.load_children(coa_tree.root_node, true); // expand all node trigger
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
// Source: https://en.wikipedia.org/wiki/Fiscal_year
|
||||
// default 1st Jan - 31st Dec
|
||||
|
||||
erpnext.setup.fiscal_years = {
|
||||
"Afghanistan": ["12-21", "12-20"],
|
||||
"Australia": ["07-01", "06-30"],
|
||||
"Bangladesh": ["07-01", "06-30"],
|
||||
"Canada": ["04-01", "03-31"],
|
||||
Afghanistan: ["12-21", "12-20"],
|
||||
Australia: ["07-01", "06-30"],
|
||||
Bangladesh: ["07-01", "06-30"],
|
||||
Canada: ["04-01", "03-31"],
|
||||
"Costa Rica": ["10-01", "09-30"],
|
||||
"Egypt": ["07-01", "06-30"],
|
||||
Egypt: ["07-01", "06-30"],
|
||||
"Hong Kong": ["04-01", "03-31"],
|
||||
"India": ["04-01", "03-31"],
|
||||
"Iran": ["06-23", "06-22"],
|
||||
"Myanmar": ["04-01", "03-31"],
|
||||
India: ["04-01", "03-31"],
|
||||
Iran: ["06-23", "06-22"],
|
||||
Myanmar: ["04-01", "03-31"],
|
||||
"New Zealand": ["04-01", "03-31"],
|
||||
"Pakistan": ["07-01", "06-30"],
|
||||
"Singapore": ["04-01", "03-31"],
|
||||
Pakistan: ["07-01", "06-30"],
|
||||
Singapore: ["04-01", "03-31"],
|
||||
"South Africa": ["03-01", "02-28"],
|
||||
"Thailand": ["10-01", "09-30"],
|
||||
Thailand: ["10-01", "09-30"],
|
||||
"United Kingdom": ["04-01", "03-31"],
|
||||
};
|
||||
|
||||
@@ -3,104 +3,114 @@
|
||||
|
||||
erpnext.SMSManager = function SMSManager(doc) {
|
||||
var me = this;
|
||||
this.setup = function() {
|
||||
this.setup = function () {
|
||||
var default_msg = {
|
||||
'Lead' : '',
|
||||
'Opportunity' : 'Your enquiry has been logged into the system. Ref No: ' + doc.name,
|
||||
'Quotation' : 'Quotation ' + doc.name + ' has been sent via email. Thanks!',
|
||||
'Sales Order' : 'Sales Order ' + doc.name + ' has been created against '
|
||||
+ (doc.quotation_no ? ('Quote No:' + doc.quotation_no) : '')
|
||||
+ (doc.po_no ? (' for your PO: ' + doc.po_no) : ''),
|
||||
'Delivery Note' : 'Items has been delivered against delivery note: ' + doc.name
|
||||
+ (doc.po_no ? (' for your PO: ' + doc.po_no) : ''),
|
||||
'Sales Invoice': 'Invoice ' + doc.name + ' has been sent via email '
|
||||
+ (doc.po_no ? (' for your PO: ' + doc.po_no) : ''),
|
||||
'Material Request' : 'Material Request ' + doc.name + ' has been raised in the system',
|
||||
'Purchase Order' : 'Purchase Order ' + doc.name + ' has been sent via email',
|
||||
'Purchase Receipt' : 'Items has been received against purchase receipt: ' + doc.name
|
||||
}
|
||||
|
||||
if (in_list(['Sales Order', 'Delivery Note', 'Sales Invoice'], doc.doctype))
|
||||
this.show(doc.contact_person, 'Customer', doc.customer, '', default_msg[doc.doctype]);
|
||||
else if (doc.doctype === 'Quotation')
|
||||
this.show(doc.contact_person, 'Customer', doc.party_name, '', default_msg[doc.doctype]);
|
||||
else if (in_list(['Purchase Order', 'Purchase Receipt'], doc.doctype))
|
||||
this.show(doc.contact_person, 'Supplier', doc.supplier, '', default_msg[doc.doctype]);
|
||||
else if (doc.doctype == 'Lead')
|
||||
this.show('', '', '', doc.mobile_no, default_msg[doc.doctype]);
|
||||
else if (doc.doctype == 'Opportunity')
|
||||
this.show('', '', '', doc.contact_no, default_msg[doc.doctype]);
|
||||
else if (doc.doctype == 'Material Request')
|
||||
this.show('', '', '', '', default_msg[doc.doctype]);
|
||||
Lead: "",
|
||||
Opportunity: "Your enquiry has been logged into the system. Ref No: " + doc.name,
|
||||
Quotation: "Quotation " + doc.name + " has been sent via email. Thanks!",
|
||||
"Sales Order":
|
||||
"Sales Order " +
|
||||
doc.name +
|
||||
" has been created against " +
|
||||
(doc.quotation_no ? "Quote No:" + doc.quotation_no : "") +
|
||||
(doc.po_no ? " for your PO: " + doc.po_no : ""),
|
||||
"Delivery Note":
|
||||
"Items has been delivered against delivery note: " +
|
||||
doc.name +
|
||||
(doc.po_no ? " for your PO: " + doc.po_no : ""),
|
||||
"Sales Invoice":
|
||||
"Invoice " +
|
||||
doc.name +
|
||||
" has been sent via email " +
|
||||
(doc.po_no ? " for your PO: " + doc.po_no : ""),
|
||||
"Material Request": "Material Request " + doc.name + " has been raised in the system",
|
||||
"Purchase Order": "Purchase Order " + doc.name + " has been sent via email",
|
||||
"Purchase Receipt": "Items has been received against purchase receipt: " + doc.name,
|
||||
};
|
||||
|
||||
if (in_list(["Sales Order", "Delivery Note", "Sales Invoice"], doc.doctype))
|
||||
this.show(doc.contact_person, "Customer", doc.customer, "", default_msg[doc.doctype]);
|
||||
else if (doc.doctype === "Quotation")
|
||||
this.show(doc.contact_person, "Customer", doc.party_name, "", default_msg[doc.doctype]);
|
||||
else if (in_list(["Purchase Order", "Purchase Receipt"], doc.doctype))
|
||||
this.show(doc.contact_person, "Supplier", doc.supplier, "", default_msg[doc.doctype]);
|
||||
else if (doc.doctype == "Lead") this.show("", "", "", doc.mobile_no, default_msg[doc.doctype]);
|
||||
else if (doc.doctype == "Opportunity")
|
||||
this.show("", "", "", doc.contact_no, default_msg[doc.doctype]);
|
||||
else if (doc.doctype == "Material Request") this.show("", "", "", "", default_msg[doc.doctype]);
|
||||
};
|
||||
|
||||
this.get_contact_number = function(contact, ref_doctype, ref_name) {
|
||||
this.get_contact_number = function (contact, ref_doctype, ref_name) {
|
||||
frappe.call({
|
||||
method: "frappe.core.doctype.sms_settings.sms_settings.get_contact_number",
|
||||
args: {
|
||||
contact_name: contact,
|
||||
ref_doctype: ref_doctype,
|
||||
ref_name: ref_name
|
||||
ref_name: ref_name,
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.exc) { frappe.msgprint(r.exc); return; }
|
||||
callback: function (r) {
|
||||
if (r.exc) {
|
||||
frappe.msgprint(r.exc);
|
||||
return;
|
||||
}
|
||||
me.number = r.message;
|
||||
me.show_dialog();
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
this.show = function(contact, ref_doctype, ref_name, mobile_nos, message) {
|
||||
this.show = function (contact, ref_doctype, ref_name, mobile_nos, message) {
|
||||
this.message = message;
|
||||
if (mobile_nos) {
|
||||
me.number = mobile_nos;
|
||||
me.show_dialog();
|
||||
} else if (contact){
|
||||
this.get_contact_number(contact, ref_doctype, ref_name)
|
||||
} else if (contact) {
|
||||
this.get_contact_number(contact, ref_doctype, ref_name);
|
||||
} else {
|
||||
me.show_dialog();
|
||||
}
|
||||
}
|
||||
this.show_dialog = function() {
|
||||
if(!me.dialog)
|
||||
me.make_dialog();
|
||||
};
|
||||
this.show_dialog = function () {
|
||||
if (!me.dialog) me.make_dialog();
|
||||
me.dialog.set_values({
|
||||
'message': me.message,
|
||||
'number': me.number
|
||||
})
|
||||
message: me.message,
|
||||
number: me.number,
|
||||
});
|
||||
me.dialog.show();
|
||||
}
|
||||
this.make_dialog = function() {
|
||||
};
|
||||
this.make_dialog = function () {
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: 'Send SMS',
|
||||
title: "Send SMS",
|
||||
width: 400,
|
||||
fields: [
|
||||
{fieldname:'number', fieldtype:'Data', label:'Mobile Number', reqd:1},
|
||||
{fieldname:'message', fieldtype:'Text', label:'Message', reqd:1},
|
||||
{fieldname:'send', fieldtype:'Button', label:'Send'}
|
||||
]
|
||||
})
|
||||
d.fields_dict.send.input.onclick = function() {
|
||||
{ fieldname: "number", fieldtype: "Data", label: "Mobile Number", reqd: 1 },
|
||||
{ fieldname: "message", fieldtype: "Text", label: "Message", reqd: 1 },
|
||||
{ fieldname: "send", fieldtype: "Button", label: "Send" },
|
||||
],
|
||||
});
|
||||
d.fields_dict.send.input.onclick = function () {
|
||||
var btn = d.fields_dict.send.input;
|
||||
var v = me.dialog.get_values();
|
||||
if(v) {
|
||||
if (v) {
|
||||
$(btn).set_working();
|
||||
frappe.call({
|
||||
method: "frappe.core.doctype.sms_settings.sms_settings.send_sms",
|
||||
args: {
|
||||
receiver_list: [v.number],
|
||||
msg: v.message
|
||||
msg: v.message,
|
||||
},
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
$(btn).done_working();
|
||||
if(r.exc) {frappe.msgprint(r.exc); return; }
|
||||
if (r.exc) {
|
||||
frappe.msgprint(r.exc);
|
||||
return;
|
||||
}
|
||||
me.dialog.hide();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
this.dialog = d;
|
||||
}
|
||||
};
|
||||
this.setup();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,68 +1,104 @@
|
||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
|
||||
erpnext.StockAnalytics = class StockAnalytics extends erpnext.StockGridReport {
|
||||
constructor(wrapper, opts) {
|
||||
var args = {
|
||||
title: __("Stock Analytics"),
|
||||
parent: $(wrapper).find('.layout-main'),
|
||||
parent: $(wrapper).find(".layout-main"),
|
||||
page: wrapper.page,
|
||||
doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry", "Brand",
|
||||
"Fiscal Year", "Serial No"],
|
||||
doctypes: [
|
||||
"Item",
|
||||
"Item Group",
|
||||
"Warehouse",
|
||||
"Stock Ledger Entry",
|
||||
"Brand",
|
||||
"Fiscal Year",
|
||||
"Serial No",
|
||||
],
|
||||
tree_grid: {
|
||||
show: true,
|
||||
parent_field: "parent_item_group",
|
||||
formatter: function(item) {
|
||||
if(!item.is_group) {
|
||||
return repl("<a \
|
||||
formatter: function (item) {
|
||||
if (!item.is_group) {
|
||||
return repl(
|
||||
"<a \
|
||||
onclick='frappe.cur_grid_report.show_stock_ledger(\"%(value)s\")'>\
|
||||
%(value)s</a>", {
|
||||
%(value)s</a>",
|
||||
{
|
||||
value: item.name,
|
||||
});
|
||||
}
|
||||
);
|
||||
} else {
|
||||
return item.name;
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
if(opts) $.extend(args, opts);
|
||||
if (opts) $.extend(args, opts);
|
||||
|
||||
super(args);
|
||||
|
||||
this.filters = [
|
||||
{fieldtype:"Select", label: __("Value or Qty"), fieldname: "value_or_qty",
|
||||
options:[{label:__("Value"), value:"Value"}, {label:__("Quantity"), value:"Quantity"}],
|
||||
filter: function(val, item, opts, me) {
|
||||
{
|
||||
fieldtype: "Select",
|
||||
label: __("Value or Qty"),
|
||||
fieldname: "value_or_qty",
|
||||
options: [
|
||||
{ label: __("Value"), value: "Value" },
|
||||
{ label: __("Quantity"), value: "Quantity" },
|
||||
],
|
||||
filter: function (val, item, opts, me) {
|
||||
return me.apply_zero_filter(val, item, opts, me);
|
||||
}},
|
||||
{fieldtype:"Select", label: __("Brand"), link:"Brand", fieldname: "brand",
|
||||
default_value: __("Select Brand..."), filter: function(val, item, opts) {
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldtype: "Select",
|
||||
label: __("Brand"),
|
||||
link: "Brand",
|
||||
fieldname: "brand",
|
||||
default_value: __("Select Brand..."),
|
||||
filter: function (val, item, opts) {
|
||||
return val == opts.default_value || item.brand == val || item._show;
|
||||
}, link_formatter: {filter_input: "brand"}},
|
||||
{fieldtype:"Select", label: __("Warehouse"), link:"Warehouse", fieldname: "warehouse",
|
||||
default_value: __("Select Warehouse...")},
|
||||
{fieldtype:"Date", label: __("From Date"), fieldname: "from_date"},
|
||||
{fieldtype:"Date", label: __("To Date"), fieldname: "to_date"},
|
||||
{fieldtype:"Select", label: __("Range"), fieldname: "range",
|
||||
options:[
|
||||
{label:__("Daily"), value:"Daily"},
|
||||
{label:__("Weekly"), value:"Weekly"},
|
||||
{label:__("Monthly"), value:"Monthly"},
|
||||
{label:__("Quarterly"), value:"Quarterly"},
|
||||
{label:__("Yearly"), value:"Yearly"},
|
||||
]}
|
||||
},
|
||||
link_formatter: { filter_input: "brand" },
|
||||
},
|
||||
{
|
||||
fieldtype: "Select",
|
||||
label: __("Warehouse"),
|
||||
link: "Warehouse",
|
||||
fieldname: "warehouse",
|
||||
default_value: __("Select Warehouse..."),
|
||||
},
|
||||
{ fieldtype: "Date", label: __("From Date"), fieldname: "from_date" },
|
||||
{ fieldtype: "Date", label: __("To Date"), fieldname: "to_date" },
|
||||
{
|
||||
fieldtype: "Select",
|
||||
label: __("Range"),
|
||||
fieldname: "range",
|
||||
options: [
|
||||
{ label: __("Daily"), value: "Daily" },
|
||||
{ label: __("Weekly"), value: "Weekly" },
|
||||
{ label: __("Monthly"), value: "Monthly" },
|
||||
{ label: __("Quarterly"), value: "Quarterly" },
|
||||
{ label: __("Yearly"), value: "Yearly" },
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
||||
setup_columns() {
|
||||
var std_columns = [
|
||||
{id: "name", name: __("Item"), field: "name", width: 300},
|
||||
{id: "brand", name: __("Brand"), field: "brand", width: 100},
|
||||
{id: "stock_uom", name: __("UOM"), field: "stock_uom", width: 100},
|
||||
{id: "opening", name: __("Opening"), field: "opening", hidden: true,
|
||||
formatter: this.currency_formatter}
|
||||
{ id: "name", name: __("Item"), field: "name", width: 300 },
|
||||
{ id: "brand", name: __("Brand"), field: "brand", width: 100 },
|
||||
{ id: "stock_uom", name: __("UOM"), field: "stock_uom", width: 100 },
|
||||
{
|
||||
id: "opening",
|
||||
name: __("Opening"),
|
||||
field: "opening",
|
||||
hidden: true,
|
||||
formatter: this.currency_formatter,
|
||||
},
|
||||
];
|
||||
|
||||
this.make_date_range_columns();
|
||||
@@ -79,24 +115,24 @@ erpnext.StockAnalytics = class StockAnalytics extends erpnext.StockGridReport {
|
||||
}
|
||||
init_filter_values() {
|
||||
super.init_filter_values();
|
||||
this.filter_inputs.range && this.filter_inputs.range.val('Monthly');
|
||||
this.filter_inputs.range && this.filter_inputs.range.val("Monthly");
|
||||
}
|
||||
prepare_data() {
|
||||
var me = this;
|
||||
|
||||
if(!this.data) {
|
||||
if (!this.data) {
|
||||
var items = this.prepare_tree("Item", "Item Group");
|
||||
|
||||
me.parent_map = {};
|
||||
me.item_by_name = {};
|
||||
me.data = [];
|
||||
|
||||
$.each(items, function(i, v) {
|
||||
$.each(items, function (i, v) {
|
||||
var d = copy_dict(v);
|
||||
|
||||
me.data.push(d);
|
||||
me.item_by_name[d.name] = d;
|
||||
if(d.parent_item_group) {
|
||||
if (d.parent_item_group) {
|
||||
me.parent_map[d.name] = d.parent_item_group;
|
||||
}
|
||||
me.reset_item_values(d);
|
||||
@@ -105,7 +141,7 @@ erpnext.StockAnalytics = class StockAnalytics extends erpnext.StockGridReport {
|
||||
this.data[0].checked = true;
|
||||
} else {
|
||||
// otherwise, only reset values
|
||||
$.each(this.data, function(i, d) {
|
||||
$.each(this.data, function (i, d) {
|
||||
me.reset_item_values(d);
|
||||
d["closing_qty_value"] = 0;
|
||||
});
|
||||
@@ -113,7 +149,6 @@ erpnext.StockAnalytics = class StockAnalytics extends erpnext.StockGridReport {
|
||||
|
||||
this.prepare_balances();
|
||||
this.update_groups();
|
||||
|
||||
}
|
||||
prepare_balances() {
|
||||
var me = this;
|
||||
@@ -124,24 +159,25 @@ erpnext.StockAnalytics = class StockAnalytics extends erpnext.StockGridReport {
|
||||
this.item_warehouse = {};
|
||||
this.serialized_buying_rates = this.get_serialized_buying_rates();
|
||||
|
||||
for(var i=0, j=data.length; i<j; i++) {
|
||||
for (var i = 0, j = data.length; i < j; i++) {
|
||||
let diff = 0;
|
||||
var sl = data[i];
|
||||
sl.posting_datetime = sl.posting_date + " " + sl.posting_time;
|
||||
var posting_datetime = frappe.datetime.str_to_obj(sl.posting_datetime);
|
||||
|
||||
if(me.is_default("warehouse") ? true : me.warehouse == sl.warehouse) {
|
||||
if (me.is_default("warehouse") ? true : me.warehouse == sl.warehouse) {
|
||||
var item = me.item_by_name[sl.item_code];
|
||||
if(item.closing_qty_value==undefined) item.closing_qty_value = 0;
|
||||
if (item.closing_qty_value == undefined) item.closing_qty_value = 0;
|
||||
|
||||
if(me.value_or_qty!="Quantity") {
|
||||
if (me.value_or_qty != "Quantity") {
|
||||
var wh = me.get_item_warehouse(sl.warehouse, sl.item_code);
|
||||
var valuation_method = item.valuation_method ?
|
||||
item.valuation_method : frappe.sys_defaults.valuation_method;
|
||||
var valuation_method = item.valuation_method
|
||||
? item.valuation_method
|
||||
: frappe.sys_defaults.valuation_method;
|
||||
var is_fifo = valuation_method == "FIFO";
|
||||
|
||||
if(sl.voucher_type=="Stock Reconciliation") {
|
||||
diff = (sl.qty_after_transaction * sl.valuation_rate) - item.closing_qty_value;
|
||||
if (sl.voucher_type == "Stock Reconciliation") {
|
||||
diff = sl.qty_after_transaction * sl.valuation_rate - item.closing_qty_value;
|
||||
wh.fifo_stack = [[sl.qty_after_transaction, sl.valuation_rate, sl.posting_date]];
|
||||
wh.balance_qty = sl.qty_after_transaction;
|
||||
wh.balance_value = sl.valuation_rate * sl.qty_after_transaction;
|
||||
@@ -149,16 +185,16 @@ erpnext.StockAnalytics = class StockAnalytics extends erpnext.StockGridReport {
|
||||
diff = me.get_value_diff(wh, sl, is_fifo);
|
||||
}
|
||||
} else {
|
||||
if(sl.voucher_type=="Stock Reconciliation") {
|
||||
if (sl.voucher_type == "Stock Reconciliation") {
|
||||
diff = sl.qty_after_transaction - item.closing_qty_value;
|
||||
} else {
|
||||
diff = sl.qty;
|
||||
}
|
||||
}
|
||||
|
||||
if(posting_datetime < from_date) {
|
||||
if (posting_datetime < from_date) {
|
||||
item.opening += diff;
|
||||
} else if(posting_datetime <= to_date) {
|
||||
} else if (posting_datetime <= to_date) {
|
||||
item[me.column_map[sl.posting_date].field] += diff;
|
||||
} else {
|
||||
break;
|
||||
@@ -170,25 +206,23 @@ erpnext.StockAnalytics = class StockAnalytics extends erpnext.StockGridReport {
|
||||
}
|
||||
update_groups() {
|
||||
var me = this;
|
||||
$.each(this.data, function(i, item) {
|
||||
$.each(this.data, function (i, item) {
|
||||
// update groups
|
||||
if(!item.is_group && me.apply_filter(item, "brand")) {
|
||||
if (!item.is_group && me.apply_filter(item, "brand")) {
|
||||
var balance = item.opening;
|
||||
$.each(me.columns, function(i, col) {
|
||||
if(col.formatter==me.currency_formatter && !col.hidden) {
|
||||
$.each(me.columns, function (i, col) {
|
||||
if (col.formatter == me.currency_formatter && !col.hidden) {
|
||||
item[col.field] = balance + item[col.field];
|
||||
balance = item[col.field];
|
||||
}
|
||||
});
|
||||
|
||||
var parent = me.parent_map[item.name];
|
||||
while(parent) {
|
||||
while (parent) {
|
||||
var parent_group = me.item_by_name[parent];
|
||||
$.each(me.columns, function(c, col) {
|
||||
$.each(me.columns, function (c, col) {
|
||||
if (col.formatter == me.currency_formatter) {
|
||||
parent_group[col.field] =
|
||||
flt(parent_group[col.field])
|
||||
+ flt(item[col.field]);
|
||||
parent_group[col.field] = flt(parent_group[col.field]) + flt(item[col.field]);
|
||||
}
|
||||
});
|
||||
parent = me.parent_map[parent];
|
||||
@@ -200,7 +234,7 @@ erpnext.StockAnalytics = class StockAnalytics extends erpnext.StockGridReport {
|
||||
frappe.route_options = {
|
||||
item_code: item_code,
|
||||
from_date: this.from_date,
|
||||
to_date: this.to_date
|
||||
to_date: this.to_date,
|
||||
};
|
||||
frappe.set_route("query-report", "Stock Ledger");
|
||||
}
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
|
||||
erpnext.StockGridReport = class StockGridReport extends frappe.views.TreeGridReport {
|
||||
get_item_warehouse(warehouse, item) {
|
||||
if(!this.item_warehouse[item]) this.item_warehouse[item] = {};
|
||||
if(!this.item_warehouse[item][warehouse]) this.item_warehouse[item][warehouse] = {
|
||||
balance_qty: 0.0, balance_value: 0.0, fifo_stack: []
|
||||
};
|
||||
if (!this.item_warehouse[item]) this.item_warehouse[item] = {};
|
||||
if (!this.item_warehouse[item][warehouse])
|
||||
this.item_warehouse[item][warehouse] = {
|
||||
balance_qty: 0.0,
|
||||
balance_value: 0.0,
|
||||
fifo_stack: [],
|
||||
};
|
||||
return this.item_warehouse[item][warehouse];
|
||||
}
|
||||
|
||||
@@ -14,47 +17,43 @@ erpnext.StockGridReport = class StockGridReport extends frappe.views.TreeGridRep
|
||||
// value
|
||||
let value_diff = 0;
|
||||
|
||||
if(sl.qty > 0) {
|
||||
if (sl.qty > 0) {
|
||||
// incoming - rate is given
|
||||
let rate = sl.incoming_rate;
|
||||
let add_qty = sl.qty;
|
||||
if(wh.balance_qty < 0) {
|
||||
if (wh.balance_qty < 0) {
|
||||
// negative valuation
|
||||
// only add value of quantity if
|
||||
// the balance goes above 0
|
||||
add_qty = wh.balance_qty + sl.qty;
|
||||
if(add_qty < 0) {
|
||||
if (add_qty < 0) {
|
||||
add_qty = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(sl.serial_no) {
|
||||
if (sl.serial_no) {
|
||||
value_diff = this.get_serialized_value_diff(sl);
|
||||
} else {
|
||||
value_diff = (rate * add_qty);
|
||||
value_diff = rate * add_qty;
|
||||
}
|
||||
|
||||
if(add_qty)
|
||||
wh.fifo_stack.push([add_qty, sl.incoming_rate, sl.posting_date]);
|
||||
if (add_qty) wh.fifo_stack.push([add_qty, sl.incoming_rate, sl.posting_date]);
|
||||
} else {
|
||||
// called everytime for maintaining fifo stack
|
||||
var fifo_value_diff = this.get_fifo_value_diff(wh, sl);
|
||||
|
||||
// outgoing
|
||||
if(sl.serial_no) {
|
||||
if (sl.serial_no) {
|
||||
value_diff = -1 * this.get_serialized_value_diff(sl);
|
||||
} else if(is_fifo) {
|
||||
} else if (is_fifo) {
|
||||
value_diff = fifo_value_diff;
|
||||
} else {
|
||||
// average rate for weighted average
|
||||
let rate = (wh.balance_qty.toFixed(2) == 0.00 ? 0 :
|
||||
flt(wh.balance_value) / flt(wh.balance_qty));
|
||||
let rate = wh.balance_qty.toFixed(2) == 0.0 ? 0 : flt(wh.balance_value) / flt(wh.balance_qty);
|
||||
|
||||
// no change in value if negative qty
|
||||
if((wh.balance_qty + sl.qty).toFixed(2) >= 0.00)
|
||||
value_diff = (rate * sl.qty);
|
||||
else
|
||||
value_diff = -wh.balance_value;
|
||||
if ((wh.balance_qty + sl.qty).toFixed(2) >= 0.0) value_diff = rate * sl.qty;
|
||||
else value_diff = -wh.balance_value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,14 +68,14 @@ erpnext.StockGridReport = class StockGridReport extends frappe.views.TreeGridRep
|
||||
var fifo_value_diff = 0.0;
|
||||
var qty = -sl.qty;
|
||||
|
||||
for(var i=0, j=fifo_stack.length; i<j; i++) {
|
||||
for (var i = 0, j = fifo_stack.length; i < j; i++) {
|
||||
var batch = fifo_stack.pop();
|
||||
if(batch[0] >= qty) {
|
||||
if (batch[0] >= qty) {
|
||||
batch[0] = batch[0] - qty;
|
||||
fifo_value_diff += (qty * batch[1]);
|
||||
fifo_value_diff += qty * batch[1];
|
||||
|
||||
qty = 0.0;
|
||||
if(batch[0]) {
|
||||
if (batch[0]) {
|
||||
// batch still has qty put it back
|
||||
fifo_stack.push(batch);
|
||||
}
|
||||
@@ -85,7 +84,7 @@ erpnext.StockGridReport = class StockGridReport extends frappe.views.TreeGridRep
|
||||
break;
|
||||
} else {
|
||||
// consume this batch fully
|
||||
fifo_value_diff += (batch[0] * batch[1]);
|
||||
fifo_value_diff += batch[0] * batch[1];
|
||||
qty = qty - batch[0];
|
||||
}
|
||||
}
|
||||
@@ -99,8 +98,8 @@ erpnext.StockGridReport = class StockGridReport extends frappe.views.TreeGridRep
|
||||
|
||||
var value_diff = 0.0;
|
||||
|
||||
$.each(sl.serial_no.trim().split("\n"), function(i, sr) {
|
||||
if(sr) {
|
||||
$.each(sl.serial_no.trim().split("\n"), function (i, sr) {
|
||||
if (sr) {
|
||||
value_diff += flt(me.serialized_buying_rates[sr.trim().toLowerCase()]);
|
||||
}
|
||||
});
|
||||
@@ -112,7 +111,7 @@ erpnext.StockGridReport = class StockGridReport extends frappe.views.TreeGridRep
|
||||
var serialized_buying_rates = {};
|
||||
|
||||
if (frappe.report_dump.data["Serial No"]) {
|
||||
$.each(frappe.report_dump.data["Serial No"], function(i, sn) {
|
||||
$.each(frappe.report_dump.data["Serial No"], function (i, sn) {
|
||||
serialized_buying_rates[sn.name.toLowerCase()] = flt(sn.incoming_rate);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
frappe.ui.form.ControlData = class ControlData extends frappe.ui.form.ControlData {
|
||||
frappe.ui.form.ControlData = class ControlData extends frappe.ui.form.ControlData {
|
||||
make_input() {
|
||||
super.make_input();
|
||||
if (this.df.options == 'Phone') {
|
||||
if (this.df.options == "Phone") {
|
||||
this.setup_phone();
|
||||
}
|
||||
if (this.frm && this.frm.fields_dict) {
|
||||
Object.values(this.frm.fields_dict).forEach(function(field) {
|
||||
if (field.df.read_only === 1 && field.df.options === 'Phone'
|
||||
&& field.disp_area.style[0] != 'display' && !field.has_icon) {
|
||||
Object.values(this.frm.fields_dict).forEach(function (field) {
|
||||
if (
|
||||
field.df.read_only === 1 &&
|
||||
field.df.options === "Phone" &&
|
||||
field.disp_area.style[0] != "display" &&
|
||||
!field.has_icon
|
||||
) {
|
||||
field.setup_phone && field.setup_phone();
|
||||
field.has_icon = true;
|
||||
}
|
||||
@@ -16,15 +20,18 @@ frappe.ui.form.ControlData = class ControlData extends frappe.ui.form.ControlDat
|
||||
}
|
||||
setup_phone() {
|
||||
if (frappe.phone_call.handler) {
|
||||
let control = this.df.read_only ? '.control-value' : '.control-input';
|
||||
this.$wrapper.find(control)
|
||||
.append(`
|
||||
let control = this.df.read_only ? ".control-value" : ".control-input";
|
||||
this.$wrapper
|
||||
.find(control)
|
||||
.append(
|
||||
`
|
||||
<span class="phone-btn">
|
||||
<a class="btn-open no-decoration" title="${__('Make a call')}">
|
||||
${frappe.utils.icon('call')}
|
||||
<a class="btn-open no-decoration" title="${__("Make a call")}">
|
||||
${frappe.utils.icon("call")}
|
||||
</span>
|
||||
`)
|
||||
.find('.phone-btn')
|
||||
`
|
||||
)
|
||||
.find(".phone-btn")
|
||||
.click(() => {
|
||||
frappe.phone_call.handler(this.get_value(), this.frm);
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -58,13 +58,15 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
return;
|
||||
}
|
||||
|
||||
me.update_table(data).then(row => {
|
||||
this.play_success_sound();
|
||||
resolve(row);
|
||||
}).catch(() => {
|
||||
this.play_fail_sound();
|
||||
reject();
|
||||
});
|
||||
me.update_table(data)
|
||||
.then((row) => {
|
||||
this.play_success_sound();
|
||||
resolve(row);
|
||||
})
|
||||
.catch(() => {
|
||||
this.play_fail_sound();
|
||||
reject();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -87,7 +89,7 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
let cur_grid = this.frm.fields_dict[this.items_table_name].grid;
|
||||
frappe.flags.trigger_from_barcode_scanner = true;
|
||||
|
||||
const {item_code, barcode, batch_no, serial_no, uom} = data;
|
||||
const { item_code, barcode, batch_no, serial_no, uom } = data;
|
||||
|
||||
let row = this.get_row_to_modify_on_scan(item_code, batch_no, uom, barcode);
|
||||
|
||||
@@ -116,16 +118,17 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
|
||||
frappe.run_serially([
|
||||
() => this.set_selector_trigger_flag(data),
|
||||
() => this.set_item(row, item_code, barcode, batch_no, serial_no).then(qty => {
|
||||
this.show_scan_message(row.idx, row.item_code, qty);
|
||||
}),
|
||||
() =>
|
||||
this.set_item(row, item_code, barcode, batch_no, serial_no).then((qty) => {
|
||||
this.show_scan_message(row.idx, row.item_code, qty);
|
||||
}),
|
||||
() => this.set_barcode_uom(row, uom),
|
||||
() => this.set_serial_no(row, serial_no),
|
||||
() => this.set_batch_no(row, batch_no),
|
||||
() => this.set_barcode(row, barcode),
|
||||
() => this.clean_up(),
|
||||
() => this.revert_selector_flag(),
|
||||
() => resolve(row)
|
||||
() => resolve(row),
|
||||
]);
|
||||
});
|
||||
}
|
||||
@@ -133,7 +136,7 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
// batch and serial selector is reduandant when all info can be added by scan
|
||||
// this flag on item row is used by transaction.js to avoid triggering selector
|
||||
set_selector_trigger_flag(data) {
|
||||
const {batch_no, serial_no, has_batch_no, has_serial_no} = data;
|
||||
const { batch_no, serial_no, has_batch_no, has_serial_no } = data;
|
||||
|
||||
const require_selecting_batch = has_batch_no && !batch_no;
|
||||
const require_selecting_serial = has_serial_no && !serial_no;
|
||||
@@ -149,17 +152,17 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
}
|
||||
|
||||
set_item(row, item_code, barcode, batch_no, serial_no) {
|
||||
return new Promise(resolve => {
|
||||
return new Promise((resolve) => {
|
||||
const increment = async (value = 1) => {
|
||||
const item_data = {item_code: item_code, use_serial_batch_fields: 1.0};
|
||||
const item_data = { item_code: item_code, use_serial_batch_fields: 1.0 };
|
||||
frappe.flags.trigger_from_barcode_scanner = true;
|
||||
item_data[this.qty_field] = Number((row[this.qty_field] || 0)) + Number(value);
|
||||
item_data[this.qty_field] = Number(row[this.qty_field] || 0) + Number(value);
|
||||
await frappe.model.set_value(row.doctype, row.name, item_data);
|
||||
return value;
|
||||
};
|
||||
|
||||
if (this.prompt_qty) {
|
||||
frappe.prompt(__("Please enter quantity for item {0}", [item_code]), ({value}) => {
|
||||
frappe.prompt(__("Please enter quantity for item {0}", [item_code]), ({ value }) => {
|
||||
increment(value).then((value) => resolve(value));
|
||||
});
|
||||
} else if (this.frm.has_items) {
|
||||
@@ -175,14 +178,15 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
this.dialog = new frappe.ui.Dialog({
|
||||
title: __("Scan barcode for item {0}", [item_code]),
|
||||
fields: me.get_fields_for_dialog(row, item_code, barcode, batch_no, serial_no),
|
||||
})
|
||||
});
|
||||
|
||||
this.dialog.set_primary_action(__("Update"), () => {
|
||||
const item_data = {item_code: item_code};
|
||||
const item_data = { item_code: item_code };
|
||||
item_data[this.qty_field] = this.dialog.get_value("scanned_qty");
|
||||
item_data["has_item_scanned"] = 1;
|
||||
|
||||
this.remaining_qty = flt(this.dialog.get_value("qty")) - flt(this.dialog.get_value("scanned_qty"));
|
||||
this.remaining_qty =
|
||||
flt(this.dialog.get_value("qty")) - flt(this.dialog.get_value("scanned_qty"));
|
||||
frappe.model.set_value(row.doctype, row.name, item_data);
|
||||
|
||||
frappe.run_serially([
|
||||
@@ -190,7 +194,7 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
() => this.set_barcode(row, this.dialog.get_value("barcode")),
|
||||
() => this.set_serial_no(row, this.dialog.get_value("serial_no")),
|
||||
() => this.add_child_for_remaining_qty(row),
|
||||
() => this.clean_up()
|
||||
() => this.clean_up(),
|
||||
]);
|
||||
|
||||
this.dialog.hide();
|
||||
@@ -219,9 +223,9 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
if (r.message) {
|
||||
this.update_dialog_values(item_code, r);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldtype: "Section Break",
|
||||
@@ -245,8 +249,8 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
},
|
||||
{
|
||||
fieldtype: "Section Break",
|
||||
}
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
if (batch_no) {
|
||||
fields.push({
|
||||
@@ -256,7 +260,7 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
label: __("Batch No"),
|
||||
default: batch_no,
|
||||
read_only: 1,
|
||||
hidden: 1
|
||||
hidden: 1,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -278,7 +282,7 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
label: __("Barcode"),
|
||||
default: barcode,
|
||||
read_only: 1,
|
||||
hidden: 1
|
||||
hidden: 1,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -286,18 +290,18 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
}
|
||||
|
||||
update_dialog_values(scanned_item, r) {
|
||||
const {item_code, barcode, batch_no, serial_no} = r.message;
|
||||
const { item_code, barcode, batch_no, serial_no } = r.message;
|
||||
|
||||
this.dialog.set_value("barcode_scanner", "");
|
||||
if (item_code === scanned_item &&
|
||||
(this.dialog.get_value("barcode") === barcode || batch_no || serial_no)) {
|
||||
|
||||
if (
|
||||
item_code === scanned_item &&
|
||||
(this.dialog.get_value("barcode") === barcode || batch_no || serial_no)
|
||||
) {
|
||||
if (batch_no) {
|
||||
this.dialog.set_value("batch_no", batch_no);
|
||||
}
|
||||
|
||||
if (serial_no) {
|
||||
|
||||
this.validate_duplicate_serial_no(serial_no);
|
||||
let serial_nos = this.dialog.get_value("serial_no") + "\n" + serial_no;
|
||||
this.dialog.set_value("serial_no", serial_nos);
|
||||
@@ -309,8 +313,9 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
}
|
||||
|
||||
validate_duplicate_serial_no(serial_no) {
|
||||
let serial_nos = this.dialog.get_value("serial_no") ?
|
||||
this.dialog.get_value("serial_no").split("\n") : [];
|
||||
let serial_nos = this.dialog.get_value("serial_no")
|
||||
? this.dialog.get_value("serial_no").split("\n")
|
||||
: [];
|
||||
|
||||
if (in_list(serial_nos, serial_no)) {
|
||||
frappe.throw(__("Serial No {0} already scanned", [serial_no]));
|
||||
@@ -318,12 +323,19 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
}
|
||||
|
||||
add_child_for_remaining_qty(prev_row) {
|
||||
if (this.remaining_qty && this.remaining_qty >0) {
|
||||
if (this.remaining_qty && this.remaining_qty > 0) {
|
||||
let cur_grid = this.frm.fields_dict[this.items_table_name].grid;
|
||||
let row = frappe.model.add_child(this.frm.doc, cur_grid.doctype, this.items_table_name);
|
||||
|
||||
let ignore_fields = ["name", "idx", "batch_no", "barcode",
|
||||
"received_qty", "serial_no", "has_item_scanned"];
|
||||
let ignore_fields = [
|
||||
"name",
|
||||
"idx",
|
||||
"batch_no",
|
||||
"barcode",
|
||||
"received_qty",
|
||||
"serial_no",
|
||||
"has_item_scanned",
|
||||
];
|
||||
|
||||
for (let key in prev_row) {
|
||||
if (in_list(ignore_fields, key)) {
|
||||
@@ -379,7 +391,7 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
if (exist) {
|
||||
this.show_alert(__("Row #{0}: Qty increased by {1}", [idx, qty]), "green");
|
||||
} else {
|
||||
this.show_alert(__("Row #{0}: Item added", [idx]), "green")
|
||||
this.show_alert(__("Row #{0}: Item added", [idx]), "green");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,17 +413,19 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
|
||||
const matching_row = (row) => {
|
||||
const item_match = row.item_code == item_code;
|
||||
const batch_match = (!row[this.batch_no_field] || row[this.batch_no_field] == batch_no);
|
||||
const batch_match = !row[this.batch_no_field] || row[this.batch_no_field] == batch_no;
|
||||
const uom_match = !uom || row[this.uom_field] == uom;
|
||||
const qty_in_limit = flt(row[this.qty_field]) < flt(row[this.max_qty_field]);
|
||||
const item_scanned = row.has_item_scanned;
|
||||
|
||||
return item_match
|
||||
&& uom_match
|
||||
&& !item_scanned
|
||||
&& (!is_batch_no_scan || batch_match)
|
||||
&& (!check_max_qty || qty_in_limit)
|
||||
}
|
||||
return (
|
||||
item_match &&
|
||||
uom_match &&
|
||||
!item_scanned &&
|
||||
(!is_batch_no_scan || batch_match) &&
|
||||
(!check_max_qty || qty_in_limit)
|
||||
);
|
||||
};
|
||||
|
||||
return this.items_table.find(matching_row) || this.get_existing_blank_row();
|
||||
}
|
||||
@@ -432,7 +446,7 @@ erpnext.utils.BarcodeScanner = class BarcodeScanner {
|
||||
this.scan_barcode_field.set_value("");
|
||||
refresh_field(this.items_table_name);
|
||||
}
|
||||
show_alert(msg, indicator, duration=3) {
|
||||
frappe.show_alert({message: msg, indicator: indicator}, duration);
|
||||
show_alert(msg, indicator, duration = 3) {
|
||||
frappe.show_alert({ message: msg, indicator: indicator }, duration);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
frappe.provide('frappe.ui.form');
|
||||
frappe.provide("frappe.ui.form");
|
||||
|
||||
frappe.ui.form.ContactAddressQuickEntryForm = class ContactAddressQuickEntryForm extends frappe.ui.form.QuickEntryForm {
|
||||
frappe.ui.form.ContactAddressQuickEntryForm = class ContactAddressQuickEntryForm extends (
|
||||
frappe.ui.form.QuickEntryForm
|
||||
) {
|
||||
constructor(doctype, after_insert, init_callback, doc, force) {
|
||||
super(doctype, after_insert, init_callback, doc, force);
|
||||
this.skip_redirect_on_error = true;
|
||||
@@ -17,8 +19,8 @@ frappe.ui.form.ContactAddressQuickEntryForm = class ContactAddressQuickEntryForm
|
||||
* Therefor, resulting in the fields being "hidden".
|
||||
*/
|
||||
const map_field_names = {
|
||||
"email_address": "email_id",
|
||||
"mobile_number": "mobile_no",
|
||||
email_address: "email_id",
|
||||
mobile_number: "mobile_no",
|
||||
};
|
||||
|
||||
Object.entries(map_field_names).forEach(([fieldname, new_fieldname]) => {
|
||||
@@ -30,71 +32,73 @@ frappe.ui.form.ContactAddressQuickEntryForm = class ContactAddressQuickEntryForm
|
||||
}
|
||||
|
||||
get_variant_fields() {
|
||||
var variant_fields = [{
|
||||
fieldtype: "Section Break",
|
||||
label: __("Primary Contact Details"),
|
||||
collapsible: 1
|
||||
},
|
||||
{
|
||||
label: __("Email Id"),
|
||||
fieldname: "email_address",
|
||||
fieldtype: "Data",
|
||||
options: "Email",
|
||||
},
|
||||
{
|
||||
fieldtype: "Column Break"
|
||||
},
|
||||
{
|
||||
label: __("Mobile Number"),
|
||||
fieldname: "mobile_number",
|
||||
fieldtype: "Data"
|
||||
},
|
||||
{
|
||||
fieldtype: "Section Break",
|
||||
label: __("Primary Address Details"),
|
||||
collapsible: 1
|
||||
},
|
||||
{
|
||||
label: __("Address Line 1"),
|
||||
fieldname: "address_line1",
|
||||
fieldtype: "Data"
|
||||
},
|
||||
{
|
||||
label: __("Address Line 2"),
|
||||
fieldname: "address_line2",
|
||||
fieldtype: "Data"
|
||||
},
|
||||
{
|
||||
label: __("ZIP Code"),
|
||||
fieldname: "pincode",
|
||||
fieldtype: "Data"
|
||||
},
|
||||
{
|
||||
fieldtype: "Column Break"
|
||||
},
|
||||
{
|
||||
label: __("City"),
|
||||
fieldname: "city",
|
||||
fieldtype: "Data"
|
||||
},
|
||||
{
|
||||
label: __("State"),
|
||||
fieldname: "state",
|
||||
fieldtype: "Data"
|
||||
},
|
||||
{
|
||||
label: __("Country"),
|
||||
fieldname: "country",
|
||||
fieldtype: "Link",
|
||||
options: "Country"
|
||||
},
|
||||
{
|
||||
label: __("Customer POS Id"),
|
||||
fieldname: "customer_pos_id",
|
||||
fieldtype: "Data",
|
||||
hidden: 1
|
||||
}];
|
||||
var variant_fields = [
|
||||
{
|
||||
fieldtype: "Section Break",
|
||||
label: __("Primary Contact Details"),
|
||||
collapsible: 1,
|
||||
},
|
||||
{
|
||||
label: __("Email Id"),
|
||||
fieldname: "email_address",
|
||||
fieldtype: "Data",
|
||||
options: "Email",
|
||||
},
|
||||
{
|
||||
fieldtype: "Column Break",
|
||||
},
|
||||
{
|
||||
label: __("Mobile Number"),
|
||||
fieldname: "mobile_number",
|
||||
fieldtype: "Data",
|
||||
},
|
||||
{
|
||||
fieldtype: "Section Break",
|
||||
label: __("Primary Address Details"),
|
||||
collapsible: 1,
|
||||
},
|
||||
{
|
||||
label: __("Address Line 1"),
|
||||
fieldname: "address_line1",
|
||||
fieldtype: "Data",
|
||||
},
|
||||
{
|
||||
label: __("Address Line 2"),
|
||||
fieldname: "address_line2",
|
||||
fieldtype: "Data",
|
||||
},
|
||||
{
|
||||
label: __("ZIP Code"),
|
||||
fieldname: "pincode",
|
||||
fieldtype: "Data",
|
||||
},
|
||||
{
|
||||
fieldtype: "Column Break",
|
||||
},
|
||||
{
|
||||
label: __("City"),
|
||||
fieldname: "city",
|
||||
fieldtype: "Data",
|
||||
},
|
||||
{
|
||||
label: __("State"),
|
||||
fieldname: "state",
|
||||
fieldtype: "Data",
|
||||
},
|
||||
{
|
||||
label: __("Country"),
|
||||
fieldname: "country",
|
||||
fieldtype: "Link",
|
||||
options: "Country",
|
||||
},
|
||||
{
|
||||
label: __("Customer POS Id"),
|
||||
fieldname: "customer_pos_id",
|
||||
fieldtype: "Data",
|
||||
hidden: 1,
|
||||
},
|
||||
];
|
||||
|
||||
return variant_fields;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6,21 +6,21 @@ erpnext.utils.CRMActivities = class CRMActivities {
|
||||
refresh() {
|
||||
var me = this;
|
||||
$(this.open_activities_wrapper).empty();
|
||||
let cur_form_footer = this.form_wrapper.find('.form-footer');
|
||||
let cur_form_footer = this.form_wrapper.find(".form-footer");
|
||||
|
||||
// all activities
|
||||
if (!$(this.all_activities_wrapper).find('.form-footer').length) {
|
||||
if (!$(this.all_activities_wrapper).find(".form-footer").length) {
|
||||
this.all_activities_wrapper.empty();
|
||||
$(cur_form_footer).appendTo(this.all_activities_wrapper);
|
||||
|
||||
// remove frappe-control class to avoid absolute position for action-btn
|
||||
$(this.all_activities_wrapper).removeClass('frappe-control');
|
||||
$(this.all_activities_wrapper).removeClass("frappe-control");
|
||||
// hide new event button
|
||||
$('.timeline-actions').find('.btn-default').hide();
|
||||
$(".timeline-actions").find(".btn-default").hide();
|
||||
// hide new comment box
|
||||
$(".comment-box").hide();
|
||||
// show only communications by default
|
||||
$($('.timeline-content').find('.nav-link')[0]).tab('show');
|
||||
$($(".timeline-content").find(".nav-link")[0]).tab("show");
|
||||
}
|
||||
|
||||
// open activities
|
||||
@@ -28,66 +28,70 @@ erpnext.utils.CRMActivities = class CRMActivities {
|
||||
method: "erpnext.crm.utils.get_open_activities",
|
||||
args: {
|
||||
ref_doctype: this.frm.doc.doctype,
|
||||
ref_docname: this.frm.doc.name
|
||||
ref_docname: this.frm.doc.name,
|
||||
},
|
||||
callback: (r) => {
|
||||
if (!r.exc) {
|
||||
var activities_html = frappe.render_template('crm_activities', {
|
||||
var activities_html = frappe.render_template("crm_activities", {
|
||||
tasks: r.message.tasks,
|
||||
events: r.message.events
|
||||
events: r.message.events,
|
||||
});
|
||||
|
||||
$(activities_html).appendTo(me.open_activities_wrapper);
|
||||
|
||||
$(".open-tasks").find(".completion-checkbox").on("click", function() {
|
||||
me.update_status(this, "ToDo");
|
||||
});
|
||||
$(".open-tasks")
|
||||
.find(".completion-checkbox")
|
||||
.on("click", function () {
|
||||
me.update_status(this, "ToDo");
|
||||
});
|
||||
|
||||
$(".open-events").find(".completion-checkbox").on("click", function() {
|
||||
me.update_status(this, "Event");
|
||||
});
|
||||
$(".open-events")
|
||||
.find(".completion-checkbox")
|
||||
.on("click", function () {
|
||||
me.update_status(this, "Event");
|
||||
});
|
||||
|
||||
me.create_task();
|
||||
me.create_event();
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
create_task () {
|
||||
create_task() {
|
||||
let me = this;
|
||||
let _create_task = () => {
|
||||
const args = {
|
||||
doc: me.frm.doc,
|
||||
frm: me.frm,
|
||||
title: __("New Task")
|
||||
title: __("New Task"),
|
||||
};
|
||||
let composer = new frappe.views.InteractionComposer(args);
|
||||
composer.dialog.get_field('interaction_type').set_value("ToDo");
|
||||
composer.dialog.get_field("interaction_type").set_value("ToDo");
|
||||
// hide column having interaction type field
|
||||
$(composer.dialog.get_field('interaction_type').wrapper).closest('.form-column').hide();
|
||||
$(composer.dialog.get_field("interaction_type").wrapper).closest(".form-column").hide();
|
||||
// hide summary field
|
||||
$(composer.dialog.get_field('summary').wrapper).closest('.form-section').hide();
|
||||
$(composer.dialog.get_field("summary").wrapper).closest(".form-section").hide();
|
||||
};
|
||||
$(".new-task-btn").click(_create_task);
|
||||
}
|
||||
|
||||
create_event () {
|
||||
create_event() {
|
||||
let me = this;
|
||||
let _create_event = () => {
|
||||
const args = {
|
||||
doc: me.frm.doc,
|
||||
frm: me.frm,
|
||||
title: __("New Event")
|
||||
title: __("New Event"),
|
||||
};
|
||||
let composer = new frappe.views.InteractionComposer(args);
|
||||
composer.dialog.get_field('interaction_type').set_value("Event");
|
||||
$(composer.dialog.get_field('interaction_type').wrapper).hide();
|
||||
composer.dialog.get_field("interaction_type").set_value("Event");
|
||||
$(composer.dialog.get_field("interaction_type").wrapper).hide();
|
||||
};
|
||||
$(".new-event-btn").click(_create_event);
|
||||
}
|
||||
|
||||
async update_status (input_field, doctype) {
|
||||
async update_status(input_field, doctype) {
|
||||
let completed = $(input_field).prop("checked") ? 1 : 0;
|
||||
let docname = $(input_field).attr("name");
|
||||
if (completed) {
|
||||
@@ -104,132 +108,129 @@ erpnext.utils.CRMNotes = class CRMNotes {
|
||||
|
||||
refresh() {
|
||||
var me = this;
|
||||
this.notes_wrapper.find('.notes-section').remove();
|
||||
this.notes_wrapper.find(".notes-section").remove();
|
||||
|
||||
let notes = this.frm.doc.notes || [];
|
||||
notes.sort(
|
||||
function(a, b) {
|
||||
return new Date(b.added_on) - new Date(a.added_on);
|
||||
}
|
||||
);
|
||||
notes.sort(function (a, b) {
|
||||
return new Date(b.added_on) - new Date(a.added_on);
|
||||
});
|
||||
|
||||
let notes_html = frappe.render_template(
|
||||
'crm_notes',
|
||||
{
|
||||
notes: notes
|
||||
}
|
||||
);
|
||||
let notes_html = frappe.render_template("crm_notes", {
|
||||
notes: notes,
|
||||
});
|
||||
$(notes_html).appendTo(this.notes_wrapper);
|
||||
|
||||
this.add_note();
|
||||
|
||||
$(".notes-section").find(".edit-note-btn").on("click", function() {
|
||||
me.edit_note(this);
|
||||
});
|
||||
$(".notes-section")
|
||||
.find(".edit-note-btn")
|
||||
.on("click", function () {
|
||||
me.edit_note(this);
|
||||
});
|
||||
|
||||
$(".notes-section").find(".delete-note-btn").on("click", function() {
|
||||
me.delete_note(this);
|
||||
});
|
||||
$(".notes-section")
|
||||
.find(".delete-note-btn")
|
||||
.on("click", function () {
|
||||
me.delete_note(this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
add_note () {
|
||||
add_note() {
|
||||
let me = this;
|
||||
let _add_note = () => {
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __('Add a Note'),
|
||||
title: __("Add a Note"),
|
||||
fields: [
|
||||
{
|
||||
"label": "Note",
|
||||
"fieldname": "note",
|
||||
"fieldtype": "Text Editor",
|
||||
"reqd": 1,
|
||||
"enable_mentions": true,
|
||||
}
|
||||
label: "Note",
|
||||
fieldname: "note",
|
||||
fieldtype: "Text Editor",
|
||||
reqd: 1,
|
||||
enable_mentions: true,
|
||||
},
|
||||
],
|
||||
primary_action: function() {
|
||||
primary_action: function () {
|
||||
var data = d.get_values();
|
||||
frappe.call({
|
||||
method: "add_note",
|
||||
doc: me.frm.doc,
|
||||
args: {
|
||||
note: data.note
|
||||
note: data.note,
|
||||
},
|
||||
freeze: true,
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
if (!r.exc) {
|
||||
me.frm.refresh_field("notes");
|
||||
me.refresh();
|
||||
}
|
||||
d.hide();
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
primary_action_label: __('Add')
|
||||
primary_action_label: __("Add"),
|
||||
});
|
||||
d.show();
|
||||
};
|
||||
$(".new-note-btn").click(_add_note);
|
||||
}
|
||||
|
||||
edit_note (edit_btn) {
|
||||
edit_note(edit_btn) {
|
||||
var me = this;
|
||||
let row = $(edit_btn).closest('.comment-content');
|
||||
let row = $(edit_btn).closest(".comment-content");
|
||||
let row_id = row.attr("name");
|
||||
let row_content = $(row).find(".content").html();
|
||||
if (row_content) {
|
||||
var d = new frappe.ui.Dialog({
|
||||
title: __('Edit Note'),
|
||||
title: __("Edit Note"),
|
||||
fields: [
|
||||
{
|
||||
"label": "Note",
|
||||
"fieldname": "note",
|
||||
"fieldtype": "Text Editor",
|
||||
"default": row_content
|
||||
}
|
||||
label: "Note",
|
||||
fieldname: "note",
|
||||
fieldtype: "Text Editor",
|
||||
default: row_content,
|
||||
},
|
||||
],
|
||||
primary_action: function() {
|
||||
primary_action: function () {
|
||||
var data = d.get_values();
|
||||
frappe.call({
|
||||
method: "edit_note",
|
||||
doc: me.frm.doc,
|
||||
args: {
|
||||
note: data.note,
|
||||
row_id: row_id
|
||||
row_id: row_id,
|
||||
},
|
||||
freeze: true,
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
if (!r.exc) {
|
||||
me.frm.refresh_field("notes");
|
||||
me.refresh();
|
||||
d.hide();
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
primary_action_label: __('Done')
|
||||
primary_action_label: __("Done"),
|
||||
});
|
||||
d.show();
|
||||
}
|
||||
}
|
||||
|
||||
delete_note (delete_btn) {
|
||||
delete_note(delete_btn) {
|
||||
var me = this;
|
||||
let row_id = $(delete_btn).closest('.comment-content').attr("name");
|
||||
let row_id = $(delete_btn).closest(".comment-content").attr("name");
|
||||
frappe.call({
|
||||
method: "delete_note",
|
||||
doc: me.frm.doc,
|
||||
args: {
|
||||
row_id: row_id
|
||||
row_id: row_id,
|
||||
},
|
||||
freeze: true,
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
if (!r.exc) {
|
||||
me.frm.refresh_field("notes");
|
||||
me.refresh();
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
frappe.provide('frappe.ui.form');
|
||||
frappe.provide("frappe.ui.form");
|
||||
|
||||
frappe.ui.form.CustomerQuickEntryForm = frappe.ui.form.ContactAddressQuickEntryForm;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
frappe.provide('erpnext.accounts');
|
||||
frappe.provide("erpnext.accounts");
|
||||
|
||||
erpnext.accounts.dimensions = {
|
||||
setup_dimension_filters(frm, doctype) {
|
||||
@@ -12,36 +12,38 @@ erpnext.accounts.dimensions = {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.get_dimensions",
|
||||
args: {
|
||||
'with_cost_center_and_project': true
|
||||
with_cost_center_and_project: true,
|
||||
},
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
me.accounting_dimensions = r.message[0];
|
||||
// Ignoring "Project" as it is already handled specifically in Sales Order and Delivery Note
|
||||
me.accounting_dimensions = me.accounting_dimensions.filter(x=>{return x.document_type != "Project"});
|
||||
me.accounting_dimensions = me.accounting_dimensions.filter((x) => {
|
||||
return x.document_type != "Project";
|
||||
});
|
||||
me.default_dimensions = r.message[1];
|
||||
me.setup_filters(frm, doctype);
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
setup_filters(frm, doctype) {
|
||||
if (doctype == 'Payment Entry' && this.accounting_dimensions) {
|
||||
frm.dimension_filters = this.accounting_dimensions
|
||||
if (doctype == "Payment Entry" && this.accounting_dimensions) {
|
||||
frm.dimension_filters = this.accounting_dimensions;
|
||||
}
|
||||
|
||||
if (this.accounting_dimensions) {
|
||||
this.accounting_dimensions.forEach((dimension) => {
|
||||
frappe.model.with_doctype(dimension['document_type'], () => {
|
||||
frappe.model.with_doctype(dimension["document_type"], () => {
|
||||
let parent_fields = [];
|
||||
frappe.meta.get_docfields(doctype).forEach((df) => {
|
||||
if (df.fieldtype === 'Link' && df.options === 'Account') {
|
||||
if (df.fieldtype === "Link" && df.options === "Account") {
|
||||
parent_fields.push(df.fieldname);
|
||||
} else if (df.fieldtype === 'Table') {
|
||||
this.setup_child_filters(frm, df.options, df.fieldname, dimension['fieldname']);
|
||||
} else if (df.fieldtype === "Table") {
|
||||
this.setup_child_filters(frm, df.options, df.fieldname, dimension["fieldname"]);
|
||||
}
|
||||
|
||||
if (frappe.meta.has_field(doctype, dimension['fieldname'])) {
|
||||
this.setup_account_filters(frm, dimension['fieldname'], parent_fields);
|
||||
if (frappe.meta.has_field(doctype, dimension["fieldname"])) {
|
||||
this.setup_account_filters(frm, dimension["fieldname"], parent_fields);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -55,12 +57,12 @@ erpnext.accounts.dimensions = {
|
||||
if (frappe.meta.has_field(doctype, dimension)) {
|
||||
frappe.model.with_doctype(doctype, () => {
|
||||
frappe.meta.get_docfields(doctype).forEach((df) => {
|
||||
if (df.fieldtype === 'Link' && df.options === 'Account') {
|
||||
if (df.fieldtype === "Link" && df.options === "Account") {
|
||||
fields.push(df.fieldname);
|
||||
}
|
||||
});
|
||||
|
||||
frm.set_query(dimension, parentfield, function(doc, cdt, cdn) {
|
||||
frm.set_query(dimension, parentfield, function (doc, cdt, cdn) {
|
||||
let row = locals[cdt][cdn];
|
||||
return erpnext.queries.get_filtered_dimensions(row, fields, dimension, doc.company);
|
||||
});
|
||||
@@ -69,7 +71,7 @@ erpnext.accounts.dimensions = {
|
||||
},
|
||||
|
||||
setup_account_filters(frm, dimension, fields) {
|
||||
frm.set_query(dimension, function(doc) {
|
||||
frm.set_query(dimension, function (doc) {
|
||||
return erpnext.queries.get_filtered_dimensions(doc, fields, dimension, doc.company);
|
||||
});
|
||||
},
|
||||
@@ -78,18 +80,26 @@ erpnext.accounts.dimensions = {
|
||||
if (this.accounting_dimensions) {
|
||||
this.accounting_dimensions.forEach((dimension) => {
|
||||
if (frm.is_new()) {
|
||||
if (frm.doc.company && Object.keys(this.default_dimensions || {}).length > 0
|
||||
&& this.default_dimensions[frm.doc.company]) {
|
||||
|
||||
let default_dimension = this.default_dimensions[frm.doc.company][dimension['fieldname']];
|
||||
if (
|
||||
frm.doc.company &&
|
||||
Object.keys(this.default_dimensions || {}).length > 0 &&
|
||||
this.default_dimensions[frm.doc.company]
|
||||
) {
|
||||
let default_dimension =
|
||||
this.default_dimensions[frm.doc.company][dimension["fieldname"]];
|
||||
|
||||
if (default_dimension) {
|
||||
if (frappe.meta.has_field(doctype, dimension['fieldname'])) {
|
||||
frm.set_value(dimension['fieldname'], default_dimension);
|
||||
if (frappe.meta.has_field(doctype, dimension["fieldname"])) {
|
||||
frm.set_value(dimension["fieldname"], default_dimension);
|
||||
}
|
||||
|
||||
$.each(frm.doc.items || frm.doc.accounts || [], function(i, row) {
|
||||
frappe.model.set_value(row.doctype, row.name, dimension['fieldname'], default_dimension);
|
||||
$.each(frm.doc.items || frm.doc.accounts || [], function (i, row) {
|
||||
frappe.model.set_value(
|
||||
row.doctype,
|
||||
row.name,
|
||||
dimension["fieldname"],
|
||||
default_dimension
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -102,8 +112,8 @@ erpnext.accounts.dimensions = {
|
||||
if (frappe.meta.has_field(frm.doctype, fieldname) && this.accounting_dimensions) {
|
||||
this.accounting_dimensions.forEach((dimension) => {
|
||||
let row = frappe.get_doc(cdt, cdn);
|
||||
frm.script_manager.copy_from_first_row(fieldname, row, [dimension['fieldname']]);
|
||||
frm.script_manager.copy_from_first_row(fieldname, row, [dimension["fieldname"]]);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@ erpnext.ItemSelector = class ItemSelector {
|
||||
$.extend(this, opts);
|
||||
|
||||
if (!this.item_field) {
|
||||
this.item_field = 'item_code';
|
||||
this.item_field = "item_code";
|
||||
}
|
||||
|
||||
if (!this.item_query) {
|
||||
@@ -16,39 +16,43 @@ erpnext.ItemSelector = class ItemSelector {
|
||||
|
||||
setup() {
|
||||
var me = this;
|
||||
if(!this.grid.add_items_button) {
|
||||
this.grid.add_items_button = this.grid.add_custom_button(__('Add Items'), function() {
|
||||
if(!me.dialog) {
|
||||
if (!this.grid.add_items_button) {
|
||||
this.grid.add_items_button = this.grid.add_custom_button(__("Add Items"), function () {
|
||||
if (!me.dialog) {
|
||||
me.make_dialog();
|
||||
}
|
||||
me.dialog.show();
|
||||
me.render_items();
|
||||
setTimeout(function() { me.dialog.input.focus(); }, 1000);
|
||||
setTimeout(function () {
|
||||
me.dialog.input.focus();
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
make_dialog() {
|
||||
this.dialog = new frappe.ui.Dialog({
|
||||
title: __('Add Items')
|
||||
title: __("Add Items"),
|
||||
});
|
||||
var body = $(this.dialog.body);
|
||||
body.html('<div><p><input type="text" class="form-control"></p>\
|
||||
<br><div class="results"></div></div>');
|
||||
body.html(
|
||||
'<div><p><input type="text" class="form-control"></p>\
|
||||
<br><div class="results"></div></div>'
|
||||
);
|
||||
|
||||
this.dialog.input = body.find('.form-control');
|
||||
this.dialog.results = body.find('.results');
|
||||
this.dialog.input = body.find(".form-control");
|
||||
this.dialog.results = body.find(".results");
|
||||
|
||||
var me = this;
|
||||
this.dialog.results.on('click', '.image-view-item', function() {
|
||||
me.add_item($(this).attr('data-name'));
|
||||
this.dialog.results.on("click", ".image-view-item", function () {
|
||||
me.add_item($(this).attr("data-name"));
|
||||
});
|
||||
|
||||
this.dialog.input.on('keyup', function() {
|
||||
if(me.timeout_id) {
|
||||
this.dialog.input.on("keyup", function () {
|
||||
if (me.timeout_id) {
|
||||
clearTimeout(me.timeout_id);
|
||||
}
|
||||
me.timeout_id = setTimeout(function() {
|
||||
me.timeout_id = setTimeout(function () {
|
||||
me.render_items();
|
||||
me.timeout_id = undefined;
|
||||
}, 500);
|
||||
@@ -61,33 +65,34 @@ erpnext.ItemSelector = class ItemSelector {
|
||||
|
||||
// find row with item if exists
|
||||
$.each(this.frm.doc.items || [], (i, d) => {
|
||||
if(d[this.item_field]===item_code) {
|
||||
frappe.model.set_value(d.doctype, d.name, 'qty', d.qty + 1);
|
||||
frappe.show_alert({message: __("Added {0} ({1})", [item_code, d.qty]), indicator: 'green'});
|
||||
if (d[this.item_field] === item_code) {
|
||||
frappe.model.set_value(d.doctype, d.name, "qty", d.qty + 1);
|
||||
frappe.show_alert({ message: __("Added {0} ({1})", [item_code, d.qty]), indicator: "green" });
|
||||
added = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if(!added) {
|
||||
if (!added) {
|
||||
var d = null;
|
||||
frappe.run_serially([
|
||||
() => { d = this.grid.add_new_row(); },
|
||||
() => {
|
||||
d = this.grid.add_new_row();
|
||||
},
|
||||
() => frappe.model.set_value(d.doctype, d.name, this.item_field, item_code),
|
||||
() => frappe.timeout(0.1),
|
||||
() => {
|
||||
frappe.model.set_value(d.doctype, d.name, 'qty', 1);
|
||||
frappe.show_alert({message: __("Added {0} ({1})", [item_code, 1]), indicator: 'green'});
|
||||
}
|
||||
frappe.model.set_value(d.doctype, d.name, "qty", 1);
|
||||
frappe.show_alert({ message: __("Added {0} ({1})", [item_code, 1]), indicator: "green" });
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
render_items() {
|
||||
let args = {
|
||||
query: this.item_query,
|
||||
filters: {}
|
||||
filters: {},
|
||||
};
|
||||
args.txt = this.dialog.input.val();
|
||||
args.as_dict = 1;
|
||||
@@ -97,14 +102,14 @@ erpnext.ItemSelector = class ItemSelector {
|
||||
}
|
||||
|
||||
var me = this;
|
||||
frappe.link_search("Item", args, function(results) {
|
||||
$.each(results, function(i, d) {
|
||||
if(!d.image) {
|
||||
frappe.link_search("Item", args, function (results) {
|
||||
$.each(results, function (i, d) {
|
||||
if (!d.image) {
|
||||
d.abbr = frappe.get_abbr(d.item_name);
|
||||
d.color = frappe.get_palette(d.item_name);
|
||||
}
|
||||
});
|
||||
me.dialog.results.html(frappe.render_template('item_selector', {'data': results}));
|
||||
me.dialog.results.html(frappe.render_template("item_selector", { data: results }));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,62 +1,74 @@
|
||||
|
||||
erpnext.landed_cost_taxes_and_charges = {
|
||||
setup_triggers: function(doctype) {
|
||||
setup_triggers: function (doctype) {
|
||||
frappe.ui.form.on(doctype, {
|
||||
refresh: function(frm) {
|
||||
let tax_field = frm.doc.doctype == 'Landed Cost Voucher' ? 'taxes' : 'additional_costs';
|
||||
frm.set_query("expense_account", tax_field, function() {
|
||||
refresh: function (frm) {
|
||||
let tax_field = frm.doc.doctype == "Landed Cost Voucher" ? "taxes" : "additional_costs";
|
||||
frm.set_query("expense_account", tax_field, function () {
|
||||
return {
|
||||
filters: {
|
||||
"account_type": ['in', ["Tax", "Chargeable", "Income Account", "Expenses Included In Valuation", "Expenses Included In Asset Valuation"]],
|
||||
"company": frm.doc.company
|
||||
}
|
||||
account_type: [
|
||||
"in",
|
||||
[
|
||||
"Tax",
|
||||
"Chargeable",
|
||||
"Income Account",
|
||||
"Expenses Included In Valuation",
|
||||
"Expenses Included In Asset Valuation",
|
||||
],
|
||||
],
|
||||
company: frm.doc.company,
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
set_account_currency: function(frm, cdt, cdn) {
|
||||
set_account_currency: function (frm, cdt, cdn) {
|
||||
let row = locals[cdt][cdn];
|
||||
if (row.expense_account) {
|
||||
frappe.db.get_value('Account', row.expense_account, 'account_currency', function(value) {
|
||||
frappe.db.get_value("Account", row.expense_account, "account_currency", function (value) {
|
||||
frappe.model.set_value(cdt, cdn, "account_currency", value.account_currency);
|
||||
frm.events.set_exchange_rate(frm, cdt, cdn);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
set_exchange_rate: function(frm, cdt, cdn) {
|
||||
set_exchange_rate: function (frm, cdt, cdn) {
|
||||
let row = locals[cdt][cdn];
|
||||
let company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
|
||||
|
||||
if (row.account_currency == company_currency) {
|
||||
row.exchange_rate = 1;
|
||||
frm.set_df_property('taxes', 'hidden', 1, row.name, 'exchange_rate');
|
||||
frm.set_df_property("taxes", "hidden", 1, row.name, "exchange_rate");
|
||||
} else if (!row.exchange_rate || row.exchange_rate == 1) {
|
||||
frm.set_df_property('taxes', 'hidden', 0, row.name, 'exchange_rate');
|
||||
frm.set_df_property("taxes", "hidden", 0, row.name, "exchange_rate");
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_exchange_rate",
|
||||
args: {
|
||||
posting_date: frm.doc.posting_date,
|
||||
account: row.expense_account,
|
||||
account_currency: row.account_currency,
|
||||
company: frm.doc.company
|
||||
company: frm.doc.company,
|
||||
},
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
frappe.model.set_value(cdt, cdn, "exchange_rate", r.message);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
frm.refresh_field('taxes');
|
||||
frm.refresh_field("taxes");
|
||||
},
|
||||
|
||||
set_base_amount: function(frm, cdt, cdn) {
|
||||
set_base_amount: function (frm, cdt, cdn) {
|
||||
let row = locals[cdt][cdn];
|
||||
frappe.model.set_value(cdt, cdn, "base_amount",
|
||||
flt(flt(row.amount)*row.exchange_rate, precision("base_amount", row)));
|
||||
}
|
||||
frappe.model.set_value(
|
||||
cdt,
|
||||
cdn,
|
||||
"base_amount",
|
||||
flt(flt(row.amount) * row.exchange_rate, precision("base_amount", row))
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,60 +1,78 @@
|
||||
frappe.provide('erpnext.accounts');
|
||||
frappe.provide("erpnext.accounts");
|
||||
|
||||
erpnext.accounts.ledger_preview = {
|
||||
show_accounting_ledger_preview(frm) {
|
||||
let me = this;
|
||||
if(!frm.is_new() && frm.doc.docstatus == 0) {
|
||||
frm.add_custom_button(__('Accounting Ledger'), function() {
|
||||
frappe.call({
|
||||
"type": "GET",
|
||||
"method": "erpnext.controllers.stock_controller.show_accounting_ledger_preview",
|
||||
"args": {
|
||||
"company": frm.doc.company,
|
||||
"doctype": frm.doc.doctype,
|
||||
"docname": frm.doc.name
|
||||
},
|
||||
"callback": function(response) {
|
||||
me.make_dialog("Accounting Ledger Preview", "accounting_ledger_preview_html", response.message.gl_columns, response.message.gl_data);
|
||||
}
|
||||
})
|
||||
}, __("Preview"));
|
||||
if (!frm.is_new() && frm.doc.docstatus == 0) {
|
||||
frm.add_custom_button(
|
||||
__("Accounting Ledger"),
|
||||
function () {
|
||||
frappe.call({
|
||||
type: "GET",
|
||||
method: "erpnext.controllers.stock_controller.show_accounting_ledger_preview",
|
||||
args: {
|
||||
company: frm.doc.company,
|
||||
doctype: frm.doc.doctype,
|
||||
docname: frm.doc.name,
|
||||
},
|
||||
callback: function (response) {
|
||||
me.make_dialog(
|
||||
"Accounting Ledger Preview",
|
||||
"accounting_ledger_preview_html",
|
||||
response.message.gl_columns,
|
||||
response.message.gl_data
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
__("Preview")
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
show_stock_ledger_preview(frm) {
|
||||
let me = this
|
||||
if(!frm.is_new() && frm.doc.docstatus == 0) {
|
||||
frm.add_custom_button(__('Stock Ledger'), function() {
|
||||
frappe.call({
|
||||
"type": "GET",
|
||||
"method": "erpnext.controllers.stock_controller.show_stock_ledger_preview",
|
||||
"args": {
|
||||
"company": frm.doc.company,
|
||||
"doctype": frm.doc.doctype,
|
||||
"docname": frm.doc.name
|
||||
},
|
||||
"callback": function(response) {
|
||||
me.make_dialog("Stock Ledger Preview", "stock_ledger_preview_html", response.message.sl_columns, response.message.sl_data);
|
||||
}
|
||||
})
|
||||
}, __("Preview"));
|
||||
let me = this;
|
||||
if (!frm.is_new() && frm.doc.docstatus == 0) {
|
||||
frm.add_custom_button(
|
||||
__("Stock Ledger"),
|
||||
function () {
|
||||
frappe.call({
|
||||
type: "GET",
|
||||
method: "erpnext.controllers.stock_controller.show_stock_ledger_preview",
|
||||
args: {
|
||||
company: frm.doc.company,
|
||||
doctype: frm.doc.doctype,
|
||||
docname: frm.doc.name,
|
||||
},
|
||||
callback: function (response) {
|
||||
me.make_dialog(
|
||||
"Stock Ledger Preview",
|
||||
"stock_ledger_preview_html",
|
||||
response.message.sl_columns,
|
||||
response.message.sl_data
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
__("Preview")
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
make_dialog(label, fieldname, columns, data) {
|
||||
let me = this;
|
||||
let dialog = new frappe.ui.Dialog({
|
||||
"size": "extra-large",
|
||||
"title": __(label),
|
||||
"fields": [
|
||||
size: "extra-large",
|
||||
title: __(label),
|
||||
fields: [
|
||||
{
|
||||
"fieldtype": "HTML",
|
||||
"fieldname": fieldname,
|
||||
fieldtype: "HTML",
|
||||
fieldname: fieldname,
|
||||
},
|
||||
]
|
||||
],
|
||||
});
|
||||
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
me.get_datatable(columns, data, dialog.get_field(fieldname).wrapper);
|
||||
}, 200);
|
||||
|
||||
@@ -70,9 +88,6 @@ erpnext.accounts.ledger_preview = {
|
||||
inlineFilters: true,
|
||||
};
|
||||
|
||||
new frappe.DataTable(
|
||||
wrapper,
|
||||
datatable_options
|
||||
);
|
||||
}
|
||||
}
|
||||
new frappe.DataTable(wrapper, datatable_options);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3,18 +3,19 @@
|
||||
|
||||
frappe.provide("erpnext.utils");
|
||||
|
||||
const SALES_DOCTYPES = ['Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice'];
|
||||
const PURCHASE_DOCTYPES = ['Supplier Quotation','Purchase Order', 'Purchase Receipt', 'Purchase Invoice'];
|
||||
const SALES_DOCTYPES = ["Quotation", "Sales Order", "Delivery Note", "Sales Invoice"];
|
||||
const PURCHASE_DOCTYPES = ["Supplier Quotation", "Purchase Order", "Purchase Receipt", "Purchase Invoice"];
|
||||
|
||||
erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
||||
erpnext.utils.get_party_details = function (frm, method, args, callback) {
|
||||
if (!method) {
|
||||
method = "erpnext.accounts.party.get_party_details";
|
||||
}
|
||||
|
||||
if (!args) {
|
||||
if ((frm.doctype != "Purchase Order" && frm.doc.customer)
|
||||
|| (frm.doc.party_name && in_list(['Quotation', 'Opportunity'], frm.doc.doctype))) {
|
||||
|
||||
if (
|
||||
(frm.doctype != "Purchase Order" && frm.doc.customer) ||
|
||||
(frm.doc.party_name && in_list(["Quotation", "Opportunity"], frm.doc.doctype))
|
||||
) {
|
||||
let party_type = "Customer";
|
||||
if (frm.doc.quotation_to && in_list(["Lead", "Prospect"], frm.doc.quotation_to)) {
|
||||
party_type = frm.doc.quotation_to;
|
||||
@@ -23,14 +24,14 @@ erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
||||
args = {
|
||||
party: frm.doc.customer || frm.doc.party_name,
|
||||
party_type: party_type,
|
||||
price_list: frm.doc.selling_price_list
|
||||
price_list: frm.doc.selling_price_list,
|
||||
};
|
||||
} else if (frm.doc.supplier) {
|
||||
args = {
|
||||
party: frm.doc.supplier,
|
||||
party_type: "Supplier",
|
||||
bill_date: frm.doc.bill_date,
|
||||
price_list: frm.doc.buying_price_list
|
||||
price_list: frm.doc.buying_price_list,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -38,14 +39,14 @@ erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
||||
if (in_list(SALES_DOCTYPES, frm.doc.doctype)) {
|
||||
args = {
|
||||
party: frm.doc.customer || frm.doc.party_name,
|
||||
party_type: 'Customer'
|
||||
party_type: "Customer",
|
||||
};
|
||||
}
|
||||
|
||||
if (in_list(PURCHASE_DOCTYPES, frm.doc.doctype)) {
|
||||
args = {
|
||||
party: frm.doc.supplier,
|
||||
party_type: 'Supplier'
|
||||
party_type: "Supplier",
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -72,13 +73,26 @@ erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
|
||||
if (!erpnext.utils.validate_mandatory(frm, "Posting / Transaction Date",
|
||||
args.posting_date, args.party_type=="Customer" ? "customer": "supplier")) return;
|
||||
if (
|
||||
!erpnext.utils.validate_mandatory(
|
||||
frm,
|
||||
"Posting / Transaction Date",
|
||||
args.posting_date,
|
||||
args.party_type == "Customer" ? "customer" : "supplier"
|
||||
)
|
||||
)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!erpnext.utils.validate_mandatory(frm, "Company", frm.doc.company, args.party_type=="Customer" ? "customer": "supplier")) {
|
||||
if (
|
||||
!erpnext.utils.validate_mandatory(
|
||||
frm,
|
||||
"Company",
|
||||
frm.doc.company,
|
||||
args.party_type == "Customer" ? "customer" : "supplier"
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -88,7 +102,7 @@ erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
||||
frappe.call({
|
||||
method: method,
|
||||
args: args,
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
frm.supplier_tds = r.message.supplier_tds;
|
||||
frm.updating_party_details = true;
|
||||
@@ -99,28 +113,28 @@ erpnext.utils.get_party_details = function(frm, method, args, callback) {
|
||||
if (callback) callback();
|
||||
frm.refresh();
|
||||
erpnext.utils.add_item(frm);
|
||||
}
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
erpnext.utils.add_item = function(frm) {
|
||||
erpnext.utils.add_item = function (frm) {
|
||||
if (frm.is_new()) {
|
||||
var prev_route = frappe.get_prev_route();
|
||||
if (prev_route[1]==='Item' && !(frm.doc.items && frm.doc.items.length)) {
|
||||
if (prev_route[1] === "Item" && !(frm.doc.items && frm.doc.items.length)) {
|
||||
// add row
|
||||
var item = frm.add_child('items');
|
||||
frm.refresh_field('items');
|
||||
var item = frm.add_child("items");
|
||||
frm.refresh_field("items");
|
||||
|
||||
// set item
|
||||
frappe.model.set_value(item.doctype, item.name, 'item_code', prev_route[2]);
|
||||
frappe.model.set_value(item.doctype, item.name, "item_code", prev_route[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
erpnext.utils.get_address_display = function(frm, address_field, display_field, is_your_company_address) {
|
||||
erpnext.utils.get_address_display = function (frm, address_field, display_field, is_your_company_address) {
|
||||
if (frm.updating_party_details) return;
|
||||
|
||||
if (!address_field) {
|
||||
@@ -135,29 +149,46 @@ erpnext.utils.get_address_display = function(frm, address_field, display_field,
|
||||
if (frm.doc[address_field]) {
|
||||
frappe.call({
|
||||
method: "frappe.contacts.doctype.address.address.get_address_display",
|
||||
args: {"address_dict": frm.doc[address_field] },
|
||||
callback: function(r) {
|
||||
args: { address_dict: frm.doc[address_field] },
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
frm.set_value(display_field, r.message)
|
||||
frm.set_value(display_field, r.message);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
} else {
|
||||
frm.set_value(display_field, '');
|
||||
frm.set_value(display_field, "");
|
||||
}
|
||||
};
|
||||
|
||||
erpnext.utils.set_taxes_from_address = function(frm, triggered_from_field, billing_address_field, shipping_address_field) {
|
||||
erpnext.utils.set_taxes_from_address = function (
|
||||
frm,
|
||||
triggered_from_field,
|
||||
billing_address_field,
|
||||
shipping_address_field
|
||||
) {
|
||||
if (frm.updating_party_details) return;
|
||||
|
||||
if (frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
|
||||
if (!erpnext.utils.validate_mandatory(frm, "Lead / Customer / Supplier",
|
||||
frm.doc.customer || frm.doc.supplier || frm.doc.lead || frm.doc.party_name, triggered_from_field)) {
|
||||
if (
|
||||
!erpnext.utils.validate_mandatory(
|
||||
frm,
|
||||
"Lead / Customer / Supplier",
|
||||
frm.doc.customer || frm.doc.supplier || frm.doc.lead || frm.doc.party_name,
|
||||
triggered_from_field
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!erpnext.utils.validate_mandatory(frm, "Posting / Transaction Date",
|
||||
frm.doc.posting_date || frm.doc.transaction_date, triggered_from_field)) {
|
||||
if (
|
||||
!erpnext.utils.validate_mandatory(
|
||||
frm,
|
||||
"Posting / Transaction Date",
|
||||
frm.doc.posting_date || frm.doc.transaction_date,
|
||||
triggered_from_field
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -167,35 +198,47 @@ erpnext.utils.set_taxes_from_address = function(frm, triggered_from_field, billi
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.party.get_address_tax_category",
|
||||
args: {
|
||||
"tax_category": frm.doc.tax_category,
|
||||
"billing_address": frm.doc[billing_address_field],
|
||||
"shipping_address": frm.doc[shipping_address_field]
|
||||
tax_category: frm.doc.tax_category,
|
||||
billing_address: frm.doc[billing_address_field],
|
||||
shipping_address: frm.doc[shipping_address_field],
|
||||
},
|
||||
callback: function(r) {
|
||||
if (!r.exc){
|
||||
callback: function (r) {
|
||||
if (!r.exc) {
|
||||
if (frm.doc.tax_category != r.message) {
|
||||
frm.set_value("tax_category", r.message);
|
||||
} else {
|
||||
erpnext.utils.set_taxes(frm, triggered_from_field);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
erpnext.utils.set_taxes = function(frm, triggered_from_field) {
|
||||
erpnext.utils.set_taxes = function (frm, triggered_from_field) {
|
||||
if (frappe.meta.get_docfield(frm.doc.doctype, "taxes")) {
|
||||
if (!erpnext.utils.validate_mandatory(frm, "Company", frm.doc.company, triggered_from_field)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!erpnext.utils.validate_mandatory(frm, "Lead / Customer / Supplier",
|
||||
frm.doc.customer || frm.doc.supplier || frm.doc.lead || frm.doc.party_name, triggered_from_field)) {
|
||||
if (
|
||||
!erpnext.utils.validate_mandatory(
|
||||
frm,
|
||||
"Lead / Customer / Supplier",
|
||||
frm.doc.customer || frm.doc.supplier || frm.doc.lead || frm.doc.party_name,
|
||||
triggered_from_field
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!erpnext.utils.validate_mandatory(frm, "Posting / Transaction Date",
|
||||
frm.doc.posting_date || frm.doc.transaction_date, triggered_from_field)) {
|
||||
if (
|
||||
!erpnext.utils.validate_mandatory(
|
||||
frm,
|
||||
"Posting / Transaction Date",
|
||||
frm.doc.posting_date || frm.doc.transaction_date,
|
||||
triggered_from_field
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -204,15 +247,15 @@ erpnext.utils.set_taxes = function(frm, triggered_from_field) {
|
||||
|
||||
var party_type, party;
|
||||
if (frm.doc.lead) {
|
||||
party_type = 'Lead';
|
||||
party_type = "Lead";
|
||||
party = frm.doc.lead;
|
||||
} else if (frm.doc.customer) {
|
||||
party_type = 'Customer';
|
||||
party_type = "Customer";
|
||||
party = frm.doc.customer;
|
||||
} else if (frm.doc.supplier) {
|
||||
party_type = 'Supplier';
|
||||
party_type = "Supplier";
|
||||
party = frm.doc.supplier;
|
||||
} else if (frm.doc.quotation_to){
|
||||
} else if (frm.doc.quotation_to) {
|
||||
party_type = frm.doc.quotation_to;
|
||||
party = frm.doc.party_name;
|
||||
}
|
||||
@@ -224,21 +267,22 @@ erpnext.utils.set_taxes = function(frm, triggered_from_field) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.party.set_taxes",
|
||||
args: {
|
||||
"party": party,
|
||||
"party_type": party_type,
|
||||
"posting_date": frm.doc.posting_date || frm.doc.transaction_date,
|
||||
"company": frm.doc.company,
|
||||
"customer_group": frm.doc.customer_group,
|
||||
"supplier_group": frm.doc.supplier_group,
|
||||
"tax_category": frm.doc.tax_category,
|
||||
"billing_address": ((frm.doc.customer || frm.doc.lead) ? (frm.doc.customer_address) : (frm.doc.supplier_address)),
|
||||
"shipping_address": frm.doc.shipping_address_name
|
||||
party: party,
|
||||
party_type: party_type,
|
||||
posting_date: frm.doc.posting_date || frm.doc.transaction_date,
|
||||
company: frm.doc.company,
|
||||
customer_group: frm.doc.customer_group,
|
||||
supplier_group: frm.doc.supplier_group,
|
||||
tax_category: frm.doc.tax_category,
|
||||
billing_address:
|
||||
frm.doc.customer || frm.doc.lead ? frm.doc.customer_address : frm.doc.supplier_address,
|
||||
shipping_address: frm.doc.shipping_address_name,
|
||||
},
|
||||
callback: function(r) {
|
||||
if (r.message){
|
||||
frm.set_value("taxes_and_charges", r.message)
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
frm.set_value("taxes_and_charges", r.message);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -266,20 +310,23 @@ erpnext.utils.get_contact_details = function (frm) {
|
||||
}
|
||||
};
|
||||
|
||||
erpnext.utils.validate_mandatory = function(frm, label, value, trigger_on) {
|
||||
erpnext.utils.validate_mandatory = function (frm, label, value, trigger_on) {
|
||||
if (!value) {
|
||||
frm.doc[trigger_on] = "";
|
||||
refresh_field(trigger_on);
|
||||
frappe.throw({message:__("Please enter {0} first", [label]), title:__("Mandatory")});
|
||||
frappe.throw({ message: __("Please enter {0} first", [label]), title: __("Mandatory") });
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
erpnext.utils.get_shipping_address = function(frm, callback) {
|
||||
erpnext.utils.get_shipping_address = function (frm, callback) {
|
||||
if (frm.doc.company) {
|
||||
if ((frm.doc.inter_company_order_reference || frm.doc.internal_invoice_reference ||
|
||||
frm.doc.internal_order_reference)) {
|
||||
if (
|
||||
frm.doc.inter_company_order_reference ||
|
||||
frm.doc.internal_invoice_reference ||
|
||||
frm.doc.internal_order_reference
|
||||
) {
|
||||
if (callback) {
|
||||
return callback();
|
||||
}
|
||||
@@ -288,20 +335,20 @@ erpnext.utils.get_shipping_address = function(frm, callback) {
|
||||
method: "erpnext.accounts.custom.address.get_shipping_address",
|
||||
args: {
|
||||
company: frm.doc.company,
|
||||
address: frm.doc.shipping_address
|
||||
address: frm.doc.shipping_address,
|
||||
},
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
frm.set_value("shipping_address", r.message[0]) //Address title or name
|
||||
frm.set_value("shipping_address_display", r.message[1]) //Address to be displayed on the page
|
||||
frm.set_value("shipping_address", r.message[0]); //Address title or name
|
||||
frm.set_value("shipping_address_display", r.message[1]); //Address to be displayed on the page
|
||||
}
|
||||
|
||||
if (callback){
|
||||
if (callback) {
|
||||
return callback();
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
} else {
|
||||
frappe.msgprint(__("Select company first"));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
frappe.provide("erpnext.selling");
|
||||
|
||||
erpnext.sales_common = {
|
||||
setup_selling_controller:function() {
|
||||
setup_selling_controller: function () {
|
||||
erpnext.selling.SellingController = class SellingController extends erpnext.TransactionController {
|
||||
setup() {
|
||||
super.setup();
|
||||
@@ -15,107 +15,123 @@ erpnext.sales_common = {
|
||||
onload() {
|
||||
super.onload();
|
||||
this.setup_queries();
|
||||
this.frm.set_query('shipping_rule', function() {
|
||||
this.frm.set_query("shipping_rule", function () {
|
||||
return {
|
||||
filters: {
|
||||
"shipping_rule_type": "Selling"
|
||||
}
|
||||
shipping_rule_type: "Selling",
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
this.frm.set_query('project', function(doc) {
|
||||
this.frm.set_query("project", function (doc) {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.get_project_name",
|
||||
filters: {
|
||||
'customer': doc.customer
|
||||
}
|
||||
}
|
||||
customer: doc.customer,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
setup_queries() {
|
||||
var me = this;
|
||||
|
||||
$.each([["customer", "customer"],
|
||||
["lead", "lead"]],
|
||||
function(i, opts) {
|
||||
if(me.frm.fields_dict[opts[0]])
|
||||
me.frm.set_query(opts[0], erpnext.queries[opts[1]]);
|
||||
});
|
||||
$.each(
|
||||
[
|
||||
["customer", "customer"],
|
||||
["lead", "lead"],
|
||||
],
|
||||
function (i, opts) {
|
||||
if (me.frm.fields_dict[opts[0]]) me.frm.set_query(opts[0], erpnext.queries[opts[1]]);
|
||||
}
|
||||
);
|
||||
|
||||
me.frm.set_query('contact_person', erpnext.queries.contact_query);
|
||||
me.frm.set_query('customer_address', erpnext.queries.address_query);
|
||||
me.frm.set_query('shipping_address_name', erpnext.queries.address_query);
|
||||
me.frm.set_query('dispatch_address_name', erpnext.queries.dispatch_address_query);
|
||||
me.frm.set_query("contact_person", erpnext.queries.contact_query);
|
||||
me.frm.set_query("customer_address", erpnext.queries.address_query);
|
||||
me.frm.set_query("shipping_address_name", erpnext.queries.address_query);
|
||||
me.frm.set_query("dispatch_address_name", erpnext.queries.dispatch_address_query);
|
||||
|
||||
erpnext.accounts.dimensions.setup_dimension_filters(me.frm, me.frm.doctype);
|
||||
|
||||
if(this.frm.fields_dict.selling_price_list) {
|
||||
this.frm.set_query("selling_price_list", function() {
|
||||
if (this.frm.fields_dict.selling_price_list) {
|
||||
this.frm.set_query("selling_price_list", function () {
|
||||
return { filters: { selling: 1 } };
|
||||
});
|
||||
}
|
||||
|
||||
if(this.frm.fields_dict.tc_name) {
|
||||
this.frm.set_query("tc_name", function() {
|
||||
if (this.frm.fields_dict.tc_name) {
|
||||
this.frm.set_query("tc_name", function () {
|
||||
return { filters: { selling: 1 } };
|
||||
});
|
||||
}
|
||||
|
||||
if(!this.frm.fields_dict["items"]) {
|
||||
if (!this.frm.fields_dict["items"]) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.frm.fields_dict["items"].grid.get_field('item_code')) {
|
||||
this.frm.set_query("item_code", "items", function() {
|
||||
if (this.frm.fields_dict["items"].grid.get_field("item_code")) {
|
||||
this.frm.set_query("item_code", "items", function () {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.item_query",
|
||||
filters: {'is_sales_item': 1, 'customer': me.frm.doc.customer, 'has_variants': 0}
|
||||
}
|
||||
filters: { is_sales_item: 1, customer: me.frm.doc.customer, has_variants: 0 },
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
if(this.frm.fields_dict["packed_items"] &&
|
||||
this.frm.fields_dict["packed_items"].grid.get_field('batch_no')) {
|
||||
this.frm.set_query("batch_no", "packed_items", function(doc, cdt, cdn) {
|
||||
return me.set_query_for_batch(doc, cdt, cdn)
|
||||
if (
|
||||
this.frm.fields_dict["packed_items"] &&
|
||||
this.frm.fields_dict["packed_items"].grid.get_field("batch_no")
|
||||
) {
|
||||
this.frm.set_query("batch_no", "packed_items", function (doc, cdt, cdn) {
|
||||
return me.set_query_for_batch(doc, cdt, cdn);
|
||||
});
|
||||
}
|
||||
|
||||
if(this.frm.fields_dict["items"].grid.get_field('item_code')) {
|
||||
this.frm.set_query("item_tax_template", "items", function(doc, cdt, cdn) {
|
||||
return me.set_query_for_item_tax_template(doc, cdt, cdn)
|
||||
if (this.frm.fields_dict["items"].grid.get_field("item_code")) {
|
||||
this.frm.set_query("item_tax_template", "items", function (doc, cdt, cdn) {
|
||||
return me.set_query_for_item_tax_template(doc, cdt, cdn);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
refresh() {
|
||||
super.refresh();
|
||||
|
||||
frappe.dynamic_link = {doc: this.frm.doc, fieldname: 'customer', doctype: 'Customer'}
|
||||
frappe.dynamic_link = { doc: this.frm.doc, fieldname: "customer", doctype: "Customer" };
|
||||
|
||||
this.frm.toggle_display("customer_name",
|
||||
(this.frm.doc.customer_name && this.frm.doc.customer_name!==this.frm.doc.customer));
|
||||
this.frm.toggle_display(
|
||||
"customer_name",
|
||||
this.frm.doc.customer_name && this.frm.doc.customer_name !== this.frm.doc.customer
|
||||
);
|
||||
|
||||
this.toggle_editable_price_list_rate();
|
||||
}
|
||||
|
||||
customer() {
|
||||
var me = this;
|
||||
erpnext.utils.get_party_details(this.frm, null, null, function() {
|
||||
erpnext.utils.get_party_details(this.frm, null, null, function () {
|
||||
me.apply_price_list();
|
||||
});
|
||||
}
|
||||
|
||||
customer_address() {
|
||||
erpnext.utils.get_address_display(this.frm, "customer_address");
|
||||
erpnext.utils.set_taxes_from_address(this.frm, "customer_address", "customer_address", "shipping_address_name");
|
||||
erpnext.utils.set_taxes_from_address(
|
||||
this.frm,
|
||||
"customer_address",
|
||||
"customer_address",
|
||||
"shipping_address_name"
|
||||
);
|
||||
}
|
||||
|
||||
shipping_address_name() {
|
||||
erpnext.utils.get_address_display(this.frm, "shipping_address_name", "shipping_address");
|
||||
erpnext.utils.set_taxes_from_address(this.frm, "shipping_address_name", "customer_address", "shipping_address_name");
|
||||
erpnext.utils.set_taxes_from_address(
|
||||
this.frm,
|
||||
"shipping_address_name",
|
||||
"customer_address",
|
||||
"shipping_address_name"
|
||||
);
|
||||
}
|
||||
|
||||
dispatch_address_name() {
|
||||
@@ -138,18 +154,17 @@ erpnext.sales_common = {
|
||||
discount_percentage(doc, cdt, cdn) {
|
||||
var item = frappe.get_doc(cdt, cdn);
|
||||
item.discount_amount = 0.0;
|
||||
this.apply_discount_on_item(doc, cdt, cdn, 'discount_percentage');
|
||||
this.apply_discount_on_item(doc, cdt, cdn, "discount_percentage");
|
||||
}
|
||||
|
||||
discount_amount(doc, cdt, cdn) {
|
||||
|
||||
if(doc.name === cdn) {
|
||||
if (doc.name === cdn) {
|
||||
return;
|
||||
}
|
||||
|
||||
var item = frappe.get_doc(cdt, cdn);
|
||||
item.discount_percentage = 0.0;
|
||||
this.apply_discount_on_item(doc, cdt, cdn, 'discount_amount');
|
||||
this.apply_discount_on_item(doc, cdt, cdn, "discount_amount");
|
||||
}
|
||||
|
||||
commission_rate() {
|
||||
@@ -157,40 +172,48 @@ erpnext.sales_common = {
|
||||
}
|
||||
|
||||
total_commission() {
|
||||
frappe.model.round_floats_in(this.frm.doc, ["amount_eligible_for_commission", "total_commission"]);
|
||||
frappe.model.round_floats_in(this.frm.doc, [
|
||||
"amount_eligible_for_commission",
|
||||
"total_commission",
|
||||
]);
|
||||
|
||||
const { amount_eligible_for_commission } = this.frm.doc;
|
||||
if(!amount_eligible_for_commission) return;
|
||||
if (!amount_eligible_for_commission) return;
|
||||
|
||||
this.frm.set_value(
|
||||
"commission_rate", flt(
|
||||
this.frm.doc.total_commission * 100.0 / amount_eligible_for_commission
|
||||
)
|
||||
"commission_rate",
|
||||
flt((this.frm.doc.total_commission * 100.0) / amount_eligible_for_commission)
|
||||
);
|
||||
}
|
||||
|
||||
allocated_percentage(doc, cdt, cdn) {
|
||||
var sales_person = frappe.get_doc(cdt, cdn);
|
||||
if(sales_person.allocated_percentage) {
|
||||
if (sales_person.allocated_percentage) {
|
||||
sales_person.allocated_percentage = flt(
|
||||
sales_person.allocated_percentage,
|
||||
precision("allocated_percentage", sales_person)
|
||||
);
|
||||
|
||||
sales_person.allocated_percentage = flt(sales_person.allocated_percentage,
|
||||
precision("allocated_percentage", sales_person));
|
||||
|
||||
sales_person.allocated_amount = flt(this.frm.doc.amount_eligible_for_commission *
|
||||
sales_person.allocated_percentage / 100.0,
|
||||
precision("allocated_amount", sales_person));
|
||||
refresh_field(["allocated_amount"], sales_person);
|
||||
sales_person.allocated_amount = flt(
|
||||
(this.frm.doc.amount_eligible_for_commission * sales_person.allocated_percentage) /
|
||||
100.0,
|
||||
precision("allocated_amount", sales_person)
|
||||
);
|
||||
refresh_field(["allocated_amount"], sales_person);
|
||||
|
||||
this.calculate_incentive(sales_person);
|
||||
refresh_field(["allocated_percentage", "allocated_amount", "commission_rate","incentives"], sales_person.name,
|
||||
sales_person.parentfield);
|
||||
refresh_field(
|
||||
["allocated_percentage", "allocated_amount", "commission_rate", "incentives"],
|
||||
sales_person.name,
|
||||
sales_person.parentfield
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
sales_person(doc, cdt, cdn) {
|
||||
var row = frappe.get_doc(cdt, cdn);
|
||||
this.calculate_incentive(row);
|
||||
refresh_field("incentives",row.name,row.parentfield);
|
||||
refresh_field("incentives", row.name, row.parentfield);
|
||||
}
|
||||
|
||||
warehouse(doc, cdt, cdn) {
|
||||
@@ -200,35 +223,47 @@ erpnext.sales_common = {
|
||||
}
|
||||
|
||||
toggle_editable_price_list_rate() {
|
||||
var df = frappe.meta.get_docfield(this.frm.doc.doctype + " Item", "price_list_rate", this.frm.doc.name);
|
||||
var df = frappe.meta.get_docfield(
|
||||
this.frm.doc.doctype + " Item",
|
||||
"price_list_rate",
|
||||
this.frm.doc.name
|
||||
);
|
||||
var editable_price_list_rate = cint(frappe.defaults.get_default("editable_price_list_rate"));
|
||||
|
||||
if(df && editable_price_list_rate) {
|
||||
const parent_field = frappe.meta.get_parentfield(this.frm.doc.doctype, this.frm.doc.doctype + " Item");
|
||||
if (df && editable_price_list_rate) {
|
||||
const parent_field = frappe.meta.get_parentfield(
|
||||
this.frm.doc.doctype,
|
||||
this.frm.doc.doctype + " Item"
|
||||
);
|
||||
if (!this.frm.fields_dict[parent_field]) return;
|
||||
|
||||
this.frm.fields_dict[parent_field].grid.update_docfield_property(
|
||||
'price_list_rate', 'read_only', 0
|
||||
"price_list_rate",
|
||||
"read_only",
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
calculate_commission() {
|
||||
if(!this.frm.fields_dict.commission_rate || this.frm.doc.docstatus === 1) return;
|
||||
if (!this.frm.fields_dict.commission_rate || this.frm.doc.docstatus === 1) return;
|
||||
|
||||
if(this.frm.doc.commission_rate > 100) {
|
||||
if (this.frm.doc.commission_rate > 100) {
|
||||
this.frm.set_value("commission_rate", 100);
|
||||
frappe.throw(`${__(frappe.meta.get_label(
|
||||
this.frm.doc.doctype, "commission_rate", this.frm.doc.name
|
||||
))} ${__("cannot be greater than 100")}`);
|
||||
frappe.throw(
|
||||
`${__(
|
||||
frappe.meta.get_label(this.frm.doc.doctype, "commission_rate", this.frm.doc.name)
|
||||
)} ${__("cannot be greater than 100")}`
|
||||
);
|
||||
}
|
||||
|
||||
this.frm.doc.amount_eligible_for_commission = this.frm.doc.items.reduce(
|
||||
(sum, item) => item.grant_commission ? sum + item.base_net_amount : sum, 0
|
||||
)
|
||||
(sum, item) => (item.grant_commission ? sum + item.base_net_amount : sum),
|
||||
0
|
||||
);
|
||||
|
||||
this.frm.doc.total_commission = flt(
|
||||
this.frm.doc.amount_eligible_for_commission * this.frm.doc.commission_rate / 100.0,
|
||||
(this.frm.doc.amount_eligible_for_commission * this.frm.doc.commission_rate) / 100.0,
|
||||
precision("total_commission")
|
||||
);
|
||||
|
||||
@@ -237,25 +272,24 @@ erpnext.sales_common = {
|
||||
|
||||
calculate_contribution() {
|
||||
var me = this;
|
||||
$.each(this.frm.doc.doctype.sales_team || [], function(i, sales_person) {
|
||||
$.each(this.frm.doc.doctype.sales_team || [], function (i, sales_person) {
|
||||
frappe.model.round_floats_in(sales_person);
|
||||
if (!sales_person.allocated_percentage) return;
|
||||
|
||||
sales_person.allocated_amount = flt(
|
||||
me.frm.doc.amount_eligible_for_commission
|
||||
* sales_person.allocated_percentage
|
||||
/ 100.0,
|
||||
(me.frm.doc.amount_eligible_for_commission * sales_person.allocated_percentage) /
|
||||
100.0,
|
||||
precision("allocated_amount", sales_person)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
calculate_incentive(row) {
|
||||
if(row.allocated_amount)
|
||||
{
|
||||
if (row.allocated_amount) {
|
||||
row.incentives = flt(
|
||||
row.allocated_amount * row.commission_rate / 100.0,
|
||||
precision("incentives", row));
|
||||
(row.allocated_amount * row.commission_rate) / 100.0,
|
||||
precision("incentives", row)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,37 +299,41 @@ erpnext.sales_common = {
|
||||
}
|
||||
|
||||
set_product_bundle_help(doc) {
|
||||
if(!this.frm.fields_dict.packing_list) return;
|
||||
if (!this.frm.fields_dict.packing_list) return;
|
||||
if ((doc.packed_items || []).length) {
|
||||
$(this.frm.fields_dict.packing_list.row.wrapper).toggle(true);
|
||||
|
||||
if (in_list(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||
var help_msg = "<div class='alert alert-warning'>" +
|
||||
__("For 'Product Bundle' items, Warehouse, Serial No and Batch No will be considered from the 'Packing List' table. If Warehouse and Batch No are same for all packing items for any 'Product Bundle' item, those values can be entered in the main Item table, values will be copied to 'Packing List' table.")+
|
||||
"</div>";
|
||||
frappe.meta.get_docfield(doc.doctype, 'product_bundle_help', doc.name).options = help_msg;
|
||||
if (in_list(["Delivery Note", "Sales Invoice"], doc.doctype)) {
|
||||
var help_msg =
|
||||
"<div class='alert alert-warning'>" +
|
||||
__(
|
||||
"For 'Product Bundle' items, Warehouse, Serial No and Batch No will be considered from the 'Packing List' table. If Warehouse and Batch No are same for all packing items for any 'Product Bundle' item, those values can be entered in the main Item table, values will be copied to 'Packing List' table."
|
||||
) +
|
||||
"</div>";
|
||||
frappe.meta.get_docfield(doc.doctype, "product_bundle_help", doc.name).options =
|
||||
help_msg;
|
||||
}
|
||||
} else {
|
||||
$(this.frm.fields_dict.packing_list.row.wrapper).toggle(false);
|
||||
if (in_list(['Delivery Note', 'Sales Invoice'], doc.doctype)) {
|
||||
frappe.meta.get_docfield(doc.doctype, 'product_bundle_help', doc.name).options = '';
|
||||
if (in_list(["Delivery Note", "Sales Invoice"], doc.doctype)) {
|
||||
frappe.meta.get_docfield(doc.doctype, "product_bundle_help", doc.name).options = "";
|
||||
}
|
||||
}
|
||||
refresh_field('product_bundle_help');
|
||||
refresh_field("product_bundle_help");
|
||||
}
|
||||
|
||||
company_address() {
|
||||
var me = this;
|
||||
if(this.frm.doc.company_address) {
|
||||
if (this.frm.doc.company_address) {
|
||||
frappe.call({
|
||||
method: "frappe.contacts.doctype.address.address.get_address_display",
|
||||
args: {"address_dict": this.frm.doc.company_address },
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
me.frm.set_value("company_address_display", r.message)
|
||||
args: { address_dict: this.frm.doc.company_address },
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
me.frm.set_value("company_address_display", r.message);
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this.frm.set_value("company_address_display", "");
|
||||
}
|
||||
@@ -314,79 +352,96 @@ erpnext.sales_common = {
|
||||
let me = this;
|
||||
let path = "assets/erpnext/js/utils/serial_no_batch_selector.js";
|
||||
|
||||
frappe.db.get_value("Item", item.item_code, ["has_batch_no", "has_serial_no"])
|
||||
.then((r) => {
|
||||
if (r.message && (r.message.has_batch_no || r.message.has_serial_no)) {
|
||||
item.has_serial_no = r.message.has_serial_no;
|
||||
item.has_batch_no = r.message.has_batch_no;
|
||||
item.type_of_transaction = item.qty > 0 ? "Outward":"Inward";
|
||||
frappe.db.get_value("Item", item.item_code, ["has_batch_no", "has_serial_no"]).then((r) => {
|
||||
if (r.message && (r.message.has_batch_no || r.message.has_serial_no)) {
|
||||
item.has_serial_no = r.message.has_serial_no;
|
||||
item.has_batch_no = r.message.has_batch_no;
|
||||
item.type_of_transaction = item.qty > 0 ? "Outward" : "Inward";
|
||||
|
||||
item.title = item.has_serial_no ?
|
||||
__("Select Serial No") : __("Select Batch No");
|
||||
item.title = item.has_serial_no ? __("Select Serial No") : __("Select Batch No");
|
||||
|
||||
if (item.has_serial_no && item.has_batch_no) {
|
||||
item.title = __("Select Serial and Batch");
|
||||
}
|
||||
|
||||
frappe.require(path, function() {
|
||||
new erpnext.SerialBatchPackageSelector(
|
||||
me.frm, item, (r) => {
|
||||
if (r) {
|
||||
let qty = Math.abs(r.total_qty);
|
||||
if (doc.is_return) {
|
||||
qty = qty * -1;
|
||||
}
|
||||
|
||||
frappe.model.set_value(item.doctype, item.name, {
|
||||
"serial_and_batch_bundle": r.name,
|
||||
"use_serial_batch_fields": 0,
|
||||
"qty": qty / flt(item.conversion_factor || 1, precision("conversion_factor", item))
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
if (item.has_serial_no && item.has_batch_no) {
|
||||
item.title = __("Select Serial and Batch");
|
||||
}
|
||||
});
|
||||
|
||||
frappe.require(path, function () {
|
||||
new erpnext.SerialBatchPackageSelector(me.frm, item, (r) => {
|
||||
if (r) {
|
||||
let qty = Math.abs(r.total_qty);
|
||||
if (doc.is_return) {
|
||||
qty = qty * -1;
|
||||
}
|
||||
|
||||
frappe.model.set_value(item.doctype, item.name, {
|
||||
serial_and_batch_bundle: r.name,
|
||||
use_serial_batch_fields: 0,
|
||||
qty:
|
||||
qty /
|
||||
flt(
|
||||
item.conversion_factor || 1,
|
||||
precision("conversion_factor", item)
|
||||
),
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
update_auto_repeat_reference(doc) {
|
||||
if (doc.auto_repeat) {
|
||||
frappe.call({
|
||||
method:"frappe.automation.doctype.auto_repeat.auto_repeat.update_reference",
|
||||
args:{
|
||||
method: "frappe.automation.doctype.auto_repeat.auto_repeat.update_reference",
|
||||
args: {
|
||||
docname: doc.auto_repeat,
|
||||
reference:doc.name
|
||||
reference: doc.name,
|
||||
},
|
||||
callback: function(r){
|
||||
if (r.message=="success") {
|
||||
frappe.show_alert({message:__("Auto repeat document updated"), indicator:'green'});
|
||||
callback: function (r) {
|
||||
if (r.message == "success") {
|
||||
frappe.show_alert({
|
||||
message: __("Auto repeat document updated"),
|
||||
indicator: "green",
|
||||
});
|
||||
} else {
|
||||
frappe.show_alert({message:__("An error occurred during the update process"), indicator:'red'});
|
||||
frappe.show_alert({
|
||||
message: __("An error occurred during the update process"),
|
||||
indicator: "red",
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
project() {
|
||||
let me = this;
|
||||
if(in_list(["Delivery Note", "Sales Invoice", "Sales Order"], this.frm.doc.doctype)) {
|
||||
if(this.frm.doc.project) {
|
||||
if (in_list(["Delivery Note", "Sales Invoice", "Sales Order"], this.frm.doc.doctype)) {
|
||||
if (this.frm.doc.project) {
|
||||
frappe.call({
|
||||
method:'erpnext.projects.doctype.project.project.get_cost_center_name' ,
|
||||
args: {project: this.frm.doc.project},
|
||||
callback: function(r, rt) {
|
||||
if(!r.exc) {
|
||||
$.each(me.frm.doc["items"] || [], function(i, row) {
|
||||
if(r.message) {
|
||||
frappe.model.set_value(row.doctype, row.name, "cost_center", r.message);
|
||||
frappe.msgprint(__("Cost Center For Item with Item Code {0} has been Changed to {1}", [row.item_name, r.message]));
|
||||
method: "erpnext.projects.doctype.project.project.get_cost_center_name",
|
||||
args: { project: this.frm.doc.project },
|
||||
callback: function (r, rt) {
|
||||
if (!r.exc) {
|
||||
$.each(me.frm.doc["items"] || [], function (i, row) {
|
||||
if (r.message) {
|
||||
frappe.model.set_value(
|
||||
row.doctype,
|
||||
row.name,
|
||||
"cost_center",
|
||||
r.message
|
||||
);
|
||||
frappe.msgprint(
|
||||
__(
|
||||
"Cost Center For Item with Item Code {0} has been Changed to {1}",
|
||||
[row.item_name, r.message]
|
||||
)
|
||||
);
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -396,57 +451,60 @@ erpnext.sales_common = {
|
||||
this.frm.set_value("additional_discount_percentage", 0);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
erpnext.pre_sales = {
|
||||
set_as_lost: function(doctype) {
|
||||
set_as_lost: function (doctype) {
|
||||
frappe.ui.form.on(doctype, {
|
||||
set_as_lost_dialog: function(frm) {
|
||||
set_as_lost_dialog: function (frm) {
|
||||
var dialog = new frappe.ui.Dialog({
|
||||
title: __("Set as Lost"),
|
||||
fields: [
|
||||
{
|
||||
"fieldtype": "Table MultiSelect",
|
||||
"label": __("Lost Reasons"),
|
||||
"fieldname": "lost_reason",
|
||||
"options": frm.doctype === 'Opportunity' ? 'Opportunity Lost Reason Detail': 'Quotation Lost Reason Detail',
|
||||
"reqd": 1
|
||||
fieldtype: "Table MultiSelect",
|
||||
label: __("Lost Reasons"),
|
||||
fieldname: "lost_reason",
|
||||
options:
|
||||
frm.doctype === "Opportunity"
|
||||
? "Opportunity Lost Reason Detail"
|
||||
: "Quotation Lost Reason Detail",
|
||||
reqd: 1,
|
||||
},
|
||||
{
|
||||
"fieldtype": "Table MultiSelect",
|
||||
"label": __("Competitors"),
|
||||
"fieldname": "competitors",
|
||||
"options": "Competitor Detail"
|
||||
fieldtype: "Table MultiSelect",
|
||||
label: __("Competitors"),
|
||||
fieldname: "competitors",
|
||||
options: "Competitor Detail",
|
||||
},
|
||||
{
|
||||
"fieldtype": "Small Text",
|
||||
"label": __("Detailed Reason"),
|
||||
"fieldname": "detailed_reason"
|
||||
fieldtype: "Small Text",
|
||||
label: __("Detailed Reason"),
|
||||
fieldname: "detailed_reason",
|
||||
},
|
||||
],
|
||||
primary_action: function() {
|
||||
primary_action: function () {
|
||||
let values = dialog.get_values();
|
||||
|
||||
frm.call({
|
||||
doc: frm.doc,
|
||||
method: 'declare_enquiry_lost',
|
||||
method: "declare_enquiry_lost",
|
||||
args: {
|
||||
'lost_reasons_list': values.lost_reason,
|
||||
'competitors': values.competitors ? values.competitors : [],
|
||||
'detailed_reason': values.detailed_reason
|
||||
lost_reasons_list: values.lost_reason,
|
||||
competitors: values.competitors ? values.competitors : [],
|
||||
detailed_reason: values.detailed_reason,
|
||||
},
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
dialog.hide();
|
||||
frm.reload_doc();
|
||||
},
|
||||
});
|
||||
},
|
||||
primary_action_label: __('Declare Lost')
|
||||
primary_action_label: __("Declare Lost"),
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -4,30 +4,30 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
this.item = item;
|
||||
this.qty = item.qty;
|
||||
this.callback = callback;
|
||||
this.bundle = this.item?.is_rejected ?
|
||||
this.item.rejected_serial_and_batch_bundle : this.item.serial_and_batch_bundle;
|
||||
this.bundle = this.item?.is_rejected
|
||||
? this.item.rejected_serial_and_batch_bundle
|
||||
: this.item.serial_and_batch_bundle;
|
||||
|
||||
this.make();
|
||||
this.render_data();
|
||||
}
|
||||
|
||||
make() {
|
||||
let label = this.item?.has_serial_no ? __('Serial Nos') : __('Batch Nos');
|
||||
let primary_label = this.bundle
|
||||
? __('Update') : __('Add');
|
||||
let label = this.item?.has_serial_no ? __("Serial Nos") : __("Batch Nos");
|
||||
let primary_label = this.bundle ? __("Update") : __("Add");
|
||||
|
||||
if (this.item?.has_serial_no && this.item?.batch_no) {
|
||||
label = __('Serial Nos / Batch Nos');
|
||||
label = __("Serial Nos / Batch Nos");
|
||||
}
|
||||
|
||||
primary_label += ' ' + label;
|
||||
primary_label += " " + label;
|
||||
|
||||
this.dialog = new frappe.ui.Dialog({
|
||||
title: this.item?.title || primary_label,
|
||||
fields: this.get_dialog_fields(),
|
||||
primary_action_label: primary_label,
|
||||
primary_action: () => this.update_bundle_entries(),
|
||||
secondary_action_label: __('Edit Full Form'),
|
||||
secondary_action_label: __("Edit Full Form"),
|
||||
secondary_action: () => this.edit_full_form(),
|
||||
});
|
||||
|
||||
@@ -45,21 +45,21 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
if (qty > 0) {
|
||||
this.dialog.set_value("qty", qty).then(() => {
|
||||
if (this.item.serial_no && !this.item.serial_and_batch_bundle) {
|
||||
let serial_nos = this.item.serial_no.split('\n');
|
||||
let serial_nos = this.item.serial_no.split("\n");
|
||||
if (serial_nos.length > 1) {
|
||||
serial_nos.forEach(serial_no => {
|
||||
serial_nos.forEach((serial_no) => {
|
||||
this.dialog.fields_dict.entries.df.data.push({
|
||||
serial_no: serial_no,
|
||||
batch_no: this.item.batch_no
|
||||
batch_no: this.item.batch_no,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
this.dialog.set_value("scan_serial_no", this.item.serial_no);
|
||||
}
|
||||
frappe.model.set_value(this.item.doctype, this.item.name, 'serial_no', '');
|
||||
frappe.model.set_value(this.item.doctype, this.item.name, "serial_no", "");
|
||||
} else if (this.item.batch_no && !this.item.serial_and_batch_bundle) {
|
||||
this.dialog.set_value("scan_batch_no", this.item.batch_no);
|
||||
frappe.model.set_value(this.item.doctype, this.item.name, 'batch_no', '');
|
||||
frappe.model.set_value(this.item.doctype, this.item.name, "batch_no", "");
|
||||
}
|
||||
|
||||
this.dialog.fields_dict.entries.grid.refresh();
|
||||
@@ -68,20 +68,20 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
}
|
||||
|
||||
get_serial_no_filters() {
|
||||
let warehouse = this.item?.type_of_transaction === "Outward" ?
|
||||
(this.item.warehouse || this.item.s_warehouse) : "";
|
||||
let warehouse =
|
||||
this.item?.type_of_transaction === "Outward" ? this.item.warehouse || this.item.s_warehouse : "";
|
||||
|
||||
if (this.frm.doc.doctype === 'Stock Entry') {
|
||||
if (this.frm.doc.doctype === "Stock Entry") {
|
||||
warehouse = this.item.s_warehouse || this.item.t_warehouse;
|
||||
}
|
||||
|
||||
if (!warehouse && this.frm.doc.doctype === 'Stock Reconciliation') {
|
||||
if (!warehouse && this.frm.doc.doctype === "Stock Reconciliation") {
|
||||
warehouse = this.get_warehouse();
|
||||
}
|
||||
|
||||
return {
|
||||
'item_code': this.item.item_code,
|
||||
'warehouse': ["=", warehouse]
|
||||
item_code: this.item.item_code,
|
||||
warehouse: ["=", warehouse],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -89,71 +89,70 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
let fields = [];
|
||||
|
||||
fields.push({
|
||||
fieldtype: 'Link',
|
||||
fieldname: 'warehouse',
|
||||
label: __('Warehouse'),
|
||||
options: 'Warehouse',
|
||||
fieldtype: "Link",
|
||||
fieldname: "warehouse",
|
||||
label: __("Warehouse"),
|
||||
options: "Warehouse",
|
||||
default: this.get_warehouse(),
|
||||
onchange: () => {
|
||||
this.item.warehouse = this.dialog.get_value('warehouse');
|
||||
this.get_auto_data()
|
||||
this.item.warehouse = this.dialog.get_value("warehouse");
|
||||
this.get_auto_data();
|
||||
},
|
||||
get_query: () => {
|
||||
return {
|
||||
filters: {
|
||||
'is_group': 0,
|
||||
'company': this.frm.doc.company,
|
||||
}
|
||||
is_group: 0,
|
||||
company: this.frm.doc.company,
|
||||
},
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (this.frm.doc.doctype === 'Stock Entry'
|
||||
&& this.frm.doc.purpose === 'Manufacture') {
|
||||
if (this.frm.doc.doctype === "Stock Entry" && this.frm.doc.purpose === "Manufacture") {
|
||||
fields.push({
|
||||
fieldtype: 'Column Break',
|
||||
fieldtype: "Column Break",
|
||||
});
|
||||
|
||||
fields.push({
|
||||
fieldtype: 'Link',
|
||||
fieldname: 'work_order',
|
||||
label: __('For Work Order'),
|
||||
options: 'Work Order',
|
||||
fieldtype: "Link",
|
||||
fieldname: "work_order",
|
||||
label: __("For Work Order"),
|
||||
options: "Work Order",
|
||||
read_only: 1,
|
||||
default: this.frm.doc.work_order,
|
||||
});
|
||||
|
||||
fields.push({
|
||||
fieldtype: 'Section Break',
|
||||
fieldtype: "Section Break",
|
||||
});
|
||||
}
|
||||
|
||||
fields.push({
|
||||
fieldtype: 'Column Break',
|
||||
fieldtype: "Column Break",
|
||||
});
|
||||
|
||||
if (this.item.has_serial_no) {
|
||||
fields.push({
|
||||
fieldtype: 'Data',
|
||||
options: 'Barcode',
|
||||
fieldname: 'scan_serial_no',
|
||||
label: __('Scan Serial No'),
|
||||
fieldtype: "Data",
|
||||
options: "Barcode",
|
||||
fieldname: "scan_serial_no",
|
||||
label: __("Scan Serial No"),
|
||||
get_query: () => {
|
||||
return {
|
||||
filters: this.get_serial_no_filters()
|
||||
filters: this.get_serial_no_filters(),
|
||||
};
|
||||
},
|
||||
onchange: () => this.scan_barcode_data()
|
||||
onchange: () => this.scan_barcode_data(),
|
||||
});
|
||||
}
|
||||
|
||||
if (this.item.has_batch_no && !this.item.has_serial_no) {
|
||||
fields.push({
|
||||
fieldtype: 'Data',
|
||||
options: 'Barcode',
|
||||
fieldname: 'scan_batch_no',
|
||||
label: __('Scan Batch No'),
|
||||
onchange: () => this.scan_barcode_data()
|
||||
fieldtype: "Data",
|
||||
options: "Barcode",
|
||||
fieldname: "scan_batch_no",
|
||||
label: __("Scan Batch No"),
|
||||
onchange: () => this.scan_barcode_data(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -164,12 +163,12 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
}
|
||||
|
||||
fields.push({
|
||||
fieldtype: 'Section Break',
|
||||
fieldtype: "Section Break",
|
||||
});
|
||||
|
||||
fields.push({
|
||||
fieldname: 'entries',
|
||||
fieldtype: 'Table',
|
||||
fieldname: "entries",
|
||||
fieldtype: "Table",
|
||||
allow_bulk_edit: true,
|
||||
data: [],
|
||||
fields: this.get_dialog_table_fields(),
|
||||
@@ -179,94 +178,95 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
}
|
||||
|
||||
get_attach_field() {
|
||||
let label = this.item?.has_serial_no ? __('Serial Nos') : __('Batch Nos');
|
||||
let primary_label = this.bundle
|
||||
? __('Update') : __('Add');
|
||||
let label = this.item?.has_serial_no ? __("Serial Nos") : __("Batch Nos");
|
||||
let primary_label = this.bundle ? __("Update") : __("Add");
|
||||
|
||||
if (this.item?.has_serial_no && this.item?.has_batch_no) {
|
||||
label = __('Serial Nos / Batch Nos');
|
||||
label = __("Serial Nos / Batch Nos");
|
||||
}
|
||||
|
||||
let fields = [
|
||||
{
|
||||
fieldtype: 'Section Break',
|
||||
label: __('{0} {1} via CSV File', [primary_label, label])
|
||||
}
|
||||
]
|
||||
fieldtype: "Section Break",
|
||||
label: __("{0} {1} via CSV File", [primary_label, label]),
|
||||
},
|
||||
];
|
||||
|
||||
if (this.item?.has_serial_no) {
|
||||
fields = [...fields,
|
||||
fields = [
|
||||
...fields,
|
||||
{
|
||||
fieldtype: 'Check',
|
||||
label: __('Import Using CSV file'),
|
||||
fieldname: 'import_using_csv_file',
|
||||
fieldtype: "Check",
|
||||
label: __("Import Using CSV file"),
|
||||
fieldname: "import_using_csv_file",
|
||||
default: 0,
|
||||
},
|
||||
{
|
||||
fieldtype: 'Section Break',
|
||||
label: __('{0} {1} Manually', [primary_label, label]),
|
||||
depends_on: 'eval:doc.import_using_csv_file === 0',
|
||||
fieldtype: "Section Break",
|
||||
label: __("{0} {1} Manually", [primary_label, label]),
|
||||
depends_on: "eval:doc.import_using_csv_file === 0",
|
||||
},
|
||||
{
|
||||
fieldtype: 'Small Text',
|
||||
label: __('Enter Serial Nos'),
|
||||
fieldname: 'upload_serial_nos',
|
||||
depends_on: 'eval:doc.import_using_csv_file === 0',
|
||||
description: __('Enter each serial no in a new line'),
|
||||
fieldtype: "Small Text",
|
||||
label: __("Enter Serial Nos"),
|
||||
fieldname: "upload_serial_nos",
|
||||
depends_on: "eval:doc.import_using_csv_file === 0",
|
||||
description: __("Enter each serial no in a new line"),
|
||||
},
|
||||
{
|
||||
fieldtype: 'Column Break',
|
||||
depends_on: 'eval:doc.import_using_csv_file === 0',
|
||||
fieldtype: "Column Break",
|
||||
depends_on: "eval:doc.import_using_csv_file === 0",
|
||||
},
|
||||
{
|
||||
fieldtype: 'Button',
|
||||
fieldname: 'make_serial_nos',
|
||||
label: __('Create Serial Nos'),
|
||||
depends_on: 'eval:doc.import_using_csv_file === 0',
|
||||
fieldtype: "Button",
|
||||
fieldname: "make_serial_nos",
|
||||
label: __("Create Serial Nos"),
|
||||
depends_on: "eval:doc.import_using_csv_file === 0",
|
||||
click: () => {
|
||||
this.create_serial_nos();
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
fieldtype: 'Section Break',
|
||||
depends_on: 'eval:doc.import_using_csv_file === 1',
|
||||
}
|
||||
fieldtype: "Section Break",
|
||||
depends_on: "eval:doc.import_using_csv_file === 1",
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
fields = [...fields,
|
||||
fields = [
|
||||
...fields,
|
||||
{
|
||||
fieldtype: 'Button',
|
||||
fieldname: 'download_csv',
|
||||
label: __('Download CSV Template'),
|
||||
click: () => this.download_csv_file()
|
||||
fieldtype: "Button",
|
||||
fieldname: "download_csv",
|
||||
label: __("Download CSV Template"),
|
||||
click: () => this.download_csv_file(),
|
||||
},
|
||||
{
|
||||
fieldtype: 'Column Break',
|
||||
fieldtype: "Column Break",
|
||||
},
|
||||
{
|
||||
fieldtype: 'Attach',
|
||||
fieldname: 'attach_serial_batch_csv',
|
||||
label: __('Attach CSV File'),
|
||||
onchange: () => this.upload_csv_file()
|
||||
}
|
||||
fieldtype: "Attach",
|
||||
fieldname: "attach_serial_batch_csv",
|
||||
label: __("Attach CSV File"),
|
||||
onchange: () => this.upload_csv_file(),
|
||||
},
|
||||
];
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
create_serial_nos() {
|
||||
let {upload_serial_nos} = this.dialog.get_values();
|
||||
let { upload_serial_nos } = this.dialog.get_values();
|
||||
|
||||
if (!upload_serial_nos) {
|
||||
frappe.throw(__('Please enter Serial Nos'));
|
||||
frappe.throw(__("Please enter Serial Nos"));
|
||||
}
|
||||
|
||||
frappe.call({
|
||||
method: 'erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.create_serial_nos',
|
||||
method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.create_serial_nos",
|
||||
args: {
|
||||
item_code: this.item.item_code,
|
||||
serial_nos: upload_serial_nos
|
||||
serial_nos: upload_serial_nos,
|
||||
},
|
||||
callback: (r) => {
|
||||
if (r.message) {
|
||||
@@ -274,20 +274,22 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
this.set_data(r.message);
|
||||
this.update_bundle_entries();
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
download_csv_file() {
|
||||
let csvFileData = ['Serial No'];
|
||||
let csvFileData = ["Serial No"];
|
||||
|
||||
if (this.item.has_serial_no && this.item.has_batch_no) {
|
||||
csvFileData = ['Serial No', 'Batch No', 'Quantity'];
|
||||
csvFileData = ["Serial No", "Batch No", "Quantity"];
|
||||
} else if (this.item.has_batch_no) {
|
||||
csvFileData = ['Batch No', 'Quantity'];
|
||||
csvFileData = ["Batch No", "Quantity"];
|
||||
}
|
||||
|
||||
const method = `/api/method/erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.download_blank_csv_template?content=${encodeURIComponent(JSON.stringify(csvFileData))}`;
|
||||
const method = `/api/method/erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.download_blank_csv_template?content=${encodeURIComponent(
|
||||
JSON.stringify(csvFileData)
|
||||
)}`;
|
||||
const w = window.open(frappe.urllib.get_full_url(method));
|
||||
if (!w) {
|
||||
frappe.msgprint(__("Please enable pop-ups"));
|
||||
@@ -295,13 +297,13 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
}
|
||||
|
||||
upload_csv_file() {
|
||||
const file_path = this.dialog.get_value("attach_serial_batch_csv")
|
||||
const file_path = this.dialog.get_value("attach_serial_batch_csv");
|
||||
|
||||
frappe.call({
|
||||
method: 'erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.upload_csv_file',
|
||||
method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.upload_csv_file",
|
||||
args: {
|
||||
item_code: this.item.item_code,
|
||||
file_path: file_path
|
||||
file_path: file_path,
|
||||
},
|
||||
callback: (r) => {
|
||||
if (r.message.serial_nos && r.message.serial_nos.length) {
|
||||
@@ -309,102 +311,106 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
} else if (r.message.batch_nos && r.message.batch_nos.length) {
|
||||
this.set_data(r.message.batch_nos);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
get_filter_fields() {
|
||||
return [
|
||||
{
|
||||
fieldtype: 'Section Break',
|
||||
label: __('Auto Fetch')
|
||||
fieldtype: "Section Break",
|
||||
label: __("Auto Fetch"),
|
||||
},
|
||||
{
|
||||
fieldtype: 'Float',
|
||||
fieldname: 'qty',
|
||||
label: __('Qty to Fetch'),
|
||||
onchange: () => this.get_auto_data()
|
||||
fieldtype: "Float",
|
||||
fieldname: "qty",
|
||||
label: __("Qty to Fetch"),
|
||||
onchange: () => this.get_auto_data(),
|
||||
},
|
||||
{
|
||||
fieldtype: 'Column Break',
|
||||
fieldtype: "Column Break",
|
||||
},
|
||||
{
|
||||
fieldtype: 'Select',
|
||||
options: ['FIFO', 'LIFO', 'Expiry'],
|
||||
default: 'FIFO',
|
||||
fieldname: 'based_on',
|
||||
label: __('Fetch Based On'),
|
||||
onchange: () => this.get_auto_data()
|
||||
fieldtype: "Select",
|
||||
options: ["FIFO", "LIFO", "Expiry"],
|
||||
default: "FIFO",
|
||||
fieldname: "based_on",
|
||||
label: __("Fetch Based On"),
|
||||
onchange: () => this.get_auto_data(),
|
||||
},
|
||||
{
|
||||
fieldtype: 'Section Break',
|
||||
fieldtype: "Section Break",
|
||||
},
|
||||
]
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
get_dialog_table_fields() {
|
||||
let fields = []
|
||||
let fields = [];
|
||||
|
||||
if (this.item.has_serial_no) {
|
||||
fields.push({
|
||||
fieldtype: 'Link',
|
||||
options: 'Serial No',
|
||||
fieldname: 'serial_no',
|
||||
label: __('Serial No'),
|
||||
fieldtype: "Link",
|
||||
options: "Serial No",
|
||||
fieldname: "serial_no",
|
||||
label: __("Serial No"),
|
||||
in_list_view: 1,
|
||||
get_query: () => {
|
||||
return {
|
||||
filters: this.get_serial_no_filters()
|
||||
}
|
||||
}
|
||||
})
|
||||
filters: this.get_serial_no_filters(),
|
||||
};
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
let batch_fields = []
|
||||
let batch_fields = [];
|
||||
if (this.item.has_batch_no) {
|
||||
batch_fields = [
|
||||
{
|
||||
fieldtype: 'Link',
|
||||
options: 'Batch',
|
||||
fieldname: 'batch_no',
|
||||
label: __('Batch No'),
|
||||
fieldtype: "Link",
|
||||
options: "Batch",
|
||||
fieldname: "batch_no",
|
||||
label: __("Batch No"),
|
||||
in_list_view: 1,
|
||||
get_query: () => {
|
||||
let is_inward = false;
|
||||
if ((["Purchase Receipt", "Purchase Invoice"].includes(this.frm.doc.doctype) && !this.frm.doc.is_return)
|
||||
|| (this.frm.doc.doctype === 'Stock Entry' && this.frm.doc.purpose === 'Material Receipt')) {
|
||||
if (
|
||||
(["Purchase Receipt", "Purchase Invoice"].includes(this.frm.doc.doctype) &&
|
||||
!this.frm.doc.is_return) ||
|
||||
(this.frm.doc.doctype === "Stock Entry" &&
|
||||
this.frm.doc.purpose === "Material Receipt")
|
||||
) {
|
||||
is_inward = true;
|
||||
}
|
||||
|
||||
return {
|
||||
query : "erpnext.controllers.queries.get_batch_no",
|
||||
query: "erpnext.controllers.queries.get_batch_no",
|
||||
filters: {
|
||||
'item_code': this.item.item_code,
|
||||
'warehouse': this.item.s_warehouse || this.item.t_warehouse || this.item.warehouse,
|
||||
'is_inward': is_inward
|
||||
}
|
||||
}
|
||||
item_code: this.item.item_code,
|
||||
warehouse:
|
||||
this.item.s_warehouse || this.item.t_warehouse || this.item.warehouse,
|
||||
is_inward: is_inward,
|
||||
},
|
||||
};
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
if (!this.item.has_serial_no) {
|
||||
batch_fields.push({
|
||||
fieldtype: 'Float',
|
||||
fieldname: 'qty',
|
||||
label: __('Quantity'),
|
||||
fieldtype: "Float",
|
||||
fieldname: "qty",
|
||||
label: __("Quantity"),
|
||||
in_list_view: 1,
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fields = [...fields, ...batch_fields];
|
||||
|
||||
fields.push({
|
||||
fieldtype: 'Data',
|
||||
fieldname: 'name',
|
||||
label: __('Name'),
|
||||
fieldtype: "Data",
|
||||
fieldname: "name",
|
||||
label: __("Name"),
|
||||
hidden: 1,
|
||||
});
|
||||
|
||||
@@ -425,26 +431,26 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
}
|
||||
|
||||
if (!based_on) {
|
||||
based_on = 'FIFO';
|
||||
based_on = "FIFO";
|
||||
}
|
||||
|
||||
if (qty) {
|
||||
frappe.call({
|
||||
method: 'erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.get_auto_data',
|
||||
method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.get_auto_data",
|
||||
args: {
|
||||
item_code: this.item.item_code,
|
||||
warehouse: this.item.warehouse || this.item.s_warehouse,
|
||||
has_serial_no: this.item.has_serial_no,
|
||||
has_batch_no: this.item.has_batch_no,
|
||||
qty: qty,
|
||||
based_on: based_on
|
||||
based_on: based_on,
|
||||
},
|
||||
callback: (r) => {
|
||||
if (r.message) {
|
||||
this.dialog.fields_dict.entries.df.data = r.message;
|
||||
this.dialog.fields_dict.entries.grid.refresh();
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -454,7 +460,7 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
|
||||
if (scan_serial_no || scan_batch_no) {
|
||||
frappe.call({
|
||||
method: 'erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.is_serial_batch_no_exists',
|
||||
method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.is_serial_batch_no_exists",
|
||||
args: {
|
||||
item_code: this.item.item_code,
|
||||
type_of_transaction: this.item.type_of_transaction,
|
||||
@@ -463,9 +469,8 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
},
|
||||
callback: (r) => {
|
||||
this.update_serial_batch_no();
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,25 +478,25 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
const { scan_serial_no, scan_batch_no } = this.dialog.get_values();
|
||||
|
||||
if (scan_serial_no) {
|
||||
let existing_row = this.dialog.fields_dict.entries.df.data.filter(d => {
|
||||
let existing_row = this.dialog.fields_dict.entries.df.data.filter((d) => {
|
||||
if (d.serial_no === scan_serial_no) {
|
||||
return d
|
||||
return d;
|
||||
}
|
||||
});
|
||||
|
||||
if (existing_row?.length) {
|
||||
frappe.throw(__('Serial No {0} already exists', [scan_serial_no]));
|
||||
frappe.throw(__("Serial No {0} already exists", [scan_serial_no]));
|
||||
}
|
||||
|
||||
if (!this.item.has_batch_no) {
|
||||
this.dialog.fields_dict.entries.df.data.push({
|
||||
serial_no: scan_serial_no
|
||||
serial_no: scan_serial_no,
|
||||
});
|
||||
|
||||
this.dialog.fields_dict.scan_serial_no.set_value('');
|
||||
this.dialog.fields_dict.scan_serial_no.set_value("");
|
||||
} else {
|
||||
frappe.call({
|
||||
method: 'erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.get_batch_no_from_serial_no',
|
||||
method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.get_batch_no_from_serial_no",
|
||||
args: {
|
||||
serial_no: scan_serial_no,
|
||||
},
|
||||
@@ -499,19 +504,18 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
if (r.message) {
|
||||
this.dialog.fields_dict.entries.df.data.push({
|
||||
serial_no: scan_serial_no,
|
||||
batch_no: r.message
|
||||
batch_no: r.message,
|
||||
});
|
||||
|
||||
this.dialog.fields_dict.scan_serial_no.set_value('');
|
||||
this.dialog.fields_dict.scan_serial_no.set_value("");
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
});
|
||||
}
|
||||
} else if (scan_batch_no) {
|
||||
let existing_row = this.dialog.fields_dict.entries.df.data.filter(d => {
|
||||
let existing_row = this.dialog.fields_dict.entries.df.data.filter((d) => {
|
||||
if (d.batch_no === scan_batch_no) {
|
||||
return d
|
||||
return d;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -520,11 +524,11 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
} else {
|
||||
this.dialog.fields_dict.entries.df.data.push({
|
||||
batch_no: scan_batch_no,
|
||||
qty: 1
|
||||
qty: 1,
|
||||
});
|
||||
}
|
||||
|
||||
this.dialog.fields_dict.scan_batch_no.set_value('');
|
||||
this.dialog.fields_dict.scan_batch_no.set_value("");
|
||||
}
|
||||
|
||||
this.dialog.fields_dict.entries.grid.refresh();
|
||||
@@ -532,33 +536,33 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
|
||||
update_bundle_entries() {
|
||||
let entries = this.dialog.get_values().entries;
|
||||
let warehouse = this.dialog.get_value('warehouse');
|
||||
let warehouse = this.dialog.get_value("warehouse");
|
||||
|
||||
if (entries && !entries.length || !entries) {
|
||||
frappe.throw(__('Please add atleast one Serial No / Batch No'));
|
||||
if ((entries && !entries.length) || !entries) {
|
||||
frappe.throw(__("Please add atleast one Serial No / Batch No"));
|
||||
}
|
||||
|
||||
frappe.call({
|
||||
method: 'erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.add_serial_batch_ledgers',
|
||||
args: {
|
||||
entries: entries,
|
||||
child_row: this.item,
|
||||
doc: this.frm.doc,
|
||||
warehouse: warehouse,
|
||||
}
|
||||
}).then(r => {
|
||||
this.callback && this.callback(r.message);
|
||||
this.frm.save();
|
||||
this.dialog.hide();
|
||||
})
|
||||
frappe
|
||||
.call({
|
||||
method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.add_serial_batch_ledgers",
|
||||
args: {
|
||||
entries: entries,
|
||||
child_row: this.item,
|
||||
doc: this.frm.doc,
|
||||
warehouse: warehouse,
|
||||
},
|
||||
})
|
||||
.then((r) => {
|
||||
this.callback && this.callback(r.message);
|
||||
this.frm.save();
|
||||
this.dialog.hide();
|
||||
});
|
||||
}
|
||||
|
||||
edit_full_form() {
|
||||
let bundle_id = this.item.serial_and_batch_bundle
|
||||
let bundle_id = this.item.serial_and_batch_bundle;
|
||||
if (!bundle_id) {
|
||||
let _new = frappe.model.get_new_doc(
|
||||
"Serial and Batch Bundle", null, null, true
|
||||
);
|
||||
let _new = frappe.model.get_new_doc("Serial and Batch Bundle", null, null, true);
|
||||
|
||||
_new.item_code = this.item.item_code;
|
||||
_new.warehouse = this.get_warehouse();
|
||||
@@ -575,34 +579,36 @@ erpnext.SerialBatchPackageSelector = class SerialNoBatchBundleUpdate {
|
||||
}
|
||||
|
||||
get_warehouse() {
|
||||
return (this.item?.type_of_transaction === "Outward" ?
|
||||
(this.item.warehouse || this.item.s_warehouse)
|
||||
: (this.item.warehouse || this.item.t_warehouse));
|
||||
return this.item?.type_of_transaction === "Outward"
|
||||
? this.item.warehouse || this.item.s_warehouse
|
||||
: this.item.warehouse || this.item.t_warehouse;
|
||||
}
|
||||
|
||||
render_data() {
|
||||
if (this.bundle) {
|
||||
frappe.call({
|
||||
method: 'erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.get_serial_batch_ledgers',
|
||||
args: {
|
||||
item_code: this.item.item_code,
|
||||
name: this.bundle,
|
||||
voucher_no: !this.frm.is_new() ? this.item.parent : "",
|
||||
}
|
||||
}).then(r => {
|
||||
if (r.message) {
|
||||
this.set_data(r.message);
|
||||
}
|
||||
})
|
||||
frappe
|
||||
.call({
|
||||
method: "erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle.get_serial_batch_ledgers",
|
||||
args: {
|
||||
item_code: this.item.item_code,
|
||||
name: this.bundle,
|
||||
voucher_no: !this.frm.is_new() ? this.item.parent : "",
|
||||
},
|
||||
})
|
||||
.then((r) => {
|
||||
if (r.message) {
|
||||
this.set_data(r.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
set_data(data) {
|
||||
data.forEach(d => {
|
||||
data.forEach((d) => {
|
||||
d.qty = Math.abs(d.qty);
|
||||
this.dialog.fields_dict.entries.df.data.push(d);
|
||||
});
|
||||
|
||||
this.dialog.fields_dict.entries.grid.refresh();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
frappe.provide('frappe.ui.form');
|
||||
frappe.provide("frappe.ui.form");
|
||||
|
||||
frappe.ui.form.SupplierQuickEntryForm = frappe.ui.form.ContactAddressQuickEntryForm;
|
||||
|
||||
@@ -1,27 +1,34 @@
|
||||
frappe.provide('erpnext.accounts');
|
||||
frappe.provide("erpnext.accounts");
|
||||
|
||||
erpnext.accounts.unreconcile_payment = {
|
||||
add_unreconcile_btn(frm) {
|
||||
if (frm.doc.docstatus == 1) {
|
||||
if(((frm.doc.doctype == "Journal Entry") && (frm.doc.voucher_type != "Journal Entry"))
|
||||
|| !["Purchase Invoice", "Sales Invoice", "Journal Entry", "Payment Entry"].includes(frm.doc.doctype)
|
||||
) {
|
||||
if (
|
||||
(frm.doc.doctype == "Journal Entry" && frm.doc.voucher_type != "Journal Entry") ||
|
||||
!["Purchase Invoice", "Sales Invoice", "Journal Entry", "Payment Entry"].includes(
|
||||
frm.doc.doctype
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
frappe.call({
|
||||
"method": "erpnext.accounts.doctype.unreconcile_payment.unreconcile_payment.doc_has_references",
|
||||
"args": {
|
||||
"doctype": frm.doc.doctype,
|
||||
"docname": frm.doc.name
|
||||
method: "erpnext.accounts.doctype.unreconcile_payment.unreconcile_payment.doc_has_references",
|
||||
args: {
|
||||
doctype: frm.doc.doctype,
|
||||
docname: frm.doc.name,
|
||||
},
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
frm.add_custom_button(__("UnReconcile"), function() {
|
||||
erpnext.accounts.unreconcile_payment.build_unreconcile_dialog(frm);
|
||||
}, __('Actions'));
|
||||
frm.add_custom_button(
|
||||
__("UnReconcile"),
|
||||
function () {
|
||||
erpnext.accounts.unreconcile_payment.build_unreconcile_dialog(frm);
|
||||
},
|
||||
__("Actions")
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -30,18 +37,18 @@ erpnext.accounts.unreconcile_payment = {
|
||||
// assuming each row is an individual voucher
|
||||
// pass this to server side method that creates unreconcile doc for each row
|
||||
let selection_map = [];
|
||||
if (['Sales Invoice', 'Purchase Invoice'].includes(frm.doc.doctype)) {
|
||||
selection_map = selections.map(function(elem) {
|
||||
if (["Sales Invoice", "Purchase Invoice"].includes(frm.doc.doctype)) {
|
||||
selection_map = selections.map(function (elem) {
|
||||
return {
|
||||
company: elem.company,
|
||||
voucher_type: elem.voucher_type,
|
||||
voucher_no: elem.voucher_no,
|
||||
against_voucher_type: frm.doc.doctype,
|
||||
against_voucher_no: frm.doc.name
|
||||
against_voucher_no: frm.doc.name,
|
||||
};
|
||||
});
|
||||
} else if (['Payment Entry', 'Journal Entry'].includes(frm.doc.doctype)) {
|
||||
selection_map = selections.map(function(elem) {
|
||||
} else if (["Payment Entry", "Journal Entry"].includes(frm.doc.doctype)) {
|
||||
selection_map = selections.map(function (elem) {
|
||||
return {
|
||||
company: elem.company,
|
||||
voucher_type: frm.doc.doctype,
|
||||
@@ -55,18 +62,41 @@ erpnext.accounts.unreconcile_payment = {
|
||||
},
|
||||
|
||||
build_unreconcile_dialog(frm) {
|
||||
if (['Sales Invoice', 'Purchase Invoice', 'Payment Entry', 'Journal Entry'].includes(frm.doc.doctype)) {
|
||||
if (
|
||||
["Sales Invoice", "Purchase Invoice", "Payment Entry", "Journal Entry"].includes(frm.doc.doctype)
|
||||
) {
|
||||
let child_table_fields = [
|
||||
{ label: __("Voucher Type"), fieldname: "voucher_type", fieldtype: "Dynamic Link", options: "DocType", in_list_view: 1, read_only: 1},
|
||||
{ label: __("Voucher No"), fieldname: "voucher_no", fieldtype: "Link", options: "voucher_type", in_list_view: 1, read_only: 1 },
|
||||
{ label: __("Allocated Amount"), fieldname: "allocated_amount", fieldtype: "Currency", in_list_view: 1, read_only: 1 , options: "account_currency"},
|
||||
{ label: __("Currency"), fieldname: "account_currency", fieldtype: "Currency", read_only: 1},
|
||||
]
|
||||
{
|
||||
label: __("Voucher Type"),
|
||||
fieldname: "voucher_type",
|
||||
fieldtype: "Dynamic Link",
|
||||
options: "DocType",
|
||||
in_list_view: 1,
|
||||
read_only: 1,
|
||||
},
|
||||
{
|
||||
label: __("Voucher No"),
|
||||
fieldname: "voucher_no",
|
||||
fieldtype: "Link",
|
||||
options: "voucher_type",
|
||||
in_list_view: 1,
|
||||
read_only: 1,
|
||||
},
|
||||
{
|
||||
label: __("Allocated Amount"),
|
||||
fieldname: "allocated_amount",
|
||||
fieldtype: "Currency",
|
||||
in_list_view: 1,
|
||||
read_only: 1,
|
||||
options: "account_currency",
|
||||
},
|
||||
{ label: __("Currency"), fieldname: "account_currency", fieldtype: "Currency", read_only: 1 },
|
||||
];
|
||||
let unreconcile_dialog_fields = [
|
||||
{
|
||||
label: __('Allocations'),
|
||||
fieldname: 'allocations',
|
||||
fieldtype: 'Table',
|
||||
label: __("Allocations"),
|
||||
fieldname: "allocations",
|
||||
fieldtype: "Table",
|
||||
read_only: 1,
|
||||
fields: child_table_fields,
|
||||
},
|
||||
@@ -74,54 +104,57 @@ erpnext.accounts.unreconcile_payment = {
|
||||
|
||||
// get linked payments
|
||||
frappe.call({
|
||||
"method": "erpnext.accounts.doctype.unreconcile_payment.unreconcile_payment.get_linked_payments_for_doc",
|
||||
"args": {
|
||||
"company": frm.doc.company,
|
||||
"doctype": frm.doc.doctype,
|
||||
"docname": frm.doc.name
|
||||
method: "erpnext.accounts.doctype.unreconcile_payment.unreconcile_payment.get_linked_payments_for_doc",
|
||||
args: {
|
||||
company: frm.doc.company,
|
||||
doctype: frm.doc.doctype,
|
||||
docname: frm.doc.name,
|
||||
},
|
||||
callback: function(r) {
|
||||
callback: function (r) {
|
||||
if (r.message) {
|
||||
// populate child table with allocations
|
||||
unreconcile_dialog_fields[0].data = r.message;
|
||||
unreconcile_dialog_fields[0].get_data = function(){ return r.message};
|
||||
unreconcile_dialog_fields[0].get_data = function () {
|
||||
return r.message;
|
||||
};
|
||||
|
||||
let d = new frappe.ui.Dialog({
|
||||
title: 'UnReconcile Allocations',
|
||||
title: "UnReconcile Allocations",
|
||||
fields: unreconcile_dialog_fields,
|
||||
size: 'large',
|
||||
size: "large",
|
||||
cannot_add_rows: true,
|
||||
primary_action_label: 'UnReconcile',
|
||||
primary_action_label: "UnReconcile",
|
||||
primary_action(values) {
|
||||
|
||||
let selected_allocations = values.allocations.filter(x=>x.__checked);
|
||||
let selected_allocations = values.allocations.filter((x) => x.__checked);
|
||||
if (selected_allocations.length > 0) {
|
||||
let selection_map = erpnext.accounts.unreconcile_payment.build_selection_map(frm, selected_allocations);
|
||||
erpnext.accounts.unreconcile_payment.create_unreconcile_docs(selection_map);
|
||||
let selection_map =
|
||||
erpnext.accounts.unreconcile_payment.build_selection_map(
|
||||
frm,
|
||||
selected_allocations
|
||||
);
|
||||
erpnext.accounts.unreconcile_payment.create_unreconcile_docs(
|
||||
selection_map
|
||||
);
|
||||
d.hide();
|
||||
|
||||
} else {
|
||||
frappe.msgprint("No Selection");
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
d.show();
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
create_unreconcile_docs(selection_map) {
|
||||
frappe.call({
|
||||
"method": "erpnext.accounts.doctype.unreconcile_payment.unreconcile_payment.create_unreconcile_doc_for_selection",
|
||||
"args": {
|
||||
"selections": selection_map
|
||||
method: "erpnext.accounts.doctype.unreconcile_payment.unreconcile_payment.create_unreconcile_doc_for_selection",
|
||||
args: {
|
||||
selections: selection_map,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
// Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// MIT License. See license.txt
|
||||
|
||||
frappe.ui.form.on('Website Theme', {
|
||||
frappe.ui.form.on("Website Theme", {
|
||||
validate(frm) {
|
||||
let theme_scss = frm.doc.theme_scss;
|
||||
if (theme_scss && theme_scss.includes('frappe/public/scss/website')
|
||||
&& !theme_scss.includes('erpnext/public/scss/website')
|
||||
if (
|
||||
theme_scss &&
|
||||
theme_scss.includes("frappe/public/scss/website") &&
|
||||
!theme_scss.includes("erpnext/public/scss/website")
|
||||
) {
|
||||
frm.set_value('theme_scss',
|
||||
`${frm.doc.theme_scss}\n@import "erpnext/public/scss/website";`);
|
||||
frm.set_value("theme_scss", `${frm.doc.theme_scss}\n@import "erpnext/public/scss/website";`);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
if(!window.erpnext) window.erpnext = {};
|
||||
if (!window.erpnext) window.erpnext = {};
|
||||
|
||||
erpnext.subscribe_to_newsletter = function(opts, btn) {
|
||||
erpnext.subscribe_to_newsletter = function (opts, btn) {
|
||||
return frappe.call({
|
||||
type: "POST",
|
||||
method: "frappe.email.doctype.newsletter.newsletter.subscribe",
|
||||
btn: btn,
|
||||
args: {"email": opts.email},
|
||||
callback: opts.callback
|
||||
args: { email: opts.email },
|
||||
callback: opts.callback,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user