summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Delavallée <tde@openerp.com>2012-09-19 13:10:00 +0200
committerThibault Delavallée <tde@openerp.com>2012-09-19 13:10:00 +0200
commitfa27dde6c97add97226a27610845cef183353c26 (patch)
tree27698e9e87b5b3fbe3ff8b898a25140fbf16d774
parent9ec025be0ed4a896b37b0323fe427e39f6abb13c (diff)
parent819455b73cbc336142579c788445b4d4734bd83f (diff)
[MERGE] Merged with addons/trunk.
bzr revid: tde@openerp.com-20120919111000-w3xmyatd6new8ghm
-rw-r--r--addons/base_calendar/base_calendar_view.xml2
-rw-r--r--addons/base_setup/res_partner_view.xml7
-rw-r--r--addons/board/static/src/css/dashboard.css33
-rw-r--r--addons/board/static/src/css/dashboard.sass26
-rw-r--r--addons/board/static/src/js/dashboard.js6
-rw-r--r--addons/board/static/src/xml/board.xml2
-rw-r--r--addons/claim_from_delivery/__openerp__.py4
-rw-r--r--addons/claim_from_delivery/claim_delivery_data.xml11
-rw-r--r--addons/claim_from_delivery/claim_delivery_view.xml26
-rw-r--r--addons/delivery/delivery_view.xml8
-rw-r--r--addons/fetchmail/i18n/mk.po333
-rw-r--r--addons/hr_recruitment/hr_recruitment_view.xml4
-rw-r--r--addons/mail/__init__.py1
-rw-r--r--addons/mail/mail_message.py27
-rw-r--r--addons/mail/mail_vote.py39
-rw-r--r--addons/mail/security/ir.model.access.csv1
-rw-r--r--addons/mail/static/src/css/mail.css25
-rw-r--r--addons/mail/static/src/js/mail.js32
-rw-r--r--addons/mail/static/src/xml/mail.xml17
-rw-r--r--addons/mail/tests/test_mail.py32
-rw-r--r--addons/mrp/board_manufacturing_view.xml3
-rw-r--r--addons/note/note.py12
-rw-r--r--addons/note/note_demo.xml9
-rw-r--r--addons/note/note_view.xml21
-rw-r--r--addons/note/security/ir.rule.xml19
-rw-r--r--addons/portal_project_issue/portal_project_issue_view.xml1
-rw-r--r--addons/procurement/procurement.py2
-rw-r--r--addons/project_issue/project_issue_view.xml4
-rw-r--r--addons/purchase/purchase.py1
-rw-r--r--addons/purchase/stock_view.xml2
-rw-r--r--addons/sale/sale.py68
-rw-r--r--addons/sale/sale_view.xml3
-rw-r--r--addons/sale/stock_view.xml3
-rw-r--r--addons/sale/test/manual_order_policy.yml43
-rw-r--r--addons/stock/board_warehouse_view.xml2
-rw-r--r--addons/stock/report/report_stock_move_view.xml3
-rw-r--r--addons/stock/security/ir.model.access.csv7
-rw-r--r--addons/stock/stock.py42
-rw-r--r--addons/stock/stock_view.xml277
-rw-r--r--addons/stock/wizard/stock_fill_inventory.py12
-rw-r--r--addons/stock/wizard/stock_fill_inventory_view.xml24
-rw-r--r--addons/stock/wizard/stock_partial_picking.py2
42 files changed, 926 insertions, 270 deletions
diff --git a/addons/base_calendar/base_calendar_view.xml b/addons/base_calendar/base_calendar_view.xml
index 89066ce74bb..0ea2be4f37f 100644
--- a/addons/base_calendar/base_calendar_view.xml
+++ b/addons/base_calendar/base_calendar_view.xml
@@ -418,7 +418,7 @@
<field name="type">ir.actions.act_window</field>
<field name="res_model">calendar.event</field>
<field name="view_type">form</field>
- <field name="view_mode">tree,form,calendar</field>
+ <field name="view_mode">calendar,tree,form</field>
<field name="search_view_id" ref="view_calendar_event_filter"/>
</record>
diff --git a/addons/base_setup/res_partner_view.xml b/addons/base_setup/res_partner_view.xml
index 5e54c0b8629..15b80151831 100644
--- a/addons/base_setup/res_partner_view.xml
+++ b/addons/base_setup/res_partner_view.xml
@@ -9,14 +9,11 @@
<field name="inherit_id" ref="base.res_partner_kanban_view"/>
<field name="arch" type="xml">
<xpath expr="//div[@class='oe_kanban_partner_categories']" position="inside">
- <span class="oe_kanban_list_many2many" data-model="res.partner.category">
- <t t-foreach="record.category_id.raw_value" t-as="category">
- <span class="oe_tag" t-att-data-list_id="category"/>
- </t>
+ <span class="oe_kanban_list_many2many">
+ <field name="category_id"/>
</span>
</xpath>
</field>
</record>
-
</data>
</openerp>
diff --git a/addons/board/static/src/css/dashboard.css b/addons/board/static/src/css/dashboard.css
index ed66e338c81..f2bbcd07071 100644
--- a/addons/board/static/src/css/dashboard.css
+++ b/addons/board/static/src/css/dashboard.css
@@ -1,3 +1,36 @@
+.openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_0 {
+ width: 100%;
+}
+.openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_1, .openerp .oe_dashboard_layout_1 .oe_dashboard_column.index_2 {
+ display: none;
+}
+.openerp .oe_dashboard_layout_1-1 .oe_dashboard_column {
+ width: 50%;
+}
+.openerp .oe_dashboard_layout_1-1 .oe_dashboard_column.index_2 {
+ display: none;
+}
+.openerp .oe_dashboard_layout_1-1-1 .oe_dashboard_column {
+ width: 33%;
+}
+.openerp .oe_dashboard_layout_2-1 .oe_dashboard_column.index_0 {
+ width: 70%;
+}
+.openerp .oe_dashboard_layout_2-1 .oe_dashboard_column.index_1 {
+ width: 30%;
+}
+.openerp .oe_dashboard_layout_2-1 .oe_dashboard_column.index_2 {
+ display: none;
+}
+.openerp .oe_dashboard_layout_1-2 .oe_dashboard_column.index_0 {
+ width: 30%;
+}
+.openerp .oe_dashboard_layout_1-2 .oe_dashboard_column.index_1 {
+ width: 70%;
+}
+.openerp .oe_dashboard_layout_1-2 .oe_dashboard_column.index_2 {
+ display: none;
+}
.openerp .oe_dashboard_layout_selector ul {
white-space: nowrap;
}
diff --git a/addons/board/static/src/css/dashboard.sass b/addons/board/static/src/css/dashboard.sass
index 32f0e3b4f3a..122b6dc232c 100644
--- a/addons/board/static/src/css/dashboard.sass
+++ b/addons/board/static/src/css/dashboard.sass
@@ -9,6 +9,31 @@
box-shadow: $bsval
.openerp
+ .oe_dashboard_layout_1 .oe_dashboard_column
+ &.index_0
+ width: 100%
+ &.index_1, &.index_2
+ display: none
+ .oe_dashboard_layout_1-1 .oe_dashboard_column
+ width: 50%
+ &.index_2
+ display: none
+ .oe_dashboard_layout_1-1-1 .oe_dashboard_column
+ width: 33%
+ .oe_dashboard_layout_2-1 .oe_dashboard_column
+ &.index_0
+ width: 70%
+ &.index_1
+ width: 30%
+ &.index_2
+ display: none
+ .oe_dashboard_layout_1-2 .oe_dashboard_column
+ &.index_0
+ width: 30%
+ &.index_1
+ width: 70%
+ &.index_2
+ display: none
.oe_dashboard_layout_selector
ul
white-space: nowrap
@@ -98,3 +123,4 @@
> tbody
tr:nth-child(odd)
background: transparent
+
diff --git a/addons/board/static/src/js/dashboard.js b/addons/board/static/src/js/dashboard.js
index 9c37924144d..43d7ca76d39 100644
--- a/addons/board/static/src/js/dashboard.js
+++ b/addons/board/static/src/js/dashboard.js
@@ -24,6 +24,10 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
scroll: false
}).bind('sortstop', self.do_save_dashboard);
+ var old_title = this.__parentedParent.get('title');
+ this.__parentedParent.on_record_loaded.add_last(function(){
+ self.__parentedParent.set({ 'title' : old_title});
+ });
// Events
this.$el.find('.oe_dashboard_link_reset').click(this.on_reset);
this.$el.find('.oe_dashboard_link_change_layout').click(this.on_change_layout);
@@ -165,8 +169,6 @@ instance.web.form.DashBoard = instance.web.form.FormWidget.extend({
this.rpc('/web/view/add_custom', {
view_id: this.view.fields_view.view_id,
arch: arch
- }, function() {
- self.$el.find('.oe_dashboard_link_reset').show();
});
},
on_load_action: function(result, index, action_attrs) {
diff --git a/addons/board/static/src/xml/board.xml b/addons/board/static/src/xml/board.xml
index e13fa707776..03ede793036 100644
--- a/addons/board/static/src/xml/board.xml
+++ b/addons/board/static/src/xml/board.xml
@@ -1,7 +1,7 @@
<template>
<t t-name="DashBoard">
<div class="oe_dashboard_links">
- <button type="button" class="button oe_dashboard_link_reset" title="Reset Layout.." t-att-style="view.fields_view.custom_view_id ? null : 'display: none'">
+ <button type="button" class="button oe_dashboard_link_reset" title="Reset Layout.." t-att-style="view.fields_view.custom_view_id || session.debug ? null : 'display: none'">
<img src="/board/static/src/img/layout_2-1.png" width="16" height="16"/>
<span> Reset </span>
</button>
diff --git a/addons/claim_from_delivery/__openerp__.py b/addons/claim_from_delivery/__openerp__.py
index 9c4395927af..9e3f7f59ca2 100644
--- a/addons/claim_from_delivery/__openerp__.py
+++ b/addons/claim_from_delivery/__openerp__.py
@@ -30,7 +30,9 @@ Create a claim from a delivery order.
Adds a Claim link to the delivery order.
""",
- 'data' : ['claim_delivery_view.xml'],
+ 'data' : [
+ 'claim_delivery_view.xml',
+ 'claim_delivery_data.xml',],
'auto_install': False,
'installable': True,
'certificate' : '001101649349223746957',
diff --git a/addons/claim_from_delivery/claim_delivery_data.xml b/addons/claim_from_delivery/claim_delivery_data.xml
new file mode 100644
index 00000000000..1b69087d4b8
--- /dev/null
+++ b/addons/claim_from_delivery/claim_delivery_data.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<openerp>
+ <data>
+
+ <record model="res.request.link" id="request_link_claim_from_delivery">
+ <field name="name">Delivery Order</field>
+ <field name="object">stock.picking.out</field>
+ </record>
+
+ </data>
+</openerp>
diff --git a/addons/claim_from_delivery/claim_delivery_view.xml b/addons/claim_from_delivery/claim_delivery_view.xml
index f345484b4a9..9187b1d11ca 100644
--- a/addons/claim_from_delivery/claim_delivery_view.xml
+++ b/addons/claim_from_delivery/claim_delivery_view.xml
@@ -1,11 +1,27 @@
<openerp>
<data>
- <act_window id="action_claim_from_delivery" name="Claim"
- domain="[]" target="current"
- context="{'default_partner_id': partner_id}"
- view_mode="form" res_model="crm.claim"
- src_model="stock.picking" />
+ <record id="action_claim_from_delivery" model="ir.actions.act_window">
+ <field name="name">Claim From Delivery</field>
+ <field name="res_model">crm.claim</field>
+ <field name="view_type">form</field>
+ <field name="view_id" ref="crm_claim.crm_case_claims_tree_view"/>
+ <field name="context">{'default_ref': 'stock.picking.out,'+str(context.get('active_id', False))}</field>
+ <field name="domain">[('ref','=','stock.picking.out,'+str(context.get('active_id',False)))]</field>
+ </record>
+
+ <record id="crm_claim_from_delivery" model="ir.ui.view">
+ <field name="name">crm.claim.from_delivery.form</field>
+ <field name="model">stock.picking.out</field>
+ <field name="inherit_id" ref="stock.view_picking_out_form"/>
+ <field name="arch" type="xml">
+ <xpath expr="/form/sheet/h1" position="before">
+ <div class="oe_right oe_button_box">
+ <button name="%(action_claim_from_delivery)d" string="Claims" type="action"/>
+ </div>
+ </xpath>
+ </field>
+ </record>
</data>
</openerp>
diff --git a/addons/delivery/delivery_view.xml b/addons/delivery/delivery_view.xml
index 6a68d1a979f..deb59983ef2 100644
--- a/addons/delivery/delivery_view.xml
+++ b/addons/delivery/delivery_view.xml
@@ -259,10 +259,10 @@
<record id="view_picking_withweight_internal_move_form" model="ir.ui.view">
<field name="name">stock.picking_withweight.internal.move.form.view</field>
- <field name="model">stock.picking</field>
- <field name="inherit_id" ref="stock.view_picking_form"/>
+ <field name="model">stock.move</field>
+ <field name="inherit_id" ref="stock.view_move_picking_tree"/>
<field name="arch" type="xml">
- <xpath expr="/form/sheet/notebook/page/field[@name='move_lines']/tree/field[@name='product_uom']" position="after">
+ <xpath expr="//field[@name='product_uom']" position="after">
<field name="weight"/>
<field name="weight_net" groups="base.group_no_one"/>
</xpath>
@@ -306,7 +306,7 @@
<record id="view_delivery_order_inherit_stock" model="ir.ui.view">
<field name="name">stock.picking.out.form</field>
- <field name="model">stock.picking</field>
+ <field name="model">stock.picking.out</field>
<field name="inherit_id" ref="stock.view_picking_out_form"/>
<field name="arch" type="xml">
<xpath expr="/form/header//button[@string='Create Invoice/Refund']" position="after">
diff --git a/addons/fetchmail/i18n/mk.po b/addons/fetchmail/i18n/mk.po
new file mode 100644
index 00000000000..741b3547812
--- /dev/null
+++ b/addons/fetchmail/i18n/mk.po
@@ -0,0 +1,333 @@
+# Macedonian translation for openobject-addons
+# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
+# This file is distributed under the same license as the openobject-addons package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: openobject-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
+"POT-Creation-Date: 2012-02-08 00:36+0000\n"
+"PO-Revision-Date: 2012-09-18 16:07+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Macedonian <mk@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: 2012-09-19 04:37+0000\n"
+"X-Generator: Launchpad (build 15966)\n"
+
+#. module: fetchmail
+#: selection:fetchmail.server,state:0
+msgid "Confirmed"
+msgstr "Потврдено"
+
+#. module: fetchmail
+#: field:fetchmail.server,server:0
+msgid "Server Name"
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,script:0
+msgid "Script"
+msgstr ""
+
+#. module: fetchmail
+#: help:fetchmail.server,priority:0
+msgid "Defines the order of processing, lower values mean higher priority"
+msgstr ""
+
+#. module: fetchmail
+#: help:fetchmail.server,is_ssl:0
+msgid ""
+"Connections are encrypted with SSL/TLS through a dedicated port (default: "
+"IMAPS=993, POP3S=995)"
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,attach:0
+msgid "Keep Attachments"
+msgstr ""
+
+#. module: fetchmail
+#: help:fetchmail.server,original:0
+msgid ""
+"Whether a full original copy of each email should be kept for referenceand "
+"attached to each processed message. This will usually double the size of "
+"your message database."
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,priority:0
+msgid "Server Priority"
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,state:0
+msgid "State"
+msgstr "Состојба"
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "POP"
+msgstr "POP"
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "Fetch Now"
+msgstr ""
+
+#. module: fetchmail
+#: model:ir.actions.act_window,name:fetchmail.action_email_server_tree
+#: model:ir.ui.menu,name:fetchmail.menu_action_fetchmail_server_tree
+msgid "Incoming Mail Servers"
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,port:0
+msgid "Port"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "POP/IMAP Servers"
+msgstr "POP/IMAP сервери"
+
+#. module: fetchmail
+#: selection:fetchmail.server,type:0
+msgid "Local Server"
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,user:0
+msgid "Username"
+msgstr ""
+
+#. module: fetchmail
+#: model:ir.model,name:fetchmail.model_fetchmail_server
+msgid "POP/IMAP Server"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "Reset Confirmation"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "SSL"
+msgstr ""
+
+#. module: fetchmail
+#: model:ir.model,name:fetchmail.model_mail_message
+msgid "Email Message"
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,date:0
+msgid "Last Fetch Date"
+msgstr ""
+
+#. module: fetchmail
+#: help:fetchmail.server,action_id:0
+msgid ""
+"Optional custom server action to trigger for each incoming mail, on the "
+"record that was created or updated by this mail"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "# of emails"
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,original:0
+msgid "Keep Original"
+msgstr ""
+
+#. module: fetchmail
+#: code:addons/fetchmail/fetchmail.py:155
+#, python-format
+msgid ""
+"Here is what we got instead:\n"
+" %s"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+#: field:fetchmail.server,configuration:0
+msgid "Configuration"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "Incoming Mail Server"
+msgstr ""
+
+#. module: fetchmail
+#: code:addons/fetchmail/fetchmail.py:155
+#, python-format
+msgid "Connection test failed!"
+msgstr ""
+
+#. module: fetchmail
+#: help:fetchmail.server,server:0
+msgid "Hostname or IP of the mail server"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "Server type IMAP."
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,name:0
+msgid "Name"
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,is_ssl:0
+msgid "SSL/TLS"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "Test & Confirm"
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,action_id:0
+msgid "Server Action"
+msgstr ""
+
+#. module: fetchmail
+#: field:mail.message,fetchmail_server_id:0
+msgid "Inbound Mail Server"
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,message_ids:0
+#: model:ir.actions.act_window,name:fetchmail.act_server_history
+msgid "Messages"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "Search Incoming Mail Servers"
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,active:0
+msgid "Active"
+msgstr ""
+
+#. module: fetchmail
+#: help:fetchmail.server,attach:0
+msgid ""
+"Whether attachments should be downloaded. If not enabled, incoming emails "
+"will be stripped of any attachments before being processed"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "Advanced Options"
+msgstr ""
+
+#. module: fetchmail
+#: selection:fetchmail.server,type:0
+msgid "IMAP Server"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "IMAP"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "Server type POP."
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,password:0
+msgid "Password"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "Actions to Perform on Incoming Mails"
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,type:0
+msgid "Server Type"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "Login Information"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "Server Information"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "If SSL required."
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "Advanced"
+msgstr ""
+
+#. module: fetchmail
+#: view:fetchmail.server:0
+msgid "Server & Login"
+msgstr ""
+
+#. module: fetchmail
+#: help:fetchmail.server,object_id:0
+msgid ""
+"Process each incoming mail as part of a conversation corresponding to this "
+"document type. This will create new documents for new conversations, or "
+"attach follow-up emails to the existing conversations (documents)."
+msgstr ""
+
+#. module: fetchmail
+#: field:fetchmail.server,object_id:0
+msgid "Create a New Record"
+msgstr ""
+
+#. module: fetchmail
+#: selection:fetchmail.server,state:0
+msgid "Not Confirmed"
+msgstr "Непотврдено"
+
+#. module: fetchmail
+#: selection:fetchmail.server,type:0
+msgid "POP Server"
+msgstr ""
+
+#. module: fetchmail
+#: view:mail.message:0
+msgid "Mail Server"
+msgstr ""
+
+#~ msgid "Confirm"
+#~ msgstr "Потврди"
+
+#~ msgid "Group By..."
+#~ msgstr "Групирај по..."
+
+#~ msgid "Type"
+#~ msgstr "Вид"
+
+#~ msgid ""
+#~ "Warning! Record for selected Model can not be created\n"
+#~ "Please choose valid Model"
+#~ msgstr ""
+#~ "Предупредување! Записот за избраниот Модел не може да се креира\n"
+#~ "Изберете валиден Модел"
diff --git a/addons/hr_recruitment/hr_recruitment_view.xml b/addons/hr_recruitment/hr_recruitment_view.xml
index 098a8aec210..08e5f31a2d2 100644
--- a/addons/hr_recruitment/hr_recruitment_view.xml
+++ b/addons/hr_recruitment/hr_recruitment_view.xml
@@ -314,9 +314,7 @@
</div>
<div class="oe_kanban_footer_left" style="margin-top:5px;">
<div class="oe_left oe_tags">
- <t t-foreach="record.categ_ids.raw_value" t-as="categ_id">
- <span class="oe_tag" t-att-data-categ_id="categ_id"></span>
- </t>
+ <field name="categ_ids"/>
</div>
</div>
</div>
diff --git a/addons/mail/__init__.py b/addons/mail/__init__.py
index 9c51853f865..92e882ae6d8 100644
--- a/addons/mail/__init__.py
+++ b/addons/mail/__init__.py
@@ -26,6 +26,7 @@ import mail_message
import mail_mail
import mail_thread
import mail_group
+import mail_vote
import res_partner
import res_users
import report
diff --git a/addons/mail/mail_message.py b/addons/mail/mail_message.py
index d5cdc9fcfc3..65ee7f41d77 100644
--- a/addons/mail/mail_message.py
+++ b/addons/mail/mail_message.py
@@ -131,6 +131,8 @@ class mail_message(osv.Model):
type='boolean', string='Unread',
help='Functional field to search for unread messages linked to uid'),
'subtype_id': fields.many2one('mail.message.subtype', 'Subtype'),
+ 'vote_user_ids': fields.many2many('res.users', 'mail_vote', 'message_id', 'user_id', string='Votes',
+ help='Users that voted for this message'),
}
def _needaction_domain_get(self, cr, uid, context=None):
@@ -149,11 +151,34 @@ class mail_message(osv.Model):
}
#------------------------------------------------------
+ # Vote/Like
+ #------------------------------------------------------
+
+ def vote_toggle(self, cr, uid, ids, user_ids=None, context=None):
+ ''' Toggles voting '''
+ if not user_ids:
+ user_ids = [uid]
+ for message in self.read(cr, uid, ids, ['vote_user_ids'], context=context):
+ for user_id in user_ids:
+ has_voted = user_id in message.get('vote_user_ids')
+ if not has_voted:
+ self.write(cr, uid, message.get('id'), {'vote_user_ids': [(4, user_id)]}, context=context)
+ else:
+ self.write(cr, uid, message.get('id'), {'vote_user_ids': [(3, user_id)]}, context=context)
+ return True
+
+ #------------------------------------------------------
# Message loading for web interface
#------------------------------------------------------
def _message_dict_get(self, cr, uid, msg, context=None):
""" Return a dict representation of the message browse record. """
+ has_voted = False
+ vote_ids = self.pool.get('res.users').name_get(cr, uid, [user.id for user in msg.vote_user_ids], context=context)
+ for vote in vote_ids:
+ if vote[0] == uid:
+ has_voted = True
+ break
attachment_ids = [{'id': attach[0], 'name': attach[1]} for attach in self.pool.get('ir.attachment').name_get(cr, uid, [x.id for x in msg.attachment_ids], context=context)]
author_id = self.pool.get('res.partner').name_get(cr, uid, [msg.author_id.id], context=context)[0]
author_user_id = self.pool.get('res.users').name_get(cr, uid, [msg.author_id.user_ids[0].id], context=context)[0]
@@ -172,6 +197,8 @@ class mail_message(osv.Model):
'author_user_id': author_user_id,
'partner_ids': partner_ids,
'child_ids': [],
+ 'vote_user_ids': vote_ids,
+ 'has_voted': has_voted
}
def message_read_tree_flatten(self, cr, uid, messages, current_level, level, context=None):
diff --git a/addons/mail/mail_vote.py b/addons/mail/mail_vote.py
new file mode 100644
index 00000000000..1e439fe0aeb
--- /dev/null
+++ b/addons/mail/mail_vote.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2012-Today OpenERP SA (<http://www.openerp.com>).
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>
+#
+##############################################################################
+
+from osv import osv, fields
+
+
+class mail_vote(osv.Model):
+ ''' Mail vote feature allow users to like and unlike messages attached
+ to a document. This allows for example to build a ranking-based
+ displaying of messages, for FAQ. '''
+
+ _name = 'mail.vote'
+ _description = 'Mail Vote'
+ _columns = {
+ 'message_id': fields.many2one('mail.message', 'Message', select=1,
+ ondelete='cascade', required=True),
+ 'user_id': fields.many2one('res.users', 'User', select=1,
+ ondelete='cascade', required=True),
+ }
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/mail/security/ir.model.access.csv b/addons/mail/security/ir.model.access.csv
index 5680184a9fb..e06950ab3fc 100644
--- a/addons/mail/security/ir.model.access.csv
+++ b/addons/mail/security/ir.model.access.csv
@@ -11,3 +11,4 @@ access_mail_alias_system,mail.alias,model_mail_alias,base.group_system,1,1,1,1
access_mail_message_subtype,mail.message.subtype,model_mail_message_subtype,,1,1,1,1
access_mail_mail_user,mail.mail,model_mail_mail,base.group_user,1,1,1,0
access_mail_mail_manager,mail.mail,model_mail_mail,group_mail_manager,1,1,1,1
+access_mail_vote_all,mail.vote.all,model_mail_vote,,1,1,1,1
diff --git a/addons/mail/static/src/css/mail.css b/addons/mail/static/src/css/mail.css
index 48a178732b0..2f9b35f1c95 100644
--- a/addons/mail/static/src/css/mail.css
+++ b/addons/mail/static/src/css/mail.css
@@ -260,6 +260,31 @@
display: none;
}
+/*--------------------------------------------------------------*/
+/* mail.vote
+/*--------------------------------------------------------------*/
+
+.openerp .oe_mail_msg_content button.oe_mail_msg_vote {
+ height:21px;
+ width: 30px;
+ padding: 1px;
+ background: #8A89BA;
+ margin-top: -4px;
+}
+
+.openerp .oe_mail_msg_content button.oe_mail_msg_vote_true {
+ background:#DC5F59;
+}
+
+.openerp .oe_mail_msg_content button.oe_mail_msg_vote span {
+ color: white;
+}
+
+.openerp .oe_mail_msg_content span.oe_mail_vote_count{
+ color: #807FB4;
+}
+
+
/* ------------------------------------------------------------ */
/* mail.compose.message form view & OpenERP hacks
/* ------------------------------------------------------------ */
diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js
index 71665bc69fb..57c777441e7 100644
--- a/addons/mail/static/src/js/mail.js
+++ b/addons/mail/static/src/js/mail.js
@@ -291,6 +291,7 @@ openerp.mail = function(session) {
truncate_limit: options.truncate_limit || 250,
}
// datasets and internal vars
+ this.records = {};
this.ds_thread = new session.web.DataSetSearch(this, this.context.default_model);
this.ds_notification = new session.web.DataSetSearch(this, 'mail.notification');
this.ds_message = new session.web.DataSetSearch(this, 'mail.message');
@@ -355,6 +356,8 @@ openerp.mail = function(session) {
'default_parent_id': parseInt(msg_id),
'default_content_subtype': 'html'} );
});
+ // event: click on 'Vote' button
+ this.$el.on('click', 'button.oe_mail_msg_vote', this.on_vote);
},
on_message_delete: function (event) {
@@ -373,6 +376,16 @@ openerp.mail = function(session) {
return this.ds_notification.call('set_message_read', [parseInt(msg_id)]);
},
+ on_vote: function (event) {
+ event.stopPropagation();
+ var self = this;
+ var message_id = $(event.srcElement).parent().data().msg_id;
+ var vote_node = $(event.srcElement).parents('li').eq(0);
+ if (! message_id) { return false; }
+ return this.ds_message.call('vote_toggle', [[parseInt(message_id)]]).pipe(
+ self.toggle_vote(message_id, vote_node));
+ },
+
/**
* Override-hack of do_action: automatically reload the chatter.
* Normally it should be called only when clicking on 'Post/Send'
@@ -492,6 +505,8 @@ openerp.mail = function(session) {
attach['url'] = mail.ChatterUtils.get_attachment_url(this.session, attach);
}
record.is_author = mail.ChatterUtils.is_author(this, record.author_user_id[0]);
+ // add to internal storage
+ this.records[record.id] = record;
// render, add the expand feature
var rendered = session.web.qweb.render('mail.thread.message', {'record': record, 'thread': this, 'options': this.options});
$(rendered).appendTo(this.$el.children('div.oe_mail_thread_display:first'));
@@ -505,6 +520,23 @@ openerp.mail = function(session) {
});
},
+ // Render vote Display template.
+ toggle_vote: function (message_id, vote_node) {
+ var self = this;
+ var record = this.records[message_id];
+ if (record.has_voted) {
+ var idx = _.map(record.vote_user_ids, function (x) { return x[0]; }).indexOf(message_id);
+ record.vote_user_ids.splice(idx, 1);
+ }
+ else {
+ record.vote_user_ids.push([this.session.uid, 'You']);
+ }
+ record.has_voted = ! record.has_voted;
+ var vote_element = session.web.qweb.render('mail.thread.message.vote', {'record': record});
+ vote_node.empty();
+ vote_node.html(vote_element);
+ },
+
/** Display 'show more' button */
update_fetch_more: function (new_value) {
if (new_value) {
diff --git a/addons/mail/static/src/xml/mail.xml b/addons/mail/static/src/xml/mail.xml
index bf339f21f1c..e3586e723e4 100644
--- a/addons/mail/static/src/xml/mail.xml
+++ b/addons/mail/static/src/xml/mail.xml
@@ -142,11 +142,9 @@
</li>
<li><a t-attf-href="#model=res.partner&amp;id=#{record.author_id[0]}"><t t-raw="record.author_id[1]"/></a></li>
<li><span t-att-title="record.date"><t t-raw="record.timerelative"/></span></li>
+ <t t-call="mail.thread.message.vote"/>
<li t-if="options.show_reply"><a class="oe_mail_msg_reply">Reply</a></li>
<li t-if="options.show_reply_by_email"><a class="oe_mail_msg_reply_by_email" t-attf-data-msg_id="{record.id}">Reply</a></li>
- <!-- uncomment when merging vote
- <li><a href="#">Like</a></li>
- -->
<li t-if="record.attachment_ids.length > 0">
<a class="oe_mail_msg_view_attachments">
<t t-if="record.attachment_ids.length == 1">1 Attachment</t>
@@ -180,4 +178,17 @@
</ul>
</t>
+ <!-- mail.thread.message.vote
+ Template used to display Like/Unlike in a mail.message
+ -->
+ <li t-name="mail.thread.message.vote">
+ <t t-if='record.vote_user_ids.length > 0'>
+ <span class="oe_left oe_mail_vote_count"><t t-esc="record.vote_user_ids.length"/> votes</span>
+ </t>
+ <button t-attf-class="oe_mail_msg_vote oe_mail_msg_vote_#{record.has_voted}" t-attf-data-msg_id="{record.id}">
+ <t t-if="! record.has_voted"><span>+1</span></t>
+ <t t-if="record.has_voted"><span>-1</span></t>
+ </button>
+ </li>
+
</template>
diff --git a/addons/mail/tests/test_mail.py b/addons/mail/tests/test_mail.py
index ebaceaeaccb..2dfb7a75136 100644
--- a/addons/mail/tests/test_mail.py
+++ b/addons/mail/tests/test_mail.py
@@ -648,8 +648,37 @@ class test_mail(TestMailMockups):
msg1.refresh()
self.assertEqual(5, len(group_pigs.message_ids), 'group should contain 5 messages')
self.assertEqual(2, len(msg1.child_ids), 'msg1 should have 2 children now')
+
+ def test_60_vote(self):
+ """ Test designed for the vote/unvote feature. """
+ cr, uid = self.cr, self.uid
+ group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id)
+ msg1 = group_pigs.message_post(body='My Body', subject='1')
+ msg1 = self.mail_message.browse(cr, uid, msg1)
+
+ # Create user Bert Tartopoils
+ user_bert_id = self.res_users.create(cr, uid, {'name': 'Bert', 'login': 'bert'})
+ user_bert = self.res_users.browse(cr, uid, user_bert_id)
+
+ # Test: msg1 and msg2 have void vote_user_ids
+ self.assertFalse(msg1.vote_user_ids, 'newly created message msg1 has not void vote_user_ids')
+ # Do: Admin vote for msg1
+ self.mail_message.vote_toggle(cr, uid, [msg1.id])
+ msg1.refresh()
+ # Test: msg1 has Admin as voter
+ self.assertEqual(set(msg1.vote_user_ids), set([user_admin]), 'after voting, Admin is not the voter')
+ # Do: Bert vote for msg1
+ self.mail_message.vote_toggle(cr, uid, [msg1.id], [user_bert_id])
+ msg1.refresh()
+ # Test: msg1 has Admin and Bert as voters
+ self.assertEqual(set(msg1.vote_user_ids), set([user_admin, user_bert]), 'after voting, Admin and Bert are not the voters')
+ # Do: Admin unvote for msg1
+ self.mail_message.vote_toggle(cr, uid, [msg1.id])
+ msg1.refresh()
+ # Test: msg1 has Bert as voter
+ self.assertEqual(set(msg1.vote_user_ids), set([user_bert]), 'after unvoting for Admin, Bert is not the voter')
- def test_60_message_subtype(self):
+ def test_70_message_subtype(self):
""" Tests designed for message_subtype. """
cr, uid = self.cr, self.uid
self.res_users.write(cr, uid, [uid], {'signature': 'Admin', 'email': 'a@a'})
@@ -676,3 +705,4 @@ class test_mail(TestMailMockups):
msg_id = self.mail_group.message_post(cr, uid, [self.group_pigs_id], body=_body1, subject=_subject, type='comment',subtype_xml_id='mail_subtype_comment')
notif_ids = self.mail_notification.search(cr, uid, [('message_id', '=', msg_id)])
self.assertTrue(len(notif_ids) >= 1,"subtype is email and show notification on wall")
+
diff --git a/addons/mrp/board_manufacturing_view.xml b/addons/mrp/board_manufacturing_view.xml
index cae1fea07dc..6bd07c2648b 100644
--- a/addons/mrp/board_manufacturing_view.xml
+++ b/addons/mrp/board_manufacturing_view.xml
@@ -30,7 +30,8 @@
icon="terp-graph"
id="menu_board_manufacturing"
parent="base.menu_reporting_dashboard"
- sequence="30"/>
+ sequence="30"
+ groups="group_mrp_manager"/>
</data>
</openerp>
diff --git a/addons/note/note.py b/addons/note/note.py
index 65848ed7828..a7bad7f6a55 100644
--- a/addons/note/note.py
+++ b/addons/note/note.py
@@ -22,6 +22,7 @@
from openerp.osv import osv, fields
from tools.translate import _
import re
+from openerp.tools.misc import html2plaintext
class note_stage(osv.osv):
""" Category of Note """
@@ -65,23 +66,24 @@ class note_note(osv.osv):
text_note = (note.memo or '').strip().split('\n')[0]
text_note = re.sub(r'(\S?)(<br[ /]*>|<[/]?p>|<[/]?div>|<table>)[\s\S]*',r'\1',text_note)
text_note = re.sub(r'<[^>]+>','',text_note)
+ text_note = html2plaintext(text_note)
res[note.id] = text_note
return res
#unactivate a sticky note and record the date
def onclick_note_is_done(self, cr, uid, ids, context=None):
- self.write(cr, uid, ids, { 'active' : False, 'date_done' : fields.date.today() })
+ self.write(cr, uid, ids, { 'open' : False, 'date_done' : fields.date.today() })
self.message_post(cr, uid, ids[0], body='Note is done.', subject=False,
type='notification', parent_id=False, attachments=None, context=context)
return False
#activate a note
def onclick_note_not_done(self, cr, uid, ids, context=None):
- self.write(cr, uid, ids, {'active' : True})
+ self.write(cr, uid, ids, {'open' : True})
self.message_post(cr, uid, ids[0], body='Note has been activated.', subject=False,
type='notification', parent_id=False, attachments=None, context=context)
return False
-
+
#used for undisplay the follower if it's the current user
def _get_my_current_partner(self, cr, uid, ids, name, args, context=None):
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
@@ -119,14 +121,14 @@ class note_note(osv.osv):
type='many2one',
relation='note.stage'),
'stage_ids': fields.many2many('note.stage','note_stage_rel','note_id','stage_id','Stages of Users'),
- 'active': fields.boolean('Active'),
+ 'open': fields.boolean('Active'),
'date_done': fields.date('Date done'),
'color': fields.integer('Color Index'),
'tag_ids' : fields.many2many('note.tag','note_tags_rel','note_id','tag_id','Tags'),
'current_partner_id' : fields.function(_get_my_current_partner),
}
_defaults = {
- 'active' : 1,
+ 'open' : 1,
'stage_id' : _get_default_stage_id,
}
_order = 'sequence'
diff --git a/addons/note/note_demo.xml b/addons/note/note_demo.xml
index 82601f903c0..1cc1b2fc790 100644
--- a/addons/note/note_demo.xml
+++ b/addons/note/note_demo.xml
@@ -138,14 +138,5 @@
<field name="color">7</field>
</record>
- <record id="note_13" model="note.note">
- <field name="memo"><![CDATA[Read those books
- <br/><br/>* Open ERP: a modern approach to integrated business management
- <br/>* Open ERP for Retail and Industrial Management
- ]]>
- </field>
- <field name="stage_id" ref="note_stage_03"/>
- </record>
-
</data>
</openerp>
diff --git a/addons/note/note_view.xml b/addons/note/note_view.xml
index 1166e687750..ccb07544c09 100644
--- a/addons/note/note_view.xml
+++ b/addons/note/note_view.xml
@@ -1,7 +1,6 @@
<?xml version="1.0"?>
<openerp>
<data>
-
<menuitem name="Organizer" id="note_my_stuff" parent="mail.mail_feeds_main"/>
<!-- note Stage Form View -->
@@ -51,7 +50,7 @@
<field name="sequence"/>
<field name="name"/>
<field name="stage_id"/>
- <field name="active"/>
+ <field name="open"/>
<field name="memo"/>
<field name="date_done"/>
<field name="current_partner_id"/>
@@ -65,8 +64,8 @@
<div t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_global_click_edit oe_semantic_html_override oe_kanban_card #{record.group_fancy==1 ? 'oe_kanban_card_fancy' : ''}">
<div class="oe_dropdown_kanban">
<span>
- <a name="onclick_note_is_done" type="object" t-if="record.active.raw_value" class="oe_e">W</a>
- <a name="onclick_note_not_done" type="object" t-if="!record.active.raw_value" class="oe_e">è</a>
+ <a name="onclick_note_is_done" type="object" t-if="record.open.raw_value" class="oe_e">W</a>
+ <a name="onclick_note_not_done" type="object" t-if="!record.open.raw_value" class="oe_e">è</a>
</span>
<!-- dropdown menu -->
@@ -78,13 +77,12 @@
</ul>
</div>
</div>
-
<!-- kanban note -->
- <div t-attf-class="oe_kanban_content #{record.active.raw_value ? '' : 'note_text_line_through'}">
+ <div t-attf-class="oe_kanban_content #{record.open.raw_value ? '' : 'note_text_line_through'}">
<!-- title -->
<field name="name"/>
</div>
- <div widget="many2many_tags" t-att-data="record.tag_ids.raw_value" model="note.tag"/>
+ <field name="tag_ids"/>
<div class="oe_right">
<t t-foreach="record.message_follower_ids.raw_value" t-as="follower">
<img t-if="record.current_partner_id.raw_value!=follower" t-att-src="kanban_image('res.partner', 'image_small', follower)" width="24" height="24" class="oe_kanban_avatar" t-att-data-member_id="follower"/>
@@ -105,7 +103,7 @@
<field name="arch" type="xml">
<tree string="Stages">
<field name="name"/>
- <field name="active"/>
+ <field name="open"/>
<field name="stage_id"/>
<field name="tag_ids" widget="many2many_tags" groups="note.group_note_tags"/>
</tree>
@@ -139,9 +137,8 @@
<search string="Notes">
<field name="memo" string="Note"/>
<field name="tag_ids" groups="note.group_note_tags"/>
- <field name="stage_id"/>
- <filter name="active_true" string="Active" domain="['|',('active', '=', True),('date_done','=',time.strftime('%%Y-%%m-%%d'))]"/>
- <filter name="active_false" string="Old" domain="[('active', '=', False)]"/>
+ <filter name="open_true" string="Active" domain="['|',('open', '=', True),('date_done','=',time.strftime('%%Y-%%m-%%d'))]"/>
+ <filter name="open_false" string="Archive" domain="[('open', '=', False)]"/>
<group expand="0" string="Group By...">
<filter icon="terp-stock_symbol-selection" string="Stage" help="By sticky note Category" context="{'group_by':'stage_id'}"/>
</group>
@@ -185,7 +182,7 @@
<field name="view_type">form</field>
<field name="view_mode">kanban,tree,form</field>
<field name="search_view_id" ref="view_note_note_filter"/>
- <field name="context">{'search_default_active_true':True}</field>
+ <field name="context">{'search_default_open_true':True}</field>
</record>
<menuitem name="Notes" id="note_notes" parent="note_my_stuff" sequence="20" action="action_note_note"/>
diff --git a/addons/note/security/ir.rule.xml b/addons/note/security/ir.rule.xml
index 3d2f0d242f6..1195314cc9e 100644
--- a/addons/note/security/ir.rule.xml
+++ b/addons/note/security/ir.rule.xml
@@ -1,12 +1,19 @@
<?xml version="1.0"?>
<openerp>
<data>
- <record id="note_note_rule_global" model="ir.rule">
- <field name="name">Only followers can access a sticky notes</field>
- <field model="ir.model" ref="model_note_note" name="model_id"/>
- <field name="domain_force">['|',('message_follower_ids','=',False),('message_follower_ids','=',user.partner_id.id)]</field>
- <field eval="True" name="global"/>
- </record>
+ <record id="note_note_rule_global" model="ir.rule">
+ <field name="name">Only followers can access a sticky notes</field>
+ <field model="ir.model" ref="model_note_note" name="model_id"/>
+ <field name="domain_force">[('message_follower_ids','=',user.partner_id.id)]</field>
+ <field eval="True" name="global"/>
+ </record>
+
+ <record id="note_stage_rule_global" model="ir.rule">
+ <field name="name">Each user have his stage name</field>
+ <field model="ir.model" ref="model_note_stage" name="model_id"/>
+ <field name="domain_force">['|',('user_id','=',False),('user_id','=',user.id)]</field>
+ <field eval="True" name="global"/>
+ </record>
</data>
</openerp>
diff --git a/addons/portal_project_issue/portal_project_issue_view.xml b/addons/portal_project_issue/portal_project_issue_view.xml
index 5d0b4ce081e..1030dedbdf8 100644
--- a/addons/portal_project_issue/portal_project_issue_view.xml
+++ b/addons/portal_project_issue/portal_project_issue_view.xml
@@ -27,6 +27,7 @@
<t t-foreach="record.categ_ids.raw_value" t-as="categ_id">
<span class="oe_tag" t-att-data-categ_id="categ_id"></span>
</t>
+ <field name="categ_ids"/>
</div>
<div class="oe_right">
Creation: <field name="create_date"/>
diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py
index dcb47f1af88..950c295f27b 100644
--- a/addons/procurement/procurement.py
+++ b/addons/procurement/procurement.py
@@ -554,7 +554,7 @@ class stock_warehouse_orderpoint(osv.osv):
'logic': fields.selection([('max','Order to Max'),('price','Best price (not yet active!)')], 'Reordering Mode', required=True),
'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', required=True, ondelete="cascade"),
'location_id': fields.many2one('stock.location', 'Location', required=True, ondelete="cascade"),
- 'product_id': fields.many2one('product.product', 'Product', required=True, ondelete='cascade', domain=[('type','=','product')]),
+ 'product_id': fields.many2one('product.product', 'Product', required=True, ondelete='cascade', domain=[('type','!=','service')]),
'product_uom': fields.many2one('product.uom', 'Product Unit of Measure', required=True),
'product_min_qty': fields.float('Minimum Quantity', required=True,
help="When the virtual stock goes below the Min Quantity specified for this field, OpenERP generates "\
diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml
index fea22c519a8..be7427fe8f4 100644
--- a/addons/project_issue/project_issue_view.xml
+++ b/addons/project_issue/project_issue_view.xml
@@ -269,9 +269,7 @@
</div>
<div class="oe_kanban_footer_left">
<div class="oe_left oe_tags">
- <t t-foreach="record.categ_ids.raw_value" t-as="categ_id">
- <span class="oe_tag" t-att-data-categ_id="categ_id"></span>
- </t>
+ <field name="categ_ids"/>
</div>
<div class="oe_right">
<span class="oe_kanban_highlight">
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index b0f10d3f71f..8bcd6d39ef9 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -548,6 +548,7 @@ class purchase_order(osv.osv):
'partner_id': order.dest_address_id.id or order.partner_id.id,
'move_dest_id': order_line.move_dest_id.id,
'state': 'draft',
+ 'type':'in',
'purchase_line_id': order_line.id,
'company_id': order.company_id.id,
'price_unit': order_line.price_unit
diff --git a/addons/purchase/stock_view.xml b/addons/purchase/stock_view.xml
index b522618ed2e..21c52b4d2ec 100644
--- a/addons/purchase/stock_view.xml
+++ b/addons/purchase/stock_view.xml
@@ -31,7 +31,7 @@
<field name="purchase_id"/>
</xpath>
<xpath expr="//field[@name='company_id']" position="after">
- <field name="warehouse_id"/>
+ <field name="warehouse_id" groups="stock.group_locations"/>
</xpath>
</field>
</record>
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index 6767d841b08..cc6e5f71f30 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -145,6 +145,14 @@ class sale_order(osv.osv):
res[sale.id] = 0.0
return res
+ def _invoice_exists(self, cursor, user, ids, name, arg, context=None):
+ res = {}
+ for sale in self.browse(cursor, user, ids, context=context):
+ res[sale.id] = False
+ if sale.invoice_ids:
+ res[sale.id] = True
+ return res
+
def _invoiced(self, cursor, user, ids, name, arg, context=None):
res = {}
for sale in self.browse(cursor, user, ids, context=context):
@@ -156,7 +164,7 @@ class sale_order(osv.osv):
if invoice.state != 'paid':
res[sale.id] = False
break
- if not invoice_existence:
+ if not invoice_existence or sale.state == 'manual':
res[sale.id] = False
return res
@@ -245,6 +253,8 @@ class sale_order(osv.osv):
'invoiced_rate': fields.function(_invoiced_rate, string='Invoiced', type='float'),
'invoiced': fields.function(_invoiced, string='Paid',
fnct_search=_invoiced_search, type='boolean', help="It indicates that an invoice has been paid."),
+ 'invoice_exists': fields.function(_invoice_exists, string='Invoiced',
+ fnct_search=_invoiced_search, type='boolean', help="It indicates that sale order has at least one invoice."),
'note': fields.text('Terms and conditions'),
'amount_untaxed': fields.function(_amount_all, digits_compute= dp.get_precision('Account'), string='Untaxed Amount',
@@ -518,68 +528,45 @@ class sale_order(osv.osv):
This function returns an action that display existing invoices of given sale order ids. It can either be a in a list or in a form view, if there is only one invoice to show.
'''
mod_obj = self.pool.get('ir.model.data')
- result = {
- 'name': _('Cutomer Invoice'),
- 'view_type': 'form',
- 'res_model': 'account.invoice',
- 'context': "{'type':'out_invoice', 'journal_type': 'sale'}",
- 'type': 'ir.actions.act_window',
- 'nodestroy': True,
- 'target': 'current',
- }
+ act_obj = self.pool.get('ir.actions.act_window')
+
+ result = mod_obj.get_object_reference(cr, uid, 'account', 'action_invoice_tree1')
+ id = result and result[1] or False
+ result = act_obj.read(cr, uid, [id], context=context)[0]
#compute the number of invoices to display
inv_ids = []
for so in self.browse(cr, uid, ids, context=context):
inv_ids += [invoice.id for invoice in so.invoice_ids]
#choose the view_mode accordingly
if len(inv_ids)>1:
- res = mod_obj.get_object_reference(cr, uid, 'account', 'invoice_tree')
- result.update({
- 'view_mode': 'tree,form',
- 'res_id': inv_ids or False
- })
+ result['domain'] = "[('id','in',["+','.join(map(str, inv_ids))+"])]"
else:
res = mod_obj.get_object_reference(cr, uid, 'account', 'invoice_form')
- result.update({
- 'view_mode': 'form',
- 'res_id': inv_ids and inv_ids[0] or False,
- })
- result.update(view_id = res and res[1] or False)
+ result['views'] = [(res and res[1] or False, 'form')]
+ result['res_id'] = inv_ids and inv_ids[0] or False
return result
-
def action_view_delivery(self, cr, uid, ids, context=None):
'''
This function returns an action that display existing delivery orders of given sale order ids. It can either be a in a list or in a form view, if there is only one delivery order to show.
'''
mod_obj = self.pool.get('ir.model.data')
- result = {
- 'name': _('Delivery Order'),
- 'view_type': 'form',
- 'res_model': 'stock.picking',
- 'context': "{'type':'out'}",
- 'type': 'ir.actions.act_window',
- 'nodestroy': True,
- 'target': 'current',
- }
+ act_obj = self.pool.get('ir.actions.act_window')
+
+ result = mod_obj.get_object_reference(cr, uid, 'stock', 'action_picking_tree')
+ id = result and result[1] or False
+ result = act_obj.read(cr, uid, [id], context=context)[0]
#compute the number of delivery orders to display
pick_ids = []
for so in self.browse(cr, uid, ids, context=context):
pick_ids += [picking.id for picking in so.picking_ids]
#choose the view_mode accordingly
if len(pick_ids) > 1:
- res = mod_obj.get_object_reference(cr, uid, 'stock', 'view_picking_out_tree')
- result.update({
- 'view_mode': 'tree,form',
- 'res_id': pick_ids or False
- })
+ result['domain'] = "[('id','in',["+','.join(map(str, pick_ids))+"])]"
else:
res = mod_obj.get_object_reference(cr, uid, 'stock', 'view_picking_out_form')
- result.update({
- 'view_mode': 'form',
- 'res_id': pick_ids and pick_ids[0] or False,
- })
- result.update(view_id = res and res[1] or False)
+ result['views'] = [(res and res[1] or False, 'form')]
+ result['res_id'] = pick_ids and pick_ids[0] or False
return result
def test_no_product(self, cr, uid, order, context):
@@ -883,6 +870,7 @@ class sale_order(osv.osv):
'sale_line_id': line.id,
'tracking_id': False,
'state': 'draft',
+ 'type':'out',
#'state': 'waiting',
'note': '\n'.join(line.name.split('\n')[1:]),
'company_id': order.company_id.id,
diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml
index 651454ef73d..5c2320a7d5c 100644
--- a/addons/sale/sale_view.xml
+++ b/addons/sale/sale_view.xml
@@ -163,7 +163,7 @@
<button name="action_button_confirm" states="draft" string="Confirm" type="object"/>
<button name="action_button_confirm" states="sent" string="Confirm" class="oe_highlight" type="object"/>
<button name="action_view_invoice" string="View Invoice" type="object" class="oe_highlight"
- attrs="{'invisible': ['|','|',('state', '!=','progress'), ('invoiced', '=', True),('order_policy','=','picking')]}"/>
+ attrs="{'invisible': [('invoice_exists', '=', False)]}"/>
<button name="action_view_delivery" string="View Delivery Order" type="object" class="oe_highlight"
attrs="{'invisible': ['|','|','|',('picking_ids','=',False),('picking_ids','=',[]), ('state', 'not in', ('progress','manual')),('shipped','=',True)]}"/>
<button name="%(action_view_sale_advance_payment_inv)d" string="Create Invoice"
@@ -320,6 +320,7 @@
<group>
<field name="invoiced"/>
<field name="shipped"/>
+ <field name="invoice_exists" invisible="1"/>
</group>
</group>
</page>
diff --git a/addons/sale/stock_view.xml b/addons/sale/stock_view.xml
index eb0f1e415f5..0eb64f98e9b 100644
--- a/addons/sale/stock_view.xml
+++ b/addons/sale/stock_view.xml
@@ -9,9 +9,6 @@
<field name="move_type" position="before">
<field name="sale_id"/>
</field>
- <label for="partner_id" position="replace">
- <label for="partner_id" class="oe_edit_only" string="Contact"/>
- </label>
</field>
</record>
diff --git a/addons/sale/test/manual_order_policy.yml b/addons/sale/test/manual_order_policy.yml
index 3a8dcbd2f5b..17ebeb9f86b 100644
--- a/addons/sale/test/manual_order_policy.yml
+++ b/addons/sale/test/manual_order_policy.yml
@@ -1,5 +1,5 @@
-
- I confirm the Quotation with "Deliver & invoice on demand".
+ I confirm the Quotation with "On Demand" order policy.
-
!workflow {model: sale.order, action: order_confirm, ref: sale_order_2}
-
@@ -9,44 +9,34 @@
sale_order = self.browse(cr, uid, ref("sale_order_2"))
assert len(sale_order.invoice_ids) == False, "Invoice should not created."
-
- I create advance invoice.
+ I create advance invoice where type is 'Fixed Price'.
-
!python {model: sale.advance.payment.inv}: |
ctx = context.copy()
ctx.update({"active_model": 'sale.order', "active_ids": [ref("sale_order_2")], "active_id":ref("sale_order_2")})
order_line = self.pool.get('sale.order.line').browse(cr, uid, ref("sale_order_line_4"), context=context)
- pay_id = self.create(cr, uid, {'advance_payment_method': 'fixed', 'product_id': order_line.product_id.id, 'amount': order_line.price_subtotal, 'qtty': order_line.product_uom_qty})
+ pay_id = self.create(cr, uid, {'advance_payment_method': 'fixed', 'product_id': order_line.product_id.id, 'amount': order_line.price_unit})
self.create_invoices(cr, uid, [pay_id], context=ctx)
-
- I check Invoice which made advance
+ I check Invoice which made advance.
-
!python {model: sale.order}: |
order = self.browse(cr, uid, ref('sale_order_2'))
assert order.invoice_ids, "Invoice should be created after make advance invoice."
-
- I create Invoice from sale order line.
+ I create advance invoice where type is 'Invoice all the Sale Order'.
-
- !python {model: sale.order.line.make.invoice}: |
+ !python {model: sale.advance.payment.inv}: |
ctx = context.copy()
- ctx.update({"active_model": 'sale.order.line', "active_ids": [ref("sale_order_line_5")], "active_id":ref("sale_order_line_5")})
- self.make_invoices(cr, uid, [], context=ctx)
--
- I check Invoice which made from sale order line.
--
- !python {model: sale.order.line}: |
- line = self.browse(cr, uid, ref('sale_order_line_5'))
- assert line.invoiced, "Line is not invoiced."
- assert line.invoice_lines, "Invoice line should be created."
--
- I create manual Invoice for order.
+ ctx.update({"active_model": 'sale.order', "active_ids": [ref("sale_order_2")], "active_id":ref("sale_order_2")})
+ pay_id = self.create(cr, uid, {'advance_payment_method': 'all'})
+ self.create_invoices(cr, uid, [pay_id], context=ctx)
-
- !record {model: sale.make.invoice, id: sale_make_invoice_1}:
- invoice_date: !eval time.strftime('%Y-%m-%d')
+ I check Invoice which made advance where type is 'Invoice all the Sale Order'.
-
- !python {model: sale.make.invoice}: |
- ctx = context.copy()
- ctx = ctx.update({"active_model": 'sale.order', "active_ids": [ref("sale_order_2")], "active_id":ref("sale_order_2")})
- self.make_invoices(cr, uid, [ref("sale_make_invoice_1")], context)
+ !python {model: sale.order}: |
+ order = self.browse(cr, uid, ref('sale_order_2'))
+ assert order.invoice_ids, "Invoice should be created after make advance invoice where type is 'Invoice all the Sale Order'."
-
I open the Invoice.
-
@@ -57,7 +47,7 @@
for invoice in so.invoice_ids:
wf_service.trg_validate(uid, 'account.invoice', invoice.id, 'invoice_open', cr)
-
- I pay the invoice
+ I pay the invoice.
-
!python {model: account.invoice}: |
sale_order = self.pool.get('sale.order')
@@ -75,8 +65,9 @@
!python {model: sale.order}: |
sale_order = self.browse(cr, uid, ref("sale_order_2"))
assert sale_order.invoice_ids, "Invoice should be created."
- assert sale_order.invoiced, "Order is not invoiced."
- assert sale_order.state == 'manual', 'Order should be in Manual.'
+ assert sale_order.invoice_exists, "Order is not invoiced."
+ assert sale_order.invoiced, "Order is not paid."
+ assert sale_order.state == 'progress', 'Order should be in Progress.'
-
I set order policy "Deliver & invoice on demand" as default policy.
diff --git a/addons/stock/board_warehouse_view.xml b/addons/stock/board_warehouse_view.xml
index b223e731e8f..839a99c1fa7 100644
--- a/addons/stock/board_warehouse_view.xml
+++ b/addons/stock/board_warehouse_view.xml
@@ -61,7 +61,7 @@
parent="base.menu_reporting_dashboard"
action="open_board_warehouse"
sequence="25"
- groups="group_stock_manager"/>
+ groups="stock.group_stock_user"/>
</data>
</openerp>
diff --git a/addons/stock/report/report_stock_move_view.xml b/addons/stock/report/report_stock_move_view.xml
index a78a506cefe..4c911dd6e7c 100644
--- a/addons/stock/report/report_stock_move_view.xml
+++ b/addons/stock/report/report_stock_move_view.xml
@@ -6,7 +6,8 @@
id="stock.next_id_61"
name="Warehouse"
sequence="15"
- parent="base.menu_reporting"/>
+ parent="base.menu_reporting"
+ groups="group_stock_manager"/>
<record id="view_stock_tree" model="ir.ui.view">
<field name="name">report.stock.move.tree</field>
diff --git a/addons/stock/security/ir.model.access.csv b/addons/stock/security/ir.model.access.csv
index f56696bcbaa..b0ae333a9ef 100644
--- a/addons/stock/security/ir.model.access.csv
+++ b/addons/stock/security/ir.model.access.csv
@@ -21,11 +21,11 @@ access_stock_production_lot_manager,stock.production.lot manager,model_stock_pro
access_stock_production_lot_user,stock.production.lot user,model_stock_production_lot,stock.group_stock_user,1,1,1,1
access_stock_production_lot_revision,stock.production.lot.revision,model_stock_production_lot_revision,stock.group_stock_user,1,1,1,1
access_stock_move_manager,stock.move manager,model_stock_move,stock.group_stock_manager,1,1,0,0
-access_stock_move_user,stock.move user,model_stock_move,stock.group_stock_user,1,0,0,0
+access_stock_move_user,stock.move user,model_stock_move,stock.group_stock_user,1,1,1,0
access_stock_move_warehouse_manager,stock.move.manager,model_stock_move,stock.group_stock_manager,1,1,1,1
-access_stock_inventory_user,stock.inventory user,model_stock_inventory,stock.group_stock_user,1,0,0,0
+access_stock_inventory_user,stock.inventory user,model_stock_inventory,stock.group_stock_user,1,1,1,0
access_stock_inventory_manager,stock.inventory manager,model_stock_inventory,stock.group_stock_manager,1,1,1,1
-access_stock_inventory_line_user,stock.inventory.line user,model_stock_inventory_line,stock.group_stock_user,1,0,0,0
+access_stock_inventory_line_user,stock.inventory.line user,model_stock_inventory_line,stock.group_stock_user,1,1,1,0
access_stock_inventory_line_manager,stock.inventory.line manager,model_stock_inventory_line,stock.group_stock_manager,1,1,1,1
access_stock_report_prodlots,stock.report.prodlots,model_stock_report_prodlots,stock.group_stock_manager,1,0,0,0
access_stock_location_sale_manager,stock.location sale manager,model_stock_location,base.group_sale_manager,1,0,0,0
@@ -61,3 +61,4 @@ access_product_group_res_partner_stock_manager,res_partner group_stock_manager,b
access_product_pricelist_version_stock_manager,product.pricelist.version stock_manager,product.model_product_pricelist_version,stock.group_stock_manager,1,1,1,1
access_product_pricelist_item_stock_manager,product.pricelist.item stock_manager,product.model_product_pricelist_item,stock.group_stock_manager,1,1,1,1
access_account_account_stock_manager,account.account stock manager,account.model_account_account,stock.group_stock_manager,1,0,0,0
+access_board_stock_user,board.board user,board.model_board_board,stock.group_stock_user,1,1,0,0
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index 50e85fa5191..77849e12627 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -1667,6 +1667,7 @@ class stock_move(osv.osv):
# used for colors in tree views:
'scrapped': fields.related('location_dest_id','scrap_location',type='boolean',relation='stock.location',string='Scrapped', readonly=True),
+ 'type': fields.related('picking_id', 'type', type='selection', selection=[('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal')], string='Shipping Type'),
}
def _check_location(self, cr, uid, ids, context=None):
for record in self.browse(cr, uid, ids, context=context):
@@ -1746,10 +1747,25 @@ class stock_move(osv.osv):
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
return user.company_id.partner_id.id
+ def _default_move_type(self, cr, uid, context=None):
+ """ Gets default type of move
+ @return: type
+ """
+ if context is None:
+ context = {}
+ picking_type = context.get('picking_type')
+ type = 'internal'
+ if picking_type == 'in':
+ type = 'in'
+ elif picking_type == 'out':
+ type = 'out'
+ return type
+
_defaults = {
'location_id': _default_location_source,
'location_dest_id': _default_location_destination,
'partner_id': _default_destination_address,
+ 'type': _default_move_type,
'state': 'draft',
'priority': '1',
'product_qty': 1.0,
@@ -1903,6 +1919,32 @@ class stock_move(osv.osv):
result['location_dest_id'] = loc_dest_id
return {'value': result}
+ def onchange_move_type(self, cr, uid, ids, type, context=None):
+ """ On change of move type gives sorce and destination location.
+ @param type: Move Type
+ @return: Dictionary of values
+ """
+ mod_obj = self.pool.get('ir.model.data')
+ location_source_id = False
+ location_dest_id = False
+ if type == 'in':
+ location_source_id = 'stock_location_suppliers'
+ location_dest_id = 'stock_location_stock'
+ elif type == 'out':
+ location_source_id = 'stock_location_stock'
+ location_dest_id = 'stock_location_customers'
+ if location_source_id:
+ try:
+ location_model, location_source_id = mod_obj.get_object_reference(cr, uid, 'stock', location_source_id)
+ except ValueError, e:
+ location_source_id = False
+ if location_dest_id:
+ try:
+ location_model, location_dest_id = mod_obj.get_object_reference(cr, uid, 'stock', location_dest_id)
+ except ValueError, e:
+ location_dest_id = False
+ return {'value':{'location_id': location_source_id, 'location_dest_id': location_dest_id}}
+
def onchange_date(self, cr, uid, ids, date, date_expected, context=None):
""" On change of Scheduled Date gives a Move date.
@param date_expected: Scheduled Date
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index 154927a2f19..83fed186f42 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -106,13 +106,16 @@
<field name="arch" type="xml">
<form string="Physical Inventory" version="7.0">
<header>
- <button name="action_confirm" states="draft" string="Confirm Inventory" type="object" class="oe_highlight"/>
- <button name="action_done" states="confirm" string="Validate Inventory" type="object" class="oe_highlight"/>
+ <button name="action_confirm" states="draft" string="Confirm Inventory" type="object" class="oe_highlight" groups="stock.group_stock_user"/>
+ <button name="action_done" states="confirm" string="Validate Inventory" type="object" class="oe_highlight" groups="stock.group_stock_manager"/>
<button name="action_cancel_draft" states="cancel" string="Set to Draft" type="object"/>
<button name="action_cancel_inventory" states="draft,confirm,done" string="Cancel Inventory" type="object"/>
<field name="state" widget="statusbar" statusbar_visible="draft,confirm"/>
</header>
<sheet>
+ <div class="oe_right oe_button_box">
+ <button name="%(action_view_stock_fill_inventory)d" string="Fill Inventory" type="action" />
+ </div>
<group>
<group>
<field name="name" placeholder="e.g. Annual inventory"/>
@@ -231,9 +234,9 @@
<field name="active"/>
</group>
<group groups="stock.group_tracking_lot" string="Traceability">
- <button name="action_traceability" icon="gtk-go-up" string="Upstream Traceability" type="object"
+ <button name="action_traceability" string="Upstream Traceability" type="object"
colspan="2"/>
- <button name="action_traceability" icon="gtk-go-down" string="Downstream Traceability" type="object"
+ <button name="action_traceability" string="Downstream Traceability" type="object"
context="{'type': 'move_history_ids'}" colspan="2"/>
</group>
</group>
@@ -334,8 +337,8 @@
<field name="arch" type="xml">
<form string="Serial Number" version="7.0">
<div class="oe_button_box oe_right">
- <button name="action_traceability" string="Upstream Traceability" type="object" context="{'type': '', 'field': 'prodlot_id'}" icon="gtk-go-up"/>
- <button name="action_traceability" string="Downstream Traceability" type="object" context="{'type': 'move_history_ids', 'field': 'prodlot_id'}" icon="gtk-go-down"/>
+ <button name="action_traceability" string="Upstream Traceability" type="object" context="{'type': 'move_history_ids2', 'field': 'prodlot_id'}"/>
+ <button name="action_traceability" string="Downstream Traceability" type="object" context="{'type': 'move_history_ids', 'field': 'prodlot_id'}"/>
</div>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
@@ -759,15 +762,10 @@
<label for="name" class="oe_edit_only"/>
<h1>
<field name="name" class="oe_inline"/>
- <span attrs="{'invisible': [('origin','=',False)]}"> - </span>
- <field name="origin" placeholder="e.g. PO0032" class="oe_inline"/>
</h1>
- <label for="partner_id" class="oe_edit_only"/>
- <h2>
- <field name="partner_id" on_change="onchange_partner_in(partner_id)"/>
- </h2>
<group>
<group>
+ <field name="partner_id" on_change="onchange_partner_in(partner_id)"/>
<field name="backorder_id" readonly="1"/>
<field name="invoice_state" string="Invoice Control" groups="account.group_account_invoice" attrs="{'invisible':[('invoice_state', '=', 'none')]}"/>
<field name="stock_journal_id" widget="selection" groups="account.group_account_user"/>
@@ -775,119 +773,23 @@
<group>
<field name="date"/>
<field name="min_date" readonly="1"/>
+ <field name="origin" placeholder="e.g. PO0032" class="oe_inline"/>
</group>
</group>
<notebook>
<page string="Products">
- <field name="move_lines" context="{'address_in_id': partner_id}">
- <tree colors="grey:scrapped == True" string="Stock Moves">
- <field name="product_id"/>
- <field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
- <field name="product_uom" string="Unit of Measure" groups="product.group_uom"/>
- <field name="product_uos" groups="product.group_uos"/>
- <button name="%(stock.move_scrap)d"
- string="Scrap Products" type="action"
- icon="gtk-convert" context="{'scrap': True}"
- states="draft,waiting,confirmed,assigned"
- groups="base.group_user"/>
- <field name="scrapped" invisible="1"/>
- <field name="prodlot_id" groups="stock.group_production_lot"/>
- <button
- name="%(stock.track_line)d"
- string="Split in Serial Number"
- groups="stock.group_production_lot"
- type="action" icon="terp-stock_effects-object-colorize"
- states="draft,waiting,confirmed,assigned"/>
- <field groups="stock.group_tracking_lot" name="tracking_id"/>
- <button name="setlast_tracking" string="Put in current pack" type="object"
- attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
- icon="terp-stock_effects-object-colorize"
- groups="stock.group_tracking_lot"
- states="draft,assigned,confirmed"/>
- <button name="%(split_into)d" string="Put in a new pack" type="action"
- groups="product.group_stock_packaging"
- icon="terp-stock_effects-object-colorize"
- states="draft,assigned,confirmed"/>
- <field name="location_dest_id" groups="stock.group_locations"/>
- <field name="state"/>
- </tree>
- <form string="Stock Moves" version="7.0">
- <header>
- <span groups="base.group_user">
- <button name="force_assign" states="confirmed" string="Force Availability" type="object" icon="gtk-jump-to"/>
- <button name="action_confirm" states="draft" string="Confirm" type="object" icon="gtk-apply"/>
- <button name="cancel_assign" states="assigned" string="Cancel Availability" type="object" icon="gtk-find"/>
- </span>
- <field name="state" widget="statusbar" statusbar_visible="draft,assigned,done"/>
- </header>
- <group>
- <group>
- <field name="name" invisible="1"/>
- <field name="product_id" on_change="onchange_product_id(product_id,location_id,location_dest_id, parent.partner_id)"/>
- <label for="product_qty"/>
- <div>
- <field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)" class="oe_inline"/>
- <field name="product_uom" string="Unit Of Measure" groups="product.group_uom" class="oe_inline"/>
- <button name="%(stock.move_scrap)d"
- string="Scrap" type="action"
- icon="gtk-convert" context="{'scrap': True}"
- states="draft,waiting,confirmed,assigned"
- groups="base.group_user"/>
- </div>
- <label for="product_uos_qty" groups="product.group_uos"/>
- <div groups="product.group_uos">
- <field name="product_uos_qty" on_change="onchange_uos_quantity(product_id, product_uos_qty, product_uos, product_uom)" class="oe_inline"/>
- <field name="product_uos" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)" class="oe_inline"/>
- </div>
- <field name="product_packaging" groups="product.group_stock_packaging" domain="[('product_id','=',product_id)]"/>
- </group>
- <group>
- <field name="create_date" invisible="1"/>
- <field name="date"/>
- <field name="date_expected" on_change="onchange_date(date,date_expected)"/>
- </group>
-
- <group string="Locations" groups="stock.group_locations">
- <field name="location_id" domain="[('usage','&lt;&gt;','view')]"/>
- <field name="location_dest_id" domain="[('usage','=','internal')]" groups="stock.group_locations"/>
- </group>
-
- <group groups="stock.group_tracking_lot" string="Traceability">
- <label for="tracking_id"/>
- <div>
- <field name="tracking_id" groups="stock.group_tracking_lot" class="oe_inline"/>
- <button name="%(split_into)d" string="New Pack" type="action"
- groups="product.group_stock_packaging"
- icon="terp-stock_effects-object-colorize"
- states="draft,assigned,confirmed"/>
- </div>
-
- <label for="prodlot_id"/>
- <div>
- <field name="prodlot_id" groups="stock.group_production_lot"
- context="{'location_id':location_id, 'product_id':product_id}"
- domain="[('product_id','=?',product_id)]"
- on_change="onchange_lot_id(prodlot_id,product_qty, location_id, product_id, product_uom)" class="oe_inline"/>
- <button name="%(track_line)d"
- groups="stock.group_tracking_lot"
- states="draft,waiting,confirmed,assigned"
- string="Split" type="action" icon="terp-stock_effects-object-colorize"/>
- </div>
- </group>
- </group>
- </form>
- </field>
+ <field name="move_lines" context="{'address_in_id': partner_id, 'form_view_ref':'view_move_picking_form', 'tree_view_ref':'view_move_picking_tree'}"/>
</page>
<page string="Additional Info">
<group>
<group>
<field name="move_type"/>
- <field name="type" groups="base.group_user"/>
+ <field name="type" groups="base.group_no_one"/>
<field name="auto_picking" groups="base.group_user"/>
</group>
<group>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
- <field name="date_done"/>
+ <field name="date_done" groups="base.group_no_one"/>
</group>
</group>
</page>
@@ -972,7 +874,7 @@
<record id="view_picking_out_tree" model="ir.ui.view">
<field name="name">stock.picking.out.tree</field>
- <field name="model">stock.picking</field>
+ <field name="model">stock.picking.out</field>
<field name="arch" type="xml">
<tree colors="blue:state == 'draft';grey:state == 'cancel';red:state not in ('cancel', 'done') and min_date &lt; current_date" string="Delivery Orders">
<field name="name"/>
@@ -1002,13 +904,16 @@
<button name="action_assign" states="confirmed" string="Check Availability" type="object" class="oe_highlight"/>
</xpath>
<xpath expr="/form/header//button[@name='action_process']" position="replace">
- <button name="action_process" states="assigned" string="Deliver" type="object" icon="gtk-go-forward" class="oe_highlight"/>
+ <button name="action_process" states="assigned" string="Deliver" type="object" class="oe_highlight"/>
</xpath>
<xpath expr="/form/header//field[@name='state']" position="replace">
<field name="state" nolabel="1" readonly="1" widget="statusbar" statusbar_visible="draft,confirmed,assigned,done" statusbar_colors='{"auto":"blue", "confirmed":"blue"}'/>
</xpath>
<xpath expr="//field[@name='partner_id']" position="replace">
- <field name="partner_id" on_change="onchange_partner_in(partner_id)" colspan="4" string="Customer"/>
+ <field name="partner_id" on_change="onchange_partner_in(partner_id)" string="Customer"/>
+ </xpath>
+ <xpath expr="//field[@name='move_lines']" position="replace">
+ <field name="move_lines" context="{'address_in_id': partner_id, 'picking_type': 'out', 'form_view_ref':'view_move_picking_form', 'tree_view_ref':'view_move_picking_tree'}"/>
</xpath>
<xpath expr="/form/sheet" position="after">
<div class="oe_chatter">
@@ -1131,7 +1036,10 @@
<button name="action_process" states="assigned" string="Receive" type="object" class="oe_highlight"/>
</xpath>
<xpath expr="//field[@name='partner_id']" position="replace">
- <field name="partner_id" on_change="onchange_partner_in(partner_id)" colspan="4" string="Supplier"/>
+ <field name="partner_id" on_change="onchange_partner_in(partner_id)" string="Supplier"/>
+ </xpath>
+ <xpath expr="//field[@name='move_lines']" position="replace">
+ <field name="move_lines" context="{'address_in_id': partner_id, 'picking_type': 'in', 'form_view_ref':'view_move_picking_form', 'tree_view_ref':'view_move_picking_tree'}"/>
</xpath>
<xpath expr="/form/sheet" position="after">
<div class="oe_chatter">
@@ -1207,7 +1115,7 @@
</record>
<menuitem action="action_picking_tree4" id="menu_action_picking_tree4" parent="menu_stock_warehouse_mgmt" sequence="1"/>
- <menuitem action="action_picking_tree6" id="menu_action_picking_tree6" parent="menu_stock_warehouse_mgmt" sequence="2"/>
+ <menuitem action="action_picking_tree6" id="menu_action_picking_tree6" parent="menu_stock_warehouse_mgmt" sequence="2" groups="stock.group_locations"/>
<record id="view_move_tree" model="ir.ui.view">
<field name="name">stock.move.tree</field>
@@ -1218,6 +1126,7 @@
<field name="name"/>
<field name="picking_id" string="Reference"/>
<field name="origin"/>
+ <field name="type" on_change="onchange_move_type(type)"/>
<field name="create_date" invisible="1" groups="base.group_no_one"/>
<field name="product_id" on_change="onchange_product_id(product_id,location_id,location_dest_id, False)"/>
<field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
@@ -1251,6 +1160,45 @@
</field>
</record>
+ <record id="view_move_picking_tree" model="ir.ui.view">
+ <field name="name">stock.move.tree</field>
+ <field name="model">stock.move</field>
+ <field eval="4" name="priority"/>
+ <field name="arch" type="xml">
+ <tree colors="grey:scrapped == True" string="Stock Moves">
+ <field name="product_id"/>
+ <field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)"/>
+ <field name="product_uom" string="Unit of Measure" groups="product.group_uom"/>
+ <field name="product_uos" groups="product.group_uos"/>
+ <button name="%(stock.move_scrap)d"
+ string="Scrap Products" type="action"
+ icon="gtk-convert" context="{'scrap': True}"
+ states="draft,waiting,confirmed,assigned"
+ groups="base.group_user"/>
+ <field name="scrapped" invisible="1"/>
+ <field name="prodlot_id" groups="stock.group_production_lot"/>
+ <button
+ name="%(stock.track_line)d"
+ string="Split in Serial Number"
+ groups="stock.group_production_lot"
+ type="action" icon="terp-stock_effects-object-colorize"
+ states="draft,waiting,confirmed,assigned"/>
+ <field groups="stock.group_tracking_lot" name="tracking_id"/>
+ <button name="setlast_tracking" string="Put in current pack" type="object"
+ attrs="{'invisible': [('tracking_id','&lt;&gt;',False)]}"
+ icon="terp-stock_effects-object-colorize"
+ groups="stock.group_tracking_lot"
+ states="draft,assigned,confirmed"/>
+ <button name="%(split_into)d" string="Put in a new pack" type="action"
+ groups="product.group_stock_packaging"
+ icon="terp-stock_effects-object-colorize"
+ states="draft,assigned,confirmed"/>
+ <field name="location_dest_id" groups="stock.group_locations"/>
+ <field name="state"/>
+ </tree>
+ </field>
+ </record>
+
<record id="view_move_form" model="ir.ui.view">
<field name="name">stock.move.form</field>
<field name="model">stock.move</field>
@@ -1292,6 +1240,7 @@
</group>
<group name="origin_grp" string="Origin">
<field name="picking_id"/>
+ <field name="type" on_change="onchange_move_type(type)"/>
<field name="location_id" groups="stock.group_locations"/>
<field name="create_date" groups="base.group_no_one"/>
</group>
@@ -1329,6 +1278,81 @@
</field>
</record>
+ <record id="view_move_picking_form" model="ir.ui.view">
+ <field name="name">stock.move.form</field>
+ <field name="model">stock.move</field>
+ <field eval="2" name="priority"/>
+ <field name="arch" type="xml">
+ <form string="Stock Moves" version="7.0">
+ <header>
+ <span groups="base.group_user">
+ <button name="force_assign" states="confirmed" string="Force Availability" type="object"/>
+ <button name="action_confirm" states="draft" string="Confirm" type="object"/>
+ <button name="cancel_assign" states="assigned" string="Cancel Availability" type="object"/>
+ </span>
+ <field name="state" widget="statusbar" statusbar_visible="draft,assigned,done"/>
+ </header>
+ <group>
+ <group>
+ <field name="name" invisible="1"/>
+ <field name="product_id" on_change="onchange_product_id(product_id,location_id,location_dest_id, parent.partner_id)"/>
+ <field name="type" invisible="1"/>
+ <label for="product_qty"/>
+ <div>
+ <field name="product_qty" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)" class="oe_inline"/>
+ <field name="product_uom" string="Unit Of Measure" groups="product.group_uom" class="oe_inline"/>
+ <button name="%(stock.move_scrap)d"
+ string="Scrap" type="action"
+ icon="gtk-convert" context="{'scrap': True}"
+ states="draft,waiting,confirmed,assigned"
+ groups="base.group_user"/>
+ </div>
+ <label for="product_uos_qty" groups="product.group_uos"/>
+ <div groups="product.group_uos">
+ <field name="product_uos_qty" on_change="onchange_uos_quantity(product_id, product_uos_qty, product_uos, product_uom)" class="oe_inline"/>
+ <field name="product_uos" on_change="onchange_quantity(product_id, product_qty, product_uom, product_uos)" class="oe_inline"/>
+ </div>
+ <field name="product_packaging" groups="product.group_stock_packaging" domain="[('product_id','=',product_id)]"/>
+ </group>
+ <group>
+ <field name="create_date" invisible="1"/>
+ <field name="date"/>
+ <field name="date_expected" on_change="onchange_date(date,date_expected)"/>
+ </group>
+
+ <group string="Locations" groups="stock.group_locations">
+ <field name="location_id" domain="[('usage','&lt;&gt;','view')]"/>
+ <field name="location_dest_id" domain="[('usage','=','internal')]" groups="stock.group_locations"/>
+ </group>
+
+ <group groups="stock.group_tracking_lot" string="Traceability">
+ <label for="tracking_id"/>
+ <div>
+ <field name="tracking_id" groups="stock.group_tracking_lot" class="oe_inline"/>
+ <button name="%(split_into)d"
+ string="New Pack" type="action"
+ groups="product.group_stock_packaging"
+ icon="terp-stock_effects-object-colorize"
+ states="draft,assigned,confirmed"/>
+ </div>
+
+ <label for="prodlot_id"/>
+ <div>
+ <field name="prodlot_id" groups="stock.group_production_lot"
+ context="{'location_id':location_id, 'product_id':product_id}"
+ domain="[('product_id','=?',product_id)]"
+ on_change="onchange_lot_id(prodlot_id,product_qty, location_id, product_id, product_uom)" class="oe_inline"/>
+ <button name="%(track_line)d"
+ groups="stock.group_tracking_lot"
+ states="draft,waiting,confirmed,assigned"
+ string="Split" type="action" icon="terp-stock_effects-object-colorize"/>
+ </div>
+ </group>
+ </group>
+ </form>
+ </field>
+ </record>
+
<record id="view_move_search" model="ir.ui.view">
<field name="name">stock.move.search</field>
<field name="model">stock.move</field>
@@ -1380,6 +1404,21 @@
</p>
</field>
</record>
+
+ <record model="ir.actions.act_window.view" id="action_stock_move_tree_all">
+ <field name="sequence" eval="1"/>
+ <field name="view_mode">tree</field>
+ <field name="view_id" ref="view_move_tree"/>
+ <field name="act_window_id" ref="action_move_form2"/>
+ </record>
+
+ <record model="ir.actions.act_window.view" id="action_stock_move_form_all">
+ <field name="sequence" eval="3"/>
+ <field name="view_mode">form</field>
+ <field name="view_id" ref="view_move_form"/>
+ <field name="act_window_id" ref="action_move_form2"/>
+ </record>
+
<menuitem action="action_move_form2" id="menu_action_move_form2" parent="menu_traceability" sequence="3"/>
<!--
@@ -1453,7 +1492,7 @@
<field name="view_mode">tree,form</field>
<field name="domain">['|','&amp;',('picking_id','=',False),('location_id.usage', 'in', ['customer','supplier']),'&amp;',('picking_id','!=',False),('picking_id.type','=','in')]</field>
<field name="view_id" ref="view_move_tree_reception_picking"/>
- <field name="context" eval="'{\'product_receive\' : True, \'default_location_id\':%d, \'default_location_dest_id\':%d, \'search_default_future\': 1}' % (ref('stock_location_suppliers'),ref('stock_location_stock') )"/>
+ <field name="context">{'product_receive': True, 'search_default_future': True, 'picking_type': 'in'}</field>
<field name="help" type="html">
<p>
Click to register a product reception.
@@ -1588,7 +1627,7 @@
<field name="view_mode">tree,form</field>
<field name="domain">['|','&amp;',('picking_id','=',False),('location_dest_id.usage', 'in', ['customer','supplier']),'&amp;',('picking_id','!=',False),('picking_id.type','=','out')]</field>
<field name="view_id" ref="view_move_tree_reception_picking"/>
- <field name="context" eval="'{\'default_location_id\':%d, \'default_location_dest_id\':%d, \'search_default_future\': 1}' % (ref('stock_location_stock'),ref('stock_location_customers'))"/>
+ <field name="context">{'picking_type': 'out', 'search_default_future': True}</field>
<field name="help" type="html">
<p>
You will find in this list all products you have to deliver to
diff --git a/addons/stock/wizard/stock_fill_inventory.py b/addons/stock/wizard/stock_fill_inventory.py
index 10a1d625e16..9b730d22982 100644
--- a/addons/stock/wizard/stock_fill_inventory.py
+++ b/addons/stock/wizard/stock_fill_inventory.py
@@ -25,11 +25,23 @@ from tools.translate import _
class stock_fill_inventory(osv.osv_memory):
_name = "stock.fill.inventory"
_description = "Import Inventory"
+
+ def _default_location(self, cr, uid, ids, context=None):
+ try:
+ loc_model, location_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'stock_location_stock')
+ except ValueError, e:
+ return False
+ return location_id or False
+
_columns = {
'location_id': fields.many2one('stock.location', 'Location', required=True),
'recursive': fields.boolean("Include children",help="If checked, products contained in child locations of selected location will be included as well."),
'set_stock_zero': fields.boolean("Set to zero",help="If checked, all product quantities will be set to zero to help ensure a real physical inventory is done"),
}
+ _defaults = {
+ 'location_id': _default_location,
+ }
+
def view_init(self, cr, uid, fields_list, context=None):
"""
Creates view dynamically and adding fields at runtime.
diff --git a/addons/stock/wizard/stock_fill_inventory_view.xml b/addons/stock/wizard/stock_fill_inventory_view.xml
index 47e6355bcdc..5533bf0580e 100644
--- a/addons/stock/wizard/stock_fill_inventory_view.xml
+++ b/addons/stock/wizard/stock_fill_inventory_view.xml
@@ -8,8 +8,8 @@
<form string="Import Inventory" version="7.0">
<separator string="Import current product inventory from the following location"/>
<group>
- <field name="location_id"/>
- <field name="recursive"/>
+ <field name="location_id" groups="stock.group_locations"/>
+ <field name="recursive" groups="stock.group_locations"/>
<field name="set_stock_zero"/>
</group>
<footer>
@@ -21,14 +21,16 @@
</field>
</record>
- <act_window name="Import Inventory"
- res_model="stock.fill.inventory"
- src_model="stock.inventory"
- view_mode="form"
- target="new"
- context="{'search_default_in_location':1}"
- key2="client_action_multi"
- id="action_view_stock_fill_inventory"/>
-
+ <record id="action_view_stock_fill_inventory" model="ir.actions.act_window">
+ <field name="name">Fill Inventory</field>
+ <field name="type">ir.actions.act_window</field>
+ <field name="res_model">stock.fill.inventory</field>
+ <field name="view_type">form</field>
+ <field name="view_mode">form</field>
+ <field name="view_id" ref="view_stock_fill_inventory"/>
+ <field name="target">new</field>
+ <field name="context">{'search_default_in_location':1}</field>
+ </record>
+
</data>
</openerp>
diff --git a/addons/stock/wizard/stock_partial_picking.py b/addons/stock/wizard/stock_partial_picking.py
index b3720b8a51b..755da7c42ee 100644
--- a/addons/stock/wizard/stock_partial_picking.py
+++ b/addons/stock/wizard/stock_partial_picking.py
@@ -78,7 +78,7 @@ class stock_partial_picking(osv.osv_memory):
if context is None:
context={}
res = super(stock_partial_picking, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
- type = context.get('active_model','').split('.')[-1]
+ type = context.get('default_type', False)
if type:
doc = etree.XML(res['arch'])
for node in doc.xpath("//button[@name='do_partial']"):