fix: merge conflict

This commit is contained in:
Nabin Hait 2019-11-25 18:12:56 +05:30
commit a7d168c05f
12 changed files with 78 additions and 125 deletions

View File

@ -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'''

View File

@ -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:

View File

@ -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
})

View File

@ -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,

View File

@ -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'),

View File

@ -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: {} }));
}
}
});

View File

@ -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",

View File

@ -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):

View 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

View File

@ -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

View File

@ -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
})

View File

@ -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()