mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-23 19:19:40 +00:00
Compare commits
105 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b8a7926464 | ||
|
|
7f540af7a6 | ||
|
|
b18ad55e2b | ||
|
|
b439afb5e5 | ||
|
|
cf895c220c | ||
|
|
9342f650e0 | ||
|
|
b91aed807a | ||
|
|
085706bcbf | ||
|
|
8685225644 | ||
|
|
6557e37d5c | ||
|
|
698c040d21 | ||
|
|
c381327e6e | ||
|
|
334f032780 | ||
|
|
ee874a2a36 | ||
|
|
8132be288f | ||
|
|
d75d3a927d | ||
|
|
651d8e996b | ||
|
|
d01d74cafd | ||
|
|
9789b50ae5 | ||
|
|
5224a04628 | ||
|
|
bdab3103e3 | ||
|
|
376e8945f7 | ||
|
|
3d5ef804b2 | ||
|
|
977eff911f | ||
|
|
9b797974b5 | ||
|
|
075e33245e | ||
|
|
fd23fa7c0b | ||
|
|
542bf8f7d4 | ||
|
|
4810d1fa2d | ||
|
|
8d161ef2e1 | ||
|
|
e60d51b74c | ||
|
|
b30e184f6b | ||
|
|
0900407c18 | ||
|
|
c16b373969 | ||
|
|
e9fc31168d | ||
|
|
d33c44e3a5 | ||
|
|
a27c417e48 | ||
|
|
cbd26e3b2c | ||
|
|
2a81960e0b | ||
|
|
801029e055 | ||
|
|
c29c5210f9 | ||
|
|
a3a59ea895 | ||
|
|
684d44385f | ||
|
|
eae077e05d | ||
|
|
e887e92dd4 | ||
|
|
0a1f3e4058 | ||
|
|
05d0cd9574 | ||
|
|
2ef7c7ae5c | ||
|
|
d79cca3ba7 | ||
|
|
f83302836c | ||
|
|
bd99a7cb5d | ||
|
|
29570d1ecb | ||
|
|
f2b7ec919a | ||
|
|
f76aab6021 | ||
|
|
2b63e14089 | ||
|
|
1d210968de | ||
|
|
0c93445be0 | ||
|
|
7fc05d6432 | ||
|
|
a943535520 | ||
|
|
60fb1b8643 | ||
|
|
aa68058910 | ||
|
|
8dd859920f | ||
|
|
7f6b99aca4 | ||
|
|
01dc2e412d | ||
|
|
e9747a8a6e | ||
|
|
7652b857c8 | ||
|
|
98f499a43e | ||
|
|
535462fc20 | ||
|
|
e346a499c7 | ||
|
|
8adbfa8a09 | ||
|
|
866c295989 | ||
|
|
67bceef1cb | ||
|
|
38bfcaa203 | ||
|
|
00e841d744 | ||
|
|
9b18ed4ffe | ||
|
|
d65d67e0a7 | ||
|
|
a78bac61cc | ||
|
|
48cb3d89b6 | ||
|
|
8dfbe7c748 | ||
|
|
99a3593a0d | ||
|
|
7be942db54 | ||
|
|
24f658d633 | ||
|
|
d51e1587d5 | ||
|
|
b3ba7f01ef | ||
|
|
e0ab64d6cc | ||
|
|
952b1cb9a7 | ||
|
|
6f27f580e1 | ||
|
|
440650d4a2 | ||
|
|
6261745366 | ||
|
|
d209f21e76 | ||
|
|
da4689461a | ||
|
|
a5a733630f | ||
|
|
0075c7e659 | ||
|
|
7017dc029a | ||
|
|
f98835036b | ||
|
|
47c8d5fd56 | ||
|
|
6209f2f75b | ||
|
|
463808ef9e | ||
|
|
256a3fef95 | ||
|
|
387c2846aa | ||
|
|
2cb294c8b4 | ||
|
|
598a0c918d | ||
|
|
176577b549 | ||
|
|
27c1f85836 | ||
|
|
84ecaac27d |
@@ -2,7 +2,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
__version__ = '7.1.9'
|
||||
__version__ = '7.1.18'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
||||
@@ -27,7 +27,8 @@ frappe.treeview_settings["Account"] = {
|
||||
{fieldtype:'Check', fieldname:'is_group', label:__('Is Group'),
|
||||
description: __('Further accounts can be made under Groups, but entries can be made against non-Groups')},
|
||||
{fieldtype:'Select', fieldname:'root_type', label:__('Root Type'),
|
||||
options: ['Asset', 'Liability', 'Equity', 'Income', 'Expense'].join('\n')},
|
||||
options: ['Asset', 'Liability', 'Equity', 'Income', 'Expense'].join('\n'),
|
||||
depends_on: 'eval:doc.is_group && !doc.parent_account'},
|
||||
{fieldtype:'Select', fieldname:'account_type', label:__('Account Type'),
|
||||
options: ['', 'Bank', 'Cash', 'Stock', 'Tax', 'Chargeable', 'Fixed Asset'].join('\n'),
|
||||
description: __("Optional. This setting will be used to filter in various transactions.")
|
||||
@@ -79,4 +80,4 @@ frappe.treeview_settings["Account"] = {
|
||||
}
|
||||
],
|
||||
extend_toolbar: true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ frappe.ui.form.on('Asset', {
|
||||
refresh: function(frm) {
|
||||
frappe.ui.form.trigger("Asset", "is_existing_asset");
|
||||
frm.toggle_display("next_depreciation_date", frm.doc.docstatus < 1);
|
||||
frm.events.make_schedules_editable(frm);
|
||||
|
||||
if (frm.doc.docstatus==1) {
|
||||
if (frm.doc.status=='Submitted' && !frm.doc.is_existing_asset && !frm.doc.purchase_invoice) {
|
||||
@@ -141,6 +142,22 @@ frappe.ui.form.on('Asset', {
|
||||
frm.toggle_enable("supplier", frm.doc.is_existing_asset);
|
||||
frm.toggle_reqd("next_depreciation_date", !frm.doc.is_existing_asset);
|
||||
},
|
||||
|
||||
opening_accumulated_depreciation: function(frm) {
|
||||
erpnext.asset.set_accululated_depreciation(frm);
|
||||
},
|
||||
|
||||
depreciation_method: function(frm) {
|
||||
frm.events.make_schedules_editable(frm);
|
||||
},
|
||||
|
||||
make_schedules_editable: function(frm) {
|
||||
var is_editable = frm.doc.depreciation_method==="Manual" ? true : false;
|
||||
frm.toggle_enable("schedules", is_editable);
|
||||
frm.fields_dict["schedules"].grid.toggle_enable("schedule_date", is_editable);
|
||||
frm.fields_dict["schedules"].grid.toggle_enable("depreciation_amount", is_editable);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
frappe.ui.form.on('Depreciation Schedule', {
|
||||
@@ -159,9 +176,25 @@ frappe.ui.form.on('Depreciation Schedule', {
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
depreciation_amount: function(frm, cdt, cdn) {
|
||||
erpnext.asset.set_accululated_depreciation(frm);
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
erpnext.asset.set_accululated_depreciation = function(frm) {
|
||||
if(frm.doc.depreciation_method != "Manual") return;
|
||||
|
||||
accumulated_depreciation = flt(frm.doc.opening_accumulated_depreciation);
|
||||
$.each(frm.doc.schedules || [], function(i, row) {
|
||||
accumulated_depreciation += flt(row.depreciation_amount);
|
||||
frappe.model.set_value(row.doctype, row.name,
|
||||
"accumulated_depreciation_amount", accumulated_depreciation);
|
||||
})
|
||||
}
|
||||
|
||||
erpnext.asset.make_purchase_invoice = function(frm) {
|
||||
frappe.call({
|
||||
args: {
|
||||
|
||||
@@ -516,7 +516,7 @@
|
||||
"columns": 0,
|
||||
"fieldname": "value_after_depreciation",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
@@ -580,7 +580,7 @@
|
||||
"label": "Depreciation Method",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nStraight Line\nDouble Declining Balance",
|
||||
"options": "\nStraight Line\nDouble Declining Balance\nManual",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
@@ -750,7 +750,7 @@
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
@@ -797,7 +797,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-11-03 14:58:53.710357",
|
||||
"modified": "2016-11-18 15:59:19.774500",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Asset",
|
||||
|
||||
@@ -18,6 +18,7 @@ class Asset(Document):
|
||||
self.set_missing_values()
|
||||
self.validate_asset_values()
|
||||
self.make_depreciation_schedule()
|
||||
self.set_accumulated_depreciation()
|
||||
self.validate_expected_value_after_useful_life()
|
||||
# Validate depreciation related accounts
|
||||
get_depreciation_accounts(self)
|
||||
@@ -48,7 +49,7 @@ class Asset(Document):
|
||||
for field, value in item_details.items():
|
||||
if not self.get(field):
|
||||
self.set(field, value)
|
||||
|
||||
|
||||
self.value_after_depreciation = (flt(self.gross_purchase_amount) -
|
||||
flt(self.opening_accumulated_depreciation))
|
||||
|
||||
@@ -87,9 +88,10 @@ class Asset(Document):
|
||||
frappe.throw(_("Please set Next Depreciation Date"))
|
||||
|
||||
def make_depreciation_schedule(self):
|
||||
self.schedules = []
|
||||
if self.depreciation_method != 'Manual':
|
||||
self.schedules = []
|
||||
|
||||
if not self.get("schedules") and self.next_depreciation_date:
|
||||
accumulated_depreciation = flt(self.opening_accumulated_depreciation)
|
||||
value_after_depreciation = flt(self.value_after_depreciation)
|
||||
|
||||
number_of_pending_depreciations = cint(self.total_number_of_depreciations) - \
|
||||
@@ -100,18 +102,21 @@ class Asset(Document):
|
||||
n * cint(self.frequency_of_depreciation))
|
||||
|
||||
depreciation_amount = self.get_depreciation_amount(value_after_depreciation)
|
||||
|
||||
accumulated_depreciation += flt(depreciation_amount)
|
||||
value_after_depreciation -= flt(depreciation_amount)
|
||||
|
||||
self.append("schedules", {
|
||||
"schedule_date": schedule_date,
|
||||
"depreciation_amount": depreciation_amount,
|
||||
"accumulated_depreciation_amount": accumulated_depreciation
|
||||
"depreciation_amount": depreciation_amount
|
||||
})
|
||||
|
||||
def set_accumulated_depreciation(self):
|
||||
accumulated_depreciation = flt(self.opening_accumulated_depreciation)
|
||||
for d in self.get("schedules"):
|
||||
accumulated_depreciation += flt(d.depreciation_amount)
|
||||
d.accumulated_depreciation_amount = accumulated_depreciation
|
||||
|
||||
def get_depreciation_amount(self, depreciable_value):
|
||||
if self.depreciation_method == "Straight Line":
|
||||
if self.depreciation_method in ("Straight Line", "Manual"):
|
||||
depreciation_amount = (flt(self.value_after_depreciation) -
|
||||
flt(self.expected_value_after_useful_life)) / (cint(self.total_number_of_depreciations) -
|
||||
cint(self.number_of_depreciations_booked))
|
||||
@@ -126,16 +131,15 @@ class Asset(Document):
|
||||
return depreciation_amount
|
||||
|
||||
def validate_expected_value_after_useful_life(self):
|
||||
if self.depreciation_method == "Double Declining Balance":
|
||||
accumulated_depreciation_after_full_schedule = \
|
||||
max([d.accumulated_depreciation_amount for d in self.get("schedules")])
|
||||
|
||||
asset_value_after_full_schedule = (flt(self.gross_purchase_amount) -
|
||||
flt(accumulated_depreciation_after_full_schedule))
|
||||
|
||||
if self.expected_value_after_useful_life < asset_value_after_full_schedule:
|
||||
frappe.throw(_("Expected value after useful life must be greater than or equal to {0}")
|
||||
.format(asset_value_after_full_schedule))
|
||||
accumulated_depreciation_after_full_schedule = \
|
||||
max([d.accumulated_depreciation_amount for d in self.get("schedules")])
|
||||
|
||||
asset_value_after_full_schedule = (flt(self.gross_purchase_amount) -
|
||||
flt(accumulated_depreciation_after_full_schedule))
|
||||
|
||||
if self.expected_value_after_useful_life < asset_value_after_full_schedule:
|
||||
frappe.throw(_("Expected value after useful life must be greater than or equal to {0}")
|
||||
.format(asset_value_after_full_schedule))
|
||||
|
||||
def validate_cancellation(self):
|
||||
if self.status not in ("Submitted", "Partially Depreciated", "Fully Depreciated"):
|
||||
|
||||
@@ -119,6 +119,30 @@ class TestAsset(unittest.TestCase):
|
||||
for d in asset.get("schedules")]
|
||||
|
||||
self.assertEqual(schedules, expected_schedules)
|
||||
|
||||
def test_schedule_for_manual_method(self):
|
||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||
asset.depreciation_method = "Manual"
|
||||
asset.schedules = []
|
||||
for schedule_date, amount in [["2020-12-31", 40000], ["2021-06-30", 30000], ["2021-10-31", 20000]]:
|
||||
asset.append("schedules", {
|
||||
"schedule_date": schedule_date,
|
||||
"depreciation_amount": amount
|
||||
})
|
||||
asset.save()
|
||||
|
||||
self.assertEqual(asset.status, "Draft")
|
||||
|
||||
expected_schedules = [
|
||||
["2020-12-31", 40000, 40000],
|
||||
["2021-06-30", 30000, 70000],
|
||||
["2021-10-31", 20000, 90000]
|
||||
]
|
||||
|
||||
schedules = [[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
|
||||
for d in asset.get("schedules")]
|
||||
|
||||
self.assertEqual(schedules, expected_schedules)
|
||||
|
||||
def test_depreciation(self):
|
||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||
|
||||
@@ -46,6 +46,12 @@ frappe.ui.form.on("Bank Reconciliation", {
|
||||
callback: function(r, rt) {
|
||||
frm.refresh_field("payment_entries");
|
||||
frm.refresh_fields();
|
||||
|
||||
$(frm.fields_dict.payment_entries.wrapper).find("[data-fieldname=amount]").each(function(i,v){
|
||||
if (i !=0){
|
||||
$(v).addClass("text-right")
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils import flt, getdate, nowdate
|
||||
from frappe.utils import flt, getdate, nowdate, fmt_money
|
||||
from frappe import msgprint, _
|
||||
from frappe.model.document import Document
|
||||
|
||||
@@ -26,8 +26,8 @@ class BankReconciliation(Document):
|
||||
select
|
||||
"Journal Entry" as payment_document, t1.name as payment_entry,
|
||||
t1.cheque_no as cheque_number, t1.cheque_date,
|
||||
abs(t2.debit_in_account_currency - t2.credit_in_account_currency) as amount,
|
||||
t1.posting_date, t2.against_account, t1.clearance_date
|
||||
t2.debit_in_account_currency as debit, t2.credit_in_account_currency as credit,
|
||||
t1.posting_date, t2.against_account, t1.clearance_date, t2.account_currency
|
||||
from
|
||||
`tabJournal Entry` t1, `tabJournal Entry Account` t2
|
||||
where
|
||||
@@ -36,21 +36,23 @@ class BankReconciliation(Document):
|
||||
and ifnull(t1.is_opening, 'No') = 'No' {0}
|
||||
order by t1.posting_date ASC, t1.name DESC
|
||||
""".format(condition), (self.bank_account, self.from_date, self.to_date), as_dict=1)
|
||||
|
||||
|
||||
payment_entries = frappe.db.sql("""
|
||||
select
|
||||
"Payment Entry" as payment_document, name as payment_entry,
|
||||
reference_no as cheque_number, reference_date as cheque_date,
|
||||
if(paid_from=%s, paid_amount, received_amount) as amount,
|
||||
posting_date, party as against_account, clearance_date
|
||||
if(paid_from=%(account)s, paid_amount, "") as credit,
|
||||
if(paid_from=%(account)s, "", received_amount) as debit,
|
||||
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date,
|
||||
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
|
||||
from `tabPayment Entry`
|
||||
where
|
||||
(paid_from=%s or paid_to=%s) and docstatus=1
|
||||
and posting_date >= %s and posting_date <= %s {0}
|
||||
(paid_from=%(account)s or paid_to=%(account)s) and docstatus=1
|
||||
and posting_date >= %(from)s and posting_date <= %(to)s {0}
|
||||
order by
|
||||
posting_date ASC, name DESC
|
||||
""".format(condition),
|
||||
(self.bank_account, self.bank_account, self.bank_account, self.from_date, self.to_date), as_dict=1)
|
||||
{"account":self.bank_account, "from":self.from_date, "to":self.to_date}, as_dict=1)
|
||||
|
||||
entries = sorted(list(payment_entries)+list(journal_entries),
|
||||
key=lambda k: k['posting_date'] or getdate(nowdate()))
|
||||
@@ -60,6 +62,11 @@ class BankReconciliation(Document):
|
||||
|
||||
for d in entries:
|
||||
row = self.append('payment_entries', {})
|
||||
|
||||
d.amount = fmt_money(d.debit if d.debit else d.credit, 2, d.account_currency) + " " + (_("Dr") if d.debit else _("Cr"))
|
||||
d.pop("credit")
|
||||
d.pop("debit")
|
||||
d.pop("account_currency")
|
||||
row.update(d)
|
||||
self.total_amount += flt(d.amount)
|
||||
|
||||
|
||||
@@ -40,14 +40,14 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"columns": 1,
|
||||
"fieldname": "payment_entry",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Payment Entry",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -69,7 +69,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 3,
|
||||
"columns": 2,
|
||||
"fieldname": "against_account",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
@@ -99,7 +99,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 2,
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@@ -110,7 +110,7 @@
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "debit",
|
||||
"oldfieldtype": "Currency",
|
||||
"options": "account_currency",
|
||||
"options": "",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
@@ -151,7 +151,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"columns": 2,
|
||||
"fieldname": "posting_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
@@ -178,7 +178,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 3,
|
||||
"columns": 1,
|
||||
"fieldname": "cheque_number",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
@@ -267,7 +267,7 @@
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2016-08-26 01:51:36.123941",
|
||||
"modified": "2016-11-17 11:39:00.308624",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Bank Reconciliation Detail",
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
"doctype": "DocType",
|
||||
"document_type": "Document",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "schedule_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
@@ -29,7 +31,8 @@
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -40,6 +43,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "depreciation_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
@@ -55,7 +59,8 @@
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -66,6 +71,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
@@ -80,6 +86,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -90,6 +97,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "accumulated_depreciation_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
@@ -106,8 +114,9 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
@@ -116,6 +125,8 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.docstatus==1",
|
||||
"fieldname": "journal_entry",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@@ -132,6 +143,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -142,7 +154,8 @@
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"depends_on": "eval:(!doc.journal_entry && doc.schedule_date <= get_today())",
|
||||
"columns": 0,
|
||||
"depends_on": "eval:(doc.docstatus==1 && !doc.journal_entry && doc.schedule_date <= get_today())",
|
||||
"fieldname": "make_depreciation_entry",
|
||||
"fieldtype": "Button",
|
||||
"hidden": 0,
|
||||
@@ -158,6 +171,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -175,7 +189,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-07-11 03:27:59.603924",
|
||||
"modified": "2016-11-18 16:42:19.543657",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Depreciation Schedule",
|
||||
|
||||
@@ -64,11 +64,20 @@ class JournalEntry(AccountsController):
|
||||
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries
|
||||
from erpnext.hr.doctype.salary_slip.salary_slip import unlink_ref_doc_from_salary_slip
|
||||
unlink_ref_doc_from_payment_entries(self.doctype, self.name)
|
||||
unlink_ref_doc_from_salary_slip(self.name)
|
||||
unlink_ref_doc_from_salary_slip(self.name)
|
||||
self.make_gl_entries(1)
|
||||
self.update_advance_paid()
|
||||
self.update_expense_claim()
|
||||
|
||||
self.unlink_advance_entry_reference()
|
||||
|
||||
def unlink_advance_entry_reference(self):
|
||||
for d in self.get("accounts"):
|
||||
if d.is_advance and d.reference_type in ("Sales Invoice", "Purchase Invoice"):
|
||||
doc = frappe.get_doc(d.reference_type, d.reference_name)
|
||||
doc.delink_advance_entries(self.name)
|
||||
d.reference_type = ''
|
||||
d.reference_name = ''
|
||||
d.db_update()
|
||||
|
||||
def validate_party(self):
|
||||
for d in self.get("accounts"):
|
||||
|
||||
@@ -9,11 +9,14 @@
|
||||
"description": "**Monthly Distribution** helps you distribute the Budget/Target across months if you have seasonality in your business.",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 0,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"description": "Name of the Monthly Distribution",
|
||||
"fieldname": "distribution_id",
|
||||
"fieldtype": "Data",
|
||||
@@ -31,6 +34,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -41,6 +45,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "fiscal_year",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
@@ -58,6 +63,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 1,
|
||||
@@ -68,6 +74,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "percentages",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
@@ -85,6 +92,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -96,13 +104,14 @@
|
||||
"hide_toolbar": 0,
|
||||
"icon": "icon-bar-chart",
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-05-16 16:35:20.349194",
|
||||
"modified": "2016-11-21 14:54:35.998761",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Monthly Distribution",
|
||||
@@ -119,6 +128,7 @@
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"is_custom": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
@@ -139,6 +149,7 @@
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"is_custom": 0,
|
||||
"permlevel": 2,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
@@ -150,7 +161,7 @@
|
||||
"write": 0
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"sort_field": "modified",
|
||||
|
||||
@@ -406,7 +406,10 @@ frappe.ui.form.on('Payment Entry', {
|
||||
|
||||
if(!frm.doc.paid_amount && frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency) {
|
||||
frm.set_value("paid_amount", frm.doc.received_amount);
|
||||
frm.set_value("source_exchange_rate", frm.doc.target_exchange_rate);
|
||||
|
||||
if(frm.doc.target_exchange_rate) {
|
||||
frm.set_value("source_exchange_rate", frm.doc.target_exchange_rate);
|
||||
}
|
||||
frm.set_value("base_paid_amount", frm.doc.base_received_amount);
|
||||
}
|
||||
|
||||
@@ -426,7 +429,10 @@ frappe.ui.form.on('Payment Entry', {
|
||||
(frm.doc.paid_from_account_currency == frm.doc.paid_to_account_currency)) {
|
||||
|
||||
frm.set_value("received_amount", frm.doc.paid_amount);
|
||||
frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate);
|
||||
|
||||
if(frm.doc.source_exchange_rate) {
|
||||
frm.set_value("target_exchange_rate", frm.doc.source_exchange_rate);
|
||||
}
|
||||
frm.set_value("base_received_amount", frm.doc.base_paid_amount);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,14 @@ class PaymentEntry(AccountsController):
|
||||
self.setup_party_account_field()
|
||||
self.make_gl_entries(cancel=1)
|
||||
self.update_advance_paid()
|
||||
|
||||
self.delink_advance_entry_references()
|
||||
|
||||
def delink_advance_entry_references(self):
|
||||
for reference in self.references:
|
||||
if reference.reference_doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||
doc = frappe.get_doc(reference.reference_doctype, reference.reference_name)
|
||||
doc.delink_advance_entries(self.name)
|
||||
|
||||
def set_missing_values(self):
|
||||
if self.payment_type == "Internal Transfer":
|
||||
for field in ("party", "party_balance", "total_allocated_amount",
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -58,6 +59,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -84,6 +86,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -109,6 +112,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -119,7 +123,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"columns": 2,
|
||||
"fieldname": "total_amount",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@@ -135,6 +139,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -145,7 +150,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 3,
|
||||
"columns": 2,
|
||||
"fieldname": "outstanding_amount",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@@ -161,6 +166,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -171,7 +177,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 3,
|
||||
"columns": 2,
|
||||
"fieldname": "allocated_amount",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@@ -187,6 +193,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -213,6 +220,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -230,7 +238,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-08-26 01:59:04.697274",
|
||||
"modified": "2016-11-14 12:28:51.822341",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry Reference",
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2016-11-16 15:27:16.413449",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "customer_group",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Customer Group",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Customer Group",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-11-16 15:27:25.730507",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Customer Group",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class POSCustomerGroup(Document):
|
||||
pass
|
||||
0
erpnext/accounts/doctype/pos_item_group/__init__.py
Normal file
0
erpnext/accounts/doctype/pos_item_group/__init__.py
Normal file
66
erpnext/accounts/doctype/pos_item_group/pos_item_group.json
Normal file
66
erpnext/accounts/doctype/pos_item_group/pos_item_group.json
Normal file
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2016-11-16 15:26:47.706713",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "item_group",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 1,
|
||||
"label": "Item Group",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Item Group",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-11-16 15:27:32.263630",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Item Group",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_seen": 0
|
||||
}
|
||||
10
erpnext/accounts/doctype/pos_item_group/pos_item_group.py
Normal file
10
erpnext/accounts/doctype/pos_item_group/pos_item_group.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class POSItemGroup(Document):
|
||||
pass
|
||||
@@ -26,6 +26,30 @@ frappe.ui.form.on("POS Profile", "onload", function(frm) {
|
||||
});
|
||||
});
|
||||
|
||||
frappe.ui.form.on("POS Profile", {
|
||||
setup: function(frm) {
|
||||
frm.trigger("get_query_for_groups")
|
||||
},
|
||||
|
||||
get_query_for_groups: function(frm) {
|
||||
frm.fields_dict['item_groups'].grid.get_field('item_group').get_query = function(frm, cdt, cdn) {
|
||||
return{
|
||||
filters: {
|
||||
'is_group': 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
frm.fields_dict['customer_groups'].grid.get_field('customer_group').get_query = function(frm, cdt, cdn) {
|
||||
return{
|
||||
filters: {
|
||||
'is_group': 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Income Account
|
||||
// --------------------------------
|
||||
cur_frm.fields_dict['income_account'].get_query = function(doc,cdt,cdn) {
|
||||
|
||||
@@ -375,6 +375,114 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_14",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "item_groups",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Item Groups",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "POS Item Group",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_16",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "customer_groups",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Customer Groups",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "POS Customer Group",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
@@ -543,34 +651,6 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "customer_group",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_list_view": 0,
|
||||
"label": "Customer Group",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Customer Group",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
@@ -951,8 +1031,8 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-11-03 15:53:33.820428",
|
||||
"modified_by": "Administrator",
|
||||
"modified": "2016-11-17 00:20:51.377850",
|
||||
"modified_by": "rohit@erpnext.com",
|
||||
"module": "Accounts",
|
||||
"name": "POS Profile",
|
||||
"owner": "Administrator",
|
||||
|
||||
@@ -13,6 +13,7 @@ class POSProfile(Document):
|
||||
def validate(self):
|
||||
self.check_for_duplicate()
|
||||
self.validate_all_link_fields()
|
||||
self.validate_duplicate_groups()
|
||||
|
||||
def check_for_duplicate(self):
|
||||
res = frappe.db.sql("""select name, user from `tabPOS Profile`
|
||||
@@ -37,6 +38,16 @@ class POSProfile(Document):
|
||||
"company": self.company, "name": link_dn}):
|
||||
frappe.throw(_("{0} does not belong to Company {1}").format(link_dn, self.company))
|
||||
|
||||
def validate_duplicate_groups(self):
|
||||
item_groups = [d.item_group for d in self.item_groups]
|
||||
customer_groups = [d.customer_group for d in self.customer_groups]
|
||||
|
||||
if len(item_groups) != len(set(item_groups)):
|
||||
frappe.throw(_("Duplicate item group found in the item group table"), title = "Duplicate Item Group")
|
||||
|
||||
if len(customer_groups) != len(set(customer_groups)):
|
||||
frappe.throw(_("Duplicate customer group found in the cutomer group table"), title = "Duplicate Customer Group")
|
||||
|
||||
def before_save(self):
|
||||
set_account_for_mode_of_payment(self)
|
||||
|
||||
|
||||
@@ -5,8 +5,47 @@ from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
|
||||
# test_records = frappe.get_test_records('POS Profile')
|
||||
from erpnext.stock.get_item_details import get_pos_profile
|
||||
from erpnext.accounts.doctype.sales_invoice.pos import get_items_list, get_customers_list
|
||||
|
||||
class TestPOSProfile(unittest.TestCase):
|
||||
pass
|
||||
def test_pos_profile(self):
|
||||
make_pos_profile()
|
||||
|
||||
pos_profile = get_pos_profile("_Test Company") or {}
|
||||
if pos_profile:
|
||||
doc = frappe.get_doc("POS Profile", pos_profile.get("name"))
|
||||
doc.append('item_groups', {'item_group': '_Test Item Group'})
|
||||
doc.append('customer_groups', {'customer_group': '_Test Customer Group'})
|
||||
doc.save()
|
||||
|
||||
items = get_items_list(doc)
|
||||
customers = get_customers_list(doc)
|
||||
|
||||
products_count = frappe.db.sql(""" select count(name) from tabItem where item_group = '_Test Item Group'""", as_list=1)
|
||||
customers_count = frappe.db.sql(""" select count(name) from tabCustomer where customer_group = '_Test Customer Group'""")
|
||||
|
||||
self.assertEquals(len(items), products_count[0][0])
|
||||
self.assertEquals(len(customers), customers_count[0][0])
|
||||
|
||||
frappe.db.sql("delete from `tabPOS Profile`")
|
||||
|
||||
def make_pos_profile():
|
||||
pos_profile = frappe.get_doc({
|
||||
"company": "_Test Company",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"currency": "INR",
|
||||
"doctype": "POS Profile",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"income_account": "Sales - _TC",
|
||||
"name": "_Test POS Profile",
|
||||
"naming_series": "_T-POS Profile-",
|
||||
"selling_price_list": "_Test Price List",
|
||||
"territory": "_Test Territory",
|
||||
"warehouse": "_Test Warehouse - _TC",
|
||||
"write_off_account": "_Test Write Off - _TC",
|
||||
"write_off_cost_center": "_Test Write Off Cost Center - _TC"
|
||||
})
|
||||
|
||||
if not frappe.db.exists("POS Profile", "_Test POS Profile"):
|
||||
pos_profile.insert()
|
||||
@@ -4,7 +4,6 @@ def get_data():
|
||||
return {
|
||||
'fieldname': 'purchase_invoice',
|
||||
'non_standard_fieldnames': {
|
||||
'Delivery Note': 'against_sales_invoice',
|
||||
'Journal Entry': 'reference_name',
|
||||
'Payment Entry': 'reference_name',
|
||||
'Payment Request': 'reference_name',
|
||||
@@ -12,8 +11,8 @@ def get_data():
|
||||
'Purchase Invoice': 'return_against'
|
||||
},
|
||||
'internal_links': {
|
||||
'Purchase Order': ['items', 'sales_order'],
|
||||
'Purchase Receipt': ['items', 'delivery_note'],
|
||||
'Purchase Order': ['items', 'purchase_order'],
|
||||
'Purchase Receipt': ['items', 'purchase_receipt'],
|
||||
},
|
||||
'transactions': [
|
||||
{
|
||||
|
||||
@@ -437,6 +437,85 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
|
||||
self.assertEquals(frappe.db.get_value("Serial No", pi.get("items")[0].rejected_serial_no,
|
||||
"warehouse"), pi.get("items")[0].rejected_warehouse)
|
||||
|
||||
def test_outstanding_amount_after_advance_jv_cancelation(self):
|
||||
from erpnext.accounts.doctype.journal_entry.test_journal_entry \
|
||||
import test_records as jv_test_records
|
||||
|
||||
jv = frappe.copy_doc(jv_test_records[1])
|
||||
jv.insert()
|
||||
jv.submit()
|
||||
|
||||
pi = frappe.copy_doc(test_records[0])
|
||||
pi.append("advances", {
|
||||
"reference_type": "Journal Entry",
|
||||
"reference_name": jv.name,
|
||||
"reference_row": jv.get("accounts")[0].name,
|
||||
"advance_amount": 400,
|
||||
"allocated_amount": 300,
|
||||
"remarks": jv.remark
|
||||
})
|
||||
pi.insert()
|
||||
pi.submit()
|
||||
pi.load_from_db()
|
||||
|
||||
#check outstanding after advance allocation
|
||||
self.assertEqual(flt(pi.outstanding_amount), flt(pi.grand_total - pi.total_advance))
|
||||
|
||||
#added to avoid Document has been modified exception
|
||||
jv = frappe.get_doc("Journal Entry", jv.name)
|
||||
jv.cancel()
|
||||
|
||||
pi.load_from_db()
|
||||
#check outstanding after advance cancellation
|
||||
self.assertEqual(flt(pi.outstanding_amount), flt(pi.grand_total + pi.total_advance))
|
||||
|
||||
def test_outstanding_amount_after_advance_payment_entry_cancelation(self):
|
||||
pe = frappe.get_doc({
|
||||
"doctype": "Payment Entry",
|
||||
"payment_type": "Pay",
|
||||
"party_type": "Supplier",
|
||||
"party": "_Test Supplier",
|
||||
"company": "_Test Company",
|
||||
"paid_from_account_currency": "INR",
|
||||
"paid_to_account_currency": "INR",
|
||||
"source_exchange_rate": 1,
|
||||
"target_exchange_rate": 1,
|
||||
"reference_no": "1",
|
||||
"reference_date": nowdate(),
|
||||
"received_amount": 300,
|
||||
"paid_amount": 300,
|
||||
"paid_from": "_Test Cash - _TC",
|
||||
"paid_to": "_Test Payable - _TC"
|
||||
})
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
pi = frappe.copy_doc(test_records[0])
|
||||
pi.is_pos = 0
|
||||
pi.append("advances", {
|
||||
"doctype": "Purchase Invoice Advance",
|
||||
"reference_type": "Payment Entry",
|
||||
"reference_name": pe.name,
|
||||
"advance_amount": 300,
|
||||
"allocated_amount": 300,
|
||||
"remarks": pe.remarks
|
||||
})
|
||||
pi.insert()
|
||||
pi.submit()
|
||||
|
||||
pi.load_from_db()
|
||||
|
||||
#check outstanding after advance allocation
|
||||
self.assertEqual(flt(pi.outstanding_amount), flt(pi.grand_total - pi.total_advance))
|
||||
|
||||
#added to avoid Document has been modified exception
|
||||
pe = frappe.get_doc("Payment Entry", pe.name)
|
||||
pe.cancel()
|
||||
|
||||
pi.load_from_db()
|
||||
#check outstanding after advance cancellation
|
||||
self.assertEqual(flt(pi.outstanding_amount), flt(pi.grand_total + pi.total_advance))
|
||||
|
||||
def unlink_payment_on_cancel_of_invoice(enable=1):
|
||||
accounts_settings = frappe.get_doc("Accounts Settings")
|
||||
|
||||
@@ -30,10 +30,16 @@ def get_pos_data():
|
||||
return {
|
||||
'doc': doc,
|
||||
'default_customer': pos_profile.get('customer'),
|
||||
'items': get_items(doc, pos_profile),
|
||||
'customers': get_customers(pos_profile, doc, company_data.default_currency),
|
||||
'pricing_rules': get_pricing_rules(doc),
|
||||
'items': get_items_list(pos_profile),
|
||||
'customers': get_customers_list(pos_profile),
|
||||
'serial_no_data': get_serial_no_data(pos_profile, doc.company),
|
||||
'batch_no_data': get_batch_no_data(),
|
||||
'tax_data': get_item_tax_data(),
|
||||
'price_list_data': get_price_list_data(doc.selling_price_list),
|
||||
'bin_data': get_bin_data(pos_profile),
|
||||
'pricing_rules': get_pricing_rule_data(doc),
|
||||
'print_template': print_template,
|
||||
'pos_profile': pos_profile,
|
||||
'meta': {
|
||||
'invoice': frappe.get_meta('Sales Invoice'),
|
||||
'items': frappe.get_meta('Sales Invoice Item'),
|
||||
@@ -104,63 +110,117 @@ def update_tax_table(doc):
|
||||
for tax in taxes:
|
||||
doc.append('taxes', tax)
|
||||
|
||||
def get_items(doc, pos_profile):
|
||||
item_list = []
|
||||
for item in frappe.get_all("Item", fields=["*"], filters={'disabled': 0, 'has_variants': 0, 'is_sales_item': 1}):
|
||||
item_doc = frappe.get_doc('Item', item.name)
|
||||
if item_doc.taxes:
|
||||
item.taxes = json.dumps(dict(([d.tax_type, d.tax_rate] for d in
|
||||
item_doc.get("taxes"))))
|
||||
def get_items_list(pos_profile):
|
||||
cond = "1=1"
|
||||
item_groups = []
|
||||
if pos_profile.get('item_groups'):
|
||||
# Get items based on the item groups defined in the POS profile
|
||||
|
||||
item.price_list_rate = frappe.db.get_value('Item Price', {'item_code': item.name,
|
||||
'price_list': doc.selling_price_list}, 'price_list_rate') or 0
|
||||
item.default_warehouse = pos_profile.get('warehouse') or \
|
||||
get_item_warehouse_for_company(doc.company, item.default_warehouse) or None
|
||||
item.expense_account = pos_profile.get('expense_account') or item.expense_account
|
||||
item.income_account = pos_profile.get('income_account') or item_doc.income_account
|
||||
item.cost_center = pos_profile.get('cost_center') or item_doc.selling_cost_center
|
||||
item.actual_qty = frappe.db.get_value('Bin', {'item_code': item.name,
|
||||
'warehouse': item.default_warehouse}, 'actual_qty') or 0
|
||||
item.serial_nos = get_serial_nos(item, pos_profile, doc.company)
|
||||
item.batch_nos = frappe.db.sql_list("""select name from `tabBatch` where ifnull(expiry_date, '4000-10-10') > curdate()
|
||||
and item = %(item_code)s""", {'item_code': item.item_code})
|
||||
cond = "item_group in (%s)"%(', '.join(['%s']*len(pos_profile.get('item_groups'))))
|
||||
item_groups = [d.item_group for d in pos_profile.get('item_groups')]
|
||||
|
||||
item_list.append(item)
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
name, item_code, item_name, description, item_group, expense_account, has_batch_no,
|
||||
has_serial_no, expense_account, selling_cost_center, stock_uom, image,
|
||||
default_warehouse, is_stock_item
|
||||
from
|
||||
tabItem
|
||||
where
|
||||
disabled = 0 and has_variants = 0 and is_sales_item = 1 and {cond}
|
||||
""".format(cond=cond), tuple(item_groups), as_dict=1)
|
||||
|
||||
return item_list
|
||||
def get_customers_list(pos_profile):
|
||||
cond = "1=1"
|
||||
customer_groups = []
|
||||
if pos_profile.get('customer_groups'):
|
||||
# Get customers based on the customer groups defined in the POS profile
|
||||
|
||||
def get_item_warehouse_for_company(company, warehouse):
|
||||
if frappe.db.get_value('Warehouse', warehouse, 'company') != company:
|
||||
warehouse = None
|
||||
return warehouse
|
||||
cond = "customer_group in (%s)"%(', '.join(['%s']*len(pos_profile.get('customer_groups'))))
|
||||
customer_groups = [d.customer_group for d in pos_profile.get('customer_groups')]
|
||||
|
||||
return frappe.db.sql(""" select name, customer_name, customer_group,
|
||||
territory from tabCustomer where disabled = 0
|
||||
and {cond}""".format(cond=cond), tuple(customer_groups), as_dict=1) or {}
|
||||
|
||||
def get_serial_no_data(pos_profile, company):
|
||||
# get itemwise serial no data
|
||||
# example {'Nokia Lumia 1020': {'SN0001': 'Pune'}}
|
||||
# where Nokia Lumia 1020 is item code, SN0001 is serial no and Pune is warehouse
|
||||
|
||||
def get_serial_nos(item, pos_profile, company):
|
||||
cond = "1=1"
|
||||
if pos_profile.get('update_stock') and pos_profile.get('warehouse'):
|
||||
cond = "warehouse = '{0}'".format(pos_profile.get('warehouse'))
|
||||
|
||||
serial_nos = frappe.db.sql("""select name, warehouse from `tabSerial No` where {0}
|
||||
and item_code = %(item_code)s and company = %(company)s
|
||||
""".format(cond), {'item_code': item.item_code, 'company': company}, as_dict=1)
|
||||
serial_nos = frappe.db.sql("""select name, warehouse, item_code from `tabSerial No` where {0}
|
||||
and company = %(company)s """.format(cond), {'company': company}, as_dict=1)
|
||||
|
||||
serial_no_list = {}
|
||||
for serial_no in serial_nos:
|
||||
serial_no_list[serial_no.name] = serial_no.warehouse
|
||||
itemwise_serial_no = {}
|
||||
for sn in serial_nos:
|
||||
if sn.item_code not in itemwise_serial_no:
|
||||
itemwise_serial_no.setdefault(sn.item_code, {})
|
||||
itemwise_serial_no[sn.item_code][sn.name] = sn.warehouse
|
||||
|
||||
return serial_no_list
|
||||
return itemwise_serial_no
|
||||
|
||||
def get_customers(pos_profile, doc, company_currency):
|
||||
filters = {'disabled': 0}
|
||||
customer_list = []
|
||||
customers = frappe.get_all("Customer", fields=["*"], filters = filters)
|
||||
def get_batch_no_data():
|
||||
# get itemwise batch no data
|
||||
# exmaple: {'LED-GRE': [Batch001, Batch002]}
|
||||
# where LED-GRE is item code, SN0001 is serial no and Pune is warehouse
|
||||
|
||||
for customer in customers:
|
||||
customer_currency = get_party_account_currency('Customer', customer.name, doc.company) or doc.currency
|
||||
if customer_currency == doc.currency or customer_currency == company_currency:
|
||||
customer_list.append(customer)
|
||||
return customer_list
|
||||
itemwise_batch = {}
|
||||
batches = frappe.db.sql("""select name, item from `tabBatch`
|
||||
where ifnull(expiry_date, '4000-10-10') >= curdate()""", as_dict=1)
|
||||
|
||||
def get_pricing_rules(doc):
|
||||
for batch in batches:
|
||||
if batch.item not in itemwise_batch:
|
||||
itemwise_batch.setdefault(batch.item, [])
|
||||
itemwise_batch[batch.item].append(batch.name)
|
||||
|
||||
return itemwise_batch
|
||||
|
||||
def get_item_tax_data():
|
||||
# get default tax of an item
|
||||
# example: {'Consulting Services': {'Excise 12 - TS': '12.000'}}
|
||||
|
||||
itemwise_tax = {}
|
||||
taxes = frappe.db.sql(""" select parent, tax_type, tax_rate from `tabItem Tax`""", as_dict=1)
|
||||
|
||||
for tax in taxes:
|
||||
if tax.parent not in itemwise_tax:
|
||||
itemwise_tax.setdefault(tax.parent, {})
|
||||
itemwise_tax[tax.parent][tax.tax_type] = tax.tax_rate
|
||||
|
||||
return itemwise_tax
|
||||
|
||||
def get_price_list_data(selling_price_list):
|
||||
itemwise_price_list = {}
|
||||
price_lists = frappe.db.sql("""Select ifnull(price_list_rate, 0) as price_list_rate,
|
||||
item_code from `tabItem Price` ip where price_list = %(price_list)s""",
|
||||
{'price_list': selling_price_list}, as_dict=1)
|
||||
|
||||
for item in price_lists:
|
||||
itemwise_price_list[item.item_code] = item.price_list_rate
|
||||
|
||||
return itemwise_price_list
|
||||
|
||||
def get_bin_data(pos_profile):
|
||||
itemwise_bin_data = {}
|
||||
cond = "1=1"
|
||||
if pos_profile.get('warehouse'):
|
||||
cond = "warehouse = '{0}'".format(pos_profile.get('warehouse'))
|
||||
|
||||
bin_data = frappe.db.sql(""" select item_code, warehouse, actual_qty from `tabBin`
|
||||
where actual_qty > 0 and {cond}""".format(cond=cond), as_dict=1)
|
||||
|
||||
for bins in bin_data:
|
||||
if bins.item_code not in itemwise_bin_data:
|
||||
itemwise_bin_data.setdefault(bins.item_code, {})
|
||||
itemwise_bin_data[bins.item_code][bins.warehouse] = bins.actual_qty
|
||||
|
||||
return itemwise_bin_data
|
||||
|
||||
def get_pricing_rule_data(doc):
|
||||
pricing_rules = ""
|
||||
if doc.ignore_pricing_rule == 0:
|
||||
pricing_rules = frappe.db.sql(""" Select * from `tabPricing Rule` where docstatus < 2
|
||||
|
||||
@@ -20,6 +20,13 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
erpnext.queries.setup_queries(this.frm, "Warehouse", function() {
|
||||
return erpnext.queries.warehouse(me.frm.doc);
|
||||
});
|
||||
|
||||
if(this.frm.doc.__islocal && this.frm.doc.is_pos) {
|
||||
//Load pos profile data on the invoice if the default value of Is POS is 1
|
||||
|
||||
me.frm.script_manager.trigger("is_pos");
|
||||
me.frm.refresh_fields();
|
||||
}
|
||||
},
|
||||
|
||||
refresh: function(doc, dt, dn) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import unittest, copy
|
||||
from frappe.utils import nowdate, add_days, flt, nowdate
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction
|
||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import unlink_payment_on_cancel_of_invoice
|
||||
from erpnext.accounts.doctype.pos_profile.test_pos_profile import make_pos_profile
|
||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
||||
from erpnext.exceptions import InvalidAccountCurrency, InvalidCurrency
|
||||
from erpnext.stock.doctype.serial_no.serial_no import SerialNoWarehouseError
|
||||
@@ -467,7 +468,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
def test_pos_gl_entry_with_perpetual_inventory(self):
|
||||
set_perpetual_inventory()
|
||||
self.make_pos_profile()
|
||||
make_pos_profile()
|
||||
|
||||
self._insert_purchase_receipt()
|
||||
pos = copy.deepcopy(test_records[1])
|
||||
@@ -486,7 +487,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
def test_pos_change_amount(self):
|
||||
set_perpetual_inventory()
|
||||
self.make_pos_profile()
|
||||
make_pos_profile()
|
||||
|
||||
self._insert_purchase_receipt()
|
||||
pos = copy.deepcopy(test_records[1])
|
||||
@@ -508,7 +509,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
set_perpetual_inventory()
|
||||
|
||||
self.make_pos_profile()
|
||||
make_pos_profile()
|
||||
self._insert_purchase_receipt()
|
||||
|
||||
pos = copy.deepcopy(test_records[1])
|
||||
@@ -572,26 +573,6 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
frappe.db.sql("delete from `tabPOS Profile`")
|
||||
|
||||
def make_pos_profile(self):
|
||||
pos_profile = frappe.get_doc({
|
||||
"company": "_Test Company",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"currency": "INR",
|
||||
"doctype": "POS Profile",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"income_account": "Sales - _TC",
|
||||
"name": "_Test POS Profile",
|
||||
"naming_series": "_T-POS Profile-",
|
||||
"selling_price_list": "_Test Price List",
|
||||
"territory": "_Test Territory",
|
||||
"warehouse": "_Test Warehouse - _TC",
|
||||
"write_off_account": "_Test Write Off - _TC",
|
||||
"write_off_cost_center": "_Test Write Off Cost Center - _TC"
|
||||
})
|
||||
|
||||
if not frappe.db.exists("POS Profile", "_Test POS Profile"):
|
||||
pos_profile.insert()
|
||||
|
||||
def test_sales_invoice_gl_entry_with_perpetual_inventory_no_item_code(self):
|
||||
set_perpetual_inventory()
|
||||
|
||||
@@ -980,6 +961,86 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
pe.submit()
|
||||
|
||||
self.assertEquals(frappe.db.get_value('Customer', customer.name, 'status'), 'Active')
|
||||
|
||||
def test_outstanding_amount_after_advance_jv_cancelation(self):
|
||||
from erpnext.accounts.doctype.journal_entry.test_journal_entry \
|
||||
import test_records as jv_test_records
|
||||
|
||||
jv = frappe.copy_doc(jv_test_records[0])
|
||||
jv.insert()
|
||||
jv.submit()
|
||||
|
||||
si = frappe.copy_doc(test_records[0])
|
||||
si.append("advances", {
|
||||
"doctype": "Sales Invoice Advance",
|
||||
"reference_type": "Journal Entry",
|
||||
"reference_name": jv.name,
|
||||
"reference_row": jv.get("accounts")[0].name,
|
||||
"advance_amount": 400,
|
||||
"allocated_amount": 300,
|
||||
"remarks": jv.remark
|
||||
})
|
||||
si.insert()
|
||||
si.submit()
|
||||
si.load_from_db()
|
||||
|
||||
#check outstanding after advance allocation
|
||||
self.assertEqual(flt(si.outstanding_amount), flt(si.grand_total - si.total_advance, si.precision("outstanding_amount")))
|
||||
|
||||
#added to avoid Document has been modified exception
|
||||
jv = frappe.get_doc("Journal Entry", jv.name)
|
||||
jv.cancel()
|
||||
|
||||
si.load_from_db()
|
||||
#check outstanding after advance cancellation
|
||||
self.assertEqual(flt(si.outstanding_amount), flt(si.grand_total + si.total_advance, si.precision("outstanding_amount")))
|
||||
|
||||
def test_outstanding_amount_after_advance_payment_entry_cancelation(self):
|
||||
pe = frappe.get_doc({
|
||||
"doctype": "Payment Entry",
|
||||
"payment_type": "Receive",
|
||||
"party_type": "Customer",
|
||||
"party": "_Test Customer",
|
||||
"company": "_Test Company",
|
||||
"paid_from_account_currency": "INR",
|
||||
"paid_to_account_currency": "INR",
|
||||
"source_exchange_rate": 1,
|
||||
"target_exchange_rate": 1,
|
||||
"reference_no": "1",
|
||||
"reference_date": nowdate(),
|
||||
"received_amount": 300,
|
||||
"paid_amount": 300,
|
||||
"paid_from": "_Test Receivable - _TC",
|
||||
"paid_to": "_Test Cash - _TC"
|
||||
})
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
si = frappe.copy_doc(test_records[0])
|
||||
si.is_pos = 0
|
||||
si.append("advances", {
|
||||
"doctype": "Sales Invoice Advance",
|
||||
"reference_type": "Payment Entry",
|
||||
"reference_name": pe.name,
|
||||
"advance_amount": 300,
|
||||
"allocated_amount": 300,
|
||||
"remarks": pe.remarks
|
||||
})
|
||||
si.insert()
|
||||
si.submit()
|
||||
|
||||
si.load_from_db()
|
||||
|
||||
#check outstanding after advance allocation
|
||||
self.assertEqual(flt(si.outstanding_amount), flt(si.grand_total - si.total_advance, si.precision("outstanding_amount")))
|
||||
|
||||
#added to avoid Document has been modified exception
|
||||
pe = frappe.get_doc("Payment Entry", pe.name)
|
||||
pe.cancel()
|
||||
|
||||
si.load_from_db()
|
||||
#check outstanding after advance cancellation
|
||||
self.assertEqual(flt(si.outstanding_amount), flt(si.grand_total + si.total_advance, si.precision("outstanding_amount")))
|
||||
|
||||
def create_sales_invoice(**args):
|
||||
si = frappe.new_doc("Sales Invoice")
|
||||
|
||||
@@ -25,7 +25,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
this.set_indicator();
|
||||
this.onload();
|
||||
this.make_menu_list();
|
||||
this.set_interval_for_si_sync();
|
||||
this.si_docs = this.get_doc_from_localstorage();
|
||||
},
|
||||
|
||||
@@ -73,8 +72,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
this.get_data_from_server(function(){
|
||||
me.create_new();
|
||||
});
|
||||
|
||||
this.check_internet_connection();
|
||||
},
|
||||
|
||||
make_menu_list: function(){
|
||||
@@ -204,13 +201,10 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
freeze: true,
|
||||
freeze_message: __("Master data syncing, it might take some time"),
|
||||
callback: function(r){
|
||||
window.items = r.message.items;
|
||||
window.customers = r.message.customers;
|
||||
window.pricing_rules = r.message.pricing_rules;
|
||||
window.meta = r.message.meta;
|
||||
window.print_template = r.message.print_template;
|
||||
me.default_customer = r.message.default_customer || null;
|
||||
me.init_master_data(r)
|
||||
localStorage.setItem('doc', JSON.stringify(r.message.doc));
|
||||
me.set_interval_for_si_sync();
|
||||
me.check_internet_connection();
|
||||
if(callback){
|
||||
callback();
|
||||
}
|
||||
@@ -218,6 +212,22 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
})
|
||||
},
|
||||
|
||||
init_master_data: function(r){
|
||||
var me = this;
|
||||
this.meta = r.message.meta;
|
||||
this.item_data = r.message.items;
|
||||
this.customers = r.message.customers;
|
||||
this.serial_no_data = r.message.serial_no_data;
|
||||
this.batch_no_data = r.message.batch_no_data;
|
||||
this.tax_data = r.message.tax_data;
|
||||
this.price_list_data = r.message.price_list_data;
|
||||
this.bin_data = r.message.bin_data;
|
||||
this.pricing_rules = r.message.pricing_rules;
|
||||
this.print_template = r.message.print_template;
|
||||
this.pos_profile_data = r.message.pos_profile;
|
||||
this.default_customer = r.message.default_customer || null;
|
||||
},
|
||||
|
||||
save_previous_entry : function(){
|
||||
if(this.frm.doc.items.length > 0){
|
||||
this.create_invoice()
|
||||
@@ -233,20 +243,19 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
},
|
||||
|
||||
load_data: function(load_doc){
|
||||
this.items = window.items;
|
||||
this.customers = window.customers;
|
||||
this.pricing_rules = window.pricing_rules;
|
||||
var me = this;
|
||||
|
||||
this.items = this.item_data;
|
||||
if(load_doc) {
|
||||
this.frm.doc = JSON.parse(localStorage.getItem('doc'));
|
||||
}
|
||||
|
||||
$.each(window.meta, function(i, data){
|
||||
$.each(this.meta, function(i, data){
|
||||
frappe.meta.sync(data)
|
||||
})
|
||||
|
||||
this.print_template = frappe.render_template("print_template",
|
||||
{content: window.print_template, title:"POS",
|
||||
{content: this.print_template, title:"POS",
|
||||
base_url: frappe.urllib.get_base_url(), print_css: frappe.boot.print_css})
|
||||
},
|
||||
|
||||
@@ -387,12 +396,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
var $wrap = me.wrapper.find(".item-list");
|
||||
me.wrapper.find(".item-list").empty();
|
||||
|
||||
if (this.items) {
|
||||
if (this.items.length > 0) {
|
||||
$.each(this.items, function(index, obj) {
|
||||
if(index < 30){
|
||||
$(frappe.render_template("pos_item", {
|
||||
item_code: obj.name,
|
||||
item_price: format_currency(obj.price_list_rate, me.frm.doc.currency),
|
||||
item_price: format_currency(me.price_list_data[obj.name], me.frm.doc.currency),
|
||||
item_name: obj.name===obj.item_name ? "" : obj.item_name,
|
||||
item_image: obj.image ? "url('" + obj.image + "')" : null,
|
||||
color: frappe.get_palette(obj.item_name),
|
||||
@@ -400,6 +409,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
})).tooltip().appendTo($wrap);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("<h4>Searching record not found.</h4>").appendTo($wrap)
|
||||
}
|
||||
|
||||
if(this.items.length == 1
|
||||
@@ -426,7 +437,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
this.item_batch_no = {};
|
||||
|
||||
if(item_code){
|
||||
return $.grep(window.items, function(item){
|
||||
return $.grep(this.item_data, function(item){
|
||||
if(item.item_code == item_code ){
|
||||
return true
|
||||
}
|
||||
@@ -439,14 +450,15 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
search_status = true
|
||||
|
||||
if(key){
|
||||
return $.grep(window.items, function(item){
|
||||
return $.grep(this.item_data, function(item){
|
||||
if(search_status){
|
||||
if(in_list(item.batch_nos, me.search.$input.val())){
|
||||
if(in_list(me.batch_no_data[item.item_code], me.search.$input.val())){
|
||||
search_status = false;
|
||||
return me.item_batch_no[item.item_code] = me.search.$input.val()
|
||||
} else if(in_list(Object.keys(item.serial_nos), me.search.$input.val())) {
|
||||
} else if( me.serial_no_data[item.item_code]
|
||||
&& in_list(Object.keys(me.serial_no_data[item.item_code]), me.search.$input.val())) {
|
||||
search_status = false;
|
||||
me.item_serial_no[item.item_code] = [me.search.$input.val(), item.serial_nos[me.search.$input.val()]]
|
||||
me.item_serial_no[item.item_code] = [me.search.$input.val(), me.serial_no_data[item.item_code][me.search.$input.val()]]
|
||||
return true
|
||||
} else if(item.barcode == me.search.$input.val()) {
|
||||
search_status = false;
|
||||
@@ -458,7 +470,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
}
|
||||
})
|
||||
}else{
|
||||
return window.items;
|
||||
return this.item_data;
|
||||
}
|
||||
},
|
||||
|
||||
@@ -611,18 +623,18 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
this.child.description = this.items[0].description;
|
||||
this.child.qty = 1;
|
||||
this.child.item_group = this.items[0].item_group;
|
||||
this.child.cost_center = this.items[0].cost_center;
|
||||
this.child.income_account = this.items[0].income_account;
|
||||
this.child.cost_center = this.pos_profile_data['cost_center'] || this.items[0].cost_center;
|
||||
this.child.income_account = this.pos_profile_data['income_account'] || this.items[0].income_account;
|
||||
this.child.warehouse = (this.item_serial_no[this.child.item_code]
|
||||
? this.item_serial_no[this.child.item_code][1] : this.items[0].default_warehouse);
|
||||
this.child.price_list_rate = flt(this.items[0].price_list_rate, 9) / flt(this.frm.doc.conversion_rate, 9);
|
||||
this.child.rate = flt(this.items[0].price_list_rate, 9) / flt(this.frm.doc.conversion_rate, 9);
|
||||
this.child.actual_qty = this.items[0].actual_qty;
|
||||
? this.item_serial_no[this.child.item_code][1] : (this.pos_profile_data['warehouse'] || this.items[0].default_warehouse) );
|
||||
this.child.price_list_rate = flt(this.price_list_data[this.child.item_code], 9) / flt(this.frm.doc.conversion_rate, 9);
|
||||
this.child.rate = flt(this.price_list_data[this.child.item_code], 9) / flt(this.frm.doc.conversion_rate, 9);
|
||||
this.child.actual_qty = me.get_actual_qty(this.items[0]);
|
||||
this.child.amount = flt(this.child.qty) * flt(this.child.rate);
|
||||
this.child.batch_no = this.item_batch_no[this.child.item_code];
|
||||
this.child.serial_no = (this.item_serial_no[this.child.item_code]
|
||||
? this.item_serial_no[this.child.item_code][0] : '');
|
||||
this.child.item_tax_rate = this.items[0].taxes;
|
||||
this.child.item_tax_rate = JSON.stringify(this.tax_data[this.child.item_code]);
|
||||
},
|
||||
|
||||
update_paid_amount_status: function(update_paid_amount){
|
||||
@@ -668,7 +680,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
item_code: d.item_code,
|
||||
item_name: (d.item_name===d.item_code || !d.item_name) ? "" : ("<br>" + d.item_name),
|
||||
qty: d.qty,
|
||||
actual_qty: d.actual_qty,
|
||||
actual_qty: me.actual_qty,
|
||||
projected_qty: d.projected_qty,
|
||||
rate: format_number(d.rate, me.frm.doc.currency),
|
||||
amount: format_currency(d.amount, me.frm.doc.currency)
|
||||
@@ -1064,8 +1076,18 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
},
|
||||
|
||||
validate_warehouse: function(){
|
||||
if(!this.items[0].default_warehouse){
|
||||
if(this.items[0].is_stock_item && !this.items[0].default_warehouse && !this.pos_profile_data['warehouse']){
|
||||
frappe.throw(__("Default warehouse is required for selected item"))
|
||||
}
|
||||
},
|
||||
|
||||
get_actual_qty: function(item) {
|
||||
this.actual_qty = 0.0;
|
||||
var warehouse = this.pos_profile_data['warehouse'] || item.default_warehouse;
|
||||
if(warehouse && this.bin_data[item.item_code]) {
|
||||
this.actual_qty = this.bin_data[item.item_code][warehouse] || 0;
|
||||
}
|
||||
|
||||
return this.actual_qty
|
||||
}
|
||||
})
|
||||
@@ -4,7 +4,7 @@
|
||||
<h2 class="text-center">{%= __(report.report_name) %}</h2>
|
||||
<h4 class="text-center">{%= filters.customer || filters.supplier %} </h4>
|
||||
<h5 class="text-center">
|
||||
{%= filters.ageing_based_on %}
|
||||
{%= __(filters.ageing_based_on) %}
|
||||
{%= __("Until") %}
|
||||
{%= dateutil.str_to_user(filters.report_date) %}
|
||||
</h5>
|
||||
@@ -12,7 +12,7 @@
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
{% if(__(report.report_name) == "Accounts Receivable" || __(report.report_name) == "Accounts Payable") { %}
|
||||
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
||||
<th style="width: 15%">{%= __("Date") %}</th>
|
||||
<th style="width: 15%">{%= __("Ref") %}</th>
|
||||
<th style="width: 40%">{%= __("Party") %}</th>
|
||||
@@ -30,7 +30,7 @@
|
||||
<tbody>
|
||||
{% for(var i=0, l=data.length; i<l; i++) { %}
|
||||
<tr>
|
||||
{% if(__(report.report_name) == "Accounts Receivable" || __(report.report_name) == "Accounts Payable") { %}
|
||||
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
||||
{% if(data[i][__("Customer")] || data[i][__("Supplier")]) { %}
|
||||
<td>{%= dateutil.str_to_user(data[i][__("Posting Date")]) %}</td>
|
||||
<td>{%= data[i][__("Voucher Type")] %}
|
||||
@@ -38,21 +38,21 @@
|
||||
<td>{%= data[i][__("Customer Name")] || data[i][__("Customer")] || data[i][__("Supplier Name")] || data[i][__("Supplier")] %}
|
||||
<br>{%= __("Remarks") %}: {%= data[i][__("Remarks")] %}</td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i][__("Invoiced Amount")], data[i]["currency"]) %}</td>
|
||||
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i][__("Paid Amount")], data[i]["currency"]) %}</td>
|
||||
{%= format_currency(data[i]["Paid Amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i][__("Outstanding Amount")], data[i]["currency"]) %}</td>
|
||||
{%= format_currency(data[i]["Outstanding Amount"], data[i]["currency"]) %}</td>
|
||||
{% } else { %}
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td><b>{%= __("Total") %}</b></td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i][__("Invoiced Amount")]) %}</td>
|
||||
{%= format_currency(data[i]["Invoiced Amount"]) %}</td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i][__("Paid Amount")]) %}</td>
|
||||
{%= format_currency(data[i]["Paid Amount"]) %}</td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i][__("Outstanding Amount")]) %}</td>
|
||||
{%= format_currency(data[i]["Outstanding Amount"]) %}</td>
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
{% if(data[i][__("Customer")] || data[i][__("Supplier")]|| " ") { %}
|
||||
@@ -71,4 +71,4 @@
|
||||
{% } %}
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="text-right text-muted">Printed On {%= dateutil.str_to_user(dateutil.get_datetime_as_string()) %}</p>
|
||||
<p class="text-right text-muted">{{ __("Printed On") }}{%= dateutil.str_to_user(dateutil.get_datetime_as_string()) %}</p>
|
||||
@@ -88,6 +88,9 @@ class ReceivablePayableReport(object):
|
||||
|
||||
future_vouchers = self.get_entries_after(self.filters.report_date, args.get("party_type"))
|
||||
|
||||
if not self.filters.get("company"):
|
||||
self.filters["company"] = frappe.db.get_single_value('Global Defaults', 'default_company')
|
||||
|
||||
company_currency = frappe.db.get_value("Company", self.filters.get("company"), "default_currency")
|
||||
|
||||
data = []
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
from frappe.utils import flt, cint
|
||||
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
|
||||
|
||||
def execute(filters=None):
|
||||
@@ -14,10 +14,10 @@ def execute(filters=None):
|
||||
liability = get_data(filters.company, "Liability", "Credit", period_list, only_current_fiscal_year=False)
|
||||
equity = get_data(filters.company, "Equity", "Credit", period_list, only_current_fiscal_year=False)
|
||||
|
||||
provisional_profit_loss,total_credit = get_provisional_profit_loss(asset, liability, equity,
|
||||
provisional_profit_loss, total_credit = get_provisional_profit_loss(asset, liability, equity,
|
||||
period_list, filters.company)
|
||||
|
||||
message,opening_balance = check_opening_balance(asset, liability, equity)
|
||||
message, opening_balance = check_opening_balance(asset, liability, equity)
|
||||
|
||||
data = []
|
||||
data.extend(asset or [])
|
||||
@@ -32,7 +32,9 @@ def execute(filters=None):
|
||||
}
|
||||
for period in period_list:
|
||||
unclosed[period.key] = opening_balance
|
||||
provisional_profit_loss[period.key] = provisional_profit_loss[period.key] - opening_balance
|
||||
if provisional_profit_loss:
|
||||
provisional_profit_loss[period.key] = provisional_profit_loss[period.key] - opening_balance
|
||||
|
||||
unclosed["total"]=opening_balance
|
||||
data.append(unclosed)
|
||||
|
||||
@@ -48,15 +50,11 @@ def execute(filters=None):
|
||||
return columns, data, message, chart
|
||||
|
||||
def get_provisional_profit_loss(asset, liability, equity, period_list, company):
|
||||
provisional_profit_loss = {}
|
||||
total_row = {}
|
||||
if asset and (liability or equity):
|
||||
total = total_row_total=0
|
||||
currency = frappe.db.get_value("Company", company, "default_currency")
|
||||
provisional_profit_loss = {
|
||||
"account_name": "'" + _("Provisional Profit / Loss (Credit)") + "'",
|
||||
"account": None,
|
||||
"warn_if_negative": True,
|
||||
"currency": currency
|
||||
}
|
||||
total_row = {
|
||||
"account_name": "'" + _("Total (Credit)") + "'",
|
||||
"account": None,
|
||||
@@ -85,19 +83,25 @@ def get_provisional_profit_loss(asset, liability, equity, period_list, company):
|
||||
total_row["total"] = total_row_total
|
||||
|
||||
if has_value:
|
||||
return provisional_profit_loss, total_row
|
||||
return None,total_row
|
||||
return None, None
|
||||
provisional_profit_loss.update({
|
||||
"account_name": "'" + _("Provisional Profit / Loss (Credit)") + "'",
|
||||
"account": None,
|
||||
"warn_if_negative": True,
|
||||
"currency": currency
|
||||
})
|
||||
|
||||
return provisional_profit_loss, total_row
|
||||
|
||||
def check_opening_balance(asset, liability, equity):
|
||||
# Check if previous year balance sheet closed
|
||||
opening_balance = 0
|
||||
float_precision = cint(frappe.db.get_default("float_precision")) or 2
|
||||
if asset:
|
||||
opening_balance = flt(asset[0].get("opening_balance", 0))
|
||||
opening_balance = flt(asset[0].get("opening_balance", 0), float_precision)
|
||||
if liability:
|
||||
opening_balance -= flt(liability[0].get("opening_balance", 0))
|
||||
opening_balance -= flt(liability[0].get("opening_balance", 0), float_precision)
|
||||
if equity:
|
||||
opening_balance -= flt(equity[0].get("opening_balance", 0))
|
||||
opening_balance -= flt(equity[0].get("opening_balance", 0), float_precision)
|
||||
|
||||
if opening_balance:
|
||||
return _("Previous Financial Year is not closed"),opening_balance
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 15%">{%= __("Posting Date") %}</th>
|
||||
<th style="width: 15%">{%= __("Journal Entry") %}</th>
|
||||
<th style="width: 15%">{%= __("Payment Entry") %}</th>
|
||||
<th style="width: 40%">{%= __("Reference") %}</th>
|
||||
<th style="width: 15%; text-align: right;">{%= __("Debit") %}</th>
|
||||
<th style="width: 15%; text-align: right;">{%= __("Credit") %}</th>
|
||||
@@ -19,10 +19,10 @@
|
||||
{% if (data[i]["posting_date"]) { %}
|
||||
<tr>
|
||||
<td>{%= dateutil.str_to_user(data[i]["posting_date"]) %}</td>
|
||||
<td>{%= data[i]["journal_entry"] %}</td>
|
||||
<td>{%= data[i]["payment_entry"] %}</td>
|
||||
<td>{%= __("Against") %}: {%= data[i]["against_account"] %}
|
||||
{% if (data[i]["reference"]) { %}
|
||||
<br>{%= __("Reference") %}: {%= data[i]["reference"] %}
|
||||
{% if (data[i]["reference_no"]) { %}
|
||||
<br>{%= __("Reference") %}: {%= data[i]["reference_no"] %}
|
||||
{% if (data[i]["ref_date"]) { %}
|
||||
<br>{%= __("Reference Date") %}: {%= dateutil.str_to_user(data[i]["ref_date"]) %}
|
||||
{% } %}
|
||||
@@ -38,7 +38,7 @@
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>{%= data[i]["journal_entry"] %}</td>
|
||||
<td>{%= data[i]["payment_entry"] %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["debit"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["credit"]) %}</td>
|
||||
</tr>
|
||||
|
||||
@@ -129,7 +129,7 @@ def get_entries(filters):
|
||||
reference_no, reference_date as ref_date,
|
||||
if(paid_to=%(account)s, received_amount, 0) as debit,
|
||||
if(paid_from=%(account)s, paid_amount, 0) as credit,
|
||||
posting_date, party as against_account, clearance_date,
|
||||
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date,
|
||||
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
|
||||
from `tabPayment Entry`
|
||||
where
|
||||
|
||||
1
erpnext/accounts/report/cash_flow/cash_flow.html
Normal file
1
erpnext/accounts/report/cash_flow/cash_flow.html
Normal file
@@ -0,0 +1 @@
|
||||
{% include "accounts/report/financial_statements.html" %}
|
||||
@@ -0,0 +1 @@
|
||||
{% include "accounts/report/financial_statements.html" %}
|
||||
@@ -50,6 +50,19 @@ frappe.query_reports["Trial Balance for Party"] = {
|
||||
"options": ["Customer", "Supplier"],
|
||||
"default": "Customer"
|
||||
},
|
||||
{
|
||||
"fieldname":"party",
|
||||
"label": __("Party"),
|
||||
"fieldtype": "Dynamic Link",
|
||||
"get_options": function() {
|
||||
var party_type = frappe.query_report_filters_by_name.party_type.get_value();
|
||||
var party = frappe.query_report_filters_by_name.party.get_value();
|
||||
if(party && !party_type) {
|
||||
frappe.throw(__("Please select Party Type first"));
|
||||
}
|
||||
return party_type;
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldname": "show_zero_values",
|
||||
"label": __("Show zero values"),
|
||||
|
||||
@@ -20,13 +20,23 @@ def execute(filters=None):
|
||||
|
||||
def get_data(filters, show_party_name):
|
||||
party_name_field = "customer_name" if filters.get("party_type")=="Customer" else "supplier_name"
|
||||
parties = frappe.get_all(filters.get("party_type"), fields = ["name", party_name_field], order_by="name")
|
||||
party_filters = {"name": filters.get("party")} if filters.get("party") else {}
|
||||
parties = frappe.get_all(filters.get("party_type"), fields = ["name", party_name_field],
|
||||
filters = party_filters, order_by="name")
|
||||
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
|
||||
opening_balances = get_opening_balances(filters)
|
||||
balances_within_period = get_balances_within_period(filters)
|
||||
|
||||
data = []
|
||||
total_debit, total_credit = 0, 0
|
||||
# total_debit, total_credit = 0, 0
|
||||
total_row = frappe._dict({
|
||||
"opening_debit": 0,
|
||||
"opening_credit": 0,
|
||||
"debit": 0,
|
||||
"credit": 0,
|
||||
"closing_debit": 0,
|
||||
"closing_credit": 0
|
||||
})
|
||||
for party in parties:
|
||||
row = { "party": party.name }
|
||||
if show_party_name:
|
||||
@@ -45,11 +55,7 @@ def get_data(filters, show_party_name):
|
||||
"debit": debit,
|
||||
"credit": credit
|
||||
})
|
||||
|
||||
# totals
|
||||
total_debit += debit
|
||||
total_credit += credit
|
||||
|
||||
|
||||
# closing
|
||||
closing_debit, closing_credit = toggle_debit_credit(opening_debit + debit, opening_credit + credit)
|
||||
row.update({
|
||||
@@ -57,6 +63,10 @@ def get_data(filters, show_party_name):
|
||||
"closing_credit": closing_credit
|
||||
})
|
||||
|
||||
# totals
|
||||
for col in total_row:
|
||||
total_row[col] += row.get(col)
|
||||
|
||||
row.update({
|
||||
"currency": company_currency
|
||||
})
|
||||
@@ -69,13 +79,12 @@ def get_data(filters, show_party_name):
|
||||
data.append(row)
|
||||
|
||||
# Add total row
|
||||
if total_debit or total_credit:
|
||||
data.append({
|
||||
"party": "'" + _("Totals") + "'",
|
||||
"debit": total_debit,
|
||||
"credit": total_credit,
|
||||
"currency": company_currency
|
||||
})
|
||||
|
||||
total_row.update({
|
||||
"party": "'" + _("Totals") + "'",
|
||||
"currency": company_currency
|
||||
})
|
||||
data.append(total_row)
|
||||
|
||||
return data
|
||||
|
||||
|
||||
@@ -231,6 +231,7 @@ class PurchaseOrder(BuyingController):
|
||||
"target_parent_dt": "Sales Order",
|
||||
"target_dt": "Sales Order Item",
|
||||
'target_field': 'ordered_qty',
|
||||
"join_field": "sales_order_item",
|
||||
"target_parent_field": ''
|
||||
})
|
||||
|
||||
|
||||
@@ -371,6 +371,12 @@ def get_data():
|
||||
"doctype": "GL Entry",
|
||||
"is_query_report": True,
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"name": "Profitability Analysis",
|
||||
"doctype": "GL Entry",
|
||||
"is_query_report": True,
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"name": "Payment Period Based On Invoice Date",
|
||||
|
||||
@@ -32,12 +32,13 @@ def get_filters_cond(doctype, filters, conditions):
|
||||
|
||||
# searches for active employees
|
||||
def employee_query(doctype, txt, searchfield, start, page_len, filters):
|
||||
conditions = []
|
||||
return frappe.db.sql("""select name, employee_name from `tabEmployee`
|
||||
where status = 'Active'
|
||||
and docstatus < 2
|
||||
and ({key} like %(txt)s
|
||||
or employee_name like %(txt)s)
|
||||
{mcond}
|
||||
{fcond} {mcond}
|
||||
order by
|
||||
if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999),
|
||||
if(locate(%(_txt)s, employee_name), locate(%(_txt)s, employee_name), 99999),
|
||||
@@ -45,6 +46,7 @@ def employee_query(doctype, txt, searchfield, start, page_len, filters):
|
||||
name, employee_name
|
||||
limit %(start)s, %(page_len)s""".format(**{
|
||||
'key': searchfield,
|
||||
'fcond': get_filters_cond(doctype, filters, conditions),
|
||||
'mcond': get_match_cond(doctype)
|
||||
}), {
|
||||
'txt': "%%%s%%" % txt,
|
||||
|
||||
@@ -207,6 +207,7 @@ def make_return_doc(doctype, source_name, target_doc=None):
|
||||
target_doc.rejected_qty = -1* source_doc.rejected_qty
|
||||
target_doc.qty = -1* source_doc.qty
|
||||
target_doc.purchase_order = source_doc.purchase_order
|
||||
target_doc.purchase_order_item = source_doc.purchase_order_item
|
||||
target_doc.rejected_warehouse = source_doc.rejected_warehouse
|
||||
elif doctype == "Purchase Invoice":
|
||||
target_doc.received_qty = -1* source_doc.received_qty
|
||||
|
||||
@@ -164,14 +164,18 @@ class SellingController(StockController):
|
||||
frappe.throw(_("Maxiumm discount for Item {0} is {1}%").format(d.item_code, discount))
|
||||
|
||||
def validate_selling_price(self):
|
||||
def throw_message(item_name, rate, ref_rate_field):
|
||||
frappe.throw(_("""Selling price for item {0} is lower than its {1}. Selling price should be atleast {2}""")
|
||||
.format(item_name, ref_rate_field, rate))
|
||||
|
||||
if not frappe.db.get_single_value("Selling Settings", "validate_selling_price"):
|
||||
return
|
||||
|
||||
for it in self.get("items"):
|
||||
last_purchase_rate, is_stock_item = frappe.db.get_value("Item", it.name, ["last_purchase_rate", "is_stock_item"])
|
||||
last_purchase_rate, is_stock_item = frappe.db.get_value("Item", it.item_code, ["last_purchase_rate", "is_stock_item"])
|
||||
|
||||
if flt(it.base_rate) < flt(last_purchase_rate):
|
||||
throw(it.name, last_purchase_rate, "last purchase rate")
|
||||
throw_message(it.item_name, last_purchase_rate, "last purchase rate")
|
||||
|
||||
last_valuation_rate = frappe.db.sql("""
|
||||
SELECT valuation_rate FROM `tabStock Ledger Entry` WHERE item_code = %s
|
||||
@@ -182,9 +186,6 @@ class SellingController(StockController):
|
||||
if is_stock_item and flt(it.base_rate) < flt(last_valuation_rate):
|
||||
throw_message(it.name, last_valuation_rate, "valuation rate")
|
||||
|
||||
def throw_message(item_name, rate, ref_rate_field):
|
||||
frappe.throw(_("""Selling price for item {0} is lower than its {1}. Selling price should be atleast {2}""")
|
||||
.format(item_name, ref_rate_field, rate))
|
||||
|
||||
def get_item_list(self):
|
||||
il = []
|
||||
|
||||
@@ -271,19 +271,19 @@ class StatusUpdater(Document):
|
||||
%(update_modified)s
|
||||
where name='%(name)s'""" % args)
|
||||
|
||||
# update field
|
||||
if args.get('status_field'):
|
||||
frappe.db.sql("""update `tab%(target_parent_dt)s`
|
||||
set %(status_field)s = if(%(target_parent_field)s<0.001,
|
||||
'Not %(keyword)s', if(%(target_parent_field)s>=99.99,
|
||||
'Fully %(keyword)s', 'Partly %(keyword)s'))
|
||||
where name='%(name)s'""" % args)
|
||||
# update field
|
||||
if args.get('status_field'):
|
||||
frappe.db.sql("""update `tab%(target_parent_dt)s`
|
||||
set %(status_field)s = if(%(target_parent_field)s<0.001,
|
||||
'Not %(keyword)s', if(%(target_parent_field)s>=99.99,
|
||||
'Fully %(keyword)s', 'Partly %(keyword)s'))
|
||||
where name='%(name)s'""" % args)
|
||||
|
||||
if update_modified:
|
||||
target = frappe.get_doc(args["target_parent_dt"], args["name"])
|
||||
target.set_status(update=True)
|
||||
target.notify_update()
|
||||
notify_status(target)
|
||||
if update_modified:
|
||||
target = frappe.get_doc(args["target_parent_dt"], args["name"])
|
||||
target.set_status(update=True)
|
||||
target.notify_update()
|
||||
notify_status(target)
|
||||
|
||||
def _update_modified(self, args, update_modified):
|
||||
args['update_modified'] = ''
|
||||
|
||||
@@ -23,20 +23,19 @@ frappe.ui.form.on("Opportunity", {
|
||||
refresh: function(frm) {
|
||||
var doc = frm.doc;
|
||||
frm.events.enquiry_from(frm);
|
||||
|
||||
if(doc.status!=="Lost") {
|
||||
if(doc.with_items){
|
||||
frm.add_custom_button(__('Supplier Quotation'),
|
||||
function() {
|
||||
frm.trigger("make_supplier_quotation")
|
||||
}, __("Make"));
|
||||
|
||||
frm.add_custom_button(__('Quotation'),
|
||||
cur_frm.cscript.create_quotation, __("Make"));
|
||||
|
||||
frm.page.set_inner_btn_group_as_primary(__("Make"));
|
||||
}
|
||||
|
||||
frm.add_custom_button(__('Quotation'),
|
||||
cur_frm.cscript.create_quotation, __("Make"));
|
||||
|
||||
frm.page.set_inner_btn_group_as_primary(__("Make"));
|
||||
|
||||
if(doc.status!=="Quotation") {
|
||||
frm.add_custom_button(__('Lost'),
|
||||
cur_frm.cscript['Declare Opportunity Lost']);
|
||||
@@ -61,9 +60,10 @@ erpnext.crm.Opportunity = frappe.ui.form.Controller.extend({
|
||||
this.frm.doc.enquiry_from = "Lead";
|
||||
|
||||
if(!this.frm.doc.status)
|
||||
set_multiple(cdt, cdn, { status:'Draft' });
|
||||
set_multiple(this.frm.doc.doctype, this.frm.doc.name, { status:'Open' });
|
||||
if(!this.frm.doc.company && frappe.defaults.get_user_default("Company"))
|
||||
set_multiple(cdt, cdn, { company:frappe.defaults.get_user_default("Company") });
|
||||
set_multiple(this.frm.doc.doctype, this.frm.doc.name,
|
||||
{ company:frappe.defaults.get_user_default("Company") });
|
||||
|
||||
this.setup_queries();
|
||||
},
|
||||
|
||||
@@ -39,6 +39,9 @@ class Opportunity(TransactionBase):
|
||||
|
||||
if not self.title:
|
||||
self.title = self.customer_name
|
||||
|
||||
if not self.with_items:
|
||||
self.items = []
|
||||
|
||||
|
||||
def make_new_lead_if_required(self):
|
||||
|
||||
BIN
erpnext/docs/assets/img/buying/add_taxes_to_doc.png
Normal file
BIN
erpnext/docs/assets/img/buying/add_taxes_to_doc.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 154 KiB |
BIN
erpnext/docs/assets/img/buying/buying_flow.png
Normal file
BIN
erpnext/docs/assets/img/buying/buying_flow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
BIN
erpnext/docs/assets/img/buying/show_tax_breakup.png
Normal file
BIN
erpnext/docs/assets/img/buying/show_tax_breakup.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 118 KiB |
@@ -7,7 +7,7 @@ Supplier Quotation.
|
||||
|
||||
#### Purchase Order Flow Chart
|
||||
|
||||

|
||||

|
||||
|
||||
In ERPNext, you can also make a Purchase Order directly by going to:
|
||||
|
||||
@@ -39,6 +39,12 @@ which you collect from your Customer. In many regions, what you pay to your
|
||||
government is only the difference between what you collect from your Customer
|
||||
and what you pay to your Supplier. This is called Value Added Tax (VAT).
|
||||
|
||||
#### Add Taxes in Purchase Order
|
||||
<img class="screenshot" alt="Purchase Order" src="{{docs_base_url}}/assets/img/buying/add_taxes_to_doc.png">
|
||||
|
||||
#### Show Tax break-up
|
||||
<img class="screenshot" alt="Purchase Order" src="{{docs_base_url}}/assets/img/buying/show_tax_breakup.png">
|
||||
|
||||
For example you buy Items worth X and sell them for 1.3X. So your Customer
|
||||
pays 1.3 times the tax you pay your Supplier. Since you have already paid tax
|
||||
to your Supplier for X, what you owe your government is only the tax on 0.3X.
|
||||
@@ -49,7 +55,7 @@ Ideally you must create two Accounts for each type of VAT you pay and collect,
|
||||
effect. Please contact your accountant if you need more help or post a query
|
||||
on our forums!
|
||||
|
||||
|
||||
|
||||
|
||||
#### Purchase UOM and Stock UOM Conversion
|
||||
|
||||
@@ -82,5 +88,5 @@ __Step 5:__ Notice that the stock quantity will be updated accordingly.
|
||||
|
||||
__Step 6:__ Save and Submit the Form.
|
||||
|
||||
|
||||
|
||||
{next}
|
||||
|
||||
@@ -8,7 +8,7 @@ You can make a supplier quotation from a Material Request
|
||||
|
||||
#### Supplier Quotation Flow-Chart
|
||||
|
||||

|
||||

|
||||
|
||||
You can also make a Supplier Quotation directly from:
|
||||
|
||||
@@ -23,11 +23,22 @@ usually send out a message (Request for Quote) to various Suppliers. In
|
||||
many cases, especially if you have centralized buying, you may want to record
|
||||
all the quotes so that
|
||||
|
||||
* You can easily compare prices in the future
|
||||
* You can easily compare prices in the future
|
||||
* Audit whether all Suppliers were given the opportunity to quote.
|
||||
|
||||
Supplier Quotations are not necessary for most small businesses. Always
|
||||
evaluate the cost of collecting information to the value it really provides!
|
||||
You could only do this for high value items.
|
||||
|
||||
#### Taxes
|
||||
If your Supplier is going to charge you additional taxes or charge like a shipping or insurance charge, you can add it here. It will help you to accurately track your costs. Also, if some of these charges add to the value of the product you will have to mention them in the Taxes table. You can also use templates for your taxes. For more information on setting up your taxes see the Purchase Taxes and Charges Template.
|
||||
|
||||
You can select relevant tax by going to "Taxes and Charges" section and adding an entry to the table as shown below,
|
||||
|
||||
<img class="screenshot" alt="Supplier Quotation" src="{{docs_base_url}}/assets/img/buying/add_taxes_to_doc.png">
|
||||
|
||||
Besides, in case of multiple items you can keep track of taxes on each by clicking "Show tax break-up"
|
||||
|
||||
<img class="screenshot" alt="Supplier Quotation" src="{{docs_base_url}}/assets/img/buying/show_tax_breakup.png">
|
||||
|
||||
{next}
|
||||
|
||||
@@ -212,3 +212,5 @@ bot_parsers = [
|
||||
]
|
||||
|
||||
get_site_info = 'erpnext.utilities.get_site_info'
|
||||
|
||||
payment_gateway_enabled = "erpnext.accounts.utils.create_payment_gateway_and_account"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 0,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:expense_type",
|
||||
"beta": 0,
|
||||
"creation": "2012-03-27 14:35:55",
|
||||
@@ -10,11 +10,13 @@
|
||||
"doctype": "DocType",
|
||||
"document_type": "Setup",
|
||||
"editable_grid": 0,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "expense_type",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
@@ -41,6 +43,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
@@ -68,6 +71,7 @@
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "accounts",
|
||||
"fieldtype": "Table",
|
||||
"hidden": 0,
|
||||
@@ -102,7 +106,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-07-18 12:36:10.096252",
|
||||
"modified": "2016-11-07 11:54:10.936716",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Expense Claim Type",
|
||||
@@ -118,6 +122,7 @@
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"is_custom": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
@@ -138,6 +143,7 @@
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"is_custom": 0,
|
||||
"permlevel": 0,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
|
||||
@@ -22,7 +22,7 @@ class ProcessPayroll(Document):
|
||||
|
||||
sal_struct = frappe.db.sql("""
|
||||
select name from `tabSalary Structure`
|
||||
where docstatus != 2 and company = %(company)s and
|
||||
where docstatus != 2 and is_active = 'Yes' and company = %(company)s and
|
||||
ifnull(salary_slip_based_on_timesheet,0) = %(salary_slip_based_on_timesheet)s""",
|
||||
{"company": self.company, "salary_slip_based_on_timesheet":self.salary_slip_based_on_timesheet})
|
||||
|
||||
@@ -51,8 +51,8 @@ class ProcessPayroll(Document):
|
||||
|
||||
def get_joining_releiving_condition(self):
|
||||
cond = """
|
||||
and ifnull(t1.date_of_joining, '0000-00-00') <= '%(from_date)s'
|
||||
and ifnull(t1.relieving_date, '2199-12-31') >= '%(to_date)s'
|
||||
and ifnull(t1.date_of_joining, '0000-00-00') <= '%(to_date)s'
|
||||
and ifnull(t1.relieving_date, '2199-12-31') >= '%(from_date)s'
|
||||
""" % {"from_date": self.from_date, "to_date": self.to_date}
|
||||
return cond
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -58,8 +59,9 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "120px",
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0,
|
||||
@@ -86,6 +88,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -112,6 +115,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -137,6 +141,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -164,6 +169,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -182,7 +188,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-08-31 08:08:47.359578",
|
||||
"modified": "2016-11-16 12:44:37.733773",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Salary Component",
|
||||
@@ -199,6 +205,7 @@
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"is_custom": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
|
||||
@@ -10,7 +10,6 @@ from frappe import _
|
||||
class SalaryComponent(Document):
|
||||
def validate(self):
|
||||
self.validate_abbr()
|
||||
|
||||
|
||||
def validate_abbr(self):
|
||||
if not self.salary_component_abbr:
|
||||
@@ -21,8 +20,5 @@ class SalaryComponent(Document):
|
||||
if self.get('__islocal') and len(self.salary_component_abbr) > 5:
|
||||
frappe.throw(_("Abbreviation cannot have more than 5 characters"))
|
||||
|
||||
if not self.salary_component_abbr.strip():
|
||||
frappe.throw(_("Abbreviation is mandatory"))
|
||||
|
||||
if frappe.db.sql("select salary_component_abbr from `tabSalary Component` where name!=%s and salary_component_abbr=%s", (self.name, self.salary_component_abbr)):
|
||||
frappe.throw(_("Abbreviation already used for another salary component"))
|
||||
@@ -28,7 +28,15 @@ frappe.ui.form.on('Salary Structure', {
|
||||
type: "deduction"
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
frm.set_query("employee", "employees", function(doc) {
|
||||
return {
|
||||
query: "erpnext.controllers.queries.employee_query",
|
||||
filters: {
|
||||
company: doc.company
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
@@ -182,11 +190,3 @@ frappe.ui.form.on('Salary Detail', {
|
||||
calculate_totals(frm.doc);
|
||||
}
|
||||
})
|
||||
|
||||
frappe.ui.form.on('Salary Structure Employee', {
|
||||
onload: function(frm) {
|
||||
frm.set_query("employee","employees", function(doc,cdt,cdn) {
|
||||
return{ query: "erpnext.controllers.queries.employee_query" }
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
@@ -8,32 +8,32 @@ from frappe import msgprint, _
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
|
||||
|
||||
salary_slips = get_salary_slips(filters)
|
||||
columns, earning_types, ded_types = get_columns(salary_slips)
|
||||
ss_earning_map = get_ss_earning_map(salary_slips)
|
||||
ss_ded_map = get_ss_ded_map(salary_slips)
|
||||
|
||||
|
||||
|
||||
|
||||
data = []
|
||||
for ss in salary_slips:
|
||||
row = [ss.name, ss.employee, ss.employee_name, ss.branch, ss.department, ss.designation,
|
||||
ss.company, ss.month, ss.leave_withut_pay, ss.payment_days]
|
||||
|
||||
|
||||
for e in earning_types:
|
||||
row.append(ss_earning_map.get(ss.name, {}).get(e))
|
||||
|
||||
|
||||
row += [ss.arrear_amount, ss.leave_encashment_amount, ss.gross_pay]
|
||||
|
||||
|
||||
for d in ded_types:
|
||||
row.append(ss_ded_map.get(ss.name, {}).get(d))
|
||||
|
||||
|
||||
row += [ss.total_deduction, ss.net_pay]
|
||||
|
||||
|
||||
data.append(row)
|
||||
|
||||
|
||||
return columns, data
|
||||
|
||||
|
||||
def get_columns(salary_slips):
|
||||
columns = [
|
||||
_("Salary Slip ID") + ":Link/Salary Slip:150",_("Employee") + ":Link/Employee:120", _("Employee Name") + "::140", _("Branch") + ":Link/Branch:120",
|
||||
@@ -41,7 +41,7 @@ def get_columns(salary_slips):
|
||||
_("Company") + ":Link/Company:120", _("Month") + "::80", _("Leave Without Pay") + ":Float:130",
|
||||
_("Payment Days") + ":Float:120"
|
||||
]
|
||||
|
||||
|
||||
salary_components = {_("Earning"): [], _("Deduction"): []}
|
||||
|
||||
for component in frappe.db.sql("""select distinct sd.salary_component, sc.type
|
||||
@@ -61,47 +61,47 @@ def get_salary_slips(filters):
|
||||
conditions, filters = get_conditions(filters)
|
||||
salary_slips = frappe.db.sql("""select * from `tabSalary Slip` where docstatus = 1 %s
|
||||
order by employee, month""" % conditions, filters, as_dict=1)
|
||||
|
||||
|
||||
if not salary_slips:
|
||||
msgprint(_("No salary slip found for month: ") + cstr(filters.get("month")) +
|
||||
_(" and year: ") + cstr(filters.get("fiscal_year")), raise_exception=1)
|
||||
|
||||
frappe.throw(_("No salary slip found for month {0} and year {1}").format(
|
||||
filters.get("month"), filters.get("fiscal_year")))
|
||||
|
||||
return salary_slips
|
||||
|
||||
|
||||
def get_conditions(filters):
|
||||
conditions = ""
|
||||
if filters.get("month"):
|
||||
month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov",
|
||||
month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov",
|
||||
"Dec"].index(filters["month"]) + 1
|
||||
filters["month"] = month
|
||||
conditions += " and month = %(month)s"
|
||||
|
||||
|
||||
if filters.get("fiscal_year"): conditions += " and fiscal_year = %(fiscal_year)s"
|
||||
if filters.get("company"): conditions += " and company = %(company)s"
|
||||
if filters.get("employee"): conditions += " and employee = %(employee)s"
|
||||
|
||||
|
||||
return conditions, filters
|
||||
|
||||
|
||||
def get_ss_earning_map(salary_slips):
|
||||
ss_earnings = frappe.db.sql("""select parent, salary_component, amount
|
||||
ss_earnings = frappe.db.sql("""select parent, salary_component, amount
|
||||
from `tabSalary Detail` where parent in (%s)""" %
|
||||
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]), as_dict=1)
|
||||
|
||||
|
||||
ss_earning_map = {}
|
||||
for d in ss_earnings:
|
||||
ss_earning_map.setdefault(d.parent, frappe._dict()).setdefault(d.salary_component, [])
|
||||
ss_earning_map[d.parent][d.salary_component] = flt(d.amount)
|
||||
|
||||
|
||||
return ss_earning_map
|
||||
|
||||
def get_ss_ded_map(salary_slips):
|
||||
ss_deductions = frappe.db.sql("""select parent, salary_component, amount
|
||||
ss_deductions = frappe.db.sql("""select parent, salary_component, amount
|
||||
from `tabSalary Detail` where parent in (%s)""" %
|
||||
(', '.join(['%s']*len(salary_slips))), tuple([d.name for d in salary_slips]), as_dict=1)
|
||||
|
||||
|
||||
ss_ded_map = {}
|
||||
for d in ss_deductions:
|
||||
ss_ded_map.setdefault(d.parent, frappe._dict()).setdefault(d.salary_component, [])
|
||||
ss_ded_map[d.parent][d.salary_component] = flt(d.amount)
|
||||
|
||||
|
||||
return ss_ded_map
|
||||
@@ -816,7 +816,7 @@
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-08-17 05:35:34.331954",
|
||||
"modified": "2016-11-16 05:35:34.331954",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Planning Tool",
|
||||
|
||||
@@ -486,7 +486,9 @@ class ProductionPlanningTool(Document):
|
||||
"qty": requested_qty,
|
||||
"schedule_date": add_days(nowdate(), cint(item_wrapper.lead_time_days)),
|
||||
"warehouse": self.purchase_request_for_warehouse,
|
||||
"sales_order": sales_order if sales_order!="No Sales Order" else None
|
||||
"sales_order": sales_order if sales_order!="No Sales Order" else None,
|
||||
"project": frappe.db.get_value("Sales Order", sales_order, "project") \
|
||||
if sales_order!="No Sales Order" else None
|
||||
})
|
||||
|
||||
material_request.flags.ignore_permissions = 1
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
|
||||
|
||||
//--------- ONLOAD -------------
|
||||
cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
frappe.call({
|
||||
type:"GET",
|
||||
method:"erpnext.manufacturing.doctype.workstation.workstation.get_default_holiday_list",
|
||||
callback: function(r) {
|
||||
if(!r.exe && r.message){
|
||||
cur_frm.set_value("holiday_list", r.message);
|
||||
}
|
||||
frappe.ui.form.on("Workstation", {
|
||||
onload: function(frm) {
|
||||
if(frm.is_new())
|
||||
{
|
||||
frappe.call({
|
||||
type:"GET",
|
||||
method:"erpnext.manufacturing.doctype.workstation.workstation.get_default_holiday_list",
|
||||
callback: function(r) {
|
||||
if(!r.exe && r.message){
|
||||
cur_frm.set_value("holiday_list", r.message);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -346,4 +346,7 @@ execute:frappe.db.sql("update `tabStock Entry` set total_amount = null where pur
|
||||
erpnext.patches.v7_0.repost_gle_for_pi_with_update_stock #2016-11-01
|
||||
erpnext.patches.v7_1.add_account_user_role_for_timesheet
|
||||
erpnext.patches.v7_0.set_base_amount_in_invoice_payment_table
|
||||
erpnext.patches.v7_1.update_invoice_status
|
||||
erpnext.patches.v7_1.update_invoice_status
|
||||
erpnext.patches.v7_0.po_status_issue_for_pr_return
|
||||
erpnext.patches.v7_1.update_missing_salary_component_type
|
||||
erpnext.patches.v7_0.update_autoname_field
|
||||
@@ -6,6 +6,8 @@ from erpnext.patches.v7_0.migrate_schools_to_erpnext import reload_doctypes_for_
|
||||
|
||||
def execute():
|
||||
'''hide new style icons if old ones are set'''
|
||||
frappe.reload_doc('desk', 'doctype', 'desktop_icon')
|
||||
|
||||
reload_doctypes_for_schools_icons()
|
||||
|
||||
sync_desktop_icons()
|
||||
|
||||
36
erpnext/patches/v7_0/po_status_issue_for_pr_return.py
Normal file
36
erpnext/patches/v7_0/po_status_issue_for_pr_return.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
parent_list = []
|
||||
count = 0
|
||||
for data in frappe.db.sql("""
|
||||
select
|
||||
`tabPurchase Receipt Item`.purchase_order, `tabPurchase Receipt Item`.name,
|
||||
`tabPurchase Receipt Item`.item_code, `tabPurchase Receipt Item`.idx,
|
||||
`tabPurchase Receipt Item`.parent
|
||||
from
|
||||
`tabPurchase Receipt Item`, `tabPurchase Receipt`
|
||||
where
|
||||
`tabPurchase Receipt Item`.parent = `tabPurchase Receipt`.name and
|
||||
`tabPurchase Receipt Item`.purchase_order_item is null and
|
||||
`tabPurchase Receipt Item`.purchase_order is not null and
|
||||
`tabPurchase Receipt`.is_return = 1""", as_dict=1):
|
||||
name = frappe.db.get_value('Purchase Order Item',
|
||||
{'item_code': data.item_code, 'parent': data.purchase_order, 'idx': data.idx}, 'name')
|
||||
|
||||
if name:
|
||||
frappe.db.set_value('Purchase Receipt Item', data.name, 'purchase_order_item', name, update_modified=False)
|
||||
parent_list.append(data.parent)
|
||||
|
||||
count +=1
|
||||
if count % 200 == 0:
|
||||
frappe.db.commit()
|
||||
|
||||
if len(parent_list) > 0:
|
||||
for parent in set(parent_list):
|
||||
doc = frappe.get_doc('Purchase Receipt', parent)
|
||||
doc.update_qty(update_modified=False)
|
||||
@@ -9,6 +9,8 @@ def execute():
|
||||
if not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
return
|
||||
|
||||
frappe.reload_doctype("Purchase Invoice")
|
||||
|
||||
for pi in frappe.db.sql("""select name from `tabPurchase Invoice`
|
||||
where update_stock=1 and docstatus=1 order by posting_date asc""", as_dict=1):
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@ def execute():
|
||||
si_list = frappe.db.sql("""
|
||||
select distinct parent
|
||||
from `tabSales Invoice Payment`
|
||||
where docstatus!=2 and amount != 0 and base_amount = 0
|
||||
where docstatus!=2 and parenttype = 'Sales Invoice'
|
||||
and amount != 0 and base_amount = 0
|
||||
""")
|
||||
|
||||
count = 0
|
||||
@@ -20,4 +21,4 @@ def execute():
|
||||
count +=1
|
||||
|
||||
if count % 200 == 0:
|
||||
frappe.db.commit()
|
||||
frappe.db.commit()
|
||||
|
||||
14
erpnext/patches/v7_0/update_autoname_field.py
Normal file
14
erpnext/patches/v7_0/update_autoname_field.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
doctypes = frappe.db.sql(""" select name, autoname from `tabDocType`
|
||||
where autoname like 'field:%' and allow_rename = 1""", as_dict=1)
|
||||
|
||||
for doctype in doctypes:
|
||||
fieldname = doctype.autoname.split(":")[1]
|
||||
if fieldname:
|
||||
frappe.db.sql(""" update `tab%s` set %s = name """%(doctype.name, fieldname))
|
||||
@@ -14,6 +14,4 @@ def execute():
|
||||
employee.prefered_contact_email = "User ID"
|
||||
employee.prefered_email = employee.user_id
|
||||
|
||||
employee.flags.ignore_mandatory = True
|
||||
employee.flags.ignore_validate = True
|
||||
employee.save()
|
||||
employee.db_update()
|
||||
48
erpnext/patches/v7_1/update_missing_salary_component_type.py
Normal file
48
erpnext/patches/v7_1/update_missing_salary_component_type.py
Normal file
@@ -0,0 +1,48 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
from frappe.utils import cstr
|
||||
|
||||
'''
|
||||
Some components do not have type set, try and guess whether they turn up in
|
||||
earnings or deductions in existing salary slips
|
||||
'''
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc("accounts", "doctype", "salary_component_account")
|
||||
|
||||
for s in frappe.db.sql('''select name, type, salary_component_abbr from `tabSalary Component`
|
||||
where ifnull(type, "")="" or ifnull(salary_component_abbr, "") = ""''', as_dict=1):
|
||||
|
||||
component = frappe.get_doc('Salary Component', s.name)
|
||||
|
||||
# guess
|
||||
if not s.type:
|
||||
guess = frappe.db.sql('''select
|
||||
parentfield from `tabSalary Detail`
|
||||
where salary_component=%s limit 1''', s.name)
|
||||
|
||||
if guess:
|
||||
component.type = 'Earning' if guess[0][0]=='earnings' else 'Deduction'
|
||||
|
||||
else:
|
||||
component.type = 'Deduction'
|
||||
|
||||
if not s.salary_component_abbr:
|
||||
abbr = ''.join([c[0] for c in component.salary_component.split()]).upper()
|
||||
|
||||
abbr_count = frappe.db.sql("""
|
||||
select
|
||||
count(name)
|
||||
from
|
||||
`tabSalary Component`
|
||||
where
|
||||
salary_component_abbr = %s or salary_component_abbr like %s
|
||||
""", (abbr, abbr + "-%%"))
|
||||
|
||||
if abbr_count and abbr_count[0][0] > 0:
|
||||
abbr = abbr + "-" + cstr(abbr_count[0][0])
|
||||
|
||||
component.salary_component_abbr = abbr
|
||||
|
||||
component.save()
|
||||
@@ -2,6 +2,7 @@ import frappe
|
||||
|
||||
def execute():
|
||||
frappe.reload_doctype('Role')
|
||||
frappe.reload_doctype('User')
|
||||
for role_name in ('Customer', 'Supplier', 'Student'):
|
||||
if frappe.db.exists('Role', role_name):
|
||||
frappe.db.set_value('Role', role_name, 'desk_access', 0)
|
||||
|
||||
@@ -181,7 +181,6 @@
|
||||
}
|
||||
.cart-dropdown-container .cart-items-dropdown {
|
||||
max-height: 350px;
|
||||
overflow: auto;
|
||||
}
|
||||
.cart-dropdown-container .cart-items-dropdown .cart-dropdown {
|
||||
display: block;
|
||||
|
||||
@@ -65,7 +65,7 @@ $.extend(shopping_cart, {
|
||||
var cart_count = getCookie("cart_count");
|
||||
|
||||
if(cart_count) {
|
||||
$(".shopping-cart").toggleClass('hidden', true);
|
||||
$(".shopping-cart").toggleClass('hidden', false);
|
||||
}
|
||||
|
||||
var $cart = $('.cart-icon');
|
||||
|
||||
@@ -233,7 +233,6 @@
|
||||
|
||||
.cart-items-dropdown {
|
||||
max-height: 350px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.cart-items-dropdown .cart-dropdown {
|
||||
|
||||
@@ -10,7 +10,7 @@ def get_data():
|
||||
'items': ['Student Log', 'Student Group', 'Student Attendance']
|
||||
},
|
||||
{
|
||||
'items': ['Program Enrollment', 'Fees', 'Assessment', 'Guardian']
|
||||
'items': ['Program Enrollment', 'Fees', 'Assessment']
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -23,7 +23,7 @@ class StudentAdmission(WebsiteGenerator):
|
||||
context.parents = [{'name': 'admissions', 'title': _('All Student Admissions') }]
|
||||
|
||||
def get_title(self):
|
||||
return _("Admissions for {0}").format(self.academic_term)
|
||||
return _("Admissions for {0}").format(self.academic_year)
|
||||
|
||||
def get_list_context(context):
|
||||
context.title = _("Student Admissions")
|
||||
|
||||
@@ -920,7 +920,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2016-10-10 06:19:19.319038",
|
||||
"modified": "2016-11-17 10:26:13.225135",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Schools",
|
||||
"name": "Student Applicant",
|
||||
@@ -947,27 +947,6 @@
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 1,
|
||||
"import": 0,
|
||||
"is_custom": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Guest",
|
||||
"set_user_permissions": 0,
|
||||
"share": 0,
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
|
||||
@@ -372,7 +372,7 @@
|
||||
"in_list_view": 0,
|
||||
"label": "Customer's Purchase Order",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "po_no",
|
||||
"oldfieldtype": "Data",
|
||||
"permlevel": 0,
|
||||
@@ -403,7 +403,7 @@
|
||||
"in_list_view": 0,
|
||||
"label": "Customer's Purchase Order Date",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"no_copy": 0,
|
||||
"oldfieldname": "po_date",
|
||||
"oldfieldtype": "Date",
|
||||
"permlevel": 0,
|
||||
@@ -3226,7 +3226,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-11-05 08:09:08.921026",
|
||||
"modified": "2016-11-14 16:07:45.817880",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Sales Order",
|
||||
|
||||
@@ -66,27 +66,42 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
});
|
||||
}
|
||||
|
||||
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('batch_no')) {
|
||||
this.frm.set_query("batch_no", "items", function(doc, cdt, cdn) {
|
||||
var item = frappe.get_doc(cdt, cdn);
|
||||
if(!item.item_code) {
|
||||
frappe.throw(__("Please enter Item Code to get batch no"));
|
||||
} else {
|
||||
filters = {
|
||||
'item_code': item.item_code,
|
||||
'posting_date': me.frm.doc.posting_date || frappe.datetime.nowdate(),
|
||||
}
|
||||
if(item.warehouse) filters["warehouse"] = item.warehouse
|
||||
|
||||
return {
|
||||
query : "erpnext.controllers.queries.get_batch_no",
|
||||
filters: filters
|
||||
}
|
||||
}
|
||||
return me.set_query_for_batch(doc, cdt, cdn)
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
set_query_for_batch: function(doc, cdt, cdn) {
|
||||
// Show item's batches in the dropdown of batch no
|
||||
|
||||
var me = this;
|
||||
var item = frappe.get_doc(cdt, cdn);
|
||||
|
||||
if(!item.item_code) {
|
||||
frappe.throw(__("Please enter Item Code to get batch no"));
|
||||
} else {
|
||||
filters = {
|
||||
'item_code': item.item_code,
|
||||
'posting_date': me.frm.doc.posting_date || frappe.datetime.nowdate(),
|
||||
}
|
||||
if(item.warehouse) filters["warehouse"] = item.warehouse
|
||||
|
||||
return {
|
||||
query : "erpnext.controllers.queries.get_batch_no",
|
||||
filters: filters
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
this._super();
|
||||
this.frm.toggle_display("customer_name",
|
||||
|
||||
@@ -14,7 +14,8 @@ class NamingSeriesNotSetError(frappe.ValidationError): pass
|
||||
class NamingSeries(Document):
|
||||
def get_transactions(self, arg=None):
|
||||
doctypes = list(set(frappe.db.sql_list("""select parent
|
||||
from `tabDocField` where fieldname='naming_series'""")
|
||||
from `tabDocField` df where fieldname='naming_series' and
|
||||
exists(select * from `tabDocPerm` dp, `tabRole` role where dp.role = role.name and dp.parent = df.parent and not role.disabled)""")
|
||||
+ frappe.db.sql_list("""select dt from `tabCustom Field`
|
||||
where fieldname='naming_series'""")))
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ def setup_complete(args=None):
|
||||
frappe.message_log.pop()
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def create_fiscal_year_and_company(args):
|
||||
if (args.get('fy_start_date')):
|
||||
curr_fiscal_year = get_fy_details(args.get('fy_start_date'), args.get('fy_end_date'))
|
||||
@@ -244,12 +244,12 @@ def get_fy_details(fy_start_date, fy_end_date):
|
||||
else:
|
||||
fy = cstr(start_year) + '-' + cstr(start_year + 1)
|
||||
return fy
|
||||
|
||||
|
||||
def create_sales_tax(args):
|
||||
country_wise_tax = get_country_wise_tax(args.get("country"))
|
||||
if country_wise_tax and len(country_wise_tax) > 0:
|
||||
for sales_tax, tax_data in country_wise_tax.items():
|
||||
make_tax_account_and_template(args.get("company_name").strip(),
|
||||
make_tax_account_and_template(args.get("company_name").strip(),
|
||||
tax_data.get('account_name'), tax_data.get('tax_rate'), sales_tax)
|
||||
|
||||
def get_country_wise_tax(country):
|
||||
@@ -267,7 +267,7 @@ def create_taxes(args):
|
||||
account_name = args.get("tax_" + str(i))
|
||||
|
||||
make_tax_account_and_template(args.get("company_name").strip(), account_name, tax_rate)
|
||||
|
||||
|
||||
def make_tax_account_and_template(company, account_name, tax_rate, template_name=None):
|
||||
try:
|
||||
account = make_tax_account(company, account_name, tax_rate)
|
||||
@@ -280,14 +280,14 @@ def make_tax_account_and_template(company, account_name, tax_rate, template_name
|
||||
raise
|
||||
except RootNotEditable, e:
|
||||
pass
|
||||
|
||||
|
||||
def get_tax_account_group(company):
|
||||
tax_group = frappe.db.get_value("Account",
|
||||
tax_group = frappe.db.get_value("Account",
|
||||
{"account_name": "Duties and Taxes", "is_group": 1, "company": company})
|
||||
if not tax_group:
|
||||
tax_group = frappe.db.get_value("Account", {"is_group": 1, "root_type": "Liability",
|
||||
tax_group = frappe.db.get_value("Account", {"is_group": 1, "root_type": "Liability",
|
||||
"account_type": "Tax", "company": company})
|
||||
|
||||
|
||||
return tax_group
|
||||
|
||||
def make_tax_account(company, account_name, tax_rate):
|
||||
@@ -308,7 +308,7 @@ def make_tax_account(company, account_name, tax_rate):
|
||||
def make_sales_and_purchase_tax_templates(account, template_name=None):
|
||||
if not template_name:
|
||||
template_name = account.name
|
||||
|
||||
|
||||
sales_tax_template = {
|
||||
"doctype": "Sales Taxes and Charges Template",
|
||||
"title": template_name,
|
||||
@@ -548,35 +548,50 @@ def create_academic_term():
|
||||
academic_term = frappe.new_doc("Academic Term")
|
||||
academic_term.academic_year = y
|
||||
academic_term.term_name = t
|
||||
academic_term.save()
|
||||
try:
|
||||
academic_term.save()
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
def create_academic_year():
|
||||
ac = ["2013-14", "2014-15", "2015-16", "2016-17", "2017-18"]
|
||||
for d in ac:
|
||||
academic_year = frappe.new_doc("Academic Year")
|
||||
academic_year.academic_year_name = d
|
||||
academic_year.save()
|
||||
try:
|
||||
academic_year.save()
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
def create_program(args):
|
||||
for i in xrange(1,6):
|
||||
if args.get("program_" + str(i)):
|
||||
program = frappe.new_doc("Program")
|
||||
program.program_name = args.get("program_" + str(i))
|
||||
program.save()
|
||||
try:
|
||||
program.save()
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
def create_course(args):
|
||||
for i in xrange(1,6):
|
||||
if args.get("course_" + str(i)):
|
||||
course = frappe.new_doc("Course")
|
||||
course.course_name = args.get("course_" + str(i))
|
||||
course.save()
|
||||
try:
|
||||
course.save()
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
def create_instructor(args):
|
||||
for i in xrange(1,6):
|
||||
if args.get("instructor_" + str(i)):
|
||||
instructor = frappe.new_doc("Instructor")
|
||||
instructor.instructor_name = args.get("instructor_" + str(i))
|
||||
instructor.save()
|
||||
try:
|
||||
instructor.save()
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
def create_room(args):
|
||||
for i in xrange(1,6):
|
||||
@@ -584,6 +599,9 @@ def create_room(args):
|
||||
room = frappe.new_doc("Room")
|
||||
room.room_name = args.get("room_" + str(i))
|
||||
room.seating_capacity = args.get("room_capacity_" + str(i))
|
||||
room.save()
|
||||
try:
|
||||
room.save()
|
||||
except frappe.DuplicateEntryError:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -60,6 +61,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "150px",
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 1,
|
||||
@@ -89,6 +91,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "150px",
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -114,6 +117,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -139,6 +143,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -165,6 +170,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -193,6 +199,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "300px",
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -219,6 +226,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -245,6 +253,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -272,6 +281,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -297,6 +307,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -325,6 +336,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -355,6 +367,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "100px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -380,6 +393,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -409,6 +423,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "50px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -439,6 +454,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "100px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -466,6 +482,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -495,6 +512,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -521,6 +539,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -549,6 +568,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -576,6 +596,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -603,6 +624,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -627,6 +649,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -656,6 +679,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "150px",
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -686,6 +710,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "100px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -711,6 +736,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -740,6 +766,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "150px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -770,6 +797,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "100px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -797,6 +825,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -822,6 +851,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -849,6 +879,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -876,6 +907,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -901,6 +933,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -928,6 +961,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -955,6 +989,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -980,6 +1015,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1009,6 +1045,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "100px",
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1039,6 +1076,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1066,6 +1104,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1094,6 +1133,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1122,6 +1162,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "150px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1151,6 +1192,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "150px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1181,6 +1223,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1210,6 +1253,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "150px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1238,6 +1282,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1262,6 +1307,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1288,6 +1334,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1316,6 +1363,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1337,12 +1385,13 @@
|
||||
"in_list_view": 0,
|
||||
"label": "Against Sales Order",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Sales Order",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1363,12 +1412,13 @@
|
||||
"in_list_view": 0,
|
||||
"label": "Against Sales Invoice",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Sales Invoice",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1397,6 +1447,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "150px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 1,
|
||||
@@ -1424,6 +1475,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1452,6 +1504,7 @@
|
||||
"print_hide_if_no_value": 0,
|
||||
"print_width": "150px",
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1480,6 +1533,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1507,6 +1561,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -1524,7 +1579,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-11-01 13:01:29.621272",
|
||||
"modified": "2016-11-23 12:33:37.728117",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Delivery Note Item",
|
||||
|
||||
@@ -141,7 +141,7 @@ class Item(WebsiteGenerator):
|
||||
|
||||
def make_route(self):
|
||||
if not self.route:
|
||||
return frappe.db.get_value('Item Group', self.item_group, 'route') + '/' + self.scrub(self.item_name)
|
||||
return cstr(frappe.db.get_value('Item Group', self.item_group, 'route')) + '/' + self.scrub(self.item_name)
|
||||
|
||||
def get_parents(self, context):
|
||||
item_group, route = frappe.db.get_value('Item Group', self.item_group, ['name', 'route'])
|
||||
|
||||
@@ -372,6 +372,7 @@ def raise_production_orders(material_request):
|
||||
mr= frappe.get_doc("Material Request", material_request)
|
||||
errors =[]
|
||||
production_orders = []
|
||||
default_wip_warehouse = frappe.db.get_single_value("Manufacturing Settings", "default_wip_warehouse")
|
||||
for d in mr.items:
|
||||
if (d.qty - d.ordered_qty) >0:
|
||||
if frappe.db.get_value("BOM", {"item": d.item_code, "is_default": 1}):
|
||||
@@ -379,6 +380,7 @@ def raise_production_orders(material_request):
|
||||
prod_order.production_item = d.item_code
|
||||
prod_order.qty = d.qty - d.ordered_qty
|
||||
prod_order.fg_warehouse = d.warehouse
|
||||
prod_order.wip_warehouse = default_wip_warehouse
|
||||
prod_order.description = d.description
|
||||
prod_order.stock_uom = d.uom
|
||||
prod_order.expected_delivery_date = d.schedule_date
|
||||
|
||||
@@ -16,7 +16,7 @@ class PackedItem(Document):
|
||||
def get_product_bundle_items(item_code):
|
||||
return frappe.db.sql("""select t1.item_code, t1.qty, t1.uom, t1.description
|
||||
from `tabProduct Bundle Item` t1, `tabProduct Bundle` t2
|
||||
where t2.new_item_code=%s and t1.parent = t2.name""", item_code, as_dict=1)
|
||||
where t2.new_item_code=%s and t1.parent = t2.name order by t1.idx""", item_code, as_dict=1)
|
||||
|
||||
def get_packing_item_details(item):
|
||||
return frappe.db.sql("""select item_name, description, stock_uom from `tabItem`
|
||||
|
||||
@@ -8,6 +8,7 @@ frappe.query_reports["Stock Balance"] = {
|
||||
"label": __("From Date"),
|
||||
"fieldtype": "Date",
|
||||
"width": "80",
|
||||
"reqd": 1,
|
||||
"default": sys_defaults.year_start_date,
|
||||
},
|
||||
{
|
||||
@@ -15,6 +16,7 @@ frappe.query_reports["Stock Balance"] = {
|
||||
"label": __("To Date"),
|
||||
"fieldtype": "Date",
|
||||
"width": "80",
|
||||
"reqd": 1,
|
||||
"default": frappe.datetime.get_today()
|
||||
},
|
||||
{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
{% block title %} {{ title }} {% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{% include "templates/includes/breadcrumbs.html" %}
|
||||
{% include "templates/includes/breadcrumbs.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% block page_content %}
|
||||
@@ -25,17 +25,17 @@
|
||||
{{ _("Item Code") }}: <span itemprop="productID">{{ variant and variant.name or name }}</span></p>
|
||||
<br>
|
||||
<div class="item-attribute-selectors">
|
||||
{% if has_variants %}
|
||||
{% for d in attributes %}
|
||||
{% if has_variants %}
|
||||
{% for d in attributes %}
|
||||
{% if attribute_values[d.attribute] -%}
|
||||
<div class="item-view-attribute {% if (attribute_values[d.attribute] | len)==1 -%} hidden {%- endif %}"
|
||||
style="margin-bottom: 10px;">
|
||||
<h6 class="text-muted">{{ _(d.attribute) }}</h6>
|
||||
<select class="form-control"
|
||||
style="max-width: 140px"
|
||||
data-attribute="{{ d.attribute }}">
|
||||
<div class="item-view-attribute {% if (attribute_values[d.attribute] | len)==1 -%} hidden {%- endif %}"
|
||||
style="margin-bottom: 10px;">
|
||||
<h6 class="text-muted">{{ _(d.attribute) }}</h6>
|
||||
<select class="form-control"
|
||||
style="max-width: 140px"
|
||||
data-attribute="{{ d.attribute }}">
|
||||
{% for value in attribute_values[d.attribute] %}
|
||||
<option value="{{ value }}"
|
||||
<option value="{{ value }}"
|
||||
{% if selected_attributes and selected_attributes[d.attribute]==value -%}
|
||||
selected
|
||||
{%- elif disabled_attributes and value in disabled_attributes.get(d.attribute, []) -%}
|
||||
@@ -43,12 +43,12 @@
|
||||
{%- endif %}>
|
||||
{{ _(value) }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{%- endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<br>
|
||||
<div style="min-height: 100px; margin: 10px 0;">
|
||||
@@ -56,18 +56,17 @@
|
||||
<h4 class="item-price" itemprop="price"></h4>
|
||||
<div class="item-stock" itemprop="availability"></div>
|
||||
</div>
|
||||
<div class="item-cart hide">
|
||||
<div id="item-add-to-cart">
|
||||
<button class="btn btn-primary btn-sm">
|
||||
{{ _("Add to Cart") }}</button>
|
||||
</div>
|
||||
<div id="item-update-cart"
|
||||
style="display: none;
|
||||
padding-left: 0px; padding-right: 0px;
|
||||
padding-top: 10px;">
|
||||
<a href="/cart">{{ _("Goto Cart") }}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-cart hide">
|
||||
<div id="item-add-to-cart">
|
||||
<button class="btn btn-primary btn-sm">
|
||||
{{ _("Add to Cart") }}</button>
|
||||
</div>
|
||||
<div id="item-update-cart" style="display: none;">
|
||||
<a href="/cart" class='btn btn-sm btn-default'>
|
||||
<i class='octicon octicon-check'></i>
|
||||
{{ _("View in Cart") }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -101,10 +100,10 @@
|
||||
<script>
|
||||
{% include "templates/includes/product_page.js" %}
|
||||
|
||||
{% if variant_info %}
|
||||
window.variant_info = {{ variant_info }};
|
||||
{% else %}
|
||||
window.variant_info = null;
|
||||
{% endif %}
|
||||
{% if variant_info %}
|
||||
window.variant_info = {{ variant_info }};
|
||||
{% else %}
|
||||
window.variant_info = null;
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="cart-dropdown-container">
|
||||
<div id="cart-error" class="alert alert-danger"
|
||||
style="display: none;"></div>
|
||||
style="display: none;"></div>
|
||||
<div class="row cart-items-dropdown cart-item-header text-muted">
|
||||
<div class="col-sm-6 col-xs-6 h6 text-uppercase">
|
||||
{{ _("Item") }}
|
||||
@@ -9,13 +9,13 @@
|
||||
{{ _("Price") }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% if doc.items %}
|
||||
<div class="cart-items-dropdown">
|
||||
{% include "templates/includes/cart/cart_items_dropdown.html" %}
|
||||
</div>
|
||||
<div class="checkout-btn">
|
||||
<a href="/cart" class="btn btn-block btn-primary">{{ _("Checkout") }}</a>
|
||||
<a href="/cart" class="btn btn-block btn-primary">{{ _("Checkout") }}</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<p>{{ _("Cart is Empty") }}</p>
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
</div>
|
||||
<div class="col-sm-4 col-xs-4 text-right col-amount">
|
||||
{{ d.get_formatted("amount") }}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
@@ -1,7 +1,12 @@
|
||||
{% macro product_image_square(website_image, css_class="") %}
|
||||
{% if website_image -%} <meta itemprop="image" content="{{ frappe.utils.quoted(website_image) | abs_url }}"></meta>{%- endif %}
|
||||
<div class="product-image product-image-square {% if not website_image -%} missing-image {%- endif %} {{ css_class }}"
|
||||
{% if website_image -%} style="background-image: url('{{ frappe.utils.quoted(website_image) | abs_url }}');" {%- endif %}>
|
||||
{% if website_image -%}
|
||||
<meta itemprop="image" content="{{ frappe.utils.quoted(website_image) | abs_url }}"></meta>
|
||||
{%- endif %}
|
||||
<div class="product-image product-image-square
|
||||
{% if not website_image -%} missing-image {%- endif %} {{ css_class }}"
|
||||
{% if website_image -%}
|
||||
style="background-image: url('{{ frappe.utils.quoted(website_image) | abs_url }}');"
|
||||
{%- endif %}>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
{% block navbar_right_extension %}
|
||||
<li class="shopping-cart hidden">
|
||||
<div class="cart-icon small">
|
||||
<div class="cart-icon">
|
||||
<a class="dropdown-toggle" href="#" data-toggle="dropdown" id="navLogin">
|
||||
Cart <span class="badge-wrapper" id="cart-count"></span>
|
||||
</a>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<div class="row item_name_and_description">
|
||||
<div class="col-xs-4 col-sm-2 order-image-col">
|
||||
<div class="order-image">
|
||||
{{ product_image_square(d.image) }}
|
||||
{{ product_image_square(d.thumbnail or d.image) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-8 col-sm-10">
|
||||
@@ -13,23 +13,24 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro item_name_and_description_cart(d) %}
|
||||
<div class="row item_name_dropdown">
|
||||
<div class="col-xs-4 col-sm-4 order-image-col">
|
||||
<div class="order-image">
|
||||
{{ product_image_square(d.image) }}
|
||||
{{ product_image_square(d.thumbnail or d.image) }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-8 col-sm-8">
|
||||
{{ d.item_code|truncate(25) }}
|
||||
{{ d.item_code|truncate(25) }}
|
||||
<div class="input-group number-spinner">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default cart-btn" data-dir="dwn">
|
||||
–</button>
|
||||
</span>
|
||||
<input class="form-control text-right cart-qty"
|
||||
value = "{{ d.get_formatted('qty') }}"
|
||||
data-item-code="{{ d.item_code }}">
|
||||
<input class="form-control text-right cart-qty"
|
||||
value = "{{ d.get_formatted('qty') }}"
|
||||
data-item-code="{{ d.item_code }}">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default cart-btn" data-dir="up">
|
||||
+</button>
|
||||
|
||||
@@ -10,15 +10,43 @@ from frappe.utils import cint, formatdate
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
def send_message(subject="Website Query", message="", sender="", status="Open"):
|
||||
from frappe.www.contact import send_message as website_send_message
|
||||
lead = customer = None
|
||||
|
||||
website_send_message(subject, message, sender)
|
||||
|
||||
customer = frappe.db.get_value('Contact', dict(email_id=sender), 'customer')
|
||||
if not customer:
|
||||
lead = frappe.db.get_value('Lead', dict(email_id=sender))
|
||||
if not lead:
|
||||
new_lead = frappe.get_doc(dict(
|
||||
doctype='Lead',
|
||||
email_id = sender,
|
||||
lead_name = sender.split('@')[0].title()
|
||||
)).insert(ignore_permissions=True)
|
||||
|
||||
opportunity = frappe.get_doc(dict(
|
||||
doctype='Opportunity',
|
||||
enquiry_from = 'Customer' if customer else 'Lead',
|
||||
status = 'Open',
|
||||
title = subject,
|
||||
to_discuss=message
|
||||
))
|
||||
|
||||
if customer:
|
||||
opportunity.customer = customer
|
||||
else:
|
||||
opportunity.lead = new_lead.name
|
||||
|
||||
opportunity.insert(ignore_permissions=True)
|
||||
|
||||
comm = frappe.get_doc({
|
||||
"doctype":"Communication",
|
||||
"subject": subject,
|
||||
"content": message,
|
||||
"sender": sender,
|
||||
"sent_or_received": "Received"
|
||||
"sent_or_received": "Received",
|
||||
'reference_doctype': 'Opportunity',
|
||||
'reference_name': opportunity.name
|
||||
})
|
||||
comm.insert(ignore_permissions=True)
|
||||
|
||||
|
||||
@@ -420,7 +420,7 @@ DocType: Employee,Single,Unique
|
||||
DocType: Account,Cost of Goods Sold,Coût des marchandises vendues
|
||||
DocType: Purchase Invoice,Yearly,Annuel
|
||||
apps/erpnext/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +226,Please enter Cost Center,S'il vous plaît entrer Centre de coûts
|
||||
DocType: Journal Entry Account,Sales Order,Bon de commande
|
||||
DocType: Journal Entry Account,Sales Order,Commande client
|
||||
apps/erpnext/erpnext/accounts/report/gross_profit/gross_profit.py +68,Avg. Selling Rate,Moy. Taux de vente
|
||||
DocType: Assessment,Examiner Name,Nom de l'examinateur
|
||||
apps/erpnext/erpnext/utilities/transaction_base.py +149,Quantity cannot be a fraction in row {0},La quantité ne peut pas être une fraction à la ligne {0}
|
||||
@@ -722,7 +722,7 @@ The tax rate you define here will be the standard tax rate for all **Items**. If
|
||||
|
||||
#### Description of Columns
|
||||
|
||||
1. Calculation Type:
|
||||
1. Calculation Type:
|
||||
- This can be on **Net Total** (that is the sum of basic amount).
|
||||
- **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.
|
||||
- **Actual** (as mentioned).
|
||||
@@ -733,19 +733,19 @@ The tax rate you define here will be the standard tax rate for all **Items**. If
|
||||
6. Amount: Tax amount.
|
||||
7. Total: Cumulative total to this point.
|
||||
8. Enter Row: If based on ""Previous Row Total"" you can select the row number which will be taken as a base for this calculation (default is the previous row).
|
||||
9. Is this Tax included in Basic Rate?: If you check this, it means that this tax will not be shown below the item table, but will be included in the Basic Rate in your main item table. This is useful where you want give a flat price (inclusive of all taxes) price to customers.","Modèle de la taxe standard qui peut être appliqué à toutes les opérations de vente. Ce modèle peut contenir la liste des chefs d'impôt ainsi que d'autres chefs dépenses / revenus comme le ""port"", ""assurance"", ""Manipulation"", etc.
|
||||
9. Is this Tax included in Basic Rate?: If you check this, it means that this tax will not be shown below the item table, but will be included in the Basic Rate in your main item table. This is useful where you want give a flat price (inclusive of all taxes) price to customers.","Modèle de la taxe standard qui peut être appliqué à toutes les opérations de vente. Ce modèle peut contenir la liste des chefs d'impôt ainsi que d'autres chefs dépenses / revenus comme le ""port"", ""assurance"", ""Manipulation"", etc.
|
||||
|
||||
#### Remarque
|
||||
#### Remarque
|
||||
|
||||
Le taux d'imposition vous définir ici sera le taux d'imposition standard pour tous les articles ** **. Se il ya ** ** Articles qui ont des taux différents, ils doivent être ajoutés dans le ** Impôt de l'article ** ** table dans le Point ** maître.
|
||||
|
||||
#### Description des colonnes
|
||||
#### Description des colonnes
|
||||
|
||||
1. Type de calcul:
|
||||
1. Type de calcul:
|
||||
- Cela peut être le ** Net Total ** (ce est la somme de montant de base).
|
||||
- ** Sur Rang Précédent Total / Montant ** (pour les taxes ou frais cumulatifs). Si vous sélectionnez cette option, la taxe sera appliquée en pourcentage de la rangée précédente (dans la table d'impôt) montant ou totale.
|
||||
- ** ** Réelles (comme mentionné).
|
||||
2. Compte chef: Le grand livre de compte en vertu de laquelle cette taxe sera réservé
|
||||
2. Compte chef: Le grand livre de compte en vertu de laquelle cette taxe sera réservé
|
||||
3. Centre de Coût: Si la taxe / redevance est un revenu (comme le transport) ou dépenses qu'elle doit être réservé contre un centre de coûts.
|
||||
4. Description: Description de la taxe (qui sera imprimée sur les factures / guillemets).
|
||||
5. Taux: Le taux d'imposition.
|
||||
@@ -941,7 +941,7 @@ apps/erpnext/erpnext/accounts/doctype/c_form/c_form.py +30,"Row {0}: Invoice {1}
|
||||
Please enter a valid Invoice","Row {0}: Invoice {1} est invalide, il pourrait être annulé / n'existe pas. \ S'il vous plaît entrer une facture valide"
|
||||
apps/erpnext/erpnext/accounts/doctype/journal_entry/journal_entry.py +105,Row {0}: Payment against Sales/Purchase Order should always be marked as advance,Row {0}: Paiement contre Ventes / bon de commande doit toujours être marqué comme avance
|
||||
apps/erpnext/erpnext/setup/setup_wizard/industry_type.py +16,Chemical,chimique
|
||||
apps/erpnext/erpnext/schools/doctype/grading_structure/grading_structure.py +24,"The intervals for Grade Code {0} overlaps with the grade intervals for other grades.
|
||||
apps/erpnext/erpnext/schools/doctype/grading_structure/grading_structure.py +24,"The intervals for Grade Code {0} overlaps with the grade intervals for other grades.
|
||||
Please check intervals {0} and {1} and try again",Les intervalles de code grade {0} chevauchements avec les intervalles de qualité pour les autres grades. S'il vous plaît vérifier les intervalles {0} et {1} et essayez à nouveau
|
||||
apps/erpnext/erpnext/stock/doctype/stock_entry/stock_entry.py +694,All items have already been transferred for this Production Order.,Tous les éléments ont déjà été transférés pour cet ordre de production.
|
||||
DocType: Process Payroll,Select Payroll Year and Month,Sélectionnez paie Année et mois
|
||||
@@ -2171,7 +2171,7 @@ The tax rate you define here will be the standard tax rate for all **Items**. If
|
||||
|
||||
#### Description of Columns
|
||||
|
||||
1. Calculation Type:
|
||||
1. Calculation Type:
|
||||
- This can be on **Net Total** (that is the sum of basic amount).
|
||||
- **On Previous Row Total / Amount** (for cumulative taxes or charges). If you select this option, the tax will be applied as a percentage of the previous row (in the tax table) amount or total.
|
||||
- **Actual** (as mentioned).
|
||||
@@ -2183,19 +2183,19 @@ The tax rate you define here will be the standard tax rate for all **Items**. If
|
||||
7. Total: Cumulative total to this point.
|
||||
8. Enter Row: If based on ""Previous Row Total"" you can select the row number which will be taken as a base for this calculation (default is the previous row).
|
||||
9. Consider Tax or Charge for: In this section you can specify if the tax / charge is only for valuation (not a part of total) or only for total (does not add value to the item) or for both.
|
||||
10. Add or Deduct: Whether you want to add or deduct the tax.","Modèle de la taxe standard qui peut être appliqué à toutes les opérations d'achat. Ce modèle peut contenir la liste des chefs d'impôt ainsi que d'autres chefs de dépenses comme ""Expédition"", ""assurance"", ""Manipulation"", etc.
|
||||
10. Add or Deduct: Whether you want to add or deduct the tax.","Modèle de la taxe standard qui peut être appliqué à toutes les opérations d'achat. Ce modèle peut contenir la liste des chefs d'impôt ainsi que d'autres chefs de dépenses comme ""Expédition"", ""assurance"", ""Manipulation"", etc.
|
||||
|
||||
#### Remarque
|
||||
#### Remarque
|
||||
|
||||
Le taux d'imposition que vous définissez ici sera le taux d'imposition standard pour tous les articles ** **. Se il ya ** ** Articles qui ont des taux différents, ils doivent être ajoutés dans le ** Impôt de l'article ** ** table dans le Point ** maître.
|
||||
|
||||
#### Description des colonnes
|
||||
#### Description des colonnes
|
||||
|
||||
1. Type de calcul:
|
||||
1. Type de calcul:
|
||||
- Cela peut être le ** Net Total ** (ce est la somme de montant de base).
|
||||
- ** Sur Rang Précédent Total / Montant ** (pour les taxes ou frais cumulatifs). Si vous sélectionnez cette option, la taxe sera appliquée en pourcentage de la rangée précédente (dans la table d'impôt) montant ou totale.
|
||||
- ** ** Réelles (comme mentionné).
|
||||
2. Compte chef: Le grand livre de compte en vertu de laquelle cette taxe sera réservé
|
||||
2. Compte chef: Le grand livre de compte en vertu de laquelle cette taxe sera réservé
|
||||
3. Centre de Coût: Si la taxe / redevance est un revenu (comme le transport) ou dépenses qu'elle doit être réservé contre un centre de coûts.
|
||||
4. Description: Description de la taxe (qui sera imprimée sur les factures / guillemets).
|
||||
5. Taux: Le taux d'imposition.
|
||||
@@ -2389,7 +2389,7 @@ Examples:
|
||||
1. Ways of addressing disputes, indemnity, liability, etc.
|
||||
1. Address and Contact of your Company.","Conditions d'utilisation standard qui peuvent être ajoutés aux ventes et achats.
|
||||
|
||||
Exemples:
|
||||
Exemples:
|
||||
|
||||
1. Validité de l'offre.
|
||||
1. Conditions de paiement (à l'avance, à crédit, une partie avance etc).
|
||||
@@ -2398,7 +2398,7 @@ Examples:
|
||||
1. Garantie cas échéant.
|
||||
1. Politique de retour.
|
||||
1. Conditions d'expédition, le cas échéant.
|
||||
1. Façons de différends adressage, indemnisation, la responsabilité, etc.
|
||||
1. Façons de différends adressage, indemnisation, la responsabilité, etc.
|
||||
1. Adresse et contact de votre société."
|
||||
DocType: Attendance,Leave Type,Type de Congé
|
||||
apps/erpnext/erpnext/controllers/stock_controller.py +173,Expense / Difference account ({0}) must be a 'Profit or Loss' account,Dépenses / compte de la différence ({0}) doit être un compte «de résultat»
|
||||
@@ -3384,7 +3384,7 @@ DocType: Accounts Settings,"If enabled, the system will post accounting entries
|
||||
apps/erpnext/erpnext/setup/setup_wizard/industry_type.py +15,Brokerage,courtage
|
||||
DocType: Address,Postal Code,Code Postal
|
||||
DocType: Production Order Operation,"in Minutes
|
||||
Updated via 'Time Log'","Mise à jour en quelques minutes
|
||||
Updated via 'Time Log'","Mise à jour en quelques minutes
|
||||
via 'Log Time'"
|
||||
DocType: Customer,From Lead,Du prospect
|
||||
apps/erpnext/erpnext/config/manufacturing.py +13,Orders released for production.,Commandes validé pour la production.
|
||||
@@ -3564,7 +3564,7 @@ apps/erpnext/erpnext/controllers/recurring_document.py +133,Please find attached
|
||||
apps/erpnext/erpnext/accounts/report/bank_reconciliation_statement/bank_reconciliation_statement.py +34,Bank Statement balance as per General Ledger,Solde du relevé bancaire que par General Ledger
|
||||
DocType: Job Applicant,Applicant Name,Nom du demandeur
|
||||
DocType: Authorization Rule,Customer / Item Name,Client / Nom d'article
|
||||
DocType: Product Bundle,"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**.
|
||||
DocType: Product Bundle,"Aggregate group of **Items** into another **Item**. This is useful if you are bundling a certain **Items** into a package and you maintain stock of the packed **Items** and not the aggregate **Item**.
|
||||
|
||||
The package **Item** will have ""Is Stock Item"" as ""No"" and ""Is Sales Item"" as ""Yes"".
|
||||
|
||||
@@ -3711,17 +3711,17 @@ DocType: Address Template,"<h4>Default Template</h4>
|
||||
{% if phone %}Phone: {{ phone }}<br>{% endif -%}
|
||||
{% if fax %}Fax: {{ fax }}<br>{% endif -%}
|
||||
{% if email_id %}Email: {{ email_id }}<br>{% endif -%}
|
||||
</code></pre>","<H4> Modèle par défaut </ h4>
|
||||
<p> <a Utilise href=""http://jinja.pocoo.org/docs/templates/""> Jinja Templating </a> et tous les champs d'adresse ( y compris les champs personnalisés le cas échéant) sera disponible </ p>
|
||||
<pre> <code> {{address_line1}} & lt; br & gt;
|
||||
{% si address_line2%} {{address_line2}} & lt; br & gt; { % endif -%}
|
||||
{{ville}} & lt; br & gt;
|
||||
{% si l'état%} {{}} Etat & lt; br & gt; {% endif -%} {% if
|
||||
code PIN%} PIN: {{code PIN}} & lt; br & gt; {% endif -%}
|
||||
{{pays}} & lt; br & gt;
|
||||
{% si le téléphone%} Téléphone: {{téléphone}} & lt; br & gt; { % endif -%}
|
||||
{% if télécopieur%} Fax: {{fax}} & lt; br & gt; {% endif -%}
|
||||
{% si email_id%} Email: {{email_id}} & lt; br & gt ; {% endif -%}
|
||||
</code></pre>","<H4> Modèle par défaut </ h4>
|
||||
<p> <a Utilise href=""http://jinja.pocoo.org/docs/templates/""> Jinja Templating </a> et tous les champs d'adresse ( y compris les champs personnalisés le cas échéant) sera disponible </ p>
|
||||
<pre> <code> {{address_line1}} & lt; br & gt;
|
||||
{% si address_line2%} {{address_line2}} & lt; br & gt; { % endif -%}
|
||||
{{ville}} & lt; br & gt;
|
||||
{% si l'état%} {{}} Etat & lt; br & gt; {% endif -%} {% if
|
||||
code PIN%} PIN: {{code PIN}} & lt; br & gt; {% endif -%}
|
||||
{{pays}} & lt; br & gt;
|
||||
{% si le téléphone%} Téléphone: {{téléphone}} & lt; br & gt; { % endif -%}
|
||||
{% if télécopieur%} Fax: {{fax}} & lt; br & gt; {% endif -%}
|
||||
{% si email_id%} Email: {{email_id}} & lt; br & gt ; {% endif -%}
|
||||
</ code> </ pre>"
|
||||
DocType: Salary Detail,Default Amount,Montant par défaut
|
||||
apps/erpnext/erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py +93,Warehouse not found in the system,Entrepôt pas trouvé dans le système
|
||||
@@ -3914,7 +3914,7 @@ DocType: Purchase Invoice Item,Rejected Serial No,N° de série rejetés
|
||||
apps/erpnext/erpnext/accounts/doctype/fiscal_year/fiscal_year.py +80,Year start date or end date is overlapping with {0}. To avoid please set company,Année de début ou de fin chevauche avec {0}. Pour éviter s'il vous plaît définir la société
|
||||
apps/erpnext/erpnext/maintenance/doctype/maintenance_schedule/maintenance_schedule.py +157,Start date should be less than end date for Item {0},La date de début doit être inférieure à la date de fin de l'article {0}
|
||||
DocType: Item,"Example: ABCD.#####
|
||||
If series is set and Serial No is not mentioned in transactions, then automatic serial number will be created based on this series. If you always want to explicitly mention Serial Nos for this item. leave this blank.","Exemple:. ABCD #####
|
||||
If series is set and Serial No is not mentioned in transactions, then automatic serial number will be created based on this series. If you always want to explicitly mention Serial Nos for this item. leave this blank.","Exemple:. ABCD #####
|
||||
Si la série est réglé et n ° de série ne est pas mentionné dans les transactions, le numéro de série, puis automatique sera créé sur la base de cette série. Si vous voulez toujours de mentionner explicitement numéros de série pour ce produit. laissez ce champ vide."
|
||||
DocType: Upload Attendance,Upload Attendance,Chargez fréquentation
|
||||
apps/erpnext/erpnext/stock/doctype/stock_entry/stock_entry.js +113,BOM and Manufacturing Quantity are required,BOM et fabrication Quantité sont nécessaires
|
||||
|
||||
|
@@ -103,4 +103,5 @@ def update_contact(doc, method):
|
||||
for key in ("first_name", "last_name", "phone"):
|
||||
if doc.get(key):
|
||||
contact.set(key, doc.get(key))
|
||||
contact.flags.ignore_mandatory = True
|
||||
contact.save(ignore_permissions=True)
|
||||
|
||||
@@ -125,6 +125,20 @@ class TransactionBase(StatusUpdater):
|
||||
ret = None
|
||||
|
||||
return ret
|
||||
|
||||
def delink_advance_entries(self, linked_doc_name):
|
||||
total_allocated_amount = 0
|
||||
for adv in self.advances:
|
||||
consider_for_total_advance = True
|
||||
if adv.reference_name == linked_doc_name:
|
||||
frappe.db.sql("""delete from `tab{0} Advance`
|
||||
where name = %s""".format(self.doctype), adv.name)
|
||||
consider_for_total_advance = False
|
||||
|
||||
if consider_for_total_advance:
|
||||
total_allocated_amount += flt(adv.allocated_amount, adv.precision("allocated_amount"))
|
||||
|
||||
frappe.db.set_value(self.doctype, self.name, "total_advance", total_allocated_amount, update_modified=False)
|
||||
|
||||
def delete_events(ref_type, ref_name):
|
||||
frappe.delete_doc("Event", frappe.db.sql_list("""select name from `tabEvent`
|
||||
|
||||
@@ -4,4 +4,4 @@ import frappe
|
||||
|
||||
def get_context(context):
|
||||
# do your magic here
|
||||
pass
|
||||
context.show_sidebar = True
|
||||
|
||||
Reference in New Issue
Block a user