Error when creating custom doctype

Hi,

im creating custom doctype and when try to add new i got the following error :
Traceback (innermost last):
File “/home/sigma/frappe-bench/apps/frappe/frappe/widgets/form/save.py”, line 18, in savedocs
doc.save()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/document.py”, line 175, in save
self.insert()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/document.py”, line 145, in insert
self._validate()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/document.py”, line 257, in _validate
self._validate_constants()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/base_document.py”, line 343, in _validate_constants
if self.get(fieldname) != values.get(fieldname):
AttributeError: ‘NoneType’ object has no attribute ‘get’

Traceback (innermost last):
File “/home/sigma/frappe-bench/apps/frappe/frappe/app.py”, line 49, in application
response = frappe.handler.handle()
File “/home/sigma/frappe-bench/apps/frappe/frappe/handler.py”, line 66, in handle
execute_cmd(cmd)
File “/home/sigma/frappe-bench/apps/frappe/frappe/handler.py”, line 89, in execute_cmd
ret = frappe.call(method, **frappe.form_dict)
File “/home/sigma/frappe-bench/apps/frappe/frappe/init.py”, line 531, in call
return fn(*args, **newargs)
File “/home/sigma/frappe-bench/apps/frappe/frappe/widgets/form/save.py”, line 18, in savedocs
doc.save()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/document.py”, line 175, in save
self.insert()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/document.py”, line 145, in insert
self._validate()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/document.py”, line 257, in _validate
self._validate_constants()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/base_document.py”, line 343, in _validate_constants
if self.get(fieldname) != values.get(fieldname):
AttributeError: ‘NoneType’ object has no attribute ‘get’

here my code :

from future import unicode_literals
import frappe
from frappe.utils import cint, cstr, flt

from frappe import _
from frappe.model.document import Document

class ProductionActualCost(Document):
def on_submit(self):
last_transaction = frappe.get_list(“Production Actual Cost”,
fields=[“posting_date”],
filters = {
“posting_date”: ("<=", self.posting_date),
“name”: ("!=", self.name)
})
isFirst = 1
from_date=“2001-01-01”
if last_transaction :
isFirst=0
from_date=last_transaction[0].posting_date

    to_date = self.posting_date
    filters={"from_date":from_date,"to_date":to_date}
    monthly=get_monthly_cost(filters)
    time=get_work_timelog_data(filters)
    production=get_production_data(filters)
    summarize(time,production,monthly,self)

