订餐系统的主要功能便是用户下单部分,这里我们分为表头mylunch_order和表体mylunch_order_line两张主要的数据表,表头主要记录订单的一些通用信息,比如下单的操作人员 下单日期 订单状态 以及订单的总价;表体主要记录订餐人,订餐的供应商,餐名,单价等具体的信息。

class MyLunchOrder(osv.Model):

    _name = "mylunch.order"
_description = "MyLunch Order" def name_get(self, cr, uid, ids, context=None):
if not ids:
return []
res = []
for elmt in self.browse(cr, uid, ids, context=context):
name = _("MyLunch Order")
name = name + ' ' + str(elmt.id)
res.append((elmt.id, name)) return res def _alerts_get(self, cr, uid, ids, name, arg, context=None):
result = {}
alert_msg = self._default_alerts_get(cr, uid, context=context)
for order in self.browse(cr, uid, ids, context=context):
if order.state == 'new':
result[order.id] = alert_msg
return result def _default_alerts_get(self, cr, uid, context=None):
alert_ref = self.pool.get('mylunch.alert')
alert_ids = alert_ref.search(cr, uid, [], context=context)
alert_msg = [] for alert in alert_ref.browse(cr, uid, alert_ids, context=context):
alert_msg.append(alert.message) return '\n'.join(alert_msg) def _fetch_orders_from_lines(self, cr, uid, ids, name, context=None):
result = set()
for order_line in self.browse(cr, uid, ids, context=context):
if order_line.order_id:
result.add(order_line.order_id.id)
return list(result) def _price_get(self, cr, uid, ids, name, arg, context=None):
result = dict.fromkeys(ids, 0)
for order in self.browse(cr, uid, ids, context=context):
result[order.id] = sum(order_line.product_id.price
for order_line in order.order_line_ids)
return result _columns = {
'user_id': fields.many2one('res.users', 'Use Name', required=True, readonly=True, states={'new':[('readonly',False)]}),
'date': fields.date('Date', required=True, readonly=True, states={'new':[('readonly',False)]}),
'state': fields.selection([('new', 'New'),\
('confirmed', 'Confirmed'),\
('cancelled', 'Cancelled'),\
('partially', 'Partially Confirmed')],\
'Status', readonly=True, select=True, copy=False),
'alerts': fields.function(_alerts_get, string='Alerts', type='text'),
'order_line_ids': fields.one2many('mylunch.order.line', 'order_id', 'Products',
ondelete='cascade', readonly=True, states={'new': [('readonly', False)]}, copy=True),
'total': fields.function(_price_get, string='Total', store={
'mylunch.order.line': (_fetch_orders_from_lines, ['product_id', 'order_id'], 20)
}),
} _defaults = {
'user_id': lambda self, cr, uid, context: uid,
'date': fields.date.context_today,
'state': 'new',
'alerts': _default_alerts_get,
}

mylunch.order类这里主要有2个字段对应的功能相对复杂,alerts和total字段,alerts字段使用了function方法来获取我们之前设置的警告信息,

_alerts_get方法为每一个订单设置对应的警告信息,而这个警告信息是通过_default_alert_get方法获取数据库中所有的alert数据,并把这些数据合并成一条以“\n”分隔的字符串。

total字段用来计算所有表体价格的总和,也是一个函数计算得来,只不过这个数据会存储在数据库中。_price_get函数在数据存储的时候会调用,根据当前订单的id获取所有的表体明细,将所有明细的单价相加,得到订单总和。当UI界面订餐菜单和订单变化的时候,这里要及时修改这里的总价,就需要调用_fetch_orders_from_lines方法,注意这里的参数由于是mylunch.order.line,所以_fetch_orders_from_lines方法的参数self就是mylunch.order.line这个类,这样这个方法的功能是根据表体的id查询出其所属的订单表头id,确定目标对象。大概相当于

update mylunch_order set total = @totalPrice where id = @TargetId,这里确定了TargetId,那么@totalPrice价格是怎么计算出来的呢?貌似我们的类中没有体现出来这个计算过程,估计应该是框架帮我们完成了具体的计算工作,猜测的话应该会获取变化之后所有的product_id,然后计算出总和。具体过程不是很清楚,这里要深入研究框架的源代码了。

class MyLunchOrderLine(osv.Model):
_name = 'mylunch.order.line'
_description = 'My Lunch Order Line' def _get_line_order_ids(self, cr, uid, ids, context=None):
result = set()
for lunch_order in self.browse(cr, uid, ids, context):
for line in lunch_order.order_line_ids:
result.add(line.id)
return list(result) _columns = {
'name': fields.related('product_id', 'name', readonly=True),
'order_id': fields.many2one('mylunch.order', 'Order', ondelete='cascade'),
'product_id': fields.many2one('mylunch.production', 'Product', required=True),
'date': fields.related('order_id', 'date', type='date', string='Date', readonly=True,
store={
'mylunch.order': (_get_line_order_ids, ['date'], 10),
'mylunch.order.line': (lambda self, cr, uid, ids, context: ids, [], 10)
}),
'supplier_id': fields.related('product_id', 'supplier_id', type='many2one', relation='res.partner',
string='Supplier', readonly=True, store=True),
'user_id': fields.related('order_id', 'user_id', type='many2one', relation='res.users',
string='User', readonly=True, store=True),
'note': fields.text('Note'),
'price': fields.float('Price'),
'state': fields.selection([('new', 'New'),\
('confirmed', 'Confirmed'),\
('ordered', 'Ordered'),\
('cancelled', 'Cancelled')], 'Status', readonly=True, select=True),
'cashmove': fields.one2many('mylunch.cashmove', 'order_line_id', 'Cash Move', ondelete='cascade')
}

表体明细的话主要在date日期上,其值主要引用表头的日期date字段,有两种情况会造成该字段的变化更新,1.如果表头的日期date字段变化了,

就调用_get_line_order_ids方法,根据表头的id获取其下表体的所有id,确定更新目标条件,然后框架帮我们完成date日期的条件设置,达到字段的更新目的。2.如果表体的任何一条数据的任何字段在UI变化了,也会修改date字段,只不过这里使用了lambda匿名表达式。

class MyLunchCashmove(osv.Model):
_name = 'mylunch.cashmove'
_description = 'My Lunch CashMove'
_columns = {
'user_id': fields.many2one('res.users', 'User Name', required=True),
'date': fields.date('Date', required=True),
'amount': fields.float('Amount', required=True),
'description': fields.text('Description'),
'order_line_id': fields.many2one('mylunch.order.line', 'Order', ondelete='cascade'),
'state': fields.selection([('order', 'Order'), ('payment', 'Payment')], 'Is an order or a payment'),
} _defaults = {
'user_id': lambda self, cr, uid, context: uid,
'date': fields.date.context_today,
'state': 'payment'
}

菜单事件代码:

<act_window id="action_mylunch_order_form" name="MyOrder" res_model="mylunch.order" view_mode="tree,form"/>
<menuitem name="New Order" parent="menu_mylunch_title" id="menu_lunch_order_form" action="action_mylunch_order_form" sequence=""/>

列表视图布局:

        <record model="ir.ui.view" id="orders_tree_view">
<field name="name">Orders Tree View</field>
<field name="model">mylunch.order</field>
<field name="arch" type="xml">
<tree string="Orders Tree">
<field name="date"></field>
<field name="user_id"></field>
<field name="order_line_ids"></field>
<field name="state"></field>
<field name="total" sum="Total"></field>
</tree>
</field>
</record>

其中total字段的sum属性,会在列表的抵补显示总和是多少,大概效果如下图:

Form表单视图:

        <record model="ir.ui.view" id="orders_form_view">
<field name="name">myLunch Order Form</field>
<field name="model">mylunch.order</field>
<field name="arch" type="xml">
<form string="MyOrders Form" class="oe_mylunch">
<header>
<field name="state" widget="statusbar" statusbar_visible="new,confirmed"/>
</header>
<sheet>
<group>
<group>
<field name="user_id" context="{'default_groups_ref': ['base.group_user','base.group_partner_manager','mylunch.group_my_lunch_user']}"/>
</group>
<group>
<field name="date"/>
</group>
</group>
<field name="alerts" attrs="{'invisible':['|',('state','!=','new'),('alerts','=',False)]}" class="oe_inline oe_mylunch_alert"> </field>
<div name="preferences"> </div>
<separator string="Select your order"></separator>
<field name="order_line_ids" nolabel="">
<tree string="List" editable="bottom">
<field name="product_id"></field>
<field name="note"></field>
<field name="price"></field>
<field name="supplier_id" invisible=""></field>
<field name="state" invisible=""></field>
</tree>
</field>
<group class="oe_subtotal_footer oe_right">
<field name="total"></field>
</group>
<br/><br/>
</sheet>
</form>
</field>
</record>

这里嵌套了表体明细列表,这个视图很有代表性,充分体现了表头与表体明细的布局设计方式,我们还可以在此基础上进行相关的界面扩展,效果图如下:

权限设计:

id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
mylunch_order_manager,'MyLunch Order Manager group',model_mylunch_order,group_my_lunch_manager,1,1,1,1
mylunch_order_user,'MyLunch Order user group',model_mylunch_order,group_my_lunch_user,1,1,1,1
mylunch_order_line_manager,'MyLunch Order Line Manager',model_mylunch_order_line,group_my_lunch_manager,1,1,1,1
mylunch_order_line_user,'MyLunch Order Line user group',model_mylunch_order_line,group_my_lunch_user,1,1,1,1
mylunch_cashmove_manager,'MyLunch Cashmove Manager group',model_mylunch_cashmove,group_my_lunch_manager,1,1,1,1
mylunch_cashmove_user,'MyLunch Cashmove user group',model_mylunch_cashmove,group_my_lunch_user,1,0,0,0

odoo订餐系统之订单设计的更多相关文章

  1. odoo订餐系统之菜单设计

    1.model类的设计 class MyLunchProduction(osv.Model): _name = "mylunch.production" _description ...

  2. odoo订餐系统之类型设计

    这次开发的模块是订餐的类型设计,比如大荤 小荤 蔬菜 米饭 等基本数据.1.设计model类,很简单就一个字段: class MyLunchProductionCategory(osv.Model): ...

  3. odoo订餐系统之订单相关知识点理解

    1.对重载函数name_get的理解 第一,此函数位于Model基类中,返回值是一个list列表,列表中的每个值是如(key,value)形式的键值对,此处为(id,name). 第二,在自己的Mod ...

  4. odoo 订餐系统之消息提醒

    打算入手odoo开发新的系统,先研究下开发的过程是如何的.案例模仿自带的订餐系统,此系统模块不多,但很典型,可以达到联系的目的.先记录下订餐系统消息提醒的开发过程. 1.添加自己的addons目录my ...

  5. Python flask构建微信小程序订餐系统

    第1章 <Python Flask构建微信小程序订餐系统>课程简介 本章内容会带领大家通览整体架构,功能模块,及学习建议.让大家在一个清晰的开发思路下,进行后续的学习.同时领着大家登陆ht ...

  6. 终于等到你---订餐系统之负载均衡(nginx+memcached+ftp上传图片+iis)

    又见毕业 对面工商大学的毕业生叕在拍毕业照了,一个个脸上都挂满了笑容,也许是满意自己四年的修行,也许是期待步入繁华的社会... 恰逢其时的连绵细雨与满天柳絮,似乎也是在映衬他们心中那些离别的忧伤,与对 ...

  7. 订餐系统之微信支付,踩了官方demo的坑

        最近一个项目要增加微信支付的功能,想来这个东西出来这么久了,按微信提供的应该可以很快搞定的,结果提供的demo( JS API网页支付)中各种坑,咨询他们的客服,态度倒是非常好,就是解决不了问 ...

  8. Java开源生鲜电商平台-财务系统模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-财务系统模块的设计与架构(源码可下载) 前言:任何一个平台也好,系统也好,挣钱养活团队这个是无可厚非的,那么对于一个生鲜B2B平台盈利模式( 查看:http://www.cn ...

  9. Python flask构建微信小程序订餐系统☝☝☝

    Python flask构建微信小程序订餐系统☝☝☝ 一.Flask MVC框架结构 1.1实际项目结构 1.2application.py  项目配置文件 Flask之flask-script模块使 ...

随机推荐

  1. 如何打jar包

    一.制作只含有字节码文件的jar包1.最简单的jar包——直接输出hello2.含有两个类的jar包——通过调用输出hello3.有目录结构的jar包——通过引包并调用输出hello 二.制作含有ja ...

  2. SpringCloud+Feign环境下文件上传与form-data同时存在的解决办法(2)

    书接上文. 上文中描述了如何在 SpringCloud+Feign环境下上传文件与form-data同时存在的解决办法,实践证明基本可行,但却会引入其他问题. 主要导致的后果是: 1. 无法与普通Fe ...

  3. 关于excel中的查找

    弹出查找界面后,点击“选项”按钮 在范围下拉框中选择: 1.工作表:表示在当前表sheet中进行查找 2.工作簿:表示在此excel整个文件中进行查找

  4. [MapReduce_add_3] MapReduce 通过分区解决数据倾斜

    0. 说明 数据倾斜及解决方法的介绍与代码实现 1. 介绍 [1.1 数据倾斜的含义] 大量数据发送到同一个节点进行处理,造成此节点繁忙甚至瘫痪,而其他节点资源空闲 [1.2 解决数据倾斜的方式] 重 ...

  5. sql server2014企业版无人值守批处理脚本自动化安装

    ▲版权声明:本文为博主原创文章,未经博主允许不得转载. SQL Server系列软件是Microsoft 公司推出的关系型数据库管理系统.2014年4月16日于旧金山召开的一场发布会上,微软CEO萨蒂 ...

  6. Linux远程访问及控制(SSH)

    1.ssh协议:用于远程登录,端口号:22/tcp 配置文件: 1)服务器端口:/etc/ssh/sshd_config 2)客户端 :/etc/ssh/ssh_config 2.服务器监听选项: U ...

  7. Ubuntu 16.04 LTS 降级安装GCC 4.8

    转载自https://www.linuxidc.com/Linux/2017-03/142299.htm Ubuntu 16.04 LTS 降级安装GCC 4.8 [日期:2017-03-28] 来源 ...

  8. 简单Nginx下防跨站、跨目录安全设置,支持PHP 5.3.3以上版本

    Nginx下存在跨站和跨目录的问题,跨站和跨目录影响同服务器/VPS上的其他网站. PHP在5.3.3以上已经增加了HOST配置,可以起到防跨站.跨目录的问题. 如果你是PHP 5.3.3以上的版本, ...

  9. oracle中nvarchar2字符集不匹配

    oracle当多表union时遇到nvarchar2类型时报错 字符集不匹配对使用nvarchar的地方,加上 to_char( nvarchar 的变量或字段 ) 如:select to_char( ...

  10. 使用hint优化Oracle的运行计划 以及 SQL Tune Advisor的使用

    背景: 某表忽然出现查询很缓慢的情况.cost 100+ 秒以上:严重影响生产. 原SQL: explain plan for select * from ( select ID id,RET_NO ...