[MERGE] from upstream

bzr revid: fva@openerp.com-20130805120523-ux0vnixhbe59pvrf
bzr revid: fva@openerp.com-20130805123836-1vhj1e5mb0ejiu9j
This commit is contained in:
Frédéric van der Essen 2013-08-05 14:38:36 +02:00
commit c7ae298ad5
48 changed files with 1415 additions and 930 deletions

View File

@ -8,19 +8,19 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
"PO-Revision-Date: 2012-04-13 22:35+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"PO-Revision-Date: 2013-07-30 22:25+0000\n"
"Last-Translator: Masaki Yamaya <Unknown>\n"
"Language-Team: Japanese <ja@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-03-16 05:47+0000\n"
"X-Generator: Launchpad (build 16532)\n"
"X-Launchpad-Export-Date: 2013-07-31 05:16+0000\n"
"X-Generator: Launchpad (build 16718)\n"
#. module: account_accountant
#: model:ir.actions.client,name:account_accountant.action_client_account_menu
msgid "Open Accounting Menu"
msgstr ""
msgstr "会計メニューを開く"
#~ msgid ""
#~ "\n"

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2012-12-21 17:05+0000\n"
"PO-Revision-Date: 2012-06-13 17:16+0000\n"
"Last-Translator: Akira Hiyama <Unknown>\n"
"PO-Revision-Date: 2013-07-30 22:29+0000\n"
"Last-Translator: Masaki Yamaya <Unknown>\n"
"Language-Team: Japanese <ja@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-03-16 05:34+0000\n"
"X-Generator: Launchpad (build 16532)\n"
"X-Launchpad-Export-Date: 2013-07-31 05:16+0000\n"
"X-Generator: Launchpad (build 16718)\n"
#. module: account_budget
#: view:account.budget.analytic:0
@ -418,7 +418,7 @@ msgstr "からの分析"
#. module: account_budget
#: view:crossovered.budget:0
msgid "Draft Budgets"
msgstr "ドラフト予算"
msgstr "予算"
#, python-format
#~ msgid "The General Budget '%s' has no Accounts!"

View File

@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
"PO-Revision-Date: 2013-04-24 06:41+0000\n"
"Last-Translator: viney <Unknown>\n"
"PO-Revision-Date: 2013-07-26 07:07+0000\n"
"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-04-25 05:20+0000\n"
"X-Generator: Launchpad (build 16580)\n"
"X-Launchpad-Export-Date: 2013-07-27 05:02+0000\n"
"X-Generator: Launchpad (build 16700)\n"
#. module: point_of_sale
#: field:report.transaction.pos,product_nb:0
@ -51,7 +51,7 @@ msgstr "打印销售订单的收据"
#. module: point_of_sale
#: field:pos.session,cash_register_balance_end:0
msgid "Computed Balance"
msgstr ""
msgstr "计算余额"
#. module: point_of_sale
#: view:pos.session:0
@ -62,7 +62,7 @@ msgstr "今天"
#. module: point_of_sale
#: field:pos.config,iface_electronic_scale:0
msgid "Electronic Scale Interface"
msgstr ""
msgstr "电子称接口"
#. module: point_of_sale
#: model:pos.category,name:point_of_sale.plain_water
@ -85,7 +85,7 @@ msgstr ""
#: field:pos.config,journal_id:0
#: field:pos.order,sale_journal:0
msgid "Sale Journal"
msgstr ""
msgstr "销售日记账"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.spa_2l_product_template
@ -102,7 +102,7 @@ msgstr "销售详情"
#. module: point_of_sale
#: constraint:pos.config:0
msgid "You cannot have two cash controls in one Point Of Sale !"
msgstr ""
msgstr "同一个销售点不能使用两个钱箱"
#. module: point_of_sale
#: field:pos.payment.report.user,user_id:0
@ -111,7 +111,7 @@ msgstr ""
#: view:report.pos.order:0
#: field:report.pos.order,user_id:0
msgid "Salesperson"
msgstr ""
msgstr "销售员"
#. module: point_of_sale
#: view:report.pos.order:0
@ -128,13 +128,13 @@ msgstr "产品名称"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.pamplemousse_rouge_pamplemousse_product_template
msgid "Red grapefruit"
msgstr ""
msgstr "红葡萄柚"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:1343
#: code:addons/point_of_sale/point_of_sale.py:1373
#, python-format
msgid "Assign a Custom EAN"
msgstr ""
msgstr "使用自定义的条码"
#. module: point_of_sale
#: view:pos.session.opening:0
@ -164,12 +164,12 @@ msgstr "取钱"
#: code:addons/point_of_sale/point_of_sale.py:105
#, python-format
msgid "not used"
msgstr ""
msgstr "未被使用"
#. module: point_of_sale
#: field:pos.config,iface_vkeyboard:0
msgid "Virtual KeyBoard Interface"
msgstr ""
msgstr "虚拟键盘接口"
#. module: point_of_sale
#. openerp-web
@ -181,11 +181,11 @@ msgstr "+/-"
#. module: point_of_sale
#: field:pos.ean_wizard,ean13_pattern:0
msgid "Reference"
msgstr ""
msgstr "单号"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:1041
#: code:addons/point_of_sale/point_of_sale.py:1057
#: code:addons/point_of_sale/point_of_sale.py:1066
#: code:addons/point_of_sale/point_of_sale.py:1083
#: report:pos.invoice:0
#: report:pos.lines:0
#, python-format
@ -200,32 +200,32 @@ msgstr "开始日期"
#. module: point_of_sale
#: constraint:pos.session:0
msgid "You cannot create two active sessions with the same responsible!"
msgstr ""
msgstr "同一个负责人不能创建两个活动销售会话"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:473
#, python-format
msgid "Weighting"
msgstr ""
msgstr "称重"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.fenouil_fenouil_product_template
msgid "Fennel"
msgstr ""
msgstr "小茴香"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:472
#, python-format
msgid "Help needed"
msgstr ""
msgstr "需要帮助"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:739
#: code:addons/point_of_sale/point_of_sale.py:760
#, python-format
msgid "Configuration Error!"
msgstr ""
msgstr "设置错误!"
#. module: point_of_sale
#: report:account.statement:0
@ -237,7 +237,7 @@ msgstr "业务伙伴"
#. module: point_of_sale
#: view:pos.session:0
msgid "Closing Cash Control"
msgstr ""
msgstr "关闭现金箱"
#. module: point_of_sale
#: report:pos.details:0
@ -259,7 +259,7 @@ msgstr "会计信息"
#. module: point_of_sale
#: field:pos.session.opening,show_config:0
msgid "Show Config"
msgstr ""
msgstr "显示配置"
#. module: point_of_sale
#: report:pos.lines:0
@ -277,7 +277,7 @@ msgstr "折扣合计"
#: code:addons/point_of_sale/static/src/xml/pos.xml:441
#, python-format
msgid "Debug Window"
msgstr ""
msgstr "调试窗口"
#. module: point_of_sale
#. openerp-web
@ -315,10 +315,10 @@ msgid "Disc.(%)"
msgstr "折扣(%)"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:1006
#: code:addons/point_of_sale/point_of_sale.py:1031
#, python-format
msgid "Please define income account for this product: \"%s\" (id:%d)."
msgstr ""
msgstr "请为这个产品定义收益科目:\"%s\" (id:%d)."
#. module: point_of_sale
#: view:report.pos.order:0
@ -336,7 +336,7 @@ msgstr "Leffe Brune 33cl"
msgid ""
"Check this if this point of sale should open by default in a self checkout "
"mode. If unchecked, OpenERP uses the normal cashier mode by default."
msgstr ""
msgstr "如果需要把自助收银作为默认模式,请选中这里。 如果未选, OpenERP 将使用普通收银员作为默认模式。"
#. module: point_of_sale
#: model:ir.actions.report.xml,name:point_of_sale.pos_sales_user
@ -353,7 +353,7 @@ msgstr "饮料类"
#: model:ir.actions.act_window,name:point_of_sale.action_pos_session_opening
#: model:ir.ui.menu,name:point_of_sale.menu_pos_session_opening
msgid "Your Session"
msgstr ""
msgstr "您的销售会话"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.stella_50cl_product_template
@ -375,12 +375,12 @@ msgstr "上级类别"
#: code:addons/point_of_sale/static/src/xml/pos.xml:482
#, python-format
msgid "Open Cashbox"
msgstr ""
msgstr "打开钱箱"
#. module: point_of_sale
#: view:pos.session.opening:0
msgid "Select your Point of Sale"
msgstr ""
msgstr "选择您的销售点"
#. module: point_of_sale
#: field:report.sales.by.margin.pos,total:0
@ -404,25 +404,25 @@ msgstr "Dr. Oetker Ristorante Speciale"
#: code:addons/point_of_sale/static/src/xml/pos.xml:480
#, python-format
msgid "Payment Request"
msgstr ""
msgstr "付款请求"
#. module: point_of_sale
#: field:product.product,to_weight:0
msgid "To Weight"
msgstr ""
msgstr "需要称重"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:476
#, python-format
msgid "Hardware Events"
msgstr ""
msgstr "硬件事件"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:301
#, python-format
msgid "You should assign a Point of Sale to your session."
msgstr ""
msgstr "您需要为您的销售会话指定一个销售点"
#. module: point_of_sale
#: view:pos.order.line:0
@ -435,7 +435,7 @@ msgid "Fanta Orange 33cl"
msgstr "Fanta Orange 33cl"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:420
#: code:addons/point_of_sale/point_of_sale.py:423
#, python-format
msgid ""
"Please set your profit and loss accounts on your payment method '%s'. This "
@ -446,10 +446,10 @@ msgstr ""
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:315
#: code:addons/point_of_sale/point_of_sale.py:512
#: code:addons/point_of_sale/point_of_sale.py:514
#, python-format
msgid "error!"
msgstr ""
msgstr "错误!"
#. module: point_of_sale
#: model:ir.actions.act_window,name:point_of_sale.action_report_sales_by_user_pos_month
@ -471,12 +471,12 @@ msgstr ""
#. module: point_of_sale
#: model:product.template,name:point_of_sale.Onions_product_template
msgid "Onions"
msgstr ""
msgstr "洋葱"
#. module: point_of_sale
#: view:pos.session:0
msgid "Validate & Open Session"
msgstr ""
msgstr "验证并打开销售会话"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:99
@ -484,18 +484,18 @@ msgstr ""
#: selection:pos.session.opening,pos_state:0
#, python-format
msgid "In Progress"
msgstr ""
msgstr "进行中"
#. module: point_of_sale
#: view:pos.session:0
#: field:pos.session,opening_details_ids:0
msgid "Opening Cash Control"
msgstr ""
msgstr "正在打开钱箱"
#. module: point_of_sale
#: help:res.users,ean13:0
msgid "BarCode"
msgstr ""
msgstr "条码"
#. module: point_of_sale
#: help:pos.category,image_medium:0
@ -508,19 +508,19 @@ msgstr ""
#. module: point_of_sale
#: view:pos.session.opening:0
msgid "Open Session"
msgstr ""
msgstr "打开销售会话"
#. module: point_of_sale
#: model:ir.ui.menu,name:point_of_sale.menu_point_of_sale
msgid "Daily Operations"
msgstr "每天经营"
msgstr "日常经营"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:42
#, python-format
msgid "Google Chrome"
msgstr ""
msgstr "Google Chrome"
#. module: point_of_sale
#: model:pos.category,name:point_of_sale.sparkling_water
@ -543,7 +543,7 @@ msgstr "查询现金对账单"
#: field:pos.session.opening,pos_state_str:0
#: field:report.pos.order,state:0
msgid "Status"
msgstr ""
msgstr "状态"
#. module: point_of_sale
#: selection:report.pos.order,month:0
@ -568,14 +568,14 @@ msgstr "POS单明细"
#. module: point_of_sale
#: view:pos.config:0
msgid "Point of Sale Configuration"
msgstr ""
msgstr "销售点配置"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:359
#, python-format
msgid "Your order has to be validated by a cashier."
msgstr ""
msgstr "您的订单已被收银员确认"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.fanta_orange_50cl_product_template
@ -609,7 +609,7 @@ msgid ""
msgstr ""
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:867
#: code:addons/point_of_sale/point_of_sale.py:888
#, python-format
msgid "Customer Invoice"
msgstr "客户发票"
@ -619,7 +619,7 @@ msgstr "客户发票"
msgid ""
"You can continue sales from the touchscreen interface by clicking on \"Start "
"Selling\" or close the cash register session."
msgstr ""
msgstr "通过触摸屏幕的“开始销售”或者关闭钱箱之后您就可以继续进行销售。"
#. module: point_of_sale
#: report:account.statement:0
@ -631,7 +631,7 @@ msgstr "结束日期"
#. module: point_of_sale
#: view:pos.session:0
msgid "Opening Cashbox Lines"
msgstr ""
msgstr "正在打开钱箱"
#. module: point_of_sale
#: selection:report.pos.order,month:0
@ -678,7 +678,7 @@ msgstr "行号"
#: code:addons/point_of_sale/static/src/xml/pos.xml:453
#, python-format
msgid "Set Weight"
msgstr ""
msgstr "设置重量"
#. module: point_of_sale
#: view:account.bank.statement:0
@ -693,7 +693,7 @@ msgstr "净合计:"
#. module: point_of_sale
#: model:ir.actions.client,name:point_of_sale.action_client_pos_menu
msgid "Open POS Menu"
msgstr ""
msgstr "打开销售点菜单"
#. module: point_of_sale
#: report:pos.details_summary:0
@ -710,12 +710,12 @@ msgstr "发表POS机日记帐分录"
#: code:addons/point_of_sale/static/src/xml/pos.xml:457
#, python-format
msgid "Barcode Scanner"
msgstr ""
msgstr "条码扫描器"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.pomme_granny_smith_product_template
msgid "Granny Smith apples"
msgstr ""
msgstr "Granny Smith 苹果"
#. module: point_of_sale
#: help:product.product,expense_pdt:0
@ -743,7 +743,7 @@ msgstr ""
#. module: point_of_sale
#: view:pos.session.opening:0
msgid "Click to start a session."
msgstr ""
msgstr "单击开始销售会话"
#. module: point_of_sale
#: view:pos.details:0
@ -778,7 +778,7 @@ msgstr "新增产品"
#. module: point_of_sale
#: field:pos.config,name:0
msgid "Point of Sale Name"
msgstr ""
msgstr "销售点名称"
#. module: point_of_sale
#: field:report.transaction.pos,invoice_am:0
@ -825,7 +825,7 @@ msgstr "期末结余"
#: code:addons/point_of_sale/wizard/pos_box_out.py:89
#, python-format
msgid "please check that account is set to %s."
msgstr ""
msgstr "请检查该科目已经设为为:%s"
#. module: point_of_sale
#: help:pos.category,image:0
@ -863,7 +863,7 @@ msgstr ""
#. module: point_of_sale
#: view:pos.ean_wizard:0
msgid "Ean13 Generator"
msgstr ""
msgstr "条码生成器"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.spa_1l_product_template
@ -879,7 +879,7 @@ msgstr "错误无效的EAN编码"
#. module: point_of_sale
#: model:pos.category,name:point_of_sale.legumes_racine
msgid "Root vegetables"
msgstr ""
msgstr "根类蔬菜"
#. module: point_of_sale
#: model:ir.actions.act_window,name:point_of_sale.act_pos_open_statement
@ -939,7 +939,7 @@ msgstr ""
#. module: point_of_sale
#: view:res.users:0
msgid "Edit EAN"
msgstr ""
msgstr "编辑条码"
#. module: point_of_sale
#: code:addons/point_of_sale/wizard/pos_open_statement.py:80
@ -965,7 +965,7 @@ msgstr ""
#. module: point_of_sale
#: field:pos.session.opening,pos_session_id:0
msgid "PoS Session"
msgstr ""
msgstr "销售点会话"
#. module: point_of_sale
#: selection:report.pos.order,month:0
@ -979,7 +979,7 @@ msgid "User's Product"
msgstr "用户的产品"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:1143
#: code:addons/point_of_sale/point_of_sale.py:1173
#, python-format
msgid ""
"You have to select a pricelist in the sale form !\n"
@ -1011,7 +1011,7 @@ msgstr "增加一个全局折扣"
#. module: point_of_sale
#: view:pos.config:0
msgid "Journals"
msgstr ""
msgstr "日记账"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.oetker_prosciutto_product_template
@ -1031,7 +1031,7 @@ msgstr "Coca-Cola Light Lemon 50cl"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/point_of_sale.py:518
#: code:addons/point_of_sale/point_of_sale.py:520
#: code:addons/point_of_sale/static/src/xml/pos.xml:689
#: code:addons/point_of_sale/static/src/xml/pos.xml:744
#, python-format
@ -1041,7 +1041,7 @@ msgstr ""
#. module: point_of_sale
#: view:product.product:0
msgid "Set a Custom EAN"
msgstr ""
msgstr "设置自定义条码"
#. module: point_of_sale
#. openerp-web
@ -1053,7 +1053,7 @@ msgstr ""
#. module: point_of_sale
#: model:pos.category,name:point_of_sale.legumes
msgid "Fresh vegetables"
msgstr ""
msgstr "新鲜蔬菜"
#. module: point_of_sale
#: view:pos.session:0
@ -1065,7 +1065,7 @@ msgstr ""
#: code:addons/point_of_sale/static/src/xml/pos.xml:478
#, python-format
msgid "Scan Item Success"
msgstr ""
msgstr "扫描条目成功"
#. module: point_of_sale
#: report:account.statement:0
@ -1082,17 +1082,17 @@ msgstr ""
#. module: point_of_sale
#: sql_constraint:pos.session:0
msgid "The name of this POS Session must be unique !"
msgstr ""
msgstr "销售会话名称必须唯一"
#. module: point_of_sale
#: view:pos.session:0
msgid "Opening Subtotal"
msgstr ""
msgstr "小计"
#. module: point_of_sale
#: view:pos.session:0
msgid "payment method."
msgstr ""
msgstr "付款方式"
#. module: point_of_sale
#: view:pos.order:0
@ -1137,7 +1137,7 @@ msgstr "折扣"
#. module: point_of_sale
#: view:pos.order:0
msgid "(update)"
msgstr ""
msgstr "(更新)"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.ijsboerke_vanille_2,5l_product_template
@ -1153,12 +1153,12 @@ msgstr "销售详情"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.evian_2l_product_template
msgid "2L Evian"
msgstr ""
msgstr "2L 依云"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:373
#: code:addons/point_of_sale/point_of_sale.py:472
#: code:addons/point_of_sale/wizard/pos_session_opening.py:34
#: code:addons/point_of_sale/point_of_sale.py:474
#: code:addons/point_of_sale/wizard/pos_session_opening.py:33
#, python-format
msgid "Start Point Of Sale"
msgstr ""
@ -1215,14 +1215,14 @@ msgstr "Chaudfontaine Petillante 50cl"
#: code:addons/point_of_sale/static/src/xml/pos.xml:485
#, python-format
msgid "Read Weighting Scale"
msgstr ""
msgstr "读取电子秤"
#. module: point_of_sale
#. openerp-web
#: code:addons/point_of_sale/static/src/xml/pos.xml:426
#, python-format
msgid "0.00 €"
msgstr ""
msgstr "0.00 €"
#. module: point_of_sale
#: field:pos.order.line,create_date:0
@ -1240,7 +1240,7 @@ msgstr "今天的销售情况"
#: code:addons/point_of_sale/static/src/xml/pos.xml:324
#, python-format
msgid "Welcome"
msgstr ""
msgstr "欢迎"
#. module: point_of_sale
#: code:addons/point_of_sale/wizard/pos_box_entries.py:46
@ -1295,7 +1295,7 @@ msgstr "已开票合计"
#: model:ir.model,name:point_of_sale.model_pos_category
#: field:product.product,pos_categ_id:0
msgid "Point of Sale Category"
msgstr ""
msgstr "销售点商品分类"
#. module: point_of_sale
#: view:report.pos.order:0
@ -1315,7 +1315,7 @@ msgstr ""
#: code:addons/point_of_sale/static/src/xml/pos.xml:324
#, python-format
msgid "Choose your type of receipt:"
msgstr ""
msgstr "选择小票类型"
#. module: point_of_sale
#: model:ir.model,name:point_of_sale.model_report_sales_by_margin_pos_month
@ -1352,7 +1352,7 @@ msgstr ""
#: code:addons/point_of_sale/static/src/xml/pos.xml:479
#, python-format
msgid "Scan Item Unrecognized"
msgstr ""
msgstr "未能识别扫描的条目"
#. module: point_of_sale
#: report:all.closed.cashbox.of.the.day:0
@ -1360,7 +1360,7 @@ msgid "Today's Closed Cashbox"
msgstr "今日关闭的钱箱"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:897
#: code:addons/point_of_sale/point_of_sale.py:920
#, python-format
msgid "Selected orders do not have the same session!"
msgstr ""
@ -1396,7 +1396,7 @@ msgstr "开启日期"
#: model:ir.actions.act_window,name:point_of_sale.action_pos_session
#: model:ir.ui.menu,name:point_of_sale.menu_pos_session_all
msgid "All Sessions"
msgstr ""
msgstr "全部销售会话"
#. module: point_of_sale
#. openerp-web
@ -1415,7 +1415,7 @@ msgstr "税:"
#: code:addons/point_of_sale/static/src/xml/pos.xml:271
#, python-format
msgid "Thank you for shopping with us."
msgstr ""
msgstr "感谢您的光临。"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.coca_light_2l_product_template
@ -1431,7 +1431,7 @@ msgstr "Dr. Oetker Ristorante Funghi"
#: model:ir.actions.act_window,name:point_of_sale.pos_category_action
#: model:ir.ui.menu,name:point_of_sale.menu_pos_category
msgid "Product Categories"
msgstr ""
msgstr "商品类别"
#. module: point_of_sale
#: help:pos.config,journal_id:0
@ -1448,7 +1448,7 @@ msgstr "折扣"
#: code:addons/point_of_sale/static/src/xml/pos.xml:467
#, python-format
msgid "Invalid Ean"
msgstr ""
msgstr "无效的条码"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.lindemans_kriek_37,5cl_product_template
@ -1458,7 +1458,7 @@ msgstr "Lindemans Kriek 37.5cl"
#. module: point_of_sale
#: view:pos.config:0
msgid "Point of Sale Config"
msgstr ""
msgstr "销售点配置"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.coca_zero_33cl_product_template
@ -1511,7 +1511,7 @@ msgstr "税:"
#. module: point_of_sale
#: view:pos.session:0
msgid "+ Transactions"
msgstr ""
msgstr "+ 交易"
#. module: point_of_sale
#: model:ir.actions.act_window,name:point_of_sale.action_pos_discount
@ -1541,12 +1541,12 @@ msgstr "用户"
#: code:addons/point_of_sale/static/src/xml/pos.xml:194
#, python-format
msgid "Kg"
msgstr ""
msgstr "千克"
#. module: point_of_sale
#: field:product.product,available_in_pos:0
msgid "Available in the Point of Sale"
msgstr ""
msgstr "可在销售点销售"
#. module: point_of_sale
#: selection:pos.config,state:0
@ -1563,7 +1563,7 @@ msgstr ""
#: code:addons/point_of_sale/static/src/xml/pos.xml:338
#, python-format
msgid "The scanned product was not recognized"
msgstr ""
msgstr "无法识别扫描的商品"
#. module: point_of_sale
#: model:ir.model,name:point_of_sale.model_report_transaction_pos
@ -1613,7 +1613,7 @@ msgstr "11月"
#: code:addons/point_of_sale/static/src/xml/pos.xml:267
#, python-format
msgid "Please scan an item or your member card"
msgstr ""
msgstr "请扫描商品或您的会员卡"
#. module: point_of_sale
#: model:product.template,name:point_of_sale.poivron_verts_product_template
@ -1644,7 +1644,7 @@ msgid "Number of Transaction"
msgstr "交易数"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:738
#: code:addons/point_of_sale/point_of_sale.py:759
#, python-format
msgid ""
"There is no receivable account defined to make payment for the partner: "
@ -1655,7 +1655,7 @@ msgstr ""
#: view:pos.config:0
#: selection:pos.config,state:0
msgid "Inactive"
msgstr ""
msgstr "不活跃的"
#. module: point_of_sale
#. openerp-web
@ -1679,7 +1679,7 @@ msgstr "取消"
#: code:addons/point_of_sale/static/src/xml/pos.xml:296
#, python-format
msgid "Please put your product on the scale"
msgstr ""
msgstr "请将商品放到称上"
#. module: point_of_sale
#: model:ir.actions.report.xml,name:point_of_sale.pos_details_summary
@ -1699,7 +1699,7 @@ msgstr "Timmermans Kriek 37.5cl"
#. module: point_of_sale
#: field:pos.config,sequence_id:0
msgid "Order IDs Sequence"
msgstr ""
msgstr "订单号序列"
#. module: point_of_sale
#: report:pos.invoice:0
@ -1815,7 +1815,7 @@ msgid "Difference"
msgstr ""
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:529
#: code:addons/point_of_sale/point_of_sale.py:549
#, python-format
msgid "Unable to Delete !"
msgstr "不能删除!"
@ -1978,7 +1978,7 @@ msgid "Salespeople"
msgstr ""
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:756
#: code:addons/point_of_sale/point_of_sale.py:777
#: code:addons/point_of_sale/wizard/pos_box_entries.py:118
#: code:addons/point_of_sale/wizard/pos_box_out.py:91
#, python-format
@ -1986,7 +1986,7 @@ msgid "You have to open at least one cashbox."
msgstr ""
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:1142
#: code:addons/point_of_sale/point_of_sale.py:1172
#, python-format
msgid "No Pricelist !"
msgstr "没有价格表!"
@ -2038,7 +2038,7 @@ msgid "No Cash Register Defined !"
msgstr "没有定义收银机"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:513
#: code:addons/point_of_sale/point_of_sale.py:515
#, python-format
msgid ""
"No cash statement found for this session. Unable to record returned cash."
@ -2761,7 +2761,7 @@ msgid "Pos Lines"
msgstr "销售单明细"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:413
#: code:addons/point_of_sale/point_of_sale.py:416
#, python-format
msgid "Point of Sale Profit"
msgstr ""
@ -2774,7 +2774,7 @@ msgid "Please wait, a cashier is on the way"
msgstr ""
#. module: point_of_sale
#: code:addons/point_of_sale/wizard/pos_session_opening.py:68
#: code:addons/point_of_sale/wizard/pos_session_opening.py:67
#: field:pos.box.entries,session_id:0
#: view:pos.order:0
#: field:pos.order,session_id:0
@ -3085,15 +3085,17 @@ msgstr ""
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:300
#: code:addons/point_of_sale/point_of_sale.py:409
#: code:addons/point_of_sale/point_of_sale.py:419
#: code:addons/point_of_sale/point_of_sale.py:457
#: code:addons/point_of_sale/point_of_sale.py:712
#: code:addons/point_of_sale/point_of_sale.py:756
#: code:addons/point_of_sale/point_of_sale.py:818
#: code:addons/point_of_sale/point_of_sale.py:897
#: code:addons/point_of_sale/point_of_sale.py:1006
#: code:addons/point_of_sale/point_of_sale.py:412
#: code:addons/point_of_sale/point_of_sale.py:422
#: code:addons/point_of_sale/point_of_sale.py:459
#: code:addons/point_of_sale/point_of_sale.py:536
#: code:addons/point_of_sale/point_of_sale.py:733
#: code:addons/point_of_sale/point_of_sale.py:777
#: code:addons/point_of_sale/point_of_sale.py:839
#: code:addons/point_of_sale/point_of_sale.py:920
#: code:addons/point_of_sale/point_of_sale.py:1031
#: code:addons/point_of_sale/report/pos_invoice.py:46
#: code:addons/point_of_sale/wizard/pos_box.py:23
#: code:addons/point_of_sale/wizard/pos_box.py:22
#: code:addons/point_of_sale/wizard/pos_box_entries.py:46
#: code:addons/point_of_sale/wizard/pos_box_entries.py:118
#: code:addons/point_of_sale/wizard/pos_box_entries.py:123
@ -3187,13 +3189,13 @@ msgid "Chaudfontaine 1.5l"
msgstr "Chaudfontaine 1.5l"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:1069
#: code:addons/point_of_sale/point_of_sale.py:1096
#, python-format
msgid "Trade Receivables"
msgstr ""
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:529
#: code:addons/point_of_sale/point_of_sale.py:549
#, python-format
msgid "In order to delete a sale, it must be new or cancelled."
msgstr "只有新的或被取消的销售流水可以删除"
@ -3228,7 +3230,7 @@ msgid "Journal Entry"
msgstr "日记账簿"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:736
#: code:addons/point_of_sale/point_of_sale.py:757
#, python-format
msgid "There is no receivable account defined to make payment."
msgstr ""
@ -3259,7 +3261,7 @@ msgid "Supplier Invoice"
msgstr "供应商发票"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:458
#: code:addons/point_of_sale/point_of_sale.py:460
#, python-format
msgid ""
"You cannot confirm all orders of this session, because they have not the "
@ -3338,7 +3340,7 @@ msgid "Coca-Cola Regular 1L"
msgstr "Coca-Cola Regular 1L"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:712
#: code:addons/point_of_sale/point_of_sale.py:733
#, python-format
msgid "Unable to cancel the picking."
msgstr "无法取消发货"
@ -3379,7 +3381,7 @@ msgid "Spa Barisart 1.5l"
msgstr "Spa Barisart 1.5l"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:789
#: code:addons/point_of_sale/point_of_sale.py:810
#: view:pos.order:0
#, python-format
msgid "Return Products"
@ -3495,7 +3497,7 @@ msgid "Default Point of Sale"
msgstr ""
#. module: point_of_sale
#: code:addons/point_of_sale/wizard/pos_box.py:24
#: code:addons/point_of_sale/wizard/pos_box.py:23
#, python-format
msgid "There is no cash register for this PoS Session"
msgstr ""
@ -3539,7 +3541,7 @@ msgid "PRO-FORMA"
msgstr "形式发票"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:818
#: code:addons/point_of_sale/point_of_sale.py:839
#, python-format
msgid "Please provide a partner for the sale."
msgstr "请提供业务伙伴。"
@ -3591,7 +3593,7 @@ msgid "Print Receipt"
msgstr "打印收银条"
#. module: point_of_sale
#: code:addons/point_of_sale/point_of_sale.py:417
#: code:addons/point_of_sale/point_of_sale.py:420
#, python-format
msgid "Point of Sale Loss"
msgstr ""
@ -4020,6 +4022,7 @@ msgstr ""
#~ msgid "Discount percentage"
#~ msgstr "折扣百分比"
#, python-format
#~ msgid "Close"
#~ msgstr "关闭"
@ -4843,9 +4846,11 @@ msgstr ""
#~ msgid "Subtotal:"
#~ msgstr "小计:"
#, python-format
#~ msgid "Validate"
#~ msgstr "确认"
#, python-format
#~ msgid "Print"
#~ msgstr "打印"
@ -4931,6 +4936,7 @@ msgstr ""
#~ msgid "PoS Backend"
#~ msgstr "POS后端"
#, python-format
#~ msgid "Next Order"
#~ msgstr "下一订单"

