clinic/netforce_clinic/models/shop.py

622 lines
22 KiB
Python
Raw Normal View History

2015-01-21 01:35:55 +00:00
import time
from netforce.model import Model, fields, get_model
2015-02-04 08:51:14 +00:00
from netforce.access import get_active_user, set_active_user, get_active_company
2015-02-12 08:52:35 +00:00
from netforce.utils import get_data_path, get_file_path
2015-02-13 07:46:39 +00:00
from . import utils
2015-01-21 01:35:55 +00:00
2015-01-23 10:28:08 +00:00
class Shop(Model):
_name="clinic.shop"
_string="Shop"
2015-02-04 08:51:14 +00:00
_name_field="number"
_multi_company=True
2015-01-21 01:35:55 +00:00
def _get_all(self,ids,context={}):
res={}
st=get_model("clinic.setting").browse(1)
shop_categs=[x.id for x in st.shop_categs]
2015-01-21 01:35:55 +00:00
for obj in self.browse(ids):
total=0
for line in obj.lines:
amt=line.amount or 0
total+=amt
2015-01-21 01:35:55 +00:00
res[obj.id]={
'total': total,
'shop_categs': shop_categs,
2015-01-21 01:35:55 +00:00
}
return res
_fields={
"number": fields.Char("Number",required=True,search=True),
2015-03-17 00:56:55 +00:00
"ref": fields.Char("Customer Name",search=True),
2015-01-21 01:35:55 +00:00
'date': fields.Date("Date",search=True),
2015-03-02 04:03:07 +00:00
'patient_id': fields.Many2One('clinic.patient','Patient',search=True,domain=[['state','=','admit']]),
2015-02-02 10:47:19 +00:00
'contact_id': fields.Many2One('partner','Contact',search=True),
2015-02-04 08:51:14 +00:00
'department_id': fields.Many2One("clinic.department","Department",search=True),
'branch_id': fields.Many2One("clinic.branch","Branch",search=True),
2015-01-23 10:28:08 +00:00
'lines': fields.One2Many('clinic.shop.line','shop_id','Lines'),
2015-01-21 01:35:55 +00:00
'total': fields.Float("Total",function="_get_all",function_multi=True),
'user_id': fields.Many2One("base.user","Pharmacist"),
'state': fields.Selection([['draft','Draft'],['waiting_payment','Waiting Payment'],['paid','Paid']],'State'),
"pickings": fields.One2Many("stock.picking","related_id","Pickings"),
"invoices": fields.One2Many("account.invoice","related_id","Invoices"),
2015-01-23 10:28:08 +00:00
"payments": fields.One2Many("account.payment","related_id","Payments"),
'dom_str': fields.Char("Dom Str"),
2015-01-29 16:38:22 +00:00
'shop_categs': fields.Many2Many("product.categ","Categs",function="_get_all",function_multi=True,store=True),
"related_id": fields.Reference([["sale.order","Sales Order"],["purchase.order","Purchase Order"],["project","Project"],["job","Service Order"],["service.contract","Service Contract"]],"Related To"),
2015-02-04 08:51:14 +00:00
'company_id': fields.Many2One("company","Company"),
"pay_type": fields.Selection([("cash","Cash"),("credit","Credit")],"Pay Type"),
2015-02-13 07:46:39 +00:00
"pay_by": fields.Selection([("cash","Cash"),("cheque","Cheque")],"Pay By"),
'pay_date': fields.Date("Pay Date"),
'bank_name': fields.Char("Bank"),
'bank_branch': fields.Char("Bank Branch"),
'cheque_no': fields.Char("Cheque No."),
2015-02-04 08:51:14 +00:00
'hd_case_call': fields.Boolean("HD Case Call"),
2015-02-13 07:46:39 +00:00
'note': fields.Text("Note"),
2015-01-21 01:35:55 +00:00
}
2015-01-29 16:38:22 +00:00
def _get_shop_categs(self,context={}):
st=get_model("clinic.setting").browse(1)
shop_categs=[x.id for x in st.shop_categs]
return shop_categs
def _get_related(self,context={}):
related_id=None
if context.get('refer_id'):
related_id="clinic.hd.case,%s"%context.get("refer_id")
return related_id
def _get_patient(self,context={}):
patient_id=None
if context.get('refer_id'):
refer_id=context.get("refer_id")
hd_case=get_model("clinic.hd.case").browse(refer_id)
patient_id=hd_case.patient_id.id
return patient_id
2015-01-22 10:40:05 +00:00
2015-02-04 08:51:14 +00:00
def _get_contact(self,context={}):
partner_id=None
if context.get('refer_id'):
refer_id=context.get("refer_id")
hd_case=get_model("clinic.hd.case").browse(refer_id)
patient=hd_case.patient_id
partner=patient.partner_id
partner_id=partner.id
return partner_id
def _get_hdcase_call(self,context={}):
res=False
if context.get('hd_case_call'):
res=True
return res
2015-02-04 05:13:10 +00:00
def _get_number(self,context={}):
while 1:
seq_id=get_model("sequence").find_sequence(name="Clinic RD Shop")
num=get_model("sequence").get_next_number(seq_id,context=context)
if not num:
return None
user_id=get_active_user()
set_active_user(1)
res=self.search([["number","=",num]])
set_active_user(user_id)
if not res:
return num
get_model("sequence").increment_number(seq_id,context=context)
2015-03-17 10:04:14 +00:00
def _get_branch(self,context={}):
res=get_model('select.company').get_select()
if res:
return res['branch_id']
def _get_department(self,context={}):
res=get_model('select.company').get_select()
if res:
if res.get("department_ids"):
return res['department_ids'][0]
else:
return res['department_id']
2015-01-21 01:35:55 +00:00
_defaults={
'number': '/',
2015-01-22 10:40:05 +00:00
'date': lambda *a: time.strftime("%Y-%m-%d"),
2015-01-21 01:35:55 +00:00
'user_id': lambda *a: get_active_user(),
2015-02-04 08:51:14 +00:00
'company_id': lambda *a: get_active_company(),
2015-01-22 10:40:05 +00:00
'branch_id': _get_branch,
'department_id': _get_department,
2015-01-21 01:35:55 +00:00
'state': 'draft',
2015-01-29 16:38:22 +00:00
'shop_categs': _get_shop_categs,
'related_id': _get_related,
'patient_id': _get_patient,
2015-02-04 08:51:14 +00:00
'contact_id': _get_contact,
'pay_type': 'cash',
'hd_case_call': _get_hdcase_call,
2015-01-21 01:35:55 +00:00
}
def update_all(self,context={}):
data=context['data']
data['total']=0
for line in data['lines']:
data['total']+=line['amount'] or 0
return data
def onchange_line(self,context={}):
data=context['data']
path=context['path']
line=get_data_path(data,path,parent=True)
line['amount']=(line['qty'] or 0)*(line['price'] or 0)
data=self.update_all(context=context)
return data
2015-01-21 01:35:55 +00:00
def onchange_product(self,context={}):
data=context['data']
path=context['path']
line=get_data_path(data,path,parent=True)
prod_id=line['product_id']
prod=get_model('product').browse(prod_id)
line['uom_id']=prod.uom_id.id
line['description']=prod.name or ''
line['price']=prod.sale_price or 0
if not line.get('qty'):
line['qty']=1
line['amount']=line['price']*line['qty']
data=self.update_all(context)
2015-01-21 01:35:55 +00:00
return data
2015-02-02 01:41:43 +00:00
def onchange_categ(self,context={}):
data=context['data']
path=context['path']
line=get_data_path(data,path,parent=True)
line['product_id']=None
return data
2015-02-02 10:47:19 +00:00
def onchange_patient(self,context={}):
data=context['data']
patient_id=data['patient_id']
patient=get_model("clinic.patient").browse(patient_id)
dpt=patient.department_id
branch=patient.branch_id
contact=patient.partner_id
data['department_id']=dpt.id
data['branch_id']=branch.id
data['contact_id']=contact.id
return data
2015-01-21 01:35:55 +00:00
2015-02-13 07:46:39 +00:00
def onchange_contact(self,context={}):
data=context['data']
contact_id=data['contact_id']
data['patient_id']=None
2015-03-17 10:04:14 +00:00
#data['department_id']=None
#data['branch_id']=None
2015-02-13 07:46:39 +00:00
for patient in get_model("clinic.patient").search_browse([['partner_id','=',contact_id]]):
dpt=patient.department_id
branch=patient.branch_id
data['department_id']=dpt.id
data['branch_id']=branch.id
data['patient_id']=patient.id
return data
2015-01-29 16:38:22 +00:00
def create(self,vals,**kw):
id=super().create(vals,**kw)
self.function_store([id])
return id
def write(self,ids,vals,**kw):
super().write(ids,vals,**kw)
self.function_store(ids)
2015-02-04 05:13:10 +00:00
def pay_credit(self,ids,context={}):
obj=self.browse(ids)[0]
active_id=obj.id
action="clinic_shop"
2015-02-04 08:51:14 +00:00
if obj.hd_case_call:
2015-02-04 05:13:10 +00:00
active_id=obj.related_id.id
action="clinic_hd_case"
st=get_model("clinic.setting").browse(1)
if not st.shop_type_id:
raise Exception("Please defind Shop Type on menu Clinic Settings -> RD Shop")
if obj.number=="/":
obj.write({
'number': self._get_number(),
})
2015-02-04 08:51:14 +00:00
obj.make_invoices()
2015-02-04 05:13:10 +00:00
return {
'next': {
'name': action,
'mode': 'form',
'active_id': active_id,
},
'flash': 'Pay Successfully',
}
def pay_cash(self,ids,context={}):
2015-01-29 16:38:22 +00:00
obj=self.browse(ids)[0]
active_id=obj.id
action="clinic_shop"
2015-02-04 08:51:14 +00:00
if obj.hd_case_call:
2015-01-29 16:38:22 +00:00
active_id=obj.related_id.id
action="clinic_hd_case"
2015-02-04 05:13:10 +00:00
st=get_model("clinic.setting").browse(1)
if not st.shop_type_id:
raise Exception("Please defind Shop Type on menu Clinic Settings -> RD Shop")
if obj.number=="/":
obj.write({
2015-02-04 08:51:14 +00:00
'number': self._get_number(),
2015-02-04 05:13:10 +00:00
})
2015-02-04 08:51:14 +00:00
obj.make_payment()
2015-01-29 16:38:22 +00:00
return {
'next': {
'name': action,
'mode': 'form',
'active_id': active_id,
},
'flash': 'Pay Successfully',
}
2015-02-04 08:51:14 +00:00
def make_invoices(self,ids,context={}):
setting=get_model("settings").browse(1,context)
cst=get_model("clinic.setting").browse(1)
shop_type=cst.shop_type_id
currency_id=setting.currency_id.id
if not currency_id:
raise Exception("Currency not found in account settings")
company_id=get_active_company()
uom=get_model("uom").search_browse([['name','ilike','%Unit%']])
if not uom:
raise Exception("Unit not found in uom")
obj=self.browse(ids[0])
if obj.invoices:
for inv in obj.invoices:
inv.void()
due_date=obj.date[1:10] # XXX
context['type']='out'
context['inv_type']='invoice'
cst=get_model('clinic.setting').browse(1)
prod_acc=cst.get_product_account
partner=obj.contact_id
vals={
"type": "out",
"inv_type": "invoice",
"tax_type": "tax_in",
'due_date': due_date,
"ref": obj.number or "",
'department_id': obj.department_id.id,
"related_id": "clinic.shop,%s"%obj.id,
"currency_id": currency_id,
"company_id": company_id,
'partner_id': partner.id,
"lines": [],
}
for line in obj.lines:
if line.amount < 1:
continue
prod=line.product_id
acc=prod_acc(prod.id,shop_type.id,'credit')
account_id=acc.get("ar_credit_id",None)
ar_debit_id=acc.get("ar_debit_id",None)
if not account_id:
raise Exception("No Income Credit Account for product [%s] %s"%(prod.code, prod.name))
if not ar_debit_id:
raise Exception("No Ar Debit Account for product [%s] %s"%(prod.code, prod.name))
vals['lines'].append(('create',{
"product_id": prod.id,
"description": line.description or "",
"qty": line.qty,
"uom_id": line.uom_id.id,
"unit_price": line.price or 0,
"amount": line.amount or 0,
'account_id': account_id,
'ar_debit_id': ar_debit_id,
}))
inv_id=get_model("account.invoice").create(vals,context)
inv=get_model("account.invoice").browse(inv_id)
inv.post()
obj.make_pickings()
obj.write({
'state': 'paid',
'pay_type': 'credit',
})
def make_pickings(self,ids,context={}):
obj=self.browse(ids[0])
partner=obj.contact_id
# no picking
if not obj.lines:
return
ship_address_id=None
for address in partner.addresses:
if address.type=="shipping":
ship_address_id=address.id
break
if not ship_address_id:
raise Exception("No shipping address for contact %s"%partner.name)
# default journal
cust_loc_id=None
wh_loc_id=None
# find location
# 1. from department -> branch -> stock journal -> from, to
department=obj.department_id
if department:
stock_journal=department.pick_out_journal_id
if stock_journal:
wh_loc_id=stock_journal.location_from_id.id
cust_loc_id=stock_journal.location_to_id.id
pick_vals={
"type": "out",
'journal_id': stock_journal.id,
"ref": obj.number,
"related_id": "clinic.shop,%s"%obj.id,
"partner_id": partner.id,
"ship_address_id": ship_address_id,
"state": "draft",
"lines": [],
}
if not cust_loc_id:
res=get_model("stock.location").search([["type","=","customer"]])
if not res:
raise Exception("Customer location not found!")
cust_loc_id=res[0]
for line in obj.lines:
if line.qty < 1:
continue
prod=line.product_id
if prod.type != 'stock':
continue
if not wh_loc_id:
wh_loc_id=prod.location_id.id
if not wh_loc_id:
res=get_model("stock.location").search([["type","=","internal"]])
if not res:
raise Exception("Warehouse not found")
wh_loc_id=res[0]
line_vals={
"product_id": prod.id,
"qty": line.qty,
"uom_id": prod.uom_id.id,
"location_from_id": wh_loc_id,
"location_to_id": cust_loc_id,
}
pick_vals["lines"].append(("create",line_vals))
if not pick_vals["lines"]:
return {
"flash": "Nothing left to deliver",
}
picking_obj=get_model("stock.picking")
2015-03-17 14:37:18 +00:00
context={
'pick_type': 'out',
'journal_id': pick_vals['journal_id'],
}
pick_id=picking_obj.create(pick_vals,context=context)
2015-02-04 08:51:14 +00:00
pick=picking_obj.browse(pick_id)
pick.set_done([pick_id])
def make_payment(self,ids,context={}):
obj=self.browse(ids)[0]
partner=obj.contact_id
cst=get_model('clinic.setting').browse(1)
shop_type=cst.shop_type_id
cash_account_id=cst.cash_account_id.id
income_account_id=cst.income_account_id.id
if not cash_account_id:
raise Exception("No Cash Account")
if not income_account_id:
raise Exception("No Income Account")
company_id=get_active_company()
vals={
"partner_id": partner.id,
"company_id": company_id,
"type": "in",
"pay_type": "direct",
'date': time.strftime("%Y-%m-%d"),
"account_id": cash_account_id,
'related_id': "clinic.shop,%s"%obj.id,
'ref': obj.number,
'direct_lines': [],
}
prod_acc=cst.get_product_account
for line in obj.lines:
prod=line.product_id
acc=prod_acc(prod.id,shop_type.id,'cash')
account_id=acc.get("ar_credit_id",None)
ar_debit_id=acc.get("ar_debit_id",None)
if not account_id:
raise Exception("No Income Credit Account for product [%s] %s"%(prod.code, prod.name))
if not ar_debit_id:
raise Exception("No Ar Debit Account for product [%s] %s"%(prod.code, prod.name))
desc="[%s] %s"%(prod.code, line.description or "")
vals['direct_lines'].append(('create',{
"description": desc,
"qty": line.qty,
"unit_price": line.price or 0,
"amount": line.amount or 0,
'account_id': account_id,
}))
payment_id=get_model("account.payment").create(vals,context={"type":"in"})
payment=get_model('account.payment').browse(payment_id)
payment.post()
obj.make_pickings()
obj.write({
'state': 'paid',
'pay_type': 'cash',
})
def to_draft(self,ids,context={}):
for obj in self.browse(ids):
for payment in obj.payments:
payment.to_draft()
payment.delete()
for inv in obj.invoices:
inv.write({
'state': 'draft',
})
if inv.move_id:
inv.move_id.to_draft()
inv.move_id.delete()
inv.delete()
for picking in obj.pickings:
2015-03-17 09:01:51 +00:00
picking.to_draft(context=context)
2015-02-04 08:51:14 +00:00
picking.delete()
obj.write({
'state': 'draft',
})
if obj:
return {
'next': {
'name': {
'next': 'clinic_shop',
'mode': 'form',
'active_id': obj.id,
},
'flash': '%s has been set to draft'%obj.number or "",
}
}
def view_payment(self,ids,context={}):
return {
'next': {
'name': 'payment',
'mode': 'form',
'active_id': ids[0],
},
}
2015-03-04 04:54:55 +00:00
def get_page(self,context={}):
2015-02-12 08:52:35 +00:00
if not context.get('refer_id'):
return {}
shop_id=int(context['refer_id'])
shop=self.browse(shop_id)
comp_id=get_active_company()
comp=get_model('company').browse(comp_id)
st=get_model('settings').browse(1)
2015-02-27 03:48:57 +00:00
cst=get_model('clinic.setting').browse(1)
2015-02-12 08:52:35 +00:00
addresses=st.addresses
comp_addr=''
if addresses:
comp_addr=addresses[0].address_text
cust=shop.contact_id
cust_name=cust.name or ''
cust_addr=''
if cust.addresses:
cust_addr=cust.addresses[0].address_text
2015-03-11 03:52:45 +00:00
if 'your' in cust_addr:
cust_addr=''
2015-02-12 08:52:35 +00:00
if cust.walkin_cust:
cust_name=shop.ref or ''
no=1
sub_total=0
amount_total=0
lines=[]
for line in shop.lines:
amt=line.amount or 0
prod=line.product_id
lines.append({
'no': no,
'product_name': prod.name or '',
'description': line.description or '',
'uom_name': line.uom_id.name or '',
'qty': line.qty or 0,
'price': line.price or 0,
'amount': amt,
})
sub_total+=amt
no+=1
2015-02-13 07:46:39 +00:00
amount_total=sub_total #XXX
is_draft=shop.state=='draft' and True or False
is_cheque=False
pay_type=shop.pay_type or ''
2015-02-26 06:15:36 +00:00
user_id=get_active_user()
user=get_model("base.user").browse(user_id)
2015-03-13 07:43:57 +00:00
#XXX remove ,
index=0
for ca in comp_addr:
ca=ca.replace(" ","")
if ca==',':
break
index+=1
comp_addr=comp_addr[index+1:]
2015-02-12 08:52:35 +00:00
data={
'comp_name': comp.name or '',
'comp_addr': comp_addr or '',
2015-02-13 07:46:39 +00:00
'tax_no': st.tax_no or '',
2015-02-12 08:52:35 +00:00
'number': shop.number or '',
'ref': shop.ref,
'date': shop.date,
2015-03-13 07:43:57 +00:00
'datenow': shop.date or time.strftime("%d/%m/%Y"),
'dateprint': shop.date or time.strftime("%d/%m/%Y %H:%M:%S"),
2015-02-12 08:52:35 +00:00
'cust_name': cust_name,
'cust_addr': cust_addr,
2015-02-13 07:46:39 +00:00
'note': shop.note or '',
2015-02-12 08:52:35 +00:00
'lines':lines,
2015-02-13 07:46:39 +00:00
'amount_subtotal': sub_total,
2015-02-12 08:52:35 +00:00
'amount_total': amount_total,
2015-02-13 07:46:39 +00:00
'total_text': utils.num2word(amount_total),
'is_cheque': is_cheque,
'is_draft': is_draft,
2015-02-26 06:15:36 +00:00
'user_name': user.name or "",
2015-03-13 07:43:57 +00:00
'state': shop.state or "",
2015-02-12 08:52:35 +00:00
}
blank_dot=''
if pay_type=='cash':
data['pay_type']='Cash'
if shop.cheque_no:
data['is_cheque']=True
data['bank_name']=shop.bank_name or blank_dot
data['branch_name']=shop.branch_name or blank_dot
data['cheque_no']=shop.cheque_no or blank_dot
data['cheque_date']=shop.pay_date or blank_dot
else:
data['pay_type']='Credit'
2015-02-13 07:46:39 +00:00
if st.logo:
data['logo']=get_file_path(st.logo)
2015-02-27 03:48:57 +00:00
if cst.signature:
data['signature']=get_file_path(cst.signature)
2015-02-12 08:52:35 +00:00
return data
def get_data(self,ids,context={}):
settings=get_model('settings').browse(1)
pages=[]
for obj in get_model('clinic.shop').browse(ids):
context['refer_id']=obj.id
2015-03-04 04:54:55 +00:00
data=get_model('clinic.shop').get_page(context=context)
2015-03-11 03:52:45 +00:00
limit_item=15
2015-03-13 07:43:57 +00:00
if data['state']=='draft':
limit_item=10
2015-03-11 03:52:45 +00:00
for i in range(len(data['lines']),limit_item):
2015-03-11 01:44:02 +00:00
data['lines'].append({
'no': '',
'product_name': '',
'description': '',
'uom_name': '',
'qty': None,
'price': None,
'amount': None,
})
2015-02-12 08:52:35 +00:00
pages.append(data)
if pages:
pages[-1]["is_last_page"]=True
return {
"pages": pages,
"logo": get_file_path(settings.logo),
}
2015-02-13 07:46:39 +00:00
def pay(self,ids,context={}):
res={}
obj=self.browse(ids)[0]
if not obj.lines:
raise Exception("No item")
if obj.pay_type=='cash':
res=obj.pay_cash()
else:
res=obj.pay_credit()
return res
2015-02-12 08:52:35 +00:00
2015-01-23 10:28:08 +00:00
Shop.register()