def summarize(time,production,monthly,doc):
    cuttingQty=0
    assemblyQty=0
    stitchingQty=0    
    totalCuttingQty=0
    totalAssemblyQty=0
    totalStitchingQty=0
    year=0
    dateofyear=0
    spk=[]
    curspk=""
    i=0
    str=""
    totalQtyOfAll=0
    date=""
    for data in production:
        totalQtyOfAll+=data.get("produced_qty")
        if year==0 and dateofyear==0:
            year=data.get("year")
            dateofyear=data.get("tgl")
            curspk=data.get("kode_spk")
            date=data.get("posting_date")
        if year==data.get("year") and dateofyear==data.get("tgl"):
            
            if curspk==data.get("kode_spk"):
                if data.get("category")=="Stitching" :
                    stitchingQty+=data.get("produced_qty")
                    totalStitchingQty+=data.get("produced_qty")
                if data.get("category")=="Assembly" :
                    assemblyQty+=data.get("produced_qty")
                    totalAssemblyQty+=data.get("produced_qty")
                if data.get("category")=="Cutting" :
                    cuttingQty+=data.get("produced_qty")
                    totalCuttingQty+=data.get("produced_qty")
            else:
                spk.append([curspk,cuttingQty,stitchingQty,assemblyQty,date])
                cuttingQty=0
                assemblyQty=0
                stitchingQty=0
                curspk=data.get("kode_spk")
                if data.get("category")=="Stitching" :
                    stitchingQty=data.get("produced_qty")
                    totalStitchingQty+=data.get("produced_qty")
                if data.get("category")=="Assembly" :
                    assemblyQty=data.get("produced_qty")
                    totalAssemblyQty+=data.get("produced_qty")
                if data.get("category")=="Cutting" :
                    cuttingQty=data.get("produced_qty")
                    totalCuttingQty+=data.get("produced_qty")
        else:
            spk.append([curspk,cuttingQty,stitchingQty,assemblyQty,date])
            for row in spk:
                flag=1
                if i>=len(time):
                    i=len(time)-1
                while flag==1 and i<len(time):
                    if time[i][0]==year and time[i][1]==dateofyear:
                        flag=0
                    elif time[i][0]>year or time[i][1]>dateofyear:
                        flag=2
                    else:
                        i+=1
                cHours=0
                cPayment=0
                #cAvg=0
                sHours=0
                sPayment=0
                #sAvg=0
                aHours=0
                aPayment=0
                #aAvg=0
                if flag==0 and row[1]>0 and totalCuttingQty>0:
                    cHours=(float(row[1])*float(time[i][4]))/float(totalCuttingQty)
                    cPayment=(float(row[1])*float(time[i][5]))/float(totalCuttingQty)
                    #cAvg=float(cPayment)/float(row[1])
                if flag==0 and row[2]>0 and totalStitchingQty>0:
                    sHours=(float(row[2])*float(time[i][7]))/float(totalStitchingQty)
                    sPayment=(float(row[2])*float(time[i][8]))/float(totalStitchingQty)
                    #sAvg=float(sPayment)/float(row[2])
                if flag==0 and row[3]>0 and totalAssemblyQty>0:
                    aHours=(float(row[3])*float(time[i][10]))/float(totalAssemblyQty)
                    aPayment=(float(row[3])*float(time[i][11]))/float(totalAssemblyQty)
                    #aAvg=float(aPayment)/float(row[3])
                cWork=0
                sWork=0
                aWork=0
                #frappe.throw("compare {0} with {1} is resulting {2} with flag {3} from index {4}".format(row[4],time[i][2],row[4]==time[i][2],flag,i))
                if row[4]==time[i][2]:
                    cWork=time[i][3]
                    sWork=time[i][6]
                    aWork=time[i][9]
                #result.append([row[0],row[4],row[1],cWork,cHours,cPayment,cAvg,row[2],sWork,sHours,sPayment,sAvg,row[3],aWork,aHours,aPayment,aAvg])
                result.append([row[0],row[4],row[1],cWork,cHours,cPayment,row[2],sWork,sHours,sPayment,row[3],aWork,aHours,aPayment])
            spk=[]
            cuttingQty=0
            assemblyQty=0
            stitchingQty=0
            totalCuttingQty=0
            totalAssemblyQty=0
            totalStitchingQty=0
            year=data.get("year")
            dateofyear=data.get("tgl")
            curspk=data.get("kode_spk")
            date=data.get("posting_date")
            if data.get("category")=="Stitching" :
                stitchingQty=data.get("produced_qty")
                totalStitchingQty+=stitchingQty
            if data.get("category")=="Assembly" :
                assemblyQty=data.get("produced_qty")
                totalAssemblyQty+=assemblyQty
            if data.get("category")=="Cutting" :
                cuttingQty=data.get("produced_qty")
                totalCuttingQty+=cuttingQty
    
    if len(production)>0 :
        spk.append([curspk,cuttingQty,stitchingQty,assemblyQty,date])
        
        
        #frappe.throw("{} total cutting {} total sticing {} total assembly {}".format(spk,totalCuttingQty,totalStitchingQty,totalAssemblyQty))
        #frappe.throw(spk)
        for row in spk:
            flag=1
            if i>=len(time):
                i=len(time)-1
            while flag==1 and i<len(time):
                if time[i][0]==year and time[i][1]==dateofyear:
                    flag=0
                elif time[i][0]>year or time[i][1]>dateofyear:
                    flag=2
                else:
                    i+=1
            cHours=0
            cPayment=0
            #cAvg=0
            sHours=0
            sPayment=0
            #sAvg=0
            aHours=0
            aPayment=0
            #aAvg=0
            if flag==0 and row[1]>0 and totalCuttingQty>0:
                cHours=(float(row[1])*float(time[i][4]))/float(totalCuttingQty)
                cPayment=(float(row[1])*float(time[i][5]))/float(totalCuttingQty)
                #cAvg=float(cPayment)/float(row[1])
            if flag==0 and row[2]>0 and totalStitchingQty>0:
                sHours=(float(row[2])*float(time[i][7]))/float(totalStitchingQty)
                sPayment=(float(row[2])*float(time[i][8]))/float(totalStitchingQty)
                #sAvg=float(sPayment)/float(row[2])
            if flag==0 and row[3]>0 and totalAssemblyQty>0:
                aHours=(float(row[3])*float(time[i][10]))/float(totalAssemblyQty)
                aPayment=(float(row[3])*float(time[i][11]))/float(totalAssemblyQty)
                #aAvg=float(aPayment)/float(row[3])
            cWork=0
            sWork=0
            aWork=0
            if date==row[4]:
                cWork=time[i][3]
                sWork=time[i][6]
                aWork=time[i][9]
            #result.append([row[0],row[4],row[1],cWork,cHours,cPayment,cAvg,row[2],sWork,sHours,sPayment,sAvg,row[3],aWork,aHours,aPayment,aAvg])
            result.append([row[0],row[4],row[1],cWork,cHours,cPayment,row[2],sWork,sHours,sPayment,row[3],aWork,aHours,aPayment])
    generate_monthly_cost(result,monthly,totalQtyOfAll,doc)

