Compare commits
95 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11fc4f85d0 | ||
|
|
17452a1695 | ||
|
|
7c3d48e353 | ||
|
|
5d288e407c | ||
|
|
f64fae752f | ||
|
|
82763f052f | ||
|
|
bafc73568a | ||
|
|
d015195617 | ||
|
|
b2f550ccb3 | ||
|
|
41413af42d | ||
|
|
ec60ebde6f | ||
|
|
ce81a61fe7 | ||
|
|
dc76b3fa20 | ||
|
|
828cbee12a | ||
|
|
5f5ef16b91 | ||
|
|
686ef8308a | ||
|
|
b63ad44b10 | ||
|
|
5ef121bc10 | ||
|
|
42c1836db5 | ||
|
|
9dbdef3bd5 | ||
|
|
9fd42ed2f7 | ||
|
|
000835c454 | ||
|
|
de1f934e22 | ||
|
|
7cbd916b00 | ||
|
|
56fcf30cb9 | ||
|
|
ebbdd772a9 | ||
|
|
6268d83173 | ||
|
|
4599467939 | ||
|
|
d3613479c6 | ||
|
|
6bf301f53c | ||
|
|
27d7f21553 | ||
|
|
8f87cff4bd | ||
|
|
8f39766924 | ||
|
|
39669f2717 | ||
|
|
3c1017c43b | ||
|
|
0b18a2d347 | ||
|
|
6262496e70 | ||
|
|
c9963f1805 | ||
|
|
8a2b1bcb97 | ||
|
|
b8ecf7c757 | ||
|
|
cf89fa2253 | ||
|
|
419c1eb90d | ||
|
|
2c214e0362 | ||
|
|
7d04dd0bfd | ||
|
|
f1371a7ee7 | ||
|
|
995a78421a | ||
|
|
352187bee6 | ||
|
|
c6d8121f4a | ||
|
|
030ade428b | ||
|
|
c87595b2da | ||
|
|
42f2674cba | ||
|
|
5359f2651a | ||
|
|
42dcffdad4 | ||
|
|
f7c1743b28 | ||
|
|
64aa6620be | ||
|
|
ed43f8015c | ||
|
|
d3fe7ec858 | ||
|
|
c8b406d050 | ||
|
|
2aa577f110 | ||
|
|
f06d175061 | ||
|
|
74b2116adb | ||
|
|
2204d0af94 | ||
|
|
b8a568765d | ||
|
|
cf29f6468d | ||
|
|
aded46d33e | ||
|
|
b8dd046c84 | ||
|
|
e5fa5e6111 | ||
|
|
b89cf1b3ec | ||
|
|
a33d468d30 | ||
|
|
e481a211b1 | ||
|
|
ca23b5ecfd | ||
|
|
11190268ab | ||
|
|
a19150ddaf | ||
|
|
c17dff4b01 | ||
|
|
47fe136d15 | ||
|
|
8f25402dce | ||
|
|
a9165744e2 | ||
|
|
3ebfad7115 | ||
|
|
c7ef8dda79 | ||
|
|
4a6c178795 | ||
|
|
8908543a9c | ||
|
|
065badc54b | ||
|
|
cd2798368b | ||
|
|
2c30acdcb2 | ||
|
|
4a4a6594d1 | ||
|
|
e3035a593c | ||
|
|
587dde0044 | ||
|
|
b6d13ef5b7 | ||
|
|
a3e9dbbcc3 | ||
|
|
80069a6379 | ||
|
|
98c515fe7d | ||
|
|
6ee8c545e3 | ||
|
|
3c67146e4b | ||
|
|
e2c200a91e | ||
|
|
d9d5925f14 |
@@ -1,2 +1,2 @@
|
||||
from __future__ import unicode_literals
|
||||
__version__ = '5.0.12'
|
||||
__version__ = '5.0.20'
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
"label": "Account Type",
|
||||
"oldfieldname": "account_type",
|
||||
"oldfieldtype": "Select",
|
||||
"options": "\nBank\nCash\nTax\nChargeable\nWarehouse\nReceivable\nPayable\nEquity\nFixed Asset\nCost of Goods Sold\nExpense Account\nIncome Account\nStock Received But Not Billed\nExpenses Included In Valuation\nStock Adjustment\nStock\nTemporary",
|
||||
"options": "\nBank\nCash\nTax\nChargeable\nWarehouse\nReceivable\nPayable\nEquity\nFixed Asset\nCost of Goods Sold\nExpense Account\nRound Off\nIncome Account\nStock Received But Not Billed\nExpenses Included In Valuation\nStock Adjustment\nStock\nTemporary",
|
||||
"permlevel": 0,
|
||||
"search_index": 0
|
||||
},
|
||||
@@ -171,7 +171,7 @@
|
||||
"icon": "icon-money",
|
||||
"idx": 1,
|
||||
"in_create": 0,
|
||||
"modified": "2015-04-27 20:07:37.147184",
|
||||
"modified": "2015-05-28 14:10:40.606010",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Account",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"country_code": "ni",
|
||||
"name": "Catalogo de Cuentas",
|
||||
"name": "Catalogo de Cuentas Nicaragua",
|
||||
"is_active": "Yes",
|
||||
"tree": {
|
||||
"Activo": {
|
||||
@@ -72,7 +72,7 @@
|
||||
"IVA Acreditable por Importaciones": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"IVA Acreditable por Prestacion de Servicios": {
|
||||
"IVA Acreditable por Prestacion de Servicios y Uso y Goce de Bienes": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Acreditacion Proporcional": {}
|
||||
@@ -229,11 +229,19 @@
|
||||
"Impuesto al Valor Agregado por Pagar": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Impuesto sobre la Renta": {
|
||||
"Impuesto sobre la Renta por Actividades Economicas": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Impuestos Municipales": {
|
||||
"account_type": "Tax"
|
||||
"Impuesto Municipal Sobre Ingresos": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Recoleccion Basura": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Matricula Municipal": {
|
||||
"account_type": "Tax"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Retenciones por Pagar": {
|
||||
@@ -241,7 +249,13 @@
|
||||
"Retencion Rentas del Trabajo Tarifa Progresiva": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Retencion Definitiva por Rentas del Trabajo": {
|
||||
"Retencion Definitiva 10% por Rentas del Trabajo - Indemnizacion Adicional": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Retencion Definitiva 12.5% por Rentas del Trabajo - Dietas": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Retencion Definitiva 15% por Rentas del Trabajo - No Residentes": {
|
||||
"account_type": "Tax"
|
||||
}
|
||||
},
|
||||
@@ -258,11 +272,26 @@
|
||||
"Retencion 5% compra Madera en Rollo": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Retencion Definitiva 1.5% Actividades Economicas No Residentes": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Retencion Definitiva 3% Actividades Economicas No Residentes": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Retencion Definitiva 10% Actividades Economicas No Residentes": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Retencion Definitiva 15% Actividades Economicas No Residentes": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Otras Retenciones 10%": {
|
||||
"account_type": "Tax"
|
||||
}
|
||||
},
|
||||
"Rentas y Ganancias de Capital": {
|
||||
"Retencion Defintiva 15% por Rentas de Capital": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Retencion Defintiva 10% por Rentas de Capital": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
@@ -272,10 +301,16 @@
|
||||
"Retencion Definitiva 10% por Ganancia de Capital": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Retencion Definitiva Actividades Economicas No Residentes": {
|
||||
"Retencion Definitiva 0.25% Transacciones Bursatiles": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Retencion Definitiva Transacciones Bursatiles": {
|
||||
"Retencion Definitiva 1% Transacciones Bursatiles": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Retencion Definitiva 1.5% Transacciones Bursatiles": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Retencion Definitiva 2% Transacciones Bursatiles": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"Retenciones Defintiva 5% Fondos de Inversion": {
|
||||
|
||||
@@ -117,8 +117,8 @@ def get():
|
||||
_("Print and Stationary"): {
|
||||
"account_type": "Expense Account"
|
||||
},
|
||||
_("Rounded Off"): {
|
||||
"account_type": "Expense Account"
|
||||
_("Round Off"): {
|
||||
"account_type": "Round Off"
|
||||
},
|
||||
_("Salary"): {
|
||||
"account_type": "Expense Account"
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.ui.form.on("Bank Reconciliation", {
|
||||
refresh: function(frm) {
|
||||
frm.disable_save();
|
||||
},
|
||||
|
||||
update_clearance_date: function(frm) {
|
||||
return frappe.call({
|
||||
method: "update_details",
|
||||
@@ -33,5 +37,4 @@ cur_frm.cscript.onload = function(doc, cdt, cdn) {
|
||||
|
||||
cur_frm.set_value("from_date", frappe.datetime.month_start());
|
||||
cur_frm.set_value("to_date", frappe.datetime.month_end());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,7 +25,8 @@ class BankReconciliation(Document):
|
||||
where
|
||||
t2.parent = t1.name and t2.account = %s
|
||||
and t1.posting_date >= %s and t1.posting_date <= %s and t1.docstatus=1
|
||||
and ifnull(t1.is_opening, 'No') = 'No' %s""" %
|
||||
and ifnull(t1.is_opening, 'No') = 'No' %s
|
||||
order by t1.posting_date""" %
|
||||
('%s', '%s', '%s', condition), (self.bank_account, self.from_date, self.to_date), as_dict=1)
|
||||
|
||||
self.set('journal_entries', [])
|
||||
|
||||
25
erpnext/accounts/doctype/gl_entry/test_gl_entry.py
Normal file
25
erpnext/accounts/doctype/gl_entry/test_gl_entry.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# 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, unittest
|
||||
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
|
||||
|
||||
class TestGLEntry(unittest.TestCase):
|
||||
def test_round_off_entry(self):
|
||||
frappe.db.set_value("Company", "_Test Company", "round_off_account", "_Test Write Off - _TC")
|
||||
frappe.db.set_value("Company", "_Test Company", "round_off_cost_center", "_Test Cost Center - _TC")
|
||||
|
||||
jv = make_journal_entry("_Test Account Cost for Goods Sold - _TC",
|
||||
"_Test Account Bank Account - _TC", 100, "_Test Cost Center - _TC", submit=False)
|
||||
|
||||
jv.get("accounts")[0].debit = 100.01
|
||||
jv.flags.ignore_validate = True
|
||||
jv.submit()
|
||||
|
||||
round_off_entry = frappe.db.sql("""select name from `tabGL Entry`
|
||||
where voucher_type='Journal Entry' and voucher_no = %s
|
||||
and account='_Test Write Off - _TC' and cost_center='_Test Cost Center - _TC'
|
||||
and ifnull(debit, 0) = 0 and ifnull(credit, 0) = '.01'""", jv.name)
|
||||
|
||||
self.assertTrue(round_off_entry)
|
||||
@@ -4,7 +4,7 @@
|
||||
frappe.provide("erpnext.accounts");
|
||||
frappe.require("assets/erpnext/js/utils.js");
|
||||
|
||||
erpnext.accounts.JournalVoucher = frappe.ui.form.Controller.extend({
|
||||
erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
|
||||
onload: function() {
|
||||
this.load_defaults();
|
||||
this.setup_queries();
|
||||
@@ -130,10 +130,31 @@ erpnext.accounts.JournalVoucher = frappe.ui.form.Controller.extend({
|
||||
cur_frm.cscript.update_totals(me.frm.doc);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
accounts_add: function(doc, cdt, cdn) {
|
||||
var row = frappe.get_doc(cdt, cdn);
|
||||
$.each(doc.accounts, function(i, d) {
|
||||
if(d.account && d.party && d.party_type) {
|
||||
row.account = d.account;
|
||||
row.party = d.party;
|
||||
row.party_type = d.party_type;
|
||||
}
|
||||
});
|
||||
|
||||
// set difference
|
||||
if(doc.difference) {
|
||||
if(doc.difference > 0) {
|
||||
row.credit = doc.difference;
|
||||
} else {
|
||||
row.debit = -doc.difference;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
cur_frm.script_manager.make(erpnext.accounts.JournalVoucher);
|
||||
cur_frm.script_manager.make(erpnext.accounts.JournalEntry);
|
||||
|
||||
cur_frm.cscript.refresh = function(doc) {
|
||||
erpnext.toggle_naming_series();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils import cstr, flt, fmt_money, formatdate, getdate, cint
|
||||
from frappe.utils import cstr, flt, fmt_money, formatdate, getdate
|
||||
from frappe import msgprint, _, scrub
|
||||
from erpnext.setup.utils import get_company_currency
|
||||
from erpnext.controllers.accounts_controller import AccountsController
|
||||
@@ -81,7 +81,8 @@ class JournalEntry(AccountsController):
|
||||
frappe.throw(_("Row {0}: Party Type and Party is only applicable against Receivable / Payable account").format(d.idx))
|
||||
|
||||
def check_credit_limit(self):
|
||||
customers = list(set([d.party for d in self.get("accounts") if d.party_type=="Customer" and flt(d.debit) > 0]))
|
||||
customers = list(set([d.party for d in self.get("accounts")
|
||||
if d.party_type=="Customer" and d.party and flt(d.debit) > 0]))
|
||||
if customers:
|
||||
from erpnext.selling.doctype.customer.customer import check_credit_limit
|
||||
for customer in customers:
|
||||
@@ -427,12 +428,11 @@ class JournalEntry(AccountsController):
|
||||
def validate_expense_claim(self):
|
||||
for d in self.accounts:
|
||||
if d.against_expense_claim:
|
||||
sanctioned_amount, reimbursed_amount = frappe.db.get_value("Expense Claim", d.against_expense_claim,
|
||||
("total_sanctioned_amount", "total_amount_reimbursed"))
|
||||
pending_amount = cint(sanctioned_amount) - cint(reimbursed_amount)
|
||||
sanctioned_amount, reimbursed_amount = frappe.db.get_value("Expense Claim",
|
||||
d.against_expense_claim, ("total_sanctioned_amount", "total_amount_reimbursed"))
|
||||
pending_amount = flt(sanctioned_amount) - flt(reimbursed_amount)
|
||||
if d.debit > pending_amount:
|
||||
frappe.throw(_("Row No {0}: Amount cannot be greater than Pending Amount against Expense Claim {1}. \
|
||||
Pending Amount is {2}".format(d.idx, d.against_expense_claim, pending_amount)))
|
||||
frappe.throw(_("Row No {0}: Amount cannot be greater than Pending Amount against Expense Claim {1}. Pending Amount is {2}".format(d.idx, d.against_expense_claim, pending_amount)))
|
||||
|
||||
def validate_credit_debit_note(self):
|
||||
if self.stock_entry:
|
||||
|
||||
@@ -44,6 +44,10 @@ erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.ext
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
this.frm.disable_save();
|
||||
},
|
||||
|
||||
party: function() {
|
||||
var me = this
|
||||
|
||||
@@ -32,6 +32,7 @@ frappe.ui.form.on("Payment Tool", "onload", function(frm) {
|
||||
});
|
||||
|
||||
frappe.ui.form.on("Payment Tool", "refresh", function(frm) {
|
||||
frm.disable_save();
|
||||
frappe.ui.form.trigger("Payment Tool", "party_type");
|
||||
});
|
||||
|
||||
|
||||
@@ -312,7 +312,7 @@
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"modified": "2015-02-21 03:59:08.154966",
|
||||
"modified": "2015-06-05 11:17:33.843334",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Tool",
|
||||
|
||||
@@ -205,9 +205,9 @@ def get_pricing_rules(args):
|
||||
|
||||
def filter_pricing_rules(args, pricing_rules):
|
||||
# filter for qty
|
||||
if pricing_rules and args.get("qty"):
|
||||
pricing_rules = filter(lambda x: (args.qty>=flt(x.min_qty)
|
||||
and (args.qty<=x.max_qty if x.max_qty else True)), pricing_rules)
|
||||
if pricing_rules:
|
||||
pricing_rules = filter(lambda x: (flt(args.get("qty"))>=flt(x.min_qty)
|
||||
and (flt(args.get("qty"))<=x.max_qty if x.max_qty else True)), pricing_rules)
|
||||
|
||||
# find pricing rule with highest priority
|
||||
if pricing_rules:
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text",
|
||||
"in_list_view": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Description",
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Text",
|
||||
@@ -452,7 +452,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2015-05-27 02:47:16.341373",
|
||||
"modified": "2015-06-02 14:18:56.294949",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice Item",
|
||||
|
||||
@@ -65,7 +65,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
});
|
||||
|
||||
if(!from_delivery_note) {
|
||||
cur_frm.page.add_menu_item(__('Make Delivery'), cur_frm.cscript['Make Delivery Note'], "icon-truck")
|
||||
cur_frm.add_custom_button(__('Make Delivery'), cur_frm.cscript['Make Delivery Note'], "icon-truck")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,14 +75,14 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
}
|
||||
|
||||
// Show buttons only when pos view is active
|
||||
if (doc.docstatus===0 && !cur_frm.page.current_view_name!=="pos") {
|
||||
if (cint(doc.docstatus==0) && cur_frm.page.current_view_name!=="pos") {
|
||||
cur_frm.cscript.sales_order_btn();
|
||||
cur_frm.cscript.delivery_note_btn();
|
||||
}
|
||||
},
|
||||
|
||||
sales_order_btn: function() {
|
||||
this.$sales_order_btn = cur_frm.page.add_menu_item(__('From Sales Order'),
|
||||
this.$sales_order_btn = cur_frm.add_custom_button(__('From Sales Order'),
|
||||
function() {
|
||||
frappe.model.map_current_doc({
|
||||
method: "erpnext.selling.doctype.sales_order.sales_order.make_sales_invoice",
|
||||
@@ -99,7 +99,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
},
|
||||
|
||||
delivery_note_btn: function() {
|
||||
this.$delivery_note_btn = cur_frm.page.add_menu_item(__('From Delivery Note'),
|
||||
this.$delivery_note_btn = cur_frm.add_custom_button(__('From Delivery Note'),
|
||||
function() {
|
||||
frappe.model.map_current_doc({
|
||||
method: "erpnext.stock.doctype.delivery_note.delivery_note.make_sales_invoice",
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text",
|
||||
"in_list_view": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Description",
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Text",
|
||||
@@ -505,7 +505,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2015-05-27 02:47:15.645114",
|
||||
"modified": "2015-06-02 14:18:45.176726",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Item",
|
||||
|
||||
@@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils import flt, cstr
|
||||
from frappe import _
|
||||
from frappe.model.meta import get_field_precision
|
||||
from erpnext.accounts.utils import validate_expense_against_budget
|
||||
|
||||
|
||||
@@ -55,28 +56,23 @@ def merge_similar_entries(gl_map):
|
||||
|
||||
def check_if_in_list(gle, gl_map):
|
||||
for e in gl_map:
|
||||
if e.account == gle.account and \
|
||||
cstr(e.get('against_voucher'))==cstr(gle.get('against_voucher')) \
|
||||
and cstr(e.get('against_voucher_type')) == \
|
||||
cstr(gle.get('against_voucher_type')) \
|
||||
and cstr(e.get('cost_center')) == cstr(gle.get('cost_center')):
|
||||
return e
|
||||
if e.account == gle.account \
|
||||
and cstr(e.get('party_type'))==cstr(gle.get('party_type')) \
|
||||
and cstr(e.get('party'))==cstr(gle.get('party')) \
|
||||
and cstr(e.get('against_voucher'))==cstr(gle.get('against_voucher')) \
|
||||
and cstr(e.get('against_voucher_type')) == cstr(gle.get('against_voucher_type')) \
|
||||
and cstr(e.get('cost_center')) == cstr(gle.get('cost_center')):
|
||||
return e
|
||||
|
||||
def save_entries(gl_map, adv_adj, update_outstanding):
|
||||
validate_account_for_auto_accounting_for_stock(gl_map)
|
||||
|
||||
total_debit = total_credit = 0.0
|
||||
round_off_debit_credit(gl_map)
|
||||
|
||||
for entry in gl_map:
|
||||
make_entry(entry, adv_adj, update_outstanding)
|
||||
# check against budget
|
||||
validate_expense_against_budget(entry)
|
||||
|
||||
# update total debit / credit
|
||||
total_debit += flt(entry.debit)
|
||||
total_credit += flt(entry.credit)
|
||||
|
||||
validate_total_debit_credit(total_debit, total_credit, gl_map)
|
||||
|
||||
def make_entry(args, adv_adj, update_outstanding):
|
||||
args.update({"doctype": "GL Entry"})
|
||||
gle = frappe.get_doc(args)
|
||||
@@ -85,10 +81,6 @@ def make_entry(args, adv_adj, update_outstanding):
|
||||
gle.run_method("on_update_with_args", adv_adj, update_outstanding)
|
||||
gle.submit()
|
||||
|
||||
def validate_total_debit_credit(total_debit, total_credit, gl_map):
|
||||
if abs(total_debit - total_credit) > 0.005:
|
||||
frappe.throw(_("Debit and Credit not equal for {0} #{1}. Difference is {2}.").format(gl_map[0].voucher_type, gl_map[0].voucher_no, total_debit - total_credit))
|
||||
|
||||
def validate_account_for_auto_accounting_for_stock(gl_map):
|
||||
if gl_map[0].voucher_type=="Journal Entry":
|
||||
aii_accounts = [d[0] for d in frappe.db.sql("""select name from tabAccount
|
||||
@@ -96,7 +88,54 @@ def validate_account_for_auto_accounting_for_stock(gl_map):
|
||||
|
||||
for entry in gl_map:
|
||||
if entry.account in aii_accounts:
|
||||
frappe.throw(_("Account: {0} can only be updated via Stock Transactions").format(entry.account), StockAccountInvalidTransaction)
|
||||
frappe.throw(_("Account: {0} can only be updated via Stock Transactions")
|
||||
.format(entry.account), StockAccountInvalidTransaction)
|
||||
|
||||
def round_off_debit_credit(gl_map):
|
||||
precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit"),
|
||||
currency=frappe.db.get_value("Company", gl_map[0].company, "default_currency", cache=True))
|
||||
|
||||
debit_credit_diff = 0.0
|
||||
for entry in gl_map:
|
||||
entry.debit = flt(entry.debit, precision)
|
||||
entry.credit = flt(entry.credit, precision)
|
||||
debit_credit_diff += entry.debit - entry.credit
|
||||
|
||||
debit_credit_diff = flt(debit_credit_diff, precision)
|
||||
if abs(debit_credit_diff) >= (5.0 / (10**precision)):
|
||||
frappe.throw(_("Debit and Credit not equal for {0} #{1}. Difference is {2}.")
|
||||
.format(gl_map[0].voucher_type, gl_map[0].voucher_no, debit_credit_diff))
|
||||
|
||||
elif abs(debit_credit_diff) >= (1.0 / (10**precision)):
|
||||
make_round_off_gle(gl_map, debit_credit_diff)
|
||||
|
||||
def make_round_off_gle(gl_map, debit_credit_diff):
|
||||
round_off_account, round_off_cost_center = frappe.db.get_value("Company", gl_map[0].company,
|
||||
["round_off_account", "round_off_cost_center"]) or [None, None]
|
||||
if not round_off_account:
|
||||
frappe.throw(_("Please mention Round Off Account in Company"))
|
||||
|
||||
if not round_off_cost_center:
|
||||
frappe.throw(_("Please mention Round Off Cost Center in Company"))
|
||||
|
||||
|
||||
round_off_gle = frappe._dict()
|
||||
for k in ["voucher_type", "voucher_no", "company",
|
||||
"posting_date", "remarks", "fiscal_year", "is_opening"]:
|
||||
round_off_gle[k] = gl_map[0][k]
|
||||
|
||||
round_off_gle.update({
|
||||
"account": round_off_account,
|
||||
"debit": abs(debit_credit_diff) if debit_credit_diff < 0 else 0,
|
||||
"credit": debit_credit_diff if debit_credit_diff > 0 else 0,
|
||||
"cost_center": round_off_cost_center,
|
||||
"party_type": None,
|
||||
"party": None,
|
||||
"against_voucher_type": None,
|
||||
"against_voucher": None
|
||||
})
|
||||
|
||||
gl_map.append(round_off_gle)
|
||||
|
||||
|
||||
def delete_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None,
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<button class="btn btn-primary btn-lg">{%= __("Start") %}</button>
|
||||
</p>
|
||||
<p class="pos-setting-message hide">
|
||||
<a class="btn btn-default btn-sm" href="#Form/POS Setting/New POS Setting">
|
||||
{%= __("Make new POS Setting") %}</a>
|
||||
<a class="btn btn-default btn-sm" href="#Form/POS Profile/New POS Profile">
|
||||
{%= __("Make new POS Profile") %}</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -16,12 +16,16 @@ def get_party_details(party=None, account=None, party_type="Customer", company=N
|
||||
|
||||
if not party:
|
||||
return {}
|
||||
|
||||
if not frappe.db.exists(party_type, party):
|
||||
frappe.throw(_("{0}: {1} does not exists").format(party_type, party))
|
||||
|
||||
return _get_party_details(party, account, party_type,
|
||||
company, posting_date, price_list, currency, doctype)
|
||||
|
||||
def _get_party_details(party=None, account=None, party_type="Customer", company=None,
|
||||
posting_date=None, price_list=None, currency=None, doctype=None, ignore_permissions=False):
|
||||
|
||||
out = frappe._dict(set_account_and_due_date(party, account, party_type, company, posting_date, doctype))
|
||||
|
||||
party = out[party_type.lower()]
|
||||
|
||||
@@ -14,7 +14,7 @@ def execute(filters=None):
|
||||
source = gross_profit_data.grouped_data if filters.get("group_by") != "Invoice" else gross_profit_data.data
|
||||
|
||||
group_wise_columns = frappe._dict({
|
||||
"invoice": ["name", "posting_date", "posting_time", "item_code", "item_name", "brand", "description", \
|
||||
"invoice": ["parent", "customer", "posting_date", "posting_time", "item_code", "item_name", "brand", "description", \
|
||||
"warehouse", "qty", "base_rate", "buying_rate", "base_amount",
|
||||
"buying_amount", "gross_profit", "gross_profit_percent", "project"],
|
||||
"item_code": ["item_code", "item_name", "brand", "description", "warehouse", "qty", "base_rate",
|
||||
@@ -50,7 +50,7 @@ def execute(filters=None):
|
||||
def get_columns(group_wise_columns, filters):
|
||||
columns = []
|
||||
column_map = frappe._dict({
|
||||
"name": _("Sales Invoice") + ":Link/Sales Invoice:120",
|
||||
"parent": _("Sales Invoice") + ":Link/Sales Invoice:120",
|
||||
"posting_date": _("Posting Date") + ":Date",
|
||||
"posting_time": _("Posting Time"),
|
||||
"item_code": _("Item Code") + ":Link/Item",
|
||||
@@ -183,8 +183,6 @@ class GrossProfitGenerator(object):
|
||||
my_sle = self.sle.get((item_code, row.warehouse))
|
||||
for i, sle in enumerate(my_sle):
|
||||
# find the stock valution rate from stock ledger entry
|
||||
print sle.voucher_type, row.parenttype, sle.voucher_no, row.parent, \
|
||||
sle.voucher_detail_no, row.item_row
|
||||
if sle.voucher_type == row.parenttype and row.parent == sle.voucher_no and \
|
||||
sle.voucher_detail_no == row.item_row:
|
||||
previous_stock_value = len(my_sle) > i+1 and \
|
||||
|
||||
@@ -12,7 +12,6 @@ def execute(filters=None):
|
||||
invoice_list = get_invoices(filters)
|
||||
columns, expense_accounts, tax_accounts = get_columns(invoice_list)
|
||||
|
||||
|
||||
if not invoice_list:
|
||||
msgprint(_("No record found"))
|
||||
return columns, invoice_list
|
||||
@@ -30,7 +29,8 @@ def execute(filters=None):
|
||||
purchase_receipt = list(set(invoice_po_pr_map.get(inv.name, {}).get("purchase_receipt", [])))
|
||||
project_name = list(set(invoice_po_pr_map.get(inv.name, {}).get("project_name", [])))
|
||||
|
||||
row = [inv.name, inv.posting_date, inv.supplier, inv.supplier_name, supplier_details.get(inv.supplier),
|
||||
row = [inv.name, inv.posting_date, inv.supplier, inv.supplier_name,
|
||||
supplier_details.get(inv.supplier),
|
||||
inv.credit_to, ", ".join(project_name), inv.bill_no, inv.bill_date, inv.remarks,
|
||||
", ".join(purchase_order), ", ".join(purchase_receipt)]
|
||||
|
||||
@@ -54,8 +54,7 @@ def execute(filters=None):
|
||||
|
||||
# total tax, grand total, outstanding amount & rounded total
|
||||
row += [total_tax, inv.base_grand_total, flt(inv.base_grand_total, 2), inv.outstanding_amount]
|
||||
data.append(row)
|
||||
# raise Exception
|
||||
data.append(row)
|
||||
|
||||
return columns, data
|
||||
|
||||
@@ -107,7 +106,7 @@ def get_conditions(filters):
|
||||
|
||||
def get_invoices(filters):
|
||||
conditions = get_conditions(filters)
|
||||
return frappe.db.sql("""select name, posting_date, credit_to, supplier, supplier_name
|
||||
return frappe.db.sql("""select name, posting_date, credit_to, supplier, supplier_name,
|
||||
bill_no, bill_date, remarks, base_net_total, base_grand_total, outstanding_amount
|
||||
from `tabPurchase Invoice` where docstatus = 1 %s
|
||||
order by posting_date desc, name desc""" % conditions, filters, as_dict=1)
|
||||
|
||||
@@ -30,7 +30,8 @@ def execute(filters=None):
|
||||
delivery_note = list(set(invoice_so_dn_map.get(inv.name, {}).get("delivery_note", [])))
|
||||
|
||||
row = [inv.name, inv.posting_date, inv.customer, inv.customer_name,
|
||||
customer_map.get(inv.customer)["customer_group"], customer_map.get(inv.customer)["territory"],
|
||||
customer_map.get(inv.customer, {}).get("customer_group"),
|
||||
customer_map.get(inv.customer, {}).get("territory"),
|
||||
inv.debit_to, inv.project_name, inv.remarks, ", ".join(sales_order), ", ".join(delivery_note)]
|
||||
|
||||
# map income values
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"description": "Supplier (vendor) name as entered in supplier master",
|
||||
"description": "",
|
||||
"fieldname": "supplier",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
@@ -873,7 +873,7 @@
|
||||
"icon": "icon-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2015-05-27 02:48:02.452899",
|
||||
"modified": "2015-06-02 17:15:44.711032",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order",
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"in_list_view": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Description",
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Small Text",
|
||||
@@ -538,7 +538,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2015-05-27 02:47:16.553472",
|
||||
"modified": "2015-06-02 14:19:21.459032",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order Item",
|
||||
|
||||
@@ -57,3 +57,7 @@ cur_frm.fields_dict['item_serial_no'].get_query = function(doc, cdt, cdn) {
|
||||
|
||||
return { filters: filter }
|
||||
}
|
||||
|
||||
cur_frm.add_fetch('item_code', 'item_name', 'item_name');
|
||||
cur_frm.add_fetch('item_code', 'description', 'description');
|
||||
|
||||
|
||||
@@ -127,6 +127,14 @@
|
||||
"permlevel": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"label": "Item Name",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
@@ -219,7 +227,7 @@
|
||||
"icon": "icon-search",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2015-04-14 07:37:07.331291",
|
||||
"modified": "2015-06-08 02:40:25.121948",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Quality Inspection",
|
||||
|
||||
@@ -31,7 +31,6 @@ class QualityInspection(Document):
|
||||
(self.name, self.modified, self.purchase_receipt_no,
|
||||
self.item_code))
|
||||
|
||||
|
||||
def on_cancel(self):
|
||||
if self.purchase_receipt_no:
|
||||
frappe.db.sql("""update `tabPurchase Receipt Item` t1, `tabPurchase Receipt` t2
|
||||
@@ -39,7 +38,6 @@ class QualityInspection(Document):
|
||||
where t1.parent = %s and t1.item_code = %s and t1.parent = t2.name""",
|
||||
(self.modified, self.purchase_receipt_no, self.item_code))
|
||||
|
||||
|
||||
def item_query(doctype, txt, searchfield, start, page_len, filters):
|
||||
if filters.get("from"):
|
||||
from frappe.desk.reportview import get_match_cond
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"description": "Supplier (vendor) name as entered in supplier master",
|
||||
"description": "",
|
||||
"fieldname": "supplier",
|
||||
"fieldtype": "Link",
|
||||
"in_filter": 1,
|
||||
@@ -660,7 +660,7 @@
|
||||
"icon": "icon-shopping-cart",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2015-05-27 02:48:02.098540",
|
||||
"modified": "2015-06-02 17:15:57.283516",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Supplier Quotation",
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"in_list_view": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Description",
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Small Text",
|
||||
@@ -413,7 +413,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2015-05-27 02:47:15.853886",
|
||||
"modified": "2015-06-02 14:19:33.922968",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Supplier Quotation Item",
|
||||
|
||||
2
erpnext/change_log/v5/v5_0_12.md
Normal file
2
erpnext/change_log/v5/v5_0_12.md
Normal file
@@ -0,0 +1,2 @@
|
||||
- Introduced `Round Off` account to book rounding loss automatically
|
||||
- Added 2 new fields 'Round Off Account' and 'Round Off Cost Center' in Company
|
||||
@@ -31,7 +31,7 @@ def get_data():
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Opening Stock Balance"),
|
||||
"youtube_id": "yPgrtfeCTs"
|
||||
"youtube_id": "0yPgrtfeCTs"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
@@ -106,7 +106,7 @@ def get_data():
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Opening Stock Balance"),
|
||||
"youtube_id": "yPgrtfeCTs"
|
||||
"youtube_id": "0yPgrtfeCTs"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
|
||||
@@ -266,7 +266,7 @@ def get_data():
|
||||
{
|
||||
"type": "help",
|
||||
"label": _("Opening Stock Balance"),
|
||||
"youtube_id": "yPgrtfeCTs"
|
||||
"youtube_id": "0yPgrtfeCTs"
|
||||
},
|
||||
{
|
||||
"type": "help",
|
||||
|
||||
@@ -38,7 +38,8 @@ class AccountsController(TransactionBase):
|
||||
convert_to_recurring(self, self.get("posting_date") or self.get("transaction_date"))
|
||||
|
||||
def before_recurring(self):
|
||||
self.fiscal_year = None
|
||||
if self.meta.get_field("fiscal_year"):
|
||||
self.fiscal_year = None
|
||||
if self.meta.get_field("due_date"):
|
||||
self.due_date = None
|
||||
|
||||
@@ -46,7 +47,7 @@ class AccountsController(TransactionBase):
|
||||
for fieldname in ["posting_date", "transaction_date"]:
|
||||
if not self.get(fieldname) and self.meta.get_field(fieldname):
|
||||
self.set(fieldname, today())
|
||||
if not self.fiscal_year:
|
||||
if self.meta.get_field("fiscal_year") and not self.fiscal_year:
|
||||
self.fiscal_year = get_fiscal_year(self.get(fieldname))[0]
|
||||
break
|
||||
|
||||
@@ -334,7 +335,7 @@ class AccountsController(TransactionBase):
|
||||
@frappe.whitelist()
|
||||
def get_tax_rate(account_head):
|
||||
return frappe.db.get_value("Account", account_head, "tax_rate")
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_default_taxes_and_charges(master_doctype):
|
||||
default_tax = frappe.db.get_value(master_doctype, {"is_default": 1})
|
||||
|
||||
@@ -78,7 +78,7 @@ class StatusUpdater(Document):
|
||||
self.status = s[0]
|
||||
break
|
||||
|
||||
if self.status != _status:
|
||||
if self.status != _status and self.status not in ("Submitted", "Cancelled"):
|
||||
self.add_comment("Label", _(self.status))
|
||||
|
||||
if update:
|
||||
|
||||
@@ -44,11 +44,14 @@ class NewsletterList(Document):
|
||||
return self.update_total_subscribers()
|
||||
|
||||
def update_total_subscribers(self):
|
||||
self.total_subscribers = frappe.db.sql("""select count(*) from `tabNewsletter List Subscriber`
|
||||
where newsletter_list=%s""", self.name)[0][0]
|
||||
self.total_subscribers = self.get_total_subscribers()
|
||||
self.db_update()
|
||||
return self.total_subscribers
|
||||
|
||||
def get_total_subscribers(self):
|
||||
return frappe.db.sql("""select count(*) from `tabNewsletter List Subscriber`
|
||||
where newsletter_list=%s""", self.name)[0][0]
|
||||
|
||||
def on_trash(self):
|
||||
for d in frappe.get_all("Newsletter List Subscriber", "name", {"newsletter_list": self.name}):
|
||||
frappe.delete_doc("Newsletter List Subscriber", d.name)
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text",
|
||||
"in_list_view": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Description",
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Text",
|
||||
@@ -134,7 +134,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2015-05-14 14:55:18.325286",
|
||||
"modified": "2015-06-02 14:18:16.622288",
|
||||
"modified_by": "Administrator",
|
||||
"module": "CRM",
|
||||
"name": "Opportunity Item",
|
||||
|
||||
@@ -5,7 +5,7 @@ app_publisher = "Frappe Technologies Pvt. Ltd. and Contributors"
|
||||
app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
|
||||
app_icon = "icon-th"
|
||||
app_color = "#e74c3c"
|
||||
app_version = "5.0.12"
|
||||
app_version = "5.0.20"
|
||||
|
||||
error_report_email = "support@erpnext.com"
|
||||
|
||||
@@ -38,16 +38,14 @@ website_route_rules = [
|
||||
{"from_route": "/invoices", "to_route": "Sales Invoice"},
|
||||
{"from_route": "/invoices/<path:name>", "to_route": "print", "defaults": {"doctype": "Sales Invoice"}},
|
||||
{"from_route": "/shipments", "to_route": "Delivery Note"},
|
||||
{"from_route": "/shipments/<path:name>", "to_route": "print", "defaults": {"doctype": "Delivery Note"}},
|
||||
{"from_route": "/issues", "to_route": "Issue"},
|
||||
{"from_route": "/issues/<path:name>", "to_route": "print", "defaults": {"doctype": "Issue"}},
|
||||
{"from_route": "/addresses", "to_route": "Address"},
|
||||
{"from_route": "/shipments/<path:name>", "to_route": "print", "defaults": {"doctype": "Delivery Note"}}
|
||||
]
|
||||
|
||||
has_website_permission = {
|
||||
"Sales Order": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
||||
"Sales Invoice": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
||||
"Delivery Note": "erpnext.controllers.website_list_for_contact.has_website_permission"
|
||||
"Delivery Note": "erpnext.controllers.website_list_for_contact.has_website_permission",
|
||||
"Issue": "erpnext.support.doctype.issue.issue.has_website_permission"
|
||||
}
|
||||
|
||||
dump_report_map = "erpnext.startup.report_data_map.data_map"
|
||||
|
||||
@@ -23,9 +23,6 @@ class LeaveAllocation(Document):
|
||||
def on_update(self):
|
||||
self.get_total_allocated_leaves()
|
||||
|
||||
def on_cancel(self):
|
||||
self.check_for_leave_application()
|
||||
|
||||
def validate_new_leaves_allocated_value(self):
|
||||
"""validate that leave allocation is in multiples of 0.5"""
|
||||
if flt(self.new_leaves_allocated) % 0.5:
|
||||
|
||||
@@ -130,6 +130,7 @@
|
||||
"description": "",
|
||||
"fieldname": "leave_approver",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 1,
|
||||
"label": "Leave Approver",
|
||||
"options": "User",
|
||||
"permlevel": 0
|
||||
@@ -216,7 +217,7 @@
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"max_attachments": 3,
|
||||
"modified": "2015-04-30 02:19:39.330689",
|
||||
"modified": "2015-05-27 18:44:36.708614",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Leave Application",
|
||||
|
||||
@@ -24,4 +24,8 @@ cur_frm.cscript.to_date = function(doc, cdt, cdn) {
|
||||
cur_frm.cscript.allocation_type = function (doc, cdt, cdn){
|
||||
doc.no_of_days = '';
|
||||
refresh_field('no_of_days');
|
||||
}
|
||||
}
|
||||
|
||||
frappe.ui.form.on("Leave Control Panel", "refresh", function(frm) {
|
||||
frm.disable_save();
|
||||
});
|
||||
@@ -94,11 +94,11 @@
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"hide_toolbar": 1,
|
||||
"icon": "icon-cog",
|
||||
"idx": 1,
|
||||
"issingle": 1,
|
||||
"modified": "2015-02-05 05:11:40.791976",
|
||||
"modified": "2015-06-05 11:38:19.994852",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Leave Control Panel",
|
||||
@@ -110,7 +110,7 @@
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "HR User",
|
||||
"share": 1,
|
||||
"share": 0,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
|
||||
@@ -43,3 +43,8 @@ cur_frm.cscript.make_jv = function(doc, dt, dn) {
|
||||
frappe.set_route("Form", doc.doctype, doc.name);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
frappe.ui.form.on("Salary Manager", "refresh", function(frm) {
|
||||
frm.disable_save();
|
||||
});
|
||||
@@ -150,10 +150,11 @@
|
||||
"permlevel": 0
|
||||
}
|
||||
],
|
||||
"hide_toolbar": 1,
|
||||
"icon": "icon-cog",
|
||||
"idx": 1,
|
||||
"issingle": 1,
|
||||
"modified": "2015-02-25 07:21:04.778082",
|
||||
"modified": "2015-06-05 11:33:00.152362",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Salary Manager",
|
||||
|
||||
@@ -12,6 +12,7 @@ erpnext.hr.AttendanceControlPanel = frappe.ui.form.Controller.extend({
|
||||
},
|
||||
|
||||
refresh: function() {
|
||||
this.frm.disable_save();
|
||||
this.show_upload();
|
||||
},
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"allow_copy": 1,
|
||||
"creation": "2013-01-25 11:34:53",
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
@@ -53,11 +54,13 @@
|
||||
"permlevel": 0
|
||||
}
|
||||
],
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 1,
|
||||
"icon": "icon-upload-alt",
|
||||
"idx": 1,
|
||||
"issingle": 1,
|
||||
"max_attachments": 1,
|
||||
"modified": "2015-02-05 05:11:48.540845",
|
||||
"modified": "2015-06-05 11:37:04.348120",
|
||||
"modified_by": "Administrator",
|
||||
"module": "HR",
|
||||
"name": "Upload Attendance",
|
||||
@@ -65,25 +68,25 @@
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"email": 1,
|
||||
"email": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "HR User",
|
||||
"share": 1,
|
||||
"share": 0,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"create": 1,
|
||||
"email": 1,
|
||||
"email": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "HR Manager",
|
||||
"share": 1,
|
||||
"share": 0,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
|
||||
@@ -424,6 +424,6 @@ def validate_bom_no(item, bom_no):
|
||||
if bom.docstatus != 1:
|
||||
if not getattr(frappe.flags, "in_test", False):
|
||||
frappe.throw(_("BOM {0} must be submitted").format(bom_no))
|
||||
if item and not (bom.item == item or \
|
||||
bom.item == frappe.db.get_value("Item", item, "variant_of")):
|
||||
if item and not (bom.item.lower() == item.lower() or \
|
||||
bom.item.lower() == cstr(frappe.db.get_value("Item", item, "variant_of")).lower()):
|
||||
frappe.throw(_("BOM {0} does not belong to Item {1}").format(bom_no, item))
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"allow_copy": 1,
|
||||
"creation": "2013-01-21 12:03:47",
|
||||
"default_print_format": "Standard",
|
||||
"docstatus": 0,
|
||||
@@ -154,11 +155,12 @@
|
||||
"permlevel": 0
|
||||
}
|
||||
],
|
||||
"hide_toolbar": 1,
|
||||
"icon": "icon-calendar",
|
||||
"idx": 1,
|
||||
"in_create": 1,
|
||||
"issingle": 1,
|
||||
"modified": "2015-02-05 05:11:43.010625",
|
||||
"modified": "2015-06-05 11:44:31.629114",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Manufacturing",
|
||||
"name": "Production Planning Tool",
|
||||
|
||||
@@ -161,3 +161,8 @@ erpnext.patches.v5_0.set_footer_address
|
||||
execute:frappe.db.set_value("Backup Manager", None, "send_backups_to_dropbox", 1 if frappe.db.get_value("Backup Manager", None, "upload_backups_to_dropbox") in ("Daily", "Weekly") else 0)
|
||||
execute:frappe.db.sql_list("delete from `tabDocPerm` where parent='Issue' and modified_by='Administrator' and role='Guest'")
|
||||
erpnext.patches.v5_0.update_item_and_description_again
|
||||
erpnext.patches.v5_0.repost_gle_for_jv_with_multiple_party
|
||||
erpnext.patches.v5_0.portal_fixes
|
||||
erpnext.patches.v5_0.reset_values_in_tools
|
||||
execute:frappe.delete_doc("Page", "users")
|
||||
erpnext.patches.v5_0.update_material_transferred_for_manufacturing_again
|
||||
6
erpnext/patches/v5_0/portal_fixes.py
Normal file
6
erpnext/patches/v5_0/portal_fixes.py
Normal file
@@ -0,0 +1,6 @@
|
||||
import frappe
|
||||
import erpnext.setup.install
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc("website", "doctype", "web_form_field", force=True)
|
||||
erpnext.setup.install.add_web_forms()
|
||||
@@ -9,13 +9,13 @@ def execute():
|
||||
# NOTE: sequence is important
|
||||
renamed_fields = get_all_renamed_fields()
|
||||
|
||||
for dt, script_field in (("Custom Script", "script"), ("Print Format", "html")):
|
||||
for dt, script_field, ref_dt_field in (("Custom Script", "script", "dt"), ("Print Format", "html", "doc_type")):
|
||||
|
||||
cond1 = " or ".join("""{0} like "%%{1}%%" """.format(script_field, d[0].replace("_", "\\_")) for d in renamed_fields)
|
||||
cond2 = " and standard = 'No'" if dt == "Print Format" else ""
|
||||
|
||||
for name, script in frappe.db.sql("select name, {0} as script from `tab{1}` where ({2}) {3}".format(script_field, dt, cond1, cond2)):
|
||||
update_script(dt, name, script_field, script, renamed_fields)
|
||||
for name, script, ref_dt in frappe.db.sql("select name, {0} as script, {1} as ref_dt from `tab{2}` where ({3}) {4}".format(script_field, ref_dt_field, dt, cond1, cond2)):
|
||||
update_script(dt, name, ref_dt, script_field, script, renamed_fields)
|
||||
|
||||
def get_all_renamed_fields():
|
||||
from erpnext.patches.v5_0.rename_table_fieldnames import rename_map
|
||||
@@ -46,20 +46,20 @@ def get_all_renamed_fields():
|
||||
)
|
||||
|
||||
for fields in rename_map.values():
|
||||
valid_fields = [d for d in fields if d[0] != "entries"]
|
||||
renamed_fields += tuple(valid_fields)
|
||||
renamed_fields += tuple(fields)
|
||||
|
||||
return renamed_fields
|
||||
|
||||
def update_script(dt, name, script_field, script, renamed_fields):
|
||||
def update_script(dt, name, ref_dt, script_field, script, renamed_fields):
|
||||
for from_field, to_field in renamed_fields:
|
||||
script = re.sub(r"\b{}\b".format(from_field), to_field, script)
|
||||
|
||||
if dt == "Journal Entry":
|
||||
if from_field != "entries":
|
||||
script = re.sub(r"\b{}\b".format(from_field), to_field, script)
|
||||
|
||||
if ref_dt == "Journal Entry":
|
||||
script = re.sub(r"\bentries\b", "accounts", script)
|
||||
elif dt == "Bank Reconciliation":
|
||||
elif ref_dt == "Bank Reconciliation":
|
||||
script = re.sub(r"\bentries\b", "journal_entries", script)
|
||||
elif dt in ("Sales Invoice", "Purchase Invoice"):
|
||||
elif ref_dt in ("Sales Invoice", "Purchase Invoice"):
|
||||
script = re.sub(r"\bentries\b", "items", script)
|
||||
|
||||
frappe.db.set_value(dt, name, script_field, script)
|
||||
@@ -0,0 +1,26 @@
|
||||
# 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():
|
||||
je_list = frappe.db.sql_list("""
|
||||
select par.name from `tabJournal Entry` par
|
||||
where par.docstatus=1 and par.creation > '2015-03-01'
|
||||
and (select count(distinct child.party) from `tabJournal Entry Account` child
|
||||
where par.name=child.parent and ifnull(child.party, '') != '') > 1
|
||||
""")
|
||||
|
||||
for d in je_list:
|
||||
# delete existing gle
|
||||
frappe.db.sql("delete from `tabGL Entry` where voucher_type='Journal Entry' and voucher_no=%s", d)
|
||||
|
||||
# repost gl entries
|
||||
je = frappe.get_doc("Journal Entry", d)
|
||||
je.make_gl_entries()
|
||||
|
||||
if je_list:
|
||||
print je_list
|
||||
|
||||
|
||||
11
erpnext/patches/v5_0/reset_values_in_tools.py
Normal file
11
erpnext/patches/v5_0/reset_values_in_tools.py
Normal file
@@ -0,0 +1,11 @@
|
||||
# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
for dt in ["Payment Tool", "Bank Reconciliation", "Payment Reconciliation", "Leave Control Panel",
|
||||
"Salary Manager", "Upload Attenadance", "Production Planning Tool", "BOM Replace Tool"]:
|
||||
frappe.db.sql("delete from `tabSingles` where doctype=%s", dt)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
pro_order_qty_transferred = frappe._dict()
|
||||
for se in frappe.db.sql("""select production_order, sum(fg_completed_qty) as transferred_qty
|
||||
from `tabStock Entry`
|
||||
where docstatus=1 and ifnull(production_order, '') != ''
|
||||
and purpose = 'Material Transfer for Manufacture'
|
||||
group by production_order""", as_dict=1):
|
||||
pro_order_qty_transferred.setdefault(se.production_order, se.transferred_qty)
|
||||
|
||||
for d in frappe.get_all("Production Order", filters={"docstatus": 1}, fields=["name", "qty"]):
|
||||
if d.name in pro_order_qty_transferred:
|
||||
material_transferred_for_manufacturing = pro_order_qty_transferred.get(d.name) \
|
||||
if pro_order_qty_transferred.get(d.name) <= d.qty else d.qty
|
||||
|
||||
frappe.db.sql("""update `tabProduction Order` set material_transferred_for_manufacturing=%s
|
||||
where name=%s""", (material_transferred_for_manufacturing, d.name))
|
||||
@@ -28,7 +28,11 @@ class Task(Document):
|
||||
|
||||
def validate(self):
|
||||
self.validate_dates()
|
||||
|
||||
|
||||
if self.status!=self.get_db_value("status") and self.status == "Closed":
|
||||
from frappe.desk.form.assign_to import clear
|
||||
clear(self.doctype, self.name)
|
||||
|
||||
def validate_dates(self):
|
||||
if self.exp_start_date and self.exp_end_date and getdate(self.exp_start_date) > getdate(self.exp_end_date):
|
||||
frappe.throw(_("'Expected Start Date' can not be greater than 'Expected End Date'"))
|
||||
@@ -41,17 +45,17 @@ class Task(Document):
|
||||
self.reschedule_dependent_tasks()
|
||||
self.update_percentage()
|
||||
self.update_project()
|
||||
|
||||
|
||||
def update_percentage(self):
|
||||
"""update percent complete in project"""
|
||||
if self.project and not self.flags.from_project:
|
||||
project = frappe.get_doc("Project", self.project)
|
||||
project.run_method("update_percent_complete")
|
||||
|
||||
|
||||
def update_total_expense_claim(self):
|
||||
self.total_expense_claim = frappe.db.sql("""select sum(total_sanctioned_amount) from `tabExpense Claim`
|
||||
self.total_expense_claim = frappe.db.sql("""select sum(total_sanctioned_amount) from `tabExpense Claim`
|
||||
where project = %s and task = %s and approval_status = "Approved" and docstatus=1""",(self.project, self.name))
|
||||
|
||||
|
||||
def update_time_and_costing(self):
|
||||
tl = frappe.db.sql("""select min(from_time) as start_date, max(to_time) as end_date,
|
||||
sum(billing_amount) as total_billing_amount, sum(costing_amount) as total_costing_amount,
|
||||
@@ -64,14 +68,14 @@ class Task(Document):
|
||||
self.actual_time= tl.time
|
||||
self.act_start_date= tl.start_date
|
||||
self.act_end_date= tl.end_date
|
||||
|
||||
|
||||
def update_project(self):
|
||||
if self.project and frappe.db.exists("Project", self.project):
|
||||
project = frappe.get_doc("Project", self.project)
|
||||
project.flags.dont_sync_tasks = True
|
||||
project.update_costing()
|
||||
project.save()
|
||||
|
||||
|
||||
def check_recursion(self):
|
||||
if self.flags.ignore_recursion_check: return
|
||||
check_list = [['task', 'parent'], ['parent', 'task']]
|
||||
@@ -88,7 +92,7 @@ class Task(Document):
|
||||
task_list.append(b[0])
|
||||
if count == 15:
|
||||
break
|
||||
|
||||
|
||||
def reschedule_dependent_tasks(self):
|
||||
end_date = self.exp_end_date or self.act_end_date
|
||||
if end_date:
|
||||
|
||||
@@ -11,19 +11,19 @@ from erpnext.projects.doctype.task.task import CircularReferenceError
|
||||
|
||||
class TestTask(unittest.TestCase):
|
||||
def test_circular_reference(self):
|
||||
|
||||
|
||||
task1 = frappe.new_doc('Task')
|
||||
task1.update({
|
||||
"status": "Open",
|
||||
"status": "Open",
|
||||
"subject": "_Test Task 1",
|
||||
"exp_start_date": "2015-1-1",
|
||||
"exp_end_date": "2015-1-10"
|
||||
})
|
||||
task1.save()
|
||||
|
||||
|
||||
task2 = frappe.new_doc('Task')
|
||||
task2.update({
|
||||
"status": "Open",
|
||||
"status": "Open",
|
||||
"subject": "_Test Task 2",
|
||||
"exp_start_date": "2015-1-11",
|
||||
"exp_end_date": "2015-1-15",
|
||||
@@ -34,10 +34,10 @@ class TestTask(unittest.TestCase):
|
||||
]
|
||||
})
|
||||
task2.save()
|
||||
|
||||
|
||||
task3 = frappe.new_doc('Task')
|
||||
task3.update({
|
||||
"status": "Open",
|
||||
"status": "Open",
|
||||
"subject": "_Test Task 2",
|
||||
"exp_start_date": "2015-1-11",
|
||||
"exp_end_date": "2015-1-15",
|
||||
@@ -53,13 +53,13 @@ class TestTask(unittest.TestCase):
|
||||
"task": task3.name
|
||||
})
|
||||
self.assertRaises(CircularReferenceError, task1.save)
|
||||
|
||||
|
||||
task1.set("depends_on", [])
|
||||
task1.save()
|
||||
|
||||
|
||||
task4 = frappe.new_doc('Task')
|
||||
task4.update({
|
||||
"status": "Open",
|
||||
"status": "Open",
|
||||
"subject": "_Test Task 1",
|
||||
"exp_start_date": "2015-1-1",
|
||||
"exp_end_date": "2015-1-15",
|
||||
@@ -74,20 +74,20 @@ class TestTask(unittest.TestCase):
|
||||
task3.append("depends_on", {
|
||||
"task": task4.name
|
||||
})
|
||||
|
||||
|
||||
def test_reschedule_dependent_task(self):
|
||||
task1 = frappe.new_doc('Task')
|
||||
task1.update({
|
||||
"status": "Open",
|
||||
"status": "Open",
|
||||
"subject": "_Test Task 1",
|
||||
"exp_start_date": "2015-1-1",
|
||||
"exp_end_date": "2015-1-10"
|
||||
})
|
||||
task1.save()
|
||||
|
||||
|
||||
task2 = frappe.new_doc('Task')
|
||||
task2.update({
|
||||
"status": "Open",
|
||||
"status": "Open",
|
||||
"subject": "_Test Task 2",
|
||||
"exp_start_date": "2015-1-11",
|
||||
"exp_end_date": "2015-1-15",
|
||||
@@ -98,10 +98,10 @@ class TestTask(unittest.TestCase):
|
||||
]
|
||||
})
|
||||
task2.save()
|
||||
|
||||
|
||||
task3 = frappe.new_doc('Task')
|
||||
task3.update({
|
||||
"status": "Open",
|
||||
"status": "Open",
|
||||
"subject": "_Test Task 3",
|
||||
"exp_start_date": "2015-1-16",
|
||||
"exp_end_date": "2015-1-18",
|
||||
@@ -112,18 +112,18 @@ class TestTask(unittest.TestCase):
|
||||
]
|
||||
})
|
||||
task3.save()
|
||||
|
||||
|
||||
task1.update({
|
||||
"exp_end_date": "2015-1-20"
|
||||
})
|
||||
task1.save()
|
||||
|
||||
|
||||
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_start_date"), getdate('2015-1-21'))
|
||||
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_end_date"), getdate('2015-1-25'))
|
||||
|
||||
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_start_date"), getdate('2015-1-26'))
|
||||
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_end_date"), getdate('2015-1-28'))
|
||||
|
||||
|
||||
time_log = frappe.new_doc('Time Log')
|
||||
time_log.update({
|
||||
"from_time": "2015-1-1",
|
||||
@@ -131,18 +131,49 @@ class TestTask(unittest.TestCase):
|
||||
"task": task1.name
|
||||
})
|
||||
time_log.submit()
|
||||
|
||||
|
||||
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_start_date"), getdate('2015-1-21'))
|
||||
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_end_date"), getdate('2015-1-25'))
|
||||
|
||||
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_start_date"), getdate('2015-1-26'))
|
||||
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_end_date"), getdate('2015-1-28'))
|
||||
|
||||
|
||||
time_log.cancel()
|
||||
|
||||
|
||||
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_start_date"), getdate('2015-1-21'))
|
||||
self.assertEqual(frappe.db.get_value("Task", task2.name, "exp_end_date"), getdate('2015-1-25'))
|
||||
|
||||
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_start_date"), getdate('2015-1-26'))
|
||||
self.assertEqual(frappe.db.get_value("Task", task3.name, "exp_end_date"), getdate('2015-1-28'))
|
||||
|
||||
|
||||
|
||||
def test_close_assignment(self):
|
||||
task = frappe.new_doc("Task")
|
||||
task.subject = "Test Close Assignment"
|
||||
task.insert()
|
||||
|
||||
def assign():
|
||||
from frappe.desk.form import assign_to
|
||||
assign_to.add({
|
||||
"assign_to": "test@example.com",
|
||||
"doctype": task.doctype,
|
||||
"name": task.name,
|
||||
"description": "Close this task"
|
||||
})
|
||||
|
||||
def get_owner_and_status():
|
||||
return frappe.db.get_value("ToDo", filters={"reference_type": task.doctype, "reference_name": task.name,
|
||||
"description": "Close this task"}, fieldname=("owner", "status"), as_dict=True)
|
||||
|
||||
assign()
|
||||
todo = get_owner_and_status()
|
||||
self.assertEquals(todo.owner, "test@example.com")
|
||||
self.assertEquals(todo.status, "Open")
|
||||
|
||||
# assignment should be
|
||||
task.load_from_db()
|
||||
task.status = "Closed"
|
||||
task.save()
|
||||
todo = get_owner_and_status()
|
||||
self.assertEquals(todo.owner, "test@example.com")
|
||||
self.assertEquals(todo.status, "Closed")
|
||||
|
||||
@@ -195,8 +195,6 @@ class TimeLog(Document):
|
||||
if self.for_manufacturing:
|
||||
if not self.production_order:
|
||||
frappe.throw(_("Production Order is Mandatory"))
|
||||
if not self.operation:
|
||||
frappe.throw(_("Operation is Mandatory"))
|
||||
if not self.completed_qty:
|
||||
self.completed_qty = 0
|
||||
|
||||
|
||||
@@ -105,6 +105,15 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
||||
}
|
||||
},
|
||||
|
||||
barcode: function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if(d.barcode=="" || d.barcode==null) {
|
||||
// barcode cleared, remove item
|
||||
d.item_code = "";
|
||||
}
|
||||
this.item_code(doc, cdt, cdn);
|
||||
},
|
||||
|
||||
item_code: function(doc, cdt, cdn) {
|
||||
var me = this;
|
||||
var item = frappe.get_doc(cdt, cdn);
|
||||
|
||||
@@ -81,7 +81,8 @@ erpnext.feature_setup.feature_dict = {
|
||||
'Item': {'fields': ['barcode']},
|
||||
'Delivery Note': {'items': ['barcode']},
|
||||
'Sales Invoice': {'items': ['barcode']},
|
||||
'Stock Entry': {'items': ['barcode']}
|
||||
'Stock Entry': {'items': ['barcode']},
|
||||
'Purchase Receipt': {'items': ['barcode']}
|
||||
},
|
||||
'fs_item_group_in_details': {
|
||||
'Delivery Note': {'items':['item_group']},
|
||||
|
||||
@@ -139,7 +139,7 @@ erpnext.StockAnalytics = erpnext.StockGridReport.extend({
|
||||
|
||||
if(sl.voucher_type=="Stock Reconciliation") {
|
||||
var diff = (sl.qty_after_transaction * sl.valuation_rate) - item.closing_qty_value;
|
||||
wh.fifo_stack.push([sl.qty_after_transaction, sl.valuation_rate, sl.posting_date]);
|
||||
wh.fifo_stack = [[sl.qty_after_transaction, sl.valuation_rate, sl.posting_date]];
|
||||
wh.balance_qty = sl.qty_after_transaction;
|
||||
wh.balance_value = sl.valuation_rate * sl.qty_after_transaction;
|
||||
} else {
|
||||
@@ -167,7 +167,6 @@ erpnext.StockAnalytics = erpnext.StockGridReport.extend({
|
||||
},
|
||||
update_groups: function() {
|
||||
var me = this;
|
||||
|
||||
$.each(this.data, function(i, item) {
|
||||
// update groups
|
||||
if(!item.is_group && me.apply_filter(item, "brand")) {
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"in_list_view": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Description",
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Small Text",
|
||||
@@ -298,12 +298,13 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "prevdoc_doctype",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"label": "Against Doctype",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "prevdoc_doctype",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_width": "150px",
|
||||
@@ -313,11 +314,12 @@
|
||||
},
|
||||
{
|
||||
"fieldname": "prevdoc_docname",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"label": "Against Docname",
|
||||
"no_copy": 1,
|
||||
"oldfieldname": "prevdoc_docname",
|
||||
"oldfieldtype": "Data",
|
||||
"options": "prevdoc_doctype",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_width": "150px",
|
||||
@@ -390,7 +392,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2015-05-27 02:47:15.474119",
|
||||
"modified": "2015-06-02 14:18:00.266748",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Quotation Item",
|
||||
|
||||
@@ -43,8 +43,8 @@ def get_so_details():
|
||||
|
||||
def get_last_so_amt(customer):
|
||||
res = frappe.db.sql("""select base_net_total from `tabSales Order`
|
||||
where customer ='%(customer)s' and docstatus = 1 order by transaction_date desc
|
||||
limit 1""" % {'customer': frappe.db.escape(customer)})
|
||||
where customer = %s and docstatus = 1 order by transaction_date desc
|
||||
limit 1""", customer)
|
||||
|
||||
return res and res[0][0] or 0
|
||||
|
||||
|
||||
@@ -124,15 +124,6 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
this.apply_pricing_rule();
|
||||
},
|
||||
|
||||
barcode: function(doc, cdt, cdn) {
|
||||
var d = locals[cdt][cdn];
|
||||
if(d.barcode=="" || d.barcode==null) {
|
||||
// barcode cleared, remove item
|
||||
d.item_code = "";
|
||||
}
|
||||
this.item_code(doc, cdt, cdn);
|
||||
},
|
||||
|
||||
selling_price_list: function() {
|
||||
this.apply_price_list();
|
||||
},
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
frappe.provide("erpnext.company");
|
||||
|
||||
frappe.ui.form.on("Company", {
|
||||
onload: function(frm) {
|
||||
erpnext.company.setup_queries(frm);
|
||||
},
|
||||
|
||||
onload_post_render: function(frm) {
|
||||
frm.get_field("delete_company_transactions").$input.addClass("btn-danger");
|
||||
},
|
||||
@@ -114,98 +118,43 @@ cur_frm.cscript.change_abbr = function() {
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.default_bank_account.get_query = function(doc) {
|
||||
return{
|
||||
filters: [
|
||||
['Account', 'account_type', '=', 'Bank'],
|
||||
['Account', 'is_group', '=', 0],
|
||||
['Account', 'company', '=', doc.name]
|
||||
]
|
||||
erpnext.company.setup_queries = function(frm) {
|
||||
$.each([
|
||||
["default_bank_account", {"account_type": "Bank"}],
|
||||
["default_cash_account", {"account_type": "Cash"}],
|
||||
["default_receivable_account", {"account_type": "Receivable"}],
|
||||
["default_payable_account", {"account_type": "Payable"}],
|
||||
["default_expense_account", {"root_type": "Expense"}],
|
||||
["default_income_account", {"root_type": "Income"}],
|
||||
["round_off_account", {"root_type": "Expense"}],
|
||||
["cost_center", {}],
|
||||
["round_off_cost_center", {}]
|
||||
], function(i, v) {
|
||||
erpnext.company.set_custom_query(frm, v);
|
||||
});
|
||||
|
||||
if (sys_defaults.auto_accounting_for_stock) {
|
||||
$.each([
|
||||
["stock_adjustment_account", {"root_type": "Expense"}],
|
||||
["expenses_included_in_valuation", {"root_type": "Expense"}],
|
||||
["stock_received_but_not_billed", {"report_type": "Balance Sheet"}]
|
||||
], function(i, v) {
|
||||
erpnext.company.set_custom_query(frm, v);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.default_cash_account.get_query = function(doc) {
|
||||
return{
|
||||
filters: [
|
||||
['Account', 'account_type', '=', 'Cash'],
|
||||
['Account', 'is_group', '=', 0],
|
||||
['Account', 'company', '=', doc.name]
|
||||
]
|
||||
}
|
||||
}
|
||||
erpnext.company.set_custom_query = function(frm, v) {
|
||||
var filters = {
|
||||
"company": frm.doc.name,
|
||||
"is_group": 0
|
||||
};
|
||||
for (var key in v[1])
|
||||
filters[key] = v[1][key];
|
||||
|
||||
cur_frm.fields_dict.default_receivable_account.get_query = function(doc) {
|
||||
return{
|
||||
filters:{
|
||||
'company': doc.name,
|
||||
"is_group": 0,
|
||||
"account_type": "Receivable"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.default_payable_account.get_query = function(doc) {
|
||||
return{
|
||||
filters:{
|
||||
'company': doc.name,
|
||||
"is_group": 0,
|
||||
"account_type": "Payable"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
cur_frm.fields_dict.default_expense_account.get_query = function(doc) {
|
||||
return{
|
||||
filters:{
|
||||
'company': doc.name,
|
||||
"is_group": 0,
|
||||
"report_type": "Profit and Loss"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.default_income_account.get_query = function(doc) {
|
||||
return{
|
||||
filters:{
|
||||
'company': doc.name,
|
||||
"is_group": 0,
|
||||
"report_type": "Profit and Loss"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict.cost_center.get_query = function(doc) {
|
||||
return{
|
||||
filters:{
|
||||
'company': doc.name,
|
||||
"is_group": 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sys_defaults.auto_accounting_for_stock) {
|
||||
cur_frm.fields_dict["stock_adjustment_account"].get_query = function(doc) {
|
||||
frm.set_query(v[0], function() {
|
||||
return {
|
||||
"filters": {
|
||||
"report_type": "Profit and Loss",
|
||||
"company": doc.name,
|
||||
"is_group": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_frm.fields_dict["expenses_included_in_valuation"].get_query =
|
||||
cur_frm.fields_dict["stock_adjustment_account"].get_query;
|
||||
|
||||
cur_frm.fields_dict["stock_received_but_not_billed"].get_query = function(doc) {
|
||||
return {
|
||||
"filters": {
|
||||
"report_type": "Balance Sheet",
|
||||
"company": doc.name,
|
||||
"is_group": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
filters: filters
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -170,6 +170,15 @@
|
||||
"permlevel": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "round_off_account",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 0,
|
||||
"label": "Round Off Account",
|
||||
"options": "Account",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break0",
|
||||
"fieldtype": "Column Break",
|
||||
@@ -211,6 +220,15 @@
|
||||
"options": "Account",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "round_off_cost_center",
|
||||
"fieldtype": "Link",
|
||||
"ignore_user_permissions": 0,
|
||||
"label": "Round Off Cost Center",
|
||||
"options": "Cost Center",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_22",
|
||||
"fieldtype": "Section Break",
|
||||
@@ -414,7 +432,7 @@
|
||||
],
|
||||
"icon": "icon-building",
|
||||
"idx": 1,
|
||||
"modified": "2015-05-19 02:00:41.055138",
|
||||
"modified": "2015-05-28 12:56:18.175509",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Setup",
|
||||
"name": "Company",
|
||||
|
||||
@@ -114,6 +114,7 @@ class Company(Document):
|
||||
def set_default_accounts(self):
|
||||
self._set_default_account("default_cash_account", "Cash")
|
||||
self._set_default_account("default_bank_account", "Bank")
|
||||
self._set_default_account("round_off_account", "Round Off")
|
||||
|
||||
if cint(frappe.db.get_single_value("Accounts Settings", "auto_accounting_for_stock")):
|
||||
self._set_default_account("stock_received_but_not_billed", "Stock Received But Not Billed")
|
||||
@@ -161,6 +162,7 @@ class Company(Document):
|
||||
cc_doc.insert()
|
||||
|
||||
frappe.db.set(self, "cost_center", _("Main") + " - " + self.abbr)
|
||||
frappe.db.set(self, "round_off_cost_center", _("Main") + " - " + self.abbr)
|
||||
|
||||
def before_rename(self, olddn, newdn, merge=False):
|
||||
if merge:
|
||||
|
||||
@@ -27,12 +27,7 @@ def delete_for_doctype(doctype, company_name):
|
||||
company_fieldname = meta.get("fields", {"fieldtype": "Link",
|
||||
"options": "Company"})[0].fieldname
|
||||
|
||||
if meta.issingle:
|
||||
single = frappe.get_doc(doctype, doctype)
|
||||
single.set(company_fieldname, "")
|
||||
single.flags.ignore_mandatory = True
|
||||
single.save()
|
||||
else:
|
||||
if not meta.issingle:
|
||||
if not meta.istable:
|
||||
# delete children
|
||||
for df in meta.get_table_fields():
|
||||
|
||||
@@ -12,7 +12,6 @@ from frappe.model.document import Document
|
||||
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'""")
|
||||
|
||||
167
erpnext/setup/fixtures/web_form/addresses.json
Normal file
167
erpnext/setup/fixtures/web_form/addresses.json
Normal file
@@ -0,0 +1,167 @@
|
||||
[
|
||||
{
|
||||
"allow_comments": 0,
|
||||
"allow_delete": 0,
|
||||
"allow_edit": 1,
|
||||
"allow_multiple": 1,
|
||||
"breadcrumbs": null,
|
||||
"doc_type": "Address",
|
||||
"docstatus": 0,
|
||||
"doctype": "Web Form",
|
||||
"introduction_text": null,
|
||||
"login_required": 1,
|
||||
"modified": "2015-06-01 06:53:43.699336",
|
||||
"name": "addresses",
|
||||
"page_name": "addresses",
|
||||
"published": 1,
|
||||
"success_message": null,
|
||||
"success_url": "/addresses",
|
||||
"title": "Addresses",
|
||||
"web_form_fields": [
|
||||
{
|
||||
"default": null,
|
||||
"description": "",
|
||||
"fieldname": "address_title",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"label": "Address Title",
|
||||
"options": null,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"default": null,
|
||||
"description": null,
|
||||
"fieldname": "address_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"label": "Address Type",
|
||||
"options": "Billing\nShipping\nOffice\nPersonal\nPlant\nPostal\nShop\nSubsidiary\nWarehouse\nOther",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": null,
|
||||
"description": null,
|
||||
"fieldname": "address_line1",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"label": "Address Line 1",
|
||||
"options": null,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": null,
|
||||
"description": null,
|
||||
"fieldname": "address_line2",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"label": "Address Line 2",
|
||||
"options": null,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"default": null,
|
||||
"description": null,
|
||||
"fieldname": "city",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"label": "City/Town",
|
||||
"options": null,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": null,
|
||||
"description": null,
|
||||
"fieldname": "state",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"label": "State",
|
||||
"options": null,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"default": null,
|
||||
"description": null,
|
||||
"fieldname": "pincode",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"label": "Pincode",
|
||||
"options": null,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"default": null,
|
||||
"description": null,
|
||||
"fieldname": "country",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"label": "Country",
|
||||
"options": "Country",
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": null,
|
||||
"description": null,
|
||||
"fieldname": null,
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": null,
|
||||
"label": null,
|
||||
"options": null,
|
||||
"read_only": null,
|
||||
"reqd": null
|
||||
},
|
||||
{
|
||||
"default": null,
|
||||
"description": null,
|
||||
"fieldname": "email_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"label": "Email Id",
|
||||
"options": null,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"default": null,
|
||||
"description": null,
|
||||
"fieldname": "phone",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"label": "Phone",
|
||||
"options": null,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "",
|
||||
"fieldname": "is_primary_address",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"label": "Preferred Billing Address",
|
||||
"options": null,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"description": "",
|
||||
"fieldname": "is_shipping_address",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"label": "Preferred Shipping Address",
|
||||
"options": null,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
}
|
||||
],
|
||||
"web_page_link_text": null
|
||||
}
|
||||
]
|
||||
68
erpnext/setup/fixtures/web_form/issues.json
Normal file
68
erpnext/setup/fixtures/web_form/issues.json
Normal file
@@ -0,0 +1,68 @@
|
||||
[
|
||||
{
|
||||
"allow_comments": 1,
|
||||
"allow_delete": 1,
|
||||
"allow_edit": 1,
|
||||
"allow_multiple": 1,
|
||||
"breadcrumbs": "[{\"title\":\"Issues\", \"name\":\"issues\"}]",
|
||||
"doc_type": "Issue",
|
||||
"docstatus": 0,
|
||||
"doctype": "Web Form",
|
||||
"introduction_text": null,
|
||||
"login_required": 1,
|
||||
"modified": "2015-06-01 08:14:26.350792",
|
||||
"name": "issues",
|
||||
"page_name": "issues",
|
||||
"published": 1,
|
||||
"success_message": "",
|
||||
"success_url": "/issues",
|
||||
"title": "Issues",
|
||||
"web_form_fields": [
|
||||
{
|
||||
"default": null,
|
||||
"description": null,
|
||||
"fieldname": "subject",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"label": "Subject",
|
||||
"options": null,
|
||||
"read_only": 0,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "Open",
|
||||
"description": null,
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"hidden": null,
|
||||
"label": "Status",
|
||||
"options": "Open\nReplied\nHold\nClosed",
|
||||
"read_only": 1,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"default": null,
|
||||
"description": null,
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 0,
|
||||
"label": "Description",
|
||||
"options": null,
|
||||
"read_only": 0,
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"default": null,
|
||||
"description": null,
|
||||
"fieldname": "attachment",
|
||||
"fieldtype": "Attach",
|
||||
"hidden": null,
|
||||
"label": "Attachment",
|
||||
"options": null,
|
||||
"read_only": null,
|
||||
"reqd": null
|
||||
}
|
||||
],
|
||||
"web_page_link_text": null
|
||||
}
|
||||
]
|
||||
@@ -15,6 +15,7 @@ def after_install():
|
||||
feature_setup()
|
||||
from erpnext.setup.page.setup_wizard.setup_wizard import add_all_roles_to
|
||||
add_all_roles_to("Administrator")
|
||||
add_web_forms()
|
||||
frappe.db.commit()
|
||||
|
||||
def feature_setup():
|
||||
@@ -48,3 +49,12 @@ def set_single_defaults():
|
||||
pass
|
||||
|
||||
frappe.db.set_default("date_format", "dd-mm-yyyy")
|
||||
|
||||
def add_web_forms():
|
||||
"""Import web forms for Issues and Addresses"""
|
||||
from frappe.modules.import_file import import_file_by_path
|
||||
|
||||
import_file_by_path(frappe.get_app_path("erpnext", "setup/fixtures/web_form/issues.json"),
|
||||
data_import=True)
|
||||
import_file_by_path(frappe.get_app_path("erpnext", "setup/fixtures/web_form/addresses.json"),
|
||||
data_import=True)
|
||||
|
||||
@@ -215,6 +215,7 @@ $.extend(erpnext.wiz, {
|
||||
|
||||
slide.get_field("language")
|
||||
.set_input(erpnext.wiz.welcome.data.default_language || "english");
|
||||
moment.locale("en");
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -5,17 +5,18 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import throw, _
|
||||
import frappe.defaults
|
||||
from frappe.utils import flt, get_fullname, fmt_money, cstr
|
||||
from frappe.utils import cint, flt, get_fullname, fmt_money, cstr
|
||||
from erpnext.utilities.doctype.address.address import get_address_display
|
||||
from frappe.utils.nestedset import get_root_of
|
||||
|
||||
class WebsitePriceListMissingError(frappe.ValidationError): pass
|
||||
|
||||
def set_cart_count(quotation=None):
|
||||
if not quotation:
|
||||
quotation = _get_cart_quotation()
|
||||
cart_count = cstr(len(quotation.get("items")))
|
||||
frappe.local.cookie_manager.set_cookie("cart_count", cart_count)
|
||||
if cint(frappe.db.get_singles_value("Shopping Cart Settings", "enabled")):
|
||||
if not quotation:
|
||||
quotation = _get_cart_quotation()
|
||||
cart_count = cstr(len(quotation.get("items")))
|
||||
frappe.local.cookie_manager.set_cookie("cart_count", cart_count)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_cart_quotation(doc=None):
|
||||
@@ -29,7 +30,7 @@ def get_cart_quotation(doc=None):
|
||||
return {
|
||||
"doc": decorate_quotation_doc(doc),
|
||||
"addresses": [{"name": address.name, "display": address.display}
|
||||
for address in get_address_docs(party)],
|
||||
for address in get_address_docs(party=party)],
|
||||
"shipping_rules": get_applicable_shipping_rules(party)
|
||||
}
|
||||
|
||||
@@ -281,12 +282,13 @@ def get_lead_or_customer():
|
||||
|
||||
return lead_doc
|
||||
|
||||
def get_address_docs(party=None):
|
||||
def get_address_docs(doctype=None, txt=None, filters=None, limit_start=0, limit_page_length=20, party=None):
|
||||
if not party:
|
||||
party = get_lead_or_customer()
|
||||
|
||||
address_docs = frappe.db.sql("""select * from `tabAddress`
|
||||
where `%s`=%s order by name""" % (party.doctype.lower(), "%s"), party.name,
|
||||
where `{0}`=%s order by name limit {1}, {2}""".format(party.doctype.lower(),
|
||||
limit_start, limit_page_length), party.name,
|
||||
as_dict=True, update={"doctype": "Address"})
|
||||
|
||||
for address in address_docs:
|
||||
|
||||
@@ -8,7 +8,7 @@ import frappe
|
||||
from frappe import _, msgprint
|
||||
from frappe.utils import comma_and
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils.nestedset import get_ancestors_of
|
||||
from frappe.utils.nestedset import get_ancestors_of, get_root_of
|
||||
from erpnext.utilities.doctype.address.address import get_territory_from_address
|
||||
|
||||
class ShoppingCartSetupError(frappe.ValidationError): pass
|
||||
@@ -42,7 +42,7 @@ class ShoppingCartSettings(Document):
|
||||
return territory_name_map
|
||||
|
||||
def validate_price_lists(self):
|
||||
territory_name_map = self.validate_overlapping_territories("price_lists", "selling_price_list")
|
||||
self.validate_overlapping_territories("price_lists", "selling_price_list")
|
||||
|
||||
# validate that a Shopping Cart Price List exists for the default territory as a catch all!
|
||||
price_list_for_default_territory = self.get_name_from_territory(self.default_territory, "price_lists",
|
||||
@@ -131,7 +131,8 @@ class ShoppingCartSettings(Document):
|
||||
def get_price_list(self, billing_territory):
|
||||
price_list = self.get_name_from_territory(billing_territory, "price_lists", "selling_price_list")
|
||||
if not (price_list and price_list[0]):
|
||||
price_list = self.get_name_from_territory(self.default_territory, "price_lists", "selling_price_list")
|
||||
price_list = self.get_name_from_territory(self.default_territory or get_root_of("Territory"),
|
||||
"price_lists", "selling_price_list")
|
||||
|
||||
return price_list and price_list[0] or None
|
||||
|
||||
@@ -165,7 +166,7 @@ def is_cart_enabled():
|
||||
return get_shopping_cart_settings().enabled
|
||||
|
||||
def get_default_territory():
|
||||
return get_shopping_cart_settings().default_territory
|
||||
return get_shopping_cart_settings().default_territory or get_root_of("Territory")
|
||||
|
||||
def check_shopping_cart_enabled():
|
||||
if not get_shopping_cart_settings().enabled:
|
||||
|
||||
@@ -6,7 +6,6 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
import frappe.defaults
|
||||
from frappe.utils import cint
|
||||
from erpnext.shopping_cart.doctype.shopping_cart_settings.shopping_cart_settings import is_cart_enabled
|
||||
|
||||
def show_cart_count():
|
||||
@@ -44,6 +43,6 @@ def update_my_account_context(context):
|
||||
{"label": _("Orders"), "url": "orders"},
|
||||
{"label": _("Invoices"), "url": "invoices"},
|
||||
{"label": _("Shipments"), "url": "shipments"},
|
||||
# {"label": _("Issues"), "url": "tickets"},
|
||||
{"label": _("Issues"), "url": "issues"},
|
||||
{"label": _("Addresses"), "url": "addresses"},
|
||||
])
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Small Text",
|
||||
"in_list_view": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Description",
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Small Text",
|
||||
@@ -523,7 +523,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2015-05-27 02:47:16.946934",
|
||||
"modified": "2015-06-02 14:18:34.512236",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Delivery Note Item",
|
||||
|
||||
@@ -90,7 +90,7 @@ class TestItem(unittest.TestCase):
|
||||
"income_account": "Sales - _TC",
|
||||
"expense_account": "_Test Account Cost for Goods Sold - _TC",
|
||||
"cost_center": "_Test Cost Center 2 - _TC",
|
||||
"qty": 0.0,
|
||||
"qty": 1.0,
|
||||
"price_list_rate": 100.0,
|
||||
"base_price_list_rate": 0.0,
|
||||
"discount_percentage": 0.0,
|
||||
|
||||
@@ -221,7 +221,7 @@
|
||||
"icon": "icon-ticket",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2015-05-27 15:36:06.818491",
|
||||
"modified": "2015-06-09 05:47:05.934432",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Material Request",
|
||||
|
||||
@@ -6,7 +6,13 @@ frappe.listview_settings['Material Request'] = {
|
||||
} else if(doc.docstatus==1 && flt(doc.per_ordered) < 100) {
|
||||
return [__("Pending"), "orange", "per_ordered,<,100"];
|
||||
} else if(doc.docstatus==1 && flt(doc.per_ordered) == 100) {
|
||||
return [__("Ordered"), "green", "per_ordered,=,100"];
|
||||
if (doc.material_request_type == "Purchase") {
|
||||
return [__("Ordered"), "green", "per_ordered,=,100"];
|
||||
} else if (doc.material_request_type == "Material Transfer") {
|
||||
return [__("Transfered"), "green", "per_ordered,=,100"];
|
||||
} else if (doc.material_request_type == "Material Issue") {
|
||||
return [__("Issued"), "green", "per_ordered,=,100"];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text",
|
||||
"in_list_view": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Description",
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Text",
|
||||
@@ -264,7 +264,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2015-02-19 01:07:00.695393",
|
||||
"modified": "2015-06-02 14:19:45.611733",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Material Request Item",
|
||||
|
||||
@@ -4,6 +4,19 @@
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "barcode",
|
||||
"fieldtype": "Data",
|
||||
"label": "Barcode",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_2",
|
||||
"fieldtype": "Section Break",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
},
|
||||
{
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
@@ -49,7 +62,7 @@
|
||||
{
|
||||
"fieldname": "description",
|
||||
"fieldtype": "Text",
|
||||
"in_list_view": 1,
|
||||
"in_list_view": 0,
|
||||
"label": "Description",
|
||||
"oldfieldname": "description",
|
||||
"oldfieldtype": "Text",
|
||||
@@ -642,7 +655,7 @@
|
||||
],
|
||||
"idx": 1,
|
||||
"istable": 1,
|
||||
"modified": "2015-05-27 02:47:16.086625",
|
||||
"modified": "2015-06-08 08:21:18.024324",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Purchase Receipt Item",
|
||||
|
||||
@@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe.defaults
|
||||
|
||||
from frappe.utils import cstr, cint, flt, comma_or, nowdate, get_datetime
|
||||
from frappe.utils import cstr, cint, flt, comma_or, get_datetime
|
||||
|
||||
from frappe import _
|
||||
from erpnext.stock.utils import get_incoming_rate
|
||||
@@ -185,11 +185,16 @@ class StockEntry(StockController):
|
||||
|
||||
def validate_production_order(self):
|
||||
if self.purpose in ("Manufacture", "Material Transfer for Manufacture"):
|
||||
if not self.bom_no:
|
||||
frappe.throw(_("BOM No is mandatory"))
|
||||
|
||||
# check if production order is entered
|
||||
if not self.production_order:
|
||||
frappe.throw(_("Production order number is mandatory for stock entry purpose manufacture"))
|
||||
# check for double entry
|
||||
if self.purpose=="Manufacture":
|
||||
if not self.fg_completed_qty:
|
||||
frappe.throw(_("For Quantity (Manufactured Qty) is mandatory"))
|
||||
self.check_if_operations_completed()
|
||||
self.check_duplicate_entry_for_production_order()
|
||||
elif self.purpose != "Material Transfer":
|
||||
@@ -378,10 +383,21 @@ class StockEntry(StockController):
|
||||
|
||||
def validate_finished_goods(self):
|
||||
"""validation: finished good quantity should be same as manufacturing quantity"""
|
||||
items_with_target_warehouse = []
|
||||
for d in self.get('items'):
|
||||
if d.bom_no and flt(d.transfer_qty) != flt(self.fg_completed_qty):
|
||||
frappe.throw(_("Quantity in row {0} ({1}) must be same as manufactured quantity {2}"). \
|
||||
format(d.idx, d.transfer_qty, self.fg_completed_qty))
|
||||
|
||||
if self.production_order and self.purpose == "Manufacture" and d.t_warehouse:
|
||||
items_with_target_warehouse.append(d.item_code)
|
||||
|
||||
if self.production_order and self.purpose == "Manufacture":
|
||||
production_item = frappe.db.get_value("Production Order",
|
||||
self.production_order, "production_item")
|
||||
if production_item not in items_with_target_warehouse:
|
||||
frappe.throw(_("Finished Item {0} must be entered for Manufacture type entry")
|
||||
.format(production_item))
|
||||
|
||||
def validate_return_reference_doc(self):
|
||||
"""validate item with reference doc"""
|
||||
@@ -399,7 +415,6 @@ class StockEntry(StockController):
|
||||
|
||||
# posting date check
|
||||
ref_posting_datetime = "%s %s" % (ref.doc.posting_date, ref.doc.posting_time or "00:00:00")
|
||||
this_posting_datetime = "%s %s" % (self.posting_date, self.posting_time)
|
||||
|
||||
if get_datetime(ref_posting_datetime) < get_datetime(ref_posting_datetime):
|
||||
from frappe.utils.dateutils import datetime_in_user_format
|
||||
@@ -474,9 +489,10 @@ class StockEntry(StockController):
|
||||
pro_doc = frappe.get_doc("Production Order", self.production_order)
|
||||
_validate_production_order(pro_doc)
|
||||
pro_doc.run_method("update_status")
|
||||
pro_doc.run_method("update_production_order_qty")
|
||||
if self.purpose == "Manufacture":
|
||||
self.update_planned_qty(pro_doc)
|
||||
if self.fg_completed_qty:
|
||||
pro_doc.run_method("update_production_order_qty")
|
||||
if self.purpose == "Manufacture":
|
||||
self.update_planned_qty(pro_doc)
|
||||
|
||||
def update_planned_qty(self, pro_doc):
|
||||
from erpnext.stock.utils import update_bin
|
||||
@@ -546,9 +562,6 @@ class StockEntry(StockController):
|
||||
return ret
|
||||
|
||||
def get_items(self):
|
||||
if not self.fg_completed_qty or not self.bom_no:
|
||||
frappe.throw(_("BOM and Manufacturing Quantity are required"))
|
||||
|
||||
self.set('items', [])
|
||||
self.validate_production_order()
|
||||
|
||||
@@ -638,17 +651,16 @@ class StockEntry(StockController):
|
||||
issued_item_qty = self.get_issued_qty()
|
||||
|
||||
max_qty = flt(self.pro_doc.qty)
|
||||
only_pending_fetched = []
|
||||
|
||||
for item in item_dict:
|
||||
pending_to_issue = (max_qty * item_dict[item]["qty"]) - issued_item_qty.get(item, 0)
|
||||
desire_to_transfer = flt(self.fg_completed_qty) * item_dict[item]["qty"]
|
||||
|
||||
if desire_to_transfer <= pending_to_issue:
|
||||
item_dict[item]["qty"] = desire_to_transfer
|
||||
else:
|
||||
elif pending_to_issue > 0:
|
||||
item_dict[item]["qty"] = pending_to_issue
|
||||
if pending_to_issue:
|
||||
only_pending_fetched.append(item)
|
||||
else:
|
||||
item_dict[item]["qty"] = 0
|
||||
|
||||
# delete items with 0 qty
|
||||
for item in item_dict.keys():
|
||||
@@ -659,9 +671,6 @@ class StockEntry(StockController):
|
||||
if not len(item_dict):
|
||||
frappe.msgprint(_("""All items have already been transferred for this Production Order."""))
|
||||
|
||||
elif only_pending_fetched:
|
||||
frappe.msgprint(_("Pending Items {0} updated").format(only_pending_fetched))
|
||||
|
||||
return item_dict
|
||||
|
||||
def get_issued_qty(self):
|
||||
|
||||
@@ -163,8 +163,8 @@ def get_basic_details(args, item):
|
||||
"uom": item.stock_uom,
|
||||
"min_order_qty": flt(item.min_order_qty) if args.parenttype == "Material Request" else "",
|
||||
"conversion_factor": 1.0,
|
||||
"qty": args.qty or 0.0,
|
||||
"stock_qty": 0.0,
|
||||
"qty": args.qty or 1.0,
|
||||
"stock_qty": 1.0,
|
||||
"price_list_rate": 0.0,
|
||||
"base_price_list_rate": 0.0,
|
||||
"rate": 0.0,
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
"oldfieldtype": "Data",
|
||||
"options": "Email",
|
||||
"permlevel": 0,
|
||||
"reqd": 1
|
||||
"reqd": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "fold",
|
||||
@@ -229,11 +229,19 @@
|
||||
"hidden": 1,
|
||||
"label": "Content Type",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "attachment",
|
||||
"fieldtype": "Attach",
|
||||
"hidden": 1,
|
||||
"label": "Attachment",
|
||||
"permlevel": 0,
|
||||
"precision": ""
|
||||
}
|
||||
],
|
||||
"icon": "icon-ticket",
|
||||
"idx": 1,
|
||||
"modified": "2015-05-28 03:21:04.690112",
|
||||
"modified": "2015-06-01 08:14:01.750421",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Support",
|
||||
"name": "Issue",
|
||||
|
||||
@@ -17,6 +17,8 @@ class Issue(Document):
|
||||
return "{0}: {1}".format(_(self.status), self.subject)
|
||||
|
||||
def validate(self):
|
||||
if not self.raised_by:
|
||||
self.raised_by = frappe.session.user
|
||||
self.update_status()
|
||||
self.set_lead_contact(self.raised_by)
|
||||
|
||||
@@ -54,7 +56,8 @@ class Issue(Document):
|
||||
def get_list_context(context=None):
|
||||
return {
|
||||
"title": _("My Issues"),
|
||||
"get_list": get_issue_list
|
||||
"get_list": get_issue_list,
|
||||
"row_template": "templates/includes/issue_row.html"
|
||||
}
|
||||
|
||||
def get_issue_list(doctype, txt, filters, limit_start, limit_page_length=20):
|
||||
@@ -84,3 +87,6 @@ def set_multiple_status(names, status):
|
||||
names = json.loads(names)
|
||||
for name in names:
|
||||
set_status(name, status)
|
||||
|
||||
def has_website_permission(doc, ptype, user, verbose=False):
|
||||
return doc.raised_by==user
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% $.each(visible_columns || [], function(i, df) { %}
|
||||
{% var val = doc.get_formatted(df.fieldname);
|
||||
if((df.fieldname !== "description") && val) { %}
|
||||
if((df.fieldname !== "description" && df.fieldname !== "item_name") && val) { %}
|
||||
<div class="row">
|
||||
<div class="col-xs-4 text-ellipsis">
|
||||
<strong title="{%= __(df.label) %}">{%= __(df.label) %}:</strong>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{% var visible_columns = row.get_visible_columns(["item_code", "item_name", "description", "qty", "rate", "amount", "stock_uom", "uom", "discount_percentage", "schedule_date", "warehouse", "against_sales_order", "sales_order"]); %}
|
||||
{% var visible_columns = row.get_visible_columns(["item_code", "qty", "rate", "amount", "stock_uom", "uom", "discount_percentage", "schedule_date", "warehouse", "against_sales_order", "sales_order"]); %}
|
||||
|
||||
{% if(!doc) { %}
|
||||
<div class="row">
|
||||
@@ -8,6 +8,7 @@
|
||||
<div class="col-sm-2 col-xs-4 text-right">{%= __("Amount") %}</div>
|
||||
</div>
|
||||
{% } else { %}
|
||||
{% var visible_column_fieldnames = $.map(visible_columns, function(x, i) {return x.fieldname}); %}
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-xs-8">
|
||||
{% if(doc.warehouse) {
|
||||
@@ -45,8 +46,14 @@
|
||||
<strong>{%= doc.item_code %}</strong>
|
||||
{% } %}
|
||||
|
||||
{% if(doc.item_name != doc.item_code) { %}
|
||||
{% if(doc.item_name != doc.item_code && in_list(visible_column_fieldnames, "item_name")) { %}
|
||||
<br>{%= doc.item_name %}{% } %}
|
||||
|
||||
{% if((doc.description != doc.item_code != doc.item_name) &&
|
||||
in_list(visible_column_fieldnames, "description")) { %}
|
||||
<br>
|
||||
<strong>Description: </strong>
|
||||
{%= doc.get_formatted("description") %}{% } %}
|
||||
{% include "templates/form_grid/includes/visible_cols.html" %}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% var visible_columns = row.get_visible_columns(["item_code", "warehouse",
|
||||
"item_name", "description", "amount", "stock_uom", "uom", "qty", "schedule_date"]); %}
|
||||
"item_name", "amount", "stock_uom", "uom", "qty", "schedule_date"]); %}
|
||||
|
||||
{% if(!doc) { %}
|
||||
<div class="row">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% var visible_columns = row.get_visible_columns(["item_code",
|
||||
"item_name", "description", "amount", "stock_uom", "uom", "qty",
|
||||
"item_name", "amount", "stock_uom", "uom", "qty",
|
||||
"s_warehouse", "t_warehouse", "incoming_rate"]);
|
||||
%}
|
||||
|
||||
|
||||
@@ -2,10 +2,13 @@
|
||||
|
||||
{% block header %}<h2>{{ title }}</h2>{% endblock %}
|
||||
|
||||
{% block header_actions %}
|
||||
{% include 'templates/includes/product_search_box.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% from "erpnext/templates/includes/macros.html" import product_image %}
|
||||
<div class="item-content">
|
||||
{% include 'templates/includes/product_search_box.html' %}
|
||||
<div class="product-page-content" itemscope itemtype="http://schema.org/Product">
|
||||
<div class="row">
|
||||
<div class="col-sm-5">
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
{% block header_actions %}
|
||||
{% include 'templates/includes/product_search_box.html' %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="item-group-content">
|
||||
{% include 'templates/includes/product_search_box.html' %}
|
||||
<div>
|
||||
{% if slideshow %}<!-- slideshow -->
|
||||
{% include "templates/includes/slideshow.html" %}
|
||||
|
||||
20
erpnext/templates/includes/address_row.html
Normal file
20
erpnext/templates/includes/address_row.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<div class="web-list-item">
|
||||
<a href="/addresses?name={{ doc.name }}" no-pjax>
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<span class="strong">{{ doc.address_title }}</span>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
{{ doc.address_type }}
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
{{ doc.address_line1 }}<br>
|
||||
{% if doc.address_line2 %}{{ doc.address_line2 }}<br>{% endif %}
|
||||
{{ doc.city }}<br>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
{% if doc.state %}{{ doc.state }}, {% endif %}{{ doc.country }}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
16
erpnext/templates/includes/issue_row.html
Normal file
16
erpnext/templates/includes/issue_row.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<div class="web-list-item">
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<a class="no-decoration" href="/issues?name={{ doc.name }}" no-pjax>
|
||||
{{ doc.subject }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<span class="indicator {{ "red" if doc.status=="Open" else "blue" }}">
|
||||
{{ doc.status }}</span>
|
||||
</div>
|
||||
<div class="col-sm-2 text-muted text-right small">
|
||||
{{ frappe.format_date(doc.creation) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,6 +1,6 @@
|
||||
{% from "erpnext/templates/includes/macros.html" import product_image_square %}
|
||||
|
||||
<a class="product-link" href="{{ (route or page_name)|with_leading_slash }}">
|
||||
<a class="product-link" href="{{ (route or page_name)|abs_url }}">
|
||||
<div class="col-sm-2 col-xs-4 product-image-wrapper">
|
||||
{{ product_image_square(website_image) }}
|
||||
<div class="text-ellipsis inline-block small product-text">{{ item_name }}</div>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<!-- TODO product listing -->
|
||||
<div class="container content">
|
||||
<div style="height: 120px; overflow: hidden;">
|
||||
<a href="{{ (route or page_name)|with_leading_slash }}">
|
||||
<a href="{{ (route or page_name)|abs_url }}">
|
||||
{%- if website_image -%}
|
||||
<img class="product-image" style="width: 80%; margin: auto;" src="{{ website_image|with_leading_slash }}">
|
||||
<img class="product-image" style="width: 80%; margin: auto;" src="{{ website_image|abs_url }}">
|
||||
{%- else -%}
|
||||
<div style="width: 80%; height: 120px; background-color: #F7FAFC;"></div>
|
||||
{%- endif -%}
|
||||
</a>
|
||||
</div>
|
||||
<div style="height: 100px; overflow: hidden; font-size: 80%;">
|
||||
<div><a href="{{ (route or page_name)|with_leading_slash }}">{{ item_name }}</a></div>
|
||||
<div><a href="{{ (route or page_name)|abs_url }}">{{ item_name }}</a></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
<div class="product-search pull-right">
|
||||
<form class="form-inline form-search">
|
||||
<div class="input-group">
|
||||
<input class="form-control" type="text" id="product-search"
|
||||
placeholder="Product Search...">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="button" id="btn-product-search">
|
||||
<i class="icon-search"></i></button>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<script>
|
||||
frappe.ready(function() {
|
||||
$(".product-search").remove();
|
||||
|
||||
$('<div class="product-search pull-right">\
|
||||
<form class="form-inline form-search">\
|
||||
<div class="input-group">\
|
||||
<input class="form-control" type="text" id="product-search" placeholder="Product Search...">\
|
||||
<span class="input-group-btn">\
|
||||
<button class="btn btn-default" type="button" id="btn-product-search">\
|
||||
<i class="icon-search"></i></button>\
|
||||
</span>\
|
||||
</div>\
|
||||
</form>\
|
||||
</div>').prependTo(".page-header-block");
|
||||
|
||||
$('.dropdown-toggle').dropdown();
|
||||
$("#btn-product-search").click(function() {
|
||||
var txt = $("#product-search").val();
|
||||
if(txt) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{% set doc = frappe.get_doc(doc) %}
|
||||
<a class="website-list-row" href="/{{ pathname }}/{{ doc.name }}" no-pjax>
|
||||
<div class="web-list-item">
|
||||
<a href="/{{ pathname }}/{{ doc.name }}" no-pjax>
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-xs-7">
|
||||
<div class="row">
|
||||
@@ -12,7 +13,7 @@
|
||||
<span class="indicator orange">{{ doc.status_display }}</span>
|
||||
{%- endif -%}
|
||||
{%- elif doc.status -%}
|
||||
<span class="indicator">{{ doc.status }}</span>
|
||||
<span class="indicator blue">{{ doc.status }}</span>
|
||||
{%- endif -%}
|
||||
</div>
|
||||
</div>
|
||||
@@ -27,4 +28,4 @@
|
||||
{{ frappe.utils.pretty_date(doc.creation) }}</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
{% block title %} {{ title }} {% endblock %}
|
||||
|
||||
{% block header %}<h2>{{ title }}</h2>{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% macro render_fields(docfields) -%}
|
||||
{% for df in docfields -%}
|
||||
{% if df.fieldtype == "Data" -%}
|
||||
<fieldset>
|
||||
<label>{{ df.label }}</label>
|
||||
<input class="form-control" type="text" placeholder="Type {{ df.label }}"
|
||||
data-fieldname="{{ df.fieldname }}" data-fieldtype="{{ df.fieldtype }}"
|
||||
{% if doc and doc.get(df.fieldname) -%} value="{{ doc[df.fieldname] }}" {%- endif %}>
|
||||
</fieldset>
|
||||
{% elif df.fieldtype == "Check" -%}
|
||||
<fieldset class="checkbox">
|
||||
<label><input type="checkbox" data-fieldname="{{ df.fieldname }}"
|
||||
data-fieldtype="{{ df.fieldtype }}"
|
||||
{% if doc and frappe.utils.cint(doc.get(df.fieldname)) -%} checked="checked" {%- endif %}>
|
||||
{{ df.label }}</label>
|
||||
</fieldset>
|
||||
{% elif df.fieldtype in ("Select", "Link") -%}
|
||||
<fieldset>
|
||||
{% set select_options = frappe.get_list(df.options)|map(attribute="name")
|
||||
if df.fieldtype == "Link" else df.options.split("\n") %}
|
||||
<label>{{ df.label }}</label>
|
||||
<select class="form-control" data-fieldname="{{ df.fieldname }}" data-fieldtype="{{ df.fieldtype }}">
|
||||
{% for value in select_options -%}
|
||||
{% if doc and doc.get(df.fieldname) == value -%}
|
||||
<option selected="selected">{{ value }}</option>
|
||||
{% else -%}
|
||||
<option>{{ value }}</option>
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
</select>
|
||||
</fieldset>
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
{%- endmacro %}
|
||||
|
||||
<div class="container content">
|
||||
<ul class="breadcrumb">
|
||||
<li><a href="/index">Home</a></li>
|
||||
<li><a href="/addresses">My Addresses</a></li>
|
||||
<li class="active"><i class="icon-map-marker icon-fixed-width"></i> {{ title }}</li>
|
||||
</ul>
|
||||
<h3><i class="icon-map-marker icon-fixed-width"></i> {{ title }}</h3>
|
||||
<button type="button" class="btn btn-primary pull-right" id="address-save"><i class="icon-ok"></i>
|
||||
{{ doc and "Save" or "Insert" }}</button>
|
||||
<div class="clearfix"></div>
|
||||
<hr>
|
||||
<div id="address-error" class="alert alert-danger" style="display:none"></div>
|
||||
<form autocomplete="on">
|
||||
<div class="row">
|
||||
<section class="col-md-6">
|
||||
{{ render_fields(meta.left_fields) }}
|
||||
</section>
|
||||
<section class="col-md-6">
|
||||
{{ render_fields(meta.right_fields) }}
|
||||
</section>
|
||||
</section>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
;(function() {
|
||||
console.log("yoyo");
|
||||
frappe.ready(function() {
|
||||
bind_save();
|
||||
});
|
||||
|
||||
var bind_save = function() {
|
||||
$("#address-save").on("click", function() {
|
||||
console.log("clicked!");
|
||||
|
||||
var fields = {
|
||||
name: "{{ docname or '' }}"
|
||||
};
|
||||
|
||||
$("form").find("[data-fieldname]").each(function(i, input) {
|
||||
var $input = $(input);
|
||||
var fieldname = $(input).attr("data-fieldname");
|
||||
var fieldtype = $(input).attr("data-fieldtype");
|
||||
|
||||
if(fieldtype == "Check") {
|
||||
fields[fieldname] = $input.is(":checked") ? 1 : 0;
|
||||
} else {
|
||||
fields[fieldname] = $input.val();
|
||||
}
|
||||
});
|
||||
|
||||
frappe.call({
|
||||
btn: $(this),
|
||||
type: "POST",
|
||||
method: "erpnext.templates.pages.address.save_address",
|
||||
args: { fields: fields, address_fieldname: get_url_arg("address_fieldname") },
|
||||
error_msg: "#address-error",
|
||||
callback: function(r) {
|
||||
if(get_url_arg("address_fieldname")) {
|
||||
window.location.href = "cart";
|
||||
} else {
|
||||
window.location.href = "address?name=" + encodeURIComponent(r.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- no-sidebar -->
|
||||
{% endblock %}
|
||||
@@ -1,62 +0,0 @@
|
||||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import json
|
||||
|
||||
import frappe
|
||||
from erpnext.shopping_cart.cart import get_lead_or_customer, update_cart_address
|
||||
from frappe.desk.form.meta import get_meta
|
||||
|
||||
no_cache = 1
|
||||
no_sitemap = 1
|
||||
|
||||
def get_context(context):
|
||||
def _get_fields(fieldnames):
|
||||
return [frappe._dict(zip(["label", "fieldname", "fieldtype", "options"],
|
||||
[df.label, df.fieldname, df.fieldtype, df.options]))
|
||||
for df in get_meta("Address").get("fields", {"fieldname": ["in", fieldnames]})]
|
||||
|
||||
docname = doc = None
|
||||
title = "New Address"
|
||||
if frappe.form_dict.name:
|
||||
doc = frappe.get_doc("Address", frappe.form_dict.name)
|
||||
docname = doc.name
|
||||
title = doc.name
|
||||
|
||||
return {
|
||||
"doc": doc,
|
||||
"meta": frappe._dict({
|
||||
"left_fields": _get_fields(["address_title", "address_type", "address_line1", "address_line2",
|
||||
"city", "state", "pincode", "country"]),
|
||||
"right_fields": _get_fields(["email_id", "phone", "fax", "is_primary_address",
|
||||
"is_shipping_address"])
|
||||
}),
|
||||
"docname": docname,
|
||||
"title": title
|
||||
}
|
||||
|
||||
@frappe.whitelist()
|
||||
def save_address(fields, address_fieldname=None):
|
||||
party = get_lead_or_customer()
|
||||
fields = json.loads(fields)
|
||||
|
||||
if fields.get("name"):
|
||||
doc = frappe.get_doc("Address", fields.get("name"))
|
||||
else:
|
||||
doc = frappe.get_doc({"doctype": "Address", "__islocal": 1})
|
||||
|
||||
doc.update(fields)
|
||||
|
||||
party_fieldname = party.doctype.lower()
|
||||
doc.update({
|
||||
party_fieldname: party.name,
|
||||
(party_fieldname + "_name"): party.get(party_fieldname + "_name")
|
||||
})
|
||||
doc.flags.ignore_permissions = True
|
||||
doc.save()
|
||||
|
||||
if address_fieldname:
|
||||
update_cart_address(address_fieldname, doc.name)
|
||||
|
||||
return doc.name
|
||||
@@ -1,50 +0,0 @@
|
||||
{% block title %} {{ "My Addresses" }} {% endblock %}
|
||||
|
||||
{% block header %}<h2>My Addresses</h2>{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}{% include "templates/includes/breadcrumbs.html" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="addresses-content">
|
||||
<p><a class="btn btn-default" href="/address"><i class="icon-plus"> New Address</i></a></p>
|
||||
<hr>
|
||||
<div id="address-list">
|
||||
<div class="text-muted progress">{{ _("Loading") }}...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
;(function() {
|
||||
var fetch_addresses = function() {
|
||||
frappe.call({
|
||||
method: "erpnext.templates.pages.addresses.get_addresses",
|
||||
callback: function(r) {
|
||||
$("#address-list .progress").remove();
|
||||
var $list = $("#address-list");
|
||||
|
||||
if(!(r.message && r.message.length)) {
|
||||
$list.html("<div class='alert'>No Addresses Found</div>");
|
||||
return;
|
||||
}
|
||||
|
||||
$.each(r.message, function(i, address) {
|
||||
address.url_name = encodeURIComponent(address.name);
|
||||
$(repl('<div> \
|
||||
<p><a href="/address?name=%(url_name)s">%(name)s</a></p> \
|
||||
<p>%(display)s</p> \
|
||||
<hr> \
|
||||
</div>', address)).appendTo($list);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$(document).ready(function() {
|
||||
fetch_addresses();
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- no-sidebar -->
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
# 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
|
||||
from erpnext.shopping_cart.cart import get_address_docs
|
||||
|
||||
no_cache = 1
|
||||
no_sitemap = 1
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_addresses():
|
||||
return get_address_docs()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user