mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-24 15:39:20 +00:00
Merge branch 'version-13-hotfix' of https://github.com/frappe/erpnext into bootstraped_gst_setup
This commit is contained in:
@@ -84,13 +84,13 @@ erpnext.buying.BuyingController = erpnext.TransactionController.extend({
|
||||
if (me.frm.doc.is_subcontracted == "Yes") {
|
||||
return{
|
||||
query: "erpnext.controllers.queries.item_query",
|
||||
filters:{ 'is_sub_contracted_item': 1 }
|
||||
filters:{ 'supplier': me.frm.doc.supplier, 'is_sub_contracted_item': 1 }
|
||||
}
|
||||
}
|
||||
else {
|
||||
return{
|
||||
query: "erpnext.controllers.queries.item_query",
|
||||
filters: {'is_purchase_item': 1}
|
||||
filters: { 'supplier': me.frm.doc.supplier, 'is_purchase_item': 1 }
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -562,7 +562,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
weight_uom: item.weight_uom,
|
||||
manufacturer: item.manufacturer,
|
||||
stock_uom: item.stock_uom,
|
||||
pos_profile: me.frm.doc.doctype == 'Sales Invoice' ? me.frm.doc.pos_profile : '',
|
||||
pos_profile: cint(me.frm.doc.is_pos) ? me.frm.doc.pos_profile : '',
|
||||
cost_center: item.cost_center,
|
||||
tax_category: me.frm.doc.tax_category,
|
||||
item_tax_template: item.item_tax_template,
|
||||
@@ -953,15 +953,15 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
(this.frm.doc.payment_schedule && this.frm.doc.payment_schedule.length)) {
|
||||
var message1 = "";
|
||||
var message2 = "";
|
||||
var final_message = "Please clear the ";
|
||||
var final_message = __("Please clear the") + " ";
|
||||
|
||||
if (this.frm.doc.payment_terms_template) {
|
||||
message1 = "selected Payment Terms Template";
|
||||
message1 = __("selected Payment Terms Template");
|
||||
final_message = final_message + message1;
|
||||
}
|
||||
|
||||
if ((this.frm.doc.payment_schedule || []).length) {
|
||||
message2 = "Payment Schedule Table";
|
||||
message2 = __("Payment Schedule Table");
|
||||
if (message1.length !== 0) message2 = " and " + message2;
|
||||
final_message = final_message + message2;
|
||||
}
|
||||
@@ -1329,7 +1329,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
|
||||
this.toggle_item_grid_columns(company_currency);
|
||||
|
||||
if(this.frm.fields_dict["operations"]) {
|
||||
if (this.frm.doc.operations && this.frm.doc.operations.length > 0) {
|
||||
this.frm.set_currency_labels(["operating_cost", "hour_rate"], this.frm.doc.currency, "operations");
|
||||
this.frm.set_currency_labels(["base_operating_cost", "base_hour_rate"], company_currency, "operations");
|
||||
|
||||
@@ -1340,7 +1340,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
});
|
||||
}
|
||||
|
||||
if(this.frm.fields_dict["scrap_items"]) {
|
||||
if (this.frm.doc.scrap_items && this.frm.doc.scrap_items.length > 0) {
|
||||
this.frm.set_currency_labels(["rate", "amount"], this.frm.doc.currency, "scrap_items");
|
||||
this.frm.set_currency_labels(["base_rate", "base_amount"], company_currency, "scrap_items");
|
||||
|
||||
@@ -1351,13 +1351,13 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
});
|
||||
}
|
||||
|
||||
if(this.frm.fields_dict["taxes"]) {
|
||||
if (this.frm.doc.taxes && this.frm.doc.taxes.length > 0) {
|
||||
this.frm.set_currency_labels(["tax_amount", "total", "tax_amount_after_discount"], this.frm.doc.currency, "taxes");
|
||||
|
||||
this.frm.set_currency_labels(["base_tax_amount", "base_total", "base_tax_amount_after_discount"], company_currency, "taxes");
|
||||
}
|
||||
|
||||
if(this.frm.fields_dict["advances"]) {
|
||||
if (this.frm.doc.advances && this.frm.doc.advances.length > 0) {
|
||||
this.frm.set_currency_labels(["advance_amount", "allocated_amount"],
|
||||
this.frm.doc.party_account_currency, "advances");
|
||||
}
|
||||
@@ -1379,12 +1379,12 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
|
||||
update_payment_schedule_grid_labels: function(company_currency) {
|
||||
const me = this;
|
||||
if (this.frm.fields_dict["payment_schedule"]) {
|
||||
if (this.frm.doc.payment_schedule && this.frm.doc.payment_schedule.length > 0) {
|
||||
this.frm.set_currency_labels(["base_payment_amount", "base_outstanding", "base_paid_amount"],
|
||||
company_currency, "payment_schedule");
|
||||
this.frm.set_currency_labels(["payment_amount", "outstanding", "paid_amount"],
|
||||
this.frm.doc.currency, "payment_schedule");
|
||||
|
||||
|
||||
var schedule_grid = this.frm.fields_dict["payment_schedule"].grid;
|
||||
$.each(["base_payment_amount", "base_outstanding", "base_paid_amount"], function(i, fname) {
|
||||
if (frappe.meta.get_docfield(schedule_grid.doctype, fname))
|
||||
@@ -2034,7 +2034,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
if(r.message && !r.exc) {
|
||||
me.frm.set_value("payment_schedule", r.message);
|
||||
const company_currency = me.get_company_currency();
|
||||
this.update_payment_schedule_grid_labels(company_currency);
|
||||
me.update_payment_schedule_grid_labels(company_currency);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -644,14 +644,14 @@ frappe.help.help_links["List/Payment Request"] = [
|
||||
frappe.help.help_links["List/Asset"] = [
|
||||
{
|
||||
label: "Managing Fixed Assets",
|
||||
url: docsUrl + "user/manual/en/accounts/managing-fixed-assets",
|
||||
url: docsUrl + "user/manual/en/accounts/opening-balance/fixed_assets",
|
||||
},
|
||||
];
|
||||
|
||||
frappe.help.help_links["List/Asset Category"] = [
|
||||
{
|
||||
label: "Asset Category",
|
||||
url: docsUrl + "user/manual/en/accounts/managing-fixed-assets",
|
||||
url: docsUrl + "user/manual/en/asset/asset-category",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -663,7 +663,7 @@ frappe.help.help_links["List/Item"] = [
|
||||
{ label: "Item", url: docsUrl + "user/manual/en/stock/item" },
|
||||
{
|
||||
label: "Item Price",
|
||||
url: docsUrl + "user/manual/en/stock/item/item-price",
|
||||
url: docsUrl + "user/manual/en/stock/item-price",
|
||||
},
|
||||
{
|
||||
label: "Barcode",
|
||||
@@ -672,25 +672,25 @@ frappe.help.help_links["List/Item"] = [
|
||||
},
|
||||
{
|
||||
label: "Item Wise Taxation",
|
||||
url: docsUrl + "user/manual/en/accounts/item-wise-taxation",
|
||||
url: docsUrl + "user/manual/en/accounts/item-tax-template",
|
||||
},
|
||||
{
|
||||
label: "Managing Fixed Assets",
|
||||
url: docsUrl + "user/manual/en/accounts/managing-fixed-assets",
|
||||
url: docsUrl + "user/manual/en/accounts/opening-balance/fixed_assets",
|
||||
},
|
||||
{
|
||||
label: "Item Codification",
|
||||
url: docsUrl + "user/manual/en/stock/item/item-codification",
|
||||
url: docsUrl + "user/manual/en/stock/articles/item-codification",
|
||||
},
|
||||
{
|
||||
label: "Item Variants",
|
||||
url: docsUrl + "user/manual/en/stock/item/item-variants",
|
||||
url: docsUrl + "user/manual/en/stock/item-variants",
|
||||
},
|
||||
{
|
||||
label: "Item Valuation",
|
||||
url:
|
||||
docsUrl +
|
||||
"user/manual/en/stock/item/item-valuation-fifo-and-moving-average",
|
||||
"user/manual/en/stock/articles/item-valuation-fifo-and-moving-average",
|
||||
},
|
||||
];
|
||||
|
||||
@@ -698,7 +698,7 @@ frappe.help.help_links["Form/Item"] = [
|
||||
{ label: "Item", url: docsUrl + "user/manual/en/stock/item" },
|
||||
{
|
||||
label: "Item Price",
|
||||
url: docsUrl + "user/manual/en/stock/item/item-price",
|
||||
url: docsUrl + "user/manual/en/stock/item-price",
|
||||
},
|
||||
{
|
||||
label: "Barcode",
|
||||
@@ -707,19 +707,19 @@ frappe.help.help_links["Form/Item"] = [
|
||||
},
|
||||
{
|
||||
label: "Item Wise Taxation",
|
||||
url: docsUrl + "user/manual/en/accounts/item-wise-taxation",
|
||||
url: docsUrl + "user/manual/en/accounts/item-tax-template",
|
||||
},
|
||||
{
|
||||
label: "Managing Fixed Assets",
|
||||
url: docsUrl + "user/manual/en/accounts/managing-fixed-assets",
|
||||
url: docsUrl + "user/manual/en/accounts/opening-balance/fixed_assets",
|
||||
},
|
||||
{
|
||||
label: "Item Codification",
|
||||
url: docsUrl + "user/manual/en/stock/item/item-codification",
|
||||
url: docsUrl + "user/manual/en/stock/articles/item-codification",
|
||||
},
|
||||
{
|
||||
label: "Item Variants",
|
||||
url: docsUrl + "user/manual/en/stock/item/item-variants",
|
||||
url: docsUrl + "user/manual/en/stock/item-variants",
|
||||
},
|
||||
{
|
||||
label: "Item Valuation",
|
||||
|
||||
@@ -48,31 +48,24 @@ $.extend(erpnext, {
|
||||
return cint(frappe.boot.sysdefaults.allow_stale);
|
||||
},
|
||||
|
||||
setup_serial_no: function() {
|
||||
var grid_row = cur_frm.open_grid_row();
|
||||
if(!grid_row || !grid_row.grid_form.fields_dict.serial_no ||
|
||||
grid_row.grid_form.fields_dict.serial_no.get_status()!=="Write") return;
|
||||
setup_serial_or_batch_no: function() {
|
||||
let grid_row = cur_frm.open_grid_row();
|
||||
if (!grid_row || !grid_row.grid_form.fields_dict.serial_no ||
|
||||
grid_row.grid_form.fields_dict.serial_no.get_status() !== "Write") return;
|
||||
|
||||
var $btn = $('<button class="btn btn-sm btn-default">'+__("Add Serial No")+'</button>')
|
||||
.appendTo($("<div>")
|
||||
.css({"margin-bottom": "10px", "margin-top": "10px"})
|
||||
.appendTo(grid_row.grid_form.fields_dict.serial_no.$wrapper));
|
||||
frappe.model.get_value('Item', {'name': grid_row.doc.item_code},
|
||||
['has_serial_no', 'has_batch_no'], ({has_serial_no, has_batch_no}) => {
|
||||
Object.assign(grid_row.doc, {has_serial_no, has_batch_no});
|
||||
|
||||
var me = this;
|
||||
$btn.on("click", function() {
|
||||
let callback = '';
|
||||
let on_close = '';
|
||||
|
||||
frappe.model.get_value('Item', {'name':grid_row.doc.item_code}, 'has_serial_no',
|
||||
(data) => {
|
||||
if(data) {
|
||||
grid_row.doc.has_serial_no = data.has_serial_no;
|
||||
me.show_serial_batch_selector(grid_row.frm, grid_row.doc,
|
||||
callback, on_close, true);
|
||||
}
|
||||
if (has_serial_no) {
|
||||
attach_selector_button(__("Add Serial No"),
|
||||
grid_row.grid_form.fields_dict.serial_no.$wrapper, this, grid_row);
|
||||
} else if (has_batch_no) {
|
||||
attach_selector_button(__("Pick Batch No"),
|
||||
grid_row.grid_form.fields_dict.batch_no.$wrapper, this, grid_row);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
route_to_adjustment_jv: (args) => {
|
||||
@@ -731,6 +724,18 @@ frappe.form.link_formatters['Employee'] = function(value, doc) {
|
||||
}
|
||||
}
|
||||
|
||||
frappe.form.link_formatters['Project'] = function(value, doc) {
|
||||
if (doc && value && doc.project_name && doc.project_name !== value && doc.project === value) {
|
||||
return value + ': ' + doc.project_name;
|
||||
} else if (!value && doc.doctype && doc.project_name) {
|
||||
// format blank value in child table
|
||||
return doc.project;
|
||||
} else {
|
||||
// if value is blank in report view or project name and name are the same, return as is
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
// add description on posting time
|
||||
$(document).on('app_ready', function() {
|
||||
if(!frappe.datetime.is_timezone_same()) {
|
||||
@@ -743,3 +748,14 @@ $(document).on('app_ready', function() {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function attach_selector_button(inner_text, append_loction, context, grid_row) {
|
||||
let $btn_div = $("<div>").css({"margin-bottom": "10px", "margin-top": "10px"})
|
||||
.appendTo(append_loction);
|
||||
let $btn = $(`<button class="btn btn-sm btn-default">${inner_text}</button>`)
|
||||
.appendTo($btn_div);
|
||||
|
||||
$btn.on("click", function() {
|
||||
context.show_serial_batch_selector(grid_row.frm, grid_row.doc, "", "", true);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -74,9 +74,18 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
fieldname: 'qty',
|
||||
fieldtype:'Float',
|
||||
read_only: me.has_batch && !me.has_serial_no,
|
||||
label: __(me.has_batch && !me.has_serial_no ? 'Total Qty' : 'Qty'),
|
||||
label: __(me.has_batch && !me.has_serial_no ? 'Selected Qty' : 'Qty'),
|
||||
default: flt(me.item.stock_qty),
|
||||
},
|
||||
...get_pending_qty_fields(me),
|
||||
{
|
||||
fieldname: 'uom',
|
||||
read_only: 1,
|
||||
fieldtype: 'Link',
|
||||
options: 'UOM',
|
||||
label: __('UOM'),
|
||||
default: me.item.uom
|
||||
},
|
||||
{
|
||||
fieldname: 'auto_fetch_button',
|
||||
fieldtype:'Button',
|
||||
@@ -173,6 +182,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
|
||||
if (this.has_batch && !this.has_serial_no) {
|
||||
this.update_total_qty();
|
||||
this.update_pending_qtys();
|
||||
}
|
||||
|
||||
this.dialog.show();
|
||||
@@ -313,7 +323,21 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
|
||||
qty_field.set_input(total_qty);
|
||||
},
|
||||
update_pending_qtys: function() {
|
||||
const pending_qty_field = this.dialog.fields_dict.pending_qty;
|
||||
const total_selected_qty_field = this.dialog.fields_dict.total_selected_qty;
|
||||
|
||||
if (!pending_qty_field || !total_selected_qty_field) return;
|
||||
|
||||
const me = this;
|
||||
const required_qty = this.dialog.fields_dict.required_qty.value;
|
||||
const selected_qty = this.dialog.fields_dict.qty.value;
|
||||
const total_selected_qty = selected_qty + calc_total_selected_qty(me);
|
||||
const pending_qty = required_qty - total_selected_qty;
|
||||
|
||||
pending_qty_field.set_input(pending_qty);
|
||||
total_selected_qty_field.set_input(total_selected_qty);
|
||||
},
|
||||
get_batch_fields: function() {
|
||||
var me = this;
|
||||
|
||||
@@ -415,6 +439,7 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
}
|
||||
|
||||
me.update_total_qty();
|
||||
me.update_pending_qtys();
|
||||
}
|
||||
},
|
||||
],
|
||||
@@ -511,3 +536,60 @@ erpnext.SerialNoBatchSelector = Class.extend({
|
||||
];
|
||||
}
|
||||
});
|
||||
|
||||
function get_pending_qty_fields(me) {
|
||||
if (!check_can_calculate_pending_qty(me)) return [];
|
||||
const { frm: { doc: { fg_completed_qty }}, item: { item_code, stock_qty }} = me;
|
||||
const { qty_consumed_per_unit } = erpnext.stock.bom.items[item_code];
|
||||
|
||||
const total_selected_qty = calc_total_selected_qty(me);
|
||||
const required_qty = flt(fg_completed_qty) * flt(qty_consumed_per_unit);
|
||||
const pending_qty = required_qty - (flt(stock_qty) + total_selected_qty);
|
||||
|
||||
const pending_qty_fields = [
|
||||
{ fieldtype: 'Section Break', label: __('Pending Quantity') },
|
||||
{
|
||||
fieldname: 'required_qty',
|
||||
read_only: 1,
|
||||
fieldtype: 'Float',
|
||||
label: __('Required Qty'),
|
||||
default: required_qty
|
||||
},
|
||||
{ fieldtype: 'Column Break' },
|
||||
{
|
||||
fieldname: 'total_selected_qty',
|
||||
read_only: 1,
|
||||
fieldtype: 'Float',
|
||||
label: __('Total Selected Qty'),
|
||||
default: total_selected_qty
|
||||
},
|
||||
{ fieldtype: 'Column Break' },
|
||||
{
|
||||
fieldname: 'pending_qty',
|
||||
read_only: 1,
|
||||
fieldtype: 'Float',
|
||||
label: __('Pending Qty'),
|
||||
default: pending_qty
|
||||
},
|
||||
];
|
||||
return pending_qty_fields;
|
||||
}
|
||||
|
||||
function calc_total_selected_qty(me) {
|
||||
const { frm: { doc: { items }}, item: { name, item_code }} = me;
|
||||
const totalSelectedQty = items
|
||||
.filter( item => ( item.name !== name ) && ( item.item_code === item_code ) )
|
||||
.map( item => flt(item.qty) )
|
||||
.reduce( (i, j) => i + j, 0);
|
||||
return totalSelectedQty;
|
||||
}
|
||||
|
||||
function check_can_calculate_pending_qty(me) {
|
||||
const { frm: { doc }, item } = me;
|
||||
const docChecks = doc.bom_no
|
||||
&& doc.fg_completed_qty
|
||||
&& erpnext.stock.bom
|
||||
&& erpnext.stock.bom.name === doc.bom_no;
|
||||
const itemChecks = !!item;
|
||||
return docChecks && itemChecks;
|
||||
}
|
||||
|
||||
@@ -129,11 +129,20 @@
|
||||
@extend .pointer-no-select;
|
||||
border-radius: var(--border-radius-md);
|
||||
box-shadow: var(--shadow-base);
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.02, 1.02);
|
||||
}
|
||||
|
||||
.item-qty-pill {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
margin: var(--margin-sm);
|
||||
justify-content: flex-end;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.item-display {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -766,9 +775,10 @@
|
||||
> .payment-modes {
|
||||
display: flex;
|
||||
padding-bottom: var(--padding-sm);
|
||||
margin-bottom: var(--margin-xs);
|
||||
margin-bottom: var(--margin-sm);
|
||||
overflow-x: scroll;
|
||||
overflow-y: hidden;
|
||||
flex-shrink: 0;
|
||||
|
||||
> .payment-mode-wrapper {
|
||||
min-width: 40%;
|
||||
@@ -825,9 +835,24 @@
|
||||
> .fields-numpad-container {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
justify-content: flex-end;
|
||||
|
||||
> .fields-section {
|
||||
flex: 1;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding-bottom: var(--margin-md);
|
||||
|
||||
.invoice-fields {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
> .number-pad {
|
||||
@@ -835,6 +860,7 @@
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: flex-end;
|
||||
max-width: 50%;
|
||||
|
||||
.numpad-container {
|
||||
display: grid;
|
||||
@@ -861,6 +887,7 @@
|
||||
margin-bottom: var(--margin-sm);
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
flex-shrink: 0;
|
||||
|
||||
> .totals {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user