Merge branch 'hotfix'
This commit is contained in:
commit
58dda68430
@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '11.1.5'
|
||||
__version__ = '11.1.6'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
@ -60,7 +60,7 @@ def get_booking_dates(doc, item, start_date=None, end_date=None):
|
||||
deferred_account = "deferred_revenue_account" if doc.doctype=="Sales Invoice" else "deferred_expense_account"
|
||||
last_gl_entry, skip = False, False
|
||||
|
||||
booking_end_date = getdate(add_days(today(), -1)) if not end_date else end_date
|
||||
booking_end_date = getdate(add_days(today(), -1) if not end_date else end_date)
|
||||
if booking_end_date < item.service_start_date or \
|
||||
(item.service_stop_date and booking_end_date.month > item.service_stop_date.month):
|
||||
return None, None, None, True
|
||||
@ -71,7 +71,7 @@ def get_booking_dates(doc, item, start_date=None, end_date=None):
|
||||
last_gl_entry = True
|
||||
booking_end_date = item.service_stop_date
|
||||
|
||||
booking_start_date = getdate(add_months(today(), -1)) if not start_date else start_date
|
||||
booking_start_date = getdate(add_months(today(), -1) if not start_date else start_date)
|
||||
booking_start_date = booking_start_date \
|
||||
if booking_start_date > item.service_start_date else item.service_start_date
|
||||
|
||||
@ -113,7 +113,6 @@ def calculate_amount_and_base_amount(doc, item, last_gl_entry, total_days, total
|
||||
group by voucher_detail_no
|
||||
'''.format(total_credit_debit, total_credit_debit_currency),
|
||||
(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name), as_dict=True)
|
||||
|
||||
already_booked_amount = gl_entries_details[0].total_credit if gl_entries_details else 0
|
||||
base_amount = flt(item.base_net_amount - already_booked_amount, item.precision("base_net_amount"))
|
||||
if account_currency==doc.company_currency:
|
||||
@ -140,7 +139,7 @@ def book_deferred_income_or_expense(doc, start_date=None, end_date=None):
|
||||
get_booking_dates(doc, item, start_date, end_date)
|
||||
|
||||
if skip: continue
|
||||
total_days = date_diff(item.service_end_date, item.service_start_date)
|
||||
total_days = date_diff(item.service_end_date, item.service_start_date) + 1
|
||||
total_booking_days = date_diff(booking_end_date, booking_start_date) + 1
|
||||
|
||||
account_currency = get_account_currency(item.expense_account)
|
||||
@ -179,6 +178,10 @@ def book_deferred_income_or_expense(doc, start_date=None, end_date=None):
|
||||
'project': project
|
||||
}, account_currency)
|
||||
)
|
||||
|
||||
if gl_entries:
|
||||
make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
|
||||
try:
|
||||
make_gl_entries(gl_entries, cancel=(doc.docstatus == 2), merge_entries=True)
|
||||
frappe.db.commit()
|
||||
except:
|
||||
frappe.db.rollback()
|
||||
frappe.log_error(message = frappe.get_traceback(), title = _("Error while processing deferred accounting for {0}").format(doc.name))
|
@ -101,7 +101,7 @@ def set_account_currency(filters):
|
||||
frappe.db.get_value(filters.party_type, filters.party[0], "default_currency"))
|
||||
|
||||
filters["account_currency"] = account_currency or filters.company_currency
|
||||
if filters.account_currency != filters.company_currency:
|
||||
if filters.account_currency != filters.company_currency and not filters.presentation_currency:
|
||||
filters.presentation_currency = filters.account_currency
|
||||
|
||||
return filters
|
||||
|
@ -104,7 +104,7 @@ def convert_to_presentation_currency(gl_entries, currency_info):
|
||||
credit_in_account_currency = flt(entry['credit_in_account_currency'])
|
||||
account_currency = entry['account_currency']
|
||||
|
||||
if account_currency != presentation_currency or (account_currency == presentation_currency and not is_p_or_l_account(account)):
|
||||
if account_currency != presentation_currency:
|
||||
value = debit or credit
|
||||
|
||||
date = currency_info['report_date'] if not is_p_or_l_account(account) else entry['posting_date']
|
||||
|
@ -615,7 +615,7 @@ def get_held_invoices(party_type, party):
|
||||
return held_invoices
|
||||
|
||||
|
||||
def get_outstanding_invoices(party_type, party, account, condition=None, limit=1000):
|
||||
def get_outstanding_invoices(party_type, party, account, condition=None, limit=None):
|
||||
outstanding_invoices = []
|
||||
precision = frappe.get_precision("Sales Invoice", "outstanding_amount") or 2
|
||||
|
||||
@ -628,7 +628,7 @@ def get_outstanding_invoices(party_type, party, account, condition=None, limit=1
|
||||
|
||||
invoice = 'Sales Invoice' if erpnext.get_party_account_type(party_type) == 'Receivable' else 'Purchase Invoice'
|
||||
held_invoices = get_held_invoices(party_type, party)
|
||||
limit_cond = "limit %s" % (limit or 1000)
|
||||
limit_cond = "limit %s" % limit if limit else ""
|
||||
|
||||
invoice_list = frappe.db.sql("""
|
||||
select
|
||||
|
@ -456,7 +456,7 @@ def make_rm_stock_entry(purchase_order, rm_items):
|
||||
items_dict = {
|
||||
rm_item_code: {
|
||||
"item_name": rm_item_data["item_name"],
|
||||
"description": item_wh[rm_item_code].get('description'),
|
||||
"description": item_wh.get(rm_item_code, {}).get('description', ""),
|
||||
'qty': rm_item_data["qty"],
|
||||
'from_warehouse': rm_item_data["warehouse"],
|
||||
'stock_uom': rm_item_data["stock_uom"],
|
||||
|
@ -1,12 +1,13 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"add_total_row": 1,
|
||||
"creation": "2018-10-05 16:08:24.156448",
|
||||
"disable_prepared_report": 0,
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2018-10-05 16:08:33.272201",
|
||||
"modified": "2019-02-12 14:32:29.107109",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Analytics",
|
||||
|
@ -276,8 +276,8 @@ class ProductionPlan(Document):
|
||||
item_dict[(d.item_code, d.material_request_item, d.warehouse)] = item_details
|
||||
else:
|
||||
item_details.update({
|
||||
"qty":flt(item_dict.get((d.item_code, d.sales_order, d.warehouse),{})
|
||||
.get("qty")) + flt(d.planned_qty)
|
||||
"qty": flt(item_dict.get((d.item_code, d.sales_order, d.warehouse),{})
|
||||
.get("qty")) + (flt(d.planned_qty) - flt(d.ordered_qty))
|
||||
})
|
||||
item_dict[(d.item_code, d.sales_order, d.warehouse)] = item_details
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"add_total_row": 1,
|
||||
"creation": "2018-10-11 19:28:37.085066",
|
||||
"disable_prepared_report": 0,
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"letter_head": "",
|
||||
"modified": "2018-10-11 19:28:37.085066",
|
||||
"modified": "2019-02-12 14:32:16.392521",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Analytics",
|
||||
|
@ -19,9 +19,10 @@ def execute():
|
||||
SELECT
|
||||
parent, SUM(qty) as qty
|
||||
FROM
|
||||
`tab%s Item`
|
||||
`tab{0} Item`
|
||||
where parenttype = '{0}'
|
||||
GROUP BY parent
|
||||
''' % (doctype), as_dict = True)
|
||||
'''.format(doctype), as_dict = True)
|
||||
|
||||
# Query to update total_qty might become too big, Update in batches
|
||||
# batch_size is chosen arbitrarily, Don't try too hard to reason about it
|
||||
|
@ -18,7 +18,7 @@ frappe.ui.form.on("Timesheet", {
|
||||
return{
|
||||
filters: {
|
||||
'project': child.project,
|
||||
'status': ["!=", "Closed"]
|
||||
'status': ["!=", "Cancelled"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -276,13 +276,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
scan_barcode: function() {
|
||||
let scan_barcode_field = this.frm.fields_dict["scan_barcode"];
|
||||
|
||||
let show_description = function(idx, item_code, exist=null) {
|
||||
if(exist) {
|
||||
scan_barcode_field.set_new_description(__('Row : ') + idx + ' ' +
|
||||
item_code + __(' Qty increased by 1'));
|
||||
let show_description = function(idx, exist = null) {
|
||||
if (exist) {
|
||||
scan_barcode_field.set_new_description(__('Row #{0}: Qty increased by 1', [idx]));
|
||||
} else {
|
||||
scan_barcode_field.set_new_description(__('New row : ') + idx + ' ' +
|
||||
item_code + __(' Created'));
|
||||
scan_barcode_field.set_new_description(__('Row #{0}: Item added', [idx]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -291,39 +289,39 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
method: "erpnext.selling.page.point_of_sale.point_of_sale.search_serial_or_batch_or_barcode_number",
|
||||
args: { search_value: this.frm.doc.scan_barcode }
|
||||
}).then(r => {
|
||||
|
||||
if(r && r.message && r.message.item_code) {
|
||||
let child = "";
|
||||
let add_row_index = -1;
|
||||
let cur_grid= this.frm.fields_dict["items"].grid;
|
||||
|
||||
this.frm.doc.items.map(d => {
|
||||
if(d.item_code==r.message.item_code){
|
||||
add_row_index = d.idx;
|
||||
return;
|
||||
} else if(!d.item_code && add_row_index==-1) {
|
||||
add_row_index = d.idx;
|
||||
}
|
||||
});
|
||||
|
||||
if(add_row_index == -1) {
|
||||
child = frappe.model.add_child(this.frm.doc, cur_grid.doctype, "items", add_row_index);
|
||||
} else {
|
||||
child = cur_grid.get_grid_row(add_row_index-1).doc;
|
||||
}
|
||||
show_description(child.idx, r.message.item_code, child.item_code);
|
||||
|
||||
frappe.model.set_value(child.doctype, child.name, {
|
||||
item_code: r.message.item_code,
|
||||
qty: (child.qty || 0) + 1,
|
||||
barcode: r.message.barcode
|
||||
});
|
||||
const data = r && r.message;
|
||||
if (!data) {
|
||||
scan_barcode_field.set_new_description(__('Cannot find Item with this barcode'));
|
||||
return;
|
||||
}
|
||||
else{
|
||||
scan_barcode_field.set_new_description(this.frm.doc.scan_barcode +__(' does not exist!'));
|
||||
|
||||
let cur_grid = this.frm.fields_dict.items.grid;
|
||||
|
||||
let row_to_modify = null;
|
||||
const existing_item_row = this.frm.doc.items.find(d => d.item_code === data.item_code);
|
||||
const blank_item_row = this.frm.doc.items.find(d => !d.item_code);
|
||||
|
||||
if (existing_item_row) {
|
||||
row_to_modify = existing_item_row;
|
||||
} else if (blank_item_row) {
|
||||
row_to_modify = blank_item_row;
|
||||
}
|
||||
|
||||
if (!row_to_modify) {
|
||||
// add new row
|
||||
row_to_modify = frappe.model.add_child(this.frm.doc, cur_grid.doctype, 'items');
|
||||
}
|
||||
|
||||
show_description(row_to_modify.idx, row_to_modify.item_code);
|
||||
|
||||
frappe.model.set_value(row_to_modify.doctype, row_to_modify.name, {
|
||||
item_code: data.item_code,
|
||||
qty: (row_to_modify.qty || 0) + 1
|
||||
});
|
||||
|
||||
this.frm.refresh_field('items');
|
||||
});
|
||||
scan_barcode_field.set_value("");
|
||||
scan_barcode_field.set_value('');
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
@ -345,13 +345,14 @@ def set_tax_withholding_category(company):
|
||||
if company and tds_account:
|
||||
accounts = [dict(company=company, account=tds_account)]
|
||||
|
||||
fiscal_year = get_fiscal_year(today(), company=accounts[0].get('company'))[0]
|
||||
fiscal_year = get_fiscal_year(today(), company=company)[0]
|
||||
docs = get_tds_details(accounts, fiscal_year)
|
||||
|
||||
for d in docs:
|
||||
try:
|
||||
doc = frappe.get_doc(d)
|
||||
doc.flags.ignore_permissions = True
|
||||
doc.flags.ignore_mandatory = True
|
||||
doc.insert()
|
||||
except frappe.DuplicateEntryError:
|
||||
doc = frappe.get_doc("Tax Withholding Category", d.get("name"))
|
||||
|
@ -102,7 +102,8 @@ def get_party_details(party_type, party_list, doctype, party_details):
|
||||
records = frappe.get_list(doctype, filters=filters, fields=fields, as_list=True)
|
||||
for d in records:
|
||||
details = party_details.get(d[0])
|
||||
details.setdefault(frappe.scrub(doctype), []).append(d[1:])
|
||||
if details:
|
||||
details.setdefault(frappe.scrub(doctype), []).append(d[1:])
|
||||
|
||||
return party_details
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"add_total_row": 1,
|
||||
"creation": "2018-09-21 12:46:29.451048",
|
||||
"disable_prepared_report": 0,
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2018-09-21 12:46:29.451048",
|
||||
"modified": "2019-02-12 14:30:40.043652",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Sales Analytics",
|
||||
|
@ -700,15 +700,14 @@ class Item(WebsiteGenerator):
|
||||
frappe.db.get_single_value('Item Variant Settings', 'do_not_update_variants'):
|
||||
return
|
||||
if self.has_variants:
|
||||
updated = []
|
||||
variants = frappe.db.get_all("Item", fields=["item_code"], filters={"variant_of": self.name})
|
||||
for d in variants:
|
||||
variant = frappe.get_doc("Item", d)
|
||||
copy_attributes_to_variant(self, variant)
|
||||
variant.save()
|
||||
updated.append(d.item_code)
|
||||
if updated:
|
||||
frappe.msgprint(_("Item Variants {0} updated").format(", ".join(updated)))
|
||||
if variants:
|
||||
if len(variants) <= 30:
|
||||
update_variants(variants, self, publish_progress=False)
|
||||
frappe.msgprint(_("Item Variants updated"))
|
||||
else:
|
||||
frappe.enqueue("erpnext.stock.doctype.item.item.update_variants",
|
||||
variants=variants, template=self, now=frappe.flags.in_test, timeout=600)
|
||||
|
||||
def validate_has_variants(self):
|
||||
if not self.has_variants and frappe.db.get_value("Item", self.name, "has_variants"):
|
||||
@ -997,3 +996,13 @@ def get_item_attribute(parent, attribute_value=''):
|
||||
|
||||
return frappe.get_all("Item Attribute Value", fields = ["attribute_value"],
|
||||
filters = {'parent': parent, 'attribute_value': ("like", "%%%s%%" % attribute_value)})
|
||||
|
||||
def update_variants(variants, template, publish_progress=True):
|
||||
count=0
|
||||
for d in variants:
|
||||
variant = frappe.get_doc("Item", d)
|
||||
copy_attributes_to_variant(template, variant)
|
||||
variant.save()
|
||||
count+=1
|
||||
if publish_progress:
|
||||
frappe.publish_progress(count*100/len(variants), title = _("Updating Variants..."))
|
@ -293,8 +293,9 @@ class StockEntry(StockController):
|
||||
total_completed_qty = flt(self.fg_completed_qty) + flt(prod_order.produced_qty)
|
||||
completed_qty = d.completed_qty + (allowance_percentage/100 * d.completed_qty)
|
||||
if total_completed_qty > flt(completed_qty):
|
||||
frappe.throw(_("Row #{0}: Operation {1} is not completed for {2} qty of finished goods in Work Order # {3}. Please update operation status via Time Logs")
|
||||
.format(d.idx, d.operation, total_completed_qty, self.work_order), OperationsNotCompleteError)
|
||||
job_card = frappe.db.get_value('Job Card', {'operation_id': d.name}, 'name')
|
||||
frappe.throw(_("Row #{0}: Operation {1} is not completed for {2} qty of finished goods in Work Order # {3}. Please update operation status via Job Card # {4}")
|
||||
.format(d.idx, d.operation, total_completed_qty, self.work_order, job_card), OperationsNotCompleteError)
|
||||
|
||||
def check_duplicate_entry_for_work_order(self):
|
||||
other_ste = [t[0] for t in frappe.db.get_values("Stock Entry", {
|
||||
|
@ -16,6 +16,9 @@ from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
|
||||
|
||||
from six import string_types, iteritems
|
||||
|
||||
sales_doctypes = ['Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice']
|
||||
purchase_doctypes = ['Material Request', 'Supplier Quotation', 'Purchase Order', 'Purchase Receipt', 'Purchase Invoice']
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_item_details(args):
|
||||
"""
|
||||
@ -228,7 +231,7 @@ def get_basic_details(args, item):
|
||||
|
||||
#Set the UOM to the Default Sales UOM or Default Purchase UOM if configured in the Item Master
|
||||
if not args.uom:
|
||||
if args.get('doctype') in ['Quotation', 'Sales Order', 'Delivery Note', 'Sales Invoice']:
|
||||
if args.get('doctype') in sales_doctypes:
|
||||
args.uom = item.sales_uom if item.sales_uom else item.stock_uom
|
||||
elif (args.get('doctype') in ['Purchase Order', 'Purchase Receipt', 'Purchase Invoice']) or \
|
||||
(args.get('doctype') == 'Material Request' and args.get('material_request_type') == 'Purchase'):
|
||||
@ -281,14 +284,15 @@ def get_basic_details(args, item):
|
||||
out.conversion_factor = 1.0
|
||||
else:
|
||||
out.conversion_factor = args.conversion_factor or \
|
||||
get_conversion_factor(item.item_code, args.uom).get("conversion_factor")
|
||||
get_conversion_factor(item.name, args.uom).get("conversion_factor")
|
||||
|
||||
args.conversion_factor = out.conversion_factor
|
||||
out.stock_qty = out.qty * out.conversion_factor
|
||||
|
||||
# calculate last purchase rate
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import item_last_purchase_rate
|
||||
out.last_purchase_rate = item_last_purchase_rate(args.name, args.conversion_rate, item.item_code, out.conversion_factor)
|
||||
if args.get('doctype') in purchase_doctypes:
|
||||
from erpnext.buying.doctype.purchase_order.purchase_order import item_last_purchase_rate
|
||||
out.last_purchase_rate = item_last_purchase_rate(args.name, args.conversion_rate, item.name, out.conversion_factor)
|
||||
|
||||
# if default specified in item is for another company, fetch from company
|
||||
for d in [
|
||||
|
@ -1,12 +1,13 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"add_total_row": 1,
|
||||
"creation": "2018-10-08 12:11:32.133020",
|
||||
"disable_prepared_report": 0,
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 0,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2018-10-08 12:18:42.834270",
|
||||
"modified": "2019-02-12 14:32:22.874082",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Stock Analytics",
|
||||
|
Loading…
x
Reference in New Issue
Block a user