def generate_monthly_cost(data,monthlyCost,totalQty,doc):
    if totalQty==0 or monthlyCost==0:
        pcost=0
    else:
        pcost=float(monthlyCost)/float(totalQty)
    for row in data:
        record = frappe.get_doc({
            "doctype":"Production Actual Cost Record",
            "date":row[1],
            "kode_spk":row[0],
            "production_actual_cost":doc.name,
            "cqty":row[2],
            "cworker":row[3],
            "ctime":row[4],
            "ccost":row[5],
            "sqty":row[6],
            "sworker":row[7],
            "stime":row[8],
            "scost":row[9],
            "aqty":row[10],
            "aworker":row[11],
            "atime":row[12],
            "acost":row[13],
            "mcost":float(row[2])+float(row[6])+float(row[10])*pcost
        })
        record.insert()
        recurd.submit()
    


def get_work_timelog_data(filters):
    timelog = frappe.db.sql("""SELECT Year(date) as "year",DAYOFYEAR(date) as "tgl",date, sum(worker) as "people", sum(total_hours) as "hours" , sum(total_payment) as "payment" , activity_type from `tabTime Log` where docstatus=1 and date between %(from_date)s and %(to_date)s group by activity_type,DAYOFYEAR(date) order by date,activity_type""",filters,as_dict=1)
    year=0
    dateofyear=0
    cutting=[0,0,0]
    assembly=[0,0,0]
    stitching=[0,0,0]
    time=[]
    date=""
    for data in timelog:
        if year==0 and dateofyear==0:
            year=data.get("year")
            dateofyear=data.get("tgl")
            date=data.get("date")
        if year==data.get("year") and dateofyear==data.get("tgl"):    
            if data.get("activity_type")=="Stitching" :
                stitching=[data.get("people"),data.get("hours"),data.get("payment")]
            if data.get("activity_type")=="Assembly" :
                assembly=[data.get("people"),data.get("hours"),data.get("payment")]
            if data.get("activity_type")=="Cutting" :            
                cutting=[data.get("people"),data.get("hours"),data.get("payment")]
        else:
            time.append([year,dateofyear,date,cutting[0],cutting[1],cutting[2],stitching[0],stitching[1],stitching[2],assembly[0],assembly[1],assembly[2]])
            year=data.get("year")
            dateofyear=data.get("tgl")
            date=data.get("date")
            cutting=[0,0,0]
            assembly=[0,0,0]
            stitching=[0,0,0]
            if data.get("activity_type")=="Stitching" :
                stitching=[data.get("people"),data.get("hours"),data.get("payment")]
            if data.get("activity_type")=="Assembly" :
                assembly=[data.get("people"),data.get("hours"),data.get("payment")]
            if data.get("activity_type")=="Cutting" :
                cutting=([data.get("people"),data.get("hours"),data.get("payment")])

    if len(timelog)>0 :
        time.append([year,dateofyear,date,cutting[0],cutting[1],cutting[2],stitching[0],stitching[1],stitching[2],assembly[0],assembly[1],assembly[2]])
    return time

def get_production_data(filters):
    production_data = frappe.db.sql("""SELECT Year(STE.posting_date) as "year",DAYOFYEAR(STE.posting_date) as "tgl",prod.kode_spk,prod.category,prod.production_item,prod.name ,SUM(IF(STD.s_warehouse is NULL,1,0)*STD.qty) as "produced_qty",STE.posting_date FROM `tabProduction Order` prod JOIN `tabStock Entry` STE on STE.production_order=prod.name JOIN `tabStock Entry Detail` STD on STD.parent=STE.name WHERE prod.docstatus=1 and STE.docstatus=1 and STD.docstatus=1 and STE.posting_date between %(from_date)s and %(to_date)s group by STE.posting_date,prod.kode_spk,prod.category order by STE.posting_date,prod.kode_spk,prod.category""",filters,as_dict=1)
    return production_data
    
def get_monthly_cost(filters):
    monthly_cost=frappe.db.sql("""SELECT sum(credit-debit) as total from `tabJournal Voucher Detail` jvd JOIN `tabJournal Voucher` jv on jvd.parent=jv.name where jvd.docstatus=1 and jv.docstatus=1 and (jvd.against_account like "522%" or jvd.against_account like "523%") and jv.posting_date between %(from_date)s and %(to_date)s group by 1""",filters,as_dict=1)
    return monthly_cost[0]  

please advise …

thanks

Can you share you model files? have you pushed your app to GitHub?

Hi,

sure i can share it, but im not using github so far…ill have the doctype zipped or i can send mail to support about my apps login ?

Thanks

Hi metha,

im uplpoading mine to github here https://github.com/bobzz-zone/gsi

please take a look
the doctype i created located at manufacture > Production actual cost document

Thanks

@bobzz_zone you don’t need to push the entire bench folder.

Did you create a custom app first?

Please go through this guide first. It will give you a good understanding of how to create a plugin / app

https://frappe.io/docs/guide

Hi metha,

sorry i’ve read it but i dont really get it, so i thought i will learn by doing so i created the doctype and code tthe script i copy here

can you tell me which part i was wrong…

Thanks

You should not directly edit ERPnext code.

But how i should create it, i tried to create as new app but when i do that erpnext site cant be opened, so i tried to create just a new doctype

this means i should create separate apps that should be integrated with erpnext like shopping cart module right ?

Thanks

Hi ,

im already creating new apps for my code and the error still presist , im updated the git as well

please advise me how i can fix this problem

Thanks

If you don’t share your error, we can’t help you.

Hi,

Its still the same as before :
Traceback (innermost last):
File “/home/sigma/frappe-bench/apps/frappe/frappe/widgets/form/save.py”, line 18, in savedocs
doc.save()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/document.py”, line 175, in save
self.insert()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/document.py”, line 145, in insert
self._validate()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/document.py”, line 257, in _validate
self._validate_constants()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/base_document.py”, line 343, in _validate_constants
if self.get(fieldname) != values.get(fieldname):
AttributeError: ‘NoneType’ object has no attribute ‘get’

Traceback (innermost last):
File “/home/sigma/frappe-bench/apps/frappe/frappe/app.py”, line 49, in application
response = frappe.handler.handle()
File “/home/sigma/frappe-bench/apps/frappe/frappe/handler.py”, line 66, in handle
execute_cmd(cmd)
File “/home/sigma/frappe-bench/apps/frappe/frappe/handler.py”, line 89, in execute_cmd
ret = frappe.call(method, **frappe.form_dict)
File “/home/sigma/frappe-bench/apps/frappe/frappe/init.py”, line 531, in call
return fn(*args, **newargs)
File “/home/sigma/frappe-bench/apps/frappe/frappe/widgets/form/save.py”, line 18, in savedocs
doc.save()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/document.py”, line 175, in save
self.insert()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/document.py”, line 145, in insert
self._validate()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/document.py”, line 257, in _validate
self._validate_constants()
File “/home/sigma/frappe-bench/apps/frappe/frappe/model/base_document.py”, line 343, in _validate_constants
if self.get(fieldname) != values.get(fieldname):
AttributeError: ‘NoneType’ object has no attribute ‘get’

i had create new apps for that , you can also visit my test server 128.199.253.52 , just use default admin user im not changing that yet since its still under development (user : Administrator, pass : admin)

Thanks

There could be a field in your custom doctype that you set at “Set Only Once” that could be creating the issue. Uncheck that and see if it works…

wow thaks, its works, now i can continue my work…thanks metha…:slight_smile: