fix: merge conflict
This commit is contained in:
commit
a7d168c05f
@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '12.1.8'
|
||||
__version__ = '12.2.0'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
@ -357,7 +357,7 @@ class PurchaseInvoice(BuyingController):
|
||||
return
|
||||
if not gl_entries:
|
||||
gl_entries = self.get_gl_entries()
|
||||
|
||||
|
||||
if gl_entries:
|
||||
update_outstanding = "No" if (cint(self.is_paid) or self.write_off_account) else "Yes"
|
||||
|
||||
@ -507,7 +507,7 @@ class PurchaseInvoice(BuyingController):
|
||||
elif not item.is_fixed_asset or (item.is_fixed_asset and not is_cwip_accounting_enabled(asset_category)):
|
||||
expense_account = (item.expense_account
|
||||
if (not item.enable_deferred_expense or self.is_return) else item.deferred_expense_account)
|
||||
|
||||
|
||||
if not item.is_fixed_asset:
|
||||
amount = flt(item.base_net_amount, item.precision("base_net_amount"))
|
||||
else:
|
||||
@ -520,7 +520,7 @@ class PurchaseInvoice(BuyingController):
|
||||
"cost_center": item.cost_center,
|
||||
"project": item.project
|
||||
}, account_currency, item=item))
|
||||
|
||||
|
||||
# If asset is bought through this document and not linked to PR
|
||||
if self.update_stock and item.landed_cost_voucher_amount:
|
||||
expenses_included_in_asset_valuation = self.get_company_default("expenses_included_in_asset_valuation")
|
||||
@ -542,9 +542,9 @@ class PurchaseInvoice(BuyingController):
|
||||
"debit": flt(item.landed_cost_voucher_amount),
|
||||
"project": item.project
|
||||
}, item=item))
|
||||
|
||||
|
||||
# update gross amount of asset bought through this document
|
||||
assets = frappe.db.get_all('Asset',
|
||||
assets = frappe.db.get_all('Asset',
|
||||
filters={ 'purchase_invoice': self.name, 'item_code': item.item_code }
|
||||
)
|
||||
for asset in assets:
|
||||
@ -636,7 +636,7 @@ class PurchaseInvoice(BuyingController):
|
||||
if asset_eiiav_currency == self.company_currency else
|
||||
item.item_tax_amount / self.conversion_rate)
|
||||
}, item=item))
|
||||
|
||||
|
||||
# When update stock is checked
|
||||
# Assets are bought through this document then it will be linked to this document
|
||||
if self.update_stock:
|
||||
@ -658,9 +658,9 @@ class PurchaseInvoice(BuyingController):
|
||||
"debit": flt(item.landed_cost_voucher_amount),
|
||||
"project": item.project
|
||||
}, item=item))
|
||||
|
||||
|
||||
# update gross amount of assets bought through this document
|
||||
assets = frappe.db.get_all('Asset',
|
||||
assets = frappe.db.get_all('Asset',
|
||||
filters={ 'purchase_invoice': self.name, 'item_code': item.item_code }
|
||||
)
|
||||
for asset in assets:
|
||||
|
@ -185,7 +185,7 @@ def validate_account_for_perpetual_inventory(gl_map):
|
||||
raise_exception=StockValueAndAccountBalanceOutOfSync,
|
||||
title=_('Values Out Of Sync'),
|
||||
primary_action={
|
||||
'label': 'Make Journal Entry',
|
||||
'label': _('Make Journal Entry'),
|
||||
'client_action': 'erpnext.route_to_adjustment_jv',
|
||||
'args': journal_entry_args
|
||||
})
|
||||
|
@ -630,7 +630,7 @@ def get_held_invoices(party_type, party):
|
||||
'select name from `tabPurchase Invoice` where release_date IS NOT NULL and release_date > CURDATE()',
|
||||
as_dict=1
|
||||
)
|
||||
held_invoices = [d['name'] for d in held_invoices]
|
||||
held_invoices = set([d['name'] for d in held_invoices])
|
||||
|
||||
return held_invoices
|
||||
|
||||
@ -639,14 +639,19 @@ def get_outstanding_invoices(party_type, party, account, condition=None, filters
|
||||
outstanding_invoices = []
|
||||
precision = frappe.get_precision("Sales Invoice", "outstanding_amount") or 2
|
||||
|
||||
if erpnext.get_party_account_type(party_type) == 'Receivable':
|
||||
if account:
|
||||
root_type = frappe.get_cached_value("Account", account, "root_type")
|
||||
party_account_type = "Receivable" if root_type == "Asset" else "Payable"
|
||||
else:
|
||||
party_account_type = erpnext.get_party_account_type(party_type)
|
||||
|
||||
if party_account_type == 'Receivable':
|
||||
dr_or_cr = "debit_in_account_currency - credit_in_account_currency"
|
||||
payment_dr_or_cr = "credit_in_account_currency - debit_in_account_currency"
|
||||
else:
|
||||
dr_or_cr = "credit_in_account_currency - debit_in_account_currency"
|
||||
payment_dr_or_cr = "debit_in_account_currency - credit_in_account_currency"
|
||||
|
||||
invoice = 'Sales Invoice' if erpnext.get_party_account_type(party_type) == 'Receivable' else 'Purchase Invoice'
|
||||
held_invoices = get_held_invoices(party_type, party)
|
||||
|
||||
invoice_list = frappe.db.sql("""
|
||||
@ -665,7 +670,6 @@ def get_outstanding_invoices(party_type, party, account, condition=None, filters
|
||||
group by voucher_type, voucher_no
|
||||
order by posting_date, name""".format(
|
||||
dr_or_cr=dr_or_cr,
|
||||
invoice = invoice,
|
||||
condition=condition or ""
|
||||
), {
|
||||
"party_type": party_type,
|
||||
|
@ -33,7 +33,7 @@ class Asset(AccountsController):
|
||||
self.make_asset_movement()
|
||||
if not self.booked_fixed_asset and is_cwip_accounting_enabled(self.asset_category):
|
||||
self.make_gl_entries()
|
||||
|
||||
|
||||
def before_cancel(self):
|
||||
self.cancel_auto_gen_movement()
|
||||
|
||||
@ -43,7 +43,7 @@ class Asset(AccountsController):
|
||||
self.set_status()
|
||||
delete_gl_entries(voucher_type='Asset', voucher_no=self.name)
|
||||
self.db_set('booked_fixed_asset', 0)
|
||||
|
||||
|
||||
def validate_asset_and_reference(self):
|
||||
if self.purchase_invoice or self.purchase_receipt:
|
||||
reference_doc = 'Purchase Invoice' if self.purchase_invoice else 'Purchase Receipt'
|
||||
@ -51,8 +51,8 @@ class Asset(AccountsController):
|
||||
reference_doc = frappe.get_doc(reference_doc, reference_name)
|
||||
if reference_doc.get('company') != self.company:
|
||||
frappe.throw(_("Company of asset {0} and purchase document {1} doesn't matches.").format(self.name, reference_doc.get('name')))
|
||||
|
||||
|
||||
|
||||
|
||||
if self.is_existing_asset and self.purchase_invoice:
|
||||
frappe.throw(_("Purchase Invoice cannot be made against an existing asset {0}").format(self.name))
|
||||
|
||||
@ -125,15 +125,17 @@ class Asset(AccountsController):
|
||||
frappe.throw(_("Available-for-use Date should be after purchase date"))
|
||||
|
||||
def cancel_auto_gen_movement(self):
|
||||
reference_docname = self.purchase_invoice or self.purchase_receipt
|
||||
movement = frappe.db.get_all('Asset Movement', filters={ 'reference_name': reference_docname, 'docstatus': 1 })
|
||||
if len(movement) > 1:
|
||||
movements = frappe.db.sql(
|
||||
"""SELECT asm.name, asm.docstatus
|
||||
FROM `tabAsset Movement` asm, `tabAsset Movement Item` asm_item
|
||||
WHERE asm_item.parent=asm.name and asm_item.asset=%s and asm.docstatus=1""", self.name, as_dict=1)
|
||||
if len(movements) > 1:
|
||||
frappe.throw(_('Asset has multiple Asset Movement Entries which has to be \
|
||||
cancelled manually to cancel this asset.'))
|
||||
movement = frappe.get_doc('Asset Movement', movement[0].get('name'))
|
||||
movement = frappe.get_doc('Asset Movement', movements[0].get('name'))
|
||||
movement.flags.ignore_validate = True
|
||||
movement.cancel()
|
||||
|
||||
|
||||
def make_asset_movement(self):
|
||||
reference_doctype = 'Purchase Receipt' if self.purchase_receipt else 'Purchase Invoice'
|
||||
reference_docname = self.purchase_receipt or self.purchase_invoice
|
||||
@ -202,7 +204,7 @@ class Asset(AccountsController):
|
||||
if has_pro_rata and n==0:
|
||||
depreciation_amount, days, months = get_pro_rata_amt(d, depreciation_amount,
|
||||
self.available_for_use_date, d.depreciation_start_date)
|
||||
|
||||
|
||||
# For first depr schedule date will be the start date
|
||||
# so monthly schedule date is calculated by removing month difference between use date and start date
|
||||
monthly_schedule_date = add_months(d.depreciation_start_date, - months + 1)
|
||||
@ -260,7 +262,7 @@ class Asset(AccountsController):
|
||||
else:
|
||||
date = add_months(monthly_schedule_date, r)
|
||||
amount = depreciation_amount / month_range
|
||||
|
||||
|
||||
self.append("schedules", {
|
||||
"schedule_date": date,
|
||||
"depreciation_amount": amount,
|
||||
@ -650,31 +652,18 @@ def make_journal_entry(asset_name):
|
||||
def make_asset_movement(assets, purpose=None):
|
||||
import json
|
||||
from six import string_types
|
||||
|
||||
|
||||
if isinstance(assets, string_types):
|
||||
assets = json.loads(assets)
|
||||
|
||||
|
||||
if len(assets) == 0:
|
||||
frappe.throw(_('Atleast one asset has to be selected.'))
|
||||
|
||||
asset_movement = frappe.new_doc("Asset Movement")
|
||||
asset_movement.purpose = purpose
|
||||
prev_reference_docname = ''
|
||||
|
||||
asset_movement.quantity = len(assets)
|
||||
for asset in assets:
|
||||
asset = frappe.get_doc('Asset', asset.get('name'))
|
||||
# get PR/PI linked with asset
|
||||
reference_docname = asset.get('purchase_receipt') if asset.get('purchase_receipt') \
|
||||
else asset.get('purchase_invoice')
|
||||
# checks if all the assets are linked with a single PR/PI
|
||||
if prev_reference_docname == '':
|
||||
prev_reference_docname = reference_docname
|
||||
elif prev_reference_docname != reference_docname:
|
||||
frappe.throw(_('Assets selected should belong to same reference document.'))
|
||||
|
||||
asset_movement.company = asset.get('company')
|
||||
asset_movement.reference_doctype = 'Purchase Receipt' if asset.get('purchase_receipt') else 'Purchase Invoice'
|
||||
asset_movement.reference_name = prev_reference_docname
|
||||
asset_movement.append("assets", {
|
||||
'asset': asset.get('name'),
|
||||
'source_location': asset.get('location'),
|
||||
|
@ -31,6 +31,13 @@ frappe.ui.form.on('Asset Movement', {
|
||||
name: ["in", ["Purchase Receipt", "Purchase Invoice"]]
|
||||
}
|
||||
};
|
||||
}),
|
||||
frm.set_query("asset", "assets", () => {
|
||||
return {
|
||||
filters: {
|
||||
status: ["not in", ["Draft"]]
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@ -76,50 +83,6 @@ frappe.ui.form.on('Asset Movement', {
|
||||
});
|
||||
});
|
||||
frm.refresh_field('assets');
|
||||
},
|
||||
|
||||
reference_name: function(frm) {
|
||||
if (frm.doc.reference_name && frm.doc.reference_doctype) {
|
||||
const reference_doctype = frm.doc.reference_doctype === 'Purchase Invoice' ? 'purchase_invoice' : 'purchase_receipt';
|
||||
// On selection of reference name,
|
||||
// sets query to display assets linked to that reference doc
|
||||
frm.set_query('asset', 'assets', function() {
|
||||
return {
|
||||
filters: {
|
||||
[reference_doctype] : frm.doc.reference_name
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// fetches linked asset & adds to the assets table
|
||||
frappe.db.get_list('Asset', {
|
||||
fields: ['name', 'location', 'custodian'],
|
||||
filters: {
|
||||
[reference_doctype] : frm.doc.reference_name
|
||||
}
|
||||
}).then((docs) => {
|
||||
if (docs.length == 0) {
|
||||
frappe.msgprint(frappe._(`Please select ${frm.doc.reference_doctype} which has assets.`));
|
||||
frm.doc.reference_name = '';
|
||||
frm.refresh_field('reference_name');
|
||||
return;
|
||||
}
|
||||
frm.doc.assets = [];
|
||||
docs.forEach(doc => {
|
||||
frm.add_child('assets', {
|
||||
asset: doc.name,
|
||||
source_location: doc.location,
|
||||
from_employee: doc.custodian
|
||||
});
|
||||
frm.refresh_field('assets');
|
||||
})
|
||||
}).catch((err) => {
|
||||
console.log(err); // eslint-disable-line
|
||||
});
|
||||
} else {
|
||||
// if reference is deleted then remove query
|
||||
frm.set_query('asset', 'assets', () => ({ filters: {} }));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -9,12 +9,12 @@
|
||||
"purpose",
|
||||
"column_break_4",
|
||||
"transaction_date",
|
||||
"section_break_10",
|
||||
"assets",
|
||||
"reference",
|
||||
"reference_doctype",
|
||||
"column_break_9",
|
||||
"reference_name",
|
||||
"section_break_10",
|
||||
"assets",
|
||||
"amended_from"
|
||||
],
|
||||
"fields": [
|
||||
@ -47,6 +47,7 @@
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"collapsible": 1,
|
||||
"fieldname": "reference",
|
||||
"fieldtype": "Section Break",
|
||||
"label": "Reference"
|
||||
@ -54,18 +55,16 @@
|
||||
{
|
||||
"fieldname": "reference_doctype",
|
||||
"fieldtype": "Link",
|
||||
"label": "Reference Document",
|
||||
"label": "Reference Document Type",
|
||||
"no_copy": 1,
|
||||
"options": "DocType",
|
||||
"reqd": 1
|
||||
"options": "DocType"
|
||||
},
|
||||
{
|
||||
"fieldname": "reference_name",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"label": "Reference Document Name",
|
||||
"no_copy": 1,
|
||||
"options": "reference_doctype",
|
||||
"reqd": 1
|
||||
"options": "reference_doctype"
|
||||
},
|
||||
{
|
||||
"fieldname": "amended_from",
|
||||
@ -93,7 +92,7 @@
|
||||
}
|
||||
],
|
||||
"is_submittable": 1,
|
||||
"modified": "2019-11-21 14:35:51.880332",
|
||||
"modified": "2019-11-23 13:28:47.256935",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Assets",
|
||||
"name": "Asset Movement",
|
||||
|
@ -22,7 +22,7 @@ class AssetMovement(Document):
|
||||
if company != self.company:
|
||||
frappe.throw(_("Asset {0} does not belong to company {1}").format(d.asset, self.company))
|
||||
|
||||
if not(d.source_location or d.target_location or d.from_employee or d.to_employee):
|
||||
if not (d.source_location or d.target_location or d.from_employee or d.to_employee):
|
||||
frappe.throw(_("Either location or employee must be required"))
|
||||
|
||||
def validate_location(self):
|
||||
|
14
erpnext/change_log/v12/v12_2_0.md
Normal file
14
erpnext/change_log/v12/v12_2_0.md
Normal file
@ -0,0 +1,14 @@
|
||||
# Version 12.2.0 Release Notes
|
||||
|
||||
### Accounting
|
||||
|
||||
1. Fixed Asset
|
||||
- "Enable CWIP" options moved to Asset Category from Asset Settings
|
||||
- Removed Asset link from Purchase Receipt Item table
|
||||
- Enhanced Asset master
|
||||
- Asset Movement now handles movement of multiple assets
|
||||
- Introduced monthly depreciation
|
||||
2. GL Entries for Landed Cost Voucher now posted directly against individual Charges account
|
||||
3. Optimization of BOM Update Tool
|
||||
4. Syncing of Stock and Account balance is enforced, in case of perpetual inventory
|
||||
5. Rendered email template in Email Campaign
|
@ -641,7 +641,10 @@ class BuyingController(StockController):
|
||||
asset = frappe.get_doc('Asset', asset.name)
|
||||
if delete_asset and is_auto_create_enabled:
|
||||
# need to delete movements to delete assets otherwise throws link exists error
|
||||
movements = frappe.db.get_all('Asset Movement', filters={ 'reference_name': self.name })
|
||||
movements = frappe.db.sql(
|
||||
"""SELECT asm.name
|
||||
FROM `tabAsset Movement` asm, `tabAsset Movement Item` asm_item
|
||||
WHERE asm_item.parent=asm.name and asm_item.asset=%s""", asset.name, as_dict=1)
|
||||
for movement in movements:
|
||||
frappe.delete_doc('Asset Movement', movement.name, force=1)
|
||||
frappe.delete_doc("Asset", asset.name, force=1)
|
||||
@ -652,8 +655,12 @@ class BuyingController(StockController):
|
||||
asset.purchase_date = self.posting_date
|
||||
asset.supplier = self.supplier
|
||||
elif self.docstatus == 2:
|
||||
asset.set(field, None)
|
||||
asset.supplier = None
|
||||
if asset.docstatus == 0:
|
||||
asset.set(field, None)
|
||||
asset.supplier = None
|
||||
if asset.docstatus == 1 and delete_asset:
|
||||
frappe.throw(_('Cannot cancel this document as it is linked with submitted asset {0}.\
|
||||
Please cancel the it to continue.').format(asset.name))
|
||||
|
||||
asset.flags.ignore_validate_update_after_submit = True
|
||||
asset.flags.ignore_mandatory = True
|
||||
|
@ -140,32 +140,6 @@ class ExpenseClaim(AccountsController):
|
||||
"against": ",".join([d.default_account for d in self.expenses]),
|
||||
"party_type": "Employee",
|
||||
"party": self.employee,
|
||||
"against_voucher_type": self.doctype,
|
||||
"against_voucher": self.name
|
||||
})
|
||||
)
|
||||
|
||||
gl_entry.append(
|
||||
self.get_gl_dict({
|
||||
"account": data.advance_account,
|
||||
"debit": data.allocated_amount,
|
||||
"debit_in_account_currency": data.allocated_amount,
|
||||
"against": self.payable_account,
|
||||
"party_type": "Employee",
|
||||
"party": self.employee,
|
||||
"against_voucher_type": self.doctype,
|
||||
"against_voucher": self.name
|
||||
})
|
||||
)
|
||||
|
||||
gl_entry.append(
|
||||
self.get_gl_dict({
|
||||
"account": self.payable_account,
|
||||
"credit": data.allocated_amount,
|
||||
"credit_in_account_currency": data.allocated_amount,
|
||||
"against": data.advance_account,
|
||||
"party_type": "Employee",
|
||||
"party": self.employee,
|
||||
"against_voucher_type": "Employee Advance",
|
||||
"against_voucher": data.employee_advance
|
||||
})
|
||||
|
@ -7,7 +7,7 @@ import json
|
||||
|
||||
import frappe
|
||||
from frappe import _, throw
|
||||
from frappe.utils import add_days, cstr, date_diff, get_link_to_form, getdate
|
||||
from frappe.utils import add_days, cstr, date_diff, get_link_to_form, getdate, today
|
||||
from frappe.utils.nestedset import NestedSet
|
||||
from frappe.desk.form.assign_to import close_all_assignments, clear
|
||||
from frappe.utils import date_diff
|
||||
@ -212,8 +212,11 @@ def set_multiple_status(names, status):
|
||||
task.save()
|
||||
|
||||
def set_tasks_as_overdue():
|
||||
tasks = frappe.get_all("Task", filters={'status':['not in',['Cancelled', 'Completed']]})
|
||||
tasks = frappe.get_all("Task", filters={'status':['not in',['Cancelled', 'Closed']]})
|
||||
for task in tasks:
|
||||
if frappe.db.get_value("Task", task.name, "status") in 'Pending Review':
|
||||
if getdate(frappe.db.get_value("Task", task.name, "review_date")) < getdate(today()):
|
||||
continue
|
||||
frappe.get_doc("Task", task.name).update_status()
|
||||
|
||||
@frappe.whitelist()
|
||||
|
Loading…
x
Reference in New Issue
Block a user