Created
March 7, 2016 13:52
-
-
Save sbkolate/ec10b0f1040bad1fabe5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import unicode_literals | |
import frappe | |
from frappe.widgets.reportview import get_match_cond | |
from frappe.utils import add_days, cint, cstr, date_diff, rounded, flt, getdate, nowdate, \ | |
get_first_day, get_last_day,money_in_words, now, nowtime | |
#from frappe.utils import add_days, cint, cstr, flt, getdate, nowdate, rounded | |
from frappe import _ | |
from frappe.model.db_query import DatabaseQuery | |
from requests_oauthlib import OAuth1 as OAuth | |
from datetime import datetime | |
from time import sleep | |
import requests | |
import json | |
import datetime | |
import time | |
import itertools | |
# On submission of sales order--------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
def create_purchase_order(doc,method): | |
check_duplicate_item_code(doc) | |
check_ispurchase_item(doc,method) | |
return "Done" | |
def check_duplicate_item_code(doc): | |
duplicate_item = [] | |
s = [duplicate_item.append(d.item_code) for d in doc.get('sales_order_details')] | |
for item_code in duplicate_item: | |
if duplicate_item.count(item_code) > 1: | |
frappe.throw(_("Item code {0} is added twise, merge the qty against same Item Code").format(item_code)) | |
def check_ispurchase_item(doc,method): | |
for d in doc.get('sales_order_details'): | |
if frappe.db.get_value("Item",{'is_purchase_item':'Yes','name':d.item_code},'name'): | |
supplier_validate(d.item_code) | |
if frappe.db.get_value("Item",{'is_stock_item':'Yes','name':d.item_code},'name'): | |
Stock_Availability(doc,d) | |
assign_extra_qty_to_other(d) | |
else: | |
bin_details = frappe.db.sql(''' select ifnull(sum(soi.qty), 0) - ifnull(sum(soi.delivered_qty), 0) from | |
`tabSales Order Item` soi, `tabSales Order` so where soi.parent = so.name | |
and ifnull(soi.stop_status, "No") <> "Yes" and so.status <> "Stopped" and soi.docstatus = 1 | |
and soi.item_code ="%s" and soi.warehouse = "%s" '''%(d.item_code, d.warehouse), as_list=1) | |
so_qty = flt(bin_details[0][0]) if bin_details else 0.0 | |
po_qty = get_po_qty(d.item_code, d.warehouse) - so_qty # if negative then make po | |
if po_qty < 0: | |
create_purchase_order_record(doc,d, flt(po_qty*-1)) | |
def Stock_Availability(so_doc, child_args): | |
bin_details = frappe.db.get_value('Bin', {'item_code': child_args.item_code, 'warehouse': child_args.warehouse}, '*', as_dict=1) | |
if bin_details: | |
assign_qty = get_assigned_qty(child_args.item_code, child_args.warehouse) #get assigned qty | |
bin_qty = flt(bin_details.actual_qty) - flt(assign_qty) # To calculate the available qty | |
if flt(bin_qty) > 0.0 and flt(bin_qty) >= flt(child_args.qty): | |
sal = create_stock_assignment_document(child_args, so_doc.name, child_args.qty) | |
# Stock in Hand | |
make_history_of_assignment(sal, so_doc.transaction_date, "Stock In Hand", "", child_args.qty) | |
child_args.assigned_qty = child_args.qty | |
else: | |
assigned_qty = bin_qty | |
po_qty = (flt(child_args.qty) - flt(assigned_qty)) if flt(assigned_qty) > 0.0 else flt(child_args.qty) | |
if flt(assigned_qty) > 0.0: | |
sal = create_stock_assignment_document(child_args, so_doc.name, assigned_qty) | |
# Stock in Hand | |
make_history_of_assignment(sal, so_doc.transaction_date, "Stock In Hand", "", assigned_qty) | |
child_args.assigned_qty = assigned_qty | |
if flt(po_qty) > 0.0: | |
new_po_qty = get_po_qty(child_args.item_code, child_args.warehouse) + flt(bin_details.actual_qty) - flt(bin_details.reserved_qty) # if negative then make po | |
if new_po_qty < 0: | |
create_purchase_order_record(so_doc, child_args, flt(new_po_qty * -1)) | |
def get_assigned_qty(item_code, warehouse): | |
assign_qty = frappe.db.sql(''' select sum(ifnull(assigned_qty,0)) - sum(ifnull(delivered_qty,0)) from `tabSales Order Item` where item_code = "%s" | |
and warehouse ="%s" and docstatus=1 and ifnull(qty,0) >= ifnull(assigned_qty,0)'''%(item_code, warehouse), as_list = 1) | |
if assign_qty: | |
return assign_qty[0][0] or 0.0 | |
return 0.0 | |
def assign_extra_qty_to_other(data): | |
assign_qty = get_assigned_qty(data.item_code, data.warehouse) | |
bin_details = frappe.db.get_value('Bin', {'item_code': data.item_code, 'warehouse': data.warehouse}, '*', as_dict=1) | |
qty = flt(bin_details.actual_qty) - flt(assign_qty) | |
if cint(qty) > 0: | |
sales_order = get_item_SODetails(data.item_code) | |
if sales_order: | |
create_StockAssignment_AgainstSTopSOItem(data, sales_order, qty) | |
def get_po_qty(item_code, warehouse=None): | |
cond = 'poi.warehouse ="%s"'%(warehouse) if warehouse else '1=1' | |
qty = frappe.db.sql(''' select sum(ifnull(poi.qty,0)-ifnull(poi.received_qty,0)) from `tabPurchase Order Item` poi, `tabPurchase Order` po | |
where poi.parent = po.name and po.status <> 'Stopped' and poi.docstatus <> 2 and poi.item_code = "%s" and %s'''%(item_code, cond), as_list=1) | |
qty = flt(qty[0][0]) if qty else 0.0 | |
return qty | |
def supplier_validate(item_code): | |
if not frappe.db.get_value('Item', item_code, 'default_supplier'): | |
frappe.throw(_("Default supplier is not defined against the item code {0}").format(item_code)) | |
def create_purchase_order_record(doc,d,qty): | |
supplier=frappe.db.sql('''select default_supplier from `tabItem` where | |
name="%s"'''%d.item_code,as_list=1) | |
if supplier: | |
purchase_order=frappe.db.sql('''select name from `tabPurchase Order` where supplier="%s" | |
and docstatus=0'''%supplier[0][0],as_list=1) | |
if purchase_order: | |
purchase_order_item=frappe.db.sql('''select item_code from `tabPurchase Order Item` | |
where parent="%s" and item_code="%s"''' | |
%(purchase_order[0][0],d.item_code),as_list=1) | |
if purchase_order_item: | |
for item in purchase_order_item: | |
if item[0]==d.item_code: | |
purchase_order_qty=frappe.db.sql('''select qty,rate from `tabPurchase Order Item` | |
where parent="%s" and item_code="%s"''' | |
%(purchase_order[0][0],d.item_code),as_list=1) | |
qty_new= qty + flt(purchase_order_qty[0][0]) | |
update_qty(doc,d,item[0],purchase_order[0][0],qty_new,purchase_order_qty[0][1]) | |
else: | |
child_entry=update_child_entry(doc,d,purchase_order[0][0],qty) | |
else: | |
child_entry=update_child_entry(doc,d,purchase_order[0][0],qty) | |
purchase_order = purchase_order[0][0] | |
else: | |
purchase_order = create_new_po(doc,d,supplier[0][0],qty) | |
if purchase_order: | |
qty = qty if flt(qty) < flt(d.qty) else flt(d.qty) | |
frappe.db.sql(''' update `tabSales Order Item` set po_data = "%s", po_qty="%s" where name = "%s" '''%(purchase_order, qty, d.name)) | |
else: | |
frappe.throw("Supplier must be specify for items in Item Master Form.") | |
def create_stock_assignment_document(args, sales_order, assigned_qty): | |
sa = frappe.new_doc('Stock Assignment Log') | |
sa.item_name = args.item_name | |
sa.sales_order = sales_order | |
sa.ordered_qty = frappe.db.get_value('Sales Order Item', {'item_code': args.item_code, 'parent': sales_order}, 'qty') | |
sa.assign_qty = assigned_qty | |
sa.purchase_receipt_no = args.parent if args.doctype == 'Purchase Receipt Item' else '' | |
sa.item_code = args.item_code | |
sa.media = frappe.db.get_value("Item",args.item_code,'item_group') | |
sa.customer_name = frappe.db.get_value('Sales Order',sa.sales_order,'customer_name') | |
# # creating Document Stock Assignment entry | |
# bin_details = frappe.db.get_value('Bin', {'item_code': child_args.item_code, 'warehouse': child_args.warehouse}, '*', as_dict=1) | |
# if bin_details: | |
# bin_qty = flt(bin_details.actual_qty) - flt(bin_details.reserved_qty) | |
# if flt(bin_qty) > 0.0 and flt(bin_details.actual_qty) >= flt(child_args.qty): | |
# # make_history_of_assignment | |
# sal_child = sa.append('document_stock_assignment', {}) | |
# sal_child.created_date = frappe.get_value("Sales Order",sales_order,"transcation_date") | |
# sal_child.document_type = "Stock In Hand" | |
# sal_child.document_no = "" | |
# sal_child.qty = assigned_qty | |
sa.save(ignore_permissions=True) | |
return sa.name | |
# def delete_stock_assignment(doc, method): | |
# stl = frappe.db.sql(""" select name from `tabStock Assignment Log` where sales_order = '%s'"""%(doc.name), as_dict=1) | |
# if stl: | |
# for data in stl: | |
# delete_stl(data.name) | |
# # reduce_po(doc) | |
# reduce_po(doc) | |
# update_stock_assigned_qty_to_zero(doc) | |
def delete_stock_assignment(doc, method): | |
st_error=stop_error(doc) | |
if(st_error=='true'): | |
frappe.throw(_("You can not cancel this sales order")) | |
else: | |
stl = frappe.db.sql(""" select * from `tabStock Assignment Log` where sales_order = '%s'"""%(doc.name), as_dict=1) | |
if stl: | |
for data in stl: | |
delete_stl(data) | |
reduce_po(doc) | |
update_stock_assigned_qty_to_zero(doc) | |
def stop_error(doc): | |
st_error='' | |
for data in doc.get('sales_order_details'): | |
if(data.stop_status=="Yes"): | |
st_error='true' | |
break | |
return st_error | |
def delete_stl(args): | |
frappe.db.sql(''' delete from `tabDocument Stock Assignment` where parent="%s" '''%(args.name)) | |
frappe.db.sql(''' delete from `tabStock Assignment Log` where name="%s" '''%(args.name)) | |
def update_stock_assigned_qty_to_zero(doc): | |
for data in doc.get('sales_order_details'): | |
frappe.db.sql(''' update `tabSales Order Item` set po_data = (select true from dual where 1=2), po_qty=0.0, assigned_qty=0.0 where name = "%s" '''%(data.name)) | |
data.assigned_qty = 0.0 | |
data.po_data = '' | |
data.po_qty = 0.0 | |
def reduce_po(doc): | |
for data in doc.get('sales_order_details'): | |
if data.po_data: | |
po_details = frappe.db.get_value('Purchase Order Item', {'parent': data.po_data, 'item_code': data.item_code, 'docstatus': 0}, '*', as_dict=1) | |
update_child_table(po_details, data) | |
update_parent_table(po_details) | |
def update_child_table(po_details, data): | |
if po_details: | |
po_qty = flt(data.po_qty) or flt(data.qty) | |
qty = flt(po_details.qty) - po_qty | |
if flt(qty) >= 1.0: | |
frappe.db.sql(""" update `tabPurchase Order Item` set qty = '%s' where name ='%s'"""%(qty, po_details.name)) | |
elif flt(qty)==0.0: | |
delete_document('Purchase Order Item', po_details.name) | |
def update_parent_table(po_details): | |
if po_details: | |
count = frappe.db.sql(''' select ifnull(count(*),0) from `tabPurchase Order Item` where parent = "%s" '''%(po_details.parent), as_list=1) | |
if count: | |
if count[0][0] == 0: | |
obj = frappe.get_doc('Purchase Order', po_details.parent) | |
obj.delete() | |
# On submission of Purchase Receipt-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
def stock_assignment(doc,method): | |
for pr_details in doc.get('purchase_receipt_details'): | |
if frappe.db.get_value("Item",{'is_stock_item':'Yes','name':pr_details.item_code},'name'): | |
qty = flt(pr_details.qty) | |
sales_order = get_SODetails(pr_details.item_code) | |
if sales_order: | |
check_stock_assignment(qty, sales_order, pr_details) | |
# So list which has stock not assign or partially assign | |
def get_SODetails(item_code): | |
return frappe.db.sql('''select s.parent as parent,ifnull(s.qty,0)-ifnull(s.assigned_qty,0) AS qty, | |
s.assigned_qty as assigned_qty from `tabSales Order Item` s inner join `tabSales Order` so | |
on s.parent=so.name where s.item_code="%s" and so.docstatus=1 and ifnull(s.stop_status, 'No') <> 'Yes' and | |
ifnull(s.qty,0)>ifnull(s.assigned_qty,0) and so.status!='Stopped' order by so.priority,so.creation'''%(item_code),as_dict=1) | |
def check_stock_assignment(qty, sales_order, pr_details): | |
for so_details in sales_order: | |
if flt(qty) > 0.0 and flt(so_details.qty)>0: | |
stock_assigned_qty = so_details.qty if flt(qty) >= flt(so_details.qty) else flt(qty) | |
qty = (flt(qty) - flt(so_details.qty)) if flt(qty) >= flt(so_details.qty) else 0.0 | |
create_stock_assignment(stock_assigned_qty , so_details, pr_details) | |
def create_stock_assignment(stock_assigned_qty, sales_order_data, pr_details): | |
sal = frappe.db.get_value('Stock Assignment Log', {'sales_order': sales_order_data.parent, 'item_code': pr_details.item_code},'*', as_dict=1) | |
stock_assigned_qty = sales_order_data.qty if sales_order_data.qty < stock_assigned_qty else stock_assigned_qty | |
if sal: | |
sal_name = update_stock_assigned_qty(sal, stock_assigned_qty, pr_details) | |
else: | |
sal_name = create_stock_assignment_document(pr_details, sales_order_data.parent, stock_assigned_qty) | |
make_history_of_assignment(sal_name,nowdate(),"Purchase Receipt", pr_details.parent, stock_assigned_qty) | |
def update_stock_assigned_qty(stock_assignment_details, assigned_qty, pr_details): | |
doc_qty = get_document_STOCK_qty(stock_assignment_details.name) | |
if cint(doc_qty) == cint(stock_assignment_details.assign_qty): | |
assign_qty = cint(stock_assignment_details.assign_qty) + cint(assigned_qty) | |
else: | |
assign_qty = cint(doc_qty) + cint(assigned_qty) | |
obj = frappe.get_doc('Stock Assignment Log', stock_assignment_details.name) | |
obj.assign_qty = assign_qty | |
update_doc_SAL(obj, pr_details, assigned_qty) | |
obj.save(ignore_permissions=True) | |
return stock_assignment_details.name | |
def update_doc_SAL(obj, pr_details, assigned_qty): | |
sal = obj.append('document_stock_assignment', {}) | |
sal.document_no = pr_details.parent | |
sal.qty = assigned_qty | |
sal.created_date = nowdate() | |
sal.document_type = 'Purchase Receipt' | |
return True | |
def get_document_STOCK_qty(name): | |
sum_qty = 0.0 | |
qty = frappe.db.sql(''' select ifnull(sum(qty),0) from `tabDocument Stock Assignment` | |
where parent = "%s"'''%(name), as_list=1) | |
if qty: | |
sum_qty = qty[0][0] | |
return sum_qty | |
# def make_history_of_assignment(sal, pr_name, qty): | |
# sal= frappe.get_doc('Stock Assignment Log', sal) | |
# sal_child = sal.append('document_stock_assignment', {}) | |
# sal_child.document_no = pr_name | |
# sal_child.qty = qty | |
# sal.save(ignore_permissions=True) | |
def make_history_of_assignment(sal, date, doc_type, pr_name, qty): | |
sal= frappe.get_doc('Stock Assignment Log', sal) | |
sal_child = sal.append('document_stock_assignment', {}) | |
sal_child.created_date = nowdate(); | |
sal_child.document_type = doc_type | |
sal_child.document_no = pr_name | |
sal_child.qty = qty | |
sal.save(ignore_permissions=True) | |
def stock_cancellation(doc,method): | |
cancel_all_child_table(doc) | |
cancel_parent_table(doc) | |
# check_assigned_qty(doc) | |
def check_assigned_qty(doc): | |
for data in doc.get('purchase_receipt_details'): | |
bin_details = frappe.db.get_value('Bin', {'item_code': data.item_code, 'warehouse': data.warehouse}, '*', as_dict=1) | |
if bin_details: | |
assign_qty = get_assigned_qty(data.item_code, data.warehouse) #get assigned qty | |
actual_qty = flt(bin_details.actual_qty) | |
if flt(assign_qty) > flt(actual_qty): | |
frappe.throw(_("Not allowed to cancel, the available stock of item {0} is assigned to the sales order").format(data.item_code)) | |
def cancel_all_child_table(doc): | |
sal_details = frappe.db.sql(''' select * from `tabDocument Stock Assignment` | |
where document_no = "%s"'''%(doc.name), as_dict=1) | |
if sal_details: | |
for sal in sal_details: | |
obj = frappe.get_doc('Stock Assignment Log', sal.parent) | |
obj.assign_qty = flt(obj.assign_qty) - flt(sal.qty) | |
to_remove_obj = [] | |
for d in obj.get('document_stock_assignment'): | |
if d.name == sal.name: | |
to_remove_obj.append(d) | |
[obj.remove(d) for d in to_remove_obj] | |
obj.save(ignore_permissions=True) | |
def cancel_parent_table(doc): | |
sal_data = frappe.db.sql(''' select * from `tabStock Assignment Log` where assign_qty = 0''', as_dict=1) | |
if sal_data: | |
for data in sal_data: | |
obj = frappe.get_doc('Stock Assignment Log', data.name) | |
obj.delete() | |
# def stock_cancellation(doc,method): | |
# sal_details = frappe.db.sql(''' select * from `tabDocument Stock Assignment` | |
# where document_no = "%s"'''%(doc.name), as_dict=1) | |
# if sal_details: | |
# for sal in sal_details: | |
# obj = frappe.get_doc('Stock Assignment Log', sal.parent) | |
# obj.assign_qty = flt(obj.assign_qty) - flt(sal.qty) | |
# for d in obj.get('document_stock_assignment'): | |
# if d.name == sal.name: | |
# obj.remove(d) | |
# obj.save(ignore_permissions=True) | |
def delete_document(table, name): | |
frappe.db.sql(''' delete from `tab%s` where name = "%s" '''%(table, name)) | |
def update_so_assign_qty(args): | |
so_details = frappe.db.get_value('Sales Order Item', {'parent': args.sales_order, 'item_code': args.item_code}, 'assigned_qty') or 0.0 | |
qty = (flt(so_details) - flt(args.qty)) if flt(so_details) >= flt(args.qty) else 0.0 | |
frappe.db.sql(''' update `tabSales Order Item` set assigned_qty = "%s" where parent = "%s" and | |
item_code = "%s" '''%(qty, args.sales_order, args.item_code)) | |
def create_new_po(doc,d,supplier,qty): | |
po = frappe.new_doc('Purchase Order') | |
po.supplier= supplier | |
po.currency = frappe.db.get_value('Supplier', supplier, 'default_currency') | |
e = po.append('po_details', {}) | |
e.item_code=d.item_code | |
e.item_name=d.item_name | |
e.description=d.description | |
e.qty= qty | |
e.uom=d.stock_uom | |
e.conversion_factor=1 | |
e.rate=d.rate | |
e.amount=d.amount | |
e.base_rate=d.rate | |
e.base_amount=d.amount | |
e.warehouse=d.warehouse | |
e.schedule_date=nowdate() | |
po.save(ignore_permissions=True) | |
return po.name | |
#update_so_details(doc,d,d.item_code,po.name) | |
#update_sales_order(doc,d.item_code,po.name,e.name) | |
def update_child_entry(doc,d,purchase_order,qty): | |
doc1 = frappe.get_doc("Purchase Order", purchase_order) | |
poi = doc1.append('po_details', {}) | |
poi.item_code=d.item_code | |
poi.item_name=d.item_name | |
poi.description=d.description | |
poi.qty=qty | |
poi.uom=d.stock_uom | |
poi.conversion_factor=1 | |
poi.rate=d.rate | |
poi.amount=d.amount | |
poi.base_rate=d.rate | |
poi.base_amount=d.amount | |
poi.warehouse=d.warehouse | |
poi.schedule_date=nowdate() | |
doc1.save(ignore_permissions=True) | |
#update_so_details(doc,d,d.item_code,doc1.name) | |
def update_qty(doc,d,item,purchase_order,qty,rate): | |
amount=rate*qty | |
frappe.db.sql("""update `tabPurchase Order Item` set qty='%s', amount='%s' | |
where parent='%s' and item_code='%s'""" | |
%(qty,amount,purchase_order,item)) | |
#update_so_details(doc,d,item,purchase_order) | |
def update_so_details(doc,d,item,purchase_order): | |
doc2 = frappe.get_doc("Purchase Order", purchase_order) | |
so = doc2.append('so_item_detail', {}) | |
so.item_code=item | |
so.qty=d.qty | |
so.sales_order_name=doc.name | |
doc2.save(ignore_permissions=True) | |
# On sibmission of delivery Note--------------------------------------------------------------------------------------------------------------------------------- | |
def update_stock_assignment_log_on_submit(doc,method): | |
for d in doc.get('delivery_note_details'): | |
sales_order_name=frappe.db.sql("""select s.against_sales_order from | |
`tabDelivery Note Item` s inner join `tabDelivery Note` so | |
on s.parent=so.name where s.item_code='%s' | |
and so.docstatus=1 and s.parent='%s' | |
order by so.creation""" | |
%(d.item_code,doc.name),as_list=1) | |
if sales_order_name: | |
delivery_note_name=frappe.db.sql(""" select delivery_note from `tabStock Assignment Log` where | |
sales_order='%s' and item_code='%s' and delivery_note is not null"""%(sales_order_name[0][0],d.item_code)) | |
if not delivery_note_name: | |
frappe.db.sql("""update `tabStock Assignment Log` | |
set delivered_qty='%s', delivery_note='%s' | |
where sales_order='%s' and item_code='%s'""" | |
%(d.qty,doc.name,sales_order_name[0][0],d.item_code)) | |
else: | |
# delivery_note = delivery_note_name[0][0] + ', ' + doc.name | |
delivery_note = doc.name | |
delivery_note_details=frappe.db.sql("""select delivered_qty from `tabStock Assignment Log` | |
where sales_order='%s' and item_code='%s'"""%(sales_order_name[0][0],d.item_code)) | |
if delivery_note_details: | |
qty=cint(delivery_note_details[0][0])+d.qty | |
frappe.db.sql("""update `tabStock Assignment Log` | |
set delivered_qty='%s', delivery_note='%s' | |
where sales_order='%s' and item_code='%s'""" | |
%(qty,delivery_note,sales_order_name[0][0],d.item_code)) | |
def update_delivery_note(doc,method): | |
for d in doc.get('delivery_note_details'): | |
if(d.stop_status=="Yes"): | |
frappe.throw(_("Item code {0} is stopped please delete it.").format(d.item_code)) | |
def update_sales_invoice(doc,method): | |
for d in doc.get('entries'): | |
if(d.stop_status=="Yes"): | |
frappe.throw(_("Item code {0} is stopped please delete it.").format(d.item_code)) | |
def update_stock_assignment_log_on_cancel(doc,method): | |
update_delivery_note(doc, method) | |
for d in doc.get('delivery_note_details'): | |
name=frappe.db.sql(""" select name,delivered_qty from `tabStock Assignment Log` where | |
sales_order='%s' and item_code='%s'"""%(d.against_sales_order,d.item_code)) | |
if name: | |
delivery_note=frappe.db.sql("""select delivery_note from `tabStock Assignment Log` where | |
name='%s'"""%name[0][0]) | |
delivery_note_name=cstr(delivery_note[0][0]).split(", ") | |
if d.parent in delivery_note_name: | |
delivery_note_name.remove(d.parent) | |
qty=cint(name[0][1])-d.qty | |
if name: | |
frappe.db.sql("""update `tabStock Assignment Log` | |
set delivered_qty='%s',delivery_note='%s' where item_code='%s'"""%(qty,','.join(delivery_note_name),d.item_code)) | |
def validate_qty_on_submit(doc,method): | |
qty_count = 0 | |
for d in doc.get('delivery_note_details'): | |
qty_count += d.qty | |
if not d.assigned_qty>=d.qty: | |
frappe.throw("Delivered Quantity must be less than or equal to assigned_qty for item_code='"+d.item_code+"'") | |
doc.total_qty = qty_count | |
#For calling API through Poster--------------------------------------------------------------------------------------- | |
def check_APItime(): | |
# sync_existing_customers_address() | |
GetMissingItem() | |
time = frappe.db.sql("""select value from `tabSingles` where doctype='API Configuration Page' and field in ('date','api_type')""",as_list=1) | |
if time: | |
dates= list(itertools.chain.from_iterable(time)) | |
api_date = datetime.datetime.strptime(dates[1], '%Y-%m-%d %H:%M:%S') | |
if datetime.datetime.now() > api_date and dates[0] =='Product': | |
GetItem() | |
elif datetime.datetime.now() > api_date and dates[0]=='Customer': | |
GetCustomer() | |
elif datetime.datetime.now() > api_date and dates[0]=='Order': | |
GetOrders() | |
def get_Data_count(max_date, document_key, headers, oauth_data): | |
r = requests.get(url='http://digitales.com.au/api/rest/mcount?start_date='+cstr(max_date)+'', headers=headers, auth=oauth_data) | |
total_page_count = json.loads(r.content) | |
if total_page_count.get(document_key) > 0: | |
return total_page_count.get(document_key) | |
return 0 | |
#get missing item start | |
def getMissingItemFromSyncItem(): | |
return { | |
"get_missing_item": frappe.db.sql("""select distinct(sync_docname) from `tabSync Item` where sync_doctype='Item' and sync_status='Not Sync'""", as_list=1) | |
} | |
def GetMissingItem(): | |
update_execution_date('Customer') | |
h = {'Content-Type': 'application/json', 'Accept': 'application/json'} | |
oauth = GetOauthDetails() | |
abc=getMissingItemFromSyncItem() | |
j = [i[0] for i in abc["get_missing_item"]] | |
for k in j: | |
url='http://digitales.com.au/api/rest/products?filter[1][attribute]=sku&filter[1][in]='+k | |
r = requests.get(url=url, headers=h, auth=oauth) | |
product_data = json.loads(r.content) | |
frappe.db.sql("""update `tabSync Item` set sync_status='Sync done' where sync_doctype="Item" and sync_docname='%s'"""%(k)) | |
for index in product_data: | |
create_item(index, product_data) | |
#get missing item end | |
#Get Item from magento------------------------------------------------------------------------------------------------------------------------------------ | |
def GetItem(): | |
update_execution_date('Customer') | |
h = {'Content-Type': 'application/json', 'Accept': 'application/json'} | |
oauth = GetOauthDetails() | |
max_item_date = '1991-09-07 05:43:13' | |
max_date = frappe.db.sql(""" select max(modified_date) as max_date from `tabItem` """,as_list=1) | |
if max_date[0][0]!=None: | |
max_item_date = max_date[0][0] | |
max_item_date = max_item_date.split('.')[0] if '.' in max_item_date else max_item_date | |
max_item_date = (datetime.datetime.strptime(max_item_date, '%Y-%m-%d %H:%M:%S') - datetime.timedelta(seconds=1)).strftime('%Y-%m-%d %H:%M:%S') | |
status = get_SyncItemsCount(max_item_date, h, oauth) | |
def get_SyncItemsCount(max_date, header, oauth_data): | |
count = get_Data_count(max_date, 'product_pages_per_100_mcount', header, oauth_data) | |
original_count = count | |
count = 15 if count > 15 else count | |
pagewise_count = {} | |
if count > 0: | |
for index in range(1, count+1): | |
products_count = get_products_from_magento(index, max_date,header, oauth_data) | |
pagewise_count[index] = products_count | |
make_sync_log(json.dumps(pagewise_count), original_count, count, max_date) | |
def get_products_from_magento(page, max_date, header, oauth_data): | |
products_count = 0 | |
if page: | |
r = requests.get(url='http://digitales.com.au/api/rest/products?filter[1][attribute]=updated_at&filter[1][gt]=%s&page=%s&limit=100&order=updated_at&dir=asc'%(max_date, page), headers=header, auth=oauth_data) | |
product_data = json.loads(r.content) | |
products_count = len(product_data) | |
if products_count > 0: | |
for index in product_data: | |
name = frappe.db.get_value('Item', product_data[index].get('sku'), 'name') | |
if name: | |
update_item(name, index, product_data) | |
check_item_price(name,index,product_data) | |
else: | |
create_item(index, product_data) | |
return products_count | |
def make_sync_log(pagewise_count, original_count, synced_count, max_date): | |
slog = frappe.new_doc('Sync Log') | |
slog.pagewise_count = pagewise_count | |
slog.total_count = original_count | |
slog.synced_count = synced_count | |
slog.date = max_date | |
slog.save(ignore_permissions=True) | |
def create_item(i,content): | |
try: | |
item = frappe.new_doc('Item') | |
item.item_code = content[i].get('sku') | |
create_new_product(item,i,content) | |
item.save(ignore_permissions=True) | |
check_item_price(item.name,i,content) | |
except Exception, e: | |
item = frappe.new_doc("Sync Item") | |
item.method="create_item" | |
item.sync_status = "Not Sync" | |
item.sync_count = 1 | |
item.sync_doctype = "Item" | |
item.sync_docname = content[i].get('sku') | |
item.error=e | |
item.obj_traceback=cstr(content[i]) | |
item.save(ignore_permissions=True) | |
create_scheduler_exception(e , 'create_item ', content[i]) | |
def update_item(name,i,content): | |
try: | |
item = frappe.get_doc("Item", name) | |
create_new_product(item,i,content) | |
item.save(ignore_permissions=True) | |
except Exception, e: | |
create_scheduler_exception(e , 'method name update_item: ' ,content[i]) | |
def check_item_price(name,i,content): | |
if content[i].get('price'): | |
price_list=get_price_list() | |
if price_list: | |
item_price_list_name=frappe.db.get_value('Item Price',{'item_code':name,'price_list':price_list},'name') | |
if item_price_list_name: | |
update_price_list(item_price_list_name,i,content,price_list) | |
else: | |
create_price_list(name,i,content,price_list) | |
def get_price_list(): | |
price_list=frappe.db.sql("""select value from `tabSingles` where doctype='Configuration Page' | |
and field='price_list'""",as_list=1) | |
if price_list: | |
return price_list[0][0] | |
else: | |
frappe.msgprint("Please specify default price list in Configuration Page",raise_exception=1) | |
def update_price_list(price_list_name,i,content,price_list): | |
try: | |
item_price = frappe.get_doc("Item Price", price_list_name) | |
create_new_item_price(item_price,i,content,price_list) | |
item_price.save(ignore_permissions=True) | |
except Exception, e: | |
create_scheduler_exception(e , 'method name update_price_list: ' , content[i]) | |
def create_price_list(item,i,content,price_list): | |
try: | |
item_price=frappe.new_doc("Item Price") | |
create_new_item_price(item_price,i,content,price_list) | |
item_price.save(ignore_permissions=True) | |
except Exception, e: | |
create_scheduler_exception(e , 'method name create_price_list: ' ,content[i]) | |
def create_new_item_price(item_price,i,content,price_list): | |
item_price.price_list=price_list | |
item_price.item_code=content[i].get('sku') | |
item_price.price_list_rate=content[i].get('price') | |
return True | |
def create_new_product(item,i,content): | |
item.event_id=i | |
item.artist = content[i].get('artist') | |
item.item_name=content[i].get('name') or content[i].get('sku') | |
item.item_group = media_type(content[i].get('media')) | |
item.description = 'Desc: ' + content[i].get('short_description') if content[i].get('short_description') else content[i].get('sku') | |
warehouse=get_own_warehouse() | |
item.default_warehouse=warehouse | |
if content[i].get('barcode') and not frappe.db.get_value('Item', {'barcode':content[i].get('barcode')}, 'name'): | |
item.barcode = content[i].get('barcode') | |
item.modified_date = content[i].get('updated_at') | |
item.distributor = content[i].get('distributor') | |
item.product_release_date = content[i].get('release_date') | |
item.default_supplier = get_supplier(content[i].get('distributor')) | |
item.expense_account, item.income_account = default_ExpenxeIncomeAccount(item.item_group) | |
return True | |
def media_type(itemgroup): | |
media = 'Products' | |
if itemgroup: | |
media = itemgroup | |
media = media.split(',')[0] | |
if not frappe.db.get_value('Item Group', media, 'name'): | |
create_new_itemgroup(media) | |
return media | |
def default_ExpenxeIncomeAccount(media): | |
# Check item group and assign the default expence and income account | |
expense_account, income_account = '', '' | |
if media in ['DVD', 'CD', 'BLURAY', 'Graphic Novel', 'CDROM', 'Audio Book', 'Manga', | |
'Online Resource', 'Blu-Ray', 'PC Games', 'Hardcover', 'Playstation 3', | |
'Xbox 360', 'Xbox One', 'Playstation 4', 'Nintendo Wii U', '2CD and DVD', | |
'Graphics', '3D', 'UV', 'BLURAY, 3D', 'Nintendo 3DS', 'Nintendo Wii', 'DVD, UV', | |
'BLURAY, DVD', 'BLURAY, DVD, UV', 'Playstation Vita', 'Paperback']: | |
expense_account = "5-1100 Cost of Goods Sold : COGS Stock" | |
income_account = "4-1100 Product Sales" | |
return expense_account, income_account | |
def get_supplier(supplier): | |
temp = '' | |
if supplier: | |
if frappe.db.get_value('Customer', supplier, 'name'): | |
supplier = supplier + '(s)' | |
temp = supplier | |
name = supplier if frappe.db.get_value('Supplier', supplier, 'name') else create_supplier(supplier) | |
if temp: | |
update_supplier(supplier) | |
return name | |
return '' | |
def update_supplier(supplier): | |
try: | |
obj = frappe.get_doc('Supplier', supplier) | |
obj.supplier_name = supplier.replace('(s)', '') | |
obj.save(ignore_permissions=True) | |
except Exception,e: | |
create_scheduler_exception(e , 'method name update_supplier: ' ,supplier) | |
return True | |
def create_supplier(supplier): | |
try: | |
sl = frappe.new_doc('Supplier') | |
sl.supplier_name = supplier | |
sl.supplier_type = 'Stock supplier' if frappe.db.get_value('Supplier Type', 'Stock supplier', 'name') else create_supplier_type() | |
sl.save(ignore_permissions=True) | |
except Exception, e: | |
create_scheduler_exception(e , 'method name create_supplier: ' , supplier) | |
return sl.name | |
def create_supplier_type(): | |
try: | |
st = frappe.new_doc('Supplier Type') | |
st.supplier_type = 'Stock supplier' | |
st.save(ignore_permissions=True) | |
except Exception, e: | |
create_scheduler_exception(e, 'method name create_supplier_type: ' , 'supplier type') | |
return st.name | |
def check_uom_conversion(item): | |
stock_uom=frappe.db.sql(""" select stock_uom from `tabItem` where name='%s'"""%item,as_list=1) | |
if stock_uom: | |
uom_details= frappe.db.sql("""select ifnull(count(idx),0) from `tabUOM Conversion Detail` where uom='%s' and parent='%s' | |
"""%(stock_uom[0][0],item),as_list=1) | |
if uom_details: | |
if uom_details[0][0]!=1: | |
return False | |
else: | |
return True | |
else: | |
return False | |
# def create_new_itemgroup(i,content): | |
# try: | |
# itemgroup=frappe.new_doc('Item Group') | |
# itemgroup.parent_item_group='All Item Groups' | |
# itemgroup.item_group_name=content[i].get('media') | |
# itemgroup.is_group='No' | |
# itemgroup.save() | |
# except Exception, e: | |
# create_scheduler_exception(e , 'method name create_new_itemgroup: ' , content[i]) | |
# return itemgroup.name or 'Products' | |
def create_new_itemgroup(item_group): | |
try: | |
itemgroup=frappe.new_doc('Item Group') | |
itemgroup.parent_item_group='All Item Groups' | |
itemgroup.item_group_name=item_group | |
itemgroup.is_group='No' | |
itemgroup.save() | |
except Exception, e: | |
create_scheduler_exception(e , 'method name create_new_itemgroup: ' , item_group) | |
return itemgroup.name or 'Products' | |
def get_own_warehouse(): | |
warehouse=frappe.db.sql("""select value from `tabSingles` where doctype='Configuration Page' | |
and field='own_warehouse'""",as_list=1) | |
if warehouse: | |
return warehouse[0][0] | |
else: | |
frappe.msgprint("Please specify default own warehouse in Configuration Page",raise_exception=1) | |
def GetOauthDetails(): | |
try: | |
oauth_details = frappe.db.get_value('API Configuration Page', None, '*', as_dict=1) | |
oauth=OAuth(client_key=oauth_details.client_key, client_secret=oauth_details.client_secret, resource_owner_key= oauth_details.owner_key, resource_owner_secret=oauth_details.owner_secret) | |
return oauth | |
except Exception, e: | |
create_scheduler_exception(e , 'method name GetOauthDetails: ' , 'oauth_details') | |
#update configuration | |
def update_execution_date(document): | |
now_plus_10 = datetime.datetime.now() + datetime.timedelta(minutes = 30) | |
frappe.db.sql("""update `tabSingles` set value='%s' where doctype='API Configuration Page' and field='date'"""%(now_plus_10.strftime('%Y-%m-%d %H:%M:%S'))) | |
frappe.db.sql("""update `tabSingles` set value='%s' where doctype='API Configuration Page' and field='api_type'"""%(document)) | |
def GetCustomer(): | |
update_execution_date('Order') | |
h = {'Content-Type': 'application/json', 'Accept': 'application/json'} | |
oauth = GetOauthDetails() | |
max_customer_date = '1988-09-07 05:43:13' | |
max_date = frappe.db.sql(""" select max(modified_date) as max_date from `tabCustomer` """,as_list=1) | |
if max_date[0][0]!=None: | |
max_customer_date = max_date[0][0] | |
max_customer_date = max_customer_date.split('.')[0] if '.' in max_customer_date else max_customer_date | |
max_customer_date = (datetime.datetime.strptime(max_customer_date, '%Y-%m-%d %H:%M:%S') - datetime.timedelta(seconds=1)).strftime('%Y-%m-%d %H:%M:%S') | |
status=get_SyncCustomerCount(max_customer_date, h, oauth) | |
def get_SyncCustomerCount(max_date, header, oauth_data): | |
count = get_Data_count(max_date, 'customer_pages_per_100_mcount', header, oauth_data) | |
count = 25 if count > 30 else count | |
if count > 0: | |
for index in range(1, count+1): | |
get_customers_from_magento(index, max_date,header, oauth_data, 'missed') | |
def get_customers_from_magento(page, max_date, header, oauth_data,type_of_data=None): | |
try: | |
if page: | |
r = requests.get(url='http://digitales.com.au/api/rest/customers?filter[1][attribute]=updated_at&filter[1][gt]=%s&page=%s&limit=100&order=updated_at&dir=asc'%(max_date, page), headers=header, auth=oauth_data) | |
customer_data = json.loads(r.content) | |
if len(customer_data) > 0: | |
for index in customer_data: | |
name = frappe.db.get_value('Customer', customer_data[index].get('organisation').replace("'",""), 'name') | |
if name: | |
update_customer(name, index, customer_data) | |
GetAddress(customer_data[index].get('entity_id')) | |
else: | |
create_customer(index, customer_data) | |
GetAddress(customer_data[index].get('entity_id')) | |
except Exception, e: | |
create_scheduler_exception(e , 'Method name get_customers_from_magento' , customer_data[index].get('organisation')) | |
def create_customer(i,content): | |
temp_customer = '' | |
customer = frappe.new_doc('Customer') | |
if frappe.db.get_value('Supplier',content[i].get('organisation').replace("'",""),'name') or frappe.db.get_value('Customer Group',content[i].get('organisation').replace("'",""),'name'): | |
temp_customer= customer.customer_name = cstr(content[i].get('organisation')).replace("'","") + '(C)' | |
else: | |
customer.customer_name=cstr(content[i].get('organisation')).replace("'","") | |
if not frappe.db.get_value('Customer', customer.customer_name, 'name'): | |
create_new_customer(customer,i,content) | |
create_contact(customer,i,content) | |
if temp_customer: | |
update_customer_name(temp_customer) | |
def update_customer_name(customer_name): | |
try: | |
customer = frappe.get_doc("Customer", customer_name) | |
customer.customer_name= customer_name.replace("(C)","") | |
customer.save(ignore_permissions=True) | |
except Exception, e: | |
create_scheduler_exception(e , 'Method name update_customer_name: ' , customer_name) | |
def update_customer(customer,i ,content): | |
customer = frappe.get_doc("Customer", customer) | |
create_new_customer(customer,i,content) | |
contact=frappe.db.sql("""select name from `tabContact` where entity_id='%s'"""%content[i].get('entity_id'),as_list=1) | |
if contact: | |
update_contact(customer,i,content,contact[0][0]) | |
else: | |
create_contact(customer,i,content) | |
def update_contact(customer,i,content,contact): | |
contact = frappe.get_doc("Contact", contact) | |
create_customer_contact(customer,i,content,contact) | |
def create_contact(customer,i,content): | |
contact=frappe.new_doc('Contact') | |
if not frappe.db.get_value('Contact', {'entity_id':content[i].get('entity_id')}, 'name'): | |
create_customer_contact(customer,i,content,contact) | |
def create_new_customer(customer,i,content): | |
import itertools | |
try: | |
customer.entity_id = content[i].get('entity_id') | |
customer.customer_type = 'Company' | |
if content[i].get('group'): | |
if content[i].get('group').strip() == 'General': | |
customer.customer_group= 'All Customer Groups' | |
elif frappe.db.get_value('Customer Group', content[i].get('group').strip(), 'name'): | |
customer.customer_group=content[i].get('group').strip() or 'All Customer Groups' | |
elif frappe.db.get_value('Customer', content[i].get('group').strip(), 'name'): | |
customer.customer_group = 'All Customer Groups' | |
else: | |
customer_group=create_customer_group(content[i].get('group').strip()) | |
customer.customer_group=customer_group | |
customer.territory = 'Australia' | |
customer.customer_status = 'Existing' | |
customer.modified_date=content[i].get('updated_at') | |
customer.save(ignore_permissions=True) | |
except Exception, e: | |
item = frappe.new_doc("Sync Item") | |
item.method="create_new_customer" | |
# item.sync_status = "Not Sync" | |
# item.sync_count = 1 | |
# item.sync_doctype = "Customer" | |
# item.sync_docname = content[i].get('entity_id') | |
# item.error=e | |
item.obj_traceback=cstr(content[i]) | |
item.save(ignore_permissions=True) | |
create_scheduler_exception(e , 'Method name create_new_customer: ', content[i]) | |
def create_customer_contact(customer,i,content,contact): | |
try: | |
if content[i].get('firstname'): | |
contact.first_name=content[i].get('firstname') | |
contact.last_name=content[i].get('lastname') | |
contact.customer= customer.customer_name | |
contact.customer_name= frappe.db.get_value('Customer', contact.customer, 'customer_name') | |
contact.entity_id = content[i].get('entity_id') | |
contact.email_id=content[i].get('email') | |
contact.save(ignore_permissions=True) | |
except Exception, e: | |
create_scheduler_exception(e , 'Method name create_customer_contact: ', content[i]) | |
def create_new_contact(customer,i,content): | |
try: | |
contact=frappe.new_doc('Contact') | |
if content[i].get('firstname'): | |
contact.first_name=content[i].get('firstname') | |
contact.last_name=content[i].get('lastname') | |
contact.customer= customer | |
contact.customer_name=customer | |
contact.entity_id = content[i].get('entity_id') | |
contact.email_id=content[i].get('email') | |
contact.save(ignore_permissions=True) | |
except Exception, e: | |
create_scheduler_exception(e , 'Method name create_new_contact: ', content[i]) | |
def create_customer_group(i): | |
try: | |
cg=frappe.new_doc('Customer Group') | |
cg.customer_group_name = i | |
cg.parent_customer_group='All Customer Groups' | |
cg.is_group='No' | |
cg.save(ignore_permissions=True) | |
except Exception, e: | |
create_scheduler_exception(e , 'Method name create_customer_group: ', i) | |
return cg.name or 'All Customer Group' | |
def sync_existing_customers_address(): | |
offset = frappe.db.get_value('API Configuration Page', None, 'offset_limit') | |
if offset: | |
customer_data = frappe.db.sql(''' Select entity_id from tabContact order by creation limit %s, 100'''%(offset), as_dict=1) | |
frappe.db.sql(''' update `tabSingles` set value = "%s" where doctype = "API Configuration Page" and field="offset_limit"'''%(cint(offset)+100)) | |
if customer_data: | |
for data in customer_data: | |
GetAddress(data.entity_id) | |
def GetAddress(entity_id): | |
try: | |
h = {'Content-Type': 'application/json', 'Accept': 'application/json'} | |
oauth = GetOauthDetails() | |
customer=frappe.db.get_value('Contact',{'entity_id':entity_id},'customer') | |
if customer: | |
r = requests.get(url='http://digitales.com.au/api/rest/customers/%s/addresses'%(entity_id), headers=h, auth=oauth) | |
cust_address_data=json.loads(r.content) | |
if cust_address_data: | |
for data in cust_address_data: | |
address_entity_id = data.get('entity_id') | |
address_name = frappe.db.get_value('Address', {'entity_id': address_entity_id}, 'name') | |
if not address_name: | |
create_new_address(data, customer) | |
else: | |
update_customer_address(data, address_name, customer) | |
except Exception, e: | |
create_scheduler_exception(e, 'Get Address', entity_id) | |
def create_scheduler_exception(msg, method, obj=None): | |
se = frappe.new_doc('Scheduler Log') | |
se.method = method | |
se.error = msg | |
se.obj_traceback = cstr(obj) | |
se.save(ignore_permissions=True) | |
def create_new_address(data, customer): | |
try: | |
obj = frappe.new_doc('Address') | |
obj.address_title = cstr(data.get('firstname'))+' '+cstr(data.get('lastname')) +' '+cstr(data.get('entity_id')) | |
customer_address(data, obj, customer) | |
obj.save(ignore_permissions=True) | |
except Exception, e: | |
create_scheduler_exception(e, 'create_new_address', customer) | |
def update_customer_address(data, address_name, customer): | |
try: | |
obj = frappe.get_doc('Address', address_name) | |
customer_address(data, obj, customer) | |
obj.save(ignore_permissions=True) | |
except Exception, e: | |
create_scheduler_exception(e ,'Method name update_customer_address: ', customer) | |
def customer_address(data, obj, customer): | |
obj.address_type = get_address_type(data).get('type') # Address Type is Billing or is Shipping?? | |
obj.entity_id = cstr(data.get('entity_id')) | |
obj.address_line1 = cstr(data.get('street')[0]) | |
obj.address_line2 = cstr(data.get('street')[1]) if len(data.get('street')) > 1 else "" | |
obj.city = cstr(data.get('city')) | |
obj.country = frappe.db.get_value('Country', {'code': data.get('country_id')}, 'name') | |
obj.state = cstr(data.get('region')) | |
obj.pincode = cstr(data.get('postcode')) | |
obj.phone = cstr(data.get('telephone')) or '00000' | |
obj.fax = cstr(data.get('fax')) | |
obj.customer = customer | |
obj.customer_name = cstr(data.get('firstname'))+' '+cstr(data.get('lastname')) | |
obj.is_primary_address = get_address_type(data).get('is_primary_address') | |
obj.is_shipping_address = get_address_type(data).get('is_shipping_address') | |
def get_address_type(content): | |
if content.get('is_default_billing'): | |
return {"type":"Billing", "is_primary_address":1, "is_shipping_address":0} | |
elif content.get('is_default_shipping'): | |
return {"type":"Shipping", "is_primary_address":0, "is_shipping_address":1} | |
else: | |
return {"type":"Other", "is_primary_address":0, "is_shipping_address":0} | |
#Get Order data API | |
def GetOrders(): | |
update_execution_date('Product') | |
h = {'Content-Type': 'application/json', 'Accept': 'application/json'} | |
oauth = GetOauthDetails() | |
max_order_date = '2001-09-07 05:43:13' | |
max_date = frappe.db.sql(""" select max(modified_date) as max_date from `tabSales Order` """,as_list=1) | |
if max_date[0][0]!=None: | |
max_order_date = max_date[0][0] | |
max_order_date = max_order_date.split('.')[0] if '.' in max_order_date else max_order_date | |
max_order_date = (datetime.datetime.strptime(max_order_date, '%Y-%m-%d %H:%M:%S') - datetime.timedelta(seconds=1)).strftime('%Y-%m-%d %H:%M:%S') | |
status=get_SyncOrdersCount(max_order_date, h, oauth) | |
def get_SyncOrdersCount(max_date, header, oauth_data): | |
count = get_Data_count(max_date, 'orders_pages_per_100_mcount', header, oauth_data) | |
count = 25 if count > 30 else count | |
if count > 0: | |
for index in range(1, count+1): | |
get_orders_from_magento(index, max_date,header, oauth_data, 'missed') | |
addr_details = {} | |
def get_orders_from_magento(page, max_date, header, oauth_data,type_of_data=None): | |
if page: | |
r = requests.get(url='http://digitales.com.au/api/rest/orders?filter[1][attribute]=updated_at&filter[1][gt]=%s&page=%s&limit=100&order=updated_at&dir=asc'%(max_date, page), headers=header, auth=oauth_data) | |
order_data = json.loads(r.content) | |
if len(order_data) > 0: | |
for index in order_data: | |
try: | |
customer = frappe.db.get_value('Contact', {'entity_id': order_data[index].get('customer_id')}, 'customer') | |
if customer: | |
# create_or_update_customer_address(order_data[index].get('addresses'), customer) | |
order = frappe.db.get_value('Sales Order', {'entity_id': order_data[index].get('entity_id')}, 'name') | |
if not order: | |
create_order(index,order_data,customer) | |
else: | |
frappe.throw(_('Customer with id {0} not found in erpnext').format(order_data[index].get('customer_id'))) | |
except Exception, e: | |
create_scheduler_exception(e, 'get_orders_from_magento', index) | |
return True | |
def create_or_update_customer_address(address_details, customer): | |
address_type_mapper = {'billing': 'Billing', 'shipping': 'Shipping'} | |
if address_details: | |
for address in address_details: | |
address_type = address_type_mapper.get(address.get('address_type')) | |
if not frappe.db.get_value('Address',{'address_title': address.get('firstname') +' '+address.get('lastname') +' '+address.get('street'), 'address_type': address_type},'name'): | |
create_address_forCustomer(address, customer, address_type) | |
else: | |
cust_address=frappe.db.get_value('Address',{'address_title': address.get('firstname') +' '+address.get('lastname') +' '+address.get('street'), 'address_type': address_type},'name') | |
update_address_forCustomer(cust_address,address,customer,address_type) | |
def create_address_forCustomer(address_details, customer, address_type): | |
try: | |
cad = frappe.new_doc('Address') | |
cad.address_title = address_details.get('firstname')+' '+address_details.get('lastname') +' '+address_details.get('street') | |
cad.address_type = address_type | |
cad.address_line1 = address_details.get('street') | |
cad.city = address_details.get('city') | |
cad.state = address_details.get('region') | |
cad.pincode = address_details.get('postcode') | |
cad.phone = address_details.get('telephone') or '00000' | |
cad.customer = customer | |
cad.save(ignore_permissions=True) | |
except Exception, e: | |
create_scheduler_exception(e , 'Method name create_address_forCustomer: ' , customer) | |
def update_address_forCustomer(cust_address,address_details, customer, address_type): | |
try: | |
cad = frappe.get_doc('Address',cust_address) | |
cad.address_type = address_type | |
cad.address_line1 = address_details.get('street') | |
cad.city = address_details.get('city') | |
cad.state = address_details.get('region') | |
cad.pincode = address_details.get('postcode') | |
cad.phone = address_details.get('telephone') or '00000' | |
cad.customer = customer | |
cad.save(ignore_permissions=True) | |
except Exception, e: | |
create_scheduler_exception(e , 'Method name update_address_forCustomer: ', customer) | |
def get_missing_customers(header,oauth_data): | |
list1=[] | |
order=[] | |
for i in range(1,4): | |
r = requests.get(url='http://digitales.com.au/api/rest/orders?&page='+cstr(i)+'&limit=100',headers=header, auth=oauth_data) | |
order_data = json.loads(r.content) | |
for index in order_data: | |
if not frappe.db.get_value('Contact',{'entity_id':order_data[index].get('customer_id')},'name'): | |
list1.append(order_data[index].get('customer_id')) | |
order.append(order_data[index].get('entity_id')) | |
def get_missing_products(header,oauth_data): | |
list2=[] | |
order1=[] | |
for i in range(1,4): | |
r = requests.get(url='http://digitales.com.au/api/rest/orders?&page='+cstr(i)+'&limit=100',headers=header, auth=oauth_data) | |
order_data = json.loads(r.content) | |
for index in order_data: | |
if order_data[index].get('order_items'): | |
for i in order_data[index].get('order_items'): | |
if not frappe.db.get_value('Item',i.get('sku'),'name'): | |
list2.append(i.get('sku')) | |
order1.append(order_data[index].get('entity_id')) | |
def update_order(order,i,content,customer): | |
try: | |
order = frappe.get_doc("Sales Order", order) | |
create_new_order(order,i,content,customer) | |
order.save(ignore_permissions=True) | |
except Exception, e: | |
create_scheduler_exception(e , 'Method name update_order: ', content[i]) | |
def create_order(i,content,customer): | |
try: | |
if content[i].get('order_items'): | |
child_status=check_item_presence(i,content) | |
if child_status==True: | |
order = frappe.new_doc('Sales Order') | |
create_new_order(order,i,content,customer) | |
order.save(ignore_permissions=True) | |
except Exception, e: | |
item = frappe.new_doc("Sync Item") | |
item.method="create_order" | |
item.sync_status = "Not Sync" | |
item.sync_count = 1 | |
item.sync_doctype = "Sales Order" | |
item.sync_docname = content[i].get('entity_id') | |
item.error=e | |
item.obj_traceback=cstr(content[i]) | |
item.save(ignore_permissions=True) | |
create_scheduler_exception(e ,'Method name create_order: ', content[i]) | |
# def create_new_order(order,i,content,customer): | |
# from datetime import date | |
# from dateutil.relativedelta import relativedelta | |
# delivery_date = date.today() + relativedelta(days=+6) | |
# order.customer=customer | |
# order.entity_id=content[i].get('entity_id') | |
# order.modified_date=content[i].get('updated_at') | |
# order.delivery_date=delivery_date | |
# order.grand_total_export=content[i].get('grand_total') | |
# #order.discount_amount=content[i].get('discount_amount') | |
# if content[i].get('po_number'): | |
# order.po_no=content[i].get('po_number') | |
# order.order_type=content[i].get('order_type') | |
# for i in content[i].get('order_items'): | |
# create_child_item(i,order) | |
# # # set shipping and billing address | |
# # set_sales_order_address(content[i].get('addresses')) | |
# Makarand | |
def create_new_order(order,index,content,customer): | |
from datetime import date | |
from dateutil.relativedelta import relativedelta | |
delivery_date = date.today() + relativedelta(days=+6) | |
order.customer=customer | |
order.entity_id=content[index].get('entity_id') | |
order.modified_date=content[index].get('updated_at') | |
order.delivery_date=delivery_date | |
order.grand_total_export=content[index].get('grand_total') | |
order.order_number_details = content[index].get('increment_id') | |
order.po_no=content[index].get('po_number') | |
# If Order type is general then set SO order type as Standard Order | |
if content[index].get('order_type') == "General" or content[index].get('order_type') == None: | |
order.new_order_type="Standard Order" | |
else: | |
order.new_order_type=content[index].get('order_type') | |
for i in content[index].get('order_items'): | |
create_child_item(i,order) | |
# # set shipping and billing address | |
set_sales_order_address(content[index].get('addresses'),order) | |
def set_sales_order_address(address_details, order): | |
# Check if Address is available if it is then set addr id in SO else set None | |
address_type_mapper = {'billing': 'Billing', 'shipping': 'Shipping'} | |
if address_details: | |
for address in address_details: | |
addr_filter = {'entity_id': cstr(address.get('customer_address_id'))} | |
cust_address = frappe.db.get_value('Address',addr_filter,'name') | |
if cust_address: | |
# Check the address type if billing the set to billing addr likewise for shipping | |
if cstr(address.get('address_type')) == "billing": | |
order.customer_address = frappe.db.get_value('Address',{'entity_id':cust_address},'name') | |
if cstr(address.get('address_type')) == "shipping": | |
order.shipping_address_name = frappe.db.get_value('Address',{'entity_id':cust_address},'name') | |
def check_item_presence(i,content): | |
for i in content[i].get('order_items'): | |
item_list = [] | |
item_list.append(i) | |
status = True | |
# print item_list | |
if not frappe.db.get_value('Item',i.get('sku'),'name'): | |
item = frappe.new_doc("Sync Item") | |
item.method="check_item_presence" | |
item.sync_status = "Not Sync" | |
item.sync_count = 1 | |
item.sync_doctype = "Item" | |
item.sync_docname = i.get('sku') | |
# item.error=e | |
item.obj_traceback=cstr(i) | |
item.save(ignore_permissions=True) | |
# frappe.throw(_('Item {0} not present').format(i.get('sku'))) | |
status = False | |
return status | |
def create_child_item(i,order): | |
oi = order.append('sales_order_details', {}) | |
oi.item_code=i['sku'] | |
if i['sku']: | |
item_release_date=frappe.db.sql("""select product_release_date from `tabItem` | |
where name='%s'"""%i['sku'],as_list=1) | |
if item_release_date: | |
oi.release_date_of_item=item_release_date[0][0] | |
oi.qty=i['qty_ordered'] | |
oi.rate=i['price'] | |
art = frappe.db.get_value("Item", i['sku'],"artist") | |
if art: | |
oi.artist = art | |
# oi.amount=i['row_total_incl_tax'] | |
return True | |
@frappe.whitelist() | |
def upload(): | |
if not frappe.has_permission("Attendance", "create"): | |
raise frappe.PermissionError | |
from frappe.utils.csvutils import read_csv_content_from_uploaded_file | |
from frappe.modules import scrub | |
rows = read_csv_content_from_uploaded_file() | |
rows = filter(lambda x: x and any(x), rows) | |
if not rows: | |
msg = [_("Please select a csv file")] | |
return {"messages": msg, "error": msg} | |
columns = [scrub(f) for f in rows[4]] | |
columns[0] = "name" | |
columns[3] = "att_date" | |
ret = [] | |
error = False | |
from frappe.utils.csvutils import check_record, import_doc | |
attendance_dict = attendance_rowdata = {} | |
for i, row in enumerate(rows[5:]): | |
if not row: continue | |
row_idx = i + 5 | |
if row[1]: | |
data = row[1] | |
attendance_rowdata.setdefault(data, row) | |
if data in attendance_dict: | |
attendance_dict[data].append([row[8], row[9]]) | |
else: | |
attendance_dict.setdefault(data, [[row[8], row[9]]]) | |
if attendance_dict and attendance_rowdata: | |
for r in attendance_rowdata: | |
pass | |
if error: | |
frappe.db.rollback() | |
return {"messages": ret, "error": error} | |
# @frappe.whitelist() | |
# def assign_stopQty_toOther(doc): | |
# import json | |
# self = frappe.get_doc('Sales Order', doc) | |
# for data in self.get('sales_order_details'): | |
# qty = flt(data.assigned_qty) - flt(data.delivered_qty) | |
# if flt(data.assigned_qty) > 0.0: | |
# update_sal(data.item_code, data.parent, flt(data.delivered_qty), qty) | |
# sales_order = get_SODetails(data.item_code) | |
# if sales_order: | |
# create_StockAssignment_AgainstSTopSO(data, sales_order, qty) | |
# return "Done" | |
# added by pitambar | |
@frappe.whitelist() | |
def assign_stopQty_toOther(doc,item_list): | |
import json | |
stopping_items=item_list | |
self = frappe.get_doc('Sales Order', doc) | |
for data in self.get('sales_order_details'): | |
if data.item_code in(stopping_items) and data.stop_status!="Yes": # check item code in selected stopping item | |
if cint(frappe.db.get_value('Purchase Order', data.po_data, 'docstatus')) == 0 and data.po_data: | |
po_qty = data.po_qty if data.po_qty else 0.0 | |
reduce_po_item(data.po_data, data.item_code, po_qty) | |
update_so_item_status(data.item_code,data.parent) | |
if flt(data.qty) > flt(data.delivered_qty): | |
update_bin_qty(data.item_code,data.qty,data.delivered_qty,data.warehouse) | |
qty = flt(data.assigned_qty) - flt(data.delivered_qty) | |
if flt(data.assigned_qty) > 0.0: | |
update_sal(data.item_code, data.parent, flt(data.delivered_qty), qty) | |
sales_order = get_item_SODetails(data.item_code) | |
if sales_order: | |
create_StockAssignment_AgainstSTopSOItem(data, sales_order, qty) | |
return "Done" | |
def create_StockAssignment_AgainstSTopSOItem(data, sales_order, qty): | |
for so_data in sales_order: | |
if flt(so_data.qty) > 0.0 and qty > 0.0: | |
stock_assigned_qty = so_data.qty if flt(qty) >= flt(so_data.qty) else flt(qty) | |
qty = (flt(qty) - flt(so_data.qty)) if flt(qty) >= flt(so_data.qty) else 0.0 | |
if flt(stock_assigned_qty) > 0.0: | |
sal = frappe.db.get_value('Stock Assignment Log', {'sales_order': so_data.parent, 'item_code':data.item_code}, 'name') | |
if not sal: | |
sal = create_stock_assignment_document_item(data, so_data.parent, so_data.qty, stock_assigned_qty) | |
else: | |
sal= frappe.get_doc('Stock Assignment Log', sal) | |
sal.assign_qty = cint(sal.assign_qty) + cint(stock_assigned_qty) | |
make_history_of_assignment_item(sal, nowdate(), "Stock In Hand", "", stock_assigned_qty) | |
sal.save(ignore_permissions=True) | |
update_or_reducePoQty(so_data.parent, data.item_code) | |
def update_or_reducePoQty(sales_order, item_code): | |
obj = frappe.get_doc('Sales Order', sales_order) | |
for data in obj.get('sales_order_details'): | |
if data.item_code == item_code: | |
assign_qty = flt(data.qty) - flt(data.assigned_qty) | |
if flt(data.po_qty) > flt(assign_qty): | |
po_qty = flt(assign_qty) | |
else: | |
po_qty = 0.0 | |
frappe.db.sql(""" update `tabSales Order Item` set | |
po_qty = '%s' where name ='%s'"""%(po_qty, data.name)) | |
reduce_po_item(data.po_data, data.item_code, data.assigned_qty) | |
def reduce_po_item(purchase_order,item, assign_qty): | |
po_details = frappe.db.get_value('Purchase Order Item', {'parent': purchase_order, 'item_code': item, 'docstatus': 0}, '*', as_dict=1) | |
if po_details: | |
update_child_table_item(po_details, assign_qty) | |
update_parent_table_item(po_details) | |
def update_child_table_item(po_details, po_qty): | |
qty = flt(po_details.qty) - po_qty | |
if flt(qty) >= 1.0: | |
frappe.db.sql(""" update `tabPurchase Order Item` set qty = '%s' where name ='%s'"""%(qty, po_details.name)) | |
elif flt(qty)==0.0: | |
delete_document('Purchase Order Item', po_details.name) | |
def update_parent_table_item(po_details): | |
count = frappe.db.sql(''' select ifnull(count(*),0) from `tabPurchase Order Item` where parent = "%s" '''%(po_details.parent), as_list=1) | |
if count: | |
if count[0][0] == 0: | |
obj = frappe.get_doc('Purchase Order', po_details.parent) | |
obj.delete() | |
def create_stock_assignment_document_item(args, sales_order, qty, assigned_qty): | |
sa = frappe.new_doc('Stock Assignment Log') | |
sa.item_name = args.item_name | |
sa.sales_order = sales_order | |
sa.ordered_qty = qty | |
sa.assign_qty = assigned_qty | |
sa.purchase_receipt_no = args.parent if args.doctype == 'Purchase Receipt Item' else '' | |
sa.item_code = args.item_code | |
sa.media = frappe.db.get_value("Item",args.item_code,'item_group') | |
sa.customer_name = frappe.db.get_value('Sales Order',sa.sales_order,'customer_name') | |
return sa | |
def make_history_of_assignment_item(sal, date, doc_type, pr_name, qty): | |
sal_child = sal.append('document_stock_assignment', {}) | |
sal_child.created_date = nowdate(); | |
sal_child.document_type = doc_type | |
sal_child.document_no = pr_name | |
sal_child.qty = qty | |
# def create_stock_assignment_document_item(item_name,item_code, sales_order, assigned_qty): | |
# sa = frappe.new_doc('Stock Assignment Log') | |
# sa.item_name = item_name | |
# sa.sales_order = sales_order | |
# sa.ordered_qty = frappe.db.get_value('Sales Order Item', {'item_code':item_code, 'parent': sales_order}, 'qty') if args.doctype == 'Purchase Receipt Item' else args.qty | |
# sa.assign_qty = assigned_qty | |
# sa.purchase_receipt_no = args.parent if args.doctype == 'Purchase Receipt Item' else '' | |
# sa.item_code = args.item_code | |
# sa.customer_name = frappe.db.get_value('Sales Order',sa.sales_order,'customer_name') | |
def get_item_SODetails(item_c): | |
return frappe.db.sql('''select s.parent as parent,ifnull(s.qty,0)-ifnull(s.assigned_qty,0) AS qty, | |
s.assigned_qty as assigned_qty from `tabSales Order Item` s inner join `tabSales Order` so | |
on s.parent=so.name where s.item_code="%s" and so.docstatus=1 and ifnull(s.stop_status, 'No') <> 'Yes' and | |
ifnull(s.qty,0)>ifnull(s.assigned_qty,0) and so.status!='Stopped' order by so.priority,so.creation'''%(item_c),as_dict=1) | |
def update_bin_qty(item_code,qty,delivered_qty,warehouse): | |
obj=frappe.get_doc("Bin",{"item_code":item_code,"warehouse":warehouse}) | |
obj.reserved_qty=flt(obj.reserved_qty)-(flt(qty) - flt(delivered_qty)) | |
obj.save(ignore_permissions=True) | |
def update_so_item_status(item_code,parent): | |
frappe.db.sql(''' update `tabSales Order Item` set stop_status = "Yes" where item_code = "%s" and parent="%s"'''%(item_code,parent)) | |
frappe.db.sql(''' update `tabDelivery Note Item` set stop_status = "Yes" where item_code = "%s" and against_sales_order="%s" and docstatus<>2'''%(item_code,parent)) | |
frappe.db.sql(''' update `tabSales Invoice Item` set stop_status = "Yes" where item_code = "%s" and sales_order="%s" and docstatus<>2'''%(item_code,parent)) | |
def create_StockAssignment_AgainstSTopSO(data, sales_order, qty): | |
for so_data in sales_order: | |
if flt(so_data.qty) > 0.0 and qty > 0.0: | |
stock_assigned_qty = so_data.qty if flt(qty) >= flt(so_data.qty) else flt(qty) | |
qty = (flt(qty) - flt(so_data.qty)) if flt(qty) >= flt(so_data.qty) else 0.0 | |
if flt(stock_assigned_qty) > 0.0: | |
sal = frappe.db.get_value('Stock Assignment Log', {'sales_order': so_data.parent, 'item_code':data.item_code}, 'name') | |
if not sal: | |
sal = create_stock_assignment_document(data, so_data.parent, stock_assigned_qty) | |
make_history_of_assignment(sal, nowdate(), "Stock In Hand", "", stock_assigned_qty) | |
def update_sal(item_code, sales_order, delivered_qty, assigned_qty): | |
sal = frappe.db.get_value('Stock Assignment Log', {'item_code': item_code, 'sales_order': sales_order}, '*', as_dict=1) | |
if sal: | |
obj = frappe.get_doc('Stock Assignment Log', sal.name) | |
if flt(assigned_qty) > 0.0 and delivered_qty > 0.0: | |
obj.assign_qty = delivered_qty | |
to_remove_obj = [] | |
for d in obj.get('document_stock_assignment'): | |
if flt(assigned_qty) > 0: | |
assigned_qty = flt(assigned_qty) - flt(d.qty) | |
if flt(assigned_qty) <= 0.0: | |
d.qty = assigned_qty * -1 | |
else: | |
to_remove_obj.append(d) | |
[obj.remove(d) for d in to_remove_obj] | |
obj.save(ignore_permissions=True) | |
else: | |
frappe.db.sql(''' update `tabSales Order Item` set assigned_qty=0 where item_code ="%s" | |
and parent ="%s"'''%(item_code, sales_order)) | |
obj.delete() | |
def make_csv(): | |
import csv | |
present_list = [] | |
with open('/home/indictrance/Desktop/finaltryitem2.csv', 'rb') as f: | |
reader = csv.reader(f) | |
for item in reader: | |
item_name=frappe.db.get_value('Item', item[0], 'name') | |
if item_name: | |
present_list.append([item_name]) | |
def validate_sales_invoice(doc, method): | |
set_terms_and_condition(doc) | |
set_sales_order_details(doc) | |
set_contract_details(doc) | |
def set_terms_and_condition(si_obj): | |
si_obj.tc_name = 'Net 30' if not si_obj.tc_name else si_obj.tc_name | |
if si_obj.tc_name: | |
si_obj.terms = frappe.db.get_value('Terms and Conditions', si_obj.tc_name, 'terms') | |
def set_sales_order_details(doc): | |
if doc.entries and doc.entries[0].sales_order: | |
so = frappe.get_doc("Sales Order", doc.entries[0].sales_order) | |
doc.po_no = so.po_no if not doc.po_no else doc.po_no | |
doc.new_order_type = so.new_order_type if not doc.new_order_type else doc.new_order_type | |
budget = so.budget if not doc.budget else doc.budget | |
def set_contract_details(doc): | |
from erpnext.selling.doctype.customer.customer import get_contract_details | |
contract_details = get_contract_details(doc.customer) | |
doc.contract_number = contract_details.get("contract_no") if not doc.contract_number else doc.contract_number | |
doc.tender_group = contract_details.get("tender_group") if not doc.tender_group else doc.tender_group | |
@frappe.whitelist() | |
def get_artist(item_code): | |
return frappe.db.get_value('Item', {'name':item_code}, 'artist') or '' | |
def set_artist(doc, method): | |
for i in doc.item_details: | |
art = frappe.db.get_value('Item', {'name':i.item_code}, 'artist') or '' | |
i.artist=art |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment