Merge branch 'develop'
This commit is contained in:
commit
248a65b37d
@ -14,6 +14,8 @@ install:
|
||||
- sudo apt-get update
|
||||
- sudo apt-get purge -y mysql-common
|
||||
- sudo apt-get install mariadb-server mariadb-common libmariadbclient-dev
|
||||
- ./ci/fix-mariadb.sh
|
||||
|
||||
- wget http://downloads.sourceforge.net/project/wkhtmltopdf/0.12.1/wkhtmltox-0.12.1_linux-precise-amd64.deb
|
||||
- sudo dpkg -i wkhtmltox-0.12.1_linux-precise-amd64.deb
|
||||
- CFLAGS=-O0 pip install git+https://github.com/frappe/frappe.git@develop
|
||||
|
11
ci/fix-mariadb.sh
Executable file
11
ci/fix-mariadb.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# stolen from http://cgit.drupalcode.org/octopus/commit/?id=db4f837
|
||||
includedir=`mysql_config --variable=pkgincludedir`
|
||||
thiscwd=`pwd`
|
||||
_THIS_DB_VERSION=`mysql -V 2>&1 | tr -d "\n" | cut -d" " -f6 | awk '{ print $1}' | cut -d"-" -f1 | awk '{ print $1}' | sed "s/[\,']//g"`
|
||||
if [ "$_THIS_DB_VERSION" = "5.5.40" ] && [ ! -e "$includedir-$_THIS_DB_VERSION-fixed.log" ] ; then
|
||||
cd $includedir
|
||||
sudo patch -p1 < $thiscwd/ci/my_config.h.patch &> /dev/null
|
||||
sudo touch $includedir-$_THIS_DB_VERSION-fixed.log
|
||||
fi
|
22
ci/my_config.h.patch
Normal file
22
ci/my_config.h.patch
Normal file
@ -0,0 +1,22 @@
|
||||
diff -burp a/my_config.h b/my_config.h
|
||||
--- a/my_config.h 2014-10-09 19:32:46.000000000 -0400
|
||||
+++ b/my_config.h 2014-10-09 19:35:12.000000000 -0400
|
||||
@@ -641,17 +641,4 @@
|
||||
#define SIZEOF_TIME_T 8
|
||||
/* #undef TIME_T_UNSIGNED */
|
||||
|
||||
-/*
|
||||
- stat structure (from <sys/stat.h>) is conditionally defined
|
||||
- to have different layout and size depending on the defined macros.
|
||||
- The correct macro is defined in my_config.h, which means it MUST be
|
||||
- included first (or at least before <features.h> - so, practically,
|
||||
- before including any system headers).
|
||||
-
|
||||
- __GLIBC__ is defined in <features.h>
|
||||
-*/
|
||||
-#ifdef __GLIBC__
|
||||
-#error <my_config.h> MUST be included first!
|
||||
-#endif
|
||||
-
|
||||
#endif
|
||||
|
@ -1 +1 @@
|
||||
__version__ = '4.5.2'
|
||||
__version__ = '4.6.0'
|
||||
|
@ -14,6 +14,9 @@ class AccountsSettings(Document):
|
||||
frappe.db.set_default("auto_accounting_for_stock", self.auto_accounting_for_stock)
|
||||
|
||||
if cint(self.auto_accounting_for_stock):
|
||||
if cint(frappe.db.get_value("Stock Settings", None, "allow_negative_stock")):
|
||||
frappe.throw(_("Negative stock is not allowed in case of Perpetual Inventory, please disable it from Stock Settings"))
|
||||
|
||||
# set default perpetual account in company
|
||||
for company in frappe.db.sql("select name from tabCompany"):
|
||||
frappe.get_doc("Company", company[0]).save()
|
||||
|
@ -76,13 +76,14 @@ class JournalVoucher(AccountsController):
|
||||
|
||||
def validate_entries_for_advance(self):
|
||||
for d in self.get('entries'):
|
||||
if not d.is_advance and not d.against_voucher and \
|
||||
not d.against_invoice and not d.against_jv:
|
||||
if not (d.against_voucher and d.against_invoice and d.against_jv):
|
||||
master_type = frappe.db.get_value("Account", d.account, "master_type")
|
||||
if (master_type == 'Customer' and flt(d.credit) > 0) or \
|
||||
(master_type == 'Supplier' and flt(d.debit) > 0):
|
||||
msgprint(_("Row {0}: Please check 'Is Advance' against Account {1} if this \
|
||||
is an advance entry.").format(d.idx, d.account))
|
||||
if not d.is_advance:
|
||||
msgprint(_("Row {0}: Please check 'Is Advance' against Account {1} if this is an advance entry.").format(d.idx, d.account))
|
||||
elif (d.against_sales_order or d.against_purchase_order) and d.is_advance != "Yes":
|
||||
frappe.throw(_("Row {0}: Payment against Sales/Purchase Order should always be marked as advance").format(d.idx))
|
||||
|
||||
def validate_against_jv(self):
|
||||
for d in self.get('entries'):
|
||||
@ -177,7 +178,7 @@ class JournalVoucher(AccountsController):
|
||||
def validate_against_order_fields(self, doctype, payment_against_voucher):
|
||||
for voucher_no, payment_list in payment_against_voucher.items():
|
||||
voucher_properties = frappe.db.get_value(doctype, voucher_no,
|
||||
["docstatus", "per_billed", "advance_paid", "grand_total"])
|
||||
["docstatus", "per_billed", "status", "advance_paid", "grand_total"])
|
||||
|
||||
if voucher_properties[0] != 1:
|
||||
frappe.throw(_("{0} {1} is not submitted").format(doctype, voucher_no))
|
||||
@ -185,7 +186,10 @@ class JournalVoucher(AccountsController):
|
||||
if flt(voucher_properties[1]) >= 100:
|
||||
frappe.throw(_("{0} {1} is fully billed").format(doctype, voucher_no))
|
||||
|
||||
if flt(voucher_properties[3]) < flt(voucher_properties[2]) + flt(sum(payment_list)):
|
||||
if cstr(voucher_properties[2]) == "Stopped":
|
||||
frappe.throw(_("{0} {1} is stopped").format(doctype, voucher_no))
|
||||
|
||||
if flt(voucher_properties[4]) < flt(voucher_properties[3]) + flt(sum(payment_list)):
|
||||
frappe.throw(_("Advance paid against {0} {1} cannot be greater \
|
||||
than Grand Total {2}").format(doctype, voucher_no, voucher_properties[3]))
|
||||
|
||||
|
@ -91,6 +91,7 @@ def get_orders_to_be_billed(party_type, party_name):
|
||||
where
|
||||
%s = %s
|
||||
and docstatus = 1
|
||||
and ifnull(status, "") != "Stopped"
|
||||
and ifnull(grand_total, 0) > ifnull(advance_paid, 0)
|
||||
and ifnull(per_billed, 0) < 100.0
|
||||
""" % (voucher_type, 'customer' if party_type == "Customer" else 'supplier', '%s'),
|
||||
|
@ -31,9 +31,10 @@ class TestPaymentTool(unittest.TestCase):
|
||||
"customer": "_Test Customer 3"
|
||||
})
|
||||
|
||||
jv_against_so1 = self.create_against_jv(jv_test_records[0], {
|
||||
jv_against_so1 = self.create_against_jv(jv_test_records[0], {
|
||||
"account": "_Test Customer 3 - _TC",
|
||||
"against_sales_order": so1.name
|
||||
"against_sales_order": so1.name,
|
||||
"is_advance": "Yes"
|
||||
})
|
||||
|
||||
|
||||
@ -42,10 +43,11 @@ class TestPaymentTool(unittest.TestCase):
|
||||
"customer": "_Test Customer 3"
|
||||
})
|
||||
|
||||
jv_against_so2 = self.create_against_jv(jv_test_records[0], {
|
||||
jv_against_so2 = self.create_against_jv(jv_test_records[0], {
|
||||
"account": "_Test Customer 3 - _TC",
|
||||
"against_sales_order": so2.name,
|
||||
"credit": 1000
|
||||
"credit": 1000,
|
||||
"is_advance": "Yes"
|
||||
})
|
||||
po = self.create_voucher(po_test_records[1], {
|
||||
"supplier": "_Test Supplier 1"
|
||||
@ -54,20 +56,20 @@ class TestPaymentTool(unittest.TestCase):
|
||||
#Create SI with partial outstanding
|
||||
si1 = self.create_voucher(si_test_records[0], {
|
||||
"customer": "_Test Customer 3",
|
||||
"debit_to": "_Test Customer 3 - _TC"
|
||||
"debit_to": "_Test Customer 3 - _TC"
|
||||
})
|
||||
|
||||
jv_against_si1 = self.create_against_jv(jv_test_records[0], {
|
||||
|
||||
jv_against_si1 = self.create_against_jv(jv_test_records[0], {
|
||||
"account": "_Test Customer 3 - _TC",
|
||||
"against_invoice": si1.name
|
||||
})
|
||||
#Create SI with no outstanding
|
||||
si2 = self.create_voucher(si_test_records[0], {
|
||||
"customer": "_Test Customer 3",
|
||||
"debit_to": "_Test Customer 3 - _TC"
|
||||
"debit_to": "_Test Customer 3 - _TC"
|
||||
})
|
||||
|
||||
jv_against_si2 = self.create_against_jv(jv_test_records[0], {
|
||||
|
||||
jv_against_si2 = self.create_against_jv(jv_test_records[0], {
|
||||
"account": "_Test Customer 3 - _TC",
|
||||
"against_invoice": si2.name,
|
||||
"credit": 561.80
|
||||
@ -75,7 +77,7 @@ class TestPaymentTool(unittest.TestCase):
|
||||
|
||||
pi = self.create_voucher(pi_test_records[0], {
|
||||
"supplier": "_Test Supplier 1",
|
||||
"credit_to": "_Test Supplier 1 - _TC"
|
||||
"credit_to": "_Test Supplier 1 - _TC"
|
||||
})
|
||||
|
||||
#Create a dict containing properties and expected values
|
||||
@ -137,7 +139,7 @@ class TestPaymentTool(unittest.TestCase):
|
||||
payment_tool_doc.set(k, v)
|
||||
|
||||
self.check_outstanding_vouchers(payment_tool_doc, args, expected_outstanding)
|
||||
|
||||
|
||||
|
||||
def check_outstanding_vouchers(self, doc, args, expected_outstanding):
|
||||
from erpnext.accounts.doctype.payment_tool.payment_tool import get_outstanding_vouchers
|
||||
@ -161,7 +163,7 @@ class TestPaymentTool(unittest.TestCase):
|
||||
|
||||
new_jv = paytool.make_journal_voucher()
|
||||
|
||||
#Create a list of expected values as [party account, payment against, against_jv, against_invoice,
|
||||
#Create a list of expected values as [party account, payment against, against_jv, against_invoice,
|
||||
#against_voucher, against_sales_order, against_purchase_order]
|
||||
expected_values = [
|
||||
[paytool.party_account, 100.00, expected_outstanding.get("Journal Voucher")[0], None, None, None, None],
|
||||
@ -171,7 +173,7 @@ class TestPaymentTool(unittest.TestCase):
|
||||
[paytool.party_account, 100.00, None, None, None, None, expected_outstanding.get("Purchase Order")[0]]
|
||||
]
|
||||
|
||||
for jv_entry in new_jv.get("entries"):
|
||||
for jv_entry in new_jv.get("entries"):
|
||||
if paytool.party_account == jv_entry.get("account"):
|
||||
row = [
|
||||
jv_entry.get("account"),
|
||||
@ -183,11 +185,11 @@ class TestPaymentTool(unittest.TestCase):
|
||||
jv_entry.get("against_purchase_order"),
|
||||
]
|
||||
self.assertTrue(row in expected_values)
|
||||
|
||||
|
||||
self.assertEquals(new_jv.get("cheque_no"), paytool.reference_no)
|
||||
self.assertEquals(new_jv.get("cheque_date"), paytool.reference_date)
|
||||
|
||||
def clear_table_entries(self):
|
||||
frappe.db.sql("""delete from `tabGL Entry` where (account = "_Test Customer 3 - _TC" or account = "_Test Supplier 1 - _TC")""")
|
||||
frappe.db.sql("""delete from `tabSales Order` where customer_name = "_Test Customer 3" """)
|
||||
frappe.db.sql("""delete from `tabPurchase Order` where supplier_name = "_Test Supplier 1" """)
|
||||
frappe.db.sql("""delete from `tabPurchase Order` where supplier_name = "_Test Supplier 1" """)
|
||||
|
@ -780,6 +780,18 @@
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "Select the period when the invoice will be generated automatically",
|
||||
"fieldname": "recurring_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Recurring Type",
|
||||
"no_copy": 1,
|
||||
"options": "Monthly\nQuarterly\nHalf-yearly\nYearly",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
@ -800,18 +812,6 @@
|
||||
"no_copy": 1,
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "Select the period when the invoice will be generated automatically",
|
||||
"fieldname": "recurring_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Recurring Type",
|
||||
"no_copy": 1,
|
||||
"options": "Monthly\nQuarterly\nHalf-yearly\nYearly",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
@ -878,7 +878,7 @@
|
||||
"icon": "icon-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-10-06 12:57:32.064210",
|
||||
"modified": "2014-10-08 14:23:20.234176",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice",
|
||||
|
@ -168,6 +168,27 @@
|
||||
"reqd": 1,
|
||||
"search_index": 0
|
||||
},
|
||||
{
|
||||
"fieldname": "shipping_address_name",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 1,
|
||||
"in_filter": 1,
|
||||
"label": "Shipping Address Name",
|
||||
"options": "Address",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "shipping_address",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 1,
|
||||
"label": "Shipping Address",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "currency_section",
|
||||
"fieldtype": "Section Break",
|
||||
@ -1074,13 +1095,14 @@
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "End date of current invoice's period",
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "To Date",
|
||||
"description": "Select the period when the invoice will be generated automatically",
|
||||
"fieldname": "recurring_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Recurring Type",
|
||||
"no_copy": 1,
|
||||
"options": "\nMonthly\nQuarterly\nHalf-yearly\nYearly",
|
||||
"permlevel": 0,
|
||||
"print_hide": 0,
|
||||
"print_hide": 1,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
@ -1098,14 +1120,13 @@
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "Select the period when the invoice will be generated automatically",
|
||||
"fieldname": "recurring_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Recurring Type",
|
||||
"description": "End date of current invoice's period",
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "To Date",
|
||||
"no_copy": 1,
|
||||
"options": "\nMonthly\nQuarterly\nHalf-yearly\nYearly",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide": 0,
|
||||
"read_only": 0
|
||||
},
|
||||
{
|
||||
@ -1192,7 +1213,7 @@
|
||||
"icon": "icon-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-10-06 12:54:42.549361",
|
||||
"modified": "2014-10-10 16:54:22.284284",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
|
@ -7,7 +7,7 @@ import frappe.defaults
|
||||
from frappe.utils import cint, cstr, flt
|
||||
from frappe import _, msgprint, throw
|
||||
from erpnext.accounts.party import get_party_account, get_due_date
|
||||
from erpnext.controllers.stock_controller import update_gl_entries_after
|
||||
from erpnext.controllers.stock_controller import update_gl_entries_after, block_negative_stock
|
||||
from frappe.model.mapper import get_mapped_doc
|
||||
|
||||
from erpnext.controllers.selling_controller import SellingController
|
||||
@ -456,8 +456,8 @@ class SalesInvoice(SellingController):
|
||||
|
||||
self.make_sl_entries(sl_entries)
|
||||
|
||||
def make_gl_entries(self, repost_future_gle=True):
|
||||
gl_entries = self.get_gl_entries()
|
||||
def make_gl_entries(self, repost_future_gle=True, allow_negative_stock=False):
|
||||
gl_entries = self.get_gl_entries(allow_negative_stock=allow_negative_stock)
|
||||
|
||||
if gl_entries:
|
||||
from erpnext.accounts.general_ledger import make_gl_entries
|
||||
@ -476,7 +476,7 @@ class SalesInvoice(SellingController):
|
||||
items, warehouses = self.get_items_and_warehouses()
|
||||
update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items)
|
||||
|
||||
def get_gl_entries(self, warehouse_account=None):
|
||||
def get_gl_entries(self, warehouse_account=None, allow_negative_stock=False):
|
||||
from erpnext.accounts.general_ledger import merge_similar_entries
|
||||
|
||||
gl_entries = []
|
||||
@ -485,7 +485,7 @@ class SalesInvoice(SellingController):
|
||||
|
||||
self.make_tax_gl_entries(gl_entries)
|
||||
|
||||
self.make_item_gl_entries(gl_entries)
|
||||
self.make_item_gl_entries(gl_entries, allow_negative_stock)
|
||||
|
||||
# merge gl entries before adding pos entries
|
||||
gl_entries = merge_similar_entries(gl_entries)
|
||||
@ -520,7 +520,7 @@ class SalesInvoice(SellingController):
|
||||
})
|
||||
)
|
||||
|
||||
def make_item_gl_entries(self, gl_entries):
|
||||
def make_item_gl_entries(self, gl_entries, allow_negative_stock=False):
|
||||
# income account gl entries
|
||||
for item in self.get("entries"):
|
||||
if flt(item.base_amount):
|
||||
@ -537,7 +537,7 @@ class SalesInvoice(SellingController):
|
||||
# expense account gl entries
|
||||
if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) \
|
||||
and cint(self.update_stock):
|
||||
gl_entries += super(SalesInvoice, self).get_gl_entries()
|
||||
gl_entries += super(SalesInvoice, self).get_gl_entries(allow_negative_stock=allow_negative_stock)
|
||||
|
||||
def make_pos_gl_entries(self, gl_entries):
|
||||
if cint(self.is_pos) and self.cash_bank_account and self.paid_amount:
|
||||
|
@ -97,8 +97,7 @@ 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 delete_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None,
|
||||
|
@ -30,7 +30,8 @@ def execute(filters=None):
|
||||
data = []
|
||||
for gle in entries:
|
||||
if cstr(gle.against_voucher) == gle.voucher_no or not gle.against_voucher \
|
||||
or [gle.against_voucher_type, gle.against_voucher] in entries_after_report_date:
|
||||
or [gle.against_voucher_type, gle.against_voucher] in entries_after_report_date \
|
||||
or (gle.against_voucher_type == "Purchase Order"):
|
||||
voucher_details = voucher_detail_map.get(gle.voucher_type, {}).get(gle.voucher_no, {})
|
||||
|
||||
invoiced_amount = gle.credit > 0 and gle.credit or 0
|
||||
|
@ -79,6 +79,9 @@ class AccountsReceivableReport(object):
|
||||
return (
|
||||
# advance
|
||||
(not gle.against_voucher) or
|
||||
|
||||
# against sales order
|
||||
(gle.against_voucher_type == "Sales Order") or
|
||||
|
||||
# sales invoice
|
||||
(gle.against_voucher==gle.voucher_no and gle.debit > 0) or
|
||||
|
@ -677,6 +677,16 @@
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"fieldname": "recurring_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Recurring Type",
|
||||
"no_copy": 1,
|
||||
"options": "Monthly\nQuarterly\nHalf-yearly\nYearly",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
@ -697,16 +707,6 @@
|
||||
"no_copy": 1,
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"fieldname": "recurring_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Recurring Type",
|
||||
"no_copy": 1,
|
||||
"options": "Monthly\nQuarterly\nHalf-yearly\nYearly",
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
@ -772,7 +772,7 @@
|
||||
"icon": "icon-file-text",
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"modified": "2014-10-06 12:16:44.453946",
|
||||
"modified": "2014-10-08 14:23:29.718779",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Buying",
|
||||
"name": "Purchase Order",
|
||||
|
@ -142,10 +142,10 @@ def get_data():
|
||||
"doctype": "Item",
|
||||
},
|
||||
{
|
||||
"type": "page",
|
||||
"name": "stock-balance",
|
||||
"label": _("Stock Balance"),
|
||||
"icon": "icon-table",
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Stock Balance",
|
||||
"doctype": "Warehouse"
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
@ -170,13 +170,7 @@ def get_data():
|
||||
"name": "stock-analytics",
|
||||
"label": _("Stock Analytics"),
|
||||
"icon": "icon-bar-chart"
|
||||
},
|
||||
{
|
||||
"type": "report",
|
||||
"is_query_report": True,
|
||||
"name": "Warehouse-Wise Stock Balance",
|
||||
"doctype": "Warehouse"
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -387,7 +387,7 @@ class AccountsController(TransactionBase):
|
||||
|
||||
res = frappe.db.sql("""
|
||||
select
|
||||
t1.name as jv_no, t1.remark, t2.%s as amount, t2.name as jv_detail_no
|
||||
t1.name as jv_no, t1.remark, t2.%s as amount, t2.name as jv_detail_no, `against_%s` as against_order
|
||||
from
|
||||
`tabJournal Voucher` t1, `tabJournal Voucher Detail` t2
|
||||
where
|
||||
@ -400,7 +400,7 @@ class AccountsController(TransactionBase):
|
||||
and ifnull(t2.against_purchase_order, '') = ''
|
||||
) %s)
|
||||
order by t1.posting_date""" %
|
||||
(dr_or_cr, '%s', cond),
|
||||
(dr_or_cr, against_order_field, '%s', cond),
|
||||
tuple([account_head] + so_list), as_dict= True)
|
||||
|
||||
self.set(parentfield, [])
|
||||
@ -411,7 +411,7 @@ class AccountsController(TransactionBase):
|
||||
"jv_detail_no": d.jv_detail_no,
|
||||
"remarks": d.remark,
|
||||
"advance_amount": flt(d.amount),
|
||||
"allocate_amount": 0
|
||||
"allocated_amount": flt(d.amount) if d.against_order else 0
|
||||
})
|
||||
|
||||
def validate_advance_jv(self, advance_table_fieldname, against_order_field):
|
||||
|
@ -256,8 +256,6 @@ class BuyingController(StockController):
|
||||
rm.required_qty = required_qty
|
||||
|
||||
rm.conversion_factor = item.conversion_factor
|
||||
rm.rate = bom_item.rate
|
||||
rm.amount = required_qty * flt(bom_item.rate)
|
||||
rm.idx = rm_supplied_idx
|
||||
|
||||
if self.doctype == "Purchase Receipt":
|
||||
@ -268,7 +266,23 @@ class BuyingController(StockController):
|
||||
|
||||
rm_supplied_idx += 1
|
||||
|
||||
raw_materials_cost += required_qty * flt(bom_item.rate)
|
||||
# get raw materials rate
|
||||
if self.doctype == "Purchase Receipt":
|
||||
from erpnext.stock.utils import get_incoming_rate
|
||||
item_rate = get_incoming_rate({
|
||||
"item_code": bom_item.item_code,
|
||||
"warehouse": self.supplier_warehouse,
|
||||
"posting_date": self.posting_date,
|
||||
"posting_time": self.posting_time,
|
||||
"qty": -1 * required_qty,
|
||||
"serial_no": rm.serial_no
|
||||
})
|
||||
rm.rate = item_rate or bom_item.rate
|
||||
else:
|
||||
rm.rate = bom_item.rate
|
||||
|
||||
rm.amount = required_qty * flt(rm.rate)
|
||||
raw_materials_cost += flt(rm.amount)
|
||||
|
||||
if self.doctype == "Purchase Receipt":
|
||||
item.rm_supp_cost = raw_materials_cost
|
||||
|
@ -8,10 +8,10 @@ from frappe import msgprint, _
|
||||
import frappe.defaults
|
||||
|
||||
from erpnext.controllers.accounts_controller import AccountsController
|
||||
from erpnext.accounts.general_ledger import make_gl_entries, delete_gl_entries
|
||||
from erpnext.accounts.general_ledger import make_gl_entries, delete_gl_entries, process_gl_map
|
||||
|
||||
class StockController(AccountsController):
|
||||
def make_gl_entries(self, repost_future_gle=True):
|
||||
def make_gl_entries(self, repost_future_gle=True, allow_negative_stock=False):
|
||||
if self.docstatus == 2:
|
||||
delete_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
|
||||
|
||||
@ -19,16 +19,19 @@ class StockController(AccountsController):
|
||||
warehouse_account = get_warehouse_account()
|
||||
|
||||
if self.docstatus==1:
|
||||
gl_entries = self.get_gl_entries(warehouse_account)
|
||||
gl_entries = self.get_gl_entries(warehouse_account, allow_negative_stock=allow_negative_stock)
|
||||
make_gl_entries(gl_entries)
|
||||
|
||||
if repost_future_gle:
|
||||
items, warehouses = self.get_items_and_warehouses()
|
||||
update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items, warehouse_account)
|
||||
update_gl_entries_after(self.posting_date, self.posting_time, warehouses, items,
|
||||
warehouse_account, allow_negative_stock)
|
||||
|
||||
def get_gl_entries(self, warehouse_account=None, default_expense_account=None,
|
||||
default_cost_center=None):
|
||||
from erpnext.accounts.general_ledger import process_gl_map
|
||||
default_cost_center=None, allow_negative_stock=False):
|
||||
|
||||
block_negative_stock(allow_negative_stock)
|
||||
|
||||
if not warehouse_account:
|
||||
warehouse_account = get_warehouse_account()
|
||||
|
||||
@ -46,12 +49,17 @@ class StockController(AccountsController):
|
||||
|
||||
self.check_expense_account(detail)
|
||||
|
||||
stock_value_difference = flt(sle.stock_value_difference, 2)
|
||||
if not stock_value_difference:
|
||||
valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse)
|
||||
stock_value_difference = flt(sle.actual_qty)*flt(valuation_rate)
|
||||
|
||||
gl_list.append(self.get_gl_dict({
|
||||
"account": warehouse_account[sle.warehouse],
|
||||
"against": detail.expense_account,
|
||||
"cost_center": detail.cost_center,
|
||||
"remarks": self.get("remarks") or "Accounting Entry for Stock",
|
||||
"debit": flt(sle.stock_value_difference, 2)
|
||||
"debit": stock_value_difference
|
||||
}))
|
||||
|
||||
# to target warehouse / expense account
|
||||
@ -60,7 +68,7 @@ class StockController(AccountsController):
|
||||
"against": warehouse_account[sle.warehouse],
|
||||
"cost_center": detail.cost_center,
|
||||
"remarks": self.get("remarks") or "Accounting Entry for Stock",
|
||||
"credit": flt(sle.stock_value_difference, 2)
|
||||
"credit": stock_value_difference
|
||||
}))
|
||||
elif sle.warehouse not in warehouse_with_no_account:
|
||||
warehouse_with_no_account.append(sle.warehouse)
|
||||
@ -118,7 +126,8 @@ class StockController(AccountsController):
|
||||
|
||||
def get_stock_ledger_details(self):
|
||||
stock_ledger = {}
|
||||
for sle in frappe.db.sql("""select warehouse, stock_value_difference, voucher_detail_no
|
||||
for sle in frappe.db.sql("""select warehouse, stock_value_difference,
|
||||
voucher_detail_no, item_code, posting_date, actual_qty
|
||||
from `tabStock Ledger Entry` where voucher_type=%s and voucher_no=%s""",
|
||||
(self.doctype, self.name), as_dict=True):
|
||||
stock_ledger.setdefault(sle.voucher_detail_no, []).append(sle)
|
||||
@ -214,7 +223,8 @@ class StockController(AccountsController):
|
||||
|
||||
return serialized_items
|
||||
|
||||
def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None, warehouse_account=None):
|
||||
def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None,
|
||||
warehouse_account=None, allow_negative_stock=False):
|
||||
def _delete_gl_entries(voucher_type, voucher_no):
|
||||
frappe.db.sql("""delete from `tabGL Entry`
|
||||
where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no))
|
||||
@ -228,12 +238,12 @@ def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for
|
||||
for voucher_type, voucher_no in future_stock_vouchers:
|
||||
existing_gle = gle.get((voucher_type, voucher_no), [])
|
||||
voucher_obj = frappe.get_doc(voucher_type, voucher_no)
|
||||
expected_gle = voucher_obj.get_gl_entries(warehouse_account)
|
||||
expected_gle = voucher_obj.get_gl_entries(warehouse_account, allow_negative_stock=allow_negative_stock)
|
||||
if expected_gle:
|
||||
if not existing_gle or not compare_existing_and_expected_gle(existing_gle,
|
||||
expected_gle):
|
||||
_delete_gl_entries(voucher_type, voucher_no)
|
||||
voucher_obj.make_gl_entries(repost_future_gle=False)
|
||||
voucher_obj.make_gl_entries(repost_future_gle=False, allow_negative_stock=allow_negative_stock)
|
||||
else:
|
||||
_delete_gl_entries(voucher_type, voucher_no)
|
||||
|
||||
@ -285,3 +295,28 @@ def get_warehouse_account():
|
||||
warehouse_account = dict(frappe.db.sql("""select master_name, name from tabAccount
|
||||
where account_type = 'Warehouse' and ifnull(master_name, '') != ''"""))
|
||||
return warehouse_account
|
||||
|
||||
def block_negative_stock(allow_negative_stock=False):
|
||||
if cint(frappe.defaults.get_global_default("auto_accounting_for_stock")) and not allow_negative_stock:
|
||||
if cint(frappe.db.get_value("Stock Settings", None, "allow_negative_stock")):
|
||||
frappe.throw(_("Negative stock is not allowed in case of Perpetual Inventory, please disable it from Stock Settings"))
|
||||
|
||||
def get_valuation_rate(item_code, warehouse):
|
||||
last_valuation_rate = frappe.db.sql("""select valuation_rate
|
||||
from `tabStock Ledger Entry`
|
||||
where item_code = %s and warehouse = %s
|
||||
and ifnull(valuation_rate, 0) > 0
|
||||
order by posting_date desc, posting_time desc, name desc limit 1""", (item_code, warehouse))
|
||||
|
||||
if not last_valuation_rate:
|
||||
last_valuation_rate = frappe.db.sql("""select valuation_rate
|
||||
from `tabStock Ledger Entry`
|
||||
where item_code = %s and ifnull(valuation_rate, 0) > 0
|
||||
order by posting_date desc, posting_time desc, name desc limit 1""", item_code)
|
||||
|
||||
valuation_rate = flt(last_valuation_rate[0][0]) if last_valuation_rate else 0
|
||||
|
||||
if not valuation_rate:
|
||||
valuation_rate = frappe.db.get_value("Item Price", {"item_code": item_code, "buying": 1}, "price_list_rate")
|
||||
|
||||
return valuation_rate
|
||||
|
@ -4,7 +4,7 @@ app_publisher = "Web Notes 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 = "4.5.2"
|
||||
app_version = "4.6.0"
|
||||
|
||||
error_report_email = "support@erpnext.com"
|
||||
|
||||
|
@ -115,6 +115,9 @@ class BOM(Document):
|
||||
return rate
|
||||
|
||||
def update_cost(self):
|
||||
if self.docstatus == 2:
|
||||
return
|
||||
|
||||
for d in self.get("bom_materials"):
|
||||
d.rate = self.get_bom_material_detail({
|
||||
'item_code': d.item_code,
|
||||
@ -122,9 +125,10 @@ class BOM(Document):
|
||||
'qty': d.qty
|
||||
})["rate"]
|
||||
|
||||
if self.docstatus in (0, 1):
|
||||
if self.docstatus == 1:
|
||||
self.ignore_validate_update_after_submit = True
|
||||
self.save()
|
||||
self.calculate_cost()
|
||||
self.save()
|
||||
|
||||
def get_bom_unitcost(self, bom_no):
|
||||
bom = frappe.db.sql("""select name, total_variable_cost/quantity as unit_cost from `tabBOM`
|
||||
@ -269,29 +273,27 @@ class BOM(Document):
|
||||
"""Calculate bom totals"""
|
||||
self.calculate_op_cost()
|
||||
self.calculate_rm_cost()
|
||||
self.calculate_fixed_cost()
|
||||
self.total_variable_cost = self.raw_material_cost + self.operating_cost
|
||||
self.total_cost = self.total_variable_cost + self.total_fixed_cost
|
||||
|
||||
def calculate_op_cost(self):
|
||||
"""Update workstation rate and calculates totals"""
|
||||
total_op_cost = 0
|
||||
total_op_cost, fixed_cost = 0, 0
|
||||
for d in self.get('bom_operations'):
|
||||
if d.workstation and not d.hour_rate:
|
||||
d.hour_rate = frappe.db.get_value("Workstation", d.workstation, "hour_rate")
|
||||
if d.workstation:
|
||||
w = frappe.db.get_value("Workstation", d.workstation, ["hour_rate", "fixed_cycle_cost"])
|
||||
if not d.hour_rate:
|
||||
d.hour_rate = flt(w[0])
|
||||
|
||||
fixed_cost += flt(w[1])
|
||||
|
||||
if d.hour_rate and d.time_in_mins:
|
||||
d.operating_cost = flt(d.hour_rate) * flt(d.time_in_mins) / 60.0
|
||||
total_op_cost += flt(d.operating_cost)
|
||||
|
||||
self.operating_cost = total_op_cost
|
||||
|
||||
def calculate_fixed_cost(self):
|
||||
"""Update workstation rate and calculates totals"""
|
||||
fixed_cost = 0
|
||||
for d in self.get('bom_operations'):
|
||||
if d.workstation:
|
||||
fixed_cost += flt(frappe.db.get_value("Workstation", d.workstation, "fixed_cycle_cost"))
|
||||
self.total_fixed_cost = fixed_cost
|
||||
|
||||
|
||||
def calculate_rm_cost(self):
|
||||
"""Fetch RM rate as per today's valuation rate and calculate totals"""
|
||||
total_rm_cost = 0
|
||||
|
@ -81,4 +81,8 @@ erpnext.patches.v4_2.default_website_style
|
||||
erpnext.patches.v4_2.set_company_country
|
||||
erpnext.patches.v4_2.update_sales_order_invoice_field_name
|
||||
erpnext.patches.v4_2.cost_of_production_cycle
|
||||
erpnext.patches.v4_2.seprate_manufacture_and_repack
|
||||
erpnext.patches.v4_2.seprate_manufacture_and_repack
|
||||
execute:frappe.delete_doc("Report", "Warehouse-Wise Stock Balance")
|
||||
execute:frappe.delete_doc("DocType", "Purchase Request")
|
||||
execute:frappe.delete_doc("DocType", "Purchase Request Item")
|
||||
erpnext.patches.v4_2.recalculate_bom_cost
|
@ -2,6 +2,7 @@ import frappe
|
||||
from frappe.templates.pages.style_settings import default_properties
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc('website', 'doctype', 'style_settings')
|
||||
style_settings = frappe.get_doc("Style Settings", "Style Settings")
|
||||
if not style_settings.apply_style:
|
||||
style_settings.update(default_properties)
|
||||
|
@ -3,24 +3,49 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.utils import flt
|
||||
|
||||
def execute():
|
||||
warehouses_with_account = frappe.db.sql_list("""select master_name from tabAccount
|
||||
where ifnull(account_type, '') = 'Warehouse'""")
|
||||
from erpnext.utilities.repost_stock import repost
|
||||
repost()
|
||||
|
||||
stock_vouchers_without_gle = frappe.db.sql("""select distinct sle.voucher_type, sle.voucher_no
|
||||
warehouse_account = frappe.db.sql("""select name, master_name from tabAccount
|
||||
where ifnull(account_type, '') = 'Warehouse'""")
|
||||
warehouses = [d[1] for d in warehouse_account]
|
||||
accounts = [d[0] for d in warehouse_account]
|
||||
|
||||
stock_vouchers = frappe.db.sql("""select distinct sle.voucher_type, sle.voucher_no
|
||||
from `tabStock Ledger Entry` sle
|
||||
where sle.warehouse in (%s)
|
||||
and not exists(select name from `tabGL Entry`
|
||||
where voucher_type=sle.voucher_type and voucher_no=sle.voucher_no)
|
||||
order by sle.posting_date""" %
|
||||
', '.join(['%s']*len(warehouses_with_account)), tuple(warehouses_with_account))
|
||||
', '.join(['%s']*len(warehouses)), tuple(warehouses))
|
||||
|
||||
for voucher_type, voucher_no in stock_vouchers_without_gle:
|
||||
print voucher_type, voucher_no
|
||||
frappe.db.sql("""delete from `tabGL Entry`
|
||||
where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no))
|
||||
rejected = []
|
||||
for voucher_type, voucher_no in stock_vouchers:
|
||||
stock_bal = frappe.db.sql("""select sum(stock_value_difference) from `tabStock Ledger Entry`
|
||||
where voucher_type=%s and voucher_no =%s and warehouse in (%s)""" %
|
||||
('%s', '%s', ', '.join(['%s']*len(warehouses))), tuple([voucher_type, voucher_no] + warehouses))
|
||||
|
||||
voucher = frappe.get_doc(voucher_type, voucher_no)
|
||||
voucher.make_gl_entries()
|
||||
frappe.db.commit()
|
||||
account_bal = frappe.db.sql("""select ifnull(sum(ifnull(debit, 0) - ifnull(credit, 0)), 0)
|
||||
from `tabGL Entry`
|
||||
where voucher_type=%s and voucher_no =%s and account in (%s)
|
||||
group by voucher_type, voucher_no""" %
|
||||
('%s', '%s', ', '.join(['%s']*len(accounts))), tuple([voucher_type, voucher_no] + accounts))
|
||||
|
||||
if stock_bal and account_bal and abs(flt(stock_bal[0][0]) - flt(account_bal[0][0])) > 0.1:
|
||||
try:
|
||||
print voucher_type, voucher_no, stock_bal[0][0], account_bal[0][0]
|
||||
|
||||
frappe.db.sql("""delete from `tabGL Entry`
|
||||
where voucher_type=%s and voucher_no=%s""", (voucher_type, voucher_no))
|
||||
|
||||
voucher = frappe.get_doc(voucher_type, voucher_no)
|
||||
voucher.make_gl_entries(repost_future_gle=False, allow_negative_stock=True)
|
||||
frappe.db.commit()
|
||||
except Exception, e:
|
||||
print frappe.get_traceback()
|
||||
rejected.append([voucher_type, voucher_no])
|
||||
frappe.db.rollback()
|
||||
|
||||
print "Failed to repost: "
|
||||
print rejected
|
||||
|
16
erpnext/patches/v4_2/recalculate_bom_cost.py
Normal file
16
erpnext/patches/v4_2/recalculate_bom_cost.py
Normal file
@ -0,0 +1,16 @@
|
||||
# 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():
|
||||
for d in frappe.db.sql("select name from `tabBOM` where docstatus < 2"):
|
||||
try:
|
||||
document = frappe.get_doc('BOM', d[0])
|
||||
if document.docstatus == 1:
|
||||
document.ignore_validate_update_after_submit = True
|
||||
document.calculate_cost()
|
||||
document.save()
|
||||
except:
|
||||
pass
|
@ -138,9 +138,20 @@ erpnext.StockAnalytics = erpnext.StockGridReport.extend({
|
||||
item.valuation_method : sys_defaults.valuation_method;
|
||||
var is_fifo = valuation_method == "FIFO";
|
||||
|
||||
var diff = me.get_value_diff(wh, sl, is_fifo);
|
||||
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.balance_qty = sl.qty_after_transaction;
|
||||
wh.balance_value = sl.valuation_rate * sl.qty_after_transaction;
|
||||
} else {
|
||||
var diff = me.get_value_diff(wh, sl, is_fifo);
|
||||
}
|
||||
} else {
|
||||
var diff = sl.qty;
|
||||
if(sl.voucher_type=="Stock Reconciliation") {
|
||||
var diff = sl.qty_after_transaction - item.closing_qty_value;
|
||||
} else {
|
||||
var diff = sl.qty;
|
||||
}
|
||||
}
|
||||
|
||||
if(posting_datetime < from_date) {
|
||||
@ -150,6 +161,8 @@ erpnext.StockAnalytics = erpnext.StockGridReport.extend({
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
item.closing_qty_value += diff;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -9,8 +9,8 @@ erpnext.StockGridReport = frappe.views.TreeGridReport.extend({
|
||||
};
|
||||
return this.item_warehouse[item][warehouse];
|
||||
},
|
||||
|
||||
get_value_diff: function(wh, sl, is_fifo) {
|
||||
|
||||
get_value_diff: function(wh, sl, is_fifo) {
|
||||
// value
|
||||
if(sl.qty > 0) {
|
||||
// incoming - rate is given
|
||||
@ -30,9 +30,9 @@ erpnext.StockGridReport = frappe.views.TreeGridReport.extend({
|
||||
} else {
|
||||
var value_diff = (rate * add_qty);
|
||||
}
|
||||
|
||||
|
||||
if(add_qty)
|
||||
wh.fifo_stack.push([add_qty, sl.incoming_rate, sl.posting_date]);
|
||||
wh.fifo_stack.push([add_qty, sl.incoming_rate, sl.posting_date]);
|
||||
} else {
|
||||
// called everytime for maintaining fifo stack
|
||||
var fifo_value_diff = this.get_fifo_value_diff(wh, sl);
|
||||
@ -44,13 +44,13 @@ erpnext.StockGridReport = frappe.views.TreeGridReport.extend({
|
||||
var value_diff = fifo_value_diff;
|
||||
} else {
|
||||
// average rate for weighted average
|
||||
var rate = (wh.balance_qty.toFixed(2) == 0.00 ? 0 :
|
||||
var rate = (wh.balance_qty.toFixed(2) == 0.00 ? 0 :
|
||||
flt(wh.balance_value) / flt(wh.balance_qty));
|
||||
|
||||
|
||||
// no change in value if negative qty
|
||||
if((wh.balance_qty + sl.qty).toFixed(2) >= 0.00)
|
||||
var value_diff = (rate * sl.qty);
|
||||
else
|
||||
else
|
||||
var value_diff = -wh.balance_value;
|
||||
}
|
||||
}
|
||||
@ -58,7 +58,6 @@ erpnext.StockGridReport = frappe.views.TreeGridReport.extend({
|
||||
// update balance (only needed in case of valuation)
|
||||
wh.balance_qty += sl.qty;
|
||||
wh.balance_value += value_diff;
|
||||
|
||||
return value_diff;
|
||||
},
|
||||
get_fifo_value_diff: function(wh, sl) {
|
||||
@ -66,19 +65,19 @@ erpnext.StockGridReport = frappe.views.TreeGridReport.extend({
|
||||
var fifo_stack = (wh.fifo_stack || []).reverse();
|
||||
var fifo_value_diff = 0.0;
|
||||
var qty = -sl.qty;
|
||||
|
||||
|
||||
for(var i=0, j=fifo_stack.length; i<j; i++) {
|
||||
var batch = fifo_stack.pop();
|
||||
if(batch[0] >= qty) {
|
||||
batch[0] = batch[0] - qty;
|
||||
fifo_value_diff += (qty * batch[1]);
|
||||
|
||||
|
||||
qty = 0.0;
|
||||
if(batch[0]) {
|
||||
// batch still has qty put it back
|
||||
fifo_stack.push(batch);
|
||||
}
|
||||
|
||||
|
||||
// all qty found
|
||||
break;
|
||||
} else {
|
||||
@ -87,35 +86,34 @@ erpnext.StockGridReport = frappe.views.TreeGridReport.extend({
|
||||
qty = qty - batch[0];
|
||||
}
|
||||
}
|
||||
|
||||
// reset the updated stack
|
||||
wh.fifo_stack = fifo_stack.reverse();
|
||||
return -fifo_value_diff;
|
||||
},
|
||||
|
||||
|
||||
get_serialized_value_diff: function(sl) {
|
||||
var me = this;
|
||||
|
||||
|
||||
var value_diff = 0.0;
|
||||
|
||||
|
||||
$.each(sl.serial_no.trim().split("\n"), function(i, sr) {
|
||||
if(sr) {
|
||||
value_diff += flt(me.serialized_buying_rates[sr.trim().toLowerCase()]);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return value_diff;
|
||||
},
|
||||
|
||||
|
||||
get_serialized_buying_rates: function() {
|
||||
var serialized_buying_rates = {};
|
||||
|
||||
|
||||
if (frappe.report_dump.data["Serial No"]) {
|
||||
$.each(frappe.report_dump.data["Serial No"], function(i, sn) {
|
||||
serialized_buying_rates[sn.name.toLowerCase()] = flt(sn.incoming_rate);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return serialized_buying_rates;
|
||||
},
|
||||
});
|
||||
});
|
||||
|
@ -921,6 +921,18 @@
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "Select the period when the invoice will be generated automatically",
|
||||
"fieldname": "recurring_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Recurring Type",
|
||||
"no_copy": 1,
|
||||
"options": "\nMonthly\nQuarterly\nHalf-yearly\nYearly",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
@ -941,18 +953,6 @@
|
||||
"no_copy": 1,
|
||||
"permlevel": 0
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "Select the period when the invoice will be generated automatically",
|
||||
"fieldname": "recurring_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Recurring Type",
|
||||
"no_copy": 1,
|
||||
"options": "\nMonthly\nQuarterly\nHalf-yearly\nYearly",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1
|
||||
},
|
||||
{
|
||||
"allow_on_submit": 1,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
@ -1020,7 +1020,7 @@
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"issingle": 0,
|
||||
"modified": "2014-10-06 12:16:41.256013",
|
||||
"modified": "2014-10-08 14:22:44.717108",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Selling",
|
||||
"name": "Sales Order",
|
||||
|
@ -78,9 +78,10 @@ def setup_account(args=None):
|
||||
frappe.db.commit()
|
||||
|
||||
except:
|
||||
traceback = frappe.get_traceback()
|
||||
for hook in frappe.get_hooks("setup_wizard_exception"):
|
||||
frappe.get_attr(hook)(traceback, args)
|
||||
if args:
|
||||
traceback = frappe.get_traceback()
|
||||
for hook in frappe.get_hooks("setup_wizard_exception"):
|
||||
frappe.get_attr(hook)(traceback, args)
|
||||
|
||||
raise
|
||||
|
||||
|
@ -78,7 +78,8 @@ data_map = {
|
||||
"Stock Ledger Entry": {
|
||||
"columns": ["name", "posting_date", "posting_time", "item_code", "warehouse",
|
||||
"actual_qty as qty", "voucher_type", "voucher_no", "project",
|
||||
"ifnull(incoming_rate,0) as incoming_rate", "stock_uom", "serial_no"],
|
||||
"ifnull(incoming_rate,0) as incoming_rate", "stock_uom", "serial_no",
|
||||
"qty_after_transaction", "valuation_rate"],
|
||||
"order_by": "posting_date, posting_time, name",
|
||||
"links": {
|
||||
"item_code": ["Item", "name"],
|
||||
|
@ -11,27 +11,27 @@ class Bin(Document):
|
||||
def validate(self):
|
||||
if self.get("__islocal") or not self.stock_uom:
|
||||
self.stock_uom = frappe.db.get_value('Item', self.item_code, 'stock_uom')
|
||||
|
||||
|
||||
self.validate_mandatory()
|
||||
|
||||
|
||||
self.projected_qty = flt(self.actual_qty) + flt(self.ordered_qty) + \
|
||||
flt(self.indented_qty) + flt(self.planned_qty) - flt(self.reserved_qty)
|
||||
|
||||
|
||||
def validate_mandatory(self):
|
||||
qf = ['actual_qty', 'reserved_qty', 'ordered_qty', 'indented_qty']
|
||||
for f in qf:
|
||||
if (not getattr(self, f, None)) or (not self.get(f)):
|
||||
if (not getattr(self, f, None)) or (not self.get(f)):
|
||||
self.set(f, 0.0)
|
||||
|
||||
|
||||
def update_stock(self, args):
|
||||
self.update_qty(args)
|
||||
|
||||
if args.get("actual_qty"):
|
||||
|
||||
if args.get("actual_qty") or args.get("voucher_type") == "Stock Reconciliation":
|
||||
from erpnext.stock.stock_ledger import update_entries_after
|
||||
|
||||
|
||||
if not args.get("posting_date"):
|
||||
args["posting_date"] = nowdate()
|
||||
|
||||
|
||||
# update valuation and qty after transaction for post dated entry
|
||||
update_entries_after({
|
||||
"item_code": self.item_code,
|
||||
@ -39,21 +39,34 @@ class Bin(Document):
|
||||
"posting_date": args.get("posting_date"),
|
||||
"posting_time": args.get("posting_time")
|
||||
})
|
||||
|
||||
|
||||
def update_qty(self, args):
|
||||
# update the stock values (for current quantities)
|
||||
|
||||
self.actual_qty = flt(self.actual_qty) + flt(args.get("actual_qty"))
|
||||
if args.get("voucher_type")=="Stock Reconciliation":
|
||||
if args.get('is_cancelled') == 'No':
|
||||
self.actual_qty = args.get("qty_after_transaction")
|
||||
else:
|
||||
qty_after_transaction = frappe.db.get_value("""select qty_after_transaction
|
||||
from `tabStock Ledger Entry`
|
||||
where item_code=%s and warehouse=%s
|
||||
and not (voucher_type='Stock Reconciliation' and voucher_no=%s)
|
||||
order by posting_date desc limit 1""",
|
||||
(self.item_code, self.warehouse, args.get('voucher_no')))
|
||||
|
||||
self.actual_qty = flt(qty_after_transaction[0][0]) if qty_after_transaction else 0.0
|
||||
else:
|
||||
self.actual_qty = flt(self.actual_qty) + flt(args.get("actual_qty"))
|
||||
|
||||
self.ordered_qty = flt(self.ordered_qty) + flt(args.get("ordered_qty"))
|
||||
self.reserved_qty = flt(self.reserved_qty) + flt(args.get("reserved_qty"))
|
||||
self.indented_qty = flt(self.indented_qty) + flt(args.get("indented_qty"))
|
||||
self.planned_qty = flt(self.planned_qty) + flt(args.get("planned_qty"))
|
||||
|
||||
|
||||
self.projected_qty = flt(self.actual_qty) + flt(self.ordered_qty) + \
|
||||
flt(self.indented_qty) + flt(self.planned_qty) - flt(self.reserved_qty)
|
||||
|
||||
|
||||
self.save()
|
||||
|
||||
|
||||
def get_first_sle(self):
|
||||
sle = frappe.db.sql("""
|
||||
select * from `tabStock Ledger Entry`
|
||||
@ -62,4 +75,4 @@ class Bin(Document):
|
||||
order by timestamp(posting_date, posting_time) asc, name asc
|
||||
limit 1
|
||||
""", (self.item_code, self.warehouse), as_dict=1)
|
||||
return sle and sle[0] or None
|
||||
return sle and sle[0] or None
|
||||
|
@ -97,10 +97,10 @@ class LandedCostVoucher(Document):
|
||||
|
||||
# update stock & gl entries for cancelled state of PR
|
||||
pr.docstatus = 2
|
||||
pr.update_stock()
|
||||
pr.update_stock_ledger()
|
||||
pr.make_gl_entries_on_cancel()
|
||||
|
||||
# update stock & gl entries for submit state of PR
|
||||
pr.docstatus = 1
|
||||
pr.update_stock()
|
||||
pr.update_stock_ledger()
|
||||
pr.make_gl_entries()
|
||||
|
@ -130,7 +130,7 @@ class PurchaseReceipt(BuyingController):
|
||||
if not d.prevdoc_docname:
|
||||
frappe.throw(_("Purchase Order number required for Item {0}").format(d.item_code))
|
||||
|
||||
def update_stock(self):
|
||||
def update_stock_ledger(self):
|
||||
sl_entries = []
|
||||
stock_items = self.get_stock_items()
|
||||
|
||||
@ -234,7 +234,7 @@ class PurchaseReceipt(BuyingController):
|
||||
|
||||
self.update_ordered_qty()
|
||||
|
||||
self.update_stock()
|
||||
self.update_stock_ledger()
|
||||
|
||||
from erpnext.stock.doctype.serial_no.serial_no import update_serial_nos_after_submit
|
||||
update_serial_nos_after_submit(self, "purchase_receipt_details")
|
||||
@ -267,7 +267,7 @@ class PurchaseReceipt(BuyingController):
|
||||
|
||||
self.update_ordered_qty()
|
||||
|
||||
self.update_stock()
|
||||
self.update_stock_ledger()
|
||||
|
||||
self.update_prevdoc_status()
|
||||
pc_obj.update_last_purchase_rate(self, 0)
|
||||
@ -283,8 +283,11 @@ class PurchaseReceipt(BuyingController):
|
||||
def get_rate(self,arg):
|
||||
return frappe.get_doc('Purchase Common').get_rate(arg,self)
|
||||
|
||||
def get_gl_entries(self, warehouse_account=None):
|
||||
def get_gl_entries(self, warehouse_account=None, allow_negative_stock=False):
|
||||
from erpnext.accounts.general_ledger import process_gl_map
|
||||
from erpnext.controllers.stock_controller import block_negative_stock
|
||||
|
||||
block_negative_stock(allow_negative_stock)
|
||||
|
||||
stock_rbnb = self.get_company_default("stock_received_but_not_billed")
|
||||
expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
|
||||
|
@ -95,7 +95,7 @@ class TestPurchaseReceipt(unittest.TestCase):
|
||||
pr.insert()
|
||||
|
||||
self.assertEquals(len(pr.get("pr_raw_material_details")), 2)
|
||||
self.assertEquals(pr.get("purchase_receipt_details")[0].rm_supp_cost, 70000.0)
|
||||
self.assertEquals(pr.get("purchase_receipt_details")[0].rm_supp_cost, 20750.0)
|
||||
|
||||
|
||||
def test_serial_no_supplier(self):
|
||||
|
@ -9,14 +9,64 @@ from erpnext.stock.doctype.serial_no.serial_no import *
|
||||
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import set_perpetual_inventory
|
||||
from erpnext.stock.doctype.stock_ledger_entry.stock_ledger_entry import StockFreezeError
|
||||
|
||||
def get_sle(**args):
|
||||
condition, values = "", []
|
||||
for key, value in args.iteritems():
|
||||
condition += " and " if condition else " where "
|
||||
condition += "`{0}`=%s".format(key)
|
||||
values.append(value)
|
||||
|
||||
return frappe.db.sql("""select * from `tabStock Ledger Entry` %s
|
||||
order by timestamp(posting_date, posting_time) desc, name desc limit 1"""% condition,
|
||||
values, as_dict=1)
|
||||
|
||||
def make_zero(item_code, warehouse):
|
||||
sle = get_sle(item_code = item_code, warehouse = warehouse)
|
||||
qty = sle[0].qty_after_transaction if sle else 0
|
||||
if qty < 0:
|
||||
make_stock_entry(item_code, None, warehouse, abs(qty), incoming_rate=10)
|
||||
elif qty > 0:
|
||||
make_stock_entry(item_code, warehouse, None, qty, incoming_rate=10)
|
||||
|
||||
class TestStockEntry(unittest.TestCase):
|
||||
|
||||
def tearDown(self):
|
||||
frappe.set_user("Administrator")
|
||||
set_perpetual_inventory(0)
|
||||
if hasattr(self, "old_default_company"):
|
||||
frappe.db.set_default("company", self.old_default_company)
|
||||
|
||||
def test_fifo(self):
|
||||
frappe.db.set_default("allow_negative_stock", 1)
|
||||
item_code = "_Test Item 2"
|
||||
warehouse = "_Test Warehouse - _TC"
|
||||
make_zero(item_code, warehouse)
|
||||
|
||||
make_stock_entry(item_code, None, warehouse, 1, incoming_rate=10)
|
||||
sle = get_sle(item_code = item_code, warehouse = warehouse)[0]
|
||||
|
||||
self.assertEqual([[1, 10]], eval(sle.stock_queue))
|
||||
|
||||
# negative qty
|
||||
make_zero(item_code, warehouse)
|
||||
make_stock_entry(item_code, warehouse, None, 1, incoming_rate=10)
|
||||
sle = get_sle(item_code = item_code, warehouse = warehouse)[0]
|
||||
|
||||
self.assertEqual([[-1, 10]], eval(sle.stock_queue))
|
||||
|
||||
# further negative
|
||||
make_stock_entry(item_code, warehouse, None, 1)
|
||||
sle = get_sle(item_code = item_code, warehouse = warehouse)[0]
|
||||
|
||||
self.assertEqual([[-2, 10]], eval(sle.stock_queue))
|
||||
|
||||
# move stock to positive
|
||||
make_stock_entry(item_code, None, warehouse, 3, incoming_rate=10)
|
||||
sle = get_sle(item_code = item_code, warehouse = warehouse)[0]
|
||||
|
||||
self.assertEqual([[1, 10]], eval(sle.stock_queue))
|
||||
|
||||
frappe.db.set_default("allow_negative_stock", 0)
|
||||
|
||||
def test_auto_material_request(self):
|
||||
frappe.db.sql("""delete from `tabMaterial Request Item`""")
|
||||
frappe.db.sql("""delete from `tabMaterial Request`""")
|
||||
@ -821,19 +871,19 @@ class TestStockEntry(unittest.TestCase):
|
||||
se = frappe.copy_doc(test_records[0]).insert()
|
||||
self.assertRaises (StockFreezeError, se.submit)
|
||||
frappe.db.set_value("Stock Settings", None, "stock_frozen_upto_days", 0)
|
||||
|
||||
|
||||
def test_production_order(self):
|
||||
bom_no = frappe.db.get_value("BOM", {"item": "_Test FG Item 2",
|
||||
bom_no = frappe.db.get_value("BOM", {"item": "_Test FG Item 2",
|
||||
"is_default": 1, "docstatus": 1})
|
||||
|
||||
|
||||
production_order = frappe.new_doc("Production Order")
|
||||
production_order.update({
|
||||
"company": "_Test Company",
|
||||
"fg_warehouse": "_Test Warehouse 1 - _TC",
|
||||
"production_item": "_Test FG Item 2",
|
||||
"fg_warehouse": "_Test Warehouse 1 - _TC",
|
||||
"production_item": "_Test FG Item 2",
|
||||
"bom_no": bom_no,
|
||||
"qty": 1.0,
|
||||
"stock_uom": "Nos",
|
||||
"stock_uom": "Nos",
|
||||
"wip_warehouse": "_Test Warehouse - _TC"
|
||||
})
|
||||
production_order.insert()
|
||||
|
@ -44,11 +44,14 @@ class StockLedgerEntry(Document):
|
||||
formatdate(self.posting_date), self.posting_time))
|
||||
|
||||
def validate_mandatory(self):
|
||||
mandatory = ['warehouse','posting_date','voucher_type','voucher_no','actual_qty','company']
|
||||
mandatory = ['warehouse','posting_date','voucher_type','voucher_no','company']
|
||||
for k in mandatory:
|
||||
if not self.get(k):
|
||||
frappe.throw(_("{0} is required").format(self.meta.get_label(k)))
|
||||
|
||||
if self.voucher_type != "Stock Reconciliation" and not self.actual_qty:
|
||||
frappe.throw(_("Actual Qty is mandatory"))
|
||||
|
||||
def validate_item(self):
|
||||
item_det = frappe.db.sql("""select name, has_batch_no, docstatus, is_stock_item
|
||||
from tabItem where name=%s""", self.item_code, as_dict=True)[0]
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"allow_copy": 1,
|
||||
"allow_copy": 1,
|
||||
"autoname": "SR/.######",
|
||||
"creation": "2013-03-28 10:35:31",
|
||||
"description": "This tool helps you to update or fix the quantity and valuation of stock in the system. It is typically used to synchronise the system values and what actually exists in your warehouses.",
|
||||
@ -7,6 +7,7 @@
|
||||
"doctype": "DocType",
|
||||
"fields": [
|
||||
{
|
||||
"default": "Today",
|
||||
"fieldname": "posting_date",
|
||||
"fieldtype": "Date",
|
||||
"in_filter": 0,
|
||||
@ -118,7 +119,7 @@
|
||||
"idx": 1,
|
||||
"is_submittable": 1,
|
||||
"max_attachments": 1,
|
||||
"modified": "2014-05-26 03:05:54.024413",
|
||||
"modified": "2014-10-07 12:43:52.825575",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Stock Reconciliation",
|
||||
|
@ -16,13 +16,11 @@ class StockReconciliation(StockController):
|
||||
self.head_row = ["Item Code", "Warehouse", "Quantity", "Valuation Rate"]
|
||||
|
||||
def validate(self):
|
||||
self.entries = []
|
||||
|
||||
self.validate_data()
|
||||
self.validate_expense_account()
|
||||
|
||||
def on_submit(self):
|
||||
self.insert_stock_ledger_entries()
|
||||
self.update_stock_ledger()
|
||||
self.make_gl_entries()
|
||||
|
||||
def on_cancel(self):
|
||||
@ -126,10 +124,9 @@ class StockReconciliation(StockController):
|
||||
except Exception, e:
|
||||
self.validation_messages.append(_("Row # ") + ("%d: " % (row_num)) + cstr(e))
|
||||
|
||||
def insert_stock_ledger_entries(self):
|
||||
def update_stock_ledger(self):
|
||||
""" find difference between current and expected entries
|
||||
and create stock ledger entries based on the difference"""
|
||||
from erpnext.stock.utils import get_valuation_method
|
||||
from erpnext.stock.stock_ledger import get_previous_sle
|
||||
|
||||
row_template = ["item_code", "warehouse", "qty", "valuation_rate"]
|
||||
@ -141,105 +138,27 @@ class StockReconciliation(StockController):
|
||||
for row_num, row in enumerate(data[data.index(self.head_row)+1:]):
|
||||
row = frappe._dict(zip(row_template, row))
|
||||
row["row_num"] = row_num
|
||||
previous_sle = get_previous_sle({
|
||||
"item_code": row.item_code,
|
||||
"warehouse": row.warehouse,
|
||||
"posting_date": self.posting_date,
|
||||
"posting_time": self.posting_time
|
||||
})
|
||||
|
||||
# check valuation rate mandatory
|
||||
if row.qty not in ["", None] and not row.valuation_rate and \
|
||||
flt(previous_sle.get("qty_after_transaction")) <= 0:
|
||||
frappe.throw(_("Valuation Rate required for Item {0}").format(row.item_code))
|
||||
if row.qty in ("", None) or row.valuation_rate in ("", None):
|
||||
previous_sle = get_previous_sle({
|
||||
"item_code": row.item_code,
|
||||
"warehouse": row.warehouse,
|
||||
"posting_date": self.posting_date,
|
||||
"posting_time": self.posting_time
|
||||
})
|
||||
|
||||
change_in_qty = row.qty not in ["", None] and \
|
||||
(flt(row.qty) - flt(previous_sle.get("qty_after_transaction")))
|
||||
if row.qty in ("", None):
|
||||
row.qty = previous_sle.get("qty_after_transaction")
|
||||
|
||||
change_in_rate = row.valuation_rate not in ["", None] and \
|
||||
(flt(row.valuation_rate) - flt(previous_sle.get("valuation_rate")))
|
||||
if row.valuation_rate in ("", None):
|
||||
row.valuation_rate = previous_sle.get("valuation_rate")
|
||||
|
||||
if get_valuation_method(row.item_code) == "Moving Average":
|
||||
self.sle_for_moving_avg(row, previous_sle, change_in_qty, change_in_rate)
|
||||
# if row.qty and not row.valuation_rate:
|
||||
# frappe.throw(_("Valuation Rate required for Item {0}").format(row.item_code))
|
||||
|
||||
else:
|
||||
self.sle_for_fifo(row, previous_sle, change_in_qty, change_in_rate)
|
||||
self.insert_entries(row)
|
||||
|
||||
def sle_for_moving_avg(self, row, previous_sle, change_in_qty, change_in_rate):
|
||||
"""Insert Stock Ledger Entries for Moving Average valuation"""
|
||||
def _get_incoming_rate(qty, valuation_rate, previous_qty, previous_valuation_rate):
|
||||
if previous_valuation_rate == 0:
|
||||
return flt(valuation_rate)
|
||||
else:
|
||||
if valuation_rate in ["", None]:
|
||||
valuation_rate = previous_valuation_rate
|
||||
return (qty * valuation_rate - previous_qty * previous_valuation_rate) \
|
||||
/ flt(qty - previous_qty)
|
||||
|
||||
if change_in_qty:
|
||||
# if change in qty, irrespective of change in rate
|
||||
incoming_rate = _get_incoming_rate(flt(row.qty), flt(row.valuation_rate),
|
||||
flt(previous_sle.get("qty_after_transaction")), flt(previous_sle.get("valuation_rate")))
|
||||
|
||||
row["voucher_detail_no"] = "Row: " + cstr(row.row_num) + "/Actual Entry"
|
||||
self.insert_entries({"actual_qty": change_in_qty, "incoming_rate": incoming_rate}, row)
|
||||
|
||||
elif change_in_rate and flt(previous_sle.get("qty_after_transaction")) > 0:
|
||||
# if no change in qty, but change in rate
|
||||
# and positive actual stock before this reconciliation
|
||||
incoming_rate = _get_incoming_rate(
|
||||
flt(previous_sle.get("qty_after_transaction"))+1, flt(row.valuation_rate),
|
||||
flt(previous_sle.get("qty_after_transaction")),
|
||||
flt(previous_sle.get("valuation_rate")))
|
||||
|
||||
# +1 entry
|
||||
row["voucher_detail_no"] = "Row: " + cstr(row.row_num) + "/Valuation Adjustment +1"
|
||||
self.insert_entries({"actual_qty": 1, "incoming_rate": incoming_rate}, row)
|
||||
|
||||
# -1 entry
|
||||
row["voucher_detail_no"] = "Row: " + cstr(row.row_num) + "/Valuation Adjustment -1"
|
||||
self.insert_entries({"actual_qty": -1}, row)
|
||||
|
||||
def sle_for_fifo(self, row, previous_sle, change_in_qty, change_in_rate):
|
||||
"""Insert Stock Ledger Entries for FIFO valuation"""
|
||||
previous_stock_queue = json.loads(previous_sle.get("stock_queue") or "[]")
|
||||
previous_stock_qty = sum((batch[0] for batch in previous_stock_queue))
|
||||
previous_stock_value = sum((batch[0] * batch[1] for batch in \
|
||||
previous_stock_queue))
|
||||
|
||||
def _insert_entries():
|
||||
if previous_stock_queue != [[row.qty, row.valuation_rate]]:
|
||||
# make entry as per attachment
|
||||
if flt(row.qty):
|
||||
row["voucher_detail_no"] = "Row: " + cstr(row.row_num) + "/Actual Entry"
|
||||
self.insert_entries({"actual_qty": row.qty,
|
||||
"incoming_rate": flt(row.valuation_rate)}, row)
|
||||
|
||||
# Make reverse entry
|
||||
if previous_stock_qty:
|
||||
row["voucher_detail_no"] = "Row: " + cstr(row.row_num) + "/Reverse Entry"
|
||||
self.insert_entries({"actual_qty": -1 * previous_stock_qty,
|
||||
"incoming_rate": previous_stock_qty < 0 and
|
||||
flt(row.valuation_rate) or 0}, row)
|
||||
|
||||
|
||||
if change_in_qty:
|
||||
if row.valuation_rate in ["", None]:
|
||||
# dont want change in valuation
|
||||
if previous_stock_qty > 0:
|
||||
# set valuation_rate as previous valuation_rate
|
||||
row.valuation_rate = previous_stock_value / flt(previous_stock_qty)
|
||||
|
||||
_insert_entries()
|
||||
|
||||
elif change_in_rate and previous_stock_qty > 0:
|
||||
# if no change in qty, but change in rate
|
||||
# and positive actual stock before this reconciliation
|
||||
|
||||
row.qty = previous_stock_qty
|
||||
_insert_entries()
|
||||
|
||||
def insert_entries(self, opts, row):
|
||||
def insert_entries(self, row):
|
||||
"""Insert Stock Ledger Entries"""
|
||||
args = frappe._dict({
|
||||
"doctype": "Stock Ledger Entry",
|
||||
@ -251,16 +170,13 @@ class StockReconciliation(StockController):
|
||||
"voucher_no": self.name,
|
||||
"company": self.company,
|
||||
"stock_uom": frappe.db.get_value("Item", row.item_code, "stock_uom"),
|
||||
"voucher_detail_no": row.voucher_detail_no,
|
||||
"fiscal_year": self.fiscal_year,
|
||||
"is_cancelled": "No"
|
||||
"is_cancelled": "No",
|
||||
"qty_after_transaction": row.qty,
|
||||
"valuation_rate": row.valuation_rate
|
||||
})
|
||||
args.update(opts)
|
||||
self.make_sl_entries([args])
|
||||
|
||||
# append to entries
|
||||
self.entries.append(args)
|
||||
|
||||
def delete_and_repost_sle(self):
|
||||
""" Delete Stock Ledger Entries related to this voucher
|
||||
and repost future Stock Ledger Entries"""
|
||||
@ -282,12 +198,12 @@ class StockReconciliation(StockController):
|
||||
"posting_time": self.posting_time
|
||||
})
|
||||
|
||||
def get_gl_entries(self, warehouse_account=None):
|
||||
def get_gl_entries(self, warehouse_account=None, allow_negative_stock=False):
|
||||
if not self.cost_center:
|
||||
msgprint(_("Please enter Cost Center"), raise_exception=1)
|
||||
|
||||
return super(StockReconciliation, self).get_gl_entries(warehouse_account,
|
||||
self.expense_account, self.cost_center)
|
||||
self.expense_account, self.cost_center, allow_negative_stock=allow_negative_stock)
|
||||
|
||||
def validate_expense_account(self):
|
||||
if not cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
@ -295,7 +211,7 @@ class StockReconciliation(StockController):
|
||||
|
||||
if not self.expense_account:
|
||||
msgprint(_("Please enter Expense Account"), raise_exception=1)
|
||||
elif not frappe.db.sql("""select * from `tabStock Ledger Entry`"""):
|
||||
elif not frappe.db.sql("""select name from `tabStock Ledger Entry` limit 1"""):
|
||||
if frappe.db.get_value("Account", self.expense_account, "report_type") == "Profit and Loss":
|
||||
frappe.throw(_("Difference Account must be a 'Liability' type account, since this Stock Reconciliation is an Opening Entry"))
|
||||
|
||||
|
@ -28,7 +28,7 @@ class TestStockReconciliation(unittest.TestCase):
|
||||
[20, "", "2012-12-26", "12:05", 16000, 15, 18000],
|
||||
[10, 2000, "2012-12-26", "12:10", 20000, 5, 6000],
|
||||
[1, 1000, "2012-12-01", "00:00", 1000, 11, 13200],
|
||||
[0, "", "2012-12-26", "12:10", 0, -5, 0]
|
||||
[0, "", "2012-12-26", "12:10", 0, -5, -6000]
|
||||
]
|
||||
|
||||
for d in input_data:
|
||||
@ -63,16 +63,16 @@ class TestStockReconciliation(unittest.TestCase):
|
||||
input_data = [
|
||||
[50, 1000, "2012-12-26", "12:00", 50000, 45, 48000],
|
||||
[5, 1000, "2012-12-26", "12:00", 5000, 0, 0],
|
||||
[15, 1000, "2012-12-26", "12:00", 15000, 10, 12000],
|
||||
[15, 1000, "2012-12-26", "12:00", 15000, 10, 11500],
|
||||
[25, 900, "2012-12-26", "12:00", 22500, 20, 22500],
|
||||
[20, 500, "2012-12-26", "12:00", 10000, 15, 18000],
|
||||
[50, 1000, "2013-01-01", "12:00", 50000, 65, 68000],
|
||||
[5, 1000, "2013-01-01", "12:00", 5000, 20, 23000],
|
||||
["", 1000, "2012-12-26", "12:05", 15000, 10, 12000],
|
||||
["", 1000, "2012-12-26", "12:05", 15000, 10, 11500],
|
||||
[20, "", "2012-12-26", "12:05", 18000, 15, 18000],
|
||||
[10, 2000, "2012-12-26", "12:10", 20000, 5, 6000],
|
||||
[1, 1000, "2012-12-01", "00:00", 1000, 11, 13200],
|
||||
[0, "", "2012-12-26", "12:10", 0, -5, 0]
|
||||
[10, 2000, "2012-12-26", "12:10", 20000, 5, 7600],
|
||||
[1, 1000, "2012-12-01", "00:00", 1000, 11, 12512.73],
|
||||
[0, "", "2012-12-26", "12:10", 0, -5, -5142.86]
|
||||
|
||||
]
|
||||
|
||||
|
@ -6,18 +6,20 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
|
||||
from frappe.utils import cint
|
||||
from frappe.model.document import Document
|
||||
|
||||
class StockSettings(Document):
|
||||
|
||||
def validate(self):
|
||||
for key in ["item_naming_by", "item_group", "stock_uom",
|
||||
"allow_negative_stock"]:
|
||||
if cint(self.allow_negative_stock) and cint(frappe.defaults.get_global_default("auto_accounting_for_stock")):
|
||||
frappe.throw(_("Negative stock is not allowed in case of Perpetual Inventory"))
|
||||
|
||||
for key in ["item_naming_by", "item_group", "stock_uom", "allow_negative_stock"]:
|
||||
frappe.db.set_default(key, self.get(key, ""))
|
||||
|
||||
|
||||
from erpnext.setup.doctype.naming_series.naming_series import set_by_naming_series
|
||||
set_by_naming_series("Item", "item_code",
|
||||
set_by_naming_series("Item", "item_code",
|
||||
self.get("item_naming_by")=="Naming Series", hide_name_field=True)
|
||||
|
||||
stock_frozen_limit = 356
|
||||
@ -25,3 +27,5 @@ class StockSettings(Document):
|
||||
if submitted_stock_frozen > stock_frozen_limit:
|
||||
self.stock_frozen_upto_days = stock_frozen_limit
|
||||
frappe.msgprint (_("`Freeze Stocks Older Than` should be smaller than %d days.") %stock_frozen_limit)
|
||||
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
Stock balances on a particular day, per warehouse.
|
@ -1,181 +0,0 @@
|
||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
|
||||
frappe.require("assets/erpnext/js/stock_analytics.js");
|
||||
|
||||
frappe.pages['stock-balance'].onload = function(wrapper) {
|
||||
frappe.ui.make_app_page({
|
||||
parent: wrapper,
|
||||
title: __('Stock Balance'),
|
||||
single_column: true
|
||||
});
|
||||
|
||||
new erpnext.StockBalance(wrapper);
|
||||
|
||||
wrapper.appframe.add_module_icon("Stock");
|
||||
}
|
||||
|
||||
erpnext.StockBalance = erpnext.StockAnalytics.extend({
|
||||
init: function(wrapper) {
|
||||
this._super(wrapper, {
|
||||
title: __("Stock Balance"),
|
||||
doctypes: ["Item", "Item Group", "Warehouse", "Stock Ledger Entry", "Brand",
|
||||
"Stock Entry", "Project", "Serial No"],
|
||||
});
|
||||
},
|
||||
setup_columns: function() {
|
||||
this.columns = [
|
||||
{id: "name", name: __("Item"), field: "name", width: 300,
|
||||
formatter: this.tree_formatter},
|
||||
{id: "item_name", name: __("Item Name"), field: "item_name", width: 100},
|
||||
{id: "description", name: __("Description"), field: "description", width: 200,
|
||||
formatter: this.text_formatter},
|
||||
{id: "brand", name: __("Brand"), field: "brand", width: 100},
|
||||
{id: "stock_uom", name: __("UOM"), field: "stock_uom", width: 100},
|
||||
{id: "opening_qty", name: __("Opening Qty"), field: "opening_qty", width: 100,
|
||||
formatter: this.currency_formatter},
|
||||
{id: "inflow_qty", name: __("In Qty"), field: "inflow_qty", width: 100,
|
||||
formatter: this.currency_formatter},
|
||||
{id: "outflow_qty", name: __("Out Qty"), field: "outflow_qty", width: 100,
|
||||
formatter: this.currency_formatter},
|
||||
{id: "closing_qty", name: __("Closing Qty"), field: "closing_qty", width: 100,
|
||||
formatter: this.currency_formatter},
|
||||
|
||||
{id: "opening_value", name: __("Opening Value"), field: "opening_value", width: 100,
|
||||
formatter: this.currency_formatter},
|
||||
{id: "inflow_value", name: __("In Value"), field: "inflow_value", width: 100,
|
||||
formatter: this.currency_formatter},
|
||||
{id: "outflow_value", name: __("Out Value"), field: "outflow_value", width: 100,
|
||||
formatter: this.currency_formatter},
|
||||
{id: "closing_value", name: __("Closing Value"), field: "closing_value", width: 100,
|
||||
formatter: this.currency_formatter},
|
||||
{id: "valuation_rate", name: __("Valuation Rate"), field: "valuation_rate", width: 100,
|
||||
formatter: this.currency_formatter},
|
||||
];
|
||||
},
|
||||
|
||||
filters: [
|
||||
{fieldtype:"Select", label: __("Brand"), link:"Brand", fieldname: "brand",
|
||||
default_value: __("Select Brand..."), filter: function(val, item, opts) {
|
||||
return val == opts.default_value || item.brand == val || item._show;
|
||||
}, link_formatter: {filter_input: "brand"}},
|
||||
{fieldtype:"Select", label: __("Warehouse"), link:"Warehouse", fieldname: "warehouse",
|
||||
default_value: __("Select Warehouse..."), filter: function(val, item, opts, me) {
|
||||
return me.apply_zero_filter(val, item, opts, me);
|
||||
}},
|
||||
{fieldtype:"Select", label: __("Project"), link:"Project", fieldname: "project",
|
||||
default_value: __("Select Project..."), filter: function(val, item, opts, me) {
|
||||
return me.apply_zero_filter(val, item, opts, me);
|
||||
}, link_formatter: {filter_input: "project"}},
|
||||
{fieldtype:"Date", label: __("From Date"), fieldname: "from_date"},
|
||||
{fieldtype:"Label", label: __("To")},
|
||||
{fieldtype:"Date", label: __("To Date"), fieldname: "to_date"},
|
||||
{fieldtype:"Button", label: __("Refresh"), icon:"icon-refresh icon-white"},
|
||||
{fieldtype:"Button", label: __("Reset Filters"), icon: "icon-filter"}
|
||||
],
|
||||
|
||||
setup_plot_check: function() {
|
||||
return;
|
||||
},
|
||||
|
||||
prepare_data: function() {
|
||||
this.stock_entry_map = this.make_name_map(frappe.report_dump.data["Stock Entry"], "name");
|
||||
this._super();
|
||||
},
|
||||
|
||||
prepare_balances: function() {
|
||||
var me = this;
|
||||
var from_date = dateutil.str_to_obj(this.from_date);
|
||||
var to_date = dateutil.str_to_obj(this.to_date);
|
||||
var data = frappe.report_dump.data["Stock Ledger Entry"];
|
||||
|
||||
this.item_warehouse = {};
|
||||
this.serialized_buying_rates = this.get_serialized_buying_rates();
|
||||
|
||||
for(var i=0, j=data.length; i<j; i++) {
|
||||
var sl = data[i];
|
||||
var sl_posting_date = dateutil.str_to_obj(sl.posting_date);
|
||||
|
||||
if((me.is_default("warehouse") ? true : me.warehouse == sl.warehouse) &&
|
||||
(me.is_default("project") ? true : me.project == sl.project)) {
|
||||
var item = me.item_by_name[sl.item_code];
|
||||
var wh = me.get_item_warehouse(sl.warehouse, sl.item_code);
|
||||
var valuation_method = item.valuation_method ?
|
||||
item.valuation_method : sys_defaults.valuation_method;
|
||||
var is_fifo = valuation_method == "FIFO";
|
||||
|
||||
var qty_diff = sl.qty;
|
||||
var value_diff = me.get_value_diff(wh, sl, is_fifo);
|
||||
|
||||
if(sl_posting_date < from_date) {
|
||||
item.opening_qty += qty_diff;
|
||||
item.opening_value += value_diff;
|
||||
} else if(sl_posting_date <= to_date) {
|
||||
var ignore_inflow_outflow = this.is_default("warehouse")
|
||||
&& sl.voucher_type=="Stock Entry"
|
||||
&& this.stock_entry_map[sl.voucher_no].purpose=="Material Transfer";
|
||||
|
||||
if(!ignore_inflow_outflow) {
|
||||
if(qty_diff < 0) {
|
||||
item.outflow_qty += Math.abs(qty_diff);
|
||||
} else {
|
||||
item.inflow_qty += qty_diff;
|
||||
}
|
||||
if(value_diff < 0) {
|
||||
item.outflow_value += Math.abs(value_diff);
|
||||
} else {
|
||||
item.inflow_value += value_diff;
|
||||
}
|
||||
|
||||
item.closing_qty += qty_diff;
|
||||
item.closing_value += value_diff;
|
||||
}
|
||||
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// opening + diff = closing
|
||||
// adding opening, since diff already added to closing
|
||||
$.each(me.item_by_name, function(key, item) {
|
||||
item.closing_qty += item.opening_qty;
|
||||
item.closing_value += item.opening_value;
|
||||
|
||||
// valuation rate
|
||||
if(!item.is_group && flt(item.closing_qty) > 0)
|
||||
item.valuation_rate = flt(item.closing_value) / flt(item.closing_qty);
|
||||
else item.valuation_rate = 0.0
|
||||
});
|
||||
},
|
||||
|
||||
update_groups: function() {
|
||||
var me = this;
|
||||
|
||||
$.each(this.data, function(i, item) {
|
||||
// update groups
|
||||
if(!item.is_group && me.apply_filter(item, "brand")) {
|
||||
var parent = me.parent_map[item.name];
|
||||
while(parent) {
|
||||
parent_group = me.item_by_name[parent];
|
||||
$.each(me.columns, function(c, col) {
|
||||
if (col.formatter == me.currency_formatter && col.field != "valuation_rate") {
|
||||
parent_group[col.field] = flt(parent_group[col.field]) + flt(item[col.field]);
|
||||
}
|
||||
});
|
||||
|
||||
// show parent if filtered by brand
|
||||
if(item.brand == me.brand)
|
||||
parent_group._show = true;
|
||||
|
||||
parent = me.parent_map[parent];
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
get_plot_data: function() {
|
||||
return;
|
||||
}
|
||||
});
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"creation": "2012-12-27 18:57:47.000000",
|
||||
"docstatus": 0,
|
||||
"doctype": "Page",
|
||||
"icon": "icon-table",
|
||||
"idx": 1,
|
||||
"modified": "2013-07-11 14:44:15.000000",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "stock-balance",
|
||||
"owner": "Administrator",
|
||||
"page_name": "stock-balance",
|
||||
"roles": [
|
||||
{
|
||||
"role": "Material Manager"
|
||||
},
|
||||
{
|
||||
"role": "Analytics"
|
||||
}
|
||||
],
|
||||
"standard": "Yes",
|
||||
"title": "Stock Balance"
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
from frappe.utils import flt, cint
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
@ -57,6 +57,7 @@ def get_stock_ledger_entries(filters):
|
||||
conditions, as_dict=1)
|
||||
|
||||
def get_item_warehouse_batch_map(filters):
|
||||
float_precision = cint(frappe.db.get_default("float_precision")) or 3
|
||||
sle = get_stock_ledger_entries(filters)
|
||||
iwb_map = {}
|
||||
|
||||
@ -67,14 +68,14 @@ def get_item_warehouse_batch_map(filters):
|
||||
}))
|
||||
qty_dict = iwb_map[d.item_code][d.warehouse][d.batch_no]
|
||||
if d.posting_date < filters["from_date"]:
|
||||
qty_dict.opening_qty += flt(d.actual_qty)
|
||||
qty_dict.opening_qty += flt(d.actual_qty, float_precision)
|
||||
elif d.posting_date >= filters["from_date"] and d.posting_date <= filters["to_date"]:
|
||||
if flt(d.actual_qty) > 0:
|
||||
qty_dict.in_qty += flt(d.actual_qty)
|
||||
qty_dict.in_qty += flt(d.actual_qty, float_precision)
|
||||
else:
|
||||
qty_dict.out_qty += abs(flt(d.actual_qty))
|
||||
qty_dict.out_qty += abs(flt(d.actual_qty, float_precision))
|
||||
|
||||
qty_dict.bal_qty += flt(d.actual_qty)
|
||||
qty_dict.bal_qty += flt(d.actual_qty, float_precision)
|
||||
|
||||
return iwb_map
|
||||
|
||||
|
@ -4,10 +4,10 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import date_diff
|
||||
from frappe.utils import date_diff, flt
|
||||
|
||||
def execute(filters=None):
|
||||
|
||||
|
||||
columns = get_columns()
|
||||
item_details = get_fifo_queue(filters)
|
||||
to_date = filters["to_date"]
|
||||
@ -16,35 +16,40 @@ def execute(filters=None):
|
||||
fifo_queue = item_dict["fifo_queue"]
|
||||
details = item_dict["details"]
|
||||
if not fifo_queue: continue
|
||||
|
||||
|
||||
average_age = get_average_age(fifo_queue, to_date)
|
||||
earliest_age = date_diff(to_date, fifo_queue[0][1])
|
||||
latest_age = date_diff(to_date, fifo_queue[-1][1])
|
||||
|
||||
data.append([item, details.item_name, details.description, details.item_group,
|
||||
|
||||
data.append([item, details.item_name, details.description, details.item_group,
|
||||
details.brand, average_age, earliest_age, latest_age, details.stock_uom])
|
||||
|
||||
|
||||
return columns, data
|
||||
|
||||
|
||||
def get_average_age(fifo_queue, to_date):
|
||||
batch_age = age_qty = total_qty = 0.0
|
||||
for batch in fifo_queue:
|
||||
batch_age = date_diff(to_date, batch[1])
|
||||
age_qty += batch_age * batch[0]
|
||||
total_qty += batch[0]
|
||||
|
||||
|
||||
return (age_qty / total_qty) if total_qty else 0.0
|
||||
|
||||
|
||||
def get_columns():
|
||||
return [_("Item Code") + ":Link/Item:100", _("Item Name") + "::100", _("Description") + "::200",
|
||||
_("Item Group") + ":Link/Item Group:100", _("Brand") + ":Link/Brand:100", _("Average Age") + ":Float:100",
|
||||
return [_("Item Code") + ":Link/Item:100", _("Item Name") + "::100", _("Description") + "::200",
|
||||
_("Item Group") + ":Link/Item Group:100", _("Brand") + ":Link/Brand:100", _("Average Age") + ":Float:100",
|
||||
_("Earliest") + ":Int:80", _("Latest") + ":Int:80", _("UOM") + ":Link/UOM:100"]
|
||||
|
||||
|
||||
def get_fifo_queue(filters):
|
||||
item_details = {}
|
||||
prev_qty = 0.0
|
||||
for d in get_stock_ledger_entries(filters):
|
||||
item_details.setdefault(d.name, {"details": d, "fifo_queue": []})
|
||||
fifo_queue = item_details[d.name]["fifo_queue"]
|
||||
|
||||
if d.voucher_type == "Stock Reconciliation":
|
||||
d.actual_qty = flt(d.qty_after_transaction) - flt(prev_qty)
|
||||
|
||||
if d.actual_qty > 0:
|
||||
fifo_queue.append([d.actual_qty, d.posting_date])
|
||||
else:
|
||||
@ -52,7 +57,7 @@ def get_fifo_queue(filters):
|
||||
while qty_to_pop:
|
||||
batch = fifo_queue[0] if fifo_queue else [0, None]
|
||||
if 0 < batch[0] <= qty_to_pop:
|
||||
# if batch qty > 0
|
||||
# if batch qty > 0
|
||||
# not enough or exactly same qty in current batch, clear batch
|
||||
qty_to_pop -= batch[0]
|
||||
fifo_queue.pop(0)
|
||||
@ -61,12 +66,14 @@ def get_fifo_queue(filters):
|
||||
batch[0] -= qty_to_pop
|
||||
qty_to_pop = 0
|
||||
|
||||
prev_qty = d.qty_after_transaction
|
||||
|
||||
return item_details
|
||||
|
||||
|
||||
def get_stock_ledger_entries(filters):
|
||||
return frappe.db.sql("""select
|
||||
item.name, item.item_name, item_group, brand, description, item.stock_uom,
|
||||
actual_qty, posting_date
|
||||
return frappe.db.sql("""select
|
||||
item.name, item.item_name, item_group, brand, description, item.stock_uom,
|
||||
actual_qty, posting_date, voucher_type, qty_after_transaction
|
||||
from `tabStock Ledger Entry` sle,
|
||||
(select name, item_name, description, stock_uom, brand, item_group
|
||||
from `tabItem` {item_conditions}) item
|
||||
@ -77,19 +84,19 @@ def get_stock_ledger_entries(filters):
|
||||
order by posting_date, posting_time, sle.name"""\
|
||||
.format(item_conditions=get_item_conditions(filters),
|
||||
sle_conditions=get_sle_conditions(filters)), filters, as_dict=True)
|
||||
|
||||
|
||||
def get_item_conditions(filters):
|
||||
conditions = []
|
||||
if filters.get("item_code"):
|
||||
conditions.append("item_code=%(item_code)s")
|
||||
if filters.get("brand"):
|
||||
conditions.append("brand=%(brand)s")
|
||||
|
||||
|
||||
return "where {}".format(" and ".join(conditions)) if conditions else ""
|
||||
|
||||
|
||||
def get_sle_conditions(filters):
|
||||
conditions = []
|
||||
if filters.get("warehouse"):
|
||||
conditions.append("warehouse=%(warehouse)s")
|
||||
|
||||
return "and {}".format(" and ".join(conditions)) if conditions else ""
|
||||
|
||||
return "and {}".format(" and ".join(conditions)) if conditions else ""
|
||||
|
@ -1,7 +1,7 @@
|
||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
|
||||
// License: GNU General Public License v3. See license.txt
|
||||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.query_reports["Warehouse-Wise Stock Balance"] = {
|
||||
frappe.query_reports["Stock Balance"] = {
|
||||
"filters": [
|
||||
{
|
||||
"fieldname":"from_date",
|
||||
@ -18,4 +18,4 @@ frappe.query_reports["Warehouse-Wise Stock Balance"] = {
|
||||
"default": frappe.datetime.get_today()
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,16 +1,17 @@
|
||||
{
|
||||
"add_total_row": 0,
|
||||
"apply_user_permissions": 1,
|
||||
"creation": "2013-06-05 11:00:31",
|
||||
"creation": "2014-10-10 17:58:11.577901",
|
||||
"disabled": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "Report",
|
||||
"idx": 1,
|
||||
"is_standard": "Yes",
|
||||
"modified": "2014-06-03 07:18:17.384923",
|
||||
"modified": "2014-10-10 17:58:11.577901",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Warehouse-Wise Stock Balance",
|
||||
"name": "Stock Balance",
|
||||
"owner": "Administrator",
|
||||
"ref_doctype": "Stock Ledger Entry",
|
||||
"report_name": "Warehouse-Wise Stock Balance",
|
||||
"report_name": "Stock Balance",
|
||||
"report_type": "Script Report"
|
||||
}
|
@ -58,10 +58,10 @@ def get_conditions(filters):
|
||||
#get all details
|
||||
def get_stock_ledger_entries(filters):
|
||||
conditions = get_conditions(filters)
|
||||
return frappe.db.sql("""select item_code, warehouse, posting_date,
|
||||
actual_qty, valuation_rate, stock_uom, company
|
||||
return frappe.db.sql("""select item_code, warehouse, posting_date, actual_qty, valuation_rate,
|
||||
stock_uom, company, voucher_type, qty_after_transaction, stock_value_difference
|
||||
from `tabStock Ledger Entry`
|
||||
where docstatus < 2 %s order by item_code, warehouse""" %
|
||||
where docstatus < 2 %s order by posting_date, posting_time, name""" %
|
||||
conditions, as_dict=1)
|
||||
|
||||
def get_item_warehouse_map(filters):
|
||||
@ -80,21 +80,27 @@ def get_item_warehouse_map(filters):
|
||||
qty_dict = iwb_map[d.company][d.item_code][d.warehouse]
|
||||
qty_dict.uom = d.stock_uom
|
||||
|
||||
if d.voucher_type == "Stock Reconciliation":
|
||||
qty_diff = flt(d.qty_after_transaction) - qty_dict.bal_qty
|
||||
else:
|
||||
qty_diff = flt(d.actual_qty)
|
||||
|
||||
value_diff = flt(d.stock_value_difference)
|
||||
|
||||
if d.posting_date < filters["from_date"]:
|
||||
qty_dict.opening_qty += flt(d.actual_qty)
|
||||
qty_dict.opening_val += flt(d.actual_qty) * flt(d.valuation_rate)
|
||||
qty_dict.opening_qty += qty_diff
|
||||
qty_dict.opening_val += value_diff
|
||||
elif d.posting_date >= filters["from_date"] and d.posting_date <= filters["to_date"]:
|
||||
qty_dict.val_rate = d.valuation_rate
|
||||
|
||||
if flt(d.actual_qty) > 0:
|
||||
qty_dict.in_qty += flt(d.actual_qty)
|
||||
qty_dict.in_val += flt(d.actual_qty) * flt(d.valuation_rate)
|
||||
if qty_diff > 0:
|
||||
qty_dict.in_qty += qty_diff
|
||||
qty_dict.in_val += value_diff
|
||||
else:
|
||||
qty_dict.out_qty += abs(flt(d.actual_qty))
|
||||
qty_dict.out_val += flt(abs(flt(d.actual_qty) * flt(d.valuation_rate)))
|
||||
qty_dict.out_qty += abs(qty_diff)
|
||||
qty_dict.out_val += abs(value_diff)
|
||||
|
||||
qty_dict.bal_qty += flt(d.actual_qty)
|
||||
qty_dict.bal_val += flt(d.actual_qty) * flt(d.valuation_rate)
|
||||
qty_dict.bal_qty += qty_diff
|
||||
qty_dict.bal_val += value_diff
|
||||
|
||||
return iwb_map
|
||||
|
@ -13,16 +13,13 @@ def execute(filters=None):
|
||||
data = []
|
||||
for sle in sl_entries:
|
||||
item_detail = item_details[sle.item_code]
|
||||
voucher_link_icon = """<a href="%s"><i class="icon icon-share"
|
||||
style="cursor: pointer;"></i></a>""" \
|
||||
% ("/".join(["#Form", sle.voucher_type, sle.voucher_no]),)
|
||||
|
||||
data.append([sle.date, sle.item_code, item_detail.item_name, item_detail.item_group,
|
||||
item_detail.brand, item_detail.description, sle.warehouse,
|
||||
item_detail.stock_uom, sle.actual_qty, sle.qty_after_transaction,
|
||||
(sle.incoming_rate if sle.actual_qty > 0 else 0.0),
|
||||
sle.valuation_rate, sle.stock_value, sle.voucher_type, sle.voucher_no,
|
||||
voucher_link_icon, sle.batch_no, sle.serial_no, sle.company])
|
||||
sle.batch_no, sle.serial_no, sle.company])
|
||||
|
||||
return columns, data
|
||||
|
||||
@ -31,7 +28,7 @@ def get_columns():
|
||||
_("Brand") + ":Link/Brand:100", _("Description") + "::200", _("Warehouse") + ":Link/Warehouse:100",
|
||||
_("Stock UOM") + ":Link/UOM:100", _("Qty") + ":Float:50", _("Balance Qty") + ":Float:100",
|
||||
_("Incoming Rate") + ":Currency:110", _("Valuation Rate") + ":Currency:110", _("Balance Value") + ":Currency:110",
|
||||
_("Voucher Type") + "::110", _("Voucher #") + "::100", _("Link") + "::30", _("Batch") + ":Link/Batch:100",
|
||||
_("Voucher Type") + "::110", _("Voucher #") + ":Dynamic Link/Voucher Type:100", _("Batch") + ":Link/Batch:100",
|
||||
_("Serial #") + ":Link/Serial No:100", _("Company") + ":Link/Company:100"]
|
||||
|
||||
def get_stock_ledger_entries(filters):
|
||||
|
@ -6,6 +6,7 @@ import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import cint, flt, cstr, now
|
||||
from erpnext.stock.utils import get_valuation_method
|
||||
from erpnext.controllers.stock_controller import get_valuation_rate
|
||||
import json
|
||||
|
||||
# future reposting
|
||||
@ -27,7 +28,7 @@ def make_sl_entries(sl_entries, is_amended=None):
|
||||
if sle.get('is_cancelled') == 'Yes':
|
||||
sle['actual_qty'] = -flt(sle['actual_qty'])
|
||||
|
||||
if sle.get("actual_qty"):
|
||||
if sle.get("actual_qty") or sle.voucher_type=="Stock Reconciliation":
|
||||
sle_id = make_entry(sle)
|
||||
|
||||
args = sle.copy()
|
||||
@ -36,9 +37,9 @@ def make_sl_entries(sl_entries, is_amended=None):
|
||||
"is_amended": is_amended
|
||||
})
|
||||
update_bin(args)
|
||||
|
||||
if cancel:
|
||||
delete_cancelled_entry(sl_entries[0].get('voucher_type'),
|
||||
sl_entries[0].get('voucher_no'))
|
||||
delete_cancelled_entry(sl_entries[0].get('voucher_type'), sl_entries[0].get('voucher_no'))
|
||||
|
||||
def set_as_cancel(voucher_type, voucher_no):
|
||||
frappe.db.sql("""update `tabStock Ledger Entry` set is_cancelled='Yes',
|
||||
@ -83,7 +84,6 @@ def update_entries_after(args, verbose=1):
|
||||
|
||||
entries_to_fix = get_sle_after_datetime(previous_sle or \
|
||||
{"item_code": args["item_code"], "warehouse": args["warehouse"]}, for_update=True)
|
||||
|
||||
valuation_method = get_valuation_method(args["item_code"])
|
||||
stock_value_difference = 0.0
|
||||
|
||||
@ -95,21 +95,30 @@ def update_entries_after(args, verbose=1):
|
||||
qty_after_transaction += flt(sle.actual_qty)
|
||||
continue
|
||||
|
||||
|
||||
if sle.serial_no:
|
||||
valuation_rate = get_serialized_values(qty_after_transaction, sle, valuation_rate)
|
||||
elif valuation_method == "Moving Average":
|
||||
valuation_rate = get_moving_average_values(qty_after_transaction, sle, valuation_rate)
|
||||
else:
|
||||
valuation_rate = get_fifo_values(qty_after_transaction, sle, stock_queue)
|
||||
qty_after_transaction += flt(sle.actual_qty)
|
||||
|
||||
qty_after_transaction += flt(sle.actual_qty)
|
||||
else:
|
||||
if sle.voucher_type=="Stock Reconciliation":
|
||||
valuation_rate = sle.valuation_rate
|
||||
qty_after_transaction = sle.qty_after_transaction
|
||||
stock_queue = [[qty_after_transaction, valuation_rate]]
|
||||
else:
|
||||
if valuation_method == "Moving Average":
|
||||
valuation_rate = get_moving_average_values(qty_after_transaction, sle, valuation_rate)
|
||||
else:
|
||||
valuation_rate = get_fifo_values(qty_after_transaction, sle, stock_queue)
|
||||
|
||||
|
||||
qty_after_transaction += flt(sle.actual_qty)
|
||||
|
||||
# get stock value
|
||||
if sle.serial_no:
|
||||
stock_value = qty_after_transaction * valuation_rate
|
||||
elif valuation_method == "Moving Average":
|
||||
stock_value = (qty_after_transaction > 0) and \
|
||||
(qty_after_transaction * valuation_rate) or 0
|
||||
stock_value = qty_after_transaction * valuation_rate
|
||||
else:
|
||||
stock_value = sum((flt(batch[0]) * flt(batch[1]) for batch in stock_queue))
|
||||
|
||||
@ -247,65 +256,72 @@ def get_moving_average_values(qty_after_transaction, sle, valuation_rate):
|
||||
incoming_rate = flt(sle.incoming_rate)
|
||||
actual_qty = flt(sle.actual_qty)
|
||||
|
||||
if not incoming_rate:
|
||||
# In case of delivery/stock issue in_rate = 0 or wrong incoming rate
|
||||
incoming_rate = valuation_rate
|
||||
if flt(sle.actual_qty) > 0:
|
||||
if qty_after_transaction < 0 and not valuation_rate:
|
||||
# if negative stock, take current valuation rate as incoming rate
|
||||
valuation_rate = incoming_rate
|
||||
|
||||
elif qty_after_transaction < 0:
|
||||
# if negative stock, take current valuation rate as incoming rate
|
||||
valuation_rate = incoming_rate
|
||||
new_stock_qty = abs(qty_after_transaction) + actual_qty
|
||||
new_stock_value = (abs(qty_after_transaction) * valuation_rate) + (actual_qty * incoming_rate)
|
||||
|
||||
new_stock_qty = qty_after_transaction + actual_qty
|
||||
new_stock_value = qty_after_transaction * valuation_rate + actual_qty * incoming_rate
|
||||
if new_stock_qty:
|
||||
valuation_rate = new_stock_value / flt(new_stock_qty)
|
||||
elif not valuation_rate:
|
||||
valuation_rate = get_valuation_rate(sle.item_code, sle.warehouse)
|
||||
|
||||
if new_stock_qty > 0 and new_stock_value > 0:
|
||||
valuation_rate = new_stock_value / flt(new_stock_qty)
|
||||
elif new_stock_qty <= 0:
|
||||
valuation_rate = 0.0
|
||||
|
||||
# NOTE: val_rate is same as previous entry if new stock value is negative
|
||||
|
||||
return valuation_rate
|
||||
return abs(valuation_rate)
|
||||
|
||||
def get_fifo_values(qty_after_transaction, sle, stock_queue):
|
||||
incoming_rate = flt(sle.incoming_rate)
|
||||
actual_qty = flt(sle.actual_qty)
|
||||
if not stock_queue:
|
||||
stock_queue.append([0, 0])
|
||||
|
||||
intialize_stock_queue(stock_queue, sle.item_code, sle.warehouse)
|
||||
|
||||
if actual_qty > 0:
|
||||
if stock_queue[-1][0] > 0:
|
||||
stock_queue.append([actual_qty, incoming_rate])
|
||||
else:
|
||||
qty = stock_queue[-1][0] + actual_qty
|
||||
stock_queue[-1] = [qty, qty > 0 and incoming_rate or 0]
|
||||
if qty == 0:
|
||||
stock_queue.pop(-1)
|
||||
else:
|
||||
stock_queue[-1] = [qty, incoming_rate]
|
||||
else:
|
||||
incoming_cost = 0
|
||||
qty_to_pop = abs(actual_qty)
|
||||
while qty_to_pop:
|
||||
if not stock_queue:
|
||||
stock_queue.append([0, 0])
|
||||
intialize_stock_queue(stock_queue, sle.item_code, sle.warehouse)
|
||||
|
||||
batch = stock_queue[0]
|
||||
|
||||
if 0 < batch[0] <= qty_to_pop:
|
||||
# if batch qty > 0
|
||||
# not enough or exactly same qty in current batch, clear batch
|
||||
incoming_cost += flt(batch[0]) * flt(batch[1])
|
||||
qty_to_pop -= batch[0]
|
||||
# print qty_to_pop, batch
|
||||
|
||||
if qty_to_pop >= batch[0]:
|
||||
# consume current batch
|
||||
qty_to_pop = qty_to_pop - batch[0]
|
||||
stock_queue.pop(0)
|
||||
if not stock_queue and qty_to_pop:
|
||||
# stock finished, qty still remains to be withdrawn
|
||||
# negative stock, keep in as a negative batch
|
||||
stock_queue.append([-qty_to_pop, batch[1]])
|
||||
break
|
||||
|
||||
else:
|
||||
# all from current batch
|
||||
incoming_cost += flt(qty_to_pop) * flt(batch[1])
|
||||
batch[0] -= qty_to_pop
|
||||
# qty found in current batch
|
||||
# consume it and exit
|
||||
batch[0] = batch[0] - qty_to_pop
|
||||
qty_to_pop = 0
|
||||
|
||||
stock_value = sum((flt(batch[0]) * flt(batch[1]) for batch in stock_queue))
|
||||
stock_qty = sum((flt(batch[0]) for batch in stock_queue))
|
||||
|
||||
valuation_rate = stock_qty and (stock_value / flt(stock_qty)) or 0
|
||||
valuation_rate = (stock_value / flt(stock_qty)) if stock_qty else 0
|
||||
|
||||
return valuation_rate
|
||||
return abs(valuation_rate)
|
||||
|
||||
def intialize_stock_queue(stock_queue, item_code, warehouse):
|
||||
if not stock_queue:
|
||||
estimated_val_rate = get_valuation_rate(item_code, warehouse)
|
||||
stock_queue.append([0, estimated_val_rate])
|
||||
|
||||
def _raise_exceptions(args, verbose=1):
|
||||
deficiency = min(e["diff"] for e in _exceptions)
|
||||
|
@ -5,7 +5,6 @@ import frappe
|
||||
from frappe import _
|
||||
import json
|
||||
from frappe.utils import flt, cstr, nowdate, add_days, cint
|
||||
from frappe.defaults import get_global_default
|
||||
from frappe.utils.email_lib import sendmail
|
||||
from erpnext.accounts.utils import get_fiscal_year, FiscalYearError
|
||||
|
||||
@ -94,7 +93,7 @@ def get_valuation_method(item_code):
|
||||
"""get valuation method from item or default"""
|
||||
val_method = frappe.db.get_value('Item', item_code, 'valuation_method')
|
||||
if not val_method:
|
||||
val_method = get_global_default('valuation_method') or "FIFO"
|
||||
val_method = frappe.db.get_value("Stock Settings", None, "valuation_method") or "FIFO"
|
||||
return val_method
|
||||
|
||||
def get_fifo_rate(previous_stock_queue, qty):
|
||||
|
@ -34,7 +34,7 @@
|
||||
"<a href=""#Sales Browser/Territory"">Add / Edit</a>","<a href=""#Sales Browser/Territory""> إضافة / تحرير < / A>"
|
||||
"<h4>Default Template</h4><p>Uses <a href=""http://jinja.pocoo.org/docs/templates/"">Jinja Templating</a> and all the fields of Address (including Custom Fields if any) will be available</p><pre><code>{{ address_line1 }}<br>{% if address_line2 %}{{ address_line2 }}<br>{% endif -%}{{ city }}<br>{% if state %}{{ state }}<br>{% endif -%}{% if pincode %} PIN: {{ pincode }}<br>{% endif -%}{{ country }}<br>{% if phone %}Phone: {{ phone }}<br>{% endif -%}{% if fax %}Fax: {{ fax }}<br>{% endif -%}{% if email_id %}Email: {{ email_id }}<br>{% endif -%}</code></pre>","<h4> افتراضي قالب </ H4> <p> ويستخدم <a href=""http://jinja.pocoo.org/docs/templates/""> جنجا القولبة </ a> و كافة الحقول من العنوان ( بما في ذلك الحقول المخصصة إن وجدت) وسوف تكون متاحة </ P> <PRE> على <code> {{}} address_line1 <BR> {٪ إذا address_line2٪} {{}} address_line2 <BR> { ENDIF٪ -٪} {{المدينة}} <BR> {٪ إذا الدولة٪} {{الدولة}} {<BR>٪ ENDIF -٪} {٪ إذا كان الرقم السري٪} PIN: {{}} الرقم السري {<BR>٪ ENDIF -٪} {{البلد}} <BR> {٪ إذا كان الهاتف٪} الهاتف: {{هاتف}} {<BR> ENDIF٪ -٪} {٪ إذا الفاكس٪} فاكس: {{}} الفاكس <BR> {٪ ENDIF -٪} {٪٪ إذا email_id} البريد الإلكتروني: {{}} email_id <BR> ؛ {٪ ENDIF -٪} </ رمز> </ قبل>"
|
||||
A Customer Group exists with same name please change the Customer name or rename the Customer Group,يوجد مجموعة العملاء مع نفس الاسم الرجاء تغيير اسم العميل أو إعادة تسمية المجموعة العملاء
|
||||
A Customer exists with same name,العملاء من وجود نفس الاسم مع
|
||||
A Customer exists with same name,يوجد في قائمة العملاء عميل بنفس الاسم
|
||||
A Lead with this email id should exist,وينبغي أن يكون هذا المعرف الرصاص مع البريد الإلكتروني موجود
|
||||
A Product or Service,منتج أو خدمة
|
||||
A Supplier exists with same name,وهناك مورد موجود مع نفس الاسم
|
||||
@ -47,7 +47,7 @@ Absent,غائب
|
||||
Acceptance Criteria,معايير القبول
|
||||
Accepted,مقبول
|
||||
Accepted + Rejected Qty must be equal to Received quantity for Item {0},يجب أن يكون مقبول مرفوض + الكمية مساوية ل كمية تلقى القطعة ل {0}
|
||||
Accepted Quantity,قبلت الكمية
|
||||
Accepted Quantity,كمية مقبولة
|
||||
Accepted Warehouse,قبلت مستودع
|
||||
Account,حساب
|
||||
Account Balance,رصيد حسابك
|
||||
@ -65,12 +65,12 @@ Account with child nodes cannot be converted to ledger,حساب مع العقد
|
||||
Account with existing transaction can not be converted to group.,حساب مع الصفقة الحالية لا يمكن تحويلها إلى المجموعة.
|
||||
Account with existing transaction can not be deleted,حساب مع الصفقة الحالية لا يمكن حذف
|
||||
Account with existing transaction cannot be converted to ledger,حساب مع الصفقة الحالية لا يمكن تحويلها إلى دفتر الأستاذ
|
||||
Account {0} cannot be a Group,حساب {0} لا يمكن أن تكون المجموعة
|
||||
Account {0} does not belong to Company {1},حساب {0} لا تنتمي إلى شركة {1}
|
||||
Account {0} cannot be a Group,حساب {0} لا يمكن أن يكون مجموعة
|
||||
Account {0} does not belong to Company {1},حساب {0} لا ينتمي إلى شركة {1}
|
||||
Account {0} does not belong to company: {1},حساب {0} لا تنتمي إلى الشركة: {1}
|
||||
Account {0} does not exist,حساب {0} غير موجود
|
||||
Account {0} has been entered more than once for fiscal year {1},حساب {0} تم إدخال أكثر من مرة للعام المالي {1}
|
||||
Account {0} is frozen,حساب {0} يتم تجميد
|
||||
Account {0} is frozen,حساب {0} مجمد
|
||||
Account {0} is inactive,حساب {0} غير نشط
|
||||
Account {0} is not valid,حساب {0} غير صالح
|
||||
Account {0} must be of type 'Fixed Asset' as Item {1} is an Asset Item,"حساب {0} يجب أن تكون من النوع ' الأصول الثابتة ""كما البند {1} هو البند الأصول"
|
||||
@ -85,7 +85,7 @@ Accounting,المحاسبة
|
||||
"Accounting entry frozen up to this date, nobody can do / modify entry except role specified below.",قيد محاسبي المجمدة تصل إلى هذا التاريخ، لا أحد يمكن أن تفعل / تعديل إدخال باستثناء دور المحددة أدناه.
|
||||
Accounting journal entries.,المحاسبة إدخالات دفتر اليومية.
|
||||
Accounts,حسابات
|
||||
Accounts Browser,حسابات متصفح
|
||||
Accounts Browser,متصفح الحسابات
|
||||
Accounts Frozen Upto,حسابات مجمدة لغاية
|
||||
Accounts Payable,ذمم دائنة
|
||||
Accounts Receivable,حسابات القبض
|
||||
@ -95,13 +95,13 @@ Active: Will extract emails from ,نشط: سيتم استخراج رسائل ا
|
||||
Activity,نشاط
|
||||
Activity Log,سجل النشاط
|
||||
Activity Log:,النشاط المفتاح:
|
||||
Activity Type,النشاط نوع
|
||||
Activity Type,نوع النشاط
|
||||
Actual,فعلي
|
||||
Actual Budget,الميزانية الفعلية
|
||||
Actual Completion Date,تاريخ الإنتهاء الفعلي
|
||||
Actual Date,تاريخ الفعلية
|
||||
Actual Date,التاريخ الفعلي
|
||||
Actual End Date,تاريخ الإنتهاء الفعلي
|
||||
Actual Invoice Date,الفعلي تاريخ الفاتورة
|
||||
Actual Invoice Date,التاريخ الفعلي للفاتورة
|
||||
Actual Posting Date,تاريخ النشر الفعلي
|
||||
Actual Qty,الكمية الفعلية
|
||||
Actual Qty (at source/target),الكمية الفعلية (في المصدر / الهدف)
|
||||
@ -112,7 +112,7 @@ Actual Start Date,تاريخ البدء الفعلي
|
||||
Add,إضافة
|
||||
Add / Edit Taxes and Charges,إضافة / تعديل الضرائب والرسوم
|
||||
Add Child,إضافة الطفل
|
||||
Add Serial No,إضافة رقم المسلسل
|
||||
Add Serial No,إضافة رقم تسلسلي
|
||||
Add Taxes,إضافة الضرائب
|
||||
Add Taxes and Charges,إضافة الضرائب والرسوم
|
||||
Add or Deduct,إضافة أو خصم
|
||||
@ -131,7 +131,7 @@ Address Line 2,العنوان سطر 2
|
||||
Address Template,قالب عنوان
|
||||
Address Title,عنوان عنوان
|
||||
Address Title is mandatory.,عنوان عنوانها إلزامية.
|
||||
Address Type,عنوان نوع
|
||||
Address Type,نوع العنوان
|
||||
Address master.,عنوان رئيسي.
|
||||
Administrative Expenses,المصاريف الإدارية
|
||||
Administrative Officer,موظف إداري
|
||||
@ -217,7 +217,7 @@ Amount to Bill,تصل إلى بيل
|
||||
An Customer exists with same name,موجود على العملاء مع نفس الاسم
|
||||
"An Item Group exists with same name, please change the item name or rename the item group",وجود فريق المدينة مع نفس الاسم، الرجاء تغيير اسم العنصر أو إعادة تسمية المجموعة البند
|
||||
"An item exists with same name ({0}), please change the item group name or rename the item",عنصر موجود مع نفس الاسم ( {0} ) ، الرجاء تغيير اسم المجموعة البند أو إعادة تسمية هذا البند
|
||||
Analyst,المحلل
|
||||
Analyst,محلل
|
||||
Annual,سنوي
|
||||
Another Period Closing Entry {0} has been made after {1},دخول أخرى الفترة الإنتهاء {0} أحرز بعد {1}
|
||||
Another Salary Structure {0} is active for employee {0}. Please make its status 'Inactive' to proceed.,"هيكل الرواتب أخرى {0} نشطة للموظف {0} . يرجى التأكد مكانتها ""غير نشطة "" والمضي قدما."
|
||||
@ -266,15 +266,15 @@ Atleast one of the Selling or Buying must be selected,يجب تحديد الاق
|
||||
Atleast one warehouse is mandatory,واحدة على الاقل مستودع إلزامي
|
||||
Attach Image,إرفاق صورة
|
||||
Attach Letterhead,نعلق رأسية
|
||||
Attach Logo,نعلق شعار
|
||||
Attach Your Picture,نعلق صورتك
|
||||
Attach Logo,إرفاق صورة الشعار/العلامة التجارية
|
||||
Attach Your Picture,إرفاق صورتك
|
||||
Attendance,الحضور
|
||||
Attendance Date,تاريخ الحضور
|
||||
Attendance Details,تفاصيل الحضور
|
||||
Attendance From Date,الحضور من تاريخ
|
||||
Attendance From Date and Attendance To Date is mandatory,الحضور من التسجيل والحضور إلى تاريخ إلزامي
|
||||
Attendance To Date,الحضور إلى تاريخ
|
||||
Attendance can not be marked for future dates,لا يمكن أن تكون علامة لحضور تواريخ مستقبلية
|
||||
Attendance can not be marked for future dates,لا يمكن أن ىكون تاريخ الحضور تاريخ مستقبلي
|
||||
Attendance for employee {0} is already marked,الحضور للموظف {0} تم وضع علامة بالفعل
|
||||
Attendance record.,سجل الحضور.
|
||||
Authorization Control,إذن التحكم
|
||||
@ -287,13 +287,13 @@ Automatically extract Job Applicants from a mail box ,
|
||||
Automatically extract Leads from a mail box e.g.,استخراج الشراء تلقائيا من صندوق البريد على سبيل المثال
|
||||
Automatically updated via Stock Entry of type Manufacture/Repack,تحديثها تلقائيا عن طريق إدخال الأسهم الصنع نوع / أعد حزم
|
||||
Automotive,السيارات
|
||||
Autoreply when a new mail is received,عندما رد تلقائي تلقي بريد جديد
|
||||
Autoreply when a new mail is received,رد تلقائي عند تلقي بريد جديد
|
||||
Available,متاح
|
||||
Available Qty at Warehouse,الكمية المتاحة في مستودع
|
||||
Available Stock for Packing Items,الأسهم المتاحة للتعبئة وحدات
|
||||
"Available in BOM, Delivery Note, Purchase Invoice, Production Order, Purchase Order, Purchase Receipt, Sales Invoice, Sales Order, Stock Entry, Timesheet",المتاحة في BOM ، تسليم مذكرة ، شراء الفاتورة ، ترتيب الإنتاج، طلب شراء ، شراء استلام ، فاتورة المبيعات ، ترتيب المبيعات ، اسهم الدخول و الجدول الزمني
|
||||
Average Age,متوسط العمر
|
||||
Average Commission Rate,متوسط سعر جنة
|
||||
Average Commission Rate,متوسط العمولة
|
||||
Average Discount,متوسط الخصم
|
||||
Awesome Products,المنتجات رهيبة
|
||||
Awesome Services,خدمات رهيبة
|
||||
@ -331,9 +331,9 @@ Bank Clearance Summary,بنك ملخص التخليص
|
||||
Bank Draft,البنك مشروع
|
||||
Bank Name,اسم البنك
|
||||
Bank Overdraft Account,حساب السحب على المكشوف المصرفي
|
||||
Bank Reconciliation,البنك المصالحة
|
||||
Bank Reconciliation Detail,البنك المصالحة تفاصيل
|
||||
Bank Reconciliation Statement,بيان التسويات المصرفية
|
||||
Bank Reconciliation,تسوية البنك
|
||||
Bank Reconciliation Detail,تفاصيل تسوية البنك
|
||||
Bank Reconciliation Statement,بيان تسوية البنك
|
||||
Bank Voucher,البنك قسيمة
|
||||
Bank/Cash Balance,بنك / النقد وما في حكمه
|
||||
Banking,مصرفي
|
||||
@ -405,8 +405,8 @@ Bundle items at time of sale.,حزمة البنود في وقت البيع.
|
||||
Business Development Manager,مدير تطوير الأعمال
|
||||
Buying,شراء
|
||||
Buying & Selling,شراء وبيع
|
||||
Buying Amount,شراء المبلغ
|
||||
Buying Settings,شراء إعدادات
|
||||
Buying Amount,مبلغ الشراء
|
||||
Buying Settings,إعدادات الشراء
|
||||
"Buying must be checked, if Applicable For is selected as {0}",يجب أن يتم التحقق الشراء، إذا تم تحديد مطبق للك {0}
|
||||
C-Form,نموذج C-
|
||||
C-Form Applicable,C-نموذج قابل للتطبيق
|
||||
@ -1025,7 +1025,7 @@ Extract Emails,استخراج رسائل البريد الإلكتروني
|
||||
FCFS Rate,FCFS قيم
|
||||
Failed: ,فشل:
|
||||
Family Background,الخلفية العائلية
|
||||
Fax,بالفاكس
|
||||
Fax,فاكس
|
||||
Features Setup,ميزات الإعداد
|
||||
Feed,أطعم
|
||||
Feed Type,إطعام نوع
|
||||
@ -1041,7 +1041,7 @@ Financial / accounting year.,المالية / المحاسبة العام.
|
||||
Financial Analytics,تحليلات مالية
|
||||
Financial Services,الخدمات المالية
|
||||
Financial Year End Date,تاريخ نهاية السنة المالية
|
||||
Financial Year Start Date,السنة المالية تاريخ بدء
|
||||
Financial Year Start Date,تاريخ بدء السنة المالية
|
||||
Finished Goods,السلع تامة الصنع
|
||||
First Name,الاسم الأول
|
||||
First Responded On,أجاب أولا على
|
||||
@ -1059,7 +1059,7 @@ Food,غذاء
|
||||
For Company,لشركة
|
||||
For Employee,لموظف
|
||||
For Employee Name,لاسم الموظف
|
||||
For Price List,ل ائحة الأسعار
|
||||
For Price List,لائحة الأسعار
|
||||
For Production,للإنتاج
|
||||
For Reference Only.,للإشارة فقط.
|
||||
For Sales Invoice,لفاتورة المبيعات
|
||||
@ -1823,7 +1823,7 @@ Notify by Email on creation of automatic Material Request,إبلاغ عن طري
|
||||
Number Format,عدد تنسيق
|
||||
Offer Date,عرض التسجيل
|
||||
Office,مكتب
|
||||
Office Equipments,معدات المكاتب
|
||||
Office Equipments,أدوات المكتب
|
||||
Office Maintenance Expenses,مصاريف صيانة المكاتب
|
||||
Office Rent,مكتب للإيجار
|
||||
Old Parent,العمر الرئيسي
|
||||
@ -1840,7 +1840,7 @@ Open Production Orders,أوامر مفتوحة الانتاج
|
||||
Open Tickets,تذاكر مفتوحة
|
||||
Opening (Cr),افتتاح (الكروم )
|
||||
Opening (Dr),افتتاح ( الدكتور )
|
||||
Opening Date,فتح تاريخ
|
||||
Opening Date,تاريخ الفتح
|
||||
Opening Entry,فتح دخول
|
||||
Opening Qty,فتح الكمية
|
||||
Opening Time,يفتح من الساعة
|
||||
@ -1854,7 +1854,7 @@ Operation {0} is repeated in Operations Table,عملية {0} يتكرر في ج
|
||||
Operation {0} not present in Operations Table,عملية {0} غير موجودة في جدول العمليات
|
||||
Operations,عمليات
|
||||
Opportunity,فرصة
|
||||
Opportunity Date,الفرصة تاريخ
|
||||
Opportunity Date,تاريخ الفرصة
|
||||
Opportunity From,فرصة من
|
||||
Opportunity Item,فرصة السلعة
|
||||
Opportunity Items,فرصة الأصناف
|
||||
@ -1914,9 +1914,9 @@ Packing Slip,زلة التعبئة
|
||||
Packing Slip Item,التعبئة الإغلاق زلة
|
||||
Packing Slip Items,التعبئة عناصر زلة
|
||||
Packing Slip(s) cancelled,زلة التعبئة (ق ) إلغاء
|
||||
Page Break,الصفحة استراحة
|
||||
Page Name,الصفحة اسم
|
||||
Paid Amount,دفع المبلغ
|
||||
Page Break,فاصل الصفحة
|
||||
Page Name,اسم الصفحة
|
||||
Paid Amount,المبلغ المدفوع
|
||||
Paid amount + Write Off Amount can not be greater than Grand Total,المبلغ المدفوع + شطب المبلغ لا يمكن أن يكون أكبر من المجموع الكلي
|
||||
Pair,زوج
|
||||
Parameter,المعلمة
|
||||
@ -3128,7 +3128,7 @@ Users with this role are allowed to create / modify accounting entry before froz
|
||||
Users with this role are allowed to set frozen accounts and create / modify accounting entries against frozen accounts,يسمح للمستخدمين مع هذا الدور لضبط الحسابات المجمدة و إنشاء / تعديل القيود المحاسبية على حسابات مجمدة
|
||||
Utilities,خدمات
|
||||
Utility Expenses,مصاريف فائدة
|
||||
Valid For Territories,صالحة للالأقاليم
|
||||
Valid For Territories,صالحة للأقاليم
|
||||
Valid From,صالحة من
|
||||
Valid Upto,صالحة لغاية
|
||||
Valid for Territories,صالحة للالأقاليم
|
||||
@ -3237,7 +3237,7 @@ Write Off Voucher,شطب قسيمة
|
||||
Wrong Template: Unable to find head row.,قالب الخطأ: تعذر العثور على صف الرأس.
|
||||
Year,عام
|
||||
Year Closed,مغلق العام
|
||||
Year End Date,نهاية التاريخ العام
|
||||
Year End Date,تاريخ نهاية العام
|
||||
Year Name,اسم العام
|
||||
Year Start Date,تاريخ بدء العام
|
||||
Year of Passing,اجتياز سنة
|
||||
@ -3261,8 +3261,8 @@ You have entered duplicate items. Please rectify and try again.,لقد دخلت
|
||||
You may need to update: {0},قد تحتاج إلى تحديث : {0}
|
||||
You must Save the form before proceeding,يجب حفظ النموذج قبل الشروع
|
||||
Your Customer's TAX registration numbers (if applicable) or any general information,عميلك أرقام التسجيل الضريبي (إن وجدت) أو أي معلومات عامة
|
||||
Your Customers,الزبائن
|
||||
Your Login Id,تسجيل الدخول اسم المستخدم الخاص بك
|
||||
Your Customers,العملاء
|
||||
Your Login Id,تسجيل الدخول - اسم المستخدم الخاص بك
|
||||
Your Products or Services,المنتجات أو الخدمات الخاصة بك
|
||||
Your Suppliers,لديك موردون
|
||||
Your email address,عنوان البريد الإلكتروني الخاص بك
|
||||
|
|
@ -41,8 +41,8 @@ A Product or Service,Ένα Προϊόν ή Υπηρεσία
|
||||
A Supplier exists with same name,Ένας προμηθευτής υπάρχει με το ίδιο όνομα
|
||||
A symbol for this currency. For e.g. $,Ένα σύμβολο για το νόμισμα αυτό. Για παράδειγμα $
|
||||
AMC Expiry Date,AMC Ημερομηνία Λήξης
|
||||
Abbr,Abbr
|
||||
Abbreviation cannot have more than 5 characters,Συντομογραφία δεν μπορεί να έχει περισσότερα από 5 χαρακτήρες
|
||||
Abbr,Συντ.
|
||||
Abbreviation cannot have more than 5 characters,Μια συντομογραφία δεν μπορεί να έχει περισσότερα από 5 χαρακτήρες
|
||||
Above Value,Πάνω Value
|
||||
Absent,Απών
|
||||
Acceptance Criteria,Κριτήρια αποδοχής
|
||||
@ -50,9 +50,9 @@ Accepted,Δεκτός
|
||||
Accepted + Rejected Qty must be equal to Received quantity for Item {0},Αποδεκτές + Απορρίπτεται Ποσότητα πρέπει να είναι ίση με Ελήφθη ποσότητα για τη θέση {0}
|
||||
Accepted Quantity,ΠΟΣΟΤΗΤΑ
|
||||
Accepted Warehouse,Αποδεκτές αποθήκη
|
||||
Account,λογαριασμός
|
||||
Account Balance,Υπόλοιπο λογαριασμού
|
||||
Account Created: {0},Ο λογαριασμός Δημιουργήθηκε : {0}
|
||||
Account,Λογαριασμός
|
||||
Account Balance,Υπόλοιπο Λογαριασμού
|
||||
Account Created: {0},Ο λογαριασμός δημιουργήθηκε : {0}
|
||||
Account Details,Στοιχεία Λογαριασμού
|
||||
Account Head,Επικεφαλής λογαριασμού
|
||||
Account Name,Όνομα λογαριασμού
|
||||
|
|
File diff suppressed because it is too large
Load Diff
@ -35,41 +35,42 @@
|
||||
"<a href=""#Sales Browser/Territory"">Add / Edit</a>","<a href=""#Sales Browser/Territory""> Ajouter / Modifier < / a>"
|
||||
"<h4>Default Template</h4><p>Uses <a href=""http://jinja.pocoo.org/docs/templates/"">Jinja Templating</a> and all the fields of Address (including Custom Fields if any) will be available</p><pre><code>{{ address_line1 }}<br>{% if address_line2 %}{{ address_line2 }}<br>{% endif -%}{{ city }}<br>{% if state %}{{ state }}<br>{% endif -%}{% if pincode %} PIN: {{ pincode }}<br>{% endif -%}{{ country }}<br>{% if phone %}Phone: {{ phone }}<br>{% endif -%}{% if fax %}Fax: {{ fax }}<br>{% endif -%}{% if email_id %}Email: {{ email_id }}<br>{% endif -%}</code></pre>","<h4> modèle par défaut </ h4> <p> Utilise <a href=""http://jinja.pocoo.org/docs/templates/""> Jinja création de modèles </ a> et tous les domaines de l'Adresse ( y compris les champs personnalisés cas échéant) sera disponible </ p> <pre> <code> {{}} address_line1 Photos {% si address_line2%} {{}} address_line2 <br> { % endif -%} {{ville}} Photos {% si l'état%} {{état}} {% endif Photos -%} {% if%} code PIN PIN: {{code PIN}} {% endif Photos -%} {{pays}} Photos {% si le téléphone%} Téléphone: {{phone}} {<br> % endif -%} {% if%} fax Fax: {{fax}} {% endif Photos -%} {% if%} email_id Email: {{}} email_id Photos ; {% endif -%} </ code> </ pre>"
|
||||
A Customer Group exists with same name please change the Customer name or rename the Customer Group,BOM récursivité : {0} ne peut pas être le parent ou l'enfant de {2}
|
||||
A Customer exists with same name,Une clientèle existe avec le même nom
|
||||
A Lead with this email id should exist,Un responsable de cette id e-mail doit exister
|
||||
A Product or Service,Nouveau N ° de série ne peut pas avoir d'entrepôt . Entrepôt doit être réglé par Stock entrée ou ticket de caisse
|
||||
A Supplier exists with same name,Un Fournisseur existe avec le même nom
|
||||
A symbol for this currency. For e.g. $,Un symbole de cette monnaie. Pour exemple $
|
||||
A Customer exists with same name,Un client existe avec le même nom
|
||||
A Lead with this email id should exist,Un responsable de cet identifiant de courriel doit exister
|
||||
A Product or Service,Un produit ou service
|
||||
A Supplier exists with same name,Un fournisseur existe avec ce même nom
|
||||
A symbol for this currency. For e.g. $,Un symbole pour cette monnaie. Par exemple $
|
||||
AMC Expiry Date,AMC Date d'expiration
|
||||
Abbr,Abbr
|
||||
Abbreviation cannot have more than 5 characters,Compte avec la transaction existante ne peut pas être converti en groupe.
|
||||
Abbreviation cannot have more than 5 characters,L'abbréviation ne peut pas avoir plus de 5 caractères
|
||||
Above Value,Au-dessus de la valeur
|
||||
Absent,Absent
|
||||
Acceptance Criteria,Critères d'acceptation
|
||||
Accepted,Accepté
|
||||
Accepted + Rejected Qty must be equal to Received quantity for Item {0},Compte {0} doit être SAMES comme débit pour tenir compte de la facture de vente en ligne {0}
|
||||
Accepted + Rejected Qty must be equal to Received quantity for Item {0},"La quantité acceptée + rejetée doit être égale à la quantité reçue pour l'Item {0}
|
||||
Compte {0} doit être SAMES comme débit pour tenir compte de la facture de vente en ligne {0}"
|
||||
Accepted Quantity,Quantité acceptés
|
||||
Accepted Warehouse,Entrepôt acceptés
|
||||
Accepted Warehouse,Entrepôt acceptable
|
||||
Account,compte
|
||||
Account Balance,Solde du compte
|
||||
Account Created: {0},Compte créé : {0}
|
||||
Account Details,Détails du compte
|
||||
Account Head,Chef du compte
|
||||
Account Head,Responsable du compte
|
||||
Account Name,Nom du compte
|
||||
Account Type,Type de compte
|
||||
"Account balance already in Credit, you are not allowed to set 'Balance Must Be' as 'Debit'","Le solde du compte déjà en crédit, vous n'êtes pas autorisé à mettre en 'équilibre doit être' comme 'débit'"
|
||||
"Account balance already in Debit, you are not allowed to set 'Balance Must Be' as 'Credit'","Le solde du compte déjà en débit, vous n'êtes pas autorisé à définir 'équilibre doit être' comme 'Crédit'"
|
||||
Account for the warehouse (Perpetual Inventory) will be created under this Account.,Compte de l'entrepôt ( de l'inventaire permanent ) sera créé sous ce compte .
|
||||
Account head {0} created,Employé soulagé sur {0} doit être défini comme «gauche»
|
||||
Account must be a balance sheet account,arrhes
|
||||
Account head {0} created,Responsable du compte {0} a été crée
|
||||
Account must be a balance sheet account,Le compte doit être un bilan
|
||||
Account with child nodes cannot be converted to ledger,Liste des prix non sélectionné
|
||||
Account with existing transaction can not be converted to group.,{0} n'est pas un congé approbateur valide
|
||||
Account with existing transaction can not be deleted,Compte avec la transaction existante ne peut pas être supprimé
|
||||
Account with existing transaction cannot be converted to ledger,Compte avec la transaction existante ne peut pas être converti en livre
|
||||
Account {0} cannot be a Group,Compte {0} ne peut pas être un groupe
|
||||
Account {0} does not belong to Company {1},{0} créé
|
||||
Account {0} does not belong to Company {1},Compte {0} n'appartient pas à la société {1}
|
||||
Account {0} does not belong to company: {1},Compte {0} n'appartient pas à l'entreprise: {1}
|
||||
Account {0} does not exist,Votre adresse e-mail
|
||||
Account {0} does not exist,Compte {0} n'existe pas
|
||||
Account {0} has been entered more than once for fiscal year {1},S'il vous plaît entrer « Répétez le jour du Mois de la« valeur de champ
|
||||
Account {0} is frozen,Attention: Commande {0} existe déjà contre le même numéro de bon de commande
|
||||
Account {0} is inactive,dépenses directes
|
||||
@ -80,13 +81,13 @@ Account {0}: Parent account {1} does not belong to company: {2},Compte {0}: comp
|
||||
Account {0}: Parent account {1} does not exist,Compte {0}: compte de Parent {1} n'existe pas
|
||||
Account {0}: You can not assign itself as parent account,Compte {0}: Vous ne pouvez pas lui attribuer que compte parent
|
||||
Account: {0} can only be updated via \ Stock Transactions,Compte: {0} ne peut être mise à jour via \ Transactions de stock
|
||||
Accountant,comptable
|
||||
Accountant,Comptable
|
||||
Accounting,Comptabilité
|
||||
"Accounting Entries can be made against leaf nodes, called","Écritures comptables peuvent être faites contre nœuds feuilles , appelé"
|
||||
"Accounting entry frozen up to this date, nobody can do / modify entry except role specified below.","Saisie comptable gelé jusqu'à cette date, personne ne peut faire / modifier entrée sauf rôle spécifié ci-dessous."
|
||||
Accounting journal entries.,Les écritures comptables.
|
||||
Accounts,Comptes
|
||||
Accounts Browser,comptes navigateur
|
||||
Accounts Browser,Navigateur des comptes
|
||||
Accounts Frozen Upto,Jusqu'à comptes gelés
|
||||
Accounts Payable,Comptes à payer
|
||||
Accounts Receivable,Débiteurs
|
||||
@ -113,28 +114,28 @@ Actual Start Date,Date de début réelle
|
||||
Add,Ajouter
|
||||
Add / Edit Taxes and Charges,Ajouter / Modifier Taxes et frais
|
||||
Add Child,Ajouter un enfant
|
||||
Add Serial No,Ajouter N ° de série
|
||||
Add Serial No,Ajouter Numéro de série
|
||||
Add Taxes,Ajouter impôts
|
||||
Add Taxes and Charges,Ajouter Taxes et frais
|
||||
Add or Deduct,Ajouter ou déduire
|
||||
Add rows to set annual budgets on Accounts.,Ajoutez des lignes d'établir des budgets annuels des comptes.
|
||||
Add to Cart,ERP open source construit pour le web
|
||||
Add to calendar on this date,Ajouter au calendrier à cette date
|
||||
Add rows to set annual budgets on Accounts.,Ajoutez des lignes pour établir des budgets annuels sur des comptes.
|
||||
Add to Cart,Ajouter au panier
|
||||
Add to calendar on this date,Ajouter cette date au calendrier
|
||||
Add/Remove Recipients,Ajouter / supprimer des destinataires
|
||||
Address,Adresse
|
||||
Address & Contact,Adresse et coordonnées
|
||||
Address & Contacts,Adresse & Contacts
|
||||
Address & Contacts,Adresse & Coordonnées
|
||||
Address Desc,Adresse Desc
|
||||
Address Details,Détails de l'adresse
|
||||
Address HTML,Adresse HTML
|
||||
Address Line 1,Adresse ligne 1
|
||||
Address Line 2,Adresse ligne 2
|
||||
Address Template,Adresse modèle
|
||||
Address Title,Titre Adresse
|
||||
Address Title,Titre de l'adresse
|
||||
Address Title is mandatory.,Vous n'êtes pas autorisé à imprimer ce document
|
||||
Address Type,Type d'adresse
|
||||
Address master.,Ou créés par
|
||||
Administrative Expenses,applicabilité
|
||||
Address master.,Adresse principale
|
||||
Administrative Expenses,Dépenses administratives
|
||||
Administrative Officer,de l'administration
|
||||
Advance Amount,Montant de l'avance
|
||||
Advance amount,Montant de l'avance
|
||||
@ -142,7 +143,7 @@ Advances,Avances
|
||||
Advertisement,Publicité
|
||||
Advertising,publicité
|
||||
Aerospace,aérospatial
|
||||
After Sale Installations,Après Installations Vente
|
||||
After Sale Installations,Installations Après Vente
|
||||
Against,Contre
|
||||
Against Account,Contre compte
|
||||
Against Bill {0} dated {1},Courriel invalide : {0}
|
||||
@ -197,7 +198,7 @@ Allocated amount can not greater than unadusted amount,Montant alloué ne peut p
|
||||
Allow Bill of Materials,Laissez Bill of Materials
|
||||
Allow Bill of Materials should be 'Yes'. Because one or many active BOMs present for this item,Commande {0} n'est pas valide
|
||||
Allow Children,permettre aux enfants
|
||||
Allow Dropbox Access,Autoriser l'accès Dropbox
|
||||
Allow Dropbox Access,Autoriser l'accès au Dropbox
|
||||
Allow Google Drive Access,Autoriser Google Drive accès
|
||||
Allow Negative Balance,Laissez solde négatif
|
||||
Allow Negative Stock,Laissez Stock Négatif
|
||||
@ -219,7 +220,7 @@ An Customer exists with same name,Il existe un client avec le même nom
|
||||
"An Item Group exists with same name, please change the item name or rename the item group","Un groupe d'objet existe avec le même nom , s'il vous plaît changer le nom de l'élément ou de renommer le groupe de l'article"
|
||||
"An item exists with same name ({0}), please change the item group name or rename the item",Le compte doit être un compte de bilan
|
||||
Analyst,analyste
|
||||
Annual,Nomenclature
|
||||
Annual,Annuel
|
||||
Another Period Closing Entry {0} has been made after {1},Point Wise impôt Détail
|
||||
Another Salary Structure {0} is active for employee {0}. Please make its status 'Inactive' to proceed.,Le taux de conversion ne peut pas être égal à 0 ou 1
|
||||
"Any other comments, noteworthy effort that should go in the records.","D'autres commentaires, l'effort remarquable qui devrait aller dans les dossiers."
|
||||
@ -288,20 +289,20 @@ Automatically extract Job Applicants from a mail box ,
|
||||
Automatically extract Leads from a mail box e.g.,Extraire automatiquement des prospects à partir d'une boîte aux lettres par exemple
|
||||
Automatically updated via Stock Entry of type Manufacture/Repack,Automatiquement mis à jour via l'entrée de fabrication de type Stock / Repack
|
||||
Automotive,automobile
|
||||
Autoreply when a new mail is received,Autoreply quand un nouveau message est reçu
|
||||
Autoreply when a new mail is received,Réponse automatique lorsqu'un nouveau message est reçu
|
||||
Available,disponible
|
||||
Available Qty at Warehouse,Qté disponible à l'entrepôt
|
||||
Available Stock for Packing Items,Disponible en stock pour l'emballage Articles
|
||||
"Available in BOM, Delivery Note, Purchase Invoice, Production Order, Purchase Order, Purchase Receipt, Sales Invoice, Sales Order, Stock Entry, Timesheet","Disponible en nomenclature , bon de livraison , facture d'achat , ordre de production, bon de commande , bon de réception , la facture de vente , Sales Order , Stock entrée , des feuilles de temps"
|
||||
Average Age,moyen âge
|
||||
Average Commission Rate,Taux moyen Commission
|
||||
Average Discount,D'actualisation moyen
|
||||
Awesome Products,"Pour suivre le nom de la marque dans la note qui suit documents de livraison , Opportunité , Demande de Matériel , article , bon de commande, bon d'achat, l'acheteur réception , offre , facture de vente , ventes BOM , Sales Order , No de série"
|
||||
Awesome Services,Restrictions d'autorisation de l'utilisateur
|
||||
BOM Detail No,Détail BOM Non
|
||||
Average Age,âge moyen
|
||||
Average Commission Rate,Taux moyen de la commission
|
||||
Average Discount,Remise moyenne
|
||||
Awesome Products,Produits impressionnants
|
||||
Awesome Services,Services impressionnants
|
||||
BOM Detail No,Numéro du détail BOM
|
||||
BOM Explosion Item,Article éclatement de la nomenclature
|
||||
BOM Item,Article BOM
|
||||
BOM No,Aucune nomenclature
|
||||
BOM No,Numéro BOM
|
||||
BOM No. for a Finished Good Item,N ° nomenclature pour un produit fini Bonne
|
||||
BOM Operation,Opération BOM
|
||||
BOM Operations,Opérations de nomenclature
|
||||
@ -314,50 +315,50 @@ BOM {0} for Item {1} in row {2} is inactive or not submitted,Dépenses de voyage
|
||||
BOM {0} is not active or not submitted,Eléments requis
|
||||
BOM {0} is not submitted or inactive BOM for Item {1},BOM {0} n'est pas soumis ou inactif nomenclature pour objet {1}
|
||||
Backup Manager,Gestionnaire de sauvegarde
|
||||
Backup Right Now,Sauvegarde Right Now
|
||||
Backup Right Now,Sauvegarder immédiatement
|
||||
Backups will be uploaded to,Les sauvegardes seront téléchargées sur
|
||||
Balance Qty,solde Quantité
|
||||
Balance Sheet,Fournisseur Type maître .
|
||||
Balance Value,Valeur de balance
|
||||
Balance for Account {0} must always be {1},Point {0} avec Serial Non {1} est déjà installé
|
||||
Balance must be,avec des grands livres
|
||||
"Balances of Accounts of type ""Bank"" or ""Cash""",Date de vieillissement est obligatoire pour l'ouverture d'entrée
|
||||
Balance Qty,Qté soldée
|
||||
Balance Sheet,Bilan
|
||||
Balance Value,Valeur du solde
|
||||
Balance for Account {0} must always be {1},Solde pour le compte {0} doit toujours être {1}
|
||||
Balance must be,Solde doit être
|
||||
"Balances of Accounts of type ""Bank"" or ""Cash""","Solde du compte de type ""Banque"" ou ""Espèces"""
|
||||
Bank,Banque
|
||||
Bank / Cash Account,Banque / Compte de trésorerie
|
||||
Bank A/C No.,Bank A / C No.
|
||||
Bank / Cash Account,Compte en Banque / trésorerie
|
||||
Bank A/C No.,No. de compte bancaire
|
||||
Bank Account,Compte bancaire
|
||||
Bank Account No.,N ° de compte bancaire
|
||||
Bank Account No.,No. de compte bancaire
|
||||
Bank Accounts,Comptes bancaires
|
||||
Bank Clearance Summary,Banque Résumé de dégagement
|
||||
Bank Clearance Summary,Résumé de l'approbation de la banque
|
||||
Bank Draft,Projet de la Banque
|
||||
Bank Name,Nom de la banque
|
||||
Bank Overdraft Account,Inspection de la qualité requise pour objet {0}
|
||||
Bank Overdraft Account,Compte du découvert bancaire
|
||||
Bank Reconciliation,Rapprochement bancaire
|
||||
Bank Reconciliation Detail,Détail de rapprochement bancaire
|
||||
Bank Reconciliation Statement,État de rapprochement bancaire
|
||||
Bank Voucher,Bon Banque
|
||||
Bank/Cash Balance,Banque / Balance trésorerie
|
||||
Banking,bancaire
|
||||
Bank Reconciliation Detail,Détail du rapprochement bancaire
|
||||
Bank Reconciliation Statement,Énoncé de rapprochement bancaire
|
||||
Bank Voucher,Coupon de la banque
|
||||
Bank/Cash Balance,Solde de la banque / trésorerie
|
||||
Banking,Bancaire
|
||||
Barcode,Barcode
|
||||
Barcode {0} already used in Item {1},Lettre d'information a déjà été envoyé
|
||||
Barcode {0} already used in Item {1},Le code barre {0} est déjà utilisé dans l'article {1}
|
||||
Based On,Basé sur
|
||||
Basic,de base
|
||||
Basic Info,Informations de base
|
||||
Basic Information,Renseignements de base
|
||||
Basic Rate,Taux de base
|
||||
Basic Rate (Company Currency),Taux de base (Société Monnaie)
|
||||
Basic Rate (Company Currency),Taux de base (Monnaie de la Société )
|
||||
Batch,Lot
|
||||
Batch (lot) of an Item.,Batch (lot) d'un élément.
|
||||
Batch Finished Date,Date de lot fini
|
||||
Batch ID,ID du lot
|
||||
Batch No,Aucun lot
|
||||
Batch Started Date,Date de démarrage du lot
|
||||
Batch (lot) of an Item.,Lot d'une article.
|
||||
Batch Finished Date,La date finie d'un lot
|
||||
Batch ID,Identifiant du lot
|
||||
Batch No,Numéro du lot
|
||||
Batch Started Date,Date de début du lot
|
||||
Batch Time Logs for billing.,Temps de lots des journaux pour la facturation.
|
||||
Batch-Wise Balance History,Discontinu Histoire de la balance
|
||||
Batched for Billing,Par lots pour la facturation
|
||||
Better Prospects,De meilleures perspectives
|
||||
Bill Date,Bill Date
|
||||
Bill No,Le projet de loi no
|
||||
Bill Date,Date de la facture
|
||||
Bill No,Numéro de la facture
|
||||
Bill No {0} already booked in Purchase Invoice {1},Centre de coûts de transactions existants ne peut pas être converti en livre
|
||||
Bill of Material,De la valeur doit être inférieure à la valeur à la ligne {0}
|
||||
Bill of Material to be considered for manufacturing,Bill of Material être considéré pour la fabrication
|
||||
@ -386,22 +387,22 @@ Both Warehouse must belong to same Company,Les deux Entrepôt doit appartenir à
|
||||
Box,boîte
|
||||
Branch,Branche
|
||||
Brand,Marque
|
||||
Brand Name,Nom de marque
|
||||
Brand Name,La marque
|
||||
Brand master.,Marque maître.
|
||||
Brands,Marques
|
||||
Breakdown,Panne
|
||||
Broadcasting,radiodiffusion
|
||||
Broadcasting,Diffusion
|
||||
Brokerage,courtage
|
||||
Budget,Budget
|
||||
Budget Allocated,Budget alloué
|
||||
Budget Detail,Détail du budget
|
||||
Budget Details,Détails du budget
|
||||
Budget Distribution,Répartition du budget
|
||||
Budget Distribution Detail,Détail Répartition du budget
|
||||
Budget Distribution Detail,Détail de la répartition du budget
|
||||
Budget Distribution Details,Détails de la répartition du budget
|
||||
Budget Variance Report,Rapport sur les écarts de budget
|
||||
Budget Variance Report,Rapport sur les écarts du budget
|
||||
Budget cannot be set for Group Cost Centers,Imprimer et stationnaire
|
||||
Build Report,construire Rapport
|
||||
Build Report,Créer un rapport
|
||||
Bundle items at time of sale.,Regrouper des envois au moment de la vente.
|
||||
Business Development Manager,Directeur du développement des affaires
|
||||
Buying,Achat
|
||||
@ -501,7 +502,7 @@ Cheque Date,Date de chèques
|
||||
Cheque Number,Numéro de chèque
|
||||
Child account exists for this account. You can not delete this account.,Les matières premières ne peut pas être le même que l'article principal
|
||||
City,Ville
|
||||
City/Town,Ville /
|
||||
City/Town,Ville
|
||||
Claim Amount,Montant réclamé
|
||||
Claims for company expense.,Les réclamations pour frais de la société.
|
||||
Class / Percentage,Classe / Pourcentage
|
||||
@ -561,11 +562,11 @@ Complete,Compléter
|
||||
Complete Setup,congé de maladie
|
||||
Completed,Terminé
|
||||
Completed Production Orders,Terminé les ordres de fabrication
|
||||
Completed Qty,Complété Quantité
|
||||
Completed Qty,Quantité complétée
|
||||
Completion Date,Date d'achèvement
|
||||
Completion Status,L'état d'achèvement
|
||||
Computer,ordinateur
|
||||
Computers,Informatique
|
||||
Computers,Ordinateurs
|
||||
Confirmation Date,date de confirmation
|
||||
Confirmed orders from Customers.,Confirmé commandes provenant de clients.
|
||||
Consider Tax or Charge for,Prenons l'impôt ou charge pour
|
||||
@ -715,7 +716,7 @@ Customize the introductory text that goes as a part of that email. Each transact
|
||||
DN Detail,Détail DN
|
||||
Daily,Quotidien
|
||||
Daily Time Log Summary,Daily Time Sommaire du journal
|
||||
Database Folder ID,Database ID du dossier
|
||||
Database Folder ID,Identifiant du dossier de la base de données
|
||||
Database of potential customers.,Base de données de clients potentiels.
|
||||
Date,Date
|
||||
Date Format,Format de date
|
||||
@ -745,7 +746,7 @@ Deductions,Déductions
|
||||
Default,Par défaut
|
||||
Default Account,Compte par défaut
|
||||
Default Address Template cannot be deleted,Adresse par défaut modèle ne peut pas être supprimé
|
||||
Default Amount,Montant en défaut
|
||||
Default Amount,Montant par défaut
|
||||
Default BOM,Nomenclature par défaut
|
||||
Default Bank / Cash account will be automatically updated in POS Invoice when this mode is selected.,Par défaut Banque / argent compte sera automatiquement mis à jour dans la facture POS lorsque ce mode est sélectionné.
|
||||
Default Bank Account,Compte bancaire par défaut
|
||||
@ -779,18 +780,18 @@ Default settings for selling transactions.,principal
|
||||
Default settings for stock transactions.,minute
|
||||
Defense,défense
|
||||
"Define Budget for this Cost Center. To set budget action, see <a href=""#!List/Company"">Company Master</a>","Définir le budget pour ce centre de coûts. Pour définir l'action budgétaire, voir <a href=""#!List/Company"">Maître Société</a>"
|
||||
Del,Eff
|
||||
Delete,Effacer
|
||||
Del,Suppr
|
||||
Delete,Supprimer
|
||||
Delete {0} {1}?,Supprimer {0} {1} ?
|
||||
Delivered,Livré
|
||||
Delivered Items To Be Billed,Les articles livrés être facturé
|
||||
Delivered Items To Be Billed,Les items livrés à être facturés
|
||||
Delivered Qty,Qté livrée
|
||||
Delivered Serial No {0} cannot be deleted,médical
|
||||
Delivery Date,Date de livraison
|
||||
Delivery Details,Détails de la livraison
|
||||
Delivery Document No,Pas de livraison de documents
|
||||
Delivery Document Type,Type de document de livraison
|
||||
Delivery Note,Remarque livraison
|
||||
Delivery Note,Bon de livraison
|
||||
Delivery Note Item,Point de Livraison
|
||||
Delivery Note Items,Articles bordereau de livraison
|
||||
Delivery Note Message,Note Message de livraison
|
||||
@ -800,9 +801,9 @@ Delivery Note Trends,Bordereau de livraison Tendances
|
||||
Delivery Note {0} is not submitted,Livraison Remarque {0} n'est pas soumis
|
||||
Delivery Note {0} must not be submitted,Pas de clients ou fournisseurs Comptes trouvé
|
||||
Delivery Notes {0} must be cancelled before cancelling this Sales Order,Quantité en ligne {0} ( {1} ) doit être la même que la quantité fabriquée {2}
|
||||
Delivery Status,Delivery Status
|
||||
Delivery Time,Délai de livraison
|
||||
Delivery To,Pour livraison
|
||||
Delivery Status,Statut de la livraison
|
||||
Delivery Time,L'heure de la livraison
|
||||
Delivery To,Livrer à
|
||||
Department,Département
|
||||
Department Stores,Grands Magasins
|
||||
Depends on LWP,Dépend de LWP
|
||||
@ -822,8 +823,8 @@ Direct Income,Choisissez votre langue
|
||||
Disable,"Groupe ajoutée, rafraîchissant ..."
|
||||
Disable Rounded Total,Désactiver totale arrondie
|
||||
Disabled,Handicapé
|
||||
Discount %,% De réduction
|
||||
Discount %,% De réduction
|
||||
Discount %,% Remise
|
||||
Discount %,% Remise
|
||||
Discount (%),Remise (%)
|
||||
Discount Amount,S'il vous plaît tirer des articles de livraison Note
|
||||
"Discount Fields will be available in Purchase Order, Purchase Receipt, Purchase Invoice","Les champs d'actualisation sera disponible en commande, reçu d'achat, facture d'achat"
|
||||
@ -1464,8 +1465,8 @@ Journal Voucher {0} does not have account {1} or already matched,Journal Bon {0}
|
||||
Journal Vouchers {0} are un-linked,Date de livraison prévue ne peut pas être avant ventes Date de commande
|
||||
Keep a track of communication related to this enquiry which will help for future reference.,Gardez une trace de la communication liée à cette enquête qui aidera pour référence future.
|
||||
Keep it web friendly 900px (w) by 100px (h),Gardez web 900px amical ( w) par 100px ( h )
|
||||
Key Performance Area,Zone de performance clé
|
||||
Key Responsibility Area,Secteur de responsabilité clé
|
||||
Key Performance Area,Section de performance clé
|
||||
Key Responsibility Area,Section à responsabilité importante
|
||||
Kg,kg
|
||||
LR Date,LR Date
|
||||
LR No,LR Non
|
||||
@ -1723,9 +1724,9 @@ Net Weight UOM,Emballage Poids Net
|
||||
Net Weight of each Item,Poids net de chaque article
|
||||
Net pay cannot be negative,Landed Cost correctement mis à jour
|
||||
Never,Jamais
|
||||
New ,
|
||||
New ,Nouveau
|
||||
New Account,nouveau compte
|
||||
New Account Name,Nouveau compte Nom
|
||||
New Account Name,Nom du nouveau compte
|
||||
New BOM,Nouvelle nomenclature
|
||||
New Communications,Communications Nouveau-
|
||||
New Company,nouvelle entreprise
|
||||
@ -1761,11 +1762,11 @@ Newspaper Publishers,Éditeurs de journaux
|
||||
Next,Nombre purchse de commande requis pour objet {0}
|
||||
Next Contact By,Suivant Par
|
||||
Next Contact Date,Date Contact Suivant
|
||||
Next Date,Date d'
|
||||
Next Date,Date suivante
|
||||
Next email will be sent on:,Email sera envoyé le:
|
||||
No,Aucun
|
||||
No,Non
|
||||
No Customer Accounts found.,Aucun client ne représente trouvés.
|
||||
No Customer or Supplier Accounts found,Encaisse
|
||||
No Customer or Supplier Accounts found,Aucun compte client ou fournisseur trouvé
|
||||
No Expense Approvers. Please assign 'Expense Approver' Role to atleast one user,Compte {0} est inactif
|
||||
No Item with Barcode {0},Bon de commande {0} ' arrêté '
|
||||
No Item with Serial No {0},non autorisé
|
||||
@ -1775,13 +1776,13 @@ No Permission,Aucune autorisation
|
||||
No Production Orders created,Section de base
|
||||
No Supplier Accounts found. Supplier Accounts are identified based on 'Master Type' value in account record.,Aucun fournisseur ne représente trouvés. Comptes fournisseurs sont identifiés sur la base de la valeur «Maître Type ' dans le compte rendu.
|
||||
No accounting entries for the following warehouses,Pas d'entrées comptables pour les entrepôts suivants
|
||||
No addresses created,Aucune adresse créés
|
||||
No addresses created,Aucune adresse créée
|
||||
No contacts created,Pas de contacts créés
|
||||
No default Address Template found. Please create a new one from Setup > Printing and Branding > Address Template.,Aucune valeur par défaut Adresse modèle trouvé. S'il vous plaît créer un nouveau à partir de Configuration> Presse et Branding> Adresse modèle.
|
||||
No default BOM exists for Item {0},services impressionnants
|
||||
No description given,Le jour (s ) sur lequel vous postulez pour congé sont les vacances . Vous n'avez pas besoin de demander l'autorisation .
|
||||
No employee found,Aucun employé
|
||||
No employee found!,Aucun employé !
|
||||
No employee found,Aucun employé trouvé
|
||||
No employee found!,Aucun employé trouvé!
|
||||
No of Requested SMS,Pas de SMS demandés
|
||||
No of Sent SMS,Pas de SMS envoyés
|
||||
No of Visits,Pas de visites
|
||||
@ -1816,14 +1817,14 @@ Note: This Cost Center is a Group. Cannot make accounting entries against groups
|
||||
Note: {0},Compte avec des nœuds enfants ne peut pas être converti en livre
|
||||
Notes,Remarques
|
||||
Notes:,notes:
|
||||
Nothing to request,Rien à demander
|
||||
Nothing to request,Pas de requête à demander
|
||||
Notice (days),Avis ( jours )
|
||||
Notification Control,Contrôle de notification
|
||||
Notification Email Address,Adresse e-mail de notification
|
||||
Notify by Email on creation of automatic Material Request,Notification par courriel lors de la création de la demande de matériel automatique
|
||||
Number Format,Format numérique
|
||||
Offer Date,offre date
|
||||
Office,Fonction
|
||||
Offer Date,Date de l'offre
|
||||
Office,Bureau
|
||||
Office Equipments,Équipement de bureau
|
||||
Office Maintenance Expenses,Date d'adhésion doit être supérieure à Date de naissance
|
||||
Office Rent,POS Global Setting {0} déjà créé pour la compagnie {1}
|
||||
@ -1970,7 +1971,7 @@ Payments made during the digest period,Les paiements effectués au cours de la p
|
||||
Payments received during the digest period,Les paiements reçus au cours de la période digest
|
||||
Payroll Settings,Paramètres de la paie
|
||||
Pending,En attendant
|
||||
Pending Amount,Montant attente
|
||||
Pending Amount,Montant en attente
|
||||
Pending Items {0} updated,Machines et installations
|
||||
Pending Review,Attente d'examen
|
||||
Pending SO Items For Purchase Request,"Articles en attente Donc, pour demande d'achat"
|
||||
@ -2097,11 +2098,11 @@ Please set {0},S'il vous plaît mettre {0}
|
||||
Please setup Employee Naming System in Human Resource > HR Settings,S'il vous plaît configuration Naming System employés en ressources humaines> Paramètres RH
|
||||
Please setup numbering series for Attendance via Setup > Numbering Series,S'il vous plaît configuration série de numérotation à la fréquentation via Configuration> Série de numérotation
|
||||
Please setup your chart of accounts before you start Accounting Entries,S'il vous plaît configurer votre plan de comptes avant de commencer Écritures comptables
|
||||
Please specify,S'il vous plaît spécifier
|
||||
Please specify,Veuillez spécifier
|
||||
Please specify Company,S'il vous plaît préciser Company
|
||||
Please specify Company to proceed,Veuillez indiquer Société de procéder
|
||||
Please specify Default Currency in Company Master and Global Defaults,N ° de série {0} n'existe pas
|
||||
Please specify a,S'il vous plaît spécifier une
|
||||
Please specify a,Veuillez spécifier un
|
||||
Please specify a valid 'From Case No.',S'il vous plaît indiquer une valide »De Affaire n '
|
||||
Please specify a valid Row ID for {0} in row {1},Il s'agit d'un site d'exemple généré automatiquement à partir de ERPNext
|
||||
Please specify either Quantity or Valuation Rate or both,S'il vous plaît spécifier Quantité ou l'évaluation des taux ou à la fois
|
||||
@ -2205,7 +2206,7 @@ Publishing,édition
|
||||
Pull sales orders (pending to deliver) based on the above criteria,Tirez les ordres de vente (en attendant de livrer) sur la base des critères ci-dessus
|
||||
Purchase,Acheter
|
||||
Purchase / Manufacture Details,Achat / Fabrication Détails
|
||||
Purchase Analytics,Achat Analytics
|
||||
Purchase Analytics,Les analyses des achats
|
||||
Purchase Common,Achat commune
|
||||
Purchase Details,Conditions de souscription
|
||||
Purchase Discounts,Rabais sur l'achat
|
||||
@ -2256,7 +2257,7 @@ Qty To Manufacture,Quantité à fabriquer
|
||||
Qty as per Stock UOM,Qté en stock pour Emballage
|
||||
Qty to Deliver,Quantité à livrer
|
||||
Qty to Order,Quantité à commander
|
||||
Qty to Receive,Quantité pour recevoir
|
||||
Qty to Receive,Quantité à recevoir
|
||||
Qty to Transfer,Quantité de Transfert
|
||||
Qualification,Qualification
|
||||
Quality,Qualité
|
||||
@ -2278,11 +2279,11 @@ Quantity required for Item {0} in row {1},Quantité requise pour objet {0} à la
|
||||
Quarter,Trimestre
|
||||
Quarterly,Trimestriel
|
||||
Quick Help,Aide rapide
|
||||
Quotation,Citation
|
||||
Quotation,Devis
|
||||
Quotation Item,Article devis
|
||||
Quotation Items,Articles de devis
|
||||
Quotation Lost Reason,Devis perdu la raison
|
||||
Quotation Message,Devis message
|
||||
Quotation Message,Message du devis
|
||||
Quotation To,Devis Pour
|
||||
Quotation Trends,Devis Tendances
|
||||
Quotation {0} is cancelled,Devis {0} est annulée
|
||||
@ -2296,8 +2297,8 @@ Random,Aléatoire
|
||||
Range,Gamme
|
||||
Rate,Taux
|
||||
Rate ,Taux
|
||||
Rate (%),S'il vous plaît entrer la date soulager .
|
||||
Rate (Company Currency),Taux (Société Monnaie)
|
||||
Rate (%),Taux (%)
|
||||
Rate (Company Currency),Taux (Monnaie de la société)
|
||||
Rate Of Materials Based On,Taux de matériaux à base
|
||||
Rate and Amount,Taux et le montant
|
||||
Rate at which Customer Currency is converted to customer's base currency,Vitesse à laquelle la devise du client est converti en devise de base du client
|
||||
@ -2318,15 +2319,15 @@ Re-order Level,Re-order niveau
|
||||
Re-order Qty,Re-order Quantité
|
||||
Read,Lire
|
||||
Reading 1,Lecture 1
|
||||
Reading 10,Lecture le 10
|
||||
Reading 10,Lecture 10
|
||||
Reading 2,Lecture 2
|
||||
Reading 3,Reading 3
|
||||
Reading 4,Reading 4
|
||||
Reading 5,Reading 5
|
||||
Reading 6,Lecture 6
|
||||
Reading 7,Lecture le 7
|
||||
Reading 7,Lecture 7
|
||||
Reading 8,Lecture 8
|
||||
Reading 9,Lectures suggérées 9
|
||||
Reading 9,Lecture 9
|
||||
Real Estate,Immobilier
|
||||
Reason,Raison
|
||||
Reason for Leaving,Raison du départ
|
||||
@ -2345,7 +2346,7 @@ Received and Accepted,Reçus et acceptés
|
||||
Receiver List,Liste des récepteurs
|
||||
Receiver List is empty. Please create Receiver List,Soit quantité de cible ou le montant cible est obligatoire .
|
||||
Receiver Parameter,Paramètre récepteur
|
||||
Recipients,Récipiendaires
|
||||
Recipients,Destinataires
|
||||
Reconcile,réconcilier
|
||||
Reconciliation Data,Données de réconciliation
|
||||
Reconciliation HTML,Réconciliation HTML
|
||||
@ -2383,7 +2384,7 @@ Remarks,Remarques
|
||||
Remarks Custom,Remarques sur commande
|
||||
Rename,rebaptiser
|
||||
Rename Log,Renommez identifiez-vous
|
||||
Rename Tool,Renommer l'outil
|
||||
Rename Tool,Outils de renommage
|
||||
Rent Cost,louer coût
|
||||
Rent per hour,Louer par heure
|
||||
Rented,Loué
|
||||
@ -2419,8 +2420,8 @@ Reseller,Revendeur
|
||||
Reserved,réservé
|
||||
Reserved Qty,Quantité réservés
|
||||
"Reserved Qty: Quantity ordered for sale, but not delivered.","Réservés Quantité: Quantité de commande pour la vente , mais pas livré ."
|
||||
Reserved Quantity,Quantité réservés
|
||||
Reserved Warehouse,Réservé Entrepôt
|
||||
Reserved Quantity,Quantité réservée
|
||||
Reserved Warehouse,Entrepôt réservé
|
||||
Reserved Warehouse in Sales Order / Finished Goods Warehouse,Entrepôt réservé à des commandes clients / entrepôt de produits finis
|
||||
Reserved Warehouse is missing in Sales Order,Réservé entrepôt est manquant dans l'ordre des ventes
|
||||
Reserved Warehouse required for stock Item {0} in row {1},Centre de coûts par défaut de vente
|
||||
@ -3158,8 +3159,8 @@ Voucher Type and Date,Type de chèques et date
|
||||
Walk In,Walk In
|
||||
Warehouse,entrepôt
|
||||
Warehouse Contact Info,Entrepôt Info Contact
|
||||
Warehouse Detail,Détail d'entrepôt
|
||||
Warehouse Name,Nom d'entrepôt
|
||||
Warehouse Detail,Détail de l'entrepôt
|
||||
Warehouse Name,Nom de l'entrepôt
|
||||
Warehouse and Reference,Entrepôt et référence
|
||||
Warehouse can not be deleted as stock ledger entry exists for this warehouse.,Descendre : {0}
|
||||
Warehouse can only be changed via Stock Entry / Delivery Note / Purchase Receipt,Entrepôt ne peut être modifié via Stock Entrée / bon de livraison / reçu d'achat
|
||||
@ -3177,15 +3178,15 @@ Warehouse {0}: Parent account {1} does not bolong to the company {2},Entrepôt {
|
||||
Warehouse-Wise Stock Balance,Warehouse-Wise Stock Solde
|
||||
Warehouse-wise Item Reorder,Warehouse-sage Réorganiser article
|
||||
Warehouses,Entrepôts
|
||||
Warehouses.,applicable
|
||||
Warehouses.,Entrepôts.
|
||||
Warn,Avertir
|
||||
Warning: Leave application contains following block dates,Attention: la demande d'autorisation contient les dates de blocs suivants
|
||||
Warning: Material Requested Qty is less than Minimum Order Qty,Attention: Matériel requis Quantité est inférieure Quantité minimum à commander
|
||||
Warning: Sales Order {0} already exists against same Purchase Order number,S'il vous plaît vérifier ' Est Advance' contre compte {0} si c'est une entrée avance .
|
||||
Warning: System will not check overbilling since amount for Item {0} in {1} is zero,Attention : Le système ne vérifie pas la surfacturation depuis montant pour objet {0} dans {1} est nulle
|
||||
Warranty / AMC Details,Garantie / AMC Détails
|
||||
Warranty / AMC Status,Garantie / AMC Statut
|
||||
Warranty Expiry Date,Date d'expiration de garantie
|
||||
Warranty / AMC Details,Garantie / Détails AMC
|
||||
Warranty / AMC Status,Garantie / Statut AMC
|
||||
Warranty Expiry Date,Date d'expiration de la garantie
|
||||
Warranty Period (Days),Période de garantie (jours)
|
||||
Warranty Period (in days),Période de garantie (en jours)
|
||||
We buy this Item,Nous achetons cet article
|
||||
@ -3237,7 +3238,7 @@ Write Off Outstanding Amount,Ecrire Off Encours
|
||||
Write Off Voucher,Ecrire Off Bon
|
||||
Wrong Template: Unable to find head row.,Modèle tort: Impossible de trouver la ligne de tête.
|
||||
Year,Année
|
||||
Year Closed,L'année Fermé
|
||||
Year Closed,L'année est fermée
|
||||
Year End Date,Fin de l'exercice Date de
|
||||
Year Name,Nom Année
|
||||
Year Start Date,Date de début Année
|
||||
|
|
@ -38,30 +38,30 @@ A Customer Group exists with same name please change the Customer name or rename
|
||||
A Customer exists with same name,यह नाम से दूसरा ग्राहक मौजूद हैं
|
||||
A Lead with this email id should exist,इस ईमेल आईडी के साथ एक लीड मौजूद होना चाहिए
|
||||
A Product or Service,उत्पाद या सेवा
|
||||
A Supplier exists with same name,सप्लायर एक ही नाम के साथ मौजूद है
|
||||
A symbol for this currency. For e.g. $,इस मुद्रा के लिए एक प्रतीक है. उदाहरण के लिए $
|
||||
A Supplier exists with same name,यह नाम से दूसरा आपूर्तिकर्ता मौजूद है
|
||||
A symbol for this currency. For e.g. $,इस मुद्रा के लिए एक प्रतीक. उदाहरण के लिए $
|
||||
AMC Expiry Date,एएमसी समाप्ति तिथि
|
||||
Abbr,Abbr
|
||||
Abbreviation cannot have more than 5 characters,संक्षिप्त 5 से अधिक वर्ण नहीं हो सकता
|
||||
Above Value,मूल्य से ऊपर
|
||||
Abbr,संक्षिप्त
|
||||
Abbreviation cannot have more than 5 characters,संक्षिप्त 5 से अधिक वर्ण की नहीं हो सकती
|
||||
Above Value,ऊपर मूल्य
|
||||
Absent,अनुपस्थित
|
||||
Acceptance Criteria,स्वीकृति मानदंड
|
||||
Acceptance Criteria,स्वीकृति मापदंड
|
||||
Accepted,स्वीकार किया
|
||||
Accepted + Rejected Qty must be equal to Received quantity for Item {0},स्वीकृत + अस्वीकृत मात्रा मद के लिए प्राप्त मात्रा के बराबर होना चाहिए {0}
|
||||
Accepted Quantity,स्वीकार किए जाते हैं मात्रा
|
||||
Accepted Warehouse,स्वीकार किए जाते हैं वेअरहाउस
|
||||
Accepted Warehouse,स्वीकार किए जाते हैं गोदाम
|
||||
Account,खाता
|
||||
Account Balance,खाता शेष
|
||||
Account Created: {0},खाता बनाया : {0}
|
||||
Account Balance,खाते की शेष राशि
|
||||
Account Created: {0},खाता बन गया : {0}
|
||||
Account Details,खाता विवरण
|
||||
Account Head,लेखाशीर्ष
|
||||
Account Name,खाते का नाम
|
||||
Account Type,खाता प्रकार
|
||||
"Account balance already in Credit, you are not allowed to set 'Balance Must Be' as 'Debit'","खाता शेष राशि पहले से ही क्रेडिट में, आप सेट करने की अनुमति नहीं है 'डेबिट' के रूप में 'बैलेंस होना चाहिए'"
|
||||
"Account balance already in Debit, you are not allowed to set 'Balance Must Be' as 'Credit'","पहले से ही डेबिट में खाता शेष, आप के रूप में 'क्रेडिट' 'बैलेंस होना चाहिए' स्थापित करने के लिए अनुमति नहीं है"
|
||||
"Account balance already in Credit, you are not allowed to set 'Balance Must Be' as 'Debit'","खाते की शेष राशि पहले से ही क्रेडिट में है, कृपया आप शेष राशि को डेबिट के रूप में ही रखें "
|
||||
"Account balance already in Debit, you are not allowed to set 'Balance Must Be' as 'Credit'","खाते की शेष राशि पहले से ही डेबिट में है, कृपया आप शेष राशि को क्रेडिट के रूप में ही रखें"
|
||||
Account for the warehouse (Perpetual Inventory) will be created under this Account.,गोदाम ( सदा सूची ) के लिए खाते में इस खाते के तहत बनाया जाएगा .
|
||||
Account head {0} created,लेखा शीर्ष {0} बनाया
|
||||
Account must be a balance sheet account,खाता एक वित्तीय स्थिति विवरण खाता होना चाहिए
|
||||
Account head {0} created,लेखाशीर्ष {0} बनाया
|
||||
Account must be a balance sheet account,खाता एक वित्तीय स्थिति विवरण का खाता होना चाहिए
|
||||
Account with child nodes cannot be converted to ledger,बच्चे नोड्स के साथ खाता लेजर को परिवर्तित नहीं किया जा सकता है
|
||||
Account with existing transaction can not be converted to group.,मौजूदा लेन - देन के साथ खाता समूह को नहीं बदला जा सकता .
|
||||
Account with existing transaction can not be deleted,मौजूदा लेन - देन के साथ खाता हटाया नहीं जा सकता
|
||||
|
|
@ -44,7 +44,7 @@ AMC Expiry Date,AMCの有効期限日
|
||||
Abbr,略称
|
||||
Abbreviation cannot have more than 5 characters,略語は、5つ以上の文字を使用することはできません
|
||||
Above Value,値を上回る
|
||||
Absent,ない
|
||||
Absent,いんない
|
||||
Acceptance Criteria,合否基準
|
||||
Accepted,承認済
|
||||
Accepted + Rejected Qty must be equal to Received quantity for Item {0},一般に認められた+拒否数量、アイテムの受信量と等しくなければなりません{0}
|
||||
|
|
@ -1559,9 +1559,9 @@ Maintain same rate throughout purchase cycle,รักษาอัตราเ
|
||||
Maintenance,การบำรุงรักษา
|
||||
Maintenance Date,วันที่การบำรุงรักษา
|
||||
Maintenance Details,รายละเอียดการบำรุงรักษา
|
||||
Maintenance Schedule,ตารางการบำรุงรักษา
|
||||
Maintenance Schedule Detail,รายละเอียดตารางการบำรุงรักษา
|
||||
Maintenance Schedule Item,รายการตารางการบำรุงรักษา
|
||||
Maintenance Schedule,กำหนดการซ่อมบำรุง
|
||||
Maintenance Schedule Detail,รายละเอียดกำหนดการซ่อมบำรุง
|
||||
Maintenance Schedule Item,รายการกำหนดการซ่อมบำรุง
|
||||
Maintenance Schedule is not generated for all the items. Please click on 'Generate Schedule',ตาราง การบำรุงรักษา ที่ไม่ได้ สร้างขึ้นสำหรับ รายการทั้งหมด กรุณา คลิกที่ 'สร้าง ตาราง '
|
||||
Maintenance Schedule {0} exists against {0},ตาราง การบำรุงรักษา {0} อยู่ กับ {0}
|
||||
Maintenance Schedule {0} must be cancelled before cancelling this Sales Order,ตาราง การบำรุงรักษา {0} ต้อง ถูกยกเลิก ก่อนที่จะ ยกเลิกการ สั่งซื้อการขาย นี้
|
||||
@ -1574,7 +1574,7 @@ Maintenance Visit Purpose,วัตถุประสงค์ชมการบ
|
||||
Maintenance Visit {0} must be cancelled before cancelling this Sales Order,การบำรุงรักษา ไปที่ {0} ต้อง ถูกยกเลิก ก่อนที่จะ ยกเลิกการ สั่งซื้อการขาย นี้
|
||||
Maintenance start date can not be before delivery date for Serial No {0},วันที่เริ่มต้น การบำรุงรักษา ไม่สามารถ ก่อนวัน ส่งสำหรับ อนุกรม ไม่มี {0}
|
||||
Major/Optional Subjects,วิชาเอก / เสริม
|
||||
Make ,
|
||||
Make ,สร้าง
|
||||
Make Accounting Entry For Every Stock Movement,ทำให้ รายการ บัญชี สำหรับ ทุก การเคลื่อนไหวของ หุ้น
|
||||
Make Bank Voucher,ทำให้บัตรของธนาคาร
|
||||
Make Credit Note,ให้ เครดิต หมายเหตุ
|
||||
@ -1587,7 +1587,7 @@ Make Invoice,ทำให้ ใบแจ้งหนี้
|
||||
Make Maint. Schedule,ทำให้ Maint ตารางเวลา
|
||||
Make Maint. Visit,ทำให้ Maint เยือน
|
||||
Make Maintenance Visit,ทำให้ การบำรุงรักษา เยี่ยมชม
|
||||
Make Packing Slip,ให้ บรรจุ สลิป
|
||||
Make Packing Slip,สร้าง รายการบรรจุภัณฑ์
|
||||
Make Payment,ชำระเงิน
|
||||
Make Payment Entry,ทำ รายการ ชำระเงิน
|
||||
Make Purchase Invoice,ให้ ซื้อ ใบแจ้งหนี้
|
||||
@ -1628,7 +1628,7 @@ Mass Mailing,จดหมายมวล
|
||||
Master Name,ชื่อปริญญาโท
|
||||
Master Name is mandatory if account type is Warehouse,ชื่อ ปริญญาโท มีผลบังคับใช้ ถ้าชนิด บัญชี คลังสินค้า
|
||||
Master Type,ประเภทหลัก
|
||||
Masters,โท
|
||||
Masters,ข้อมูลหลัก
|
||||
Match non-linked Invoices and Payments.,ตรงกับใบแจ้งหนี้ไม่ได้เชื่อมโยงและการชำระเงิน
|
||||
Material Issue,ฉบับวัสดุ
|
||||
Material Receipt,ใบเสร็จรับเงินวัสดุ
|
||||
@ -2465,7 +2465,7 @@ Row {0}:Start Date must be before End Date,แถว {0}: วันที่ เ
|
||||
Rules for adding shipping costs.,กฎระเบียบ สำหรับการเพิ่ม ค่าใช้จ่ายใน การจัดส่งสินค้า
|
||||
Rules for applying pricing and discount.,กฎระเบียบ สำหรับการใช้ การกำหนดราคาและ ส่วนลด
|
||||
Rules to calculate shipping amount for a sale,กฎระเบียบในการคำนวณปริมาณการขนส่งสินค้าสำหรับการขาย
|
||||
S.O. No.,S.O. เลขที่
|
||||
S.O. No.,เลขที่ใบสั่งขาย
|
||||
SHE Cess on Excise,SHE Cess บนสรรพสามิต
|
||||
SHE Cess on Service Tax,SHE Cess กับภาษีบริการ
|
||||
SHE Cess on TDS,SHE Cess ใน TDS
|
||||
@ -2550,7 +2550,7 @@ Salutation,ประณม
|
||||
Sample Size,ขนาดของกลุ่มตัวอย่าง
|
||||
Sanctioned Amount,จำนวนตามทำนองคลองธรรม
|
||||
Saturday,วันเสาร์
|
||||
Schedule,กำหนด
|
||||
Schedule,กำหนดการ
|
||||
Schedule Date,กำหนดการ วันที่
|
||||
Schedule Details,รายละเอียดตาราง
|
||||
Scheduled,กำหนด
|
||||
@ -2564,7 +2564,7 @@ Score Earned,คะแนนที่ได้รับ
|
||||
Score must be less than or equal to 5,คะแนน ต้องน้อยกว่า หรือ เท่ากับ 5
|
||||
Scrap %,เศษ%
|
||||
Seasonality for setting budgets.,ฤดูกาลสำหรับงบประมาณการตั้งค่า
|
||||
Secretary,เลขานุการ
|
||||
Secretary,เลขา
|
||||
Secured Loans,เงินให้กู้ยืม ที่มีหลักประกัน
|
||||
Securities & Commodity Exchanges,หลักทรัพย์และ การแลกเปลี่ยน สินค้าโภคภัณฑ์
|
||||
Securities and Deposits,หลักทรัพย์และ เงินฝาก
|
||||
@ -2603,14 +2603,14 @@ Select your home country and check the timezone and currency.,เลือกป
|
||||
"Selecting ""Yes"" will allow you to create Bill of Material showing raw material and operational costs incurred to manufacture this item.",เลือก "ใช่" จะช่วยให้คุณสามารถสร้างบิลของวัสดุแสดงวัตถุดิบและต้นทุนการดำเนินงานที่เกิดขึ้นในการผลิตรายการนี้
|
||||
"Selecting ""Yes"" will allow you to make a Production Order for this item.",เลือก "ใช่" จะช่วยให้คุณที่จะทำให้การสั่งซื้อการผลิตสำหรับรายการนี้
|
||||
"Selecting ""Yes"" will give a unique identity to each entity of this item which can be viewed in the Serial No master.",เลือก "Yes" จะให้เอกลักษณ์เฉพาะของแต่ละองค์กรเพื่อรายการนี้ซึ่งสามารถดูได้ในหลักหมายเลขเครื่อง
|
||||
Selling,ขาย
|
||||
Selling Settings,การขายการตั้งค่า
|
||||
Selling,การขาย
|
||||
Selling Settings,ตั้งค่าระบบการขาย
|
||||
"Selling must be checked, if Applicable For is selected as {0}",ขายจะต้องตรวจสอบถ้าใช้สำหรับการถูกเลือกเป็น {0}
|
||||
Send,ส่ง
|
||||
Send Autoreply,ส่ง autoreply
|
||||
Send Email,ส่งอีเมล์
|
||||
Send From,ส่งเริ่มต้นที่
|
||||
Send Notifications To,ส่งการแจ้งเตือนไป
|
||||
Send From,ส่งจาก
|
||||
Send Notifications To,แจ้งเตือนไปให้
|
||||
Send Now,ส่งเดี๋ยวนี้
|
||||
Send SMS,ส่ง SMS
|
||||
Send To,ส่งให้
|
||||
|
|
@ -38,7 +38,7 @@ A Customer Group exists with same name please change the Customer name or rename
|
||||
A Customer exists with same name,Bir Müşteri aynı adla
|
||||
A Lead with this email id should exist,Bu e-posta kimliği ile bir Kurşun bulunmalıdır
|
||||
A Product or Service,Bir Ürün veya Hizmet
|
||||
A Supplier exists with same name,A Tedarikçi aynı adla
|
||||
A Supplier exists with same name,Bu Tedarikçi mevcut
|
||||
A symbol for this currency. For e.g. $,Bu para için bir sembol. Örneğin $ için
|
||||
AMC Expiry Date,AMC Son Kullanma Tarihi
|
||||
Abbr,Kısaltma
|
||||
|
|
@ -22,7 +22,11 @@ def repost(allow_negative_stock=False):
|
||||
(select item_code, warehouse from tabBin
|
||||
union
|
||||
select item_code, warehouse from `tabStock Ledger Entry`) a"""):
|
||||
repost_stock(d[0], d[1])
|
||||
try:
|
||||
repost_stock(d[0], d[1])
|
||||
frappe.db.commit()
|
||||
except:
|
||||
frappe.db.rollback()
|
||||
|
||||
if allow_negative_stock:
|
||||
frappe.db.set_default("allow_negative_stock",
|
||||
@ -209,3 +213,38 @@ def reset_serial_no_status_and_warehouse(serial_nos=None):
|
||||
|
||||
frappe.db.sql("""update `tabSerial No` set warehouse='' where status in ('Delivered', 'Purchase Returned')""")
|
||||
|
||||
def repost_all_stock_vouchers():
|
||||
warehouses_with_account = frappe.db.sql_list("""select master_name from tabAccount
|
||||
where ifnull(account_type, '') = 'Warehouse'""")
|
||||
|
||||
vouchers = frappe.db.sql("""select distinct voucher_type, voucher_no
|
||||
from `tabStock Ledger Entry` sle
|
||||
where voucher_type != "Serial No" and sle.warehouse in (%s)
|
||||
order by posting_date, posting_time, name""" %
|
||||
', '.join(['%s']*len(warehouses_with_account)), tuple(warehouses_with_account))
|
||||
|
||||
rejected = []
|
||||
i = 0
|
||||
for voucher_type, voucher_no in vouchers:
|
||||
i+=1
|
||||
print i, "/", len(vouchers)
|
||||
try:
|
||||
for dt in ["Stock Ledger Entry", "GL Entry"]:
|
||||
frappe.db.sql("""delete from `tab%s` where voucher_type=%s and voucher_no=%s"""%
|
||||
(dt, '%s', '%s'), (voucher_type, voucher_no))
|
||||
|
||||
doc = frappe.get_doc(voucher_type, voucher_no)
|
||||
if voucher_type=="Stock Entry" and doc.purpose in ["Manufacture", "Repack"]:
|
||||
doc.get_stock_and_rate(force=1)
|
||||
elif voucher_type=="Purchase Receipt" and doc.is_subcontracted == "Yes":
|
||||
doc.validate()
|
||||
|
||||
doc.update_stock_ledger()
|
||||
doc.make_gl_entries(repost_future_gle=False, allow_negative_stock=True)
|
||||
frappe.db.commit()
|
||||
except Exception, e:
|
||||
print frappe.get_traceback()
|
||||
rejected.append([voucher_type, voucher_no])
|
||||
frappe.db.rollback()
|
||||
|
||||
print rejected
|
||||
|
Loading…
x
Reference in New Issue
Block a user