Compare commits

..

25 Commits

Author SHA1 Message Date
Nabin Hait
6a8d7a1b91 Merge branch 'develop' 2015-06-16 16:50:49 +05:30
Nabin Hait
5d71a28e97 bumped to version 5.0.25 2015-06-16 17:20:49 +06:00
Nabin Hait
7d100a1ee7 Merge pull request #3480 from nabinhait/develop
Indexes
2015-06-16 16:49:26 +05:30
Nabin Hait
81dca110eb Change log added 2015-06-16 16:48:47 +05:30
Nabin Hait
9c852108d0 Added index in sales/purchase invoice and fix in index patch 2015-06-16 16:48:47 +05:30
Nabin Hait
e3ac032696 Merge pull request #3472 from neilLasrado/po
Multiple Fixes
2015-06-16 15:52:48 +05:30
Neil Trini Lasrado
64cacfb077 Fixes in Activity Cost 2015-06-16 15:42:40 +05:30
Neil Trini Lasrado
ae4cc078ea Activity Cost - Mandatory removed for Employee. 2015-06-16 15:30:08 +05:30
Nabin Hait
0ee543e932 Merge pull request #3479 from nabinhait/develop
[fix][report] Payment period based on invoice date
2015-06-16 15:29:14 +05:30
Nabin Hait
a123638d37 [fix][report] Payment period based on invoice date 2015-06-16 15:21:00 +05:30
Nabin Hait
58996985ed Merge pull request #3476 from nabinhait/develop
Expense Approver Query and discount label
2015-06-16 15:01:08 +05:30
Nabin Hait
5d0ce7939f Show only users with Expense Approver role in Expense Claim Approver field 2015-06-15 17:59:37 +05:30
Neil Trini Lasrado
4abf552d7b Over Production Allowance Percentage Setting added to Manufacturing Settings 2015-06-15 15:58:45 +05:30
Nabin Hait
7c5ba957ac Label changed for discount amount in base currency 2015-06-15 15:47:07 +05:30
Nabin Hait
77f04e293a Merge branch 'develop' 2015-06-15 10:35:39 +05:30
Nabin Hait
d1d3237784 bumped to version 5.0.24 2015-06-15 11:05:39 +06:00
Nabin Hait
76f0d26f1e Merge pull request #3471 from nabinhait/develop
Hotfix
2015-06-15 10:32:23 +05:30
Nabin Hait
65922d3079 [fix] supplier invoice date can not be after posting date 2015-06-15 10:23:53 +05:30
Nabin Hait
810041cbe3 [fix] Fixed error due to performance upgrade cleanup 2015-06-15 10:20:11 +05:30
Nabin Hait
b9626659ea Merge pull request #3465 from neilLasrado/po
Po
2015-06-15 10:04:36 +05:30
Nabin Hait
e3d13bee36 Merge pull request #3467 from anandpdoshi/anand-june-12
Fixes
2015-06-15 10:03:20 +05:30
Anand Doshi
63e4d31aa6 [fix] Task should be mandatory in Time Log only when Project is mentioned but Production Order is not 2015-06-12 18:59:18 -04:00
Anand Doshi
f2a0161709 [fix] Don't create Time Logs against Production Order if Workstation is not specified in Operations 2015-06-12 18:58:36 -04:00
Neil Trini Lasrado
3c1a4a0b9b percent_complete made no-copy in Project 2015-06-12 18:34:08 +05:30
Neil Trini Lasrado
82cc2921d1 Validation added to prevent user from creating salary structure with 'From Date' before employee 'Date of joining' 2015-06-12 18:34:08 +05:30
26 changed files with 1010 additions and 939 deletions

View File

@@ -1,2 +1,2 @@
from __future__ import unicode_literals
__version__ = '5.0.23'
__version__ = '5.0.25'

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe
from frappe.utils import cint, formatdate, flt
from frappe.utils import cint, formatdate, flt, getdate
from frappe import msgprint, _, throw
from erpnext.setup.utils import get_company_currency
import frappe.defaults
@@ -389,7 +389,7 @@ class PurchaseInvoice(BuyingController):
def validate_supplier_invoice(self):
if self.bill_date:
if self.bill_date > self.posting_date:
if getdate(self.bill_date) > getdate(self.posting_date):
frappe.throw("Supplier Invoice Date cannot be greater than Posting Date")
if self.bill_no:
if cint(frappe.db.get_single_value("Accounts Settings", "check_supplier_invoice_uniqueness")):

View File

@@ -38,7 +38,8 @@
"options": "Customer",
"permlevel": 0,
"print_hide": 1,
"read_only": 0
"read_only": 0,
"search_index": 1
},
{
"depends_on": "customer",
@@ -502,7 +503,7 @@
{
"fieldname": "base_discount_amount",
"fieldtype": "Currency",
"label": "Discount Amount (Company Currency)",
"label": "Additional Discount Amount (Company Currency)",
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
@@ -880,7 +881,7 @@
"options": "Project",
"permlevel": 0,
"read_only": 0,
"search_index": 1
"search_index": 0
},
{
"depends_on": "eval:doc.source == 'Campaign'",
@@ -1243,7 +1244,7 @@
"icon": "icon-file-text",
"idx": 1,
"is_submittable": 1,
"modified": "2015-05-27 02:48:02.897865",
"modified": "2015-06-16 16:45:06.618286",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",

View File

@@ -65,8 +65,7 @@ class SalesInvoice(SellingController):
self.set_against_income_account()
self.validate_c_form()
self.validate_time_logs_are_submitted()
self.validate_multiple_billing("Delivery Note", "dn_detail", "amount",
"items")
self.validate_multiple_billing("Delivery Note", "dn_detail", "amount", "items")
def on_submit(self):
super(SalesInvoice, self).on_submit()

View File

@@ -171,7 +171,7 @@ class ReceivablePayableReport(object):
def get_gl_entries(self, party_type):
if not hasattr(self, "gl_entries"):
conditions, values = self.prepare_conditions(party_type)
self.gl_entries = frappe.db.sql("""select posting_date, account, party_type, party, debit, credit,
self.gl_entries = frappe.db.sql("""select name, posting_date, account, party_type, party, debit, credit,
voucher_type, voucher_no, against_voucher_type, against_voucher from `tabGL Entry`
where docstatus < 2 and party_type=%s {0} order by posting_date, party"""
.format(conditions), values, as_dict=True)

View File

@@ -9,8 +9,9 @@ from frappe.utils import flt
def execute(filters=None):
if not filters: filters = {}
columns = get_columns()
validate_filters(filters)
columns = get_columns(filters)
entries = get_entries(filters)
invoice_posting_date_map = get_invoice_posting_date_map(filters)
against_date = ""
@@ -36,11 +37,18 @@ def execute(filters=None):
data.append(row)
return columns, data
def validate_filters(filters):
if (filters.get("payment_type") == "Incoming" and filters.get("party_type") == "Supplier") or \
(filters.get("payment_type") == "Outgoing" and filters.get("party_type") == "Customer"):
frappe.throw(_("{0} payment entries can not be filtered by {1}")\
.format(filters.payment_type, filters.party_type))
def get_columns():
def get_columns(filters):
return [_("Journal Entry") + ":Link/Journal Entry:140",
_("Party Type") + ":Link/DocType:100", _("Party") + ":Dynamic Link/party_type:140",
_("Posting Date") + ":Date:100", _("Against Invoice") + ":Link/Purchase Invoice:130",
_("Party Type") + ":Link/DocType:100", _("Party") + ":Dynamic Link/Party Type:140",
_("Posting Date") + ":Date:100",
_("Against Invoice") + (":Link/Purchase Invoice:130" if filters.get("payment_type") == "Outgoing" else ":Link/Sales Invoice:130"),
_("Against Invoice Posting Date") + ":Date:130", _("Debit") + ":Currency:120", _("Credit") + ":Currency:120",
_("Reference No") + "::100", _("Reference Date") + ":Date:100", _("Remarks") + "::150", _("Age") +":Int:40",
"0-30:Currency:100", "30-60:Currency:100", "60-90:Currency:100", _("90-Above") + ":Currency:100"

View File

@@ -457,7 +457,7 @@
{
"fieldname": "base_discount_amount",
"fieldtype": "Currency",
"label": "Discount Amount (Company Currency)",
"label": "Additional Discount Amount (Company Currency)",
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
@@ -873,7 +873,7 @@
"icon": "icon-file-text",
"idx": 1,
"is_submittable": 1,
"modified": "2015-06-02 17:15:44.711032",
"modified": "2015-06-15 15:38:56.794601",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order",

View File

@@ -439,7 +439,7 @@
{
"fieldname": "base_discount_amount",
"fieldtype": "Currency",
"label": "Discount Amount (Company Currency)",
"label": "Additional Discount Amount (Company Currency)",
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
@@ -660,7 +660,7 @@
"icon": "icon-shopping-cart",
"idx": 1,
"is_submittable": 1,
"modified": "2015-06-02 17:15:57.283516",
"modified": "2015-06-15 15:39:08.954248",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier Quotation",

View File

@@ -0,0 +1,17 @@
- Performance upgrade in Trial Balance, General Ledger, AR/AP, Balance Sheet and P&L Statement reports
- Add index on Account and GL Entry, Sales Invoice and Purchase Invoice table
- Don't create Time Logs against Production Order if Workstation is not specified in Operations
- Task should be mandatory in Time Log only when Project is mentioned but Production Order is not
- Supplier invoice no unique validation and supplier invoice date can not be after posting date
- Removed BOM No from mandatory from Stock Entry against Production Order
- Load tasks in project for printing purpose
- Added Customers Not Buying Since Long Time against Sales Invoice
- POS - search by Item Group
- Payment period based on invoice date: show party columns and filter based on party
- Barcode added to Purchase Receipt
- Fetch item name and desc on change of item code in Quality Inspection
- Show item name in item grid view based 'In List View' property
- Validate and update manufactured qty in Stock Entry
- Show only users with Expense Approver role in Expense Claim Approver field
- Over Production Allowance Percentage Setting added to Manufacturing Settings
- Activity Cost - Mandatory removed for Employee

View File

@@ -5,7 +5,7 @@ app_publisher = "Frappe Technologies Pvt. Ltd. and Contributors"
app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
app_icon = "icon-th"
app_color = "#e74c3c"
app_version = "5.0.23"
app_version = "5.0.25"
error_report_email = "support@erpnext.com"

View File

@@ -63,7 +63,7 @@ cur_frm.cscript.onload = function(doc,cdt,cdn) {
cur_frm.set_query("exp_approver", function() {
return {
filters: [["UserRole", "role", "=", "Expense Approver"]]
query: "erpnext.hr.doctype.expense_claim.expense_claim.get_expense_approver"
};
});
}

View File

@@ -58,4 +58,13 @@ class ExpenseClaim(Document):
def validate_sanctioned_amount(self):
for d in self.get('expenses'):
if flt(d.sanctioned_amount) > flt(d.claim_amount):
frappe.throw(_("Sanctioned Amount cannot be greater than Claim Amount in Row {0}.").format(d.idx))
frappe.throw(_("Sanctioned Amount cannot be greater than Claim Amount in Row {0}.").format(d.idx))
@frappe.whitelist()
def get_expense_approver(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql("""
select u.name, concat(u.first_name, ' ', u.last_name)
from tabUser u, tabUserRole r
where u.name = r.parent and r.role = 'Expense Approver' and u.name like %s
""", ("%" + txt + "%"))

View File

@@ -4,7 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe.utils import cstr, flt
from frappe.utils import cstr, flt, getdate
from frappe.model.naming import make_autoname
from frappe import _
from frappe.model.mapper import get_mapped_doc
@@ -14,6 +14,13 @@ from erpnext.hr.utils import set_employee_name
class SalaryStructure(Document):
def autoname(self):
self.name = make_autoname(self.employee + '/.SST' + '/.#####')
def validate(self):
self.check_existing()
self.validate_amount()
self.validate_employee()
self.validate_joining_date()
set_employee_name(self)
def get_employee_details(self):
ret = {}
@@ -77,14 +84,11 @@ class SalaryStructure(Document):
old_employee = frappe.db.get_value("Salary Structure", self.name, "employee")
if old_employee and self.employee != old_employee:
frappe.throw(_("Employee can not be changed"))
def validate(self):
self.check_existing()
self.validate_amount()
self.validate_employee()
set_employee_name(self)
def validate_joining_date(self):
joining_date = getdate(frappe.db.get_value("Employee", self.employee, "date_of_joining"))
if getdate(self.from_date) < joining_date:
frappe.throw(_("From Date in Salary Structure cannot be lesser than Employee Joining Date."))
@frappe.whitelist()
def make_salary_slip(source_name, target_doc=None):

View File

@@ -55,6 +55,13 @@
"label": "Time Between Operations (in mins)",
"permlevel": 0,
"precision": ""
},
{
"fieldname": "over_production_allowance_percentage",
"fieldtype": "Percent",
"label": "Over Production Allowance Percentage",
"permlevel": 0,
"precision": ""
}
],
"hide_heading": 0,
@@ -65,7 +72,7 @@
"is_submittable": 0,
"issingle": 1,
"istable": 0,
"modified": "2015-04-21 07:57:40.260862",
"modified": "2015-06-15 05:52:22.986958",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "Manufacturing Settings",

View File

@@ -90,8 +90,9 @@ class ProductionOrder(Document):
(self.sales_order, self.production_item))[0][0]
# total qty in SO
so_qty = flt(so_item_qty) + flt(dnpi_qty)
if total_qty > so_qty:
allowance_percentage = flt(frappe.db.get_single_value("Manufacturing Settings", "over_production_allowance_percentage"))
if total_qty > so_qty + (allowance_percentage/100 * so_qty):
frappe.throw(_("Cannot produce more Item {0} than Sales Order quantity {1}").format(self.production_item,
so_qty), OverProductionError)
@@ -217,12 +218,14 @@ class ProductionOrder(Document):
for i, d in enumerate(self.operations):
self.set_operation_start_end_time(i, d)
if not d.workstation:
continue
time_log = make_time_log(self.name, d.operation, d.planned_start_time, d.planned_end_time,
flt(self.qty) - flt(d.completed_qty), self.project_name, d.workstation, operation_id=d.name)
if d.workstation:
# validate operating hours if workstation [not mandatory] is specified
self.check_operation_fits_in_working_hours(d)
# validate operating hours if workstation [not mandatory] is specified
self.check_operation_fits_in_working_hours(d)
original_start_time = time_log.from_time
while True:

View File

@@ -5,18 +5,26 @@ import frappe
def execute():
index_map = {
"Account": ["parent_account", "lft", "rgt"],
"GL Entry": ["posting_date", "account", 'party', "voucher_no"]
"GL Entry": ["posting_date", "account", 'party', "voucher_no"],
"Sales Invoice": ["posting_date", "debit_to", "customer"],
"Purchase Invoice": ["posting_date", "credit_to", "supplier"]
}
for dt, indexes in index_map.items():
existing_indexes = [d.Key_name for d in frappe.db.sql("""show index from `tab{0}`
existing_indexes = [(d.Key_name, d.Column_name) for d in frappe.db.sql("""show index from `tab{0}`
where Column_name != 'name'""".format(dt), as_dict=1)]
for old in existing_indexes:
if old in ("parent", "group_or_ledger", "is_pl_account", "debit_or_credit", "account_name", "company"):
for old, column in existing_indexes:
if column in ("parent", "group_or_ledger", "is_group", "is_pl_account", "debit_or_credit",
"account_name", "company", "project_name", "voucher_date", "due_date", "bill_no",
"bill_date", "is_opening", "fiscal_year", "outstanding_amount"):
frappe.db.sql("alter table `tab{0}` drop index {1}".format(dt, old))
existing_indexes.remove(old)
existing_indexes = [(d.Key_name, d.Column_name) for d in frappe.db.sql("""show index from `tab{0}`
where Column_name != 'name'""".format(dt), as_dict=1)]
existing_indexed_columns = list(set([x[1] for x in existing_indexes]))
for new in indexes:
if new not in existing_indexes:
if new not in existing_indexed_columns:
frappe.db.sql("alter table `tab{0}` add index ({1})".format(dt, new))

View File

@@ -9,41 +9,6 @@
"doctype": "DocType",
"document_type": "Master",
"fields": [
{
"allow_on_submit": 0,
"fieldname": "employee",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Employee",
"no_copy": 0,
"options": "Employee",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0
},
{
"fieldname": "employee_name",
"fieldtype": "Data",
"label": "Employee Name",
"options": "",
"permlevel": 0,
"precision": "",
"read_only": 1
},
{
"fieldname": "column_break_2",
"fieldtype": "Column Break",
"permlevel": 0,
"precision": ""
},
{
"allow_on_submit": 0,
"fieldname": "activity_type",
@@ -64,6 +29,41 @@
"search_index": 0,
"set_only_once": 0
},
{
"fieldname": "column_break_2",
"fieldtype": "Column Break",
"permlevel": 0,
"precision": ""
},
{
"allow_on_submit": 0,
"fieldname": "employee",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"in_filter": 0,
"in_list_view": 0,
"label": "Employee",
"no_copy": 0,
"options": "Employee",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"read_only": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0
},
{
"fieldname": "employee_name",
"fieldtype": "Data",
"label": "Employee Name",
"options": "",
"permlevel": 0,
"precision": "",
"read_only": 1
},
{
"fieldname": "section_break_4",
"fieldtype": "Section Break",
@@ -136,7 +136,7 @@
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"modified": "2015-06-11 06:50:47.999788",
"modified": "2015-06-16 03:12:25.644839",
"modified_by": "Administrator",
"module": "Projects",
"name": "Activity Cost",

View File

@@ -15,12 +15,21 @@ class ActivityCost(Document):
self.check_unique()
def set_title(self):
if not self.employee_name:
self.employee_name = frappe.db.get_value("Employee", self.employee, "employee_name")
self.title = _("{0} for {1}").format(self.employee_name, self.activity_type)
if self.employee:
if not self.employee_name:
self.employee_name = frappe.db.get_value("Employee", self.employee, "employee_name")
self.title = _("{0} for {1}").format(self.employee_name, self.activity_type)
else:
self.title = self.activity_type
def check_unique(self):
if frappe.db.sql("""select name from `tabActivity Cost` where employee_name= %s and activity_type= %s and name != %s""",
(self.employee_name, self.activity_type, self.name)):
frappe.throw(_("Activity Cost exists for Employee {0} against Activity Type - {1}")
.format(self.employee, self.activity_type), DuplicationError)
if self.employee:
if frappe.db.sql("""select name from `tabActivity Cost` where employee_name= %s and activity_type= %s and name != %s""",
(self.employee_name, self.activity_type, self.name)):
frappe.throw(_("Activity Cost exists for Employee {0} against Activity Type - {1}")
.format(self.employee, self.activity_type), DuplicationError)
else:
if frappe.db.sql("""select name from `tabActivity Cost` where ifnull(employee, '')='' and activity_type= %s and name != %s""",
(self.activity_type, self.name)):
frappe.throw(_("Default Activity Cost exists for Activity Type - {0}")
.format(self.activity_type), DuplicationError)

View File

@@ -163,6 +163,7 @@
"fieldtype": "Percent",
"in_list_view": 0,
"label": "% Tasks Completed",
"no_copy": 1,
"permlevel": 0,
"read_only": 1
},
@@ -356,7 +357,7 @@
"icon": "icon-puzzle-piece",
"idx": 1,
"max_attachments": 4,
"modified": "2015-04-27 07:37:44.239930",
"modified": "2015-06-12 09:00:54.080220",
"modified_by": "Administrator",
"module": "Projects",
"name": "Project",

View File

@@ -128,7 +128,7 @@ class TimeLog(Document):
def update_production_order(self):
"""Updates `start_date`, `end_date`, `status` for operation in Production Order."""
if self.production_order and self.for_manufacturing:
if not self.operation_id:
frappe.throw(_("Operation ID not set"))
@@ -208,22 +208,23 @@ class TimeLog(Document):
self.production_order = None
self.operation = None
self.quantity = None
def update_cost(self):
rate = get_activity_cost(self.employee, self.activity_type)
if rate:
self.costing_rate = rate.get('costing_rate')
self.billing_rate = rate.get('billing_rate')
self.billing_rate = rate.get('billing_rate')
self.costing_amount = self.costing_rate * self.hours
if self.billable:
self.billing_amount = self.billing_rate * self.hours
else:
self.billing_amount = 0
def validate_task(self):
if self.project and not self.task:
# if a time log is being created against a project without production order
if (self.project and not self.production_order) and not self.task:
frappe.throw(_("Task is Mandatory if Time Log is against a project"))
def update_task(self):
if self.task and frappe.db.exists("Task", self.task):
task = frappe.get_doc("Task", self.task)
@@ -266,9 +267,12 @@ def get_events(start, end, filters=None):
d.title += " for Project: " + d.project
return data
@frappe.whitelist()
def get_activity_cost(employee=None, activity_type=None):
rate = frappe.db.sql("""select costing_rate, billing_rate from `tabActivity Cost` where employee= %s
and activity_type= %s""", (employee, activity_type), as_dict=1)
if not rate:
rate = frappe.db.sql("""select costing_rate, billing_rate from `tabActivity Cost` where ifnull(employee, '')=''
and activity_type= %s""", (activity_type), as_dict=1)
return rate[0] if rate else {}

View File

@@ -488,7 +488,7 @@
{
"fieldname": "base_discount_amount",
"fieldtype": "Currency",
"label": "Discount Amount (Company Currency)",
"label": "Additional Discount Amount (Company Currency)",
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
@@ -858,7 +858,7 @@
"idx": 1,
"is_submittable": 1,
"max_attachments": 1,
"modified": "2015-05-27 02:48:00.388847",
"modified": "2015-06-15 15:37:39.199814",
"modified_by": "Administrator",
"module": "Selling",
"name": "Quotation",

View File

@@ -493,7 +493,7 @@
{
"fieldname": "base_discount_amount",
"fieldtype": "Currency",
"label": "Discount Amount (Company Currency)",
"label": "Additional Discount Amount (Company Currency)",
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
@@ -1080,7 +1080,7 @@
"idx": 1,
"is_submittable": 1,
"issingle": 0,
"modified": "2015-05-27 02:48:01.160307",
"modified": "2015-06-15 15:36:38.898462",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Order",

View File

@@ -517,7 +517,7 @@
{
"fieldname": "base_discount_amount",
"fieldtype": "Currency",
"label": "Discount Amount (Company Currency)",
"label": "Additional Discount Amount (Company Currency)",
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
@@ -1070,7 +1070,7 @@
"idx": 1,
"in_create": 0,
"is_submittable": 1,
"modified": "2015-05-27 02:47:59.778147",
"modified": "2015-06-15 15:37:54.699371",
"modified_by": "Administrator",
"module": "Stock",
"name": "Delivery Note",

View File

@@ -443,7 +443,7 @@
{
"fieldname": "base_discount_amount",
"fieldtype": "Currency",
"label": "Discount Amount (Company Currency)",
"label": "Additional Discount Amount (Company Currency)",
"options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
@@ -854,7 +854,7 @@
"icon": "icon-truck",
"idx": 1,
"is_submittable": 1,
"modified": "2015-05-27 02:48:00.763945",
"modified": "2015-06-15 15:38:43.754869",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Receipt",

View File

@@ -1,6 +1,6 @@
from setuptools import setup, find_packages
version = "5.0.23"
version = "5.0.25"
with open("requirements.txt", "r") as f:
install_requires = f.readlines()