View File

@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:06+0000\n"
"PO-Revision-Date: 2012-11-27 09:28+0000\n"
"Last-Translator: 盈通 ccdos <ccdos@163.com>\n"
"PO-Revision-Date: 2013-07-28 11:18+0000\n"
"Last-Translator: Wei \"oldrev\" Li <oldrev@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2013-03-16 05:25+0000\n"
"X-Generator: Launchpad (build 16532)\n"
"X-Launchpad-Export-Date: 2013-07-29 05:25+0000\n"
"X-Generator: Launchpad (build 16700)\n"
#. module: product
#: field:product.packaging,rows:0
@ -513,7 +513,7 @@ msgstr "标准耳机"
#. module: product
#: model:product.uom,name:product.product_uom_day
msgid "Day(s)"
msgstr ""
msgstr ""
#. module: product
#: help:product.product,incoming_qty:0
@ -800,7 +800,7 @@ msgstr "结束日期"
#. module: product
#: model:product.uom,name:product.product_uom_litre
msgid "Liter(s)"
msgstr ""
msgstr ""
#. module: product
#: view:product.price_list:0
@ -843,7 +843,7 @@ msgstr "价格表"
#. module: product
#: model:product.uom,name:product.product_uom_hour
msgid "Hour(s)"
msgstr ""
msgstr "小时"
#. module: product
#: selection:product.template,state:0
@ -1114,7 +1114,7 @@ msgstr "右父项"
#. module: product
#: field:product.product,price:0
msgid "Price"
msgstr ""
msgstr "价格"
#. module: product
#: field:product.pricelist.item,price_surcharge:0
@ -1192,7 +1192,7 @@ msgstr "显示产品列表的顺序号"
#. module: product
#: model:product.uom,name:product.product_uom_dozen
msgid "Dozen(s)"
msgstr ""
msgstr ""
#. module: product
#: field:product.uom,factor:0
@ -1338,7 +1338,7 @@ msgstr "指定一个产品分类 ,规则只被应用在与这个分类以及
#. module: product
#: view:product.product:0
msgid "Inventory"
msgstr "盘点"
msgstr "库存"
#. module: product
#: field:product.product,seller_info_id:0
@ -1346,7 +1346,7 @@ msgid "Supplier Info"
msgstr "供应商信息"
#. module: product
#: code:addons/product/product.py:729
#: code:addons/product/product.py:732
#, python-format
msgid "%s (copy)"
msgstr "%s (副本)"
@ -1891,7 +1891,7 @@ msgstr "消息"
#. module: product
#: model:product.uom,name:product.product_uom_unit
msgid "Unit(s)"
msgstr ""
msgstr ""
#. module: product
#: code:addons/product/product.py:176
@ -2341,7 +2341,7 @@ msgstr "序列"
msgid ""
"Average delay in days to produce this product. In the case of multi-level "
"BOM, the manufacturing lead times of the components will be added."
msgstr ""
msgstr "生成该产品的平均延时天数。在多级BoM的情况下部件的制造提前期将被累加"
#. module: product
#: model:product.template,name:product.product_assembly_product_template
@ -2364,6 +2364,8 @@ msgid ""
" </p>\n"
" "
msgstr ""
"单击以创建一个新的计量单位\n"
" "
#. module: product
#: model:product.template,name:product.product_product_11_product_template
@ -2444,7 +2446,7 @@ msgid "15” LCD Monitor"
msgstr "15” LCD 显示器"
#. module: product
#: code:addons/product/pricelist.py:376
#: code:addons/product/pricelist.py:379
#: field:product.pricelist.item,base_pricelist_id:0
#, python-format
msgid "Other Pricelist"

View File

@ -17,4 +17,4 @@ access_product_pricelist_partner_manager,product.pricelist partner manager,model
access_product_product_employee,product.product employee,model_product_product,base.group_user,1,0,0,0
access_product_template_sale_manager,product.template salemanager,model_product_template,base.group_sale_manager,1,1,1,1
access_product_product_sale_manager,product.product salemanager,model_product_product,base.group_sale_manager,1,1,1,1
access_product_category_sale_manager,product.category salemanager,product.model_product_category,base.group_sale_manager,1,1,1,1
access_product_category_sale_manager,product.category salemanager,product.model_product_category,base.group_sale_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
17 access_product_product_employee product.product employee model_product_product base.group_user 1 0 0 0
18 access_product_template_sale_manager product.template salemanager model_product_template base.group_sale_manager 1 1 1 1
19 access_product_product_sale_manager product.product salemanager model_product_product base.group_sale_manager 1 1 1 1
20 access_product_category_sale_manager product.category salemanager product.model_product_category base.group_sale_manager 1 1 1 1

File diff suppressed because it is too large Load Diff

View File

@ -45,3 +45,11 @@
.oe_editable:focus {
outline: #80b5f2 solid 5px !important;
}
.oe_carousel_options {
cursor: pointer;
position: absolute;
white-space: nowrap;
z-index: 1;
display: none;
}

View File

@ -40,3 +40,10 @@
.oe_editable:focus
outline: #80B5F2 solid 5px !important
.oe_carousel_options
cursor: pointer
position: absolute
white-space: nowrap
z-index: 1
display: none

View File

@ -1,3 +1,11 @@
/* THIS CSS FILE IS FOR WEBSITE THEMING CUSTOMIZATION ONLY
*
* css for editor buttons, openerp widget included in the website and other
* stuff must go to the editor.css
*
*/
/* ----- GENERIC LAYOUTING HELPERS ---- */
/* Vertical Spacing */
.mt128 {
margin-top: 128px !important;
}
@ -34,6 +42,88 @@
margin-top: 0px !important;
}
.mb128 {
margin-bottom: 128px !important;
}
.mb92 {
margin-bottom: 92px !important;
}
.mb64 {
margin-bottom: 64px !important;
}
.mb48 {
margin-bottom: 48px !important;
}
.mb32 {
margin-bottom: 32px !important;
}
.mb16 {
margin-bottom: 16px !important;
}
.mb8 {
margin-bottom: 8px !important;
}
.mb4 {
margin-bottom: 4px !important;
}
.mb0 {
margin-bottom: 0px !important;
}
/* Grid of unequally tall elements */
.grid > [class*="span"] {
display: inline-block;
float: none;
vertical-align: top;
margin-right: -4px;
box-sizing: border-box;
}
.grid > [class*="span"].grid-align-top > [class*="span"] {
vertical-align: top;
}
.grid > [class*="span"].grid-align-middle > [class*="span"] {
vertical-align: middle;
}
.grid > [class*="span"].grid-align-bottom > [class*="span"] {
vertical-align: bottom;
}
/* Table with two collumns aligned on the center */
.table-equalized {
width: 100%;
}
.table-equalized td:first-child {
width: 50%;
text-align: right;
padding-right: 1em;
vertical-align: bottom;
}
.table-equalized td:last-child {
width: 50%;
text-align: left;
vertical-align: bottom;
}
/* Theming pagination inside navbar */
.navbar-inner > .pagination {
margin: 6px 0;
}
.navbar-inner > .pagination ul {
position: relative;
top: 2px;
border: solid 2px rgba(0, 0, 0, 0.05);
border-radius: 8px;
}
/* ----- BOOTSTRAP HACK FOR STICKY FOOTER ----- */
html, body {
height: 100%;
box-sizing: border-box;
@ -57,6 +147,7 @@ footer {
padding-bottom: 64px;
}
/* ---- HOMEPAGE THEME CUSTOMIZATION ---- */
.subheader {
letter-spacing: 3px;
font-weight: 300;
@ -75,10 +166,16 @@ h5 {
font-weight: bold;
}
#myCarousel .item {
min-height: 300px;
color: white;
}
.nav > .pull-right {
float: right !important;
}
/* ---- HACK FOR COVERING UP CK EDITOR BOGUS P INSERTION --- */
.navbar .nav > li > p {
margin-bottom: 0px;
}
@ -98,16 +195,3 @@ h5 {
.nav > li a {
display: block;
}
#myCarousel .item {
min-height: 300px;
color: white;
}
.carousel > .css_carousel_options {
cursor: pointer;
position: absolute;
white-space: nowrap;
z-index: 1;
display: none;
}

View File

@ -1,5 +1,16 @@
@charset "utf-8"
/*
* THIS CSS FILE IS FOR WEBSITE THEMING CUSTOMIZATION ONLY
*
* css for editor buttons, openerp widget included in the website and other
* stuff must go to the editor.css
*
*/
/* ----- GENERIC LAYOUTING HELPERS ---- */
/* Vertical Spacing */
.mt128
margin-top: 128px !important
.mt92
@ -19,6 +30,62 @@
.mt0
margin-top: 0px !important
.mb128
margin-bottom: 128px !important
.mb92
margin-bottom: 92px !important
.mb64
margin-bottom: 64px !important
.mb48
margin-bottom: 48px !important
.mb32
margin-bottom: 32px !important
.mb16
margin-bottom: 16px !important
.mb8
margin-bottom: 8px !important
.mb4
margin-bottom: 4px !important
.mb0
margin-bottom: 0px !important
/* Grid of unequally tall elements */
.grid > [class*="span"]
display: inline-block
float: none
vertical-align: top
margin-right: -4px
box-sizing: border-box
&.grid-align-top > [class*="span"]
vertical-align: top
&.grid-align-middle > [class*="span"]
vertical-align: middle
&.grid-align-bottom > [class*="span"]
vertical-align: bottom
/* Table with two collumns aligned on the center */
.table-equalized
width: 100%
td:first-child
width: 50%
text-align: right
padding-right: 1em
vertical-align: bottom
td:last-child
width: 50%
text-align: left
vertical-align: bottom
/* Theming pagination inside navbar */
.navbar-inner > .pagination
margin: 6px 0
ul
position: relative
top: 2px
border: solid 2px rgba(0,0,0,0.05)
border-radius: 8px
/* ----- BOOTSTRAP HACK FOR STICKY FOOTER ----- */
html,body
height: 100%
@ -39,8 +106,8 @@ footer
background: rgb(239, 248, 248) // rgb(221, 235, 227)
padding-top: 64px
padding-bottom: 64px
//*
color: #1abc9c !important
/* ---- HOMEPAGE THEME CUSTOMIZATION ---- */
.subheader
letter-spacing: 3px
@ -56,9 +123,16 @@ header.navbar-fixed-top
h5
font-weight: bold
#myCarousel .item
min-height: 300px
color: white
.nav > .pull-right
float: right !important //bugfix for flatly theme
/* ---- HACK FOR COVERING UP CK EDITOR BOGUS P INSERTION --- */
.navbar .nav > li > p
margin-bottom: 0px
@ -75,13 +149,3 @@ h5
.nav > li a
display: block
#myCarousel .item
min-height: 300px
color: white
.carousel > .css_carousel_options
cursor: pointer
position: absolute
white-space: nowrap
z-index: 1
display: none

View File

@ -1,4 +1,17 @@
openerp.website = function(instance) {
instance.web.ActionManager.include({
// Temporary fix until un-webclientization of the editorbar
ir_actions_client: function (action) {
if (instance.web.client_actions.get_object(action.tag)) {
return this._super.apply(this, arguments);
} else {
console.warn("Action '%s' not found in registry", action.tag);
return $.when();
}
}
});
var _lt = instance.web._lt;
var QWeb = instance.web.qweb;
instance.website.EditorBar = instance.web.Widget.extend({

View File

@ -4,18 +4,16 @@
<openerp>
<data>
<template id="header">
<div class="container">
<div class="row">
<a href='/page/website.homepage' class='brand'>
<em>Open</em><b>ERP</b>
<!--<img t-att-alt="res_company.name" src='/web/binary/company_logo'/></a>-->
</a>
<ul class="nav pull-right">
<li class='pull-right'><a href="/admin">Sign in</a></li>
<li class='pull-right'><a href="/page/website.contactus">Contact us</a></li>
</ul>
</div>
</div>
<div class="container">
<a href='/page/website.homepage' class='brand'>
<em>Open</em><b>ERP</b>
<!--<img t-att-alt="res_company.name" src='/web/binary/company_logo'/></a>-->
</a>
<ul class="nav pull-right">
<li class='pull-right'><a href="/admin">Sign in</a></li>
<li class='pull-right'><a href="/page/website.contactus">Contact us</a></li>
</ul>
</div>
</template>
<template id="footer">
@ -38,12 +36,12 @@
</ul>
</div>
<div class="span4" name="about_us">
<h5 t-record="res_company" t-field="name">Company name</h5>
<h5 t-field="res_company.name">Company name</h5>
<ul class='unstyled'>
<li><a href="/page/website.contactus">Contact us</a></li>
<li><a href="/page/website.news">News</a></li>
<li><a href="/page/website.contactus">About us</a></li>
<li><a href='#'>&amp;#x2706; <span t-record="res_company" t-field="phone"/></a></li>
<li><a href='#'>&amp;#x2706; <span t-field="res_company.phone"/></a></li>
</ul>
</div>
</div>
@ -75,23 +73,19 @@
<link rel='stylesheet' href='/website/static/lib/bootstrap/css/bootstrap-responsive.css'/>
</head>
<body>
<div id='wrap'>
<header class='navbar navbar-fixed-top'>
<div class='navbar-inner'>
<t t-call="website.header"/>
</div>
</header>
<div t-raw="0">
<div class="container">
<div class="row">
<h1>I'm an empty page, please edit me...</h1>
</div>
</div>
<header class='navbar navbar-fixed-top'>
<div class='navbar-inner'>
<t t-call="website.header"/>
</div>
</header>
<div t-raw="0" id="wrap">
<div class="container">
<h1>Main Layout</h1>
</div>
</div>
<footer>
<t t-call="website.footer"/>
<p class="text-center">&amp;copy; <span t-record="res_company" t-field="name">Company name</span>.</p>
<p class="text-center">&amp;copy; <span t-field="res_company.name">Company name</span>.</p>
</footer>
<div class='oe_snippet_editor' style="display: none;">
@ -204,7 +198,7 @@
<section>
<div id="myCarousel" class="carousel slide" data-interval='1000000'>
<div class="css_carousel_options js_carousel_options" t-ignore="1">
<div class="oe_carousel_options js_carousel_options" t-ignore="1">
<span class="label js_add"><i class="icon-plus-sign"></i></span>
<span class="label js_remove"><i class="icon-minus-sign"></i></span>
</div>
@ -212,7 +206,7 @@
<div class="carousel-inner">
<div class="item active" style="background-image: url(/website/static/src/img/greenfields.jpg); background-size: cover;" >
<div class='container'>
<h1 class='mt64'>A Nice Banner</h1>
<h1 class='mt64'>A Nice Bidule</h1>
<h2>A convincing subtitle</h2>
<a href='#' class='btn btn-success btn-large mt16'>And a <em>Call To Action</em></a>
</div>
@ -324,13 +318,13 @@
<div class="row">
<div class="span12">
<h1>404: Page not found!</h1>
<p class="oe_grey">
<p>
The page you were looking for could not be
found; it is possible you have typed the
address incorrectly, but it has most
probably been removed due to the recent
website reorganisation.
</p><p class="oe_grey">
</p><p>
Maybe you were looking for one of these
popular pages ?
</p>
@ -341,8 +335,8 @@
</div>
</div>
<div class="row">
<div class="span12">
<a class="oe_button oe_big oe_tacky" t-att-href="'/pagenew/'+path" t-if="editable">Create Page</a>
<div class="span12 mt32">
<a class="btn btn-primary" t-att-href="'/pagenew/'+path" t-if="editable">Create Page</a>
</div>
</div>
</div>
@ -353,9 +347,7 @@
<t t-call="website.layout">
<t t-set="title">Contact us - <t t-esc="res_company.name"/></t>
<div class="container">
<div class="row">
<h2>Contact us</h2>
</div>
<h2>Contact us</h2>
<div class="row">
<div class="span8">
<p>
@ -363,19 +355,19 @@
</p><p>
We'll do our best to get back to you as soon as possible.
</p>
<div class="text-center oe_mt32" name="mail_button">
<div class="text-center mt64" name="mail_button">
<a t-att-href="'mailto:'+res_company.email" class="btn btn-primary">Send us an email</a>
</div>
</div>
<div class="span4">
<address>
<strong t-record="res_company" t-field="name">Name</strong><br/>
<span t-record="res_company" t-field="street"/><br/>
<span t-record="res_company" t-field="city"/>, <span t-record="res_company" t-field="zip"/><br/>
<span t-record="res_company" t-field="country_id"> </span><br/>
<strong t-field="res_company.name">Name</strong><br/>
<span t-field="res_company.street"/><br/>
<span t-field="res_company.city"/>, <span t-field="res_company.zip"/><br/>
<span t-field="res_company.country_id"> </span><br/>
<br/>
<span>&amp;#x2706; <span t-record="res_company" t-field="phone"><t t-esc="res_company.phone"/></span></span><br/>
<i class="icon-envelope"></i> <t t-esc="res_company.email"/>
<span>&amp;#x2706; <span t-field="res_company.phone"></span></span><br/>
<i class="icon-envelope"></i> <span t-field="res_company.email"></span>
</address>
<img class="thumbnail" t-att-src="google_map_url"/>
</div>

View File

@ -6,45 +6,34 @@ from openerp.addons.web.controllers import main
from openerp.addons.web.http import request
class website(http.Controller):
public_user_id = None
def auth_method_public():
registry = openerp.modules.registry.RegistryManager.get(request.db)
request.public_uid = None
with registry.cursor() as cr:
request.public_uid = request.registry['ir.model.data'].get_object_reference(cr, openerp.SUPERUSER_ID, 'website', 'public_user')[1]
if not request.session.uid:
request.uid = request.public_uid
else:
request.uid = request.session.uid
http.auth_methods['public'] = auth_method_public
def get_uid(self):
try:
request.session.check_security()
uid = request.session._uid
except http.SessionExpiredException:
if not website.public_user_id:
data_obj = request.registry['ir.model.data']
website.public_user_id = data_obj.get_object_reference(request.cr, openerp.SUPERUSER_ID, 'website', 'public_user')[1]
uid = website.public_user_id
return uid
def isloggued(self):
return website.public_user_id != self.get_uid()
def render(self, cr, uid, template, add_values={}):
script = "\n".join(['<script type="text/javascript" src="%s"></script>' % i for i in main.manifest_list('js', db=request.db)])
css = "\n".join('<link rel="stylesheet" href="%s">' % i for i in main.manifest_list('css', db=request.db))
class website(object):
def render(self, template, add_values={}):
debug = 'debug' in request.params
script = "\n".join(['<script type="text/javascript" src="%s"></script>' % i for i in main.manifest_list('js', db=request.db, debug=debug)])
css = "\n".join('<link rel="stylesheet" href="%s">' % i for i in main.manifest_list('css', db=request.db, debug=debug))
_values = {
'editable': self.isloggued(),
'editable': request.uid != request.public_uid,
'request': request,
'registry': request.registry,
'cr': cr,
'uid': uid,
'cr': request.cr,
'uid': request.uid,
'script': script,
'css': css,
'host_url': request.httprequest.host_url,
'res_company': request.registry['res.company'].browse(request.cr, openerp.SUPERUSER_ID, 1),
}
_values.update(add_values)
return request.registry.get("ir.ui.view").render(cr, uid, template, _values)
@staticmethod
def route(*args, **kwargs):
def wrap(_funct):
@http.route(*args, **kwargs)
def wrapper(self, *a, **k):
return _funct(self, request.cr, self.get_uid(), *a, **k)
return wrapper
return wrap
return request.registry.get("ir.ui.view").render(request.cr, request.uid, template, _values)
website = website()

View File

@ -0,0 +1,2 @@
import controllers
import event

View File

@ -0,0 +1,20 @@
{
'name': 'Website Event',
'category': 'mail',
'version': '1.0',
'description': """
OpenERP Blog
============
""",
'author': 'OpenERP SA',
'depends': ['website', 'event'],
'data': [
'views/website_event.xml',
'security/ir.model.access.csv',
'security/website_event.xml',
],
'qweb': ['static/src/xml/*.xml'],
'installable': True,
'auto_install': True,
}

View File

@ -0,0 +1 @@
import main

View File

@ -0,0 +1,96 @@
# -*- coding: utf-8 -*-
from openerp.addons.web import http
from openerp.addons.web.http import request
from openerp.addons.website import website
from openerp.tools.translate import _
from datetime import datetime
from dateutil.relativedelta import relativedelta
from openerp import tools
import urllib
class website_hr(http.Controller):
@http.route(['/event'], type='http', auth="public")
def events(self, **searches):
data_obj = request.registry['event.event']
searches.setdefault('date', 'all')
def sd(date):
return date.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
today = datetime.today()
dates = [
['all', _('All Dates'), [(1, "=", 1)], 0],
['today', _('Today'), [
("date_begin", ">", sd(today)),
("date_begin", "<", sd(today + relativedelta(days=1)))],
0],
['tomorrow', _('Tomorrow'), [
("date_begin", ">", sd(today + relativedelta(days=1))),
("date_begin", "<", sd(today + relativedelta(days=2)))],
0],
['week', _('This Week'), [
("date_begin", ">=", sd(today + relativedelta(days=-today.weekday()))),
("date_begin", "<", sd(today + relativedelta(days=6-today.weekday())))],
0],
['nextweek', _('Next Week'), [
("date_begin", ">=", sd(today + relativedelta(days=7-today.weekday()))),
("date_begin", "<", sd(today + relativedelta(days=13-today.weekday())))],
0],
['month', _('This month'), [
("date_begin", ">=", sd(today.replace(day=1) + relativedelta(months=1))),
("date_begin", "<", sd(today.replace(day=1) + relativedelta(months=1)))],
0],
]
domain_search = {
'date': 'all'
}
# search domains
for date in dates:
if searches.get("date") == date[0]:
domain_search["date"] = date[2]
# count by domains without self search
domain = [(1, "=", 1)]
for key, search in domain_search.items():
if key != 'date':
domain += search
for date in dates:
date[3] = data_obj.search(request.cr, request.uid, domain + date[2], count=True)
# domain and search_path
domain = [(1, "=", 1)]
for key, search in domain_search.items():
domain += search
obj_ids = data_obj.search(request.cr, request.uid, domain)
values = {
'event_ids': data_obj.browse(request.cr, request.uid, obj_ids),
'dates': dates,
'searches': searches,
'search_path': "?%s" % urllib.urlencode(searches),
}
html = website.render("website_event.index", values)
return html
@http.route(['/event/<int:event_id>'], type='http', auth="public")
def event(self, event_id=None, **post):
return ""
@http.route(['/event/publish'], type='http', auth="public")
def publish(self, **post):
obj_id = int(post['id'])
data_obj = request.registry['event.event']
obj = data_obj.browse(request.cr, request.uid, obj_id)
data_obj.write(request.cr, request.uid, [obj_id], {'website_published': not obj.website_published})
obj = data_obj.browse(request.cr, request.uid, obj_id)
return obj.website_published and "1" or "0"

View File

@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
from openerp.osv import osv, fields
class event(osv.osv):
_inherit = 'event.event'
_columns = {
'website_published': fields.boolean('Available in the website'),
}

View File

@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_event_event_public,event.event.public,event.model_event_event,base.group_public,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_event_event_public event.event.public event.model_event_event base.group_public 1 0 0 0

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="event_event_public" model="ir.rule">
<field name="name">event: Public</field>
<field name="model_id" ref="event.model_event_event"/>
<field name="domain_force">[('website_published', '=', True)]</field>
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
</record>
</data>
</openerp>

View File

@ -0,0 +1,2 @@
sass:
sass --compass --trace -t expanded hr.sass hr.css

View File

@ -0,0 +1 @@
@import "compass/css3"

View File

@ -0,0 +1,18 @@
$(document).ready(function () {
$(document).on('click', '.js_publish, .js_unpublish', function (e) {
e.preventDefault();
var $link = $(this).parent();
$link.find('.js_publish, .js_unpublish').addClass("hidden");
var $unp = $link.find(".js_unpublish");
var $p = $link.find(".js_publish");
$.post('/event/publish', {'id': $link.data('id')}, function (result) {
if (+result) {
$p.addClass("hidden");
$unp.removeClass("hidden");
} else {
$p.removeClass("hidden");
$unp.addClass("hidden");
}
});
});
});

View File

@ -0,0 +1,131 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Layout add nav and footer -->
<record id="header_website_event" model="ir.ui.view">
<field name="name">header_website_event</field>
<field name="inherit_id" ref="website.header"/>
<field name="arch" type="xml">
<data>
<xpath expr="(//li)[last()]" position="after">
<li class="pull-right"><a href="/event">Events</a></li>
</xpath>
</data>
</field>
</record>
<record id="footer_website_event" model="ir.ui.view">
<field name="name">footer_website_event</field>
<field name="inherit_id" ref="website.footer"/>
<field name="arch" type="xml">
<data>
<xpath expr="//a[@href='/page/website.contactus']" position="after">
<li><a href="/event">Events</a></li>
</xpath>
</data>
</field>
</record>
<!-- Page -->
<template id="index">
<t t-call="website.layout">
<t t-set="head">
<script type="text/javascript" src="/website_event/static/src/js/website_event.js"></script>
<t t-raw="head"/>
</t>
<t t-set="title">Events</t>
<div class="container mt48">
<div class="row">
<div class="span4 css_noprint">
<ul class="nav nav-list">
<li class="nav-header">Date</li>
<t t-foreach="dates" t-as="date">
<li t-att-class="searches.get('date') == date[0] and 'active' or ''">
<a t-att-href="'/event/%%s&amp;date=%%s' %% (search_path, date[0])"><t t-esc="date[1]"/> <small t-if="date[3]">(<t t-esc="date[3]"/>)</small></a>
</li>
</t>
</ul>
<ul class="nav nav-list">
<li class="nav-header">Category</li>
<li class="active">
<a >All Categories <span>(27)</span></a>
</li>
<li>
<a >Conferences <span>(18)</span></a>
</li>
<li>
<a >Business <span>(18)</span></a>
</li>
<li>
<a>Classes <span>(9)</span></a>
</li>
</ul>
<ul class="nav nav-list">
<li class="nav-header">Location</li>
<li>
<a>Ramillies <span>(7)</span></a>
</li>
<li>
<a>Eindhoven <span>(6)</span></a>
</li>
<li>
<a>Hasselt <span>(6)</span></a>
</li>
<li>
<a>Herentals <span>(6)</span></a>
</li>
<li>
<a>Geel <span>(2)</span></a>
</li>
</ul>
</div>
<div class="span8">
<ul class="media-list mt32">
<t t-foreach="event_ids" t-as="event_id">
<li class="media thumbnail">
<div class="media-body">
<t t-if="event_id.register_avail">
<t t-if="event_id.register_avail == 9999">
<span class="label pull-right">No ticket available.</span>
</t>
<span t-if="event_id.register_avail != 9999" t-att-class="'label pull-right label-%%s' %% (event_id.register_avail &lt;= 10 and 'warning' or 'info')">
<t t-if="event_id.register_avail &lt;= 10">Only</t>
<t t-esc="event_id.register_avail"/>
<t t-if="event_id.register_avail &gt; 1">tickets </t>
<t t-if="event_id.register_avail == 1">ticket </t>
available.
</span>
</t>
<h4 class="media-heading"><a t-att-href="'event/%%s' %% event_id.id"><span t-field="event_id.name"> </span></a></h4>
<t t-if="editable">
<a href="#" t-att-data-id="event_id.id" class="pull-right">
<span t-att-class="'label label-success js_unpublish %%s' %% (not event_id.website_published and 'hidden' or '')">Click to Unpublish</span>
<span t-att-class="'label label-important js_publish %%s' %% (event_id.website_published and 'hidden' or '')">Click to Publish</span>
</a>
</t>
<div>
<span t-field="event_id.type">: </span>
<t t-if="event_id.user_id">
Organized by: <span t-field="event_id.user_id"> </span>
</t>
</div>
<div>
<i class="icon-time"></i> <span t-field="event_id.date_begin"> </span> <i>to</i> <span t-field="event_id.date_end"> </span>
</div>
<div t-if="event_id.country_id">
<i class="icon-map-marker"></i> <span t-field="event_id.city"> </span> <span t-field="event_id.zip"> </span>, <span t-field="event_id.country_id"> </span>
</div>
<div t-field="event_id.note"> </div>
</div>
</li>
</t>
</ul>
</div>
</div>
</div>
</t>
</template>
</data>
</openerp>

View File

@ -11,6 +11,8 @@ OpenERP Blog
'depends': ['website', 'hr'],
'data': [
'views/website_hr.xml',
'security/ir.model.access.csv',
'security/website_hr.xml',
],
'qweb': ['static/src/xml/*.xml'],
'installable': True,

View File

@ -1,19 +1,41 @@
# -*- coding: utf-8 -*-
from openerp.addons.web import http
from openerp.addons.web.http import request
from openerp.addons.website import website
class website_hr(website):
class website_hr(http.Controller):
@website.route(['/team'], type='http', auth="admin")
def blog(self, cr, uid, **post):
@http.route(['/hr'], type='http', auth="public")
def blog(self, **post):
hr_obj = request.registry['hr.employee']
employee_ids = hr_obj.search(cr, uid, [(1, "=", 1)])
employee_ids = hr_obj.search(request.cr, request.uid, [(1, "=", 1)])
values = {
'res_company': request.registry['res.company'].browse(cr, uid, 1),
'employee_ids': hr_obj.browse(cr, uid, employee_ids),
'employee_ids': hr_obj.browse(request.cr, request.uid, employee_ids),
}
html = self.render(cr, uid, "website_hr.index", values)
html = website.render("website_hr.index", values)
return html
@http.route(['/hr/publish'], type='http', auth="public")
def publish(self, **post):
obj_id = int(post['id'])
data_obj = request.registry['hr.employee']
obj = data_obj.browse(request.cr, request.uid, obj_id)
data_obj.write(request.cr, request.uid, [obj_id], {'website_published': not obj.website_published})
obj = data_obj.browse(request.cr, request.uid, obj_id)
return obj.website_published and "1" or "0"
@http.route(['/hr/publish_contact'], type='http', auth="public")
def publish_contact(self, **post):
obj_id = int(post['id'])
data_obj = request.registry['hr.employee']
obj = data_obj.browse(request.cr, request.uid, obj_id)
data_obj.write(request.cr, request.uid, [obj_id], {'website_published_on_contact_form': not obj.website_published_on_contact_form})
obj = data_obj.browse(request.cr, request.uid, obj_id)
return obj.website_published_on_contact_form and "1" or "0"

View File

@ -6,6 +6,7 @@ from openerp.osv import osv, fields
class hr(osv.osv):
_inherit = 'hr.employee'
_columns = {
'website_important': fields.boolean('Publish', help="Publish also on contact form"),
'website_published': fields.boolean('Available in the website'),
'website_published_on_contact_form': fields.boolean('Publish', help="Publish also on contact form"),
}

View File

@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_hr_employee_public,hr.employee.public,hr.model_hr_employee,base.group_public,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_hr_employee_public hr.employee.public hr.model_hr_employee base.group_public 1 0 0 0

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="hr_employee_public" model="ir.rule">
<field name="name">hr_employee: Public</field>
<field name="model_id" ref="hr.model_hr_employee"/>
<field name="domain_force">[('website_published', '=', True)]</field>
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
</record>
</data>
</openerp>

View File

@ -1,3 +1,34 @@
$(document).ready(function () {
$(document).on('click', '.js_publish, .js_unpublish', function (e) {
e.preventDefault();
var $link = $(this).parent();
$link.find('.js_publish, .js_unpublish').addClass("hidden");
var $unp = $link.find(".js_unpublish");
var $p = $link.find(".js_publish");
$.post('/hr/publish', {'id': $link.data('id')}, function (result) {
if (+result) {
$p.addClass("hidden");
$unp.removeClass("hidden");
} else {
$p.removeClass("hidden");
$unp.addClass("hidden");
}
});
});
$(document).on('click', '.js_publish_contact, .js_unpublish_contact', function (e) {
e.preventDefault();
var $link = $(this).parent();
$link.find('.js_publish_contact, .js_unpublish_contact').addClass("hidden");
var $unp = $link.find(".js_unpublish_contact");
var $p = $link.find(".js_publish_contact");
$.post('/hr/publish_contact', {'id': $link.data('id')}, function (result) {
if (+result) {
$p.addClass("hidden");
$unp.removeClass("hidden");
} else {
$p.removeClass("hidden");
$unp.addClass("hidden");
}
});
});
});

View File

@ -4,13 +4,13 @@
<!-- Layout add nav and footer -->
<record id="footer_hr_mail" model="ir.ui.view">
<record id="footer_website_hr" model="ir.ui.view">
<field name="name">footer_website_hr</field>
<field name="inherit_id" ref="website.footer"/>
<field name="arch" type="xml">
<data>
<xpath expr="//a[@href='/page/website.contactus']" position="after">
<li><a href="/team">Team</a></li>
<li><a href="/hr">Team</a></li>
</xpath>
</data>
</field>
@ -21,27 +21,42 @@
<template id="index">
<t t-call="website.layout">
<t t-set="head">
<script type="text/javascript" src="/website_mail/static/src/js/blog.js"></script>
<link rel='stylesheet' href='/website_mail/static/src/css/blog.css'/>
<script type="text/javascript" src="/website_hr/static/src/js/hr.js"></script>
<t t-raw="head"/>
</t>
<t t-set="title">Team</t>
<div class="container mt48">
<ul class="media-list">
<t t-foreach="employee_ids">
<!-- TODO: check qweb iteration -->
<li class="media pull-left">
<div t-att-class="'media-body %%s' %% (website_important and 'css_important' or '')">
<a href="#" t-att-data-id="id" class="js_important pull-right" groups="group_website_mail_manager">
<span class="label label-success">Unpublish</span>
<span class="label label-important">Publish</span>
<div class="container">
<div class="thumbnails">
<t t-foreach="employee_ids" t-as="employee_id">
<div class="span4 mt16">
<div class="media thumbnail">
<a class="pull-left" href="#">
<img class="media-object" t-att-src="'data:image/png;base64,%%s' %% employee_id.image_small"/>
</a>
<t t-raw="image"/>
<t t-raw="name"/>
<div class="media-body">
<t t-if="editable">
<div class="pull-right">
<a href="#" t-att-data-id="employee_id.id">
<span t-att-class="'label label-success js_unpublish %%s' %% (not employee_id.website_published and 'hidden' or '')">Click to Unpublish</span>
<span t-att-class="'label label-important js_publish %%s' %% (employee_id.website_published and 'hidden' or '')">Click to Publish</span>
</a><br/>
<a href="#" t-att-data-id="employee_id.id">
<span t-att-class="'label label-success js_unpublish_contact %%s' %% (not employee_id.website_published and 'hidden' or '')">hidden on Contacts</span>
<span t-att-class="'label label-important js_publish_contact %%s' %% (employee_id.website_published and 'hidden' or '')">display in Contacts</span>
</a>
</div>
</t>
<h5 class="media-heading"><t t-esc="employee_id.name"/></h5>
<div t-record="employee_id" t-field="department_id"> </div>
<div t-record="employee_id" t-field="job_id"> </div>
<div t-record="employee_id" t-field="work_location"> </div>
<div t-record="employee_id" t-field="work_phone"> </div>
<div t-record="employee_id" t-field="work_email"> </div>
</div>
</div>
</li>
</div>
</t>
</ul>
</div>
</div>
</t>
</template>

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
from openerp.addons.web import http
from openerp.addons.web.http import request
from openerp.addons.website import website
import werkzeug
@ -10,15 +11,14 @@ import simplejson
_months = {1:_("January"), 2:_("February"), 3:_("March"), 4:_("April"), 5:_("May"), 6:_("June"), 7:_("July"), 8:_("August"), 9:_("September"), 10:_("October"), 11:_("November"), 12:_("December")}
class website_mail(website):
class website_mail(http.Controller):
@website.route(['/blog', '/blog/<int:mail_group_id>', '/blog/<int:mail_group_id>/<int:blog_id>'], type='http', auth="admin")
def blog(self, cr, uid, mail_group_id=None, blog_id=None, **post):
@http.route(['/blog', '/blog/<int:mail_group_id>', '/blog/<int:mail_group_id>/<int:blog_id>'], type='http', auth="public")
def blog(self, mail_group_id=None, blog_id=None, **post):
group_obj = request.registry['mail.group']
message_obj = request.registry['mail.message']
values = {
'res_company': request.registry['res.company'].browse(cr, uid, 1),
'blog_ids': None,
'blog_id': None,
'nav_list': dict(),
@ -28,7 +28,7 @@ class website_mail(website):
}
domain = mail_group_id and [("res_id", "=", mail_group_id)] or []
for group in message_obj.read_group(cr, uid, domain + group_obj.get_public_domain(cr, uid), ['subject', 'date'], groupby="date", orderby="create_date asc"):
for group in message_obj.read_group(request.cr, request.uid, domain + group_obj.get_public_blog(request.cr, request.uid), ['subject', 'date'], groupby="date", orderby="create_date asc"):
year = group['date'].split(" ")[1]
if not values['nav_list'].get(year):
values['nav_list'][year] = {'name': year, 'date_count': 0, 'months': []}
@ -36,57 +36,57 @@ class website_mail(website):
values['nav_list'][year]['months'].append(group)
if post.get('date'):
ids = group_obj.get_public_message_ids(cr, uid, domain=domain + [("date", ">", post.get('date'))], order="create_date asc", limit=10)
ids = group_obj.get_public_message_ids(request.cr, request.uid, domain=domain + [("date", ">", post.get('date'))], order="create_date asc", limit=10)
if ids:
values['prev_date'] = message_obj.browse(cr, uid, ids.pop()).date
values['prev_date'] = message_obj.browse(request.cr, request.uid, ids.pop()).date
domain += [("date", "<=", post.get('date'))]
message_ids = group_obj.get_public_message_ids(cr, uid, domain=domain, order="create_date desc", limit=11)
message_ids = group_obj.get_public_message_ids(request.cr, request.uid, domain=domain, order="create_date desc", limit=11)
if message_ids:
values['blog_ids'] = message_obj.browse(cr, uid, message_ids)
values['blog_ids'] = message_obj.browse(request.cr, request.uid, message_ids)
if len(message_ids) > 10:
values['next_date'] = values['blog_ids'].pop().date
if blog_id:
values['blog_id'] = message_obj.browse(cr, uid, blog_id)
values['blog_id'] = message_obj.browse(request.cr, request.uid, blog_id)
comment_ids = [child_id.id for child_id in values['blog_id'].child_ids]
values['comments'] = message_obj.read(cr, uid, comment_ids, ['website_published', 'author_id', 'date', 'body'])
values['comments'] = message_obj.read(request.cr, request.uid, comment_ids, ['website_published', 'author_id', 'date', 'body'])
html = self.render(cr, uid, "website_mail.index", values)
html = website.render("website_mail.index", values)
return html
@website.route(['/blog/nav'], type='http', auth="admin")
def nav(self, cr, uid, **post):
comment_ids = request.registry['mail.group'].get_public_message_ids(cr, uid, domain=safe_eval(post.get('domain')), order="create_date asc", limit=None)
return simplejson.dumps(request.registry['mail.message'].read(cr, uid, comment_ids, ['website_published', 'subject', 'res_id']))
@http.route(['/blog/nav'], type='http', auth="public")
def nav(self, **post):
comment_ids = request.registry['mail.group'].get_public_message_ids(request.cr, request.uid, domain=safe_eval(post.get('domain')), order="create_date asc", limit=None)
return simplejson.dumps(request.registry['mail.message'].read(request.cr, request.uid, comment_ids, ['website_published', 'subject', 'res_id']))
@website.route(['/blog/publish'], type='http', auth="admin")
def publish(self, cr, uid, **post):
message_id = int(post['message_id'])
@http.route(['/blog/publish'], type='http', auth="public")
def publish(self, **post):
message_id = int(post['id'])
message_obj = request.registry['mail.message']
blog = message_obj.browse(cr, uid, message_id)
message_obj.write(cr, uid, [message_id], {'website_published': not blog.website_published})
blog = message_obj.browse(cr, uid, message_id)
blog = message_obj.browse(request.cr, request.uid, message_id)
message_obj.write(request.cr, request.uid, [message_id], {'website_published': not blog.website_published})
blog = message_obj.browse(request.cr, request.uid, message_id)
return blog.website_published and "1" or "0"
@website.route(['/blog/<int:mail_group_id>/<int:blog_id>/post'], type='http', auth="admin")
def blog_post(self, cr, uid, mail_group_id=None, blog_id=None, **post):
@http.route(['/blog/<int:mail_group_id>/<int:blog_id>/post'], type='http', auth="public")
def blog_post(self, mail_group_id=None, blog_id=None, **post):
url = request.httprequest.host_url
if post.get('body'):
request.session.body = post.get('body')
if not self.isloggued():
if not request.uid != request.public_uid:
return '%s/admin#action=redirect&url=%s/blog/%s/%s/post' % (url, url, mail_group_id, blog_id)
if 'body' in request.session and request.session.body:
request.registry['mail.group'].message_post(cr, uid, mail_group_id,
request.registry['mail.group'].message_post(request.cr, request.uid, mail_group_id,
body=request.session.body,
parent_id=blog_id,
website_published=blog_id and True or False,
type='comment',
subtype='mt_comment',
context={'mail_create_nosubscribe': True},
context={'mail_create_nosubsrequest.cribe': True},
)
request.session.body = False
@ -95,14 +95,14 @@ class website_mail(website):
else:
return werkzeug.utils.redirect("/blog/%s/%s" % (mail_group_id, blog_id))
@website.route(['/blog/<int:mail_group_id>/new'], type='http', auth="admin")
def new_blog_post(self, cr, uid, mail_group_id=None, **post):
blog_id = request.registry['mail.group'].message_post(cr, uid, mail_group_id,
@http.route(['/blog/<int:mail_group_id>/new'], type='http', auth="public")
def new_blog_post(self, mail_group_id=None, **post):
blog_id = request.registry['mail.group'].message_post(request.cr, request.uid, mail_group_id,
body=_("Blog content.<br/>Please edit this content then you can publish this blog."),
subject=_("Blog title"),
website_published=False,
type='comment',
subtype='mt_comment',
context={'mail_create_nosubscribe': True},
context={'mail_create_nosubsrequest.cribe': True},
)
return werkzeug.utils.redirect("/blog/%s/%s" % (mail_group_id, blog_id))

View File

@ -32,12 +32,12 @@ class mail_message(osv.osv):
class mail_group(osv.Model):
_inherit = 'mail.group'
def get_public_domain(self, cr, uid, context=None):
def get_public_blog(self, cr, uid, context=None):
mail_group_ids = self.search(cr, uid, [('public', '=', 'public')], context=context)
return [ ("type", "in", ['comment']),
("parent_id", "=", False),
("model", "=", 'mail.group'), ("res_id", "in", mail_group_ids)]
def get_public_message_ids(self, cr, uid, domain=[], order="create_date desc", limit=10, offset=0, context=None):
domain += self.get_public_domain(cr, uid, context=context)
domain += self.get_public_blog(cr, uid, context=context)
return self.pool.get('mail.message').search(cr, uid, domain, order=order, limit=limit, offset=offset, context=context)

View File

@ -1,12 +1,3 @@
.css_website_mail .media .label-success {
display: none;
}
.css_website_mail .css_published .label-important {
display: none;
}
.css_website_mail .css_published .label-success {
display: inline-block;
}
.css_website_mail .has-error {
border-color: red;
}

View File

@ -1,14 +1,6 @@
@import "compass/css3"
.css_website_mail
.media
.label-success
display: none
.css_published
.label-important
display: none
.label-success
display: inline-block
.has-error
border-color: red
.css_nav_month

View File

@ -1,11 +1,18 @@
$(document).ready(function () {
$('.js_website_mail').on('click', '.js_publish', function (e) {
$('.js_website_mail').on('click', '.js_publish, .js_unpublish', function (e) {
e.preventDefault();
var $media = $(this).parent();
$media.toggleClass('css_published');
$.post('/blog/publish/', {'message_id': $(this).data('id')}, function (result) {
if (+result) $media.addClass('css_published');
else $media.removeClass('css_published');
var $link = $(this).parent();
$link.find('.js_publish, .js_unpublish').addClass("hidden");
var $unp = $link.find(".js_unpublish");
var $p = $link.find(".js_publish");
$.post('/blog/publish', {'id': $link.data('id')}, function (result) {
if (+result) {
$p.addClass("hidden");
$unp.removeClass("hidden");
} else {
$p.removeClass("hidden");
$unp.addClass("hidden");
}
});
});

View File

@ -45,11 +45,11 @@
<t t-raw="head"/>
</t>
<t t-set="title">Blog</t>
<div class="container mt48 css_website_mail js_website_mail">
<div class="container mt48 js_website_mail">
<div class="row">
<div class="span4">
<ul class="nav nav-list">
<a t-if="mail_group_id" t-att-href="'/blog/%%s/new' %% mail_group_id" class="btn" groups="group_website_mail_manager">Add a new Blog</a>
<a t-if="mail_group_id and editable" t-att-href="'/blog/%%s/new' %% mail_group_id" class="btn">Add a new Blog</a>
<li class="nav-header">BLOG ARCHIVE</li>
<!-- TODO: check qweb iteration -->
<t t-foreach="nav_list" t-as="year">
@ -68,31 +68,31 @@
</div>
<div class="span8" t-if="blog_id">
<div class="media">
<div t-att-class="'media-body well %%s' %% (blog_id.website_published and 'css_published' or '')">
<a href="#" title="Click to publish or unpublish this blog" t-att-data-id="blog_id.id" class="js_publish pull-right" groups="group_website_mail_manager">
<span class="label label-success">Unpublish</span>
<span class="label label-important">Publish</span>
<div class="media-body well">
<a href="#" t-att-data-id="blog_id.id" class="pull-right" t-if="editable">
<span t-att-class="'label label-success js_unpublish %%s' %% (not blog_id.website_published and 'hidden' or '')">Click to Unpublish</span>
<span t-att-class="'label label-important js_publish %%s' %% (blog_id.website_published and 'hidden' or '')">Click to Publish</span>
</a>
<h3 t-record="blog_id" t-field="subject"></h3>
<div t-record="blog_id" t-field="body"></div>
<h3 t-field="blog_id.subject"></h3>
<div t-field="blog_id.body"></div>
<small class="pull-right muted text-right">
<div><t t-esc="blog_id.read(['author_id'])[0]['author_id'][1]"/></div>
<div><t t-esc="blog_id.date"/></div>
<div><t t-field="blog_id.author_id"/></div>
<div><t t-field="blog_id.date"/></div>
</small>
</div>
<ul class="media-list">
<t t-foreach="comments">
<t t-foreach="blog_id.child_ids" t-as="comment">
<!-- TODO: check qweb iteration -->
<li class="media">
<div t-att-class="'media-body %%s' %% (website_published and 'css_published' or '')">
<a href="#" title="Click to publish or unpublish this message" t-att-data-id="id" class="js_publish pull-right" groups="group_website_mail_manager">
<span class="label label-success">Unpublish</span>
<span class="label label-important">Publish</span>
<div class="media-body">
<a href="#" t-att-data-id="blog_id.id" class="pull-right" t-if="editable">
<span t-att-class="'label label-success js_unpublish %%s' %% (not comment.website_published and 'hidden' or '')">Click to Unpublish</span>
<span t-att-class="'label label-important js_publish %%s' %% (comment.website_published and 'hidden' or '')">Click to Publish</span>
</a>
<t t-raw="body"/>
<t t-raw="comment.body"/>
<small class="pull-right muted text-right">
<div><t t-esc="author_id[1]"/></div>
<div><t t-esc="date"/></div>
<div><t t-esc="comment.author_id"/></div>
<div><t t-esc="comment.date"/></div>
</small>
</div>
</li>
@ -109,25 +109,34 @@
<t t-foreach="blog_ids" t-as="blog">
<li class="media well">
<div t-att-class="'media-body %%s' %% (blog.website_published and 'css_published' or '')">
<a href="#" title="Click to publish or unpublish this message" t-att-data-id="blog.id" class="js_publish pull-right" groups="group_website_mail_manager">
<span class="label label-success">Unpublish</span>
<span class="label label-important">Publish</span>
<a href="#" t-att-data-id="blog.id" class="pull-right" t-if="editable">
<span t-att-class="'label label-success js_unpublish %%s' %% (not blog.website_published and 'hidden' or '')">Click to Unpublish</span>
<span t-att-class="'label label-important js_publish %%s' %% (blog.website_published and 'hidden' or '')">Click to Publish</span>
</a>
<h4 class="media-heading" ><a t-att-href="'/blog/%%s/%%s' %% (blog.res_id, blog.id)" t-record="blog" t-field="subject"></a></h4>
<h4 class="media-heading" ><a t-att-href="'/blog/%%s/%%s' %% (blog.res_id, blog.id)" t-field="blog.subject"></a></h4>
<div class="media">
<div t-record="blog" t-field="body"></div>
<div t-field="blog.body"></div>
<small class="pull-left muted text-right" t-if="len(blog.child_ids)">
<a t-if="len(blog.child_ids) &lt;= 1" t-att-href="'/blog/%%s/%%s' %% (blog.res_id, blog.id)"><t t-esc="len(blog.child_ids)"/> Message</a>
<a t-if="len(blog.child_ids) > 1" t-att-href="'/blog/%%s/%%s' %% (blog.res_id, blog.id)"><t t-esc="len(blog.child_ids)"/> Messages</a>
</small>
<small class="pull-right muted text-right">
<a t-att-href="'/blog/%%s/%%s' %% (blog.res_id, blog.id)">Read more </a>
<div><t t-esc="blog.read(['author_id'])[0]['author_id'][1]"/></div>
<div><t t-esc="blog.date"/></div>
<div><t t-field="blog.author_id"/></div>
<div><t t-field="blog.date"/></div>
</small>
</div>
</div>
</li>
</t>
</ul>
<a t-if="prev_date" t-att-href="'?date=%%s' %% (prev_date)" class="pull-left">Newer</a>
<a t-if="next_date" t-att-href="'?date=%%s' %% (next_date)" class="pull-right">Older</a>
<ul class="pager">
<li t-if="next_date" class="previous">
<a t-att-href="'?date=%%s' %% (next_date)">&amp;larr; Older</a>
</li>
<li t-if="prev_date" class="next">
<a t-att-href="'?date=%%s' %% (prev_date)">Newer &amp;rarr;</a>
</li>
</ul>
</div>
</div>
</div>

View File

@ -1,2 +1,3 @@
import controllers
import pricelist
import product

View File

@ -11,7 +11,9 @@ OpenERP E-Commerce
'depends': ['website', 'sale', 'point_of_sale'],
'data': [
'views/ecommerce.xml',
'views/pricelist.xml'
'views/pricelist.xml',
'security/ir.model.access.csv',
'security/ecommerce.xml',
],
'qweb': ['static/src/xml/*.xml'],
'installable': True,

View File

@ -1,68 +1,55 @@
# -*- coding: utf-8 -*-
import openerp
import simplejson
from openerp.addons.web import http
from openerp.addons.website import website
from openerp.addons.web.http import request
from openerp.addons.website.controllers.main import template_values
class Ecommerce(http.Controller):
def get_cr_uid(self):
cr = request.cr
uid = request.uid
if request.session._uid:
request.httprequest.session['ecommerce_partner_id'] = False
partner_id = request.registry.get('res.users').browse(cr, uid, request.session._uid).partner_id.id
else:
partner_id = request.httprequest.session.get('ecommerce_partner_id', False)
if partner_id and not request.registry.get('res.partner').search(cr, uid, [('id', '=', partner_id)]):
partner_id = None
return (cr, uid, partner_id)
def get_categories(self):
cr, uid, partner_id = self.get_cr_uid()
category_obj = request.registry.get('pos.category')
category_ids = category_obj.search(cr, uid, [('parent_id', '=', False)])
return category_obj.browse(cr, uid, category_ids)
category_ids = category_obj.search(request.cr, openerp.SUPERUSER_ID, [('parent_id', '=', False)])
return category_obj.browse(request.cr, openerp.SUPERUSER_ID, category_ids)
def get_current_order(self):
order = self.get_order(request.httprequest.session.get('ecommerce_order_id'))
request.httprequest.session['ecommerce_order_id'] = order.id
return order
def get_order(self, order_id=None):
cr, uid, partner_id = self.get_cr_uid()
order_obj = request.registry.get('sale.order')
# check if order allready exists
if order_id:
try:
order_obj.browse(cr, uid, order_id).pricelist_id
order_obj.browse(request.cr, openerp.SUPERUSER_ID, order_id).pricelist_id
except:
order_id = None
if not order_id:
fields = [k for k, v in order_obj._columns.items()]
order_value = order_obj.default_get(cr, uid, fields)
order_value['partner_id'] = partner_id or request.registry.get('res.users').browse(cr, uid, uid).partner_id.id
order_value.update(order_obj.onchange_partner_id(cr, uid, [], uid, context={})['value'])
order_id = order_obj.create(cr, uid, order_value)
return order_obj.browse(cr, uid, order_id)
order_value = order_obj.default_get(request.cr, openerp.SUPERUSER_ID, fields)
order_value['partner_id'] = openerp.SUPERUSER_ID != request.public_uid and \
request.registry.get('res.users').browse(request.cr, openerp.SUPERUSER_ID, request.uid).partner_id.id or \
None
order_value.update(order_obj.onchange_partner_id(request.cr, openerp.SUPERUSER_ID, [], request.uid, context={})['value'])
order_id = order_obj.create(request.cr, openerp.SUPERUSER_ID, order_value)
return order_obj.browse(request.cr, openerp.SUPERUSER_ID, order_id)
def get_values(self):
cr, uid, partner_id = self.get_cr_uid()
order = self.get_order(request.httprequest.session.get('ecommerce_order'))
request.httprequest.session['ecommerce_order'] = order.id
values = template_values()
values.update({
'temp': 0,
'res_company': request.registry['res.company'].browse(request.cr, 1, 1),
'order': order,
def render(self, template, values={}):
_values = {
'order': self.get_current_order(),
'categories': self.get_categories(),
})
return values
}
_values.update(values)
return website.render(template, _values)
def recommended_product(self, my_pids):
if not my_pids:
return []
cr, uid, partner_id = self.get_cr_uid()
my_pids = str(my_pids)[1:-1]
product_ids = []
query = """
@ -76,99 +63,91 @@ class Ecommerce(http.Controller):
ORDER BY COUNT(sol.order_id) DESC
LIMIT 8
""" % (my_pids, my_pids)
cr.execute(query)
for p in cr.fetchall():
request.cr.execute(query)
for p in request.cr.fetchall():
product_ids.append(p[0])
return request.registry.get('product.product').browse(cr, uid, product_ids)
return request.registry.get('product.product').browse(request.cr, request.uid, product_ids)
@http.route(['/shop', '/shop/category/<cat_id>'], type='http', auth="admin")
@http.route(['/shop', '/shop/category/<cat_id>'], type='http', auth="public")
def category(self, cat_id=0, offset=0, **post):
values = self.get_values()
cr, uid, partner_id = self.get_cr_uid()
domain = []
domain = [("sale_ok", "=", True)]
if post.get("search"):
domain += ['|', '|', ('name', 'ilike', "%%%s%%" % post.get("search")), ('description', 'ilike', "%%%s%%" % post.get("search")), ('pos_categ_id.name', 'ilike', "%%%s%%" % post.get("search"))]
domain += ['|', '|', ('name', 'ilike', "%%%s%%" % post.get("search")), ('desrequest.cription', 'ilike', "%%%s%%" % post.get("search")), ('pos_categ_id.name', 'ilike', "%%%s%%" % post.get("search"))]
if cat_id:
cat_id = cat_id and int(cat_id) or 0
domain = [('pos_categ_id.id', 'child_of', cat_id)] + domain
category_obj = request.registry.get('pos.category')
product_obj = request.registry.get('product.product')
category_ids = category_obj.search(cr, uid, [('parent_id', '=', False)])
product_ids = product_obj.search(cr, uid, domain or [(1, '=', 1)], limit=20, offset=offset)
product_ids = product_obj.search(request.cr, request.uid, domain, limit=20, offset=offset)
values.update({
values = {
'current_category': cat_id,
'categories': category_obj.browse(cr, uid, category_ids),
'products': product_obj.browse(cr, uid, product_ids),
'products': product_obj.browse(request.cr, request.uid, product_ids),
'search': post.get("search"),
})
html = request.registry.get("ir.ui.view").render(cr, uid, "website_sale.products", values)
}
html = self.render("website_sale.products", values)
return html
@http.route(['/shop/product/<product_id>'], type='http', auth="admin")
@http.route(['/shop/product/<product_id>'], type='http', auth="public")
def product(self, cat_id=0, product_id=0):
values = self.get_values()
cr, uid, partner_id = self.get_cr_uid()
order = self.get_current_order()
product_id = product_id and int(product_id) or 0
product_obj = request.registry.get('product.product')
line = [line for line in values['order'].order_line if line.product_id.id == product_id]
line = [line for line in order.order_line if line.product_id.id == product_id]
quantity = line and int(line[0].product_uom_qty) or 0
values.update({
'product': product_obj.browse(cr, uid, product_id),
values = {
'product': product_obj.browse(request.cr, request.uid, product_id),
'quantity': quantity,
'recommended_products': self.recommended_product([product_id]),
})
html = request.registry.get("ir.ui.view").render(cr, uid, "website_sale.product", values)
}
html = self.render("website_sale.product", values)
return html
@http.route(['/shop/mycart'], type='http', auth="admin")
@http.route(['/shop/mycart'], type='http', auth="public")
def mycart(self, **post):
cr, uid, partner_id = self.get_cr_uid()
values = self.get_values()
order = self.get_current_order()
if post.get('code'):
pricelist_obj = request.registry.get('product.pricelist')
order_obj = request.registry.get('sale.order')
pricelist_ids = pricelist_obj.search(cr, uid, [('code', '=', post.get('code'))])
pricelist_ids = pricelist_obj.search(request.cr, openerp.SUPERUSER_ID, [('code', '=', post.get('code'))])
if pricelist_ids:
values["order"].write({'pricelist_id': pricelist_ids[0]})
order.write({'pricelist_id': pricelist_ids[0]})
my_pids = [line.product_id.id for line in values['order'].order_line]
values["recommended_products"] = self.recommended_product(my_pids)
my_pids = [line.product_id.id for line in order.order_line]
values= {"recommended_products": self.recommended_product(my_pids)}
html = request.registry.get("ir.ui.view").render(cr, uid, "website_sale.mycart", values)
html = self.render("website_sale.mycart", values)
return html
@http.route(['/shop/add_cart'], type='http', auth="admin")
@http.route(['/shop/add_cart'], type='http', auth="public")
def add_cart(self, product_id=0, remove=False):
cr, uid, partner_id = self.get_cr_uid()
values = self.get_values()
context = {}
order_obj = request.registry.get('sale.order')
order_line_obj = request.registry.get('sale.order.line')
user_obj = request.registry.get('res.users')
product_id = product_id and int(product_id) or 0
order = values['order']
order = self.get_current_order()
quantity = 0
# values initialisation
order_line_ids = order_line_obj.search(cr, uid, [('order_id', '=', order.id), ('product_id', '=', product_id)], context=context)
order_line_ids = order_line_obj.search(request.cr, openerp.SUPERUSER_ID, [('order_id', '=', order.id), ('product_id', '=', product_id)], context=context)
values = {}
if order_line_ids:
order_line = order_line_obj.read(cr, uid, order_line_ids, [], context=context)[0]
order_line = order_line_obj.read(request.cr, openerp.SUPERUSER_ID, order_line_ids, [], context=context)[0]
quantity = order_line['product_uom_qty'] + (remove and -1 or 1)
if quantity <= 0:
order_line_obj.unlink(cr, uid, order_line_ids, context=context)
order_line_obj.unlink(request.cr, openerp.SUPERUSER_ID, order_line_ids, context=context)
else:
fields = [k for k, v in order_line_obj._columns.items()]
values = order_line_obj.default_get(cr, uid, fields, context=context)
values = order_line_obj.default_get(request.cr, openerp.SUPERUSER_ID, fields, context=context)
quantity = 1
values['product_uom_qty'] = quantity
values['product_id'] = product_id
@ -177,28 +156,26 @@ class Ecommerce(http.Controller):
# change and record value
if quantity:
pricelist_id = order.pricelist_id and order.pricelist_id.id or False
values.update(order_line_obj.product_id_change(cr, uid, [], pricelist_id, product_id,
partner_id=partner_id or request.registry.get('res.users').browse(cr, uid, uid).partner_id.id,
values.update(order_line_obj.product_id_change(request.cr, openerp.SUPERUSER_ID, [], pricelist_id, product_id,
partner_id=user_obj.browse(request.cr, openerp.SUPERUSER_ID, request.uid).partner_id.id,
context=context)['value'])
if order_line_ids:
order_line_obj.write(cr, uid, order_line_ids, values, context=context)
order_line_obj.write(request.cr, openerp.SUPERUSER_ID, order_line_ids, values, context=context)
else:
order_line_id = order_line_obj.create(cr, uid, values, context=context)
order_line_id = order_line_obj.create(request.cr, openerp.SUPERUSER_ID, values, context=context)
order.write({'order_line': [(4, order_line_id)]}, context=context)
html = request.registry.get("ir.ui.view").render(cr, uid, "website_sale.total", self.get_values())
html = self.render("website_sale.total")
return simplejson.dumps({"quantity": quantity, "totalHTML": html})
@http.route(['/shop/remove_cart'], type='http', auth="admin")
@http.route(['/shop/remove_cart'], type='http', auth="public")
def remove_cart(self, product_id=0):
return self.add_cart(product_id=product_id, remove=True)
@http.route(['/shop/checkout'], type='http', auth="admin")
@http.route(['/shop/checkout'], type='http', auth="public")
def checkout(self, **post):
cr, uid, partner_id = self.get_cr_uid()
values = self.get_values()
order = values['order']
order = self.get_current_order()
if order.state != 'draft':
return self.confirmed(**post)
@ -211,41 +188,38 @@ class Ecommerce(http.Controller):
country_state_obj = request.registry.get('res.country.state')
payment_obj = request.registry.get('portal.payment.acquirer')
values['partner'] = False
values = {'partner': False}
if post.get("login"):
user_id = user_obj.login(cr, post.get("login"), post.get("password"))
partner_id = user_obj.browse(cr, uid, user_id).partner_id.id
if partner_id:
values['partner'] = partner_obj.browse(cr, uid, partner_id)
shipping_ids = partner_obj.search(cr, uid, [("parent_id", "=", partner_id), ('type', "=", 'delivery')])
if request.uid != request.public_uid:
values['partner'] = user_obj.browse(request.cr, request.uid, request.uid).partner_id
shipping_ids = partner_obj.search(request.cr, request.uid, [("parent_id", "=", values['partner'].id), ('type', "=", 'delivery')])
values['shipping'] = None
if shipping_ids:
values['shipping'] = partner_obj.browse(cr, uid, shipping_ids[0])
values['shipping'] = partner_obj.browse(request.cr, request.uid, shipping_ids[0])
values['countries'] = country_obj.browse(cr, uid, country_obj.search(cr, uid, [(1, "=", 1)]))
values['states'] = country_state_obj.browse(cr, uid, country_state_obj.search(cr, uid, [(1, "=", 1)]))
values['countries'] = country_obj.browse(request.cr, openerp.SUPERUSER_ID, country_obj.search(request.cr, openerp.SUPERUSER_ID, [(1, "=", 1)]))
values['states'] = country_state_obj.browse(request.cr, openerp.SUPERUSER_ID, country_state_obj.search(request.cr, openerp.SUPERUSER_ID, [(1, "=", 1)]))
payment_ids = payment_obj.search(cr, uid, [('visible', '=', True)])
values['payments'] = payment_obj.browse(cr, uid, payment_ids)
payment_ids = payment_obj.search(request.cr, openerp.SUPERUSER_ID, [('visible', '=', True)])
values['payments'] = payment_obj.browse(request.cr, openerp.SUPERUSER_ID, payment_ids)
for payment in values['payments']:
content = payment_obj.render(cr, uid, payment.id, order, order.name, order.pricelist_id.currency_id, order.amount_total)
content = payment_obj.render(request.cr, openerp.SUPERUSER_ID, payment.id, order, order.name, order.pricelist_id.currency_id, order.amount_total)
payment._content = content
return request.registry.get("ir.ui.view").render(cr, uid, "website_sale.checkout", values)
return self.render("website_sale.checkout", values)
@http.route(['/shop/confirm_order'], type='http', auth="admin")
@http.route(['/shop/confirm_order'], type='http', auth="public")
def confirm_order(self, **post):
cr, uid, partner_id = self.get_cr_uid()
values = self.get_values()
order = self.get_current_order()
json = {'error': [], 'validation': False}
partner_obj = request.registry.get('res.partner')
user_obj = request.registry.get('res.users')
if values['order'].state != 'draft':
if order.state != 'draft':
json['validation'] = True
return json
if not values['order'].order_line:
if not order.order_line:
json['error'].append("empty_cart")
return json
@ -262,10 +236,10 @@ class Ecommerce(http.Controller):
# search or create company
company_id = None
if post['company']:
company_ids = partner_obj.search(cr, uid, [("name", "ilike", post['company']), ('is_company', '=', True)])
company_ids = partner_obj.search(request.cr, openerp.SUPERUSER_ID, [("name", "ilike", post['company']), ('is_company', '=', True)])
company_id = company_ids and company_ids[0] or None
if not company_id:
company_id = partner_obj.create(cr, uid, {'name': post['company'], 'is_company': True})
company_id = partner_obj.create(request.cr, openerp.SUPERUSER_ID, {'name': post['company'], 'is_company': True})
partner_value = {
'fax': post['fax'],
@ -279,10 +253,11 @@ class Ecommerce(http.Controller):
'country_id': post['country_id'],
'state_id': post['state_id'],
}
if partner_id:
partner_obj.write(cr, uid, [partner_id], partner_value)
if request.uid != request.public_uid:
partner_id = user_obj.browse(request.cr, request.uid, request.uid).partner_id.id
partner_obj.write(request.cr, request.uid, [partner_id], partner_value)
else:
partner_id = partner_obj.create(cr, uid, partner_value)
partner_id = partner_obj.create(request.cr, openerp.SUPERUSER_ID, partner_value)
shipping_id = None
if 'shipping_name' in post:
@ -300,12 +275,12 @@ class Ecommerce(http.Controller):
}
domain = [(key, '_id' in key and '=' or 'ilike', '_id' in key and int(value) or value)
for key, value in shipping_value.items() if key in required_field + ["type", "parent_id"]]
shipping_ids = partner_obj.search(cr, uid, domain)
shipping_ids = partner_obj.search(request.cr, openerp.SUPERUSER_ID, domain)
if shipping_ids:
shipping_id = shipping_ids[0]
partner_obj.write(cr, uid, [shipping_id], shipping_value)
partner_obj.write(request.cr, openerp.SUPERUSER_ID, [shipping_id], shipping_value)
else:
shipping_id = partner_obj.create(cr, uid, shipping_value)
shipping_id = partner_obj.create(request.cr, openerp.SUPERUSER_ID, shipping_value)
order_value = {
'state': 'progress',
@ -313,33 +288,41 @@ class Ecommerce(http.Controller):
'partner_invoice_id': partner_id,
'partner_shipping_id': shipping_id or partner_id
}
order_value.update(request.registry.get('sale.order').onchange_partner_id(cr, uid, [], uid, context={})['value'])
values['order'].write(order_value)
order_value.update(request.registry.get('sale.order').onchange_partner_id(request.cr, openerp.SUPERUSER_ID, [], request.uid, context={})['value'])
order.write(order_value)
json['validation'] = True
return simplejson.dumps(json)
@http.route(['/shop/confirmed'], type='http', auth="admin")
@http.route(['/shop/confirmed'], type='http', auth="public")
def confirmed(self, **post):
cr, uid, partner_id = self.get_cr_uid()
if request.httprequest.session.get('ecommerce_order'):
order = self.get_order(request.httprequest.session.get('ecommerce_order'))
if request.httprequest.session.get('ecommerce_order_id'):
order = self.get_current_order()
if order.state != 'draft':
request.httprequest.session['ecommerce_order_old'] = order.id
request.httprequest.session['ecommerce_order'] = None
request.httprequest.session['ecommerce_order_id_old'] = order.id
request.httprequest.session['ecommerce_order_id'] = None
order_old = self.get_order(request.httprequest.session.get('ecommerce_order_old'))
order_old = self.get_order(request.httprequest.session.get('ecommerce_order_id_old'))
if not order_old.order_line:
return self.mycart(**post)
values = template_values()
values.update({
values = {
'temp': 0,
'res_company': request.registry['res.company'].browse(request.cr, 1, 1),
'order': order_old,
'categories': self.get_categories(),
})
return request.registry.get("ir.ui.view").render(cr, uid, "website_sale.confirmed", values)
}
return self.render("website_sale.confirmed", values)
@http.route(['/shop/publish'], type='http', auth="public")
def publish(self, **post):
product_id = int(post['id'])
product_obj = request.registry['product.product']
product = product_obj.browse(request.cr, request.uid, product_id)
product_obj.write(request.cr, request.uid, [product_id], {'website_published': not product.website_published})
product = product_obj.browse(request.cr, request.uid, product_id)
return product.website_published and "1" or "0"
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
from openerp.osv import osv, fields
class product_pricelist(osv.osv):
_inherit = "product.product"
_columns = {
'website_published': fields.boolean('Available in the website'),
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="product_product_public" model="ir.rule">
<field name="name">product: Public product</field>
<field name="model_id" ref="product.model_product_product"/>
<field name="domain_force">[('website_published', '=', True), ("sale_ok", "=", True)]</field>
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
</record>
</data>
</openerp>

View File

@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_product_product_public,product.product.public,product.model_product_product,base.group_public,1,0,0,0
access_point_of_sale_category_public,point_of_sale.category.public,point_of_sale.model_pos_category,base.group_public,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_product_product_public product.product.public product.model_product_product base.group_public 1 0 0 0
3 access_point_of_sale_category_public point_of_sale.category.public point_of_sale.model_pos_category base.group_public 1 0 0 0

View File

@ -1,2 +1,2 @@
sass:
sass --compass --trace -t expanded ecommerce.sass ecommerce.css
sass --compass --trace -t expanded --watch ecommerce.sass:ecommerce.css

View File

@ -1,200 +0,0 @@
.oe_ecommerce .oe_total {
font-size: 13px;
margin-top: 10px;
}
.oe_ecommerce .oe_total td {
padding: 5px 10px;
}
.oe_ecommerce .oe_total table {
width: auto;
}
.oe_ecommerce .oe_total td:last-child {
text-align: right;
}
.oe_ecommerce .oe_total th:last-child {
text-align: center;
}
.oe_ecommerce .oe_products .oe_product {
text-align: center;
display: inline-block;
padding: 4px;
width: 180px;
height: 220px;
margin-right: 15px;
margin-left: 3px;
padding-top: 8px;
}
.oe_ecommerce .oe_products .oe_product .oe_hidden {
visibility: hidden;
}
.oe_ecommerce .oe_products .oe_product .pull-left {
margin: 0;
float: none;
}
.oe_ecommerce .oe_products .oe_product .oe_ecommerce_description {
display: none;
}
.oe_ecommerce .oe_products .oe_product h4 {
text-align: center;
text-shadow: 0px 1px 1px rgba(200, 200, 200, 0.2);
margin-bottom: 16px;
}
.oe_ecommerce .oe_products .oe_product img {
max-height: 110px;
max-width: 130px;
margin: 0 auto;
padding-bottom: 14px;
}
.oe_ecommerce .oe_products .oe_product:nth-child(3n) {
margin-right: 0;
}
.oe_ecommerce .oe_products .oe_product .oe_ecommerce_price {
width: 100%;
position: absolute;
bottom: 44px;
text-shadow: 0px 1px 3px rgba(255, 255, 255, 0.7);
text-align: center;
font-size: 25px;
}
.oe_ecommerce .oe_products .oe_product .oe_ecommerce_price span {
font-weight: bold;
}
.oe_ecommerce .oe_products .oe_product .oe_button_cart {
bottom: 5px;
left: 0;
}
.oe_ecommerce .oe_products .oe_product .oe_button_cart .btn-inverse {
display: none;
}
.oe_ecommerce .oe_mycart .oe_product {
display: inline-block;
width: 250px;
margin-left: 0px;
float: none;
margin-right: 16px;
padding: 8px 5px 6px 10px;
}
.oe_ecommerce .oe_mycart .oe_product > .pull-left {
width: 84px;
height: 64px;
}
.oe_ecommerce .oe_mycart .oe_product > .pull-left img {
max-width: 64px;
max-height: 64px;
margin: auto;
}
.oe_ecommerce .oe_mycart .oe_product .oe_button_cart {
position: static;
right: 6px;
top: 6px;
}
.oe_ecommerce .oe_mycart form input {
margin-bottom: 0;
}
.oe_ecommerce .oe_product {
vertical-align: top;
position: relative;
margin-top: 0;
margin-bottom: 15px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
border: 1px solid rgba(0, 0, 0, 0.1);
-webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);
}
.oe_ecommerce .oe_button_cart {
width: 100%;
font-size: 11px;
position: absolute;
}
.oe_ecommerce .oe_button_cart button {
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.44);
overflow: hidden;
text-align: center;
font-size: 12px;
margin: 0 auto;
margin-bottom: 5px;
padding: 2px;
height: 22px;
position: relative;
}
.oe_ecommerce .oe_button_cart button.btn-inverse {
background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #aaaaaa), color-stop(100%, #999999));
background: -webkit-linear-gradient(#aaaaaa, #999999);
background: -moz-linear-gradient(#aaaaaa, #999999);
background: -o-linear-gradient(#aaaaaa, #999999);
background: linear-gradient(#aaaaaa, #999999);
}
.oe_ecommerce .oe_button_cart button.btn-primary {
background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #0088cc), color-stop(100%, #0076b1));
background: -webkit-linear-gradient(#0088cc, #0076b1);
background: -moz-linear-gradient(#0088cc, #0076b1);
background: -o-linear-gradient(#0088cc, #0076b1);
background: linear-gradient(#0088cc, #0076b1);
}
.oe_ecommerce .oe_button_cart button.btn-success {
background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #51a351), color-stop(100%, #418541));
background: -webkit-linear-gradient(#51a351, #418541);
background: -moz-linear-gradient(#51a351, #418541);
background: -o-linear-gradient(#51a351, #418541);
background: linear-gradient(#51a351, #418541);
}
.oe_ecommerce .oe_search form {
width: 100%;
margin: 24px;
text-align: center;
}
.oe_ecommerce .oe_product_detail .oe_button_cart {
position: relative;
text-align: right;
}
.oe_ecommerce .oe_recommended a {
margin: 0 3px;
}
.oe_ecommerce .oe_recommended img {
max-width: 64px;
max-height: 64px;
}
.oe_ecommerce .oe_checkout h4 {
border-bottom: 1px solid #dddddd;
margin-right: 30px;
}
.oe_ecommerce .oe_checkout input:not([type="radio"]):not([type="checkbox"]):not([type="image"]) {
height: 20px;
}
.oe_ecommerce .oe_checkout input[type="image"] {
height: 30px;
}
.oe_ecommerce .oe_checkout label > input:not([type="radio"]):not([type="checkbox"]), .oe_ecommerce .oe_checkout label > div, .oe_ecommerce .oe_checkout label > select {
display: block;
margin-top: 3px;
}
.oe_ecommerce .oe_checkout label select {
margin-top: 3px;
}
.oe_ecommerce .oe_checkout label > div > input {
margin-bottom: 0;
}
.oe_ecommerce .oe_checkout .css_payments {
clear: both;
}
.oe_ecommerce .oe_checkout .css_payments .css_payment {
position: relative;
width: 80px;
overflow: hidden;
height: 30px;
text-align: center;
padding: 10px 10px 0 0;
}
.oe_ecommerce .oe_checkout .css_payments .css_error_payment {
width: 100%;
height: 100%;
position: absolute;
top: +O;
left: 0;
cursor: pointer;
}

View File

@ -1,6 +1,6 @@
@import "compass/css3"
.oe_ecommerce
//.oe_ecommerce
.oe_total
font-size: 13px
margin-top: 10px

View File

@ -1,4 +1,21 @@
$(document).ready(function () {
$('.oe_ecommerce').on('click', '.js_publish, .js_unpublish', function (e) {
e.preventDefault();
var $link = $(this).parent();
$link.find('.js_publish, .js_unpublish').addClass("hidden");
var $unp = $link.find(".js_unpublish");
var $p = $link.find(".js_publish");
$.post('/shop/publish', {'id': $link.data('id')}, function (result) {
if (+result) {
$p.addClass("hidden");
$unp.removeClass("hidden");
} else {
$p.removeClass("hidden");
$unp.addClass("hidden");
}
});
});
$('.oe_ecommerce').on('click', '.oe_product .btn, .oe_product_detail .btn', function (e) {
var $button = $(e.currentTarget);
var $product = $button.parents('.oe_product:first, .oe_product_detail:first');
@ -13,7 +30,7 @@ $(document).ready(function () {
.html(quantity);
$add.toggleClass('btn-primary', !quantity)
.toggleClass('btn-success', !!quantity);
$remove.toggleClass('oe_hidden', !quantity);
$remove.toggleClass('hidden', !quantity);
if ($('.oe_mycart').size() && !quantity) {
$product.remove()
}
@ -48,4 +65,4 @@ $(document).ready(function () {
}
});
});
});
});

View File

@ -16,6 +16,31 @@
</data>
</field>
</record>
<record id="header_ecommerce" model="ir.ui.view">
<field name="name">header_ecommerce</field>
<field name="inherit_id" ref="website.header"/>
<field name="arch" type="xml">
<data>
<xpath expr="(//li)[last()]" position="after">
<li class="pull-right"><a href="/shop/mycart"><i class="icon-shopping-cart icon-large" style="position: absolute;"></i>&amp;nbsp; &amp;nbsp; &amp;nbsp; My cart</a></li>
<li class="pull-right"><a href="/shop">Shop</a></li>
</xpath>
</data>
</field>
</record>
<record id="product_normal_form_view" model="ir.ui.view">
<field name="name">product.normal.form.inherit</field>
<field name="model">product.product</field>
<field name="inherit_id" ref="stock.view_normal_procurement_locations_form"/>
<field name="arch" type="xml">
<group name="sale" position="before">
<group name="pos" string="Website">
<field name="website_published"/>
</group>
</group>
</field>
</record>
<!-- Page Shop -->
@ -36,10 +61,7 @@
</t>
</ul>
</div>
<div class="span8">
<t t-raw="shop_content">
</t>
</div>
<t t-raw="shop_content"></t>
</div>
</div>
</t>
@ -49,7 +71,7 @@
<template id="categories_recursive">
<li t-att-class="category.id == current_category and 'active' or ''">
<a t-att-href="'/shop/category/%%s' %% category.id"><span t-record="category" t-field="name"><t t-esc="category.name"/></span></a>
<a t-att-href="'/shop/category/%%s' %% category.id"><span t-field="category.name"><t t-esc="category.name"/></span></a>
<ul t-if="category.child_id" class="nav nav-list">
<t t-foreach="category.child_id" t-as="category">
<t t-call="website_sale.categories_recursive"/>
@ -64,33 +86,64 @@
<t t-call="website_sale.page">
<t t-set="title">Product</t>
<t t-set="shop_content">
<div class="oe_search clearfix">
<form action="/shop" method="get" class="navbar-search pull-right">
<input type="text" name="search" class="search-query span4" placeholder="Search" t-att-value="search or '' or ''"/>
<button type="submit" class="btn">Submit</button>
</form>
<div class='span8 navbar navbar-inverse'>
<div class='navbar-inner'>
<div class='pagination pull-left'>
<ul>
<li><a href='#'>Prev</a></li>
<li class='active'><a href='#'>1</a></li>
<li><a href='#'>2</a></li>
<li><a href='#'>3</a></li>
<li><a href='#'>4</a></li>
<li><a href='#'>5</a></li>
<li><a href='#'>Next</a></li>
</ul>
</div>
<form action="/shop" method="get" class="navbar-search pull-right">
<input type="text" name="search" class="search-query span2" placeholder="Search" t-att-value="search or '' or ''"/>
</form>
</div>
</div>
<div class="span8">
<div class='row grid grid-align-top'>
<t t-foreach="products" t-as="product">
<t t-set="quantity" t-value="([int(line.product_uom_qty) for line in (order.order_line or []) if line.product_id.id == product.id] + [0])[0]"/>
<t t-call="website_sale.product_card"/>
</t>
</div>
</div>
<div class="span8 offset4 text-center">
<div class='pagination'>
<ul>
<li><a href='#'>Prev</a></li>
<li class='active'><a href='#'>1</a></li>
<li><a href='#'>2</a></li>
<li><a href='#'>3</a></li>
<li><a href='#'>4</a></li>
<li><a href='#'>5</a></li>
<li><a href='#'>Next</a></li>
</ul>
</div>
</div>
<span class="oe_products">
<t t-foreach="products" t-as="product">
<t t-set="quantity" t-value="([int(line.product_uom_qty) for line in (order.order_line or []) if line.product_id.id == product.id] + [0])[0]"/>
<t t-call="website_sale.product_card"/>
</t>
</span>
</t>
</t>
</template>
<template id="product_card">
<div class="media oe_product span3">
<a t-att-href="'/shop/product/%%s' %% product.id"><h4 class="media-heading"><span t-record="product" t-field="name"><t t-esc="product.name"/></span></h4></a>
<a class="pull-left" t-att-href="'/shop/product/%%s' %% product.id"><img class="media-object" t-att-src="'data:image/png;base64,' + product.image"/></a>
<div class="media-body">
<div class="oe_ecommerce_description" t-record="product" t-field="description_sale"><t t-esc="product.description_sale"/></div>
<div class="oe_ecommerce_price"><span><span t-record="product" t-field="list_price"><t t-esc="product.list_price"/></span></span></div>
<div class="oe_button_cart">
<button t-att-class="'btn btn-small btn-inverse %%s' %% (not quantity and 'oe_hidden' or '')" t-att-data-id="product.id">Remove one</button>
<button t-att-class="'btn btn-small %%s' %% (quantity and 'btn-success' or 'btn-primary')" t-att-data-id="product.id">Add to cart
<span class="oe_txt">(<span class="oe_quantity"><t t-esc="quantity"/></span>)</span>
<div class="oe_product span2 mb16 thumbnail text-center">
<a t-att-href="'/shop/product/%%s' %% product.id">
<h5 t-field="product.name"> </h5>
</a>
<a t-att-href="'/shop/product/%%s' %% product.id">
<img class="img-rounded" t-att-src="'data:image/png;base64,' + product.image"/>
</a>
<div>
<div t-field="product.description_sale">FIXME</div>
<div><span t-field="product.list_price"></span></div>
<div class="mb8 mt8">
<button t-att-class="'btn mb8 btn-small btn-inverse %%s' %% (not quantity and 'hidden' or '')" t-att-data-id="product.id">Remove one</button>
<button t-att-class="'btn btn-small %%s' %% (quantity and 'btn-success' or 'btn-primary')" t-att-data-id="product.id">
Add to cart <t t-if="quantity">(<t t-esc="quantity"/>)</t>
</button>
</div>
</div>
@ -112,17 +165,22 @@
<t t-call="website_sale.page">
<t t-set="title">Product</t>
<t t-set="shop_content">
<div class="oe_product_detail">
<h1><span t-record="product" t-field="name"><t t-esc="product.name"/></span></h1>
<div class="oe_product_detail span8">
<a href="#" t-att-data-id="product.id" class="pull-right" t-if="editable">
<span t-att-class="'label label-success js_unpublish %%s' %% (not product.website_published and 'hidden' or '')">Click to Unpublish</span>
<span t-att-class="'label label-important js_publish %%s' %% (product.website_published and 'hidden' or '')">Click to Publish</span>
</a>
<h2 t-field="product.name"></h2>
<div class="oe_button_cart">
<button t-att-class="'btn btn-inverse %%s' %% (not quantity and 'oe_hidden' or '')" t-att-data-id="product.id">Remove one</button>
<button t-att-class="'btn %%s' %% (quantity and 'btn-success' or 'btn-primary')" t-att-data-id="product.id">Add to cart
<span class="oe_txt">(<span class="oe_quantity"><t t-esc="quantity"/></span>)</span>
<button t-att-class="'btn btn-small btn-inverse %%s' %% (not quantity and 'oe_hidden' or '')" t-att-data-id="product.id">Remove one</button>
<button t-att-class="'btn btn-small %%s' %% (quantity and 'btn-success' or 'btn-primary')" t-att-data-id="product.id">
Add to cart <t t-if="quantity" >(<t t-esc="quantity"/>)</t>
</button>
</div>
<img class="media-object" t-att-src="'data:image/png;base64,' + product.image"/>
<div t-record="product" t-field="description_sale"><t t-esc="product.description_sale"/></div>
<div class="oe_ecommerce_price" t-record="product" t-field="list_price"><t t-esc="product.list_price"/></div>
<div t-field="product.description_sale"></div>
<div class="oe_ecommerce_price" t-field="product.list_price"><t t-esc="product.list_price"/></div>
<t t-call="website_sale.product_recommended"/>
</div>
</t>
@ -135,22 +193,24 @@
<t t-call="website_sale.page">
<t t-set="title">My cart</t>
<t t-set="shop_content">
<span class="oe_mycart">
<t t-foreach="order.order_line or []" t-as="line">
<t t-set="product" t-value="line.product_id"/>
<t t-set="quantity" t-value="int(line.product_uom_qty)"/>
<t t-call="website_sale.product_card"/>
</t>
<t t-call="website_sale.product_recommended"/>
<t t-call="website_sale.total"/>
<div class="media well well-small" t-if="order.order_line">
<form action="/shop/mycart" class="navbar-form">
<input name="code" type="text" placeholder="Reduction Code..."/>
<button class="btn">Submit your Reduction Code</button>
</form>
<div class="span8 oe_mycart">
<h2>My Shopping Cart</h2>
<h3 t-if="not order.order_line">Your cart is empty</h3>
<div class='row mt32 grid grid-align-top'>
<t t-foreach="order.order_line or []" t-as="line">
<t t-set="product" t-value="line.product_id"/>
<t t-set="quantity" t-value="int(line.product_uom_qty)"/>
<t t-call="website_sale.product_card"/>
</t>
</div>
<a t-if="order.order_line" href="/shop/checkout"><button class="btn btn-success">Next stage</button></a>
</span>
<t t-call="website_sale.total"/>
<form t-if="order.order_line" class="well form-search" action="/shop/mycart" >
<input name="code" class='input' type="text" placeholder="Reduction Code..."/>
<button class="btn">Apply Code</button>
</form>
<a t-if="order.order_line" href="/shop/checkout"><button class="btn btn-success">Proceed To Payment</button></a>
<t t-call="website_sale.product_recommended"/>
</div>
</t>
</t>
</template>
@ -158,14 +218,15 @@
<!-- Total Shop my cart -->
<template id="total">
<div class="oe_total">
<div class="media well well-small">
<table t-if="order.order_line">
<tr><td>Untaxed Amount</td><td><t t-esc="order.amount_untaxed"/></td></tr>
<tr><td>Taxes</td><td><t t-esc="order.amount_tax"/></td></tr>
<tr><td>Total</td><td><h3><t t-esc="order.amount_total"/></h3></td></tr>
</table>
<span t-if="not order.order_line">Your cart is empty</span>
<div class="row oe_total">
<div class="span4">
<div class="well">
<table class='table-equalized' t-if="order.order_line">
<tr> <td>Subtotal </td> <td><t t-esc="order.amount_untaxed"/></td></tr>
<tr> <td>Taxes </td> <td><t t-esc="order.amount_tax"/></td></tr>
<tr> <td><h4>Total</h4></td> <td><h4><t t-esc="order.amounttotal"/></h4></td></tr>
</table>
</div>
</div>
</div>
</template>