New trunk
bzr revid: pinky-3f10ee12cea3c4c75cef44ab04ad33ef47432907
This commit is contained in:
commit
004a0b996f
|
@ -0,0 +1,3 @@
|
|||
recursive-include doc *
|
||||
recursive-include man *
|
||||
recursive-include bin *xml *xsl *sql
|
|
@ -0,0 +1,18 @@
|
|||
Metadata-Version: 1.1
|
||||
Name: Tiny ERP
|
||||
Version: 3.2.0
|
||||
Author: Tiny.be
|
||||
Author-email: fp at tiny be
|
||||
Maintainer: Tiny.be
|
||||
Maintainer-email: fp at tiny be
|
||||
Home-page: http://tiny.be
|
||||
Download-url: http://tinyerp.org/download.php
|
||||
Summary: TinyERP is an Enterprise Resource Management written entirely in python.
|
||||
License: GPL
|
||||
Description: Tiny ERP is a complete ERP and CRM. The main features are accounting (analytic
|
||||
and financial), stock management, sales and purchases management, tasks
|
||||
automation, marketing campaigns, help desk, POS, etc. Technical features include
|
||||
a distributed server, flexible workflows, an object database, a dynamic GUI,
|
||||
customizable reports, and SOAP and XML-RPC interfaces.
|
||||
Keywords: ERP, Accounting, Stock, CRM, Enterprise, Logistics, Management, Sales, Purchases
|
||||
Platform: Linux, Win32
|
|
@ -0,0 +1,249 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be)
|
||||
#
|
||||
# $Id: __init__.py 1308 2005-09-08 18:02:01Z pinky $
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contact a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import os, sys, imp
|
||||
import itertools
|
||||
from sets import Set
|
||||
|
||||
import osv
|
||||
import tools
|
||||
import pooler
|
||||
|
||||
|
||||
import netsvc
|
||||
from osv import fields
|
||||
|
||||
logger = netsvc.Logger()
|
||||
|
||||
opj = os.path.join
|
||||
ad = tools.config['addons_path']
|
||||
sys.path.insert(1,ad)
|
||||
|
||||
class Graph(dict):
|
||||
|
||||
def addNode(self, name, deps):
|
||||
max_depth, father = 0, None
|
||||
for n in [Node(x, self) for x in deps]:
|
||||
if n.depth >= max_depth:
|
||||
father = n
|
||||
max_depth = n.depth
|
||||
if father:
|
||||
father.addChild(name)
|
||||
else:
|
||||
Node(name, self)
|
||||
|
||||
def __iter__(self):
|
||||
level = 0
|
||||
done = Set(self.keys())
|
||||
while done:
|
||||
level_modules = [(name, module) for name, module in self.items() if module.depth==level]
|
||||
for name, module in level_modules:
|
||||
done.remove(name)
|
||||
yield module
|
||||
level += 1
|
||||
|
||||
class Singleton(object):
|
||||
|
||||
def __new__(cls, name, graph):
|
||||
if name in graph:
|
||||
inst = graph[name]
|
||||
else:
|
||||
inst = object.__new__(cls)
|
||||
inst.name = name
|
||||
graph[name] = inst
|
||||
return inst
|
||||
|
||||
class Node(Singleton):
|
||||
|
||||
def __init__(self, name, graph):
|
||||
self.graph = graph
|
||||
if not hasattr(self, 'childs'):
|
||||
self.childs = []
|
||||
if not hasattr(self, 'depth'):
|
||||
self.depth = 0
|
||||
|
||||
def addChild(self, name):
|
||||
node = Node(name, self.graph)
|
||||
node.depth = self.depth + 1
|
||||
if node not in self.childs:
|
||||
self.childs.append(node)
|
||||
for attr in ('init', 'update', 'demo'):
|
||||
if hasattr(self, attr):
|
||||
setattr(node, attr, True)
|
||||
self.childs.sort(lambda x,y: cmp(x.name, y.name))
|
||||
|
||||
def hasChild(self, name):
|
||||
return Node(name, self.graph) in self.childs or \
|
||||
bool([c for c in self.childs if c.hasChild(name)])
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
super(Singleton, self).__setattr__(name, value)
|
||||
if name in ('init', 'update', 'demo'):
|
||||
tools.config[name][self.name] = 1
|
||||
for child in self.childs:
|
||||
setattr(child, name, value)
|
||||
if name == 'depth':
|
||||
for child in self.childs:
|
||||
setattr(child, name, value + 1)
|
||||
|
||||
def __iter__(self):
|
||||
return itertools.chain(iter(self.childs), *map(iter, self.childs))
|
||||
|
||||
def __str__(self):
|
||||
return self._pprint()
|
||||
|
||||
def _pprint(self, depth=0):
|
||||
s = '%s\n' % self.name
|
||||
for c in self.childs:
|
||||
s += '%s`-> %s' % (' ' * depth, c._pprint(depth+1))
|
||||
return s
|
||||
|
||||
def create_graph(module_list, force=[]):
|
||||
graph = Graph()
|
||||
packages = []
|
||||
|
||||
for module in module_list:
|
||||
terp_file = opj(ad, module, '__terp__.py')
|
||||
if os.path.isfile(terp_file):
|
||||
info = eval(file(terp_file).read())
|
||||
if info.get('installable', True):
|
||||
packages.append((module, info.get('depends', []), info))
|
||||
|
||||
current,later = Set([p for p, dep, data in packages]), Set()
|
||||
while packages and current > later:
|
||||
package, deps, datas = packages[0]
|
||||
|
||||
# if all dependencies of 'package' are already in the graph, add 'package' in the graph
|
||||
if reduce(lambda x,y: x and y in graph, deps, True):
|
||||
later.clear()
|
||||
current.remove(package)
|
||||
graph.addNode(package, deps)
|
||||
node = Node(package, graph)
|
||||
node.datas = datas
|
||||
for kind in ('init', 'demo', 'update'):
|
||||
if package in tools.config[kind] or 'all' in tools.config[kind] or kind in force:
|
||||
setattr(node, kind, True)
|
||||
else:
|
||||
later.add(package)
|
||||
packages.append((package, deps, datas))
|
||||
packages = packages[1:]
|
||||
|
||||
for package in later:
|
||||
logger.notifyChannel('init', netsvc.LOG_ERROR, 'addon:%s:Unmet dependency' % package)
|
||||
|
||||
return graph
|
||||
|
||||
def init_module_objects(cr, module_name, obj_list):
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
logger.notifyChannel('init', netsvc.LOG_INFO, 'addon:%s:creating or updating database tables' % module_name)
|
||||
for obj in obj_list:
|
||||
#CHECKME: is this test useful? all objects are supposed to have an _auto_init method, right?
|
||||
#if hasattr(obj, '_auto_init'):
|
||||
if hasattr(obj, 'init'):
|
||||
obj.init(cr)
|
||||
obj._auto_init(cr)
|
||||
cr.commit()
|
||||
|
||||
def load_module_graph(cr, graph, status={}):
|
||||
package_todo = []
|
||||
statusi = 0
|
||||
for package in graph:
|
||||
status['progress'] = (float(statusi)+0.1)/len(graph)
|
||||
m = package.name
|
||||
logger.notifyChannel('init', netsvc.LOG_INFO, 'addon:%s' % m)
|
||||
sys.stdout.flush()
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
modules = pool.instanciate(m)
|
||||
cr.execute('select state, demo from ir_module_module where name=%s', (m,))
|
||||
(package_state, package_demo) = (cr.rowcount and cr.fetchone()) or ('uninstalled', False)
|
||||
idref = {}
|
||||
status['progress'] = (float(statusi)+0.4)/len(graph)
|
||||
if hasattr(package, 'init') or hasattr(package, 'update') or package_state in ('to install', 'to upgrade'):
|
||||
init_module_objects(cr, m, modules)
|
||||
for kind in ('init', 'update'):
|
||||
for filename in package.datas.get('%s_xml' % kind, []):
|
||||
mode = 'update'
|
||||
if hasattr(package, 'init') or package_state=='to install':
|
||||
mode = 'init'
|
||||
logger.notifyChannel('init', netsvc.LOG_INFO, 'addon:%s:loading %s' % (m, filename))
|
||||
name, ext = os.path.splitext(filename)
|
||||
if ext == '.csv':
|
||||
tools.convert_csv_import(cr, m, filename, tools.file_open(opj(m, filename)).read(), idref, mode=mode)
|
||||
elif ext == '.sql':
|
||||
queries = tools.file_open(opj(m, filename)).read().split(';')
|
||||
for query in queries:
|
||||
new_query = ' '.join(query.split())
|
||||
if new_query:
|
||||
cr.execute(new_query)
|
||||
cr.commit()
|
||||
else:
|
||||
tools.convert_xml_import(cr, m, tools.file_open(opj(m, filename)).read(), idref, mode=mode)
|
||||
if hasattr(package, 'demo') or (package_demo and package_state != 'installed'):
|
||||
status['progress'] = (float(statusi)+0.75)/len(graph)
|
||||
for xml in package.datas.get('demo_xml', []):
|
||||
name, ext = os.path.splitext(xml)
|
||||
logger.notifyChannel('init', netsvc.LOG_INFO, 'addon:%s:loading %s' % (m, xml))
|
||||
if ext == '.csv':
|
||||
tools.convert_csv_import(cr, m, os.path.basename(xml), tools.file_open(opj(m, xml)).read(), idref)
|
||||
else:
|
||||
tools.convert_xml_import(cr, m, tools.file_open(opj(m, xml)).read(), idref)
|
||||
package_todo.append(package.name)
|
||||
cr.execute("update ir_module_module set state='installed', demo=%s where state in ('to upgrade', 'to install') and name=%s", (str(hasattr(package, 'demo')) or package_demo, package.name))
|
||||
cr.commit()
|
||||
statusi+=1
|
||||
cr.commit()
|
||||
|
||||
# pool = osv.osv.FakePool('base')
|
||||
# pool = pooler.get_pool(cr.dbname)
|
||||
# pool.get('ir.model.data')._process_end(cr, 1, package_todo)
|
||||
# cr.commit()
|
||||
|
||||
def register_classes():
|
||||
module_list = os.listdir(ad)
|
||||
for package in create_graph(module_list):
|
||||
m = package.name
|
||||
logger.notifyChannel('init', netsvc.LOG_INFO, 'addon:%s:registering classes' % m)
|
||||
sys.stdout.flush()
|
||||
imp.load_module(m, *imp.find_module(m))
|
||||
|
||||
def load_modules(db, force_demo=False, status={}, update_module=False):
|
||||
force = []
|
||||
if force_demo:
|
||||
force.append('demo')
|
||||
cr = db.cursor()
|
||||
if update_module:
|
||||
cr.execute("select name from ir_module_module where state in ('installed', 'to install', 'to upgrade')")
|
||||
else:
|
||||
cr.execute("select name from ir_module_module where state = 'installed'")
|
||||
module_list = [name for (name,) in cr.fetchall()]
|
||||
graph = create_graph(module_list, force)
|
||||
load_module_graph(cr, graph, status)
|
||||
cr.commit()
|
||||
cr.close()
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import ir
|
||||
import module
|
||||
import res
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"name" : "Base",
|
||||
"version" : "1.0",
|
||||
"author" : "Tiny",
|
||||
"website" : "http://tinyerp.com",
|
||||
"category" : "Generic Modules/Base",
|
||||
"description": "The kernel of Tiny ERP, needed for all installation.",
|
||||
"depends" : [],
|
||||
"init_xml" : [
|
||||
"base_data.xml",
|
||||
"base_menu.xml"
|
||||
],
|
||||
"demo_xml" : [
|
||||
"base_demo.xml",
|
||||
"res/partner/partner_demo.xml",
|
||||
"res/partner/crm_demo.xml",
|
||||
],
|
||||
"update_xml" : [
|
||||
"base_update.xml",
|
||||
"ir/ir.xml",
|
||||
"ir/workflow/workflow_view.xml",
|
||||
"module/module_data.xml",
|
||||
"module/module_wizard.xml",
|
||||
"module/module_view.xml",
|
||||
"module/module_report.xml",
|
||||
"res/res_request_view.xml",
|
||||
"res/partner/partner_report.xml",
|
||||
"res/partner/partner_view.xml",
|
||||
"res/partner/partner_wizard.xml",
|
||||
"res/res_currency_view.xml",
|
||||
"res/partner/crm_view.xml",
|
||||
"res/partner/partner_data.xml",
|
||||
"res/ir_property_view.xml",
|
||||
],
|
||||
"installable": True
|
||||
}
|
|
@ -0,0 +1,335 @@
|
|||
-------------------------------------------------------------------------
|
||||
-- Pure SQL
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE perm (
|
||||
id serial NOT NULL,
|
||||
level smallint DEFAULT 4 NOT NULL,
|
||||
uid int default null,
|
||||
gid int default null,
|
||||
primary key(id)
|
||||
);
|
||||
insert into perm (id,uid,gid) values (1,1,1);
|
||||
|
||||
CREATE TABLE inherit (
|
||||
obj_type varchar(128) not null,
|
||||
obj_id int not null,
|
||||
inst_type varchar(128) not null,
|
||||
inst_id int not null
|
||||
);
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
-- IR dictionary
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
create table ir_values
|
||||
(
|
||||
id serial,
|
||||
perm_id int references perm on delete set null,
|
||||
name varchar(128) not null,
|
||||
key varchar(128) not null,
|
||||
key2 varchar(128) not null,
|
||||
model varchar(128) not null,
|
||||
value text,
|
||||
meta text default NULL,
|
||||
res_id integer default null,
|
||||
primary key (id)
|
||||
);
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
-- Modules Description
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE ir_model (
|
||||
id serial,
|
||||
model varchar(64) DEFAULT ''::varchar NOT NULL,
|
||||
name varchar(64),
|
||||
info text,
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
CREATE TABLE ir_model_fields (
|
||||
id serial,
|
||||
model varchar(64) DEFAULT ''::varchar NOT NULL,
|
||||
model_id int references ir_model,
|
||||
name varchar(64) DEFAULT ''::varchar NOT NULL,
|
||||
relation varchar(64),
|
||||
field_description varchar(256),
|
||||
ttype varchar(64),
|
||||
group_name varchar(64),
|
||||
view_load boolean,
|
||||
relate boolean default False,
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
-- Actions
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
CREATE TABLE ir_actions (
|
||||
id serial NOT NULL,
|
||||
perm_id int references perm on delete set null,
|
||||
name varchar(64) DEFAULT ''::varchar NOT NULL,
|
||||
"type" varchar(64) DEFAULT 'window'::varchar NOT NULL,
|
||||
usage varchar(32) DEFAULT null,
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
CREATE TABLE ir_act_window (
|
||||
view_id integer,
|
||||
res_model varchar(64),
|
||||
view_type varchar(16),
|
||||
"domain" varchar(127),
|
||||
primary key(id)
|
||||
)
|
||||
INHERITS (ir_actions);
|
||||
|
||||
CREATE TABLE ir_act_report_xml (
|
||||
model varchar(64) NOT NULL,
|
||||
report_name varchar(64) NOT NULL,
|
||||
report_xsl varchar(64),
|
||||
report_xml varchar(64),
|
||||
auto boolean default true
|
||||
)
|
||||
INHERITS (ir_actions);
|
||||
|
||||
create table ir_act_report_custom (
|
||||
report_id int
|
||||
-- report_id int references ir_report_custom
|
||||
)
|
||||
INHERITS (ir_actions);
|
||||
|
||||
CREATE TABLE ir_act_group (
|
||||
exec_type varchar(64) DEFAULT 'serial'::varchar NOT NULL
|
||||
)
|
||||
INHERITS (ir_actions);
|
||||
|
||||
CREATE TABLE ir_act_group_link (
|
||||
aid integer NOT NULL,
|
||||
gid integer NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE ir_act_execute (
|
||||
func_name varchar(64) NOT NULL,
|
||||
func_arg varchar(64)
|
||||
)
|
||||
INHERITS (ir_actions);
|
||||
|
||||
CREATE TABLE ir_act_wizard (
|
||||
wiz_name varchar(64) NOT NULL
|
||||
)
|
||||
INHERITS (ir_actions);
|
||||
|
||||
CREATE TABLE ir_ui_view (
|
||||
id serial NOT NULL,
|
||||
perm_id int references perm on delete set null,
|
||||
name varchar(64) DEFAULT ''::varchar NOT NULL,
|
||||
model varchar(64) DEFAULT ''::varchar NOT NULL,
|
||||
"type" varchar(64) DEFAULT 'form'::varchar NOT NULL,
|
||||
arch text NOT NULL,
|
||||
field_parent varchar(64),
|
||||
priority integer DEFAULT 5 NOT NULL,
|
||||
primary key(id),
|
||||
CONSTRAINT ir_ui_view_type CHECK (((("type")::text = ('form'::varchar)::text) OR (("type")::text = ('tree'::varchar)::text)))
|
||||
);
|
||||
|
||||
CREATE TABLE ir_ui_menu (
|
||||
id serial NOT NULL,
|
||||
perm_id int references perm on delete set null,
|
||||
parent_id int references ir_ui_menu on delete set null,
|
||||
name varchar(64) DEFAULT ''::varchar NOT NULL,
|
||||
icon varchar(64) DEFAULT ''::varchar,
|
||||
primary key (id)
|
||||
);
|
||||
|
||||
select setval('ir_ui_menu_id_seq', 2);
|
||||
|
||||
---------------------------------
|
||||
-- Res users
|
||||
---------------------------------
|
||||
|
||||
-- level:
|
||||
-- 0 RESTRICT TO USER
|
||||
-- 1 RESTRICT TO GROUP
|
||||
-- 2 PUBLIC
|
||||
|
||||
CREATE TABLE res_users (
|
||||
id serial NOT NULL,
|
||||
perm_id int references perm on delete set null,
|
||||
name varchar(64) not null,
|
||||
active boolean default True,
|
||||
login varchar(64) NOT NULL UNIQUE,
|
||||
password varchar(32) default null,
|
||||
perm_default int references perm on delete set null,
|
||||
-- action_id int references ir_act_window on delete set null,
|
||||
action_id int,
|
||||
primary key(id)
|
||||
);
|
||||
alter table res_users add constraint res_users_login_uniq unique (login);
|
||||
|
||||
insert into res_users (id,login,password,name,action_id,perm_id,active) values (1,'root',NULL,'Administrator',NULL,1,False);
|
||||
select setval('res_users_id_seq', 2);
|
||||
|
||||
CREATE TABLE res_groups (
|
||||
id serial NOT NULL,
|
||||
perm_id int references perm on delete set null,
|
||||
name varchar(32) NOT NULL,
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
create table res_roles (
|
||||
id serial NOT NULL,
|
||||
perm_id int references perm on delete set null,
|
||||
parent_id int references res_roles on delete set null,
|
||||
name varchar(32) NOT NULL,
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
CREATE TABLE res_roles_users_rel (
|
||||
uid integer NOT NULL references res_users on delete cascade,
|
||||
rid integer NOT NULL references res_roles on delete cascade
|
||||
);
|
||||
|
||||
CREATE TABLE res_groups_users_rel (
|
||||
uid integer NOT NULL references res_users on delete cascade,
|
||||
gid integer NOT NULL references res_groups on delete cascade
|
||||
);
|
||||
|
||||
---------------------------------
|
||||
-- Workflows
|
||||
---------------------------------
|
||||
|
||||
create table wkf
|
||||
(
|
||||
id serial,
|
||||
perm_id int references perm on delete set null,
|
||||
name varchar(64),
|
||||
osv varchar(64),
|
||||
on_create bool default False,
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
create table wkf_activity
|
||||
(
|
||||
id serial,
|
||||
perm_id int references perm on delete set null,
|
||||
wkf_id int references wkf on delete cascade,
|
||||
subflow_id int references wkf on delete set null,
|
||||
split_mode varchar(3) default 'XOR',
|
||||
join_mode varchar(3) default 'XOR',
|
||||
kind varchar(16) not null default 'dummy',
|
||||
name varchar(64),
|
||||
signal_send varchar(32) default null,
|
||||
flow_start boolean default False,
|
||||
flow_stop boolean default False,
|
||||
action varchar(64) default null,
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
create table wkf_transition
|
||||
(
|
||||
id serial,
|
||||
perm_id int references perm on delete set null,
|
||||
act_from int references wkf_activity on delete cascade,
|
||||
act_to int references wkf_activity on delete cascade,
|
||||
condition varchar(128) default NULL,
|
||||
|
||||
trigger_type varchar(128) default NULL,
|
||||
trigger_expr_id varchar(128) default NULL,
|
||||
|
||||
signal varchar(64) default null,
|
||||
role_id int references res_roles on delete set null,
|
||||
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
create table wkf_instance
|
||||
(
|
||||
id serial,
|
||||
wkf_id int references wkf on delete set null,
|
||||
uid int default null,
|
||||
res_id int not null,
|
||||
res_type varchar(64) not null,
|
||||
state varchar(32) not null default 'active',
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
create table wkf_workitem
|
||||
(
|
||||
id serial,
|
||||
act_id int not null references wkf_activity on delete cascade,
|
||||
inst_id int not null references wkf_instance on delete cascade,
|
||||
subflow_id int references wkf_instance on delete cascade,
|
||||
state varchar(64) default 'blocked',
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
create table wkf_witm_trans
|
||||
(
|
||||
trans_id int not null references wkf_transition on delete cascade,
|
||||
inst_id int not null references wkf_instance on delete cascade
|
||||
);
|
||||
|
||||
create table wkf_logs
|
||||
(
|
||||
id serial,
|
||||
res_type varchar(128) not null,
|
||||
res_id int not null,
|
||||
uid int references res_users on delete set null,
|
||||
act_id int references wkf_activity on delete set null,
|
||||
time time not null,
|
||||
info varchar(128) default NULL,
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
---------------------------------
|
||||
-- Modules
|
||||
---------------------------------
|
||||
|
||||
CREATE TABLE ir_module_category (
|
||||
id serial NOT NULL,
|
||||
perm_id integer,
|
||||
create_uid integer references res_users on delete set null,
|
||||
create_date timestamp without time zone,
|
||||
write_date timestamp without time zone,
|
||||
write_uid integer references res_users on delete set null,
|
||||
parent_id integer REFERENCES ir_module_category ON DELETE SET NULL,
|
||||
name character varying(128) NOT NULL,
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE ir_module_module (
|
||||
id serial NOT NULL,
|
||||
perm_id integer,
|
||||
create_uid integer references res_users on delete set null,
|
||||
create_date timestamp without time zone,
|
||||
write_date timestamp without time zone,
|
||||
write_uid integer references res_users on delete set null,
|
||||
website character varying(256),
|
||||
name character varying(128) NOT NULL,
|
||||
author character varying(128),
|
||||
url character varying(128),
|
||||
state character varying(16),
|
||||
latest_version character varying(64),
|
||||
shortdesc character varying(256),
|
||||
category_id integer REFERENCES ir_module_category ON DELETE SET NULL,
|
||||
description text,
|
||||
demo boolean default False,
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
CREATE TABLE ir_module_module_dependency (
|
||||
id serial NOT NULL,
|
||||
perm_id integer,
|
||||
create_uid integer references res_users on delete set null,
|
||||
create_date timestamp without time zone,
|
||||
write_date timestamp without time zone,
|
||||
write_uid integer references res_users on delete set null,
|
||||
name character varying(128),
|
||||
version_pattern character varying(128) default NULL,
|
||||
module_id integer REFERENCES ir_module_module ON DELETE cascade,
|
||||
primary key(id)
|
||||
);
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,274 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data noupdate="1">
|
||||
<record model="res.users" id="user_demo">
|
||||
<field name="login">demo</field>
|
||||
<field name="password">demo</field>
|
||||
<field name="name">Demo User</field>
|
||||
<field name="signature">Fabien Pinckaers</field>
|
||||
<field name="action_id" ref="action_menu_admin"/>
|
||||
<field name="address_id" ref="main_address"/>
|
||||
<field name="company_id" ref="main_company"/>
|
||||
</record>
|
||||
|
||||
<record model="res.currency" id="USD">
|
||||
<field name="name">USD</field>
|
||||
<field name="rate">0.8400</field>
|
||||
<field name="rounding">2</field>
|
||||
<field name="accuracy">4</field>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- USA States -->
|
||||
<record model="res.country.state" id="us-al">
|
||||
<field name="name">Alabama</field>
|
||||
<field name="code">al</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-ak">
|
||||
<field name="name">Alaska</field>
|
||||
<field name="code">ak</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-az">
|
||||
<field name="name">Arizona</field>
|
||||
<field name="code">az</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-ar">
|
||||
<field name="name">Arkansas</field>
|
||||
<field name="code">ar</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-ca">
|
||||
<field name="name">California</field>
|
||||
<field name="code">ca</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-co">
|
||||
<field name="name">Colorado</field>
|
||||
<field name="code">co</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-ct">
|
||||
<field name="name">Connecticut</field>
|
||||
<field name="code">ct</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-de">
|
||||
<field name="name">Delaware</field>
|
||||
<field name="code">de</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-fl">
|
||||
<field name="name">Florida</field>
|
||||
<field name="code">fl</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-ga">
|
||||
<field name="name">Georgia</field>
|
||||
<field name="code">ga</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-hi">
|
||||
<field name="name">Hawaii</field>
|
||||
<field name="code">hi</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-id">
|
||||
<field name="name">Idaho</field>
|
||||
<field name="code">id</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-il">
|
||||
<field name="name">Illinois</field>
|
||||
<field name="code">il</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-in">
|
||||
<field name="name">Indiana</field>
|
||||
<field name="code">in</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-ia">
|
||||
<field name="name">Iowa</field>
|
||||
<field name="code">ia</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-ks">
|
||||
<field name="name">Kansas</field>
|
||||
<field name="code">ks</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-ky">
|
||||
<field name="name">Kentuky</field>
|
||||
<field name="code">ky</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-la">
|
||||
<field name="name">Louisiana</field>
|
||||
<field name="code">la</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-me">
|
||||
<field name="name">Maine</field>
|
||||
<field name="code">me</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-md">
|
||||
<field name="name">Maryland</field>
|
||||
<field name="code">md</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-ma">
|
||||
<field name="name">Massachusetts</field>
|
||||
<field name="code">ma</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-mi">
|
||||
<field name="name">Michigan</field>
|
||||
<field name="code">mi</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-mn">
|
||||
<field name="name">Minnesota</field>
|
||||
<field name="code">mn</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-ms">
|
||||
<field name="name">Mississippi</field>
|
||||
<field name="code">ms</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-mo">
|
||||
<field name="name">Missouri</field>
|
||||
<field name="code">mo</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-mt">
|
||||
<field name="name">Montana</field>
|
||||
<field name="code">mt</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-ne">
|
||||
<field name="name">Nebraska</field>
|
||||
<field name="code">ne</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-nv">
|
||||
<field name="name">Nevada</field>
|
||||
<field name="code">nv</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-nh">
|
||||
<field name="name">New Hampshire</field>
|
||||
<field name="code">nh</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-nj">
|
||||
<field name="name">New Jersey</field>
|
||||
<field name="code">nj</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-nm">
|
||||
<field name="name">New Mexico</field>
|
||||
<field name="code">nm</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-ny">
|
||||
<field name="name">New York</field>
|
||||
<field name="code">ny</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-nc">
|
||||
<field name="name">North Carolina</field>
|
||||
<field name="code">nc</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-nd">
|
||||
<field name="name">New Dakota</field>
|
||||
<field name="code">nd</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-oh">
|
||||
<field name="name">Ohio</field>
|
||||
<field name="code">oh</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-ok">
|
||||
<field name="name">Oklahoma</field>
|
||||
<field name="code">ok</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-or">
|
||||
<field name="name">Oregon</field>
|
||||
<field name="code">or</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-pa">
|
||||
<field name="name">Pennsylviania</field>
|
||||
<field name="code">pa</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-ri">
|
||||
<field name="name">Rhode Island</field>
|
||||
<field name="code">ri</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-sc">
|
||||
<field name="name">South Carolina</field>
|
||||
<field name="code">sc</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-sd">
|
||||
<field name="name">South Dakota</field>
|
||||
<field name="code">sd</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-tn">
|
||||
<field name="name">Tennessee</field>
|
||||
<field name="code">tn</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-tx">
|
||||
<field name="name">Texas</field>
|
||||
<field name="code">tx</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-ut">
|
||||
<field name="name">Utah</field>
|
||||
<field name="code">ut</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-vt">
|
||||
<field name="name">Vermont</field>
|
||||
<field name="code">vt</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-va">
|
||||
<field name="name">Virgnia</field>
|
||||
<field name="code">va</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-wa">
|
||||
<field name="name">Washington</field>
|
||||
<field name="code">wa</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-wv">
|
||||
<field name="name">West Virgnia</field>
|
||||
<field name="code">wv</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-wi">
|
||||
<field name="name">Wisconsin</field>
|
||||
<field name="code">wi</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
<record model="res.country.state" id="us-wy">
|
||||
<field name="name">Wyoming</field>
|
||||
<field name="code">wy</field>
|
||||
<field name="country_id" model="res.country" ref="us"/>
|
||||
</record>
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data>
|
||||
<!-- <menuitem name="Tools" sequence="15" groups="admin" icon="terp-tools"/> -->
|
||||
<menuitem name="Administration" sequence="20" groups="admin" icon="terp-administration"/>
|
||||
|
||||
# Admin config
|
||||
|
||||
<menuitem name="Administration/Configuration/Base" sequence="1"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="open_module_tree_company">
|
||||
<field name="name">res.company</field>
|
||||
<field name="res_model">res.company</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Configuration/Base/Define Main Company" action="open_module_tree_company" sequence="2" id="menu_company_def"/>
|
||||
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,169 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data>
|
||||
<!--
|
||||
======================
|
||||
Languages
|
||||
======================
|
||||
-->
|
||||
<record model="ir.ui.view" id="view_lang">
|
||||
<field name="name">Languages</field>
|
||||
<field name="model">res.lang</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Language">
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" select="1"/>
|
||||
<field name="translatable"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_lang">
|
||||
<field name="name">res.lang</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.lang</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Interface/Languages" action="action_lang"/>
|
||||
|
||||
<ir_set>
|
||||
<field name="key" eval="'meta'"/>
|
||||
<field name="key2" eval="'lang'"/>
|
||||
<field name="models" eval="['res.users']"/>
|
||||
<field name="name">lang</field>
|
||||
<field name="value" eval="False"/>
|
||||
<field name="meta" eval="{'type':'selection', 'string':'Language', 'selection':[(False,'en')]}"/>
|
||||
<field name="replace" eval="True"/>
|
||||
</ir_set>
|
||||
|
||||
<!--
|
||||
======================
|
||||
Groups
|
||||
======================
|
||||
-->
|
||||
<record model="ir.ui.view" id="view_groups_form">
|
||||
<field name="name">res.groups.form</field>
|
||||
<field name="model">res.groups</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Groups">
|
||||
<field name="name" colspan="3" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
======================
|
||||
Users
|
||||
======================
|
||||
-->
|
||||
<record model="ir.ui.view" id="view_users_form_simple_modif">
|
||||
<field name="name">res.users.form.modif</field>
|
||||
<field name="model">res.users</field>
|
||||
<field name="type">form</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Users">
|
||||
<field name="name" colspan="3" select="1"/>
|
||||
<field name="login" readonly="1" select="1"/>
|
||||
<field name="password"/>
|
||||
<label string="Please note that you will have to logout and relog if you change your password." colspan="4"/>
|
||||
<newline/>
|
||||
<field name="signature" colspan="3"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_users_form_simple">
|
||||
<field name="name">res.users.form</field>
|
||||
<field name="model">res.users</field>
|
||||
<field name="type">form</field>
|
||||
<field name="priority" eval="8"/>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Users">
|
||||
<field name="name" readonly="1" colspan="3" select="1"/>
|
||||
<field name="login" readonly="1" select="1"/>
|
||||
<newline/>
|
||||
<field name="signature" readonly="1" colspan="3"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_users_form">
|
||||
<field name="name">res.users.form</field>
|
||||
<field name="model">res.users</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Users">
|
||||
<field name="name" select="1"/>
|
||||
<field name="active" select="1"/>
|
||||
<field name="login" select="1"/>
|
||||
<field name="password"/>
|
||||
<field name="signature"/>
|
||||
<field name="address_id"/>
|
||||
<field name="company_id" required="1"/>
|
||||
<field name="action_id" domain="[('usage','=','menu')]" required="True"/>
|
||||
<newline/>
|
||||
<field name="groups_id"/>
|
||||
<field name="roles_id"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_users_tree">
|
||||
<field name="name">res.users.tree</field>
|
||||
<field name="model">res.users</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Users">
|
||||
<field name="name"/>
|
||||
<field name="login"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
======================
|
||||
Company
|
||||
======================
|
||||
-->
|
||||
<record model="ir.ui.view" id="view_company_form">
|
||||
<field name="name">res.company.form</field>
|
||||
<field name="model">res.company</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Company">
|
||||
<field name="name" colspan="3" select="1"/>
|
||||
<field name="partner_id" select="1"/>
|
||||
<field name="parent_id" select="1"/>
|
||||
<field name="rml_header1"/>
|
||||
<field name="rml_footer1"/>
|
||||
<field name="rml_footer2"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_company_tree">
|
||||
<field name="name">res.company.tree</field>
|
||||
<field name="model">res.company</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="field_parent">child_ids</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Companies">
|
||||
<field name="name"/>
|
||||
<field name="partner_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
# Admin config
|
||||
|
||||
<menuitem name="Administration/Configuration/User" sequence="4"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="open_module_users_list">
|
||||
<field name="name">res.users.list</field>
|
||||
<field name="res_model">res.users</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="base.view_users_tree"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Configuration/User/Define Users" action="open_module_users_list" sequence="1" id="menu_users_list"/>
|
||||
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,41 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import ir_sequence
|
||||
import ir_ui_menu
|
||||
import ir_ui_view
|
||||
import ir_actions
|
||||
import ir_default
|
||||
import ir_model
|
||||
import ir_report_custom
|
||||
import ir_attachment
|
||||
import ir_cron
|
||||
import ir_values
|
||||
import ir_translation
|
||||
import ir_exports
|
||||
import workflow
|
|
@ -0,0 +1,654 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data>
|
||||
==========================================================
|
||||
Sequences
|
||||
==========================================================
|
||||
|
||||
<record model="ir.ui.view" id="sequence_view">
|
||||
<field name="name">ir.sequence.form</field>
|
||||
<field name="model">ir.sequence</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Sequences">
|
||||
<separator string="Configuration" colspan="4"/>
|
||||
<field name="name" colspan="3" select="1"/>
|
||||
<field name="code" select="1"/>
|
||||
<field name="active" select="1"/>
|
||||
<field name="prefix"/>
|
||||
<field name="suffix"/>
|
||||
<field name="padding" />
|
||||
<field name="number_increment"/>
|
||||
<field name="number_next"/>
|
||||
<separator string="Legend (for prefix, suffix)" colspan="4"/>
|
||||
<label string="Year: %%(year)s" colspan="4"/>
|
||||
<label string="Month: %%(month)s" colspan="4"/>
|
||||
<label string="Day: %%(day)s" colspan="4"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="ir_sequence_form">
|
||||
<field name="name">ir.sequence</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.sequence</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="sequence_view"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Sequences/Sequences" action="ir_sequence_form"/>
|
||||
|
||||
==========================================================
|
||||
Sequences Types
|
||||
==========================================================
|
||||
|
||||
<record model="ir.ui.view" id="sequence_type_form_view">
|
||||
<field name="name">ir.sequence.type.form</field>
|
||||
<field name="model">ir.sequence.type</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Sequence Type">
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" readonly="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="ir_sequence_type">
|
||||
<field name="name">ir.sequence.type</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.sequence.type</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" eval="False"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Sequences/Sequence Types" action="ir_sequence_type"/>
|
||||
|
||||
==========================================================
|
||||
Actions
|
||||
==========================================================
|
||||
|
||||
<record model="ir.actions.act_window" id="ir_sequence_actions">
|
||||
<field name="name">ir.actions.actions</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.actions.actions</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low level/Base/Actions/Actions" action="ir_sequence_actions"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="ir_action_execute">
|
||||
<field name="name">ir.actions.execute</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.actions.execute</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low level/Base/Actions/Execute" action="ir_action_execute"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="ir_action_group">
|
||||
<field name="name">ir.actions.group</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.actions.group</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low level/Base/Actions/Group" action="ir_action_group"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="ir_action_report_custom">
|
||||
<field name="name">ir.actions.report.custom</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.actions.report.custom</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low level/Base/Actions/Report Custom" action="ir_action_report_custom"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="ir_action_report_xml">
|
||||
<field name="name">ir.actions.report.xml</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.actions.report.xml</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low level/Base/Actions/Report Xml" action="ir_action_report_xml"/>
|
||||
|
||||
<record model="ir.ui.view" id="view_window_action_tree">
|
||||
<field name="name">ir.actions.windows.tree</field>
|
||||
<field name="model">ir.actions.act_window</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Window Action">
|
||||
<field name="name"/>
|
||||
<field name="res_model"/>
|
||||
<field name="view_type"/>
|
||||
<field name="view_id"/>
|
||||
<field name="domain"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_window_action_form">
|
||||
<field name="name">ir.actions.windows.form</field>
|
||||
<field name="model">ir.actions.act_window</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Open a Window">
|
||||
<field name="name" colspan="3" select="1"/>
|
||||
<field name="type" readonly="1"/>
|
||||
<field name="view_id"/>
|
||||
<field name="res_model"/>
|
||||
<field name="view_type"/>
|
||||
<field name="domain" colspan="3"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="ir_action_window">
|
||||
<field name="name">ir.actions.act_window</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_window_action_form"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low level/Base/Actions/Open Window" action="ir_action_window"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="ir_action_wizard">
|
||||
<field name="name">ir.actions.wizard</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.actions.wizard</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low level/Base/Actions/Wizard" action="ir_action_wizard"/>
|
||||
|
||||
==========================================================
|
||||
Companies
|
||||
==========================================================
|
||||
|
||||
<record model="ir.actions.act_window" id="action_res_company_tree">
|
||||
<field name="name">res.company</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.company</field>
|
||||
<field name="domain">[('parent_id','=',False)]</field>
|
||||
<field name="view_type">tree</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Users/Company Structure" action="action_res_company_tree"/>
|
||||
<record model="ir.actions.act_window" id="action_res_company_form">
|
||||
<field name="name">res.groups</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.company</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Users/Company Structure/Define Companies" action="action_res_company_form"/>
|
||||
|
||||
==========================================================
|
||||
User Roles
|
||||
==========================================================
|
||||
|
||||
<record model="ir.actions.act_window" id="action_res_users">
|
||||
<field name="name">res.users</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.users</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_users_form"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Users/Users" action="action_res_users"/>
|
||||
<record model="ir.actions.act_window" id="action_res_users_my">
|
||||
<field name="name">res.users</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.users</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('id','=',uid)]</field>
|
||||
<field name="view_id" ref="view_users_form_simple_modif"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Users/Users/My password" action="action_res_users_my"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_res_groups">
|
||||
<field name="name">res.groups</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.groups</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Users/Groups" action="action_res_groups"/>
|
||||
|
||||
<record model="ir.ui.view" id="view_roles_form">
|
||||
<field name="name">res.roles.form</field>
|
||||
<field name="model">res.roles</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Role">
|
||||
<field name="name" colspan="3" select="1"/>
|
||||
<field name="parent_id" colspan="3"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_roles_tree">
|
||||
<field name="name">res.roles.tree</field>
|
||||
<field name="model">res.roles</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="field_parent">child_id</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Roles">
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_res_roles">
|
||||
<field name="name">res.roles.tree</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.roles</field>
|
||||
<field name="view_type">tree</field>
|
||||
<field name="domain" eval="[('parent_id','=',False)]"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Users/Roles structure" action="action_res_roles"/>
|
||||
<record model="ir.actions.act_window" id="action_res_roles_form">
|
||||
<field name="name">res.roles.tree</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.roles</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Users/Roles structure/Define Roles" action="action_res_roles_form"/>
|
||||
|
||||
==========================================================
|
||||
View
|
||||
==========================================================
|
||||
<record model="ir.ui.view" id="view_view_form">
|
||||
<field name="name">ir.ui.view</field>
|
||||
<field name="model">ir.ui.view</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="User Interface - Views">
|
||||
<field name="name" select="1"/>
|
||||
<field name="type"/>
|
||||
<field name="model" select="1"/>
|
||||
<field name="field_parent"/>
|
||||
<field name="priority"/>
|
||||
<field name="inherit_id"/>
|
||||
<field name="arch" colspan="3" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_ui_view">
|
||||
<field name="name">ir.ui.view</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.ui.view</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_view_form"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Interface/View" action="action_ui_view"/>
|
||||
|
||||
==========================================================
|
||||
Attachment
|
||||
==========================================================
|
||||
<record model="ir.ui.view" id="view_attachment_form">
|
||||
<field name="name">ir.attachment.view</field>
|
||||
<field name="model">ir.attachment</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Attachments">
|
||||
<field name="name" colspan="3" select="1"/>
|
||||
<field name="description" colspan="3"/>
|
||||
<field name="datas" colspan="3"/>
|
||||
<field name="datas_fname"/>
|
||||
<newline/>
|
||||
<field name="res_model" select="1"/>
|
||||
<field name="res_id"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_attachment">
|
||||
<field name="name">ir.attachment</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.attachment</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_attachment_form"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low level/Base/Attachments" action="action_attachment"/>
|
||||
|
||||
==========================================================
|
||||
Report
|
||||
==========================================================
|
||||
<record model="ir.ui.view" id="view_report_custom_fields_tree">
|
||||
<field name="name">ir.report.custom.fields.tree</field>
|
||||
<field name="model">ir.report.custom.fields</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Report Fields">
|
||||
<field name="sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="width"/>
|
||||
<field name="field_child0"/>
|
||||
<field name="field_child1"/>
|
||||
<field name="field_child2"/>
|
||||
<field name="field_child3"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_report_custom_fields_form">
|
||||
<field name="name">ir.report.custom.fields</field>
|
||||
<field name="model">ir.report.custom.fields</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Report Fields">
|
||||
<field name="name"/>
|
||||
<field name="alignment"/>
|
||||
<field name="width"/>
|
||||
<field name="sequence"/>
|
||||
<newline/>
|
||||
<field name="bgcolor"/>
|
||||
<field name="fontcolor"/>
|
||||
<newline/>
|
||||
<field name="operation"/>
|
||||
<field name="groupby"/>
|
||||
<field name="cumulate"/>
|
||||
<newline/>
|
||||
<field name="field_child0" domain="[('model_id','=',parent['model_id'])]" on_change="onchange_field_child0(field_child0)"/>
|
||||
<field name="fc0_operande" domain="[('model_id','=',parent['model_id'])]"/>
|
||||
<field name="fc0_op"/>
|
||||
<field name="fc0_condition"/>
|
||||
<newline/>
|
||||
<field name="field_child1" on_change="onchange_field_child1(field_child1)"/>
|
||||
<field name="fc1_operande"/>
|
||||
<field name="fc1_op"/>
|
||||
<field name="fc1_condition"/>
|
||||
<newline/>
|
||||
<field name="field_child2" on_change="onchange_field_child2(field_child2)"/>
|
||||
<field name="fc2_operande"/>
|
||||
<field name="fc2_op"/>
|
||||
<field name="fc2_condition"/>
|
||||
<newline/>
|
||||
<field name="field_child3"/>
|
||||
<field name="fc3_operande"/>
|
||||
<field name="fc3_op"/>
|
||||
<field name="fc3_condition"/>
|
||||
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_report_custom_form">
|
||||
<field name="name">ir.report.custom</field>
|
||||
<field name="model">ir.report.custom</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Custom Report">
|
||||
<field name="name" select="1"/>
|
||||
<field name="model_id" select="1" on_change="onchange_model_id(model_id)"/>
|
||||
<field name="title"/>
|
||||
<field name="type"/>
|
||||
<field name="print_format"/>
|
||||
<field name="print_orientation"/>
|
||||
<field name="repeat_header"/>
|
||||
<field name="footer"/>
|
||||
<field name="sortby"/>
|
||||
<field name="field_parent"/>
|
||||
<field name="frequency"/>
|
||||
<field name="limitt"/>
|
||||
<field name="menu_id" />
|
||||
<field name="fields_child0" widget="one2many_list" colspan="3"/>
|
||||
<field name="state" readonly="1" select="1"/>
|
||||
<group col="2" colspan="2">
|
||||
<button name="subscribe" string="Subscribe Report" states="unsubscribed" type="object"/>
|
||||
<button name="unsubscribe" string="Unsubscribe Report" states="subscribed" type="object"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_report_custom">
|
||||
<field name="name">ir.report.custom</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.report.custom</field>
|
||||
<field name="view_type">tree</field>
|
||||
<field name="view_id" ref="view_report_custom_form"/>
|
||||
</record>
|
||||
<!--
|
||||
<menuitem name="Administration/Report/Report Custom" action="action_report_custom"/>
|
||||
-->
|
||||
|
||||
==========================================================
|
||||
model
|
||||
==========================================================
|
||||
<record model="ir.ui.view" id="view_model_form">
|
||||
<field name="name">ir.model.form</field>
|
||||
<field name="model">ir.model</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Model Description">
|
||||
<field name="name" select="1"/>
|
||||
<field name="model" select="1"/>
|
||||
<field name="info" select="1" colspan="3"/>
|
||||
<separator string="Fields" colspan="4"/>
|
||||
<field name="field_id" colspan="4" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_model_tree">
|
||||
<field name="name">ir.model.tree</field>
|
||||
<field name="model">ir.model</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Model Description">
|
||||
<field name="name"/>
|
||||
<field name="model"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
==========================================================
|
||||
fields_description
|
||||
==========================================================
|
||||
<record model="ir.ui.view" id="view_model_fields_form">
|
||||
<field name="name">ir.model.fields.form</field>
|
||||
<field name="model">ir.model.fields</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Fields Description">
|
||||
<field name="name" select="1"/>
|
||||
<field name="model_id"/>
|
||||
<field name="field_description" select="1" colspan="4"/>
|
||||
<field name="ttype" select="1"/>
|
||||
<field name="relation" select="1"/>
|
||||
<field name="relate" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="ir_model_fields_tree">
|
||||
<field name="name">ir.model.fields.tree</field>
|
||||
<field name="model">ir.model.fields</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Fields Description">
|
||||
<field name="name" select="1"/>
|
||||
<field name="field_description" select="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_model_model">
|
||||
<field name="name">ir.model.form</field>
|
||||
<field name="res_model">ir.model</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_model_form"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low level/Base/Database Structure/Objects" action="action_model_model" id="ir_model_model_menu"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_model_fields">
|
||||
<field name="name">ir.model.fields.form</field>
|
||||
<field name="res_model">ir.model.fields</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_model_fields_form"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low level/Base/Database Structure/Fields" action="action_model_fields" id="ir_model_model_fields"/>
|
||||
|
||||
==========================================================
|
||||
Translations
|
||||
==========================================================
|
||||
|
||||
<record model="ir.ui.view" id="view_translation_form">
|
||||
<field name="name">Translations</field>
|
||||
<field name="model">ir.translation</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Translations">
|
||||
<field name="name" select="1"/>
|
||||
<field name="lang" select="1"/>
|
||||
<field name="src" colspan="3" select="1"/>
|
||||
<field name="type" select="1"/>
|
||||
<field name="res_id" select="1"/>
|
||||
<field name="value" colspan="3" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_translation">
|
||||
<field name="name">ir.translation.view</field>
|
||||
<field name="res_model">ir.translation</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_translation_form"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Translations/All terms" action="action_translation"/>
|
||||
|
||||
<record model="ir.ui.view" id="view_translation_tree">
|
||||
<field name="name">Translations</field>
|
||||
<field name="model">ir.translation</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Translations">
|
||||
<field name="name"/>
|
||||
<field name="lang"/>
|
||||
<field name="src"/>
|
||||
<field name="type"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
=============================================================
|
||||
Menu Edition
|
||||
=============================================================
|
||||
-->
|
||||
|
||||
<record model="ir.ui.view" id="edit_menu">
|
||||
<field name="name">ir.ui.menu.tree</field>
|
||||
<field name="model">ir.ui.menu</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="8"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Menu">
|
||||
<field name="complete_name" icon="icon"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="edit_menu_access">
|
||||
<field name="name">ir.ui.menu.form2</field>
|
||||
<field name="model">ir.ui.menu</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Menu">
|
||||
<field name="complete_name"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="sequence"/>
|
||||
<field name="parent_id" colspan="3" select="1"/>
|
||||
<field name="groups_id" colspan="3"/>
|
||||
<field name="icon"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="grant_menu_access">
|
||||
<field name="name">ir.ui.menu.form2</field>
|
||||
<field name="res_model">ir.ui.menu</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="edit_menu_access"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Security/Grant Access to menu"
|
||||
action="grant_menu_access" />
|
||||
|
||||
<!--
|
||||
=============================================================
|
||||
Cron Jobs
|
||||
=============================================================
|
||||
-->
|
||||
<record model="ir.ui.view" id="ir_cron_view_tree">
|
||||
<field name="name">ir.cron.tree</field>
|
||||
<field name="model">ir.cron</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Scheduled Actions">
|
||||
<field name="nextcall"/>
|
||||
<field name="name"/>
|
||||
<field name="interval_number"/>
|
||||
<field name="interval_type"/>
|
||||
<field name="numbercall"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record> <record model="ir.ui.view" id="ir_cron_view">
|
||||
<field name="name">ir.cron.form</field>
|
||||
<field name="model">ir.cron</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Scheduled Actions">
|
||||
<field name="name" select="1"/>
|
||||
<field name="active" select="1"/>
|
||||
<field name="user_id" select="1"/>
|
||||
<field name="priority" select="1"/>
|
||||
<newline/>
|
||||
<field name="interval_number"/>
|
||||
<field name="interval_type"/>
|
||||
<newline/>
|
||||
<field name="nextcall"/>
|
||||
<field name="numbercall"/>
|
||||
<field name="doall"/>
|
||||
<separator string="Action to trigger" colspan="4"/>
|
||||
<newline/>
|
||||
<field name="model" readonly="1"/>
|
||||
<field name="function" readonly="1"/>
|
||||
<field name="args" colspan="3" readonly="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="ir_cron_act">
|
||||
<field name="name">ir.cron.form</field>
|
||||
<field name="res_model">ir.cron</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="ir_cron_view"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low level/Base/Actions/Scheduled Actions"
|
||||
action="ir_cron_act"/>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="ir_access_view_tree">
|
||||
<field name="name">ir.model.access.tree</field>
|
||||
<field name="model">ir.model.access</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Access Controls">
|
||||
<field name="name"/>
|
||||
<field name="model_id"/>
|
||||
<field name="group_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="ir_access_view_form">
|
||||
<field name="name">ir.model.access.form</field>
|
||||
<field name="model">ir.model.access</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Access Controls">
|
||||
<field name="name" select="1" colspan="3"/>
|
||||
<field name="model_id" select="1"/>
|
||||
<field name="group_id" select="1"/>
|
||||
<newline/>
|
||||
<field name="perm_read"/>
|
||||
<field name="perm_write"/>
|
||||
<field name="perm_create"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="ir_access_act">
|
||||
<field name="name">ir.model.access.form</field>
|
||||
<field name="res_model">ir.model.access</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="ir_access_view_form"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Security/Access Controls" action="ir_access_act"/>
|
||||
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,141 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields,osv
|
||||
|
||||
class actions(osv.osv):
|
||||
_name = 'ir.actions.actions'
|
||||
_table = 'ir_actions'
|
||||
_columns = {
|
||||
'name': fields.char('Action Name', required=True, size=64),
|
||||
'type': fields.char('Action Type', required=True, size=32),
|
||||
'usage': fields.char('Action Usage', size=32)
|
||||
}
|
||||
_defaults = {
|
||||
'usage': lambda *a: False,
|
||||
}
|
||||
actions()
|
||||
|
||||
class act_execute(osv.osv):
|
||||
_name = 'ir.actions.execute'
|
||||
_table = 'ir_act_execute'
|
||||
_sequence = 'ir_actions_id_seq'
|
||||
_columns = {
|
||||
'name': fields.char('name', size=64, required=True, translate=True),
|
||||
'type': fields.char('type', size=32, required=True),
|
||||
'func_name': fields.char('Function Name', size=64, required=True),
|
||||
'func_arg': fields.char('Function Argument', size=64),
|
||||
'usage': fields.char('Action Usage', size=32)
|
||||
}
|
||||
act_execute()
|
||||
|
||||
class group(osv.osv):
|
||||
_name = 'ir.actions.group'
|
||||
_table = 'ir_act_group'
|
||||
_sequence = 'ir_actions_id_seq'
|
||||
_columns = {
|
||||
'name': fields.char('Group Name', size=64, required=True),
|
||||
'type': fields.char('Action Type', size=32, required=True),
|
||||
'exec_type': fields.char('Execution sequence', size=64, required=True),
|
||||
'usage': fields.char('Action Usage', size=32)
|
||||
}
|
||||
group()
|
||||
|
||||
class report_custom(osv.osv):
|
||||
_name = 'ir.actions.report.custom'
|
||||
_table = 'ir_act_report_custom'
|
||||
_sequence = 'ir_actions_id_seq'
|
||||
_columns = {
|
||||
'name': fields.char('Report Name', size=64, required=True, translate=True),
|
||||
'type': fields.char('Report Type', size=32, required=True),
|
||||
'model':fields.char('Model', size=64, required=True),
|
||||
'report_id': fields.integer('Report Ref.', required=True),
|
||||
'usage': fields.char('Action Usage', size=32)
|
||||
}
|
||||
report_custom()
|
||||
|
||||
class report_xml(osv.osv):
|
||||
_name = 'ir.actions.report.xml'
|
||||
_table = 'ir_act_report_xml'
|
||||
_sequence = 'ir_actions_id_seq'
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True, translate=True),
|
||||
'type': fields.char('Report Type', size=32, required=True),
|
||||
'model': fields.char('Model', size=64, required=True),
|
||||
'report_name': fields.char('Internal Name', size=64, required=True),
|
||||
'report_xsl': fields.char('XSL path', size=256),
|
||||
'report_xml': fields.char('XML path', size=256),
|
||||
'report_rml': fields.char('RML path', size=256),
|
||||
'auto': fields.boolean('Automatic XSL:RML', required=True),
|
||||
'usage': fields.char('Action Usage', size=32)
|
||||
}
|
||||
_defaults = {
|
||||
'type': lambda *a: 'ir.actions.report.xml',
|
||||
'auto': lambda *a: True,
|
||||
}
|
||||
report_xml()
|
||||
|
||||
class act_window(osv.osv):
|
||||
_name = 'ir.actions.act_window'
|
||||
_table = 'ir_act_window'
|
||||
_sequence = 'ir_actions_id_seq'
|
||||
_columns = {
|
||||
'name': fields.char('Action Name', size=64, required=True, translate=True),
|
||||
'type': fields.char('Action Type', size=32, required=True),
|
||||
'view_id': fields.many2one('ir.ui.view', 'View Ref.', ondelete='cascade'),
|
||||
'domain': fields.char('Domain Value', size=250),
|
||||
'context': fields.char('Context Value', size=250),
|
||||
'res_model': fields.char('Model', size=64),
|
||||
'view_type': fields.selection((('tree','Tree'),('form','Form')),string='Type of view'),
|
||||
'view_mode': fields.selection((('form,list','Form - List'),('list,form','List - Form')), string='Mode of view'),
|
||||
'usage': fields.char('Action Usage', size=32)
|
||||
}
|
||||
_defaults = {
|
||||
'type': lambda *a: 'ir.actions.act_window',
|
||||
'view_type': lambda *a: 'form',
|
||||
'view_mode': lambda *a: 'form,tree',
|
||||
'context': lambda *a: '{}'
|
||||
}
|
||||
act_window()
|
||||
|
||||
class act_wizard(osv.osv):
|
||||
_name = 'ir.actions.wizard'
|
||||
_table = 'ir_act_wizard'
|
||||
_sequence = 'ir_actions_id_seq'
|
||||
_columns = {
|
||||
'name': fields.char('Wizard info', size=64, required=True, translate=True),
|
||||
'type': fields.char('Action type', size=32, required=True),
|
||||
'wiz_name': fields.char('Wizard name', size=64, required=True),
|
||||
'multi': fields.boolean('Action on multiple doc.', help="If set to true, the wizard will not be displayed on the right toolbar of a form views.")
|
||||
}
|
||||
_defaults = {
|
||||
'type': lambda *a: 'ir.actions.wizard',
|
||||
'multi': lambda *a: False,
|
||||
}
|
||||
act_wizard()
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields,osv
|
||||
|
||||
class ir_attachment(osv.osv):
|
||||
_name = 'ir.attachment'
|
||||
_columns = {
|
||||
'name': fields.char('Attachment Name',size=64, required=True),
|
||||
'datas': fields.binary('Data'),
|
||||
'datas_fname': fields.char('Data Filename',size=64),
|
||||
'description': fields.text('Description'),
|
||||
'res_model': fields.char('Resource Model',size=64, required=True, readonly=True),
|
||||
'res_id': fields.integer('Resource ID', required=True, readonly=True),
|
||||
'link': fields.char('Link', size=256)
|
||||
}
|
||||
ir_attachment()
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
#
|
||||
# SPEC: Execute "model.function(*eval(args))" periodically
|
||||
# date : date to execute the job or NULL if directly
|
||||
# delete_after: delete the ir.cron entry after execution
|
||||
# interval_* : period
|
||||
# max_repeat : number of execution or NULL if endlessly
|
||||
#
|
||||
# TODO:
|
||||
# Error treatment: exception, request, ... -> send request to uid
|
||||
#
|
||||
|
||||
from mx import DateTime
|
||||
import time
|
||||
import netsvc
|
||||
import tools
|
||||
import pooler
|
||||
from osv import fields,osv
|
||||
|
||||
next_wait = 60
|
||||
|
||||
_intervalTypes = {
|
||||
'work_days': lambda interal: DateTime.RelativeDateTime(days=interval),
|
||||
'days': lambda interval: DateTime.RelativeDateTime(days=interval),
|
||||
'hours': lambda interval: DateTime.RelativeDateTime(hours=interval),
|
||||
'weeks': lambda interval: DateTime.RelativeDateTime(days=7*interval),
|
||||
'months': lambda interval: DateTime.RelativeDateTime(months=interval),
|
||||
'minutes': lambda interval: DateTime.RelativeDateTime(minutes=interval),
|
||||
}
|
||||
|
||||
class ir_cron(osv.osv, netsvc.Agent):
|
||||
_name = "ir.cron"
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=60, required=True),
|
||||
'user_id': fields.many2one('res.users', 'User', required=True),
|
||||
'active': fields.boolean('Active'),
|
||||
'interval_number': fields.integer('Interval Number'),
|
||||
'interval_type': fields.selection( [('minutes', 'Minutes'),
|
||||
('hours', 'Hours'), ('days', 'Days'),('weeks', 'Weeks'), ('months', 'Months')], 'Interval Unit'),
|
||||
# number of time the function is called, a negative number
|
||||
# indicates that the function will always be called.
|
||||
'numbercall': fields.integer('Number of calls'),
|
||||
|
||||
# Repeat missed cronjobs ?
|
||||
'doall' : fields.boolean('Repeat all missed'),
|
||||
|
||||
'nextcall' : fields.datetime('Next call date', required=True),
|
||||
'model': fields.char('Model', size=64),
|
||||
'function': fields.char('Function', size=64),
|
||||
'args': fields.text('Arguments'),
|
||||
|
||||
# 0 = Very Urgent, 10 = not urgent
|
||||
'priority': fields.integer('Priority (0=Very Urgent)')
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'nextcall' : lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'priority' : lambda *a: 5,
|
||||
'user_id' : lambda obj,cr,uid,context: uid,
|
||||
'interval_number' : lambda *a: 1,
|
||||
'interval_type' : lambda *a: 'months',
|
||||
'numbercall' : lambda *a: 1,
|
||||
'active' : lambda *a: 1,
|
||||
'doall' : lambda *a: 1
|
||||
}
|
||||
|
||||
def _callback(self, cr, uid, model, func, args):
|
||||
args = (args or []) and eval(args)
|
||||
f = getattr(self.pool.get(model), func)
|
||||
f(cr, uid, *args)
|
||||
|
||||
def _poolJobs(self, db_name, check=False):
|
||||
now = DateTime.now()
|
||||
#FIXME: multidb. Solution: a l'instanciation d'une nouvelle connection bd (ds pooler) fo que j'instancie
|
||||
# un nouveau pooljob avec comme parametre la bd
|
||||
try:
|
||||
cr = pooler.get_db(db_name).cursor()
|
||||
except:
|
||||
return False
|
||||
|
||||
try:
|
||||
cr.execute('select * from ir_cron where numbercall<>0 and active and nextcall<=now() order by priority')
|
||||
for job in cr.dictfetchall():
|
||||
nextcall = DateTime.strptime(job['nextcall'], '%Y-%m-%d %H:%M:%S')
|
||||
numbercall = job['numbercall']
|
||||
|
||||
ok = False
|
||||
while nextcall<now and numbercall:
|
||||
if numbercall > 0:
|
||||
numbercall -= 1
|
||||
if not ok or job['doall']:
|
||||
self._callback(cr, job['user_id'], job['model'], job['function'], job['args'])
|
||||
if numbercall:
|
||||
nextcall += _intervalTypes[job['interval_type']](job['interval_number'])
|
||||
ok = True
|
||||
addsql=''
|
||||
if not numbercall:
|
||||
addsql = ', active=False'
|
||||
cr.execute("update ir_cron set nextcall=%s, numbercall=%d"+addsql+" where id=%d",
|
||||
(nextcall.strftime('%Y-%m-%d %H:%M:%S'), numbercall, job['id']))
|
||||
cr.commit()
|
||||
finally:
|
||||
cr.close()
|
||||
#
|
||||
# Can be improved to do at the min(min(nextcalls), time()+next_wait)
|
||||
# But is this an improvement ?
|
||||
#
|
||||
if not check:
|
||||
self.setAlarm(self._poolJobs, int(time.time())+next_wait, [db_name])
|
||||
|
||||
# def __init__(self):
|
||||
# super(ir_cron, self).__init__()
|
||||
ir_cron()
|
|
@ -0,0 +1,43 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields,osv
|
||||
|
||||
class ir_default(osv.osv):
|
||||
_name = 'ir.default'
|
||||
_columns = {
|
||||
'field_tbl': fields.char('Model',size=64),
|
||||
'field_name': fields.char('Model field',size=64),
|
||||
'value': fields.char('Default Value',size=64),
|
||||
'uid': fields.many2one('res.users', 'Users'),
|
||||
'page': fields.char('View',size=64),
|
||||
'ref_table': fields.char('Table Ref.',size=64),
|
||||
'ref_id': fields.integer('ID Ref.',size=64),
|
||||
}
|
||||
ir_default()
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields,osv
|
||||
|
||||
|
||||
class ir_exports(osv.osv):
|
||||
_name = "ir.exports"
|
||||
_columns = {
|
||||
'name': fields.char('Export name', size=128),
|
||||
'resource': fields.char('Resource', size=128),
|
||||
'export_fields': fields.one2many('ir.exports.line', 'export_id',
|
||||
'Export Id'),
|
||||
}
|
||||
ir_exports()
|
||||
|
||||
|
||||
class ir_exports_line(osv.osv):
|
||||
_name = 'ir.exports.line'
|
||||
_columns = {
|
||||
'name': fields.char('Field name', size=64),
|
||||
'export_id': fields.many2one('ir.exports', 'Exportation', select=True),
|
||||
}
|
||||
ir_exports_line()
|
|
@ -0,0 +1,32 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields,osv
|
||||
import ir
|
||||
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields,osv
|
||||
import ir
|
||||
import netsvc
|
||||
|
||||
import time
|
||||
import tools
|
||||
import pooler
|
||||
|
||||
class ir_model(osv.osv):
|
||||
_name = 'ir.model'
|
||||
_rec_name = 'model'
|
||||
_columns = {
|
||||
'name': fields.char('Model name', size=64, translate=True),
|
||||
'model': fields.char('Object name', size=64, required=True),
|
||||
'info': fields.text('Information'),
|
||||
'field_id': fields.one2many('ir.model.fields', 'model_id', 'Fields', required=True),
|
||||
}
|
||||
_defaults = {
|
||||
'name': lambda *a: 'No Name',
|
||||
}
|
||||
ir_model()
|
||||
|
||||
class ir_model_fields(osv.osv):
|
||||
_name = 'ir.model.fields'
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64),
|
||||
'model': fields.char('Model Name', size=64, required=True),
|
||||
# on pourrait egalement changer ca en many2one, mais le prob c'est qu'alors faut
|
||||
# faire une jointure a chaque fois qu'on recherche vu que le client ne connait que le nom
|
||||
# de l'objet et pas son id
|
||||
'relation': fields.char('Model Relation', size=64),
|
||||
'model_id': fields.many2one('ir.model', 'Model id', required=True, select=True),
|
||||
# in fact, this is the field label
|
||||
'field_description': fields.char('Field Description', size=256),
|
||||
'ttype': fields.char('Field Type', size=64),
|
||||
'relate': fields.boolean('Click and Relate'),
|
||||
|
||||
'groups': fields.many2many('res.groups', 'ir_model_fields_group_rel', 'field_id', 'group_id', 'Groups'),
|
||||
'group_name': fields.char('Group Name', size=128),
|
||||
'view_load': fields.boolean('View Auto-Load'),
|
||||
}
|
||||
_defaults = {
|
||||
'relate': lambda *a: 1,
|
||||
'view_load': lambda *a: 0,
|
||||
'name': lambda *a: 'No Name',
|
||||
'field_description': lambda *a: 'No description available',
|
||||
}
|
||||
_order = "id"
|
||||
ir_model_fields()
|
||||
|
||||
class ir_model_access(osv.osv):
|
||||
_name = 'ir.model.access'
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True),
|
||||
'model_id': fields.many2one('ir.model', 'Model', required=True),
|
||||
'group_id': fields.many2one('res.groups', 'Group'),
|
||||
'perm_read': fields.boolean('Read Access'),
|
||||
'perm_write': fields.boolean('Write Access'),
|
||||
'perm_create': fields.boolean('Create Access'),
|
||||
}
|
||||
def check(self, cr, uid, model_name, mode='read'):
|
||||
assert mode in ['read','write','create'], 'Invalid access mode for security'
|
||||
|
||||
# fetch the list of rules for this "permission type" on this model
|
||||
cr.execute('select group_id, perm_'+mode+' from ir_model_access a left join ir_model m on (a.model_id=m.id) where m.model=%s', (model_name,))
|
||||
|
||||
# if no rule is found, grant the access
|
||||
if not cr.rowcount:
|
||||
return True
|
||||
|
||||
# compute the list of groups which have the right we are looking for
|
||||
ids = map(lambda x: str(x[0]), filter(lambda x: x[1], cr.fetchall()))
|
||||
if not ids:
|
||||
raise osv.except_osv('Access denied !', 'You can not %s this resource !' % mode)
|
||||
ids_str = ','.join(ids)
|
||||
|
||||
# check if the user is part of one of those groups
|
||||
cr.execute('select count(*) from res_groups_users_rel where uid=%d and gid in ('+ids_str+')', (uid,))
|
||||
if cr.fetchone()[0]:
|
||||
return True
|
||||
raise osv.except_osv('Access denied !', 'You can not %s this resource !' % mode)
|
||||
check = tools.cache()(check)
|
||||
|
||||
#
|
||||
# Methods to clean the cache on the Check Method.
|
||||
#
|
||||
def write(self, cr, uid, *args, **argv):
|
||||
res = super(ir_model_access, self).write(cr, uid, *args, **argv)
|
||||
self.check()
|
||||
return res
|
||||
def create(self, cr, uid, *args, **argv):
|
||||
res = super(ir_model_access, self).create(cr, uid, *args, **argv)
|
||||
self.check()
|
||||
return res
|
||||
def unlink(self, cr, uid, *args, **argv):
|
||||
res = super(ir_model_access, self).unlink(cr, uid, *args, **argv)
|
||||
self.check()
|
||||
return res
|
||||
ir_model_access()
|
||||
|
||||
class ir_model_data(osv.osv):
|
||||
_name = 'ir.model.data'
|
||||
_columns = {
|
||||
'name': fields.char('XML Identifier', required=True, size=64),
|
||||
'model': fields.char('Model', required=True, size=64),
|
||||
'module': fields.char('Module', required=True, size=64),
|
||||
'res_id': fields.integer('Resource ID'),
|
||||
'noupdate': fields.boolean('Non Updatable'),
|
||||
'date_update': fields.datetime('Update Date'),
|
||||
'date_init': fields.datetime('Init Date')
|
||||
}
|
||||
_defaults = {
|
||||
'date_init': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'date_update': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'noupdate': lambda *a: False
|
||||
}
|
||||
|
||||
def __init__(self, pool):
|
||||
osv.osv.__init__(self, pool)
|
||||
self.loads = {}
|
||||
self.doinit = True
|
||||
self.unlink_mark = {}
|
||||
|
||||
def _get_id(self,cr, uid, module, xml_id):
|
||||
ids = self.search(cr, uid, [('module','=',module),('name','=', xml_id)])
|
||||
assert len(ids)==1, '%d reference(s) to %s. You should have only one !' % (len(ids),xml_id)
|
||||
return ids[0]
|
||||
|
||||
def _update_dummy(self,cr, uid, model, module, xml_id=False, store=True):
|
||||
if not xml_id:
|
||||
return False
|
||||
try:
|
||||
id = self.read(cr, uid, [self._get_id(cr, uid, module, xml_id)], ['res_id'])[0]['res_id']
|
||||
self.loads[(module,xml_id)] = (model,id)
|
||||
except:
|
||||
id = False
|
||||
return id
|
||||
|
||||
def _update(self,cr, uid, model, module, values, xml_id=False, store=True, noupdate=False, mode='init', res_id=False):
|
||||
warning = True
|
||||
if xml_id and ('.' in xml_id):
|
||||
assert len(xml_id.split('.'))==2, '"%s" contains too many dots. XML ids should not contain dots ! These are used to refer to other modules data, as in module.reference_id' % (xml_id)
|
||||
warning = False
|
||||
module, xml_id = xml_id.split('.')
|
||||
if (not xml_id) and (not self.doinit):
|
||||
return False
|
||||
action_id = False
|
||||
if xml_id:
|
||||
cr.execute('select id,res_id from ir_model_data where module=%s and name=%s', (module,xml_id))
|
||||
results = cr.fetchall()
|
||||
for action_id2,res_id2 in results:
|
||||
cr.execute('select id from '+self.pool.get(model)._table+' where id=%d', (res_id2,))
|
||||
result3 = cr.fetchone()
|
||||
if not result3:
|
||||
cr.execute('delete from ir_model_data where id=%d', (action_id2,))
|
||||
else:
|
||||
res_id,action_id = res_id2,action_id2
|
||||
|
||||
if action_id and res_id:
|
||||
self.pool.get(model).write(cr, uid, [res_id], values)
|
||||
self.write(cr, uid, [action_id], {'date_update': time.strftime('%Y-%m-%d %H:%M:%S')})
|
||||
elif res_id:
|
||||
self.pool.get(model).write(cr, uid, [res_id], values)
|
||||
if xml_id:
|
||||
self.create(cr, uid, {'name':xml_id, 'model':model, 'module':module, 'res_id':res_id, 'noupdate':noupdate})
|
||||
else:
|
||||
if mode=='init' or (mode=='update' and xml_id):
|
||||
res_id = self.pool.get(model).create(cr, uid, values)
|
||||
if xml_id:
|
||||
self.create(cr, uid, {'name':xml_id, 'model':model, 'module':module, 'res_id':res_id, 'noupdate':noupdate})
|
||||
if xml_id:
|
||||
if warning:
|
||||
assert (module,xml_id) not in self.loads, "id '%s' is already defined in module '%s' !" % (xml_id, module)
|
||||
if res_id:
|
||||
self.loads[(module,xml_id)] = (model, res_id)
|
||||
return res_id
|
||||
|
||||
def _unlink(self, cr, uid, model, ids, direct=False):
|
||||
#self.pool.get(model).unlink(cr, uid, ids)
|
||||
for id in ids:
|
||||
self.unlink_mark[(model, id)]=False
|
||||
cr.execute('delete from ir_model_data where res_id=%d and model=\'%s\'', (id,model))
|
||||
return True
|
||||
|
||||
def ir_set(self, cr, uid, key, key2, name, models, value, replace=True, isobject=False, meta=None):
|
||||
obj = self.pool.get('ir.values')
|
||||
if type(models[0])==type([]) or type(models[0])==type(()):
|
||||
model,res_id = models[0]
|
||||
else:
|
||||
res_id=None
|
||||
model = models[0]
|
||||
|
||||
if res_id:
|
||||
where = ' and res_id=%d' % (res_id,)
|
||||
else:
|
||||
where = ' and (res_id is null)'
|
||||
|
||||
if key2:
|
||||
where += ' and key2=\'%s\'' % (key2,)
|
||||
else:
|
||||
where += ' and (key2 is null)'
|
||||
|
||||
cr.execute('select * from ir_values where model=%s and key=%s and name=%s'+where,(model, key, name))
|
||||
res = cr.fetchone()
|
||||
if not res:
|
||||
res = ir.ir_set(cr, uid, key, key2, name, models, value, replace, isobject, meta)
|
||||
return True
|
||||
|
||||
def _process_end(self, cr, uid, modules):
|
||||
if not modules:
|
||||
return True
|
||||
module_str = ["'%s'" % m for m in modules]
|
||||
cr.execute('select id,name,model,res_id,module from ir_model_data where module in ('+','.join(module_str)+') and not noupdate')
|
||||
wkf_todo = []
|
||||
for (id, name, model, res_id,module) in cr.fetchall():
|
||||
if (module,name) not in self.loads:
|
||||
self.unlink_mark[(model,res_id)] = id
|
||||
if model=='workflow.activity':
|
||||
cr.execute('select res_type,res_id from wkf_instance where id in (select inst_id from wkf_workitem where act_id=%d)', (res_id,))
|
||||
wkf_todo.extend(cr.fetchall())
|
||||
cr.execute("update wkf_transition set condition='True', role_id=NULL, signal=NULL,act_to=act_from,act_from=%d where act_to=%d", (res_id,res_id))
|
||||
cr.execute("delete from wkf_transition where act_to=%d", (res_id,))
|
||||
|
||||
for model,id in wkf_todo:
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
wf_service.trg_write(uid, model, id, cr)
|
||||
|
||||
cr.commit()
|
||||
for (model,id) in self.unlink_mark.keys():
|
||||
if self.pool.get(model):
|
||||
print 'Deleting %s@%s' % (id, model),
|
||||
try:
|
||||
self.pool.get(model).unlink(cr, uid, [id])
|
||||
if self.unlink_mark[(model,id)]:
|
||||
self.unlink(cr, uid, [self.unlink_mark[(model,id)]])
|
||||
cr.commit()
|
||||
print '... ok'
|
||||
except:
|
||||
print '... ko'
|
||||
print '-'*60
|
||||
print 'WARNING: Could not delete id', id, 'of model', model
|
||||
print '\tThere should be some relation that points to this resource'
|
||||
print '\tYou should manually fix this and restart --update=module'
|
||||
return True
|
||||
ir_model_data()
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields,osv
|
||||
from osv.orm import browse_null
|
||||
import ir
|
||||
import report.custom
|
||||
|
||||
class report_custom(osv.osv):
|
||||
_name = 'ir.report.custom'
|
||||
_columns = {
|
||||
'name': fields.char('Report Name', size=64, required=True, translate=True),
|
||||
'model_id': fields.many2one('ir.model','Model', required=True, change_default=True),
|
||||
'type': fields.selection([('table','Tabular'),('pie','Pie Chart'),('bar','Bar Chart'),('line','Line Plot')], "Report Type", size=64, required='True'),
|
||||
'title': fields.char("Report title", size=64, required='True', translate=True),
|
||||
'print_format': fields.selection((('A4','a4'),('A5','a5')), 'Print format', required=True),
|
||||
'print_orientation': fields.selection((('landscape','Landscape'),('portrait','Portrait')), 'Print orientation', required=True, size=16),
|
||||
'repeat_header': fields.boolean('Repeat Header'),
|
||||
'footer': fields.char('Report Footer', size=64, required=True),
|
||||
'sortby': fields.char('Sorted By', size=64),
|
||||
'fields_child0': fields.one2many('ir.report.custom.fields', 'report_id','Fields', required=True),
|
||||
'field_parent': fields.many2one('ir.model.fields','Child Field'),
|
||||
'state': fields.selection([('unsubscribed','Unsubscribed'),('subscribed','Subscribed')], 'State', size=64),
|
||||
'frequency': fields.selection([('Y','Yearly'),('M','Monthly'),('D','Daily')], 'Frequency', size=64),
|
||||
'limitt': fields.char('Limit', size=9),
|
||||
'menu_id': fields.many2one('ir.ui.menu', 'Menu')
|
||||
}
|
||||
_defaults = {
|
||||
'print_format': lambda *a: 'A4',
|
||||
'print_orientation': lambda *a: 'portrait',
|
||||
'state': lambda *a: 'unsubscribed',
|
||||
'type': lambda *a: 'table',
|
||||
'footer': lambda *a: 'Generated by Tiny ERP'
|
||||
}
|
||||
|
||||
def onchange_model_id(self, cr, uid, ids, model_id):
|
||||
if not(model_id):
|
||||
return {}
|
||||
return {'domain': {'field_parent': [('model_id','=',model_id)]}}
|
||||
|
||||
def unsubscribe(self, cr, uid, ids, context={}):
|
||||
#TODO: should delete the ir.actions.report.custom for these reports and do an ir_del
|
||||
self.write(cr, uid, ids, {'state':'unsubscribed'})
|
||||
return True
|
||||
|
||||
def subscribe(self, cr, uid, ids, context={}):
|
||||
for report in self.browse(cr, uid, ids):
|
||||
report.fields_child0.sort(lambda x,y : x.sequence - y.sequence)
|
||||
|
||||
# required on field0 does not seem to work( cause we use o2m_l ?)
|
||||
if not report.fields_child0:
|
||||
raise osv.except_osv('Invalid operation :', 'Enter at least one field !')
|
||||
|
||||
if report.type in ['pie', 'bar', 'line'] and report.field_parent:
|
||||
raise osv.except_osv('Invalid operation :', 'Tree can only be used in tabular reports')
|
||||
|
||||
# Otherwise it won't build a good tree. See level.pop in custom.py.
|
||||
if report.type == 'table' and report.field_parent and report.fields_child0 and not report.fields_child0[0].groupby:
|
||||
raise osv.except_osv('Invalid operation :', 'When creating tree (field child) report, data must be group by the first field')
|
||||
|
||||
if report.type == 'pie':
|
||||
if len(report.fields_child0) != 2:
|
||||
raise osv.except_osv('Invalid operation :', 'Pie charts need exactly two fields')
|
||||
else:
|
||||
c_f = {}
|
||||
for i in range(2):
|
||||
c_f[i] = []
|
||||
tmp = report.fields_child0[i]
|
||||
for j in range(3):
|
||||
c_f[i].append((not isinstance(eval('tmp.field_child'+str(j)), browse_null) and eval('tmp.field_child'+str(j)+'.ttype')) or None)
|
||||
if not reduce(lambda x,y : x or y, map(lambda x: x in ['integer', 'float'], c_f[1])):
|
||||
raise osv.except_osv('Invalid operation : ','Second field should be figures')
|
||||
|
||||
if report.type == 'bar':
|
||||
if len(report.fields_child0) < 2:
|
||||
raise osv.except_osv('Invalid operation : ','Bar charts need at least two fields')
|
||||
else:
|
||||
c_f = {}
|
||||
for i in range(len(report.fields_child0)):
|
||||
c_f[i] = []
|
||||
tmp = report.fields_child0[i]
|
||||
for j in range(3):
|
||||
c_f[i].append((not isinstance(eval('tmp.field_child'+str(j)), browse_null) and eval('tmp.field_child'+str(j)+'.ttype')) or None)
|
||||
|
||||
if i == 0:
|
||||
pass
|
||||
else:
|
||||
if not reduce(lambda x,y : x or y, map(lambda x: x in ['integer', 'float'], c_f[i])):
|
||||
raise osv.except_osv('Invalid operation : ','Field %d should be a figure' %(i,))
|
||||
|
||||
if report.state=='subscribed':
|
||||
continue
|
||||
|
||||
name = report.name
|
||||
model = report.model_id.model
|
||||
|
||||
action_def = {'report_id':report.id, 'type':'ir.actions.report.custom', 'model':model, 'name':name}
|
||||
id = self.pool.get('ir.actions.report.custom').create(cr, uid, action_def)
|
||||
m_id = report.menu_id.id
|
||||
action = "ir.actions.report.custom,%d" % (id,)
|
||||
if not report.menu_id:
|
||||
ir.ir_set(cr, uid, 'action', 'client_print_multi', name, [(model, False)], action, False, True)
|
||||
else:
|
||||
ir.ir_set(cr, uid, 'action', 'tree_but_open', 'Menuitem', [('ir.ui.menu', int(m_id))], action, False, True)
|
||||
|
||||
self.write(cr, uid, [report.id], {'state':'subscribed'}, context)
|
||||
return True
|
||||
report_custom()
|
||||
|
||||
|
||||
class report_custom_fields(osv.osv):
|
||||
_name = 'ir.report.custom.fields'
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True),
|
||||
'report_id': fields.many2one('ir.report.custom', 'Report Ref', select=True),
|
||||
'field_child0': fields.many2one('ir.model.fields', 'field child0', required=True),
|
||||
'fc0_operande': fields.many2one('ir.model.fields', 'Constraint'),
|
||||
'fc0_condition': fields.char('Condition', size=64),
|
||||
'fc0_op': fields.selection((('>','>'),('<','<'),('==','='),('in','in'),('gety,==','(year)=')), 'Relation'),
|
||||
'field_child1': fields.many2one('ir.model.fields', 'field child1'),
|
||||
'fc1_operande': fields.many2one('ir.model.fields', 'Constraint'),
|
||||
'fc1_condition': fields.char('condition', size=64),
|
||||
'fc1_op': fields.selection((('>','>'),('<','<'),('==','='),('in','in'),('gety,==','(year)=')), 'Relation'),
|
||||
'field_child2': fields.many2one('ir.model.fields', 'field child2'),
|
||||
'fc2_operande': fields.many2one('ir.model.fields', 'Constraint'),
|
||||
'fc2_condition': fields.char('condition', size=64),
|
||||
'fc2_op': fields.selection((('>','>'),('<','<'),('==','='),('in','in'),('gety,==','(year)=')), 'Relation'),
|
||||
'field_child3': fields.many2one('ir.model.fields', 'field child3'),
|
||||
'fc3_operande': fields.many2one('ir.model.fields', 'Constraint'),
|
||||
'fc3_condition': fields.char('condition', size=64),
|
||||
'fc3_op': fields.selection((('>','>'),('<','<'),('==','='),('in','in'),('gety,==','(year)=')), 'Relation'),
|
||||
'alignment': fields.selection((('left','left'),('right','right'),('center','center')), 'Alignment', required=True),
|
||||
'sequence': fields.integer('Sequence', required=True),
|
||||
'width': fields.integer('Fixed Width'),
|
||||
'operation': fields.selection((('none', 'None'),('calc_sum','Calculate Sum'),('calc_avg','Calculate Average'),('calc_count','Calculate Count'),('calc_max', 'Get Max'))),
|
||||
'groupby' : fields.boolean('Group by'),
|
||||
'bgcolor': fields.char('Background Color', size=64),
|
||||
'fontcolor': fields.char('Font color', size=64),
|
||||
'cumulate': fields.boolean('Cumulate')
|
||||
}
|
||||
_defaults = {
|
||||
'alignment': lambda *a: 'left',
|
||||
'bgcolor': lambda *a: 'white',
|
||||
'fontcolor': lambda *a: 'black',
|
||||
'operation': lambda *a: 'none',
|
||||
}
|
||||
_order = "sequence"
|
||||
|
||||
def onchange_any_field_child(self, cr, uid, ids, field_id, level):
|
||||
if not(field_id):
|
||||
return {}
|
||||
next_level_field_name = 'field_child%d' % (level+1)
|
||||
next_level_operande = 'fc%d_operande' % (level+1)
|
||||
field = self.pool.get('ir.model.fields').browse(cr, uid, [field_id])[0]
|
||||
res = self.pool.get(field.model).fields_get(cr, uid, field.name)
|
||||
if res[field.name].has_key('relation'):
|
||||
cr.execute('select id from ir_model where model=%s', (res[field.name]['relation'],))
|
||||
(id,) = cr.fetchone() or (False,)
|
||||
if id:
|
||||
return {
|
||||
'domain': {
|
||||
next_level_field_name: [('model_id', '=', id)],
|
||||
next_level_operande: [('model_id', '=', id)]
|
||||
},
|
||||
'required': {
|
||||
next_level_field_name: True
|
||||
}
|
||||
}
|
||||
else:
|
||||
print "Warning: using a relation field which uses an unknown object"
|
||||
return {'required': {next_level_field_name: True}}
|
||||
else:
|
||||
return {'domain': {next_level_field_name: []}}
|
||||
|
||||
def get_field_child_onchange_method(level):
|
||||
return lambda self, cr, uid, ids, field_id: self.onchange_any_field_child(cr, uid, ids, field_id, level)
|
||||
|
||||
onchange_field_child0 = get_field_child_onchange_method(0)
|
||||
onchange_field_child1 = get_field_child_onchange_method(1)
|
||||
onchange_field_child2 = get_field_child_onchange_method(2)
|
||||
report_custom_fields()
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import threading
|
||||
import time
|
||||
from osv import fields,osv
|
||||
|
||||
class ir_sequence_type(osv.osv):
|
||||
_name = 'ir.sequence.type'
|
||||
_columns = {
|
||||
'name': fields.char('Sequence Name',size=64, required=True),
|
||||
'code': fields.char('Sequence Code',size=32, required=True),
|
||||
}
|
||||
ir_sequence_type()
|
||||
|
||||
def _code_get(self, cr, uid, context={}):
|
||||
cr.execute('select code, name from ir_sequence_type')
|
||||
return cr.fetchall()
|
||||
|
||||
class ir_sequence(osv.osv):
|
||||
_name = 'ir.sequence'
|
||||
_columns = {
|
||||
'name': fields.char('Sequence Name',size=64, required=True),
|
||||
'code': fields.selection(_code_get, 'Sequence Code',size=64, required=True),
|
||||
'active': fields.boolean('Active'),
|
||||
'prefix': fields.char('Prefix',size=64),
|
||||
'suffix': fields.char('Suffix',size=64),
|
||||
'number_next': fields.integer('Next Number', required=True),
|
||||
'number_increment': fields.integer('Increment Number', required=True),
|
||||
'padding' : fields.integer('Number padding', required=True),
|
||||
}
|
||||
_defaults = {
|
||||
'active': lambda *a: True,
|
||||
'number_increment': lambda *a: 1,
|
||||
'number_next': lambda *a: 1,
|
||||
'padding' : lambda *a : 0,
|
||||
}
|
||||
|
||||
sequence_semaphore = threading.Semaphore()
|
||||
|
||||
def _process(self, s):
|
||||
return (s or '') % {'year':time.strftime('%Y'), 'month': time.strftime('%m'), 'day':time.strftime('%d')}
|
||||
|
||||
def get_id(self, cr, uid, sequence_id, test='id=%d'):
|
||||
self.sequence_semaphore.acquire()
|
||||
cr.execute('select id,number_next,number_increment,prefix,suffix,padding from ir_sequence where '+test+' and active=True', (sequence_id,))
|
||||
res = cr.dictfetchone()
|
||||
if res:
|
||||
cr.execute('update ir_sequence set number_next=number_next+number_increment where id=%d and active=True', (res['id'],))
|
||||
self.sequence_semaphore.release()
|
||||
if res['number_next']:
|
||||
return self._process(res['prefix']) + '%%0%sd' % res['padding'] % res['number_next'] + self._process(res['suffix'])
|
||||
else:
|
||||
return self._process(res['prefix']) + self._process(res['suffix'])
|
||||
else:
|
||||
self.sequence_semaphore.release()
|
||||
return False
|
||||
|
||||
def get(self, cr, uid, code):
|
||||
return self.get_id(cr, uid, code, test='code=%s')
|
||||
|
||||
def set(self, cr, uid, code, next_number):
|
||||
self.sequence_semaphore.acquire()
|
||||
cr.execute('update ir_sequence set number_next=%d where code=%s and active=True', (next_number, code,))
|
||||
self.sequence_semaphore.release()
|
||||
return True
|
||||
ir_sequence()
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields, osv
|
||||
from osv.osv import Cacheable
|
||||
|
||||
class ir_translation(osv.osv, Cacheable):
|
||||
_name = "ir.translation"
|
||||
_log_access = False
|
||||
_columns = {
|
||||
'name': fields.char('Field Name', size=128, required=True),
|
||||
'res_id': fields.integer('Resource ID'),
|
||||
'lang': fields.char('Language', size=5),
|
||||
'type': fields.char('Type', size=16),
|
||||
'src': fields.text('Source'),
|
||||
'value': fields.text('Translation Value'),
|
||||
}
|
||||
_sql = """
|
||||
create index ir_translation_ltn on ir_translation (lang,type,name);
|
||||
create index ir_translation_res_id on ir_translation (res_id);
|
||||
"""
|
||||
|
||||
def _get_ids(self, cr, uid, name, tt, lang, ids):
|
||||
translations, to_fetch = {}, []
|
||||
for id in ids:
|
||||
trans = self.get((lang, name, id))
|
||||
if trans:
|
||||
translations[id] = trans
|
||||
else:
|
||||
to_fetch.append(id)
|
||||
if to_fetch:
|
||||
cr.execute('select res_id,value from ir_translation where lang=%s and type=%s and name=%s and res_id in ('+','.join(map(str, to_fetch))+')', (lang,tt,name))
|
||||
for res_id, value in cr.fetchall():
|
||||
self.add((lang, tt, name, res_id), value)
|
||||
translations[res_id] = value
|
||||
return translations
|
||||
|
||||
def _set_ids(self, cr, uid, name, tt, lang, ids, value):
|
||||
cr.execute('delete from ir_translation where lang=%s and type=%s and name=%s and res_id in ('+','.join(map(str,ids))+')', (lang,tt,name))
|
||||
for id in ids:
|
||||
self.create(cr, uid, {'lang':lang, 'type':tt, 'name':name, 'res_id':id, 'value':value})
|
||||
return len(ids)
|
||||
|
||||
def _get_source(self, cr, uid, name, tt, lang, source=None):
|
||||
trans = self.get((lang, tt, name, source))
|
||||
if trans:
|
||||
return trans
|
||||
|
||||
if source:
|
||||
source = source.strip().replace('\n',' ')
|
||||
if isinstance(source, unicode):
|
||||
source = source.encode('utf8')
|
||||
cr.execute('select value from ir_translation where lang=%s and type=%s and name=%s and src=%s', (lang, tt, str(name), source))
|
||||
else:
|
||||
cr.execute('select value from ir_translation where lang=%s and type=%s and name=%s', (lang, tt, str(name)))
|
||||
res = cr.fetchone()
|
||||
if res:
|
||||
self.add((lang, tt, name, source), res[0])
|
||||
return res[0]
|
||||
else:
|
||||
self.add((lang, tt, name, source), False)
|
||||
return False
|
||||
ir_translation()
|
|
@ -0,0 +1,123 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# $Id: ir_ui_menu.py 1005 2005-07-25 08:41:42Z nicoe $
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields, osv
|
||||
from osv.orm import browse_null, browse_record
|
||||
|
||||
def one_in(setA, setB):
|
||||
"""Check the presence of an element of setA in setB
|
||||
"""
|
||||
for x in setA:
|
||||
if x in setB:
|
||||
return True
|
||||
return False
|
||||
|
||||
icons = map(lambda x: (x,x), ['STOCK_ABOUT', 'STOCK_ADD', 'STOCK_APPLY', 'STOCK_BOLD',
|
||||
'STOCK_CANCEL', 'STOCK_CDROM', 'STOCK_CLEAR', 'STOCK_CLOSE', 'STOCK_COLOR_PICKER',
|
||||
'STOCK_CONNECT', 'STOCK_CONVERT', 'STOCK_COPY', 'STOCK_CUT', 'STOCK_DELETE',
|
||||
'STOCK_DIALOG_AUTHENTICATION', 'STOCK_DIALOG_ERROR', 'STOCK_DIALOG_INFO',
|
||||
'STOCK_DIALOG_QUESTION', 'STOCK_DIALOG_WARNING', 'STOCK_DIRECTORY', 'STOCK_DISCONNECT',
|
||||
'STOCK_DND', 'STOCK_DND_MULTIPLE', 'STOCK_EDIT', 'STOCK_EXECUTE', 'STOCK_FILE',
|
||||
'STOCK_FIND', 'STOCK_FIND_AND_REPLACE', 'STOCK_FLOPPY', 'STOCK_GOTO_BOTTOM',
|
||||
'STOCK_GOTO_FIRST', 'STOCK_GOTO_LAST', 'STOCK_GOTO_TOP', 'STOCK_GO_BACK',
|
||||
'STOCK_GO_DOWN', 'STOCK_GO_FORWARD', 'STOCK_GO_UP', 'STOCK_HARDDISK',
|
||||
'STOCK_HELP', 'STOCK_HOME', 'STOCK_INDENT', 'STOCK_INDEX', 'STOCK_ITALIC',
|
||||
'STOCK_JUMP_TO', 'STOCK_JUSTIFY_CENTER', 'STOCK_JUSTIFY_FILL',
|
||||
'STOCK_JUSTIFY_LEFT', 'STOCK_JUSTIFY_RIGHT', 'STOCK_MEDIA_FORWARD',
|
||||
'STOCK_MEDIA_NEXT', 'STOCK_MEDIA_PAUSE', 'STOCK_MEDIA_PLAY',
|
||||
'STOCK_MEDIA_PREVIOUS', 'STOCK_MEDIA_RECORD', 'STOCK_MEDIA_REWIND',
|
||||
'STOCK_MEDIA_STOP', 'STOCK_MISSING_IMAGE', 'STOCK_NETWORK', 'STOCK_NEW',
|
||||
'STOCK_NO', 'STOCK_OK', 'STOCK_OPEN', 'STOCK_PASTE', 'STOCK_PREFERENCES',
|
||||
'STOCK_PRINT', 'STOCK_PRINT_PREVIEW', 'STOCK_PROPERTIES', 'STOCK_QUIT',
|
||||
'STOCK_REDO', 'STOCK_REFRESH', 'STOCK_REMOVE', 'STOCK_REVERT_TO_SAVED',
|
||||
'STOCK_SAVE', 'STOCK_SAVE_AS', 'STOCK_SELECT_COLOR', 'STOCK_SELECT_FONT',
|
||||
'STOCK_SORT_ASCENDING', 'STOCK_SORT_DESCENDING', 'STOCK_SPELL_CHECK',
|
||||
'STOCK_STOP', 'STOCK_STRIKETHROUGH', 'STOCK_UNDELETE', 'STOCK_UNDERLINE',
|
||||
'STOCK_UNDO', 'STOCK_UNINDENT', 'STOCK_YES', 'STOCK_ZOOM_100',
|
||||
'STOCK_ZOOM_FIT', 'STOCK_ZOOM_IN', 'STOCK_ZOOM_OUT',
|
||||
'terp-account', 'terp-crm', 'terp-mrp', 'terp-product', 'terp-purchase', 'terp-sale', 'terp-tools',
|
||||
'terp-administration', 'terp-hr', 'terp-partner', 'terp-project', 'terp-report', 'terp-stock'
|
||||
])
|
||||
|
||||
|
||||
class ir_ui_menu(osv.osv):
|
||||
_name = 'ir.ui.menu'
|
||||
def search(self, cr, uid, args, offset=0, limit=2000, order=None):
|
||||
ids = osv.orm.orm.search(self, cr, uid, args, offset, limit, order)
|
||||
user_groups = self.pool.get('res.users').read(cr, uid, [uid])[0]['groups_id']
|
||||
result = []
|
||||
for menu in self.browse(cr, uid, ids):
|
||||
if not len(menu.groups_id):
|
||||
result.append(menu.id)
|
||||
continue
|
||||
for g in menu.groups_id:
|
||||
if g.id in user_groups:
|
||||
result.append(menu.id)
|
||||
break
|
||||
return result
|
||||
|
||||
def _get_full_name(self, cr, uid, ids, name, args, context):
|
||||
res = {}
|
||||
for m in self.browse(cr, uid, ids):
|
||||
res[m.id] = self._get_one_full_name(m)
|
||||
return res
|
||||
|
||||
def _get_one_full_name(self, menu, level=6):
|
||||
if level<=0:
|
||||
return '...'
|
||||
if menu.parent_id:
|
||||
parent_path = self._get_one_full_name(menu.parent_id, level-1) + "/"
|
||||
else:
|
||||
parent_path = ''
|
||||
return parent_path + menu.name
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context={}):
|
||||
res = super(ir_ui_menu, self).copy(cr, uid, id, context=context)
|
||||
ids = self.pool.get('ir.values').search(cr, uid, [('model','=','ir.ui.menu'),('res_id','=',id)])
|
||||
for iv in self.pool.get('ir.values').browse(cr, uid, ids):
|
||||
new_id = self.pool.get('ir.values').copy(cr, uid, iv.id, default={'res_id':res}, context=context)
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Menu', size=64, required=True, translate=True),
|
||||
'sequence': fields.integer('Sequence'),
|
||||
'child_id' : fields.one2many('ir.ui.menu', 'parent_id','Child ids'),
|
||||
'parent_id': fields.many2one('ir.ui.menu', 'Parent Menu', select=True),
|
||||
'groups_id': fields.many2many('res.groups', 'ir_ui_menu_group_rel', 'menu_id', 'gid', 'Groups'),
|
||||
'complete_name': fields.function(_get_full_name, method=True, string='Complete Name', type='char', size=128),
|
||||
'icon': fields.selection(lambda *a: icons, 'Icon', size=64)
|
||||
}
|
||||
_defaults = {
|
||||
'icon' : lambda *a: 'STOCK_OPEN',
|
||||
'sequence' : lambda *a: 10
|
||||
}
|
||||
_order = "sequence,id"
|
||||
ir_ui_menu()
|
||||
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields,osv
|
||||
from xml import dom
|
||||
|
||||
def _check_xml(self, cr, uid, ids):
|
||||
try:
|
||||
cr.execute('select arch from ir_ui_view where id in ('+','.join(map(str,ids))+')')
|
||||
for row in cr.fetchall():
|
||||
doc = dom.minidom.parseString(row[0])
|
||||
return True
|
||||
except Exception, e:
|
||||
return False
|
||||
|
||||
class view(osv.osv):
|
||||
_name = 'ir.ui.view'
|
||||
_columns = {
|
||||
'name': fields.char('View Name',size=64, required=True),
|
||||
'model': fields.char('Model', size=64, required=True),
|
||||
'priority': fields.integer('Priority', required=True),
|
||||
'type': fields.selection((('tree','Tree'),('form','Form')), 'View Type', required=True),
|
||||
'arch': fields.text('View Architecture', required=True),
|
||||
'inherit_id': fields.many2one('ir.ui.view', 'Inherited View'),
|
||||
'field_parent': fields.char('Childs Field',size=64)
|
||||
}
|
||||
_defaults = {
|
||||
'arch': lambda *a: '<?xml version="1.0"?>\n<tree title="Unknwown">\n\t<field name="name"/>\n</tree>',
|
||||
'priority': lambda *a: 16
|
||||
}
|
||||
_order = "priority"
|
||||
_constraints = [
|
||||
(_check_xml, 'Invalid XML for View Architecture!', ['arch'])
|
||||
]
|
||||
|
||||
view()
|
||||
|
||||
class view_sc(osv.osv):
|
||||
_name = 'ir.ui.view_sc'
|
||||
_columns = {
|
||||
'name': fields.char('Shortcut Name', size=64, required=True),
|
||||
'res_id': fields.integer('Resource Ref.', required=True),
|
||||
'sequence': fields.integer('Sequence'),
|
||||
'user_id': fields.many2one('res.users', 'User Ref.', required=True, ondelete='cascade'),
|
||||
'resource': fields.char('Resource Name', size=64, required=True)
|
||||
}
|
||||
_order = 'sequence'
|
||||
_defaults = {
|
||||
'resource': lambda *a: 'ir.ui.menu',
|
||||
}
|
||||
view_sc()
|
|
@ -0,0 +1,153 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv,fields
|
||||
import pickle
|
||||
|
||||
class ir_values(osv.osv):
|
||||
_name = 'ir.values'
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=128),
|
||||
'model': fields.char('Name', size=128),
|
||||
'value': fields.text('Value'),
|
||||
'object': fields.boolean('Is Object'),
|
||||
'key': fields.char('Name', size=128),
|
||||
'key2': fields.char('Value', size=256),
|
||||
'meta': fields.text('Meta Datas'),
|
||||
'res_id': fields.integer('Resource ID'),
|
||||
'user_id': fields.many2one('res.users', 'User', ondelete='cascade')
|
||||
}
|
||||
_defaults = {
|
||||
'key': lambda *a: 'action',
|
||||
'key2': lambda *a: 'tree_but_open',
|
||||
}
|
||||
def set(self, cr, uid, key, key2, name, models, value, replace=True, isobject=False, meta=False, preserve_user=False):
|
||||
if not isobject:
|
||||
value = pickle.dumps(value)
|
||||
if meta:
|
||||
meta = pickle.dumps(meta)
|
||||
ids_res = []
|
||||
for model in models:
|
||||
if type(model)==type([]) or type(model)==type(()):
|
||||
model,res_id = model
|
||||
else:
|
||||
res_id=False
|
||||
if replace:
|
||||
ids = self.search(cr, uid, [('key','=',key),('key2','=',key2),('name','=',name),('model','=',model),('res_id','=',res_id)])
|
||||
self.unlink(cr, uid, ids)
|
||||
vals = {
|
||||
'name': name,
|
||||
'value': value,
|
||||
'model': model,
|
||||
'object': isobject,
|
||||
'key': key,
|
||||
'key2': key2 and key2[:200],
|
||||
'meta': meta,
|
||||
'user_id': preserve_user and uid,
|
||||
}
|
||||
if res_id:
|
||||
vals['res_id']= res_id
|
||||
ids_res.append(self.create(cr, uid, vals))
|
||||
return ids_res
|
||||
|
||||
#
|
||||
# Improve to add user_id check
|
||||
#
|
||||
def get(self, cr, uid, key, key2, models, meta=False, context={}, res_id_req=False, without_user=True, key2_req=True):
|
||||
result = []
|
||||
for m in models:
|
||||
if type(m)==type([]) or type(m)==type(()):
|
||||
m,res_id = m
|
||||
else:
|
||||
res_id=False
|
||||
|
||||
where1 = ['key=%s','model=%s']
|
||||
where2 = [key,m]
|
||||
where_opt = []
|
||||
if key2:
|
||||
where1.append('key2=%s')
|
||||
where2.append(key2[:200])
|
||||
else:
|
||||
dest = where1
|
||||
if not key2_req or meta:
|
||||
dest=where_opt
|
||||
dest.append('key2 is null')
|
||||
|
||||
if res_id_req and (models[-1][0]==m):
|
||||
if res_id:
|
||||
where1.append('res_id=%d' % (res_id,))
|
||||
else:
|
||||
where1.append('(res_id is NULL)')
|
||||
else:
|
||||
if res_id:
|
||||
if (models[-1][0]==m):
|
||||
where1.append('(res_id=%d or (res_id is null))' % (res_id,))
|
||||
where_opt.append('res_id=%d' % (res_id,))
|
||||
else:
|
||||
where1.append('res_id=%d' % (res_id,))
|
||||
|
||||
if not without_user:
|
||||
where_opt.append('user_id=%d' % (uid,))
|
||||
|
||||
result = []
|
||||
ok = True
|
||||
while ok and len(result)==0:
|
||||
cr.execute('select id from ir_values where '+' and '.join(where1+where_opt), where2)
|
||||
result = [x[0] for x in cr.fetchall()]
|
||||
if len(where_opt):
|
||||
where_opt.pop()
|
||||
else:
|
||||
ok = False
|
||||
|
||||
if result:
|
||||
break
|
||||
|
||||
if not result:
|
||||
return []
|
||||
cr.execute('select id,name,value,object,meta from ir_values where id in ('+','.join(map(str,result))+')')
|
||||
result = cr.fetchall()
|
||||
|
||||
def _result_get(x):
|
||||
if x[3]:
|
||||
model,id = x[2].split(',')
|
||||
datas = self.pool.get(model).read(cr, uid, [int(id)], False, context)
|
||||
if not len(datas):
|
||||
#ir_del(cr, uid, x[0])
|
||||
return False
|
||||
datas = datas[0]
|
||||
else:
|
||||
datas = pickle.loads(x[2])
|
||||
if meta:
|
||||
meta2 = pickle.loads(x[4])
|
||||
return (x[0],x[1],datas,meta2)
|
||||
return (x[0],x[1],datas)
|
||||
res = filter(bool, map(lambda x: _result_get(x), list(result)))
|
||||
return res
|
||||
ir_values()
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
import workflow
|
||||
import print_instance
|
|
@ -0,0 +1,88 @@
|
|||
import psycopg
|
||||
import pydot
|
||||
|
||||
wkf_id = 231
|
||||
|
||||
db = psycopg.connect('dbname=terp', serialize=0)
|
||||
cr=db.cursor()
|
||||
|
||||
def graph_get(cr, graph, wkf_id, nested=True, workitem={}):
|
||||
cr.execute('select * from wkf_activity where wkf_id=%d', (wkf_id,))
|
||||
nodes = cr.dictfetchall()
|
||||
activities = {}
|
||||
actfrom = {}
|
||||
actto = {}
|
||||
for n in nodes:
|
||||
activities[n['id']] = n
|
||||
if n['subflow_id'] and nested:
|
||||
cr.execute('select * from wkf where id=%d', (n['subflow_id'],))
|
||||
wkfinfo = cr.dictfetchone()
|
||||
graph2 = pydot.Cluster('subflow'+str(n['subflow_id']), fontsize=10, label = "Subflow: "+n['name']+'\\nOSV: '+wkfinfo['osv'])
|
||||
(s1,s2) = graph_get(cr, graph2, n['subflow_id'], nested,workitem)
|
||||
graph.add_subgraph(graph2)
|
||||
actfrom[n['id']] = s2
|
||||
actto[n['id']] = s1
|
||||
else:
|
||||
args = {}
|
||||
if n['flow_start'] or n['flow_stop']:
|
||||
args['style']='filled'
|
||||
args['color']='lightgrey'
|
||||
args['label']=n['name']
|
||||
if n['action']:
|
||||
args['label']+='\\n'+n['action']
|
||||
if n['subflow_id']:
|
||||
args['shape'] = 'box'
|
||||
if n['id'] in workitem:
|
||||
args['label']+='\\nx '+str(workitem[n['id']])
|
||||
args['color'] = "red"
|
||||
graph.add_node(pydot.Node(n['id'], **args))
|
||||
actfrom[n['id']] = n['id']
|
||||
actto[n['id']] = n['id']
|
||||
cr.execute('select * from wkf_transition where act_from in ('+','.join(map(lambda x: str(x['id']),nodes))+')')
|
||||
transitions = cr.dictfetchall()
|
||||
for t in transitions:
|
||||
args = {}
|
||||
args['label'] = str(t['condition'])
|
||||
if t['signal']:
|
||||
args['label'] += '\\n'+str(t['signal'])
|
||||
args['style'] = 'bold'
|
||||
|
||||
if activities[t['act_from']]['split_mode']=='AND':
|
||||
args['arrowtail']='box'
|
||||
elif str(activities[t['act_from']]['split_mode'])=='OR ':
|
||||
args['arrowtail']='inv'
|
||||
|
||||
if activities[t['act_to']]['join_mode']=='AND':
|
||||
args['arrowhead']='crow'
|
||||
|
||||
graph.add_edge(pydot.Edge(actfrom[t['act_from']],actto[t['act_to']], fontsize=8, **args))
|
||||
nodes = cr.dictfetchall()
|
||||
cr.execute('select id from wkf_activity where flow_start=True limit 1')
|
||||
start = cr.fetchone()[0]
|
||||
cr.execute('select id from wkf_activity where flow_stop=True limit 1')
|
||||
stop = cr.fetchone()[0]
|
||||
return (start,stop)
|
||||
|
||||
def graph_instance_get(cr, graph, inst_id, nested=False):
|
||||
workitems = {}
|
||||
cr.execute('select * from wkf_instance where id=%d', (inst_id,))
|
||||
inst = cr.dictfetchone()
|
||||
|
||||
def workitem_get(instance):
|
||||
cr.execute('select act_id,count(*) from wkf_workitem where inst_id=%d group by act_id', (instance,))
|
||||
workitems = dict(cr.fetchall())
|
||||
|
||||
cr.execute('select subflow_id from wkf_workitem where inst_id=%d', (instance,))
|
||||
for (subflow_id,) in cr.fetchall():
|
||||
workitems.update(workitem_get(subflow_id))
|
||||
return workitems
|
||||
|
||||
graph_get(cr, graph, inst['wkf_id'], nested, workitem_get(inst_id))
|
||||
|
||||
|
||||
cr.execute('select * from wkf where id=%d', (wkf_id,))
|
||||
wkfinfo = cr.dictfetchone()
|
||||
graph = pydot.Dot(fontsize = 16, label = "\\n\\nWorkflow: %s\\n OSV: %s"% (wkfinfo['name'],wkfinfo['osv']))
|
||||
graph_instance_get(cr, graph, 1155, True)
|
||||
graph.write_ps('/tmp/a.ps', prog='dot')
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import time, os
|
||||
|
||||
import netsvc
|
||||
import report,pooler,tools
|
||||
|
||||
|
||||
def graph_get(cr, graph, wkf_id, nested=False, workitem={}):
|
||||
import pydot
|
||||
cr.execute('select * from wkf_activity where wkf_id=%d', (wkf_id,))
|
||||
nodes = cr.dictfetchall()
|
||||
activities = {}
|
||||
actfrom = {}
|
||||
actto = {}
|
||||
for n in nodes:
|
||||
activities[n['id']] = n
|
||||
if n['subflow_id'] and nested:
|
||||
cr.execute('select * from wkf where id=%d', (n['subflow_id'],))
|
||||
wkfinfo = cr.dictfetchone()
|
||||
graph2 = pydot.Cluster('subflow'+str(n['subflow_id']), fontsize=10, label = "Subflow: "+n['name']+'\\nOSV: '+wkfinfo['osv'])
|
||||
(s1,s2) = graph_get(cr, graph2, n['subflow_id'], nested,workitem)
|
||||
graph.add_subgraph(graph2)
|
||||
actfrom[n['id']] = s2
|
||||
actto[n['id']] = s1
|
||||
else:
|
||||
args = {}
|
||||
if n['flow_start'] or n['flow_stop']:
|
||||
args['style']='filled'
|
||||
args['color']='lightgrey'
|
||||
args['label']=n['name']
|
||||
if n['subflow_id']:
|
||||
args['shape'] = 'box'
|
||||
if n['id'] in workitem:
|
||||
args['label']+='\\nx '+str(workitem[n['id']])
|
||||
args['color'] = "red"
|
||||
graph.add_node(pydot.Node(n['id'], **args))
|
||||
actfrom[n['id']] = (n['id'],{})
|
||||
actto[n['id']] = (n['id'],{})
|
||||
cr.execute('select * from wkf_transition where act_from in ('+','.join(map(lambda x: str(x['id']),nodes))+')')
|
||||
transitions = cr.dictfetchall()
|
||||
for t in transitions:
|
||||
args = {}
|
||||
args['label'] = str(t['condition'])
|
||||
if t['signal']:
|
||||
args['label'] += '\\n'+str(t['signal'])
|
||||
args['style'] = 'bold'
|
||||
|
||||
if activities[t['act_from']]['split_mode']=='AND':
|
||||
args['arrowtail']='box'
|
||||
elif str(activities[t['act_from']]['split_mode'])=='OR ':
|
||||
args['arrowtail']='inv'
|
||||
|
||||
if activities[t['act_to']]['join_mode']=='AND':
|
||||
args['arrowhead']='crow'
|
||||
|
||||
activity_from = actfrom[t['act_from']][1].get(t['signal'], actfrom[t['act_from']][0])
|
||||
activity_to = actto[t['act_to']][1].get(t['signal'], actto[t['act_to']][0])
|
||||
graph.add_edge(pydot.Edge( activity_from ,activity_to, fontsize=8, **args))
|
||||
nodes = cr.dictfetchall()
|
||||
cr.execute('select id from wkf_activity where flow_start=True and wkf_id=%d limit 1', (wkf_id,))
|
||||
start = cr.fetchone()[0]
|
||||
cr.execute("select 'subflow.'||name,id from wkf_activity where flow_stop=True and wkf_id=%d", (wkf_id,))
|
||||
stop = cr.fetchall()
|
||||
stop = (stop[0][1], dict(stop))
|
||||
return ((start,{}),stop)
|
||||
|
||||
|
||||
def graph_instance_get(cr, graph, inst_id, nested=False):
|
||||
workitems = {}
|
||||
cr.execute('select * from wkf_instance where id=%d', (inst_id,))
|
||||
inst = cr.dictfetchone()
|
||||
|
||||
def workitem_get(instance):
|
||||
cr.execute('select act_id,count(*) from wkf_workitem where inst_id=%d group by act_id', (instance,))
|
||||
workitems = dict(cr.fetchall())
|
||||
|
||||
cr.execute('select subflow_id from wkf_workitem where inst_id=%d', (instance,))
|
||||
for (subflow_id,) in cr.fetchall():
|
||||
workitems.update(workitem_get(subflow_id))
|
||||
return workitems
|
||||
graph_get(cr, graph, inst['wkf_id'], nested, workitem_get(inst_id))
|
||||
|
||||
#
|
||||
# TODO: pas clean: concurrent !!!
|
||||
#
|
||||
|
||||
class report_graph_instance(object):
|
||||
def __init__(self, cr, uid, ids, data):
|
||||
try:
|
||||
import pydot
|
||||
except Exception,e:
|
||||
print 'Import Error for pydot, you will not be able to render workflows'
|
||||
print 'Consider Installing PyDot or dependencies: http://dkbza.org/pydot.html'
|
||||
raise e
|
||||
self.done = False
|
||||
|
||||
try:
|
||||
cr.execute('select * from wkf where osv=%s limit 1', (data['model'],))
|
||||
wkfinfo = cr.dictfetchone()
|
||||
cr.execute('select id from wkf_instance where res_id=%d and wkf_id=%d order by state limit 1', (data['id'],wkfinfo['id']))
|
||||
inst_id = cr.fetchone()[0]
|
||||
|
||||
graph = pydot.Dot(fontsize=16, label="\\n\\nWorkflow: %s\\n OSV: %s" % (wkfinfo['name'],wkfinfo['osv']))
|
||||
graph_instance_get(cr, graph, inst_id, data.get('nested', False))
|
||||
ps_string = graph.create_ps(prog='dot')
|
||||
except:
|
||||
# string is in PS, like the success message would have been
|
||||
ps_string = '''%PS-Adobe-3.0
|
||||
/inch {72 mul} def
|
||||
/Times-Roman findfont 50 scalefont setfont
|
||||
1.5 inch 15 inch moveto
|
||||
(No workflow available) show
|
||||
showpage'''
|
||||
input, output = os.popen2('ps2pdf -sPAPERSIZE=a3 - -')
|
||||
input.write(ps_string)
|
||||
input.close()
|
||||
self.result = output.read()
|
||||
output.close()
|
||||
self.done = True
|
||||
|
||||
def is_done(self):
|
||||
return self.done
|
||||
|
||||
def get(self):
|
||||
if self.done:
|
||||
return self.result
|
||||
else:
|
||||
return None
|
||||
|
||||
class report_graph(report.interface.report_int):
|
||||
def __init__(self, name, table):
|
||||
report.interface.report_int.__init__(self, name)
|
||||
self.table = table
|
||||
|
||||
def result(self):
|
||||
if self.obj.is_done():
|
||||
return (True, self.obj.get(), 'pdf')
|
||||
else:
|
||||
return (False, False, False)
|
||||
|
||||
def create(self, cr, uid, ids, data, context={}):
|
||||
self.obj = report_graph_instance(cr, uid, ids, data)
|
||||
return (self.obj.get(), 'pdf')
|
||||
|
||||
report_graph('report.workflow.instance.graph', 'ir.workflow')
|
|
@ -0,0 +1,16 @@
|
|||
Copyright (c) 2004 Ero Carrera
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||
associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,33 @@
|
|||
Metadata-Version: 1.0
|
||||
Name: pydot
|
||||
Version: 0.9.9
|
||||
Summary: Python interface to Graphiz's Dot
|
||||
Home-page: http://dkbza.org/pydot.html
|
||||
Author: Ero Carrera
|
||||
Author-email: ero@dkbza.org
|
||||
License: MIT
|
||||
Description: Graphviz's dot language Python interface.
|
||||
|
||||
This module provides with a full interface to create handle modify
|
||||
and process graphs in Graphviz's dot language.
|
||||
|
||||
References:
|
||||
|
||||
pydot Homepage: http://www.dkbza.org/pydot.html
|
||||
Graphviz: http://www.research.att.com/sw/tools/graphviz/
|
||||
DOT Language: http://www.research.att.com/~erg/graphviz/info/lang.html
|
||||
|
||||
Programmed and tested with Graphviz 1.12 and Python 2.3.3 on GNU/Linux
|
||||
by Ero Carrera (c) 2004 [ero@dkbza.org]
|
||||
|
||||
Distributed under MIT license [http://opensource.org/licenses/mit-license.html].
|
||||
|
||||
Platform: any
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: Science/Research
|
||||
Classifier: License :: OSI Approved :: MIT License
|
||||
Classifier: Natural Language :: English
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Topic :: Scientific/Engineering :: Visualization
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
@ -0,0 +1,29 @@
|
|||
pydot - Python interface to Graphviz's Dot language
|
||||
Ero Carrera (c) 2004
|
||||
ero@dkbza.org
|
||||
|
||||
This code is distributed under the MIT license.
|
||||
|
||||
Requirements:
|
||||
-------------
|
||||
|
||||
pyparsing: pydot requires the pyparsing module in order to be
|
||||
able to load DOT files.
|
||||
|
||||
GraphViz: is needed in order to render the graphs into any of
|
||||
the plethora of output formats supported.
|
||||
|
||||
Installation:
|
||||
-------------
|
||||
|
||||
Should suffice with doing:
|
||||
|
||||
python setup.py install
|
||||
|
||||
Needless to say, no installation is needed just to use the module. A mere:
|
||||
|
||||
import pydot
|
||||
|
||||
should do it, provided that the directory containing the modules is on Python
|
||||
module search path.
|
||||
|
|
@ -0,0 +1 @@
|
|||
from pydot import *
|
|
@ -0,0 +1,352 @@
|
|||
#!/bin/env python
|
||||
|
||||
"""
|
||||
The dotparser parses graphviz files in dot and dot files and transforms them
|
||||
into a class representation defined by pydot.
|
||||
|
||||
The module needs pyparsing (tested with version 1.2) and pydot (tested with 0.9.9)
|
||||
|
||||
Author: Michael Krause <michael@krause-software.de>
|
||||
"""
|
||||
|
||||
import sys
|
||||
import glob
|
||||
import pydot
|
||||
|
||||
from pyparsing import __version__ as pyparsing_version
|
||||
from pyparsing import Literal, CaselessLiteral, Word, \
|
||||
Upcase, OneOrMore, ZeroOrMore, Forward, NotAny, \
|
||||
delimitedList, oneOf, Group, Optional, Combine, \
|
||||
alphas, nums, restOfLine, cStyleComment, nums, \
|
||||
alphanums, printables, empty, quotedString, \
|
||||
ParseException, ParseResults, CharsNotIn, _noncomma
|
||||
|
||||
|
||||
class P_AttrList:
|
||||
def __init__(self, toks):
|
||||
self.attrs = {}
|
||||
i = 0
|
||||
while i < len(toks):
|
||||
attrname = toks[i]
|
||||
attrvalue = toks[i+1]
|
||||
self.attrs[attrname] = attrvalue
|
||||
i += 2
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(%r)" % (self.__class__.__name__, self.attrs)
|
||||
|
||||
|
||||
class DefaultStatement(P_AttrList):
|
||||
def __init__(self, default_type, attrs):
|
||||
self.default_type = default_type
|
||||
self.attrs = attrs
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(%s, %r)" % \
|
||||
(self.__class__.__name__, self.default_type, self.attrs)
|
||||
|
||||
|
||||
def push_top_graph_stmt(str, loc, toks):
|
||||
attrs = {}
|
||||
g = None
|
||||
|
||||
for element in toks:
|
||||
if isinstance(element, ParseResults) or \
|
||||
isinstance(element, tuple) or \
|
||||
isinstance(element, list):
|
||||
|
||||
element = element[0]
|
||||
|
||||
if element == 'strict':
|
||||
attrs['strict'] = True
|
||||
elif element in ['graph', 'digraph']:
|
||||
attrs['graph_type'] = element
|
||||
elif type(element) == type(''):
|
||||
attrs['graph_name'] = element
|
||||
elif isinstance(element, pydot.Graph):
|
||||
g = pydot.Graph(**attrs)
|
||||
g.__dict__.update(element.__dict__)
|
||||
for e in g.get_edge_list():
|
||||
e.parent_graph = g
|
||||
for e in g.get_node_list():
|
||||
e.parent_graph = g
|
||||
for e in g.get_subgraph_list():
|
||||
e.set_graph_parent(g)
|
||||
|
||||
elif isinstance(element, P_AttrList):
|
||||
attrs.update(element.attrs)
|
||||
else:
|
||||
raise ValueError, "Unknown element statement: %r " % element
|
||||
|
||||
if g is not None:
|
||||
g.__dict__.update(attrs)
|
||||
return g
|
||||
|
||||
|
||||
def add_defaults(element, defaults):
|
||||
d = element.__dict__
|
||||
for key, value in defaults.items():
|
||||
if not d.get(key):
|
||||
d[key] = value
|
||||
|
||||
|
||||
def add_elements(g, toks, defaults_graph=None, defaults_node=None, defaults_edge=None):
|
||||
|
||||
if defaults_graph is None:
|
||||
defaults_graph = {}
|
||||
if defaults_node is None:
|
||||
defaults_node = {}
|
||||
if defaults_edge is None:
|
||||
defaults_edge = {}
|
||||
|
||||
for element in toks:
|
||||
if isinstance(element, pydot.Graph):
|
||||
add_defaults(element, defaults_graph)
|
||||
g.add_subgraph(element)
|
||||
elif isinstance(element, pydot.Node):
|
||||
add_defaults(element, defaults_node)
|
||||
g.add_node(element)
|
||||
elif isinstance(element, pydot.Edge):
|
||||
add_defaults(element, defaults_edge)
|
||||
g.add_edge(element)
|
||||
elif isinstance(element, ParseResults):
|
||||
for e in element:
|
||||
add_elements(g, [e], defaults_graph, defaults_node, defaults_edge)
|
||||
elif isinstance(element, DefaultStatement):
|
||||
if element.default_type == 'graph':
|
||||
default_graph_attrs = pydot.Node('graph')
|
||||
default_graph_attrs.__dict__.update(element.attrs)
|
||||
g.add_node(default_graph_attrs)
|
||||
# defaults_graph.update(element.attrs)
|
||||
# g.__dict__.update(element.attrs)
|
||||
elif element.default_type == 'node':
|
||||
default_node_attrs = pydot.Node('node')
|
||||
default_node_attrs.__dict__.update(element.attrs)
|
||||
g.add_node(default_node_attrs)
|
||||
#defaults_node.update(element.attrs)
|
||||
elif element.default_type == 'edge':
|
||||
default_edge_attrs = pydot.Node('edge')
|
||||
default_edge_attrs.__dict__.update(element.attrs)
|
||||
g.add_node(default_edge_attrs)
|
||||
#defaults_edge.update(element.attrs)
|
||||
else:
|
||||
raise ValueError, "Unknown DefaultStatement: %s " % element.default_type
|
||||
elif isinstance(element, P_AttrList):
|
||||
g.__dict__.update(element.attrs)
|
||||
else:
|
||||
raise ValueError, "Unknown element statement: %r " % element
|
||||
|
||||
|
||||
def push_graph_stmt(str, loc, toks):
|
||||
g = pydot.Subgraph()
|
||||
add_elements(g, toks)
|
||||
return g
|
||||
|
||||
|
||||
def push_subgraph_stmt(str, loc, toks):
|
||||
for e in toks:
|
||||
if len(e)==3:
|
||||
g = e[2]
|
||||
g.set_name(e[1])
|
||||
|
||||
return g
|
||||
|
||||
|
||||
def push_default_stmt(str, loc, toks):
|
||||
# The pydot class instances should be marked as
|
||||
# default statements to be inherited by actual
|
||||
# graphs, nodes and edges.
|
||||
# print "push_default_stmt", toks
|
||||
default_type = toks[0][0]
|
||||
if len(toks) > 1:
|
||||
attrs = toks[1].attrs
|
||||
else:
|
||||
attrs = {}
|
||||
|
||||
if default_type in ['graph', 'node', 'edge']:
|
||||
return DefaultStatement(default_type, attrs)
|
||||
else:
|
||||
raise ValueError, "Unknown default statement: %r " % toks
|
||||
|
||||
|
||||
def push_attr_list(str, loc, toks):
|
||||
p = P_AttrList(toks)
|
||||
return p
|
||||
|
||||
|
||||
def get_port(node):
|
||||
|
||||
if len(node)>1:
|
||||
if isinstance(node[1], ParseResults):
|
||||
if len(node[1][0])==2:
|
||||
if node[1][0][0]==':':
|
||||
return node[1][0][1]
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def push_edge_stmt(str, loc, toks):
|
||||
|
||||
tok_attrs = [a for a in toks if isinstance(a, P_AttrList)]
|
||||
attrs = {}
|
||||
for a in tok_attrs:
|
||||
attrs.update(a.attrs)
|
||||
|
||||
n_prev = toks[0]
|
||||
e = []
|
||||
for n_next in tuple(toks)[2::2]:
|
||||
port = get_port(n_prev)
|
||||
if port is not None:
|
||||
n_prev_port = ':'+port
|
||||
else:
|
||||
n_prev_port = ''
|
||||
|
||||
port = get_port(n_next)
|
||||
if port is not None:
|
||||
n_next_port = ':'+port
|
||||
else:
|
||||
n_next_port = ''
|
||||
|
||||
e.append(pydot.Edge(n_prev[0]+n_prev_port, n_next[0]+n_next_port, **attrs))
|
||||
n_prev = n_next
|
||||
return e
|
||||
|
||||
|
||||
def push_node_stmt(str, loc, toks):
|
||||
|
||||
if len(toks) == 2:
|
||||
attrs = toks[1].attrs
|
||||
else:
|
||||
attrs = {}
|
||||
|
||||
node_name = toks[0]
|
||||
if isinstance(node_name, list) or isinstance(node_name, tuple):
|
||||
if len(node_name)>0:
|
||||
node_name = node_name[0]
|
||||
|
||||
n = pydot.Node(node_name, **attrs)
|
||||
return n
|
||||
|
||||
|
||||
def strip_quotes( s, l, t ):
|
||||
return [ t[0].strip('"') ]
|
||||
|
||||
|
||||
graphparser = None
|
||||
def GRAPH_DEF():
|
||||
global graphparser
|
||||
|
||||
if not graphparser:
|
||||
# punctuation
|
||||
colon = Literal(":")
|
||||
lbrace = Literal("{")
|
||||
rbrace = Literal("}")
|
||||
lbrack = Literal("[")
|
||||
rbrack = Literal("]")
|
||||
lparen = Literal("(")
|
||||
rparen = Literal(")")
|
||||
equals = Literal("=")
|
||||
comma = Literal(",")
|
||||
dot = Literal(".")
|
||||
slash = Literal("/")
|
||||
bslash = Literal("\\")
|
||||
star = Literal("*")
|
||||
semi = Literal(";")
|
||||
at = Literal("@")
|
||||
minus = Literal("-")
|
||||
|
||||
# keywords
|
||||
strict_ = Literal("strict")
|
||||
graph_ = Literal("graph")
|
||||
digraph_ = Literal("digraph")
|
||||
subgraph_ = Literal("subgraph")
|
||||
node_ = Literal("node")
|
||||
edge_ = Literal("edge")
|
||||
|
||||
identifier = Word(alphanums + "_" ).setName("identifier")
|
||||
|
||||
double_quote = Literal('"')
|
||||
double_quoted_string = \
|
||||
Combine( double_quote + ZeroOrMore(CharsNotIn('"')) + double_quote )
|
||||
|
||||
alphastring_ = OneOrMore(CharsNotIn(_noncomma))
|
||||
|
||||
ID = (identifier | double_quoted_string.setParseAction(strip_quotes) |\
|
||||
alphastring_).setName("ID")
|
||||
|
||||
html_text = Combine(Literal("<<") + OneOrMore(CharsNotIn(",]")))
|
||||
|
||||
float_number = Combine(Optional(minus) + \
|
||||
OneOrMore(Word(nums + "."))).setName("float_number")
|
||||
|
||||
righthand_id = (float_number | ID | html_text).setName("righthand_id")
|
||||
|
||||
port_angle = (at + ID).setName("port_angle")
|
||||
|
||||
port_location = (Group(colon + ID) | \
|
||||
Group(colon + lparen + ID + comma + ID + rparen)).setName("port_location")
|
||||
|
||||
port = (Group(port_location + Optional(port_angle)) | \
|
||||
Group(port_angle + Optional(port_location))).setName("port")
|
||||
|
||||
node_id = (ID + Optional(port))
|
||||
a_list = OneOrMore(ID + Optional(equals.suppress() + righthand_id) + \
|
||||
Optional(comma.suppress())).setName("a_list")
|
||||
|
||||
attr_list = OneOrMore(lbrack.suppress() + Optional(a_list) + \
|
||||
rbrack.suppress()).setName("attr_list")
|
||||
|
||||
attr_stmt = (Group(graph_ | node_ | edge_) + attr_list).setName("attr_stmt")
|
||||
|
||||
edgeop = (Literal("--") | Literal("->")).setName("edgeop")
|
||||
|
||||
stmt_list = Forward()
|
||||
graph_stmt = Group(lbrace.suppress() + Optional(stmt_list) + \
|
||||
rbrace.suppress()).setName("graph_stmt")
|
||||
|
||||
subgraph = (Group(Optional(subgraph_ + Optional(ID)) + graph_stmt) | \
|
||||
Group(subgraph_ + ID)).setName("subgraph")
|
||||
|
||||
edgeRHS = OneOrMore(edgeop + Group(node_id | subgraph))
|
||||
|
||||
edge_stmt = Group(node_id | subgraph) + edgeRHS + Optional(attr_list)
|
||||
|
||||
node_stmt = (node_id + Optional(attr_list) + semi.suppress()).setName("node_stmt")
|
||||
|
||||
assignment = (ID + equals.suppress() + righthand_id).setName("assignment")
|
||||
stmt = (assignment | edge_stmt | attr_stmt | node_stmt | subgraph).setName("stmt")
|
||||
stmt_list << OneOrMore(stmt + Optional(semi.suppress()))
|
||||
|
||||
graphparser = (Optional(strict_) + Group((graph_ | digraph_)) + \
|
||||
Optional(ID) + graph_stmt).setResultsName("graph")
|
||||
|
||||
singleLineComment = "//" + restOfLine
|
||||
graphparser.ignore(singleLineComment)
|
||||
graphparser.ignore(cStyleComment)
|
||||
|
||||
assignment.setParseAction(push_attr_list)
|
||||
a_list.setParseAction(push_attr_list)
|
||||
edge_stmt.setParseAction(push_edge_stmt)
|
||||
node_stmt.setParseAction(push_node_stmt)
|
||||
attr_stmt.setParseAction(push_default_stmt)
|
||||
|
||||
subgraph.setParseAction(push_subgraph_stmt)
|
||||
graph_stmt.setParseAction(push_graph_stmt)
|
||||
graphparser.setParseAction(push_top_graph_stmt)
|
||||
|
||||
return graphparser
|
||||
|
||||
|
||||
def parse_dot_data(data):
|
||||
try:
|
||||
graphparser = GRAPH_DEF()
|
||||
if pyparsing_version >= '1.2':
|
||||
graphparser.parseWithTabs()
|
||||
tokens = graphparser.parseString(data)
|
||||
graph = tokens.graph
|
||||
return graph
|
||||
except ParseException, err:
|
||||
print err.line
|
||||
print " "*(err.column-1) + "^"
|
||||
print err
|
||||
return None
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from distutils.core import setup
|
||||
import pydot
|
||||
|
||||
setup( name = 'pydot',
|
||||
version = pydot.__version__,
|
||||
description = 'Python interface to Graphiz\'s Dot',
|
||||
author = 'Ero Carrera',
|
||||
author_email = 'ero@dkbza.org',
|
||||
url = 'http://dkbza.org/pydot.html',
|
||||
license = 'MIT',
|
||||
platforms = ["any"],
|
||||
classifiers = ['Development Status :: 5 - Production/Stable', \
|
||||
'Intended Audience :: Science/Research', \
|
||||
'License :: OSI Approved :: MIT License',\
|
||||
'Natural Language :: English', \
|
||||
'Operating System :: OS Independent', \
|
||||
'Programming Language :: Python', \
|
||||
'Topic :: Scientific/Engineering :: Visualization',\
|
||||
'Topic :: Software Development :: Libraries :: Python Modules'],
|
||||
long_description = "\n".join(pydot.__doc__.split('\n')),
|
||||
py_modules = ['pydot', 'dot_parser'])
|
|
@ -0,0 +1,129 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# $Id: workflow.py 1304 2005-09-08 14:35:42Z nicoe $
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields, osv
|
||||
|
||||
class workflow(osv.osv):
|
||||
_name = "workflow"
|
||||
_table = "wkf"
|
||||
_log_access = False
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True),
|
||||
'osv': fields.char('Resource Model', size=64, required=True),
|
||||
'on_create': fields.boolean('On Create'),
|
||||
'activities': fields.one2many('workflow.activity', 'wkf_id', 'Activities'),
|
||||
}
|
||||
_defaults = {
|
||||
'on_create': lambda *a: True
|
||||
}
|
||||
workflow()
|
||||
|
||||
class wkf_activity(osv.osv):
|
||||
_name = "workflow.activity"
|
||||
_table = "wkf_activity"
|
||||
_log_access = False
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True),
|
||||
'wkf_id': fields.many2one('workflow', 'Workflow', required=True, select=True),
|
||||
'split_mode': fields.selection([('XOR', 'Xor'), ('OR','Or'), ('AND','And')], 'Split Mode', size=3, required=True),
|
||||
'join_mode': fields.selection([('XOR', 'Xor'), ('AND', 'And')], 'Join Mode', size=3, required=True),
|
||||
'kind': fields.selection([('dummy', 'Dummy'), ('function', 'Function'), ('subflow', 'Subflow'), ('stopall', 'Stop All')], 'Kind', size=64, required=True),
|
||||
'action': fields.char('Action', size=64),
|
||||
'flow_start': fields.boolean('Flow Start'),
|
||||
'flow_stop': fields.boolean('Flow Stop'),
|
||||
'subflow_id': fields.many2one('workflow', 'Subflow'),
|
||||
'signal_send': fields.char('Signal (subflow.*)', size=32),
|
||||
'out_transitions': fields.one2many('workflow.transition', 'act_from', 'Outgoing transitions'),
|
||||
'in_transitions': fields.one2many('workflow.transition', 'act_to', 'Incoming transitions'),
|
||||
}
|
||||
_defaults = {
|
||||
'kind': lambda *a: 'dummy',
|
||||
'join_mode': lambda *a: 'XOR',
|
||||
'split_mode': lambda *a: 'XOR',
|
||||
}
|
||||
wkf_activity()
|
||||
|
||||
class wkf_transition(osv.osv):
|
||||
_table = "wkf_transition"
|
||||
_name = "workflow.transition"
|
||||
_log_access = False
|
||||
_rec_name = 'signal' #TODO: pas top mais bon...
|
||||
_columns = {
|
||||
'trigger_model': fields.char('Trigger Type', size=128),
|
||||
'trigger_expr_id': fields.char('Trigger Expr ID', size=128),
|
||||
'signal': fields.char('Signal (button Name)', size=64),
|
||||
'role_id': fields.many2one('res.roles', 'Role Required'),
|
||||
'condition': fields.char('Condition', required=True, size=128),
|
||||
'act_from': fields.many2one('workflow.activity', 'Source Activity', required=True, select=True),
|
||||
'act_to': fields.many2one('workflow.activity', 'Destination Activity', required=True, select=True),
|
||||
}
|
||||
_defaults = {
|
||||
'condition': lambda *a: 'True',
|
||||
}
|
||||
wkf_transition()
|
||||
|
||||
class wkf_instance(osv.osv):
|
||||
_table = "wkf_instance"
|
||||
_name = "workflow.instance"
|
||||
_rec_name = 'res_type'
|
||||
_log_access = False
|
||||
_columns = {
|
||||
'wkf_id': fields.many2one('workflow', 'Workflow', ondelete="cascade"),
|
||||
'uid': fields.integer('User ID'),
|
||||
'res_id': fields.integer('Resource ID'),
|
||||
'res_type': fields.char('Resource Model', size=64),
|
||||
'state': fields.char('State', size=32),
|
||||
}
|
||||
wkf_instance()
|
||||
|
||||
class wkf_workitem(osv.osv):
|
||||
_table = "wkf_workitem"
|
||||
_name = "workflow.workitem"
|
||||
_log_access = False
|
||||
_rec_name = 'state'
|
||||
_columns = {
|
||||
'act_id': fields.many2one('workflow.activity', 'Activity', required=True, ondelete="cascade"),
|
||||
'subflow_id': fields.many2one('workflow.instance', 'Subflow', ondelete="cascade"),
|
||||
'inst_id': fields.many2one('workflow.instance', 'Instance', required=True, ondelete="cascade"),
|
||||
'state': fields.char('State', size=64),
|
||||
}
|
||||
wkf_workitem()
|
||||
|
||||
class wkf_triggers(osv.osv):
|
||||
_table = "wkf_triggers"
|
||||
_name = "workflow.triggers"
|
||||
_log_access = False
|
||||
_columns = {
|
||||
'res_id': fields.integer('Resource ID', size=128),
|
||||
'model': fields.char('Model', size=128),
|
||||
'instance_id': fields.many2one('workflow.instance', 'Destination Instance', ondelete="cascade"),
|
||||
'workitem_id': fields.many2one('workflow.workitem', 'Workitem', required=True, ondelete="cascade"),
|
||||
}
|
||||
wkf_triggers()
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
import psycopg
|
||||
import pydot
|
||||
|
||||
wkf_id = 193
|
||||
|
||||
db = psycopg.connect('dbname=terp', serialize=0)
|
||||
cr=db.cursor()
|
||||
|
||||
def graph_get(cr, graph, wkf_id, nested=True):
|
||||
cr.execute('select * from wkf_activity where wkf_id=%d', (wkf_id,))
|
||||
nodes = cr.dictfetchall()
|
||||
activities = {}
|
||||
actfrom = {}
|
||||
actto = {}
|
||||
for n in nodes:
|
||||
activities[n['id']] = n
|
||||
if n['subflow_id'] and nested:
|
||||
cr.execute('select * from wkf where id=%d', (n['subflow_id'],))
|
||||
wkfinfo = cr.dictfetchone()
|
||||
graph2 = pydot.Cluster('subflow'+str(n['subflow_id']), fontsize=10, label = "Subflow: "+n['name']+'\\nOSV: '+wkfinfo['osv'])
|
||||
(s1,s2) = graph_get(cr, graph2, n['subflow_id'], nested)
|
||||
graph.add_subgraph(graph2)
|
||||
actfrom[n['id']] = s2
|
||||
actto[n['id']] = s1
|
||||
else:
|
||||
args = {}
|
||||
if n['flow_start'] or n['flow_stop']:
|
||||
args['style']='filled'
|
||||
args['color']='lightgrey'
|
||||
args['label']=n['name']
|
||||
if n['action']:
|
||||
args['label']+='\\n'+n['action']
|
||||
if n['subflow_id']:
|
||||
args['shape'] = 'box'
|
||||
graph.add_node(pydot.Node(n['id'], **args))
|
||||
actfrom[n['id']] = n['id']
|
||||
actto[n['id']] = n['id']
|
||||
cr.execute('select * from wkf_transition where act_from in ('+','.join(map(lambda x: str(x['id']),nodes))+')')
|
||||
transitions = cr.dictfetchall()
|
||||
for t in transitions:
|
||||
args = {}
|
||||
args['label'] = str(t['condition'])
|
||||
if t['signal']:
|
||||
args['label'] += '\\n'+str(t['signal'])
|
||||
args['style'] = 'bold'
|
||||
|
||||
if activities[t['act_from']]['split_mode']=='AND':
|
||||
args['arrowtail']='box'
|
||||
elif str(activities[t['act_from']]['split_mode'])=='OR ':
|
||||
args['arrowtail']='inv'
|
||||
|
||||
if activities[t['act_to']]['join_mode']=='AND':
|
||||
args['arrowhead']='crow'
|
||||
|
||||
graph.add_edge(pydot.Edge(actfrom[t['act_from']],actto[t['act_to']], fontsize=8, **args))
|
||||
nodes = cr.dictfetchall()
|
||||
cr.execute('select id from wkf_activity where flow_start=True limit 1')
|
||||
start = cr.fetchone()[0]
|
||||
cr.execute('select id from wkf_activity where flow_stop=True limit 1')
|
||||
stop = cr.fetchone()[0]
|
||||
return (start,stop)
|
||||
|
||||
cr.execute('select * from wkf where id=%d', (wkf_id,))
|
||||
wkfinfo = cr.dictfetchone()
|
||||
graph = pydot.Dot(fontsize = 16, label = "\\n\\nWorkflow: %s\\n OSV: %s"% (wkfinfo['name'],wkfinfo['osv']))
|
||||
graph_get(cr, graph, wkf_id, True)
|
||||
graph.write_ps('/tmp/a.ps', prog='dot')
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data>
|
||||
<menuitem name="Administration/Custom/Low level/Base/Workflows"/>
|
||||
|
||||
<!--
|
||||
================================
|
||||
Workflows
|
||||
================================
|
||||
-->
|
||||
|
||||
<record model="ir.ui.view" id="view_workflow_form">
|
||||
<field name="name">workflow.form</field>
|
||||
<field name="model">workflow</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Workflow">
|
||||
<field name="name" select="1"/>
|
||||
<field name="osv" select="1"/>
|
||||
<field name="on_create"/>
|
||||
<separator string="Activities" colspan="4"/>
|
||||
<field name="activities" colspan="4" nolabel="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_workflow_form">
|
||||
<field name="name">workflow.form</field>
|
||||
<field name="res_model">workflow</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_workflow_form"/>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Administration/Custom/Low level/Base/Workflows/Workflows"
|
||||
action="action_workflow_form"
|
||||
id="menu_workflow"/>
|
||||
|
||||
<!--
|
||||
================================
|
||||
Activities
|
||||
================================
|
||||
-->
|
||||
|
||||
<record model="ir.ui.view" id="view_workflow_activity_form">
|
||||
<field name="name">workflow.activity.form</field>
|
||||
<field name="model">workflow.activity</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Activity">
|
||||
<field name="name" colspan="3" select="1"/>
|
||||
<field name="kind" select="1"/>
|
||||
<field name="action" colspan="3" select="1"/>
|
||||
<field name="subflow_id"/>
|
||||
<field name="signal_send"/>
|
||||
<newline/>
|
||||
<field name="flow_start"/>
|
||||
<field name="flow_stop"/>
|
||||
<field name="split_mode"/>
|
||||
<field name="join_mode"/>
|
||||
<separator string="Outgoing transitions" colspan="4"/>
|
||||
<field name="out_transitions" colspan="4" nolabel="1">
|
||||
<tree string="Transitions">
|
||||
<field name="act_to"/>
|
||||
<field name="signal"/>
|
||||
<field name="role_id"/>
|
||||
<field name="condition"/>
|
||||
<field name="trigger_model"/>
|
||||
<field name="trigger_expr_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
<separator string="Incoming transitions" colspan="4"/>
|
||||
<field name="in_transitions" colspan="4" nolabel="1">
|
||||
<tree string="Transitions">
|
||||
<field name="act_from"/>
|
||||
<field name="signal"/>
|
||||
<field name="role_id"/>
|
||||
<field name="condition"/>
|
||||
<field name="trigger_model"/>
|
||||
<field name="trigger_expr_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_workflow_activity_form">
|
||||
<field name="name">workflow.activity.form</field>
|
||||
<field name="res_model">workflow.activity</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_workflow_activity_form"/>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Administration/Custom/Low level/Base/Workflows/Activities"
|
||||
action="action_workflow_activity_form"
|
||||
id="menu_workflow_activity"/>
|
||||
|
||||
|
||||
<!--
|
||||
================================
|
||||
Transitions
|
||||
================================
|
||||
-->
|
||||
|
||||
<record model="ir.ui.view" id="view_workflow_transition_form">
|
||||
<field name="name">workflow.transition.form</field>
|
||||
<field name="model">workflow.transition</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Transition">
|
||||
<field name="act_from" select="1"/>
|
||||
<field name="act_to" select="1"/>
|
||||
<field name="condition" colspan="3"/>
|
||||
<field name="signal"/>
|
||||
<field name="role_id"/>
|
||||
<field name="trigger_model"/>
|
||||
<field name="trigger_expr_id"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_workflow_transition_tree">
|
||||
<field name="name">workflow.transition.tree</field>
|
||||
<field name="model">workflow.transition</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Transition">
|
||||
<field name="act_from"/>
|
||||
<field name="act_to"/>
|
||||
<field name="signal"/>
|
||||
<field name="role_id"/>
|
||||
<field name="condition"/>
|
||||
<field name="trigger_model"/>
|
||||
<field name="trigger_expr_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.actions.act_window" id="action_workflow_transition_form">
|
||||
<field name="name">workflow.transition.form</field>
|
||||
<field name="res_model">workflow.transition</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_workflow_transition_form"/>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Administration/Custom/Low level/Base/Workflows/Transitions"
|
||||
action="action_workflow_transition_form"
|
||||
id="menu_workflow_transition"/>
|
||||
|
||||
<!--
|
||||
================================
|
||||
Instances
|
||||
================================
|
||||
-->
|
||||
|
||||
<record model="ir.ui.view" id="view_workflow_instance_form">
|
||||
<field name="name">workflow.instance.form</field>
|
||||
<field name="model">workflow.instance</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Workflow Instances">
|
||||
<field name="wkf_id" select="1"/>
|
||||
<field name="uid" select="1"/>
|
||||
<field name="res_id" select="1"/>
|
||||
<field name="res_type" select="1"/>
|
||||
<field name="state" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_workflow_instance_form">
|
||||
<field name="name">workflow.instance.form</field>
|
||||
<field name="res_model">workflow.instance</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_workflow_instance_form"/>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Administration/Custom/Low level/Base/Workflows/Instances"
|
||||
action="action_workflow_instance_form"
|
||||
id="menu_workflow_instance"/>
|
||||
|
||||
<!--
|
||||
================================
|
||||
Workitems
|
||||
================================
|
||||
-->
|
||||
|
||||
<record model="ir.ui.view" id="view_workflow_workitem_form">
|
||||
<field name="name">workflow.workitem.form</field>
|
||||
<field name="model">workflow.workitem</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Workflow Workitems">
|
||||
<field name="act_id" select="1"/>
|
||||
<field name="subflow_id" select="1"/>
|
||||
<field name="inst_id" select="1"/>
|
||||
<field name="state" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_workflow_workitem_form">
|
||||
<field name="name">workflow.workitem.form</field>
|
||||
<field name="res_model">workflow.workitem</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_workflow_workitem_form"/>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Administration/Custom/Low level/Base/Workflows/Workitems"
|
||||
action="action_workflow_workitem_form"
|
||||
id="menu_workflow_workitem"/>
|
||||
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,31 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import module
|
||||
import wizard
|
||||
import report
|
|
@ -0,0 +1,274 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2005 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import tarfile
|
||||
import re
|
||||
import urllib
|
||||
import os
|
||||
import tools
|
||||
from osv import fields, osv
|
||||
|
||||
class module_repository(osv.osv):
|
||||
_name = "ir.module.repository"
|
||||
_description = "Module Repository"
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=128),
|
||||
'url': fields.char('Url', size=256, required=True),
|
||||
}
|
||||
module_repository()
|
||||
|
||||
def get_module_info(name):
|
||||
try:
|
||||
f = file(os.path.join(tools.config['addons_path'], name, '__terp__.py'), 'r')
|
||||
data = f.read()
|
||||
info = eval(data)
|
||||
f.close()
|
||||
except:
|
||||
return {}
|
||||
return info
|
||||
|
||||
class module_category(osv.osv):
|
||||
_name = "ir.module.category"
|
||||
_description = "Module Category"
|
||||
|
||||
def _module_nbr(self,cr,uid, ids, prop, unknow_none,context):
|
||||
cr.execute('select category_id,count(*) from ir_module_module where category_id in ('+','.join(map(str,ids))+') or category_id in (select id from ir_module_category where parent_id in ('+','.join(map(str,ids))+')) group by category_id')
|
||||
result = dict(cr.fetchall())
|
||||
for id in ids:
|
||||
cr.execute('select id from ir_module_category where parent_id=%d', (id,))
|
||||
childs = [c for c, in cr.fetchall()]
|
||||
result[id] = reduce(lambda x,y:x+y, [result.get(c, 0) for c in childs], result.get(id, 0))
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
'name': fields.char("Name", size=128, required=True),
|
||||
'parent_id': fields.many2one('ir.module.category', 'Parent Category', select=True),
|
||||
'child_ids': fields.one2many('ir.module.category', 'parent_id', 'Parent Category'),
|
||||
'module_nr': fields.function(_module_nbr, method=True, string='# of Modules', type='integer')
|
||||
}
|
||||
_order = 'name'
|
||||
module_category()
|
||||
|
||||
class module(osv.osv):
|
||||
_name = "ir.module.module"
|
||||
_description = "Module"
|
||||
|
||||
def _get_installed_version(self, cr, uid, ids, field_name=None, arg=None, context={}):
|
||||
res = {}
|
||||
for m in self.browse(cr, uid, ids):
|
||||
res[m.id] = get_module_info(m.name).get('version', False)
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'name': fields.char("Name", size=128, readonly=True, required=True),
|
||||
'category_id': fields.many2one('ir.module.category', 'Category', readonly=True),
|
||||
'shortdesc': fields.char('Short description', size=256, readonly=True),
|
||||
'description': fields.text("Description", readonly=True),
|
||||
'author': fields.char("Author", size=128, readonly=True),
|
||||
'website': fields.char("Website", size=256, readonly=True),
|
||||
'installed_version': fields.function(_get_installed_version, method=True, string='Installed version', type='char'),
|
||||
'latest_version': fields.char('Latest version', size=64, readonly=True),
|
||||
'url': fields.char('URL', size=128, readonly=True),
|
||||
'dependencies_id': fields.one2many('ir.module.module.dependency', 'module_id', 'Dependencies'),
|
||||
'state': fields.selection([
|
||||
('uninstallable','Uninstallable'),
|
||||
('uninstalled','Not Installed'),
|
||||
('installed','Installed'),
|
||||
('to upgrade','To be upgraded'),
|
||||
('to remove','To be removed'),
|
||||
('to install','To be installed')
|
||||
], string='State', readonly=True),
|
||||
'demo': fields.boolean('Demo data'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'state': lambda *a: 'uninstalled',
|
||||
'demo': lambda *a: False,
|
||||
}
|
||||
_order = 'name'
|
||||
|
||||
def state_change(self, cr, uid, ids, newstate, context={}, level=50):
|
||||
if level<1:
|
||||
raise 'Recursion error in modules dependencies !'
|
||||
ids_dest = []
|
||||
for module in self.browse(cr, uid, ids):
|
||||
for dep in module.dependencies_id:
|
||||
ids2 = self.search(cr, uid, [('name','=',dep.name)])
|
||||
for id in ids2:
|
||||
if (id not in ids_dest):
|
||||
ids_dest.append(id)
|
||||
if module.state=='uninstalled':
|
||||
self.write(cr, uid, [module.id], {'state': newstate})
|
||||
if ids_dest:
|
||||
self.state_change(cr, uid, ids_dest, newstate, context, level-1)
|
||||
|
||||
for module in self.browse(cr, uid, ids):
|
||||
if module.state!='installed':
|
||||
demo=True
|
||||
for dep in module.dependencies_id:
|
||||
ids2 = self.search(cr, uid, [('name', '=', dep.name)])
|
||||
for module2 in self.browse(cr, uid, ids2):
|
||||
demo = demo and module2.demo
|
||||
self.write(cr, uid, [module.id], {'demo':demo})
|
||||
return True
|
||||
|
||||
def button_install(self, cr, uid, ids, context={}):
|
||||
return self.state_change(cr, uid, ids, 'to install', context)
|
||||
|
||||
def button_install_cancel(self, cr, uid, ids, context={}):
|
||||
self.write(cr, uid, ids, {'state': 'uninstalled'})
|
||||
return True
|
||||
|
||||
def button_uninstall(self, cr, uid, ids, context={}):
|
||||
self.write(cr, uid, ids, {'state': 'to remove'})
|
||||
return True
|
||||
|
||||
def button_remove_cancel(self, cr, uid, ids, context={}):
|
||||
self.write(cr, uid, ids, {'state': 'installed'})
|
||||
return True
|
||||
def button_upgrade(self, cr, uid, ids, context={}):
|
||||
self.write(cr, uid, ids, {'state': 'to upgrade'})
|
||||
return True
|
||||
def button_upgrade_cancel(self, cr, uid, ids, context={}):
|
||||
self.write(cr, uid, ids, {'state': 'installed'})
|
||||
return True
|
||||
def button_update_translations(self, cr, uid, ids, context={}):
|
||||
cr.execute('select code from res_lang where translatable=TRUE')
|
||||
langs = [l[0] for l in cr.fetchall()]
|
||||
modules = self.read(cr, uid, ids, ['name'])
|
||||
for module in modules:
|
||||
files = get_module_info(module['name']).get('translations', {})
|
||||
for lang in langs:
|
||||
if files.has_key(lang):
|
||||
filepath = files[lang]
|
||||
# if filepath does not contain :// we prepend the path of the module
|
||||
if filepath.find('://') == -1:
|
||||
filepath = os.path.join(tools.config['addons_path'], module['name'], filepath)
|
||||
tools.trans_load(filepath, lang)
|
||||
return True
|
||||
|
||||
# update the list of available packages
|
||||
def update_list(self, cr, uid, context={}):
|
||||
robj = self.pool.get('ir.module.repository')
|
||||
adp = tools.config['addons_path']
|
||||
|
||||
# iterate through installed modules and mark them as being so
|
||||
for name in os.listdir(adp):
|
||||
if os.path.isdir(os.path.join(adp, name)):
|
||||
version = get_module_info(name).get('version', False)
|
||||
if version:
|
||||
ids = self.search(cr, uid, [('name','=',name)])
|
||||
if not ids:
|
||||
id = self.create(cr, uid, {
|
||||
'name': name,
|
||||
'latest_version': version,
|
||||
'state': 'installed',
|
||||
})
|
||||
else:
|
||||
self.write(cr, uid, ids, {'state': 'installed'})
|
||||
|
||||
# make the list of all installable modules
|
||||
for repository in robj.browse(cr, uid, robj.search(cr, uid, [])):
|
||||
index_page = urllib.urlopen(repository.url).read()
|
||||
modules = re.findall('.*<a href="([a-zA-Z0-9.\-]+)_([a-zA-Z0-9.\-]+)\.tar\.gz">.*', index_page)
|
||||
for name, version in modules:
|
||||
# TODO: change this using urllib
|
||||
url = os.path.join(repository.url, name + '_' + version + ".tar.gz")
|
||||
ids = self.search(cr, uid, [('name','=',name)])
|
||||
if not ids:
|
||||
self.create(cr, uid, {
|
||||
'name': name,
|
||||
'latest_version': version,
|
||||
'url': url,
|
||||
'state': 'uninstalled',
|
||||
})
|
||||
else:
|
||||
for r in self.read(cr, uid, ids, ['latest_version']):
|
||||
if r['latest_version'] < version:
|
||||
self.write(cr, uid, [r['id']], {'latest_version': version, 'url':url})
|
||||
return True
|
||||
|
||||
#
|
||||
# TODO: update dependencies
|
||||
#
|
||||
def info_get(self, cr, uid, ids, context={}):
|
||||
categ_obj = self.pool.get('ir.module.category')
|
||||
|
||||
for module in self.browse(cr, uid, ids, context):
|
||||
url = module.url
|
||||
adp = tools.config['addons_path']
|
||||
info = False
|
||||
if url:
|
||||
tar = tarfile.open(mode="r|gz", fileobj=urllib.urlopen(url))
|
||||
for tarinfo in tar:
|
||||
if tarinfo.name.endswith('__terp__.py'):
|
||||
info = eval(tar.extractfile(tarinfo).read())
|
||||
elif os.path.isdir(os.path.join(adp, module.name)):
|
||||
info = get_module_info(module.name)
|
||||
if info:
|
||||
categ = info.get('category', 'Unclassified')
|
||||
parent = False
|
||||
for c in categ.split('/'):
|
||||
ids = categ_obj.search(cr, uid, [('name','=',c), ('parent_id','=',parent)])
|
||||
if not ids:
|
||||
parent = categ_obj.create(cr, uid, {'name':c, 'parent_id':parent})
|
||||
else:
|
||||
parent = ids[0]
|
||||
self.write(cr, uid, [module.id], {
|
||||
'author': info.get('author',False),
|
||||
'website': info.get('website',False),
|
||||
'shortdesc': info.get('name',False),
|
||||
'description': info.get('description',False),
|
||||
'category_id': parent
|
||||
})
|
||||
return True
|
||||
module()
|
||||
|
||||
class module_dependency(osv.osv):
|
||||
_name = "ir.module.module.dependency"
|
||||
_description = "Module dependency"
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=128),
|
||||
'module_id': fields.many2one('ir.module.module', 'Module', select=True),
|
||||
#'module_dest_id': fields.many2one('ir.module.module', 'Module'),
|
||||
'version_pattern': fields.char('Required Version', size=128),
|
||||
}
|
||||
# returns the ids of module version records which match all dependencies
|
||||
# [version_id, ...]
|
||||
def resolve(self, cr, uid, ids):
|
||||
vobj = self.pool.get('ir.module.module.version')
|
||||
objs = self.browse(cr, uid, ids)
|
||||
res = {}
|
||||
for o in objs:
|
||||
pattern = o.version_pattern and eval(o.version_pattern) or []
|
||||
print "pattern", pattern
|
||||
res[o.id] = vobj.search(cr, uid, [('module','=',o.module.id)]+pattern)
|
||||
#TODO: add smart dependencies resolver here
|
||||
# it should compute the best version for each module
|
||||
return [r[0] for r in res.itervalues()]
|
||||
module_dependency()
|
||||
|
|
@ -0,0 +1,228 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2005 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import tarfile
|
||||
import re
|
||||
import urllib2
|
||||
import os
|
||||
import shutil
|
||||
from sets import Set
|
||||
|
||||
from osv import fields, osv
|
||||
import tools
|
||||
|
||||
class module(osv.osv):
|
||||
_name = "module.module"
|
||||
_description = "Module"
|
||||
|
||||
def _costs_get(self, cr, uid, ids, prop=None, unknown_none=None, unknown_dict={}):
|
||||
dossiers = self.browse(cr, uid, ids)
|
||||
res = {}
|
||||
for d in dossiers:
|
||||
costs = [l.amount_costs for l in d.lot_id]
|
||||
cost_amount = reduce(lambda x, y: x+y, costs, 0.0)
|
||||
res[d.id] = cost_amount
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'name': fields.char("Name", size=128, readonly=True),
|
||||
'shortdesc': fields.char('Short description', size=256, readonly=True),
|
||||
'description': fields.text("Description", readonly=True),
|
||||
'author': fields.char("Author", size=128, readonly=True),
|
||||
'website': fields.char("Website", size=256, readonly=True),
|
||||
# 'running_version': fields.function(_get_installed_version, method=True, string='Installed version'),
|
||||
# 'installed_version': fields.function(_get_installed_version, method=True, string='Installed version'),
|
||||
'latest_version': fields.many2one('module.module.version', 'Latest version'),
|
||||
'versions': fields.one2many('module.module.version', 'module', 'Versions', readonly=True),
|
||||
'state': fields.selection([('uninstalled', 'Uninstalled'), ('preinstall','To install'),('installed','Installed'),('running','Running')], 'State'),
|
||||
# 'active': fields.boolean('Active'),
|
||||
}
|
||||
|
||||
# update the list of available packages
|
||||
def update(self, cr, uid, ids, *args):
|
||||
vobj = self.pool.get('module.module.version')
|
||||
|
||||
# update installed_version
|
||||
|
||||
# get the index page containing available packages from the server
|
||||
index_page = urllib2.urlopen('http://www.tinyerp.org/download/modules_test').read()
|
||||
# print index_page
|
||||
# parses it
|
||||
modules = re.findall('.*<a href="([a-zA-Z0-9.\-]+)_([a-zA-Z0-9.\-]+)\.tar\.gz">.*', index_page)
|
||||
# create module.module records and module.module.version as needed
|
||||
for name, version in modules:
|
||||
print "name", name, "version", version
|
||||
# open module package on the remote server and extract its __terp__.py
|
||||
url = 'http://www.tinyerp.org/download/modules_test/' + name + '_' + version + ".tar.gz"
|
||||
tar = tarfile.open(mode="r|gz", fileobj=urllib2.urlopen(url))
|
||||
info = {}
|
||||
# we need to go through the whole tar file, because we use a stream and we
|
||||
# are not allowed to search backward in the stream, so we can't extract one
|
||||
# particular file directly
|
||||
for tarinfo in tar:
|
||||
if tarinfo.name.endswith('__terp__.py'):
|
||||
info = eval(tar.extractfile(tarinfo).read())
|
||||
break
|
||||
tar.close()
|
||||
print info
|
||||
ids = self.search(cr, uid, [('name','=',name)])
|
||||
print ids
|
||||
if not ids:
|
||||
id = self.create(cr, uid, {
|
||||
'name': name,
|
||||
'shortdesc': info.get('name', False),
|
||||
'description': info.get('description', False),
|
||||
'author': info.get('author', False),
|
||||
'website': info.get('website', False),
|
||||
'state': 'uninstalled',
|
||||
})
|
||||
print "module_id", id
|
||||
else:
|
||||
assert len(ids)==1, "There shouldn't be two modules with the same name"
|
||||
id = ids[0]
|
||||
|
||||
version_ids = vobj.search(cr, uid, [('module','=',id),('name','=',version)])
|
||||
print version_ids
|
||||
if not version_ids:
|
||||
version_id = vobj.create(cr, uid, {
|
||||
'name': version,
|
||||
'module': id,
|
||||
'state': 'uninstalled',
|
||||
})
|
||||
print "version_id", version_id
|
||||
# update latest_version
|
||||
#TODO: compute latest version
|
||||
self.write(cr, uid, [id], {'latest_version': version_id})
|
||||
# else:
|
||||
# assert len(version_ids)==1, "There shouldn't be two versions with the same name"
|
||||
# version_id = version_ids[0]
|
||||
|
||||
return True
|
||||
|
||||
def install(self, cr, uid, ids, *args):
|
||||
objs = self.browse(cr, uid, ids)
|
||||
vobj = self.pool.get('module.module.version')
|
||||
|
||||
# get the id of latest version for each module
|
||||
version_ids = Set([o.latest_version.id for o in objs])
|
||||
# for o in objs:
|
||||
# version_ids.add()
|
||||
# version_ids = reduce(lambda dic, o: dic.update({o.latest_version.id:True}), objs, {})
|
||||
print "version_ids", version_ids
|
||||
|
||||
# add the list of dependencies
|
||||
dependencies_ids = vobj.get_dependencies(cr, uid, list(version_ids))
|
||||
print "depends", dependencies_ids
|
||||
version_ids.update(dependencies_ids)
|
||||
# version_ids = reduce(lambda dic, dep: dic.update({dep:True}), dependencies_ids, version_ids)
|
||||
print "version_ids2", version_ids
|
||||
|
||||
# remove existing version of modules
|
||||
self.remove(cr, uid, ids)
|
||||
|
||||
# install all selected modules and their dependencies
|
||||
vobj.install(cr, uid, list(version_ids))
|
||||
return True
|
||||
|
||||
|
||||
# remove existing version of modules if they exist
|
||||
def remove(self, cr, uid, ids, *args):
|
||||
objs = self.browse(cr, uid, ids)
|
||||
adp = tools.config['addons_path']
|
||||
addons = os.listdir(adp)
|
||||
for o in objs:
|
||||
if o.name in addons:
|
||||
shutil.rmtree(os.path.join(adp, o.name))
|
||||
return True
|
||||
module()
|
||||
|
||||
class module_version(osv.osv):
|
||||
_name = "module.module.version"
|
||||
_description = "Module Version"
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64),
|
||||
'module': fields.many2one('module.module', "Module"),
|
||||
'dependencies': fields.one2many('module.module.dependency', 'version', 'Dependencies'),
|
||||
'state': fields.selection([('uninstalled','Uninstalled'), ('preinstall','To install'), ('installed','Installed'), ('running','Running')], 'State'),
|
||||
}
|
||||
|
||||
def install(self, cr, uid, ids, *args):
|
||||
print "install versions", ids
|
||||
objs = self.browse(cr, uid, ids)
|
||||
|
||||
for o in objs:
|
||||
# download and unpack to destination folder
|
||||
url = 'http://www.tinyerp.org/download/modules_test/' + o.module.name + '_' + o.name + ".tar.gz"
|
||||
tar = tarfile.open(mode="r|gz", fileobj=urllib2.urlopen(url))
|
||||
for tarinfo in tar:
|
||||
tar.extract(tarinfo, tools.config['addons_path'])
|
||||
return True
|
||||
|
||||
def get_dependencies(self, cr, uid, ids, *args):
|
||||
dobj = self.pool.get('module.module.dependency')
|
||||
print "get_depends", ids
|
||||
# for each dependency, get dependencies
|
||||
objs = self.browse(cr, uid, ids)
|
||||
depends = []
|
||||
for o in objs:
|
||||
print "name", o.name
|
||||
o_depends = dobj.resolve(cr, uid, [d.id for d in o.dependencies])
|
||||
print "depends", o_depends
|
||||
depends.extend(o_depends)
|
||||
|
||||
# depends.extend([d.id for d in o.dependencies])
|
||||
print "total depends", depends
|
||||
# merge the list
|
||||
# return the list of ids
|
||||
return depends
|
||||
module_version()
|
||||
|
||||
# a module dependency record represents one dependency of a particular version of a module
|
||||
# it can depend on a range of version of one module
|
||||
class module_dependency(osv.osv):
|
||||
_name = "module.module.dependency"
|
||||
_description = "Module dependency"
|
||||
_columns = {
|
||||
'dependency_for': fields.many2one('module.module.version', 'Version'),
|
||||
'module': fields.many2one('module.module', 'Module'),
|
||||
'version_pattern': fields.char('Version pattern', size=128),
|
||||
}
|
||||
|
||||
# returns the ids of module version records which match all dependencies
|
||||
# [version_id, ...]
|
||||
def resolve(self, cr, uid, ids):
|
||||
vobj = self.pool.get('module.module.version')
|
||||
objs = self.browse(cr, uid, ids)
|
||||
res = {}
|
||||
for o in objs:
|
||||
pattern = o.version_pattern and eval(o.version_pattern) or []
|
||||
print "pattern", pattern
|
||||
res[o.id] = vobj.search(cr, uid, [('module','=',o.module.id)]+pattern)
|
||||
#TODO: add smart dependencies resolver here
|
||||
# it should compute the best version for each module
|
||||
return [r[0] for r in res.itervalues()]
|
||||
module_dependency()
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data>
|
||||
<!--
|
||||
<record model="ir.module.repository" id="module_repository_tiny">
|
||||
<field name="name">Tiny ERP Base Repository</field>
|
||||
<field name="url">http://tinyerp.org/download/modules/</field>
|
||||
</record>
|
||||
-->
|
||||
</data>
|
||||
</terp>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" ?>
|
||||
<terp>
|
||||
<data>
|
||||
|
||||
<report id="ir_module_reference_print"
|
||||
string="Technical guide"
|
||||
model="ir.module.module"
|
||||
name="ir.module.reference"
|
||||
rml="base/module/report/ir_module_reference.rml"
|
||||
auto="False" />
|
||||
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,198 @@
|
|||
<?xml version="1.0" ?>
|
||||
<terp>
|
||||
<data>
|
||||
|
||||
#
|
||||
# Modules Categories
|
||||
#
|
||||
|
||||
<record model="ir.ui.view" id="view_module_category_form">
|
||||
<field name="name">ir.module.category.form</field>
|
||||
<field name="model">ir.module.category</field>
|
||||
<field name="type">form</field>
|
||||
<field name="field_parent">child_ids</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Module Category">
|
||||
<field name="name" colspan="3"/>
|
||||
<field name="parent_id" colspan="3"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_module_category_tree">
|
||||
<field name="name">ir.module.category.tree</field>
|
||||
<field name="model">ir.module.category</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="field_parent">child_ids</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Module Category">
|
||||
<field name="name"/>
|
||||
<field name="module_nr"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_module_category_tree">
|
||||
<field name="name">ir.module.category</field>
|
||||
<field name="res_model">ir.module.category</field>
|
||||
<field name="view_type">tree</field>
|
||||
<field name="domain">[('parent_id','=',False)]</field>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Administration/Modules Management/Categories of Modules"
|
||||
action="action_module_category_tree"
|
||||
/>
|
||||
|
||||
#
|
||||
# Click on a category
|
||||
#
|
||||
|
||||
<record model="ir.actions.act_window" id="action_module_open_categ">
|
||||
<field name="name">ir.module.module</field>
|
||||
<field name="res_model">ir.module.module</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('category_id','=',active_id)]</field>
|
||||
</record>
|
||||
<record model="ir.values" id="ir_action_module_category">
|
||||
<field name="key2" eval="'tree_but_open'"/>
|
||||
<field name="model" eval="'ir.module.category'"/>
|
||||
<field name="name">Categorized Modules</field>
|
||||
<field name="value" eval="'ir.actions.act_window,%d'%action_module_open_categ"/>
|
||||
<field name="object" eval="True"/>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- Modules -->
|
||||
|
||||
<record model="ir.ui.view" id="module_form">
|
||||
<field name="name">ir.module.module.form</field>
|
||||
<field name="model">ir.module.module</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Module">
|
||||
<notebook>
|
||||
<page string="Module">
|
||||
<field name="name" select="1"/>
|
||||
<field name="shortdesc" colspan="3"/>
|
||||
<field name="description" colspan="3"/>
|
||||
<field name="installed_version"/>
|
||||
<field name="latest_version"/>
|
||||
<field name="author"/>
|
||||
<field name="website"/>
|
||||
<field name="url"/>
|
||||
<field name="demo" readonly="1"/>
|
||||
<field name="state" readonly="1"/>
|
||||
<group col="7" colspan="2">
|
||||
<button string="Update Infos" name="info_get" type="object" states="uninstalled,installed,to upgrade,to remove"/>
|
||||
<button string="Cancel Install" name="button_install_cancel" type="object" states="to install"/>
|
||||
<button string="Install" name="button_install" type="object" states="uninstalled"/>
|
||||
<!--
|
||||
<button string="Cancel Upgrade" name="button_upgrade_cancel" type="object" states="to upgrade"/>
|
||||
<button string="Cancel Remove" name="button_remove_cancel" type="object" states="to remove"/>
|
||||
<button string="Uninstall" name="button_uninstall" type="object" states="installed"/>
|
||||
-->
|
||||
<button string="Upgrade" name="button_upgrade" type="object" states="installed"/>
|
||||
<!--
|
||||
<button string="Update translations" name="button_update_translations" type="object" states="installed"/>
|
||||
-->
|
||||
</group>
|
||||
</page>
|
||||
<page string="Dependencies">
|
||||
<field name="dependencies_id" colspan="4" nolabel="1">
|
||||
<tree string="Dependencies">
|
||||
<field name="name"/>
|
||||
<field name="version_pattern"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="module_tree">
|
||||
<field name="name">ir.module.module.tree</field>
|
||||
<field name="model">ir.module.module</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Module list" colors="blue:state=='to upgrade' or state=='to install';grey:state=='uninstalled' or state=='uninstallable'">
|
||||
<field name="name"/>
|
||||
<field name="shortdesc"/>
|
||||
<field name="author"/>
|
||||
<field name="installed_version"/>
|
||||
<field name="latest_version"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="open_module_tree">
|
||||
<field name="name">ir.module.module</field>
|
||||
<field name="res_model">ir.module.module</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain"></field>
|
||||
</record>
|
||||
<menuitem name="Administration/Modules Management/Modules" action="open_module_tree"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="open_module_tree_install">
|
||||
<field name="name">ir.module.module</field>
|
||||
<field name="res_model">ir.module.module</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('state','=','installed')]</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Modules Management/Modules/Installed Modules" action="open_module_tree_install"/>
|
||||
<record model="ir.actions.act_window" id="open_module_tree_uninstall">
|
||||
<field name="name">ir.module.module</field>
|
||||
<field name="res_model">ir.module.module</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('state','=','uninstalled')]</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Modules Management/Modules/Uninstalled Modules" action="open_module_tree_uninstall"/>
|
||||
<record model="ir.actions.act_window" id="open_module_tree_upgrade">
|
||||
<field name="name">ir.module.module</field>
|
||||
<field name="res_model">ir.module.module</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[('state','<>','uninstalled'),('state','<>','installed'),('state','<>','uninstallable'),]</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Modules Management/Modules/Modules to be installed, upgraded or removed" action="open_module_tree_upgrade"/>
|
||||
|
||||
<record model="ir.ui.view" id="repository_form">
|
||||
<field name="name">ir.module.repository.form</field>
|
||||
<field name="model">ir.module.repository</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Repository">
|
||||
<field name="name" colspan="3" select="1"/>
|
||||
<field name="url" colspan="3" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="repository_tree">
|
||||
<field name="name">ir.module.repository.tree</field>
|
||||
<field name="model">ir.module.repository</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Repository list">
|
||||
<field name="name"/>
|
||||
<field name="url"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="open_repository_tree">
|
||||
<field name="name">ir.module.repository</field>
|
||||
<field name="res_model">ir.module.repository</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<!--
|
||||
<menuitem
|
||||
name="Administration/Modules Management/Repositories"
|
||||
action="open_repository_tree"
|
||||
id="menu_module_repository_tree"
|
||||
/>
|
||||
-->
|
||||
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,76 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data>
|
||||
<wizard
|
||||
id="wizard_info_get"
|
||||
string="Request Info"
|
||||
model="ir.module.module"
|
||||
name="module.info_get"/>
|
||||
|
||||
<!--
|
||||
<record model="ir.actions.wizard" id="wizard_update">
|
||||
<field name="name">Download module list</field>
|
||||
<field name="wiz_name">module.module.update</field>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Administration/Module Management/Download module list"
|
||||
action="wizard_update"
|
||||
type="wizard"
|
||||
groups="admin"
|
||||
icon="STOCK_CONVERT"
|
||||
id="menu_module_update"/>
|
||||
-->
|
||||
|
||||
<record model="ir.actions.wizard" id="wizard_upgrade">
|
||||
<field name="name">Apply marked changes</field>
|
||||
<field name="wiz_name">module.upgrade</field>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Administration/Modules Management/Apply Upgrades"
|
||||
action="wizard_upgrade"
|
||||
id="menu_wizard_upgrade"
|
||||
type="wizard"/>
|
||||
|
||||
<record model="ir.actions.wizard" id="wizard_lang_install">
|
||||
<field name="name">Install new language file</field>
|
||||
<field name="wiz_name">module.lang.install</field>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Administration/Translations/Load a new language"
|
||||
action="wizard_lang_install"
|
||||
id="menu_wizard_lang_install"
|
||||
type="wizard"/>
|
||||
|
||||
<record model="ir.actions.wizard" id="wizard_scan_addons">
|
||||
<field name="name">Scan 'addons' path</field>
|
||||
<field name="wiz_name">module.module.scan</field>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Administration/Modules Management/Update modules list"
|
||||
action="wizard_scan_addons"
|
||||
id="menu_wizard_module_scan"
|
||||
type="wizard" />
|
||||
|
||||
<record model="ir.actions.wizard" id="wizard_lang_export">
|
||||
<field name="name">Export a language</field>
|
||||
<field name="wiz_name">module.lang.export</field>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Administration/Translations/Export a language"
|
||||
action="wizard_lang_export"
|
||||
id="menu_wizard_lang_export"
|
||||
type="wizard"/>
|
||||
|
||||
<record model="ir.actions.wizard" id="wizard_lang_import">
|
||||
<field name="name">Import a language</field>
|
||||
<field name="wiz_name">module.lang.import</field>
|
||||
</record>
|
||||
<menuitem
|
||||
name="Administration/Translations/Import a language"
|
||||
action="wizard_lang_import"
|
||||
id="menu_wizard_lang_import"
|
||||
type="wizard"/>
|
||||
|
||||
</data>
|
||||
</terp>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import ir_module_reference_print
|
|
@ -0,0 +1,173 @@
|
|||
<?xml version="1.0"?>
|
||||
<document filename="test.pdf">
|
||||
<template pageSize="(595.0,842.0)" title="Test" author="Martin Simon" allowSplitting="20">
|
||||
<pageTemplate id="first">
|
||||
<frame id="first" x1="42.0" y1="42.0" width="511" height="758"/>
|
||||
</pageTemplate>
|
||||
</template>
|
||||
<stylesheet>
|
||||
<blockTableStyle id="Standard_Outline">
|
||||
<blockAlignment value="LEFT"/>
|
||||
<blockValign value="TOP"/>
|
||||
</blockTableStyle>
|
||||
<blockTableStyle id="Table1">
|
||||
<blockAlignment value="LEFT"/>
|
||||
<blockValign value="TOP"/>
|
||||
<blockBackground colorName="#e6e6e6" start="0,0" stop="0,0"/>
|
||||
<blockBackground colorName="#e6e6e6" start="1,0" stop="1,0"/>
|
||||
<blockBackground colorName="#e6e6e6" start="2,0" stop="2,0"/>
|
||||
<blockBackground colorName="#e6e6e6" start="0,1" stop="0,1"/>
|
||||
<blockBackground colorName="#e6e6e6" start="1,1" stop="1,1"/>
|
||||
<blockBackground colorName="#e6e6e6" start="2,1" stop="2,1"/>
|
||||
</blockTableStyle>
|
||||
<blockTableStyle id="Tableau1">
|
||||
<blockAlignment value="LEFT"/>
|
||||
<blockValign value="TOP"/>
|
||||
<lineStyle kind="GRID" colorName="black"/>
|
||||
<blockBackground colorName="#ff6633" start="0,0" stop="0,0"/>
|
||||
</blockTableStyle>
|
||||
<blockTableStyle id="Tableau2">
|
||||
<blockAlignment value="LEFT"/>
|
||||
<blockValign value="TOP"/>
|
||||
<blockBackground colorName="#e6e6e6" start="0,0" stop="0,0"/>
|
||||
<blockBackground colorName="#e6e6e6" start="1,0" stop="1,0"/>
|
||||
<blockBackground colorName="#e6e6e6" start="0,1" stop="0,1"/>
|
||||
<blockBackground colorName="#e6e6e6" start="1,1" stop="1,1"/>
|
||||
</blockTableStyle>
|
||||
<blockTableStyle id="Tableau3">
|
||||
<blockAlignment value="LEFT"/>
|
||||
<blockValign value="TOP"/>
|
||||
<lineStyle kind="GRID" colorName="black"/>
|
||||
<blockBackground colorName="#ffcc99" start="0,0" stop="0,0"/>
|
||||
</blockTableStyle>
|
||||
<blockTableStyle id="Tableau4">
|
||||
<blockAlignment value="LEFT"/>
|
||||
<blockValign value="TOP"/>
|
||||
</blockTableStyle>
|
||||
<initialize>
|
||||
<paraStyle name="all" alignment="justify"/>
|
||||
</initialize>
|
||||
<paraStyle name="P1" fontName="Times-Roman" fontSize="20.0" leading="25" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="P2" fontName="Times-Roman" fontSize="10.0" leading="13" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="P3" fontName="Times-Roman" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="P4" fontName="Times-Roman" fontSize="11.0" leading="14" alignment="RIGHT" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="P5" fontName="Times-Roman" fontSize="16.0" leading="20" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="P6" fontName="Times-Roman"/>
|
||||
<paraStyle name="P7" fontName="Times-Roman" fontSize="15.0" leading="19" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="P8" fontName="Times-Roman" fontSize="11.0" leading="14" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="P9" fontName="Times-Roman" alignment="LEFT" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="Standard" fontName="Times-Roman"/>
|
||||
<paraStyle name="Text body" fontName="Times-Roman" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="Heading" fontName="Helvetica" fontSize="14.0" leading="17" spaceBefore="12.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="List" fontName="Times-Roman" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="Table Contents" fontName="Times-Roman" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="Table Heading" fontName="Times-Roman" alignment="CENTER" spaceBefore="0.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="Caption" fontName="Times-Roman" fontSize="12.0" leading="15" spaceBefore="6.0" spaceAfter="6.0"/>
|
||||
<paraStyle name="Index" fontName="Times-Roman"/>
|
||||
</stylesheet>
|
||||
<story>
|
||||
<para style="Standard">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<blockTable colWidths="139.0,220.0,152.0" repeatRows="1" style="Table1">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="Table Contents">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="P1">Reference Guide</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="P2">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<para style="Table Contents">[[ company.name ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="P3">Introspection report on objects</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="P4">Printed: [[ time.strftime('%y-%m-%d')]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
<para style="Standard">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<section>
|
||||
<para style="Text body">[[ repeatIn(objects, 'module') ]]</para>
|
||||
<blockTable colWidths="510.0" repeatRows="1" style="Tableau1">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="P5">Module: [[ module.name ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
<blockTable colWidths="276.0,234.0" repeatRows="1" style="Tableau2">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="Standard">Name: [[ module.shortdesc]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="Standard">Version: [[module.latest_version]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<para style="Standard">Directory: [[ module.name ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="Standard">Web: [[ module.website ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
<para style="P6">[[ module.description ]]</para>
|
||||
<section>
|
||||
<para style="Standard">[[ repeatIn(findobj(module.name) ,'object') ]]</para>
|
||||
<blockTable colWidths="510.0" repeatRows="1" style="Tableau3">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="P7">Object: [[ object.name ]]</para>
|
||||
<pre style="P8">[[ objdoc(object.model) ]]</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
<blockTable colWidths="113.0,397.0" repeatRows="1" style="Tableau4">
|
||||
<tr>
|
||||
<td>
|
||||
<para style="P9"><font face="Times-Roman">[[ repeatIn(findflds(object.model), 'field') ]]</font> [[ field[0] ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="Standard">
|
||||
<font face="Times-Roman">[[ field[1].get('string', 'Unknown') ]], [[ field[1]['type'] ]] [[field[1].get('required',False) and ', required']] [[field[1].get('readonly',False) and ', readonly']] </font>
|
||||
</para>
|
||||
<para style="Standard">[[ field[1].get('help', '') ]]</para>
|
||||
</td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
<para style="Standard">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
</section>
|
||||
<para style="Standard">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<para style="Standard">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
<para style="Standard">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
</section>
|
||||
<para style="Standard">
|
||||
<font color="white"> </font>
|
||||
</para>
|
||||
</story>
|
||||
</document>
|
||||
|
Binary file not shown.
|
@ -0,0 +1,60 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import time
|
||||
from report import report_sxw
|
||||
|
||||
class ir_module_reference_print(report_sxw.rml_parse):
|
||||
def __init__(self, cr, uid, name, context):
|
||||
super(ir_module_reference_print, self).__init__(cr, uid, name, context)
|
||||
self.localcontext.update({
|
||||
'time': time,
|
||||
'findobj': self._object_find,
|
||||
'objdoc': self._object_doc,
|
||||
'findflds': self._fields_find,
|
||||
})
|
||||
def _object_doc(self, obj):
|
||||
modobj = self.pool.get(obj)
|
||||
return modobj.__doc__
|
||||
|
||||
def _object_find(self, module):
|
||||
modobj = self.pool.get('ir.model')
|
||||
if module=='base':
|
||||
ids = modobj.search(self.cr, self.uid, [('model','=like','res%')])
|
||||
ids += modobj.search(self.cr, self.uid, [('model','=like','ir%')])
|
||||
else:
|
||||
ids = modobj.search(self.cr, self.uid, [('model','=like',module+'%')])
|
||||
return modobj.browse(self.cr, self.uid, ids)
|
||||
|
||||
def _fields_find(self, obj):
|
||||
modobj = self.pool.get(obj)
|
||||
res = modobj.fields_get(self.cr, self.uid).items()
|
||||
return res
|
||||
|
||||
report_sxw.report_sxw('report.ir.module.reference', 'ir.module.module', 'addons/base/module/report/ir_module_reference.rml', parser=ir_module_reference_print)
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard_install_module
|
||||
import wizard_update_module
|
||||
import wizard_module_upgrade
|
||||
import wizard_module_info_get
|
||||
import wizard_module_lang_install
|
||||
import add_new
|
||||
import wizard_export_lang
|
||||
import wizard_import_lang
|
|
@ -0,0 +1,100 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be)
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contact a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import os
|
||||
import re
|
||||
import glob
|
||||
import time
|
||||
import imp
|
||||
|
||||
import tools
|
||||
import wizard
|
||||
import pooler
|
||||
|
||||
module_name_re = re.compile('.*addons.(.*?).__terp__.py$')
|
||||
|
||||
_info_arch = '''<?xml version="1.0"?>
|
||||
<form string="Scan for new modules">
|
||||
<label string="This function will check if you installed new modules in the 'addons' path of your server installation." colspan="4" />
|
||||
</form>
|
||||
'''
|
||||
_info_fields = {}
|
||||
|
||||
def get_module_info(name):
|
||||
try:
|
||||
f = file(os.path.join(tools.config['addons_path'], name, '__terp__.py'), 'r')
|
||||
data = f.read()
|
||||
info = eval(data)
|
||||
f.close()
|
||||
except:
|
||||
return {}
|
||||
return info
|
||||
|
||||
class wizard_install_module(wizard.interface):
|
||||
def watch_dir(self, cr, uid, data, context):
|
||||
mod_obj = pooler.get_pool(cr.dbname).get('ir.module.module')
|
||||
all_mods = mod_obj.read(cr, uid, mod_obj.search(cr, uid, []), ['name', 'state'])
|
||||
known_modules = set([x['name'] for x in all_mods])
|
||||
ls_ad = glob.glob(os.path.join(tools.config['addons_path'], '*', '__terp__.py'))
|
||||
modules = set([module_name_re.match(name).group(1) for name in ls_ad])
|
||||
new_modules = modules - known_modules
|
||||
for module in new_modules:
|
||||
terp = get_module_info(module)
|
||||
if not terp.get('installable', True):
|
||||
continue
|
||||
imp.load_module(module, *imp.find_module(module))
|
||||
mod_id = mod_obj.create(cr, uid, {
|
||||
'name': module,
|
||||
'state': 'uninstalled',
|
||||
'description': terp.get('description', ''),
|
||||
'shortdesc': terp.get('name', ''),
|
||||
'author': terp.get('author', 'Unknown')})
|
||||
dependencies = terp.get('depends', [])
|
||||
for d in dependencies:
|
||||
cr.execute('insert into ir_module_module_dependency (module_id,name) values (%s, %s)', (mod_id, d))
|
||||
for module in known_modules:
|
||||
terp = get_module_info(module)
|
||||
if terp.get('installable', True):
|
||||
for mod in all_mods:
|
||||
if mod['name'] == module and mod['state'] == 'uninstallable':
|
||||
mod_obj.write(cr, uid, [mod['id']], {'state': 'uninstalled'})
|
||||
return {}
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [],
|
||||
'result': {'type':'form', 'arch': _info_arch, 'fields': _info_fields, 'state':[('end','Cancel','gtk-cancel'),('addmod','Check new modules','gtk-ok')]}
|
||||
},
|
||||
'addmod': {
|
||||
'actions': [watch_dir],
|
||||
'result': {'type':'state', 'state':'end'}
|
||||
},
|
||||
}
|
||||
wizard_install_module('module.module.scan')
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import tools
|
||||
import base64
|
||||
import StringIO
|
||||
import csv
|
||||
import pooler
|
||||
|
||||
view_form_init="""<?xml version="1.0"?>
|
||||
<form string="Export language">
|
||||
<image name="gtk-info" size="64" colspan="2"/>
|
||||
<group colspan="2" col="4">
|
||||
<separator string="Export translation file" colspan="4"/>
|
||||
<label align="0.0" string="Choose a language to export:" colspan="4"/>
|
||||
<field name="lang" colspan="4"/>
|
||||
</group>
|
||||
</form>"""
|
||||
|
||||
view_form_finish="""<?xml version="1.0"?>
|
||||
<form string="Export language">
|
||||
<image name="gtk-info" size="64" colspan="2"/>
|
||||
<group colspan="2" col="4">
|
||||
<separator string="Export done" colspan="4"/>
|
||||
<field name="data" readonly="1" colspan="3"/>
|
||||
<label align="0.0" string="Save this document to a .CSV file and open it with\n your favourite spreadsheet software. The file\n encoding is UTF-8. You have to translate the latest\n column before reimporting it." colspan="4"/>
|
||||
</group>
|
||||
</form>"""
|
||||
|
||||
class wizard_export_lang(wizard.interface):
|
||||
def _get_language(self, cr, uid, context):
|
||||
lang_obj=pooler.get_pool(cr.dbname).get('res.lang')
|
||||
ids=lang_obj.search(cr, uid, [('active', '=', True),])
|
||||
langs=lang_obj.browse(cr, uid, ids)
|
||||
return [(lang.code, lang.translatable and lang.name or 'New language') for lang in langs]
|
||||
|
||||
def _get_file(self, cr, uid, data, context):
|
||||
file=tools.trans_generate(data['form']['lang'], 'all')
|
||||
buf=StringIO.StringIO()
|
||||
writer=csv.writer(buf)
|
||||
for row in file:
|
||||
writer.writerow(row)
|
||||
del file
|
||||
out=base64.encodestring(buf.getvalue())
|
||||
buf.close()
|
||||
return {'data': out}
|
||||
|
||||
fields_form={
|
||||
'lang': {'string':'Language', 'type':'selection', 'selection':_get_language,},
|
||||
}
|
||||
fields_form_finish={
|
||||
'data': {'string':'File', 'type':'binary', 'readonly': True,},
|
||||
}
|
||||
states={
|
||||
'init':{
|
||||
'actions':[],
|
||||
'result':{'type':'form', 'arch':view_form_init, 'fields': fields_form, 'state':[('end', 'Cancel', 'gtk-cancel'),('finish', 'Ok', 'gtk-ok')]}
|
||||
},
|
||||
'finish':{
|
||||
'actions':[_get_file],
|
||||
'result':{'type':'form', 'arch':view_form_finish, 'fields': fields_form_finish, 'state':[('end', 'Close', 'gtk-cancel')]}
|
||||
},
|
||||
}
|
||||
wizard_export_lang('module.lang.export')
|
|
@ -0,0 +1,75 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import tools
|
||||
import base64
|
||||
import pooler
|
||||
|
||||
view_form="""<?xml version="1.0"?>
|
||||
<form string="Import language">
|
||||
<image name="gtk-info" size="64" colspan="2"/>
|
||||
<group colspan="2" col="4">
|
||||
<separator string="Import new language" colspan="4"/>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="data" colspan="3"/>
|
||||
<label string="You have to import a .CSV file wich is encoded in UTF-8.\nPlease check that the first line of your file is:" colspan="4" align="0.0"/>
|
||||
<label string="type,name,res_id,src,value" colspan="4"/>
|
||||
</group>
|
||||
</form>"""
|
||||
|
||||
class wizard_import_lang(wizard.interface):
|
||||
def _import_lang(self, cr, uid, data, context):
|
||||
form=data['form']
|
||||
lang_obj=pooler.get_pool(cr.dbname).get('res.lang')
|
||||
ids=lang_obj.search(cr, uid, [('code', '=', form['code'])])
|
||||
if ids:
|
||||
lang_obj.write(cr, uid, ids, {'name': form['name']})
|
||||
else:
|
||||
lang_obj.create(cr, uid, {'code': form['code'], 'name': form['name']})
|
||||
buf=base64.decodestring(data['form']['data']).split('\n')
|
||||
tools.trans_load_data(cr.dbname, buf, data['form']['code'])
|
||||
return {}
|
||||
fields_form={
|
||||
'name':{'string':'Language name', 'type':'char', 'size':64, 'required':True},
|
||||
'code':{'string':'Code (eg:en_US)', 'type':'char', 'size':5, 'required':True},
|
||||
'data':{'string':'File', 'type':'binary', 'required':True},
|
||||
}
|
||||
states={
|
||||
'init':{
|
||||
'actions':[],
|
||||
'result':{'type':'form', 'arch':view_form, 'fields':fields_form, 'state':[('end', 'Cancel', 'gtk-cancel'), ('finish', 'Ok', 'gtk-ok')]}
|
||||
},
|
||||
'finish':{
|
||||
'actions':[],
|
||||
'result':{'type':'action', 'action':_import_lang, 'state':'end'}
|
||||
},
|
||||
}
|
||||
wizard_import_lang('module.lang.import')
|
|
@ -0,0 +1,67 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import netsvc
|
||||
|
||||
#TODO: upgraded modules
|
||||
#TODO: removed modules
|
||||
additional_changes_form = '''<?xml version="1.0"?>
|
||||
<form string="Additional modules">
|
||||
<label string="The following additional modules need to be installed:"/>
|
||||
<newline/>
|
||||
<field name="additional"/>
|
||||
</form>'''
|
||||
|
||||
additional_changes_fields = {
|
||||
'additional': {'string':'Additional modules', 'type':'one2many', 'relation':'ir.module.module', 'readonly':True},
|
||||
}
|
||||
|
||||
class wizard_install_module(wizard.interface):
|
||||
def _get_value(self, cr, uid, data, context):
|
||||
service = netsvc.LocalService("object_proxy")
|
||||
extra = service.execute(cr.dbname, uid, 'ir.module.module', 'get_extra_modules', data['ids'])
|
||||
return {'additional': extra}
|
||||
|
||||
def _install_module(self, cr, uid, data, context):
|
||||
service = netsvc.LocalService("object_proxy")
|
||||
res = service.execute(cr.dbname, uid, 'ir.module.module', 'install', data['ids'])
|
||||
return {}
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [_get_value],
|
||||
'result': {'type':'form', 'arch':additional_changes_form, 'fields':additional_changes_fields, 'state':[('install','Install'), ('end','Cancel')]}
|
||||
},
|
||||
'install': {
|
||||
'actions': [_install_module],
|
||||
'result': {'type':'state', 'state':'end'}
|
||||
},
|
||||
}
|
||||
wizard_install_module('module.module.install')
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import netsvc
|
||||
|
||||
class wizard_info_get(wizard.interface):
|
||||
def _update_module(self, cr, uid, data, context):
|
||||
service = netsvc.LocalService("object_proxy")
|
||||
service.execute(cr.dbname, uid, 'ir.module.module', 'info_get', data['ids'])
|
||||
return {}
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [_update_module],
|
||||
'result': {'type':'state', 'state':'end'}
|
||||
},
|
||||
}
|
||||
wizard_info_get('module.info_get')
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import tools
|
||||
|
||||
view_form_end = """<?xml version="1.0"?>
|
||||
<form string="Language file loaded.">
|
||||
<image name="gtk-info" size="64" colspan="2"/>
|
||||
<group colspan="2" col="4">
|
||||
<separator string="Installation done" colspan="4"/>
|
||||
<label align="0.0" string="The selected language has been successfully installed.\nYou must change the preferences of the user and open a new menu to view changes." colspan="4"/>
|
||||
</group>
|
||||
</form>"""
|
||||
|
||||
view_form = """<?xml version="1.0"?>
|
||||
<form string="System Upgrade">
|
||||
<image name="gtk-info" size="64" colspan="2"/>
|
||||
<group colspan="2" col="4">
|
||||
<separator string="System Upgrade" colspan="4"/>
|
||||
<label align="0.0" string="Choose a language to install:" colspan="4"/>
|
||||
<field name="lang" colspan="4"/>
|
||||
<label align="0.0" string="Note that this operation may take a few minutes." colspan="4"/>
|
||||
</group>
|
||||
</form>"""
|
||||
|
||||
|
||||
class wizard_lang_install(wizard.interface):
|
||||
def _lang_install(self, cr, uid, data, context):
|
||||
print cr, uid, data, context
|
||||
|
||||
lang = data['form']['lang']
|
||||
if lang and lang != 'en_EN':
|
||||
filename = tools.config["root_path"] + "/i18n/" + lang + ".csv"
|
||||
tools.trans_load(cr.dbname, filename, lang)
|
||||
return {}
|
||||
|
||||
def _get_language(sel, cr, uid, context):
|
||||
return tools.scan_languages()
|
||||
|
||||
fields_form = {
|
||||
'lang': {'string':'Language', 'type':'selection', 'selection':_get_language,
|
||||
},
|
||||
}
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [],
|
||||
'result': {'type':'form', 'arch':view_form, 'fields': fields_form, 'state':[('end','Cancel','gtk-cancel'),('start','Start installation','gtk-ok')]}
|
||||
},
|
||||
'start': {
|
||||
'actions': [_lang_install],
|
||||
'result': {'type':'form', 'arch':view_form_end, 'fields': {}, 'state':[('end','Ok','gtk-ok')]}
|
||||
},
|
||||
}
|
||||
wizard_lang_install('module.lang.install')
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import pooler
|
||||
|
||||
view_form_end = """<?xml version="1.0"?>
|
||||
<form string="System upgrade done">
|
||||
<separator string="System upgrade done"/>
|
||||
<label align="0.0" string="The modules have been upgraded / installed !" colspan="4"/>
|
||||
<label align="0.0" string="You may have to reinstall some language pack." colspan="4"/>
|
||||
<label align="0.0" string="We suggest you to close all tabs and open a new menu window (Ctrl T)." colspan="4"/>
|
||||
</form>"""
|
||||
|
||||
view_form = """<?xml version="1.0"?>
|
||||
<form string="System Upgrade">
|
||||
<image name="gtk-info" size="64" colspan="2"/>
|
||||
<group colspan="2" col="4">
|
||||
<label align="0.0" string="Your system will be upgraded." colspan="4"/>
|
||||
<label align="0.0" string="Note that this operation my take a few minutes." colspan="4"/>
|
||||
<separator string="Modules to update"/>
|
||||
<field name="module_info" nolabel="1" colspan="4"/>
|
||||
</group>
|
||||
</form>"""
|
||||
|
||||
view_field = {
|
||||
"module_info": {'type':'text', 'string':'Modules', 'readonly':True}
|
||||
}
|
||||
|
||||
class wizard_info_get(wizard.interface):
|
||||
def _get_install(self, cr, uid, data, context):
|
||||
pool=pooler.get_pool(cr.dbname)
|
||||
ids = pool.get('ir.module.module').search(cr, uid, [
|
||||
('state','<>','uninstalled'),
|
||||
('state','<>','installed'),
|
||||
('state','<>','uninstallable')])
|
||||
res = pool.get('ir.module.module').read(cr, uid, ids, ['name','state'], context)
|
||||
return {'module_info':'\n'.join(map(lambda x: x['name']+' : '+x['state'], res))}
|
||||
|
||||
def _upgrade_module(self, cr, uid, data, context):
|
||||
(db, pool)=pooler.restart_pool(cr.dbname, update_module=True)
|
||||
return {}
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [_get_install],
|
||||
'result': {'type':'form', 'arch':view_form, 'fields': view_field, 'state':[('end','Cancel','gtk-cancel'),('start','Start Upgrade','gtk-ok')]}
|
||||
},
|
||||
'start': {
|
||||
'actions': [_upgrade_module],
|
||||
'result': {'type':'form', 'arch':view_form_end, 'fields': {}, 'state':[('end','Close','gtk-close')]}
|
||||
},
|
||||
}
|
||||
wizard_info_get('module.upgrade')
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
# -*- coding: iso-8859-1 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import netsvc
|
||||
|
||||
class wizard_update_module(wizard.interface):
|
||||
def _update_module(self, cr, uid, data, context):
|
||||
service = netsvc.LocalService("object_proxy")
|
||||
service.execute(cr.dbname, uid, 'ir.module.module', 'update_list')
|
||||
return {}
|
||||
|
||||
def _action_module_open(self, cr, uid, data, context):
|
||||
return {
|
||||
'domain': "[]",
|
||||
'name': 'Open Module List',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'res_model': 'ir.module.module',
|
||||
'view_id': False,
|
||||
'type': 'ir.actions.act_window'
|
||||
}
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [_update_module],
|
||||
'result': {'type':'state', 'state':'open_window'}
|
||||
},
|
||||
'open_window': {
|
||||
'actions': [],
|
||||
'result': {'type': 'action', 'action': _action_module_open, 'state':'end'}
|
||||
}
|
||||
}
|
||||
wizard_update_module('module.module.update')
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
|
||||
|
||||
<xsl:template match="/">
|
||||
<xsl:apply-templates select="report"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="report">
|
||||
<document filename="example_5.pdf">
|
||||
<template leftMargin="1.5cm" rightMargin="1.5cm" topMargin="1.5cm" bottomMargin="1.5cm" title="Reporting" author="Generated by Tiny ERP, Fabien Pinckaers">
|
||||
<xsl:attribute name="pageSize">
|
||||
<xsl:value-of select="/report/config/pageSize"/>
|
||||
</xsl:attribute>
|
||||
<pageTemplate id="first">
|
||||
<pageGraphics>
|
||||
<drawCentredString>
|
||||
<xsl:attribute name="x">
|
||||
<xsl:value-of select="/report/config/pageWidth div 2"/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="y">
|
||||
<xsl:value-of select="/report/config/pageHeight - 56.69"/>
|
||||
</xsl:attribute>
|
||||
<xsl:value-of select="config/report-header"/>
|
||||
</drawCentredString>
|
||||
|
||||
<fill color="(0.2,0.2,0.2)"/>
|
||||
<setFont name="Helvetica" size="10"/>
|
||||
<drawCentredString y="10mm">
|
||||
<xsl:attribute name="x">
|
||||
<xsl:value-of select="/report/config/pageWidth div 2"/>
|
||||
</xsl:attribute>
|
||||
<xsl:value-of select="config/report-footer"/>
|
||||
</drawCentredString>
|
||||
|
||||
<fill color="(0.969,0.2,0.2)"/>
|
||||
<setFont name="Helvetica" size="8"/>
|
||||
<drawString x="1.5cm">
|
||||
<xsl:attribute name="y">
|
||||
<xsl:value-of select="/report/config/pageHeight - 56.69"/>
|
||||
</xsl:attribute><xsl:text>Tiny ERP</xsl:text>
|
||||
</drawString>
|
||||
|
||||
<fill color="(0.2,0.2,0.2)"/>
|
||||
<drawRightString>
|
||||
<xsl:attribute name="x">
|
||||
<xsl:value-of select="/report/config/pageWidth - 45"/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="y">
|
||||
<xsl:value-of select="/report/config/pageHeight - 56.69"/>
|
||||
</xsl:attribute><xsl:value-of select="/report/config/date"/>
|
||||
</drawRightString>
|
||||
</pageGraphics>
|
||||
<frame id="column" x1="1.5cm" y1="1.5cm">
|
||||
<xsl:attribute name="width">
|
||||
<xsl:value-of select="/report/config/pageWidth - 85"/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="height">
|
||||
<xsl:value-of select="/report/config/pageHeight - 100"/>
|
||||
</xsl:attribute>
|
||||
</frame>
|
||||
</pageTemplate>
|
||||
</template>
|
||||
<stylesheet>
|
||||
<paraStyle name="sum" fontName="Helvetica" textColor="green"/>
|
||||
<paraStyle name="sum_float" fontName="Helvetica" alignment="right" textColor="green"/>
|
||||
<paraStyle name="sum_end" fontName="Helvetica" textColor="red"/>
|
||||
<paraStyle name="sum_float_end" fontName="Helvetica" alignment="right" textColor="red"/>
|
||||
<blockTableStyle id="table">
|
||||
<blockValign value="TOP"/>
|
||||
<blockFont name="Helvetica" size="12" start="0,0" stop="-1,0"/>
|
||||
<blockBackground colorName="(0.8,0.8,0.8)" start="0,0" stop="-1,0"/>
|
||||
|
||||
<lineStyle kind="GRID" colorName="lightgrey" thickness="0.3"/>
|
||||
|
||||
<lineStyle kind="LINEBELOW" colorName="black" thickness="1.5" start="0,0" stop="-1,0"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="black" thickness="1.5" start="0,0" stop="-1,0"/>
|
||||
</blockTableStyle>
|
||||
</stylesheet>
|
||||
<story>
|
||||
<blockTable style="table">
|
||||
<xsl:attribute name="colWidths">
|
||||
<xsl:value-of select="/report/config/tableSize"/>
|
||||
</xsl:attribute>
|
||||
<xsl:apply-templates select="header"/>
|
||||
<xsl:apply-templates select="group"/>
|
||||
|
||||
<xsl:if test="group//@sum">
|
||||
<tr>
|
||||
<xsl:for-each select="group[position()=1]/record[position()=1]/field">
|
||||
<xsl:choose>
|
||||
<xsl:when test="position()=1">
|
||||
<td><para style="sum_end">SUM</para></td>
|
||||
</xsl:when>
|
||||
<xsl:when test="@sum">
|
||||
<xsl:variable name="ici">
|
||||
<xsl:value-of select="@id"/>
|
||||
</xsl:variable>
|
||||
<td><para style="sum_float_end"><xsl:value-of select="sum(../../../group/record/field[@id=$ici])"/></para></td>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<td/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:for-each>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
<xsl:if test="group//@count">
|
||||
<tr>
|
||||
<xsl:for-each select="group[position()=1]/record[position()=1]/field">
|
||||
<xsl:choose>
|
||||
<xsl:when test="position()=1">
|
||||
<td><para style="sum_end">#</para></td>
|
||||
</xsl:when>
|
||||
<xsl:when test="@count">
|
||||
<xsl:variable name="ici">
|
||||
<xsl:value-of select="@id"/>
|
||||
</xsl:variable>
|
||||
<td><para style="sum_float_end"><xsl:value-of select="count(../../../group/record/field[@id=$ici])"/></para></td>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<td/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:for-each>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
<xsl:if test="group//@avg">
|
||||
<tr>
|
||||
<xsl:for-each select="group[position()=1]/record[position()=1]/field">
|
||||
<xsl:choose>
|
||||
<xsl:when test="position()=1">
|
||||
<td><para style="sum_end">AVG</para></td>
|
||||
</xsl:when>
|
||||
<xsl:when test="@avg">
|
||||
<xsl:variable name="ici">
|
||||
<xsl:value-of select="@id"/>
|
||||
</xsl:variable>
|
||||
<td><para style="sum_float_end"><xsl:value-of select="sum(../../../group/record/field[@id=$ici]) div count(../../../group/record/field[@id=$ici])"/></para></td>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<td/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:for-each>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
</blockTable>
|
||||
</story>
|
||||
</document>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="header">
|
||||
<tr>
|
||||
<xsl:apply-templates select="field"/>
|
||||
</tr>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="group">
|
||||
<xsl:if test="not(/report/config/totalonly)">
|
||||
<xsl:apply-templates select="record"/>
|
||||
</xsl:if>
|
||||
<xsl:if test="/report/config/groupby">
|
||||
<!-- SUM -->
|
||||
<xsl:if test="//@sum">
|
||||
<tr>
|
||||
<xsl:for-each select="record[position()=1]/field">
|
||||
<xsl:choose>
|
||||
<xsl:when test="/report/config/groupby = @id">
|
||||
<td><para style="sum"><xsl:value-of select="."/> (SUM)</para></td>
|
||||
</xsl:when>
|
||||
<xsl:when test="@sum">
|
||||
<xsl:variable name="ici">
|
||||
<xsl:value-of select="@id"/>
|
||||
</xsl:variable>
|
||||
<td><para style="sum_float"><xsl:value-of select="sum(../../record/field[@id=$ici])"/></para></td>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<td/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:for-each>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
<!-- COUNT -->
|
||||
<xsl:if test="//@count">
|
||||
<tr>
|
||||
<xsl:for-each select="record[position()=1]/field">
|
||||
<xsl:choose>
|
||||
<xsl:when test="/report/config/groupby = @id">
|
||||
<td><para style="sum"><xsl:value-of select="."/> (#)</para></td>
|
||||
</xsl:when>
|
||||
<xsl:when test="@count">
|
||||
<xsl:variable name="ici">
|
||||
<xsl:value-of select="@id"/>
|
||||
</xsl:variable>
|
||||
<td><para style="sum_float"><xsl:value-of select="count(../../record/field[@id=$ici])"/></para></td>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<td/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:for-each>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
<!-- AVG -->
|
||||
<xsl:if test="//@avg">
|
||||
<tr>
|
||||
<xsl:for-each select="record[position()=1]/field">
|
||||
<xsl:choose>
|
||||
<xsl:when test="/report/config/groupby = @id">
|
||||
<td><para style="sum"><xsl:value-of select="."/> (AVG)</para></td>
|
||||
</xsl:when>
|
||||
<xsl:when test="@avg">
|
||||
<xsl:variable name="ici">
|
||||
<xsl:value-of select="@id"/>
|
||||
</xsl:variable>
|
||||
<td><para style="sum_float"><xsl:value-of select="sum(../../record/field[@id=$ici]) div count(../../record/field[@id=$ici])"/></para></td>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<td/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:for-each>
|
||||
</tr>
|
||||
</xsl:if>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="record">
|
||||
<tr>
|
||||
<xsl:apply-templates select="field"/>
|
||||
</tr>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="field">
|
||||
<xsl:choose>
|
||||
<xsl:when test="@level">
|
||||
<td><pre><xsl:value-of select="@level"/><xsl:value-of select="."/></pre></td>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<td><para><xsl:value-of select="."/></para></td>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version = '1.0' encoding="utf-8"?>
|
||||
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
|
||||
<xsl:variable name="signature" select="//corporate-header/signature"/>
|
||||
<xsl:variable name="title">Tiny ERP Report</xsl:variable>
|
||||
<xsl:variable name="leftMargin">1cm</xsl:variable>
|
||||
<xsl:variable name="rightMargin">1cm</xsl:variable>
|
||||
<xsl:variable name="topMargin">1cm</xsl:variable>
|
||||
<xsl:variable name="bottomMargin">1cm</xsl:variable>
|
||||
<xsl:variable name="pageSize">21cm,29.7cm</xsl:variable>
|
||||
|
||||
<xsl:variable name="page_format">a4_letter</xsl:variable>
|
||||
|
||||
<xsl:template name="first_page_frames">
|
||||
<frame id="column" x1="1.5cm" y1="1.5cm">
|
||||
<xsl:attribute name="width">
|
||||
<xsl:value-of select="/report/config/PageWidth - 85"/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="height">
|
||||
<xsl:value-of select="/report/config/PageHeight - 100"/>
|
||||
</xsl:attribute>
|
||||
</frame>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="other_pages_frames">
|
||||
<frame id="column" x1="1.5cm" y1="1.5cm">
|
||||
<xsl:attribute name="width">
|
||||
<xsl:value-of select="/report/config/PageWidth - 85"/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="height">
|
||||
<xsl:value-of select="/report/config/PageHeight - 100"/>
|
||||
</xsl:attribute>
|
||||
</frame>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
|
@ -0,0 +1,127 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
|
||||
|
||||
<xsl:import href="../../base/report/custom_default.xsl"/>
|
||||
<xsl:import href="../../base/report/custom_rml.xsl"/>
|
||||
<xsl:template match="/">
|
||||
<xsl:call-template name="rml">
|
||||
<xsl:with-param name="pageSize" select="report/config/PageSize"/>
|
||||
<xsl:with-param name="page_format" select="report/config/PageFormat"/>
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
<!-- stylesheet -->
|
||||
|
||||
<xsl:template name="stylesheet">
|
||||
<paraStyle name="title" fontName="Helvetica-Bold" fontSize="22" alignment="center"/>
|
||||
|
||||
<blockTableStyle id="products">
|
||||
<blockBackground colorName="grey" start="0,0" stop="-1,0"/>
|
||||
<blockValign value="TOP"/>
|
||||
<blockAlignment value="RIGHT"/>
|
||||
<lineStyle kind="GRID" colorName="black"/>
|
||||
</blockTableStyle>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="story">
|
||||
<xsl:apply-templates select="report"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="report">
|
||||
<xsl:apply-templates select="config"/>
|
||||
<!--<setNextTemplate name="other_pages"/>-->
|
||||
<blockTable style="products">
|
||||
<xsl:if test="string-length(./config/tableSize)>1">
|
||||
<xsl:attribute name="colWidths">
|
||||
<xsl:value-of select="./config/tableSize"/>
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
|
||||
<xsl:apply-templates select="header"/>
|
||||
<xsl:apply-templates select="lines"/>
|
||||
</blockTable>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="config">
|
||||
<para style="title">
|
||||
<xsl:value-of select="report-header"/>
|
||||
</para>
|
||||
<spacer length="1cm" width="2mm"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="header">
|
||||
<tr>
|
||||
<xsl:for-each select="field">
|
||||
<td>
|
||||
<para>
|
||||
<xsl:value-of select="."/>
|
||||
</para>
|
||||
</td>
|
||||
</xsl:for-each>
|
||||
</tr>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="lines">
|
||||
<xsl:apply-templates select="row"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="row">
|
||||
<tr>
|
||||
<xsl:apply-templates select="col"/>
|
||||
</tr>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="col">
|
||||
<td>
|
||||
<xsl:choose>
|
||||
<xsl:when test="@para='yes'">
|
||||
<xsl:choose>
|
||||
<xsl:when test="@tree='yes'">
|
||||
<para>
|
||||
<xsl:attribute name="leftIndent"><xsl:value-of select="@space"/></xsl:attribute>
|
||||
<xsl:value-of select="."/>
|
||||
</para>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<para>
|
||||
<xsl:value-of select="."/>
|
||||
</para>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xpre>
|
||||
<xsl:value-of select="."/>
|
||||
</xpre>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</td>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<!-- <xsl:template match="col">
|
||||
<td>
|
||||
<xsl:if test="@tree='yes'">
|
||||
<xsl:choose>
|
||||
<xsl:when test="@para='yes'">
|
||||
<para>
|
||||
<xsl:attribute name="leftIndent"><xsl:value-of select="@space"/></xsl:attribute>
|
||||
<xsl:value-of select="."/>
|
||||
</para>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xpre>
|
||||
<xsl:value-of select="."/>
|
||||
</xpre>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:if>
|
||||
<xsl:if test="@tree!='yes'">
|
||||
<xpre>
|
||||
<xsl:value-of select="."/>
|
||||
</xpre>
|
||||
</xsl:if>
|
||||
</td>
|
||||
</xsl:template>
|
||||
-->
|
||||
</xsl:stylesheet>
|
|
@ -0,0 +1,62 @@
|
|||
<?xml version = '1.0' encoding="utf-8"?>
|
||||
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
|
||||
|
||||
<xsl:template name="first_page_graphics_report"/>
|
||||
<xsl:template name="other_pages_graphics_report"/>
|
||||
|
||||
<xsl:template name="rml">
|
||||
<document>
|
||||
<template author="Generated by Tiny ERP, Fabien Pinckaers">
|
||||
<xsl:attribute name="pageSize">
|
||||
<xsl:value-of select="$pageSize"/>
|
||||
</xsl:attribute>
|
||||
|
||||
<xsl:attribute name="leftMargin">
|
||||
<xsl:value-of select="$leftMargin"/>
|
||||
</xsl:attribute>
|
||||
|
||||
<xsl:attribute name="rightMargin">
|
||||
<xsl:value-of select="$rightMargin"/>
|
||||
</xsl:attribute>
|
||||
|
||||
<xsl:attribute name="topMargin">
|
||||
<xsl:value-of select="$topMargin"/>
|
||||
</xsl:attribute>
|
||||
|
||||
<xsl:attribute name="bottomMargin">
|
||||
<xsl:value-of select="$bottomMargin"/>
|
||||
</xsl:attribute>
|
||||
|
||||
<xsl:attribute name="title">
|
||||
<xsl:value-of select="$title"/>
|
||||
</xsl:attribute>
|
||||
|
||||
<pageTemplate id="first_page">
|
||||
<pageGraphics>
|
||||
<xsl:call-template name="first_page_graphics_report"/>
|
||||
</pageGraphics>
|
||||
|
||||
<xsl:call-template name="first_page_frames"/>
|
||||
</pageTemplate>
|
||||
|
||||
<pageTemplate id="other_pages">
|
||||
<pageGraphics>
|
||||
<xsl:call-template name="other_pages_graphics_report"/>
|
||||
</pageGraphics>
|
||||
|
||||
<xsl:call-template name="other_pages_frames"/>
|
||||
</pageTemplate>
|
||||
</template>
|
||||
|
||||
<stylesheet>
|
||||
<xsl:call-template name="stylesheet"/>
|
||||
</stylesheet>
|
||||
|
||||
<story>
|
||||
<xsl:call-template name="story"/>
|
||||
</story>
|
||||
|
||||
</document>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
|
@ -0,0 +1,70 @@
|
|||
<?xml version = '1.0' encoding="utf-8"?>
|
||||
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
|
||||
|
||||
<xsl:template name="first_page_graphics_report"/>
|
||||
<xsl:template name="other_pages_graphics_report"/>
|
||||
<!--
|
||||
<xsl:template name="first_page_graphics_corporation"/>
|
||||
<xsl:template name="other_pages_graphics_corporation"/>
|
||||
|
||||
<xsl:template name="first_page_frames"/>
|
||||
<xsl:template name="other_pages_frames"/>
|
||||
-->
|
||||
<xsl:template name="rml">
|
||||
<document>
|
||||
<template author="Generated by Tiny ERP, Fabien Pinckaers">
|
||||
<xsl:attribute name="pageSize">
|
||||
<xsl:value-of select="$pageSize"/>
|
||||
</xsl:attribute>
|
||||
|
||||
<xsl:attribute name="leftMargin">
|
||||
<xsl:value-of select="$leftMargin"/>
|
||||
</xsl:attribute>
|
||||
|
||||
<xsl:attribute name="rightMargin">
|
||||
<xsl:value-of select="$rightMargin"/>
|
||||
</xsl:attribute>
|
||||
|
||||
<xsl:attribute name="topMargin">
|
||||
<xsl:value-of select="$topMargin"/>
|
||||
</xsl:attribute>
|
||||
|
||||
<xsl:attribute name="bottomMargin">
|
||||
<xsl:value-of select="$bottomMargin"/>
|
||||
</xsl:attribute>
|
||||
|
||||
<xsl:attribute name="title">
|
||||
<xsl:value-of select="$title"/>
|
||||
</xsl:attribute>
|
||||
|
||||
<pageTemplate id="first_page">
|
||||
<pageGraphics>
|
||||
<xsl:call-template name="first_page_graphics_corporation"/>
|
||||
<xsl:call-template name="first_page_graphics_report"/>
|
||||
</pageGraphics>
|
||||
|
||||
<xsl:call-template name="first_page_frames"/>
|
||||
</pageTemplate>
|
||||
|
||||
<pageTemplate id="other_pages">
|
||||
<pageGraphics>
|
||||
<xsl:call-template name="other_pages_graphics_corporation"/>
|
||||
<xsl:call-template name="other_pages_graphics_report"/>
|
||||
</pageGraphics>
|
||||
|
||||
<xsl:call-template name="other_pages_frames"/>
|
||||
</pageTemplate>
|
||||
</template>
|
||||
|
||||
<stylesheet>
|
||||
<xsl:call-template name="stylesheet"/>
|
||||
</stylesheet>
|
||||
|
||||
<story>
|
||||
<xsl:call-template name="story"/>
|
||||
</story>
|
||||
|
||||
</document>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
|
@ -0,0 +1,38 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import tools
|
||||
|
||||
import partner
|
||||
import res_currency
|
||||
import res_company
|
||||
import res_user
|
||||
import res_request
|
||||
|
||||
|
||||
import ir_property
|
|
@ -0,0 +1,77 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv,fields
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Properties
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def _models_get2(self, cr, uid, context={}):
|
||||
obj = self.pool.get('ir.model.fields')
|
||||
ids = obj.search(cr, uid, [('view_load','=',1)])
|
||||
res = []
|
||||
done = {}
|
||||
for o in obj.browse(cr, uid, ids, context=context):
|
||||
if o.relation not in done:
|
||||
res.append( [o.relation, o.relation])
|
||||
done[o.relation] = True
|
||||
return res
|
||||
|
||||
def _models_get(self, cr, uid, context={}):
|
||||
obj = self.pool.get('ir.model.fields')
|
||||
ids = obj.search(cr, uid, [('view_load','=',1)])
|
||||
res = []
|
||||
done = {}
|
||||
for o in obj.browse(cr, uid, ids, context=context):
|
||||
if o.model_id.id not in done:
|
||||
res.append( [o.model_id.model, o.model_id.name])
|
||||
done[o.model_id.id] = True
|
||||
return res
|
||||
|
||||
class ir_property(osv.osv):
|
||||
_name = 'ir.property'
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=128),
|
||||
'value': fields.reference('Value', selection=_models_get2, size=128),
|
||||
'res_id': fields.reference('Resource', selection=_models_get, size=128),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
'fields_id': fields.many2one('ir.model.fields', 'Fields', ondelete='cascade', required=True)
|
||||
}
|
||||
def get(self, cr, uid, name, model, res_id=False, context={}):
|
||||
cr.execute('select id from ir_model_fields where name=%s and model=%s', (name, model))
|
||||
res = cr.fetchone()
|
||||
if res:
|
||||
nid = self.search(cr, uid, [('fields_id','=',res[0]),('res_id','=',res_id)])
|
||||
if nid:
|
||||
d = self.browse(cr, uid, nid[0], context).value
|
||||
return (d and int(d.split(',')[1])) or False
|
||||
return False
|
||||
ir_property()
|
||||
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data>
|
||||
==========================================================
|
||||
Properties
|
||||
==========================================================
|
||||
|
||||
<record model="ir.ui.view" id="ir_property_view">
|
||||
<field name="name">ir.property.form</field>
|
||||
<field name="model">ir.property</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Properties">
|
||||
<separator string="Property" colspan="4"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="company_id" select="1"/>
|
||||
<field name="fields_id" colspan="3" select="1"/>
|
||||
<field name="value" colspan="3"/>
|
||||
<field name="res_id" colspan="3"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="ir_property_form">
|
||||
<field name="name">ir.property</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.property</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="domain">[('res_id','=',False)]</field>
|
||||
<field name="view_id" ref="ir_property_view"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Properties/Default Properties" action="ir_property_form" id="menu_ir_property_form"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="ir_property_form_all">
|
||||
<field name="name">ir.property</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.property</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="ir_property_view"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Properties/All Properties" action="ir_property_form_all" id="menu_ir_property_form_all"/>
|
||||
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,37 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import tools
|
||||
|
||||
from partner import *
|
||||
from crm import *
|
||||
|
||||
import wizard
|
||||
import report
|
||||
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import time
|
||||
from osv import fields,osv
|
||||
|
||||
|
||||
#
|
||||
# Sale/Purchase Canal, Media
|
||||
#
|
||||
class res_partner_canal(osv.osv):
|
||||
_name = "res.partner.canal"
|
||||
_description = "Channels"
|
||||
_columns = {
|
||||
'name': fields.char('Channel Name',size=64, required=True),
|
||||
'active': fields.boolean('Active'),
|
||||
}
|
||||
_defaults = {
|
||||
'active': lambda *a: 1,
|
||||
}
|
||||
res_partner_canal()
|
||||
|
||||
#
|
||||
# Partner: State of Mind
|
||||
#
|
||||
class res_partner_som(osv.osv):
|
||||
_name = "res.partner.som"
|
||||
_columns = {
|
||||
'name': fields.char('State of Mind',size=64, required=True),
|
||||
'factor': fields.float('Factor', required=True)
|
||||
}
|
||||
res_partner_som()
|
||||
|
||||
def _links_get(self, cr, uid, context={}):
|
||||
obj = self.pool.get('res.request.link')
|
||||
ids = obj.search(cr, uid, [])
|
||||
res = obj.read(cr, uid, ids, ['object', 'name'], context)
|
||||
return [(r['object'], r['name']) for r in res]
|
||||
|
||||
class res_partner_event(osv.osv):
|
||||
_name = "res.partner.event"
|
||||
_columns = {
|
||||
'name': fields.char('Events',size=64, required=True),
|
||||
'som': fields.many2one('res.partner.som', 'State of Mind'),
|
||||
'description': fields.text('Description'),
|
||||
'planned_cost': fields.float('Planned Cost'),
|
||||
'planned_revenue': fields.float('Planned Revenue'),
|
||||
'probability': fields.float('Probability (0.50)'),
|
||||
'document': fields.reference('Document', selection=_links_get, size=128),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', select=True),
|
||||
'date': fields.datetime('Date', size=16),
|
||||
'user_id': fields.many2one('res.users', 'User'),
|
||||
'canal_id': fields.many2one('res.partner.canal', 'Channel'),
|
||||
'partner_type': fields.selection([('customer','Customer'),('retailer','Retailer'),('prospect','Commercial Prospect')], 'Partner Relation'),
|
||||
'type': fields.selection([('sale','Sale Opportunity'),('purchase','Purchase Offer'),('prospect','Prospect Contact')], 'Type of Event'),
|
||||
'event_ical_id': fields.char('iCal id', size=64),
|
||||
}
|
||||
_order = 'date desc'
|
||||
_defaults = {
|
||||
'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
}
|
||||
res_partner_event()
|
||||
|
||||
|
||||
class res_partner_event_type(osv.osv):
|
||||
_name = "res.partner.event.type"
|
||||
_description = "Partner Events"
|
||||
_columns = {
|
||||
'name': fields.char('Event Type',size=64, required=True),
|
||||
'key': fields.char('Key', size=64, required=True),
|
||||
'active': fields.boolean('Active'),
|
||||
}
|
||||
_defaults = {
|
||||
'active': lambda *a: 1
|
||||
}
|
||||
def check(self, cr, uid, key, context={}):
|
||||
return self.search(cr, uid, [('key','=',key)])
|
||||
res_partner_event_type()
|
||||
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data noupdate="1">
|
||||
<record model="res.partner.canal">
|
||||
<field name="name">website</field>
|
||||
</record>
|
||||
<record model="res.partner.canal">
|
||||
<field name="name">phone</field>
|
||||
</record>
|
||||
<record model="res.partner.canal">
|
||||
<field name="name">direct</field>
|
||||
</record>
|
||||
<record model="res.partner.canal">
|
||||
<field name="name">E-mail</field>
|
||||
</record>
|
||||
|
||||
<record model="res.partner.som">
|
||||
<field name="name">Fury</field>
|
||||
<field name="factor">1.0</field>
|
||||
</record>
|
||||
<record model="res.partner.som">
|
||||
<field name="name">Unhappy</field>
|
||||
<field name="factor">3.0</field>
|
||||
</record>
|
||||
<record model="res.partner.som">
|
||||
<field name="name">Normal</field>
|
||||
<field name="factor">5.0</field>
|
||||
</record>
|
||||
<record model="res.partner.som">
|
||||
<field name="name">Happy</field>
|
||||
<field name="factor">7.0</field>
|
||||
</record>
|
||||
<record model="res.partner.som">
|
||||
<field name="name">Very Happy</field>
|
||||
<field name="factor">8.5</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,116 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data>
|
||||
|
||||
<record model="ir.ui.view" id="res_partner_canal-view">
|
||||
<field name="name">res.partner.canal.form</field>
|
||||
<field name="model">res.partner.canal</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Channel">
|
||||
<field name="name" select="1"/>
|
||||
<field name="active" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="res_partner_canal-act">
|
||||
<field name="name">res.partner.canal.form</field>
|
||||
<field name="res_model">res.partner.canal</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem name="Partners/Configuration/Partner events/Channels" groups="admin" action="res_partner_canal-act"/>
|
||||
|
||||
<record model="ir.ui.view" id="res_partner_event_type-view">
|
||||
<field name="name">res.partner.event.type.form</field>
|
||||
<field name="model">res.partner.event.type</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Event Type">
|
||||
<field name="name" select="1"/>
|
||||
<field name="active" select="1"/>
|
||||
<field name="key" select="1" readonly="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="res_partner_event_type-act">
|
||||
<field name="name">res.partner.event.type.form</field>
|
||||
<field name="res_model">res.partner.event.type</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem name="Partners/Configuration/Partner events/Active partner events" groups="admin" action="res_partner_event_type-act"/>
|
||||
|
||||
<record model="ir.ui.view" id="res_partner_som_tree-view">
|
||||
<field name="name">res.partner.som.tree</field>
|
||||
<field name="model">res.partner.som</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Partner State of Mind">
|
||||
<field name="name"/>
|
||||
<field name="factor"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="res_partner_som-view">
|
||||
<field name="name">res.partner.som.form</field>
|
||||
<field name="model">res.partner.som</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Partner State of Mind">
|
||||
<field name="name" select="1"/>
|
||||
<field name="factor" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="res_partner_som-act">
|
||||
<field name="name">res.partner.som.form</field>
|
||||
<field name="res_model">res.partner.som</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem name="Partners/Configuration/Partner events/States of Mind" groups="admin" action="res_partner_som-act"/>
|
||||
|
||||
<record model="ir.ui.view" id="res_partner_event-wopartner-view_form">
|
||||
<field name="name">res.partner.event.form</field>
|
||||
<field name="model">res.partner.event</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Partner Events">
|
||||
<separator string="General Description" colspan="4"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="partner_type" select="1"/>
|
||||
<field name="som" select="1"/>
|
||||
<field name="date" select="1"/>
|
||||
<field name="canal_id" select="1"/>
|
||||
<field name="type" select="1"/>
|
||||
<field name="user_id" select="1"/>
|
||||
<field name="probability"/>
|
||||
<field name="planned_revenue"/>
|
||||
<field name="planned_cost"/>
|
||||
<separator string="Description" colspan="4"/>
|
||||
<field name="description" colspan="3"/>
|
||||
<separator string="Document Link" colspan="4"/>
|
||||
<field name="document" colspan="3"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="res_partner_event-wopartner-view_tree">
|
||||
<field name="name">res.partner.event.tree</field>
|
||||
<field name="model">res.partner.event</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Partner Events">
|
||||
<field name="date"/>
|
||||
<field name="name"/>
|
||||
<field name="som"/>
|
||||
<field name="type"/>
|
||||
<field name="partner_type"/>
|
||||
<field name="user_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,372 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# $Id: partner.py 1007 2005-07-25 13:18:09Z kayhman $
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import math
|
||||
|
||||
from osv import fields,osv
|
||||
import tools
|
||||
import ir
|
||||
import pooler
|
||||
|
||||
class res_partner_function(osv.osv):
|
||||
_name = 'res.partner.function'
|
||||
_description = 'Function of the contact'
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True),
|
||||
'code': fields.char('Code', size=8),
|
||||
}
|
||||
_order = 'name'
|
||||
res_partner_function()
|
||||
|
||||
class res_country(osv.osv):
|
||||
_name = 'res.country'
|
||||
_description = 'Country'
|
||||
_columns = {
|
||||
'name': fields.char('Country Name', size=64, help='The full name of the country.'),
|
||||
'code': fields.char('Country Code', size=2, help='The ISO country code in two chars. You can use this field for quick search.'),
|
||||
}
|
||||
_sql_constraints = [
|
||||
('name_uniq', 'unique (name)', 'The name of the country must be unique !'),
|
||||
('code_uniq', 'unique (code)', 'The code of the country must be unique !')
|
||||
]
|
||||
def name_search(self, cr, user, name, args=[], operator='ilike', context={}):
|
||||
ids = self.search(cr, user, [('code','=',name)]+ args)
|
||||
if not ids:
|
||||
ids = self.search(cr, user, [('name',operator,name)]+ args)
|
||||
return self.name_get(cr, user, ids)
|
||||
_order='code'
|
||||
res_country()
|
||||
|
||||
class res_country_state(osv.osv):
|
||||
_description="Country state"
|
||||
_name = 'res.country.state'
|
||||
_columns = {
|
||||
'country_id': fields.many2one('res.country', 'Country'),
|
||||
'name': fields.char('State Name', size=64),
|
||||
'code': fields.char('State Code', size=2),
|
||||
}
|
||||
_order = 'code'
|
||||
res_country_state()
|
||||
|
||||
class res_payterm(osv.osv):
|
||||
_description = 'Payment term'
|
||||
_name = 'res.payterm'
|
||||
_columns = {
|
||||
'name': fields.char('Payment term (short name)', size=64),
|
||||
}
|
||||
res_payterm()
|
||||
|
||||
class res_partner_category_type(osv.osv):
|
||||
_description='Partner category types'
|
||||
_name = 'res.partner.category.type'
|
||||
_columns = {
|
||||
'name': fields.char('Category Name', required=True, size=64),
|
||||
}
|
||||
_order = 'name'
|
||||
res_partner_category_type()
|
||||
|
||||
def _cat_type_get(self, cr, uid, context={}):
|
||||
obj = self.pool.get('res.partner.category.type')
|
||||
ids = obj.search(cr, uid, [])
|
||||
res = obj.read(cr, uid, ids, ['name'], context)
|
||||
return [(r['name'], r['name']) for r in res]
|
||||
|
||||
class res_partner_category(osv.osv):
|
||||
def name_get(self, cr, uid, ids, context={}):
|
||||
if not len(ids):
|
||||
return []
|
||||
reads = self.read(cr, uid, ids, ['name','parent_id'], context)
|
||||
res = []
|
||||
for record in reads:
|
||||
name = record['name']
|
||||
if record['parent_id']:
|
||||
name = record['parent_id'][1]+' / '+name
|
||||
res.append((record['id'], name))
|
||||
return res
|
||||
|
||||
def _name_get_fnc(self, cr, uid, ids, prop, unknow_none, unknow_dict):
|
||||
res = self.name_get(cr, uid, ids)
|
||||
return dict(res)
|
||||
def _check_recursion(self, cr, uid, ids):
|
||||
level = 100
|
||||
while len(ids):
|
||||
cr.execute('select distinct parent_id from res_partner_category where id in ('+','.join(map(str,ids))+')')
|
||||
ids = filter(None, map(lambda x:x[0], cr.fetchall()))
|
||||
if not level:
|
||||
return False
|
||||
level -= 1
|
||||
return True
|
||||
|
||||
_description='Partner Categories'
|
||||
_name = 'res.partner.category'
|
||||
_columns = {
|
||||
'name': fields.char('Category Name', required=True, size=64),
|
||||
'type_id': fields.many2one('res.partner.category.type', 'Category Type'),
|
||||
'parent_id': fields.many2one('res.partner.category', 'Parent Category', select=True),
|
||||
'complete_name': fields.function(_name_get_fnc, method=True, type="char", string='Name'),
|
||||
'child_ids': fields.one2many('res.partner.category', 'parent_id', 'Childs Category'),
|
||||
'active' : fields.boolean('Active'),
|
||||
}
|
||||
_constraints = [
|
||||
(_check_recursion, 'Error ! You can not create recursive categories.', ['parent_id'])
|
||||
]
|
||||
_defaults = {
|
||||
'active' : lambda *a: 1,
|
||||
}
|
||||
_order = 'parent_id,name'
|
||||
res_partner_category()
|
||||
|
||||
class res_partner_title(osv.osv):
|
||||
_name = 'res.partner.title'
|
||||
_columns = {
|
||||
'name': fields.char('Title', required=True, size=46, translate=True),
|
||||
'shortcut': fields.char('Shortcut', required=True, size=16),
|
||||
'domain': fields.selection([('partner','Partner'),('contact','Contact')], 'Domain', required=True, size=24)
|
||||
}
|
||||
_order = 'name'
|
||||
res_partner_title()
|
||||
|
||||
def _contact_title_get(self, cr, uid, context={}):
|
||||
obj = self.pool.get('res.partner.title')
|
||||
ids = obj.search(cr, uid, [('domain', '=', 'contact')])
|
||||
res = obj.read(cr, uid, ids, ['shortcut','name'], context)
|
||||
return [(r['shortcut'], r['name']) for r in res]
|
||||
|
||||
def _partner_title_get(self, cr, uid, context={}):
|
||||
obj = self.pool.get('res.partner.title')
|
||||
ids = obj.search(cr, uid, [('domain', '=', 'partner')])
|
||||
res = obj.read(cr, uid, ids, ['shortcut','name'], context)
|
||||
return [(r['shortcut'], r['name']) for r in res]
|
||||
|
||||
def _lang_get(self, cr, uid, context={}):
|
||||
obj = self.pool.get('res.lang')
|
||||
ids = obj.search(cr, uid, [])
|
||||
res = obj.read(cr, uid, ids, ['code', 'name'], context)
|
||||
res = [(r['code'], r['name']) for r in res]
|
||||
return res + [(False, '')]
|
||||
|
||||
class res_partner(osv.osv):
|
||||
_description='Partner'
|
||||
_name = "res.partner"
|
||||
_order = "name"
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=128, required=True, select=True),
|
||||
'date': fields.date('Date'),
|
||||
'title': fields.selection(_partner_title_get, 'Title', size=32),
|
||||
'parent_id': fields.many2one('res.partner','Main Company', select=True),
|
||||
'child_ids': fields.one2many('res.partner', 'parent_id', 'Partner Ref.'),
|
||||
'ref': fields.char('Code', size=64),
|
||||
'lang': fields.selection(_lang_get, 'Language', size=5),
|
||||
'user_id': fields.many2one('res.users', 'Salesman'),
|
||||
'responsible': fields.many2one('res.users', 'Users'),
|
||||
'vat': fields.char('VAT',size=32),
|
||||
'bank_ids': fields.one2many('res.partner.bank', 'partner_id', 'Banks'),
|
||||
'website': fields.char('Website',size=64),
|
||||
'comment': fields.text('Notes'),
|
||||
'address': fields.one2many('res.partner.address', 'partner_id', 'Contacts'),
|
||||
'category_id': fields.many2many('res.partner.category', 'res_partner_category_rel', 'partner_id', 'category_id', 'Categories'),
|
||||
'events': fields.one2many('res.partner.event', 'partner_id', 'events'),
|
||||
'credit_limit': fields.float(string='Credit Limit'),
|
||||
'ean13': fields.char('EAN13', size=13),
|
||||
'active': fields.boolean('Active'),
|
||||
}
|
||||
_defaults = {
|
||||
'active': lambda *a: 1,
|
||||
}
|
||||
_sql_constraints = [
|
||||
('name_uniq', 'unique (name)', 'The name of the partner must be unique !')
|
||||
]
|
||||
|
||||
def _check_ean_key(self, cr, uid, ids):
|
||||
for partner_o in pooler.get_pool(cr.dbname).get('res.partner').read(cr, uid, ids, ['ean13',]):
|
||||
thisean=partner_o['ean13']
|
||||
if thisean and thisean!='':
|
||||
if len(thisean)!=13:
|
||||
return False
|
||||
sum=0
|
||||
for i in range(12):
|
||||
if not (i % 2):
|
||||
sum+=int(thisean[i])
|
||||
else:
|
||||
sum+=3*int(thisean[i])
|
||||
if math.ceil(sum/10.0)*10-sum!=int(thisean[12]):
|
||||
return False
|
||||
return True
|
||||
|
||||
# _constraints = [(_check_ean_key, 'Error: Invalid ean code', ['ean13'])]
|
||||
|
||||
def name_get(self, cr, uid, ids, context={}):
|
||||
if not len(ids):
|
||||
return []
|
||||
if context.get('show_ref', False):
|
||||
rec_name = 'ref'
|
||||
else:
|
||||
rec_name = 'name'
|
||||
|
||||
res = [(r['id'], r[rec_name]) for r in self.read(cr, uid, ids, [rec_name], context)]
|
||||
return res
|
||||
|
||||
def name_search(self, cr, uid, name, args=[], operator='ilike', context={}, limit=80):
|
||||
if name:
|
||||
ids = self.search(cr, uid, [('ref', '=', name)] + args, limit=limit)
|
||||
if not ids:
|
||||
ids = self.search(cr, uid, [('name', operator, name)] + args, limit=limit)
|
||||
else:
|
||||
ids = self.search(cr, uid, args, limit=limit)
|
||||
return self.name_get(cr, uid, ids, context)
|
||||
|
||||
def _email_send(self, cr, uid, ids, email_from, subject, body, on_error=None):
|
||||
partners = self.browse(cr, uid, ids)
|
||||
for partner in partners:
|
||||
if len(partner.address):
|
||||
if partner.address[0].email:
|
||||
tools.email_send(email_from, [partner.address[0].email], subject, body, on_error)
|
||||
return True
|
||||
|
||||
def email_send(self, cr, uid, ids, email_from, subject, body, on_error=''):
|
||||
while len(ids):
|
||||
self.pool.get('ir.cron').create(cr, uid, {
|
||||
'name': 'Send Partner Emails',
|
||||
'user_id': uid,
|
||||
# 'nextcall': False,
|
||||
'model': 'res.partner',
|
||||
'function': '_email_send',
|
||||
'args': repr([ids[:16], email_from, subject, body, on_error])
|
||||
})
|
||||
ids = ids[16:]
|
||||
return True
|
||||
|
||||
def address_get(self, cr, uid, ids, adr_pref=['default']):
|
||||
cr.execute('select type,id from res_partner_address where partner_id in ('+','.join(map(str,ids))+')')
|
||||
res = cr.fetchall()
|
||||
adr = dict(res)
|
||||
# get the id of the (first) default address if there is one,
|
||||
# otherwise get the id of the first address in the list
|
||||
if res:
|
||||
default_address = adr.get('default', res[0][1])
|
||||
else:
|
||||
default_address = False
|
||||
result = {}
|
||||
for a in adr_pref:
|
||||
result[a] = adr.get(a, default_address)
|
||||
return result
|
||||
|
||||
def gen_next_ref(self, cr, uid, ids):
|
||||
if len(ids) != 1:
|
||||
return True
|
||||
|
||||
# compute the next number ref
|
||||
cr.execute("select ref from res_partner where ref is not null order by char_length(ref) desc, ref desc limit 1")
|
||||
res = cr.dictfetchall()
|
||||
ref = res and res[0]['ref'] or '0'
|
||||
try:
|
||||
nextref = int(ref)+1
|
||||
except e:
|
||||
raise osv.except_osv('Warning', "Couldn't generate the next id because some partners have an alphabetic id !")
|
||||
|
||||
# update the current partner
|
||||
cr.execute("update res_partner set ref=%d where id=%d", (nextref, ids[0]))
|
||||
return True
|
||||
res_partner()
|
||||
|
||||
class res_partner_bank(osv.osv):
|
||||
_description='Bank Details'
|
||||
_name = "res.partner.bank"
|
||||
_order = "sequence"
|
||||
_columns = {
|
||||
'name': fields.char('Account Name', size=64, required=True),
|
||||
'sequence': fields.integer('Sequence'),
|
||||
'iban': fields.char('Account number', size=64),
|
||||
'swift': fields.char('Swift', size=64),
|
||||
'bank_name': fields.char('Bank Name', size=64),
|
||||
'bank_guichet': fields.char('Branch', size=64),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', required=True, ondelete='cascade', select=True),
|
||||
'active': fields.boolean('Active'),
|
||||
}
|
||||
_defaults = {
|
||||
'active': lambda *a: 1,
|
||||
}
|
||||
res_partner_bank()
|
||||
|
||||
|
||||
class res_partner_address(osv.osv):
|
||||
_description ='Partner Contact'
|
||||
_name = 'res.partner.address'
|
||||
_order = 'id'
|
||||
_columns = {
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', required=True, ondelete='cascade', select=True),
|
||||
'type': fields.selection( [ ('default','Default'),('invoice','Invoice'), ('delivery','Delivery'), ('contact','Contact'), ('other','Other') ],'Address Type'),
|
||||
'function': fields.many2one('res.partner.function', 'Function', relate=True),
|
||||
'title': fields.selection(_contact_title_get, 'Title', size=32),
|
||||
'name': fields.char('Contact Name', size=64),
|
||||
'street': fields.char('Street', size=128),
|
||||
'street2': fields.char('Street2', size=128),
|
||||
'zip': fields.char('Zip', change_default=True, size=24),
|
||||
'city': fields.char('City', size=128),
|
||||
'state_id': fields.many2one("res.country.state", 'State', domain="[('country_id','=',country_id)]"),
|
||||
'country_id': fields.many2one('res.country', 'Country'),
|
||||
'email': fields.char('E-Mail', size=64),
|
||||
'phone': fields.char('Phone', size=64),
|
||||
'fax': fields.char('Fax', size=64),
|
||||
'mobile': fields.char('Mobile', size=64),
|
||||
'birthdate': fields.char('Birthdate', size=64),
|
||||
'active': fields.boolean('Active'),
|
||||
}
|
||||
_defaults = {
|
||||
'active': lambda *a: 1,
|
||||
}
|
||||
|
||||
def name_get(self, cr, user, ids, context={}):
|
||||
if not len(ids):
|
||||
return []
|
||||
res = []
|
||||
for r in self.read(cr, user, ids, ['name','zip','city','partner_id']):
|
||||
if context.get('contact_display', 'contact')=='partner':
|
||||
res.append((r['id'], r['partner_id'][1]))
|
||||
else:
|
||||
addr = str(r['name'] or '')
|
||||
if r['name'] and (r['zip'] or r['city']):
|
||||
addr += ', '
|
||||
addr += str(r['zip'] or '') + ' ' + str(r['city'] or '')
|
||||
res.append((r['id'], addr))
|
||||
return res
|
||||
|
||||
def name_search(self, cr, user, name, args=[], operator='ilike', context={}, limit=80):
|
||||
if context.get('contact_display', 'contact')=='partner':
|
||||
ids = self.search(cr, user, [('partner_id',operator,name)], limit=limit)
|
||||
else:
|
||||
ids = self.search(cr, user, [('zip','=',name)] + args, limit=limit)
|
||||
if not ids:
|
||||
ids = self.search(cr, user, [('city',operator,name)] + args, limit=limit)
|
||||
if not ids:
|
||||
ids = self.search(cr, user, [('name',operator,name)] + args, limit=limit)
|
||||
return self.name_get(cr, user, ids)
|
||||
res_partner_address()
|
||||
|
||||
# vim:noexpandtab:
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data>
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,288 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data noupdate="1">
|
||||
|
||||
#
|
||||
# Resource: res.partner.title
|
||||
#
|
||||
|
||||
<record id="res_partner_title_madam" model="res.partner.title">
|
||||
<field name="domain">contact</field>
|
||||
<field name="name">Madam</field>
|
||||
<field name="shortcut">Ms.</field>
|
||||
</record>
|
||||
<record id="res_partner_title_miss" model="res.partner.title">
|
||||
<field name="domain">contact</field>
|
||||
<field name="name">Miss</field>
|
||||
<field name="shortcut">Mss</field>
|
||||
</record>
|
||||
<record id="res_partner_title_sir" model="res.partner.title">
|
||||
<field name="domain">contact</field>
|
||||
<field name="name">Sir</field>
|
||||
<field name="shortcut">M.</field>
|
||||
</record>
|
||||
|
||||
|
||||
#
|
||||
# Resource: res.partner.category
|
||||
#
|
||||
|
||||
<record id="res_partner_category_0" model="res.partner.category">
|
||||
<field name="name">Customer</field>
|
||||
</record>
|
||||
<record id="res_partner_category_1" model="res.partner.category">
|
||||
<field name="name">Prospect</field>
|
||||
</record>
|
||||
<record id="res_partner_category_2" model="res.partner.category">
|
||||
<field name="name">Tiny ERP Partners</field>
|
||||
<field name="parent_id" ref="res_partner_category_0"/>
|
||||
</record>
|
||||
<record id="res_partner_category_3" model="res.partner.category">
|
||||
<field name="name">Starter Partner</field>
|
||||
<field name="parent_id" ref="res_partner_category_2"/>
|
||||
</record>
|
||||
<record id="res_partner_category_4" model="res.partner.category">
|
||||
<field name="name">Basic Partner</field>
|
||||
<field name="parent_id" ref="res_partner_category_2"/>
|
||||
</record>
|
||||
<record id="res_partner_category_5" model="res.partner.category">
|
||||
<field name="name">Gold Partner</field>
|
||||
<field name="parent_id" ref="res_partner_category_2"/>
|
||||
</record>
|
||||
<record id="res_partner_category_7" model="res.partner.category">
|
||||
<field name="name">Openstuff.net</field>
|
||||
<field name="parent_id" ref="res_partner_category_0"/>
|
||||
</record>
|
||||
<record id="res_partner_category_12" model="res.partner.category">
|
||||
<field name="name">Segmentation</field>
|
||||
<field name="parent_id" ref="res_partner_category_0"/>
|
||||
</record>
|
||||
<record id="res_partner_category_13" model="res.partner.category">
|
||||
<field name="name">Important customers</field>
|
||||
<field name="parent_id" ref="res_partner_category_12"/>
|
||||
</record>
|
||||
<record id="res_partner_category_14" model="res.partner.category">
|
||||
<field name="name">Bad customers</field>
|
||||
<field name="parent_id" ref="res_partner_category_12"/>
|
||||
</record>
|
||||
|
||||
<record id="res_partner_category_8" model="res.partner.category">
|
||||
<field name="name">Supplier</field>
|
||||
</record>
|
||||
<record id="res_partner_category_9" model="res.partner.category">
|
||||
<field name="name">Components Supplier</field>
|
||||
<field name="parent_id" ref="res_partner_category_8"/>
|
||||
</record>
|
||||
<record id="res_partner_category_10" model="res.partner.category">
|
||||
<field name="name">Open Source Service Company</field>
|
||||
<field name="parent_id" ref="res_partner_category_8"/>
|
||||
</record>
|
||||
<record id="res_partner_category_11" model="res.partner.category">
|
||||
<field name="name">Textile Suppliers</field>
|
||||
<field name="parent_id" ref="res_partner_category_8"/>
|
||||
</record>
|
||||
|
||||
|
||||
#
|
||||
# Resource: res.partner
|
||||
#
|
||||
|
||||
<record id="res_partner_asus" model="res.partner">
|
||||
<field name="name">ASUStek</field>
|
||||
</record>
|
||||
<record id="res_partner_agrolait" model="res.partner">
|
||||
<field name="name">Agrolait</field>
|
||||
</record>
|
||||
<record id="res_partner_2" model="res.partner">
|
||||
<field name="name">Bank Wealthy and sons</field>
|
||||
</record>
|
||||
<record id="res_partner_3" model="res.partner">
|
||||
<field name="lang">en</field>
|
||||
<field name="name">China Export</field>
|
||||
</record>
|
||||
<record id="res_partner_4" model="res.partner">
|
||||
<field name="name">Distrib PC</field>
|
||||
</record>
|
||||
<record id="res_partner_5" model="res.partner">
|
||||
<field name="name">Ecole de Commerce de Liege</field>
|
||||
</record>
|
||||
<record id="res_partner_6" model="res.partner">
|
||||
<field name="name">Elec Import</field>
|
||||
</record>
|
||||
<record id="res_partner_maxtor" model="res.partner">
|
||||
<field name="name">Maxtor</field>
|
||||
</record>
|
||||
<record id="res_partner_seagate" model="res.partner">
|
||||
<field name="name">Seagate</field>
|
||||
</record>
|
||||
<record id="res_partner_8" model="res.partner">
|
||||
<field name="website">http://mediapole.net</field>
|
||||
<field name="name">Mediapole SPRL</field>
|
||||
</record>
|
||||
<record id="res_partner_9" model="res.partner">
|
||||
<field name="website">http://opensides.be</field>
|
||||
<field name="name">Opensides sprl</field>
|
||||
<field name="ref">os</field>
|
||||
</record>
|
||||
<record id="res_partner_10" model="res.partner">
|
||||
<field name="name">Tecsas</field>
|
||||
<field name="ean13">3020170000003</field>
|
||||
</record>
|
||||
<record id="res_partner_11" model="res.partner">
|
||||
<field name="name">Leclerc</field>
|
||||
</record>
|
||||
<record id="res_partner_14" model="res.partner">
|
||||
<field name="name">Centrale d'achats BML</field>
|
||||
<field name="ean13">3020178572427</field>
|
||||
<field name="parent_id" ref="res_partner_10"/>
|
||||
</record>
|
||||
<record id="res_partner_15" model="res.partner">
|
||||
<field name="name">Magazin BML 1</field>
|
||||
<field name="ean13">3020178570171</field>
|
||||
<field name="parent_id" ref="res_partner_14"/>
|
||||
</record>
|
||||
|
||||
#
|
||||
# Resource: res.partner.address
|
||||
#
|
||||
|
||||
<record id="res_partner_address_1" model="res.partner.address">
|
||||
<field name="city">Bruxelles</field>
|
||||
<field name="name">Benoit Mortier</field>
|
||||
<field name="zip">1030</field>
|
||||
<field name="country_id" model="res.country" search="[('name','=','Belgium')]"/>
|
||||
<field name="email">info@opensides.be</field>
|
||||
<field name="phone">(+32)2 211 34 83</field>
|
||||
<field name="street">Rue des Palais 44, bte 33</field>
|
||||
<field name="type">default</field>
|
||||
<field name="partner_id" ref="res_partner_9"/>
|
||||
</record>
|
||||
<record id="res_partner_address_2" model="res.partner.address">
|
||||
<field name="city">Avignon CEDEX 09</field>
|
||||
<field name="name">Laurent Jacot</field>
|
||||
<field name="zip">84911</field>
|
||||
<field name="country_id" model="res.country" search="[('name','=','France')]"/>
|
||||
<field name="email">contact@tecsas.fr</field>
|
||||
<field name="phone">(+33)4.32.74.10.57</field>
|
||||
<field name="street">85 rue du traite de Rome</field>
|
||||
<field name="type">default</field>
|
||||
<field name="partner_id" ref="res_partner_10"/>
|
||||
</record>
|
||||
<record id="res_partner_address_3" model="res.partner.address">
|
||||
<field name="city">Louvain-la-Neuve</field>
|
||||
<field name="name">Thomas Passot</field>
|
||||
<field name="zip">1348</field>
|
||||
<field name="country_id" model="res.country" search="[('name','=','Belgium')]"/>
|
||||
<field name="email">info@mediapole.net</field>
|
||||
<field name="phone">(+32).10.45.17.73</field>
|
||||
<field name="street">Rue de l'Angelique, 1</field>
|
||||
<field name="partner_id" ref="res_partner_8"/>
|
||||
</record>
|
||||
<record id="res_partner_address_tang" model="res.partner.address">
|
||||
<field name="city">Taiwan</field>
|
||||
<field name="name">Tang</field>
|
||||
<field name="zip">23410</field>
|
||||
<field name="title">M.</field>
|
||||
<field name="country_id" model="res.country" search="[('name','=','Taiwan')]"/>
|
||||
<field name="street">31 Hong Kong street</field>
|
||||
<field name="type">default</field>
|
||||
<field name="partner_id" ref="res_partner_asus"/>
|
||||
</record>
|
||||
<record id="res_partner_address_wong" model="res.partner.address">
|
||||
<field name="city">Hong Kong</field>
|
||||
<field name="name">Wong</field>
|
||||
<field name="zip">23540</field>
|
||||
<field name="title">M.</field>
|
||||
<field name="country_id" model="res.country" search="[('name','=','China')]"/>
|
||||
<field name="street">56 Beijing street</field>
|
||||
<field name="type">default</field>
|
||||
<field name="partner_id" ref="res_partner_maxtor"/>
|
||||
</record>
|
||||
<record id="res_partner_address_6" model="res.partner.address">
|
||||
<field name="city">Bruxelles</field>
|
||||
<field name="name">Etienne Lacarte</field>
|
||||
<field name="zip">2365</field>
|
||||
<field name="title">M.</field>
|
||||
<field name="country_id" model="res.country" search="[('name','=','Belgium')]"/>
|
||||
<field name="street">23 rue du Vieux Bruges</field>
|
||||
<field name="type">default</field>
|
||||
<field name="partner_id" ref="res_partner_6"/>
|
||||
</record>
|
||||
<record id="res_partner_address_7" model="res.partner.address">
|
||||
<field name="city">Namur</field>
|
||||
<field name="name">Jean Guy Lavente</field>
|
||||
<field name="zip">2541</field>
|
||||
<field name="title">M.</field>
|
||||
<field name="country_id" model="res.country" search="[('name','=','Belgium')]"/>
|
||||
<field name="street">42 rue de la Lesse</field>
|
||||
<field name="type">default</field>
|
||||
<field name="partner_id" ref="res_partner_4"/>
|
||||
</record>
|
||||
<record id="res_partner_address_8" model="res.partner.address">
|
||||
<field name="city">Wavre</field>
|
||||
<field name="name">Sylvie Lelitre</field>
|
||||
<field name="zip">5478</field>
|
||||
<field name="title">Ms.</field>
|
||||
<field name="country_id" model="res.country" search="[('name','=','Belgium')]"/>
|
||||
<field name="street">69 rue de Chimay</field>
|
||||
<field name="type">default</field>
|
||||
<field name="partner_id" ref="res_partner_agrolait"/>
|
||||
</record>
|
||||
<record id="res_partner_address_9" model="res.partner.address">
|
||||
<field name="city">Paris</field>
|
||||
<field name="name">Arthur Grosbonnet</field>
|
||||
<field name="zip">75016</field>
|
||||
<field name="title">M.</field>
|
||||
<field name="country_id" model="res.country" search="[('name','=','France')]"/>
|
||||
<field name="street">1 rue Rockfeller</field>
|
||||
<field name="type">default</field>
|
||||
<field name="partner_id" ref="res_partner_2"/>
|
||||
</record>
|
||||
<record id="res_partner_address_10" model="res.partner.address">
|
||||
<field name="city">Liege</field>
|
||||
<field name="name">Karine Lesbrouffe</field>
|
||||
<field name="zip">6985</field>
|
||||
<field name="title">Mss</field>
|
||||
<field name="country_id" model="res.country" search="[('name','=','Belgium')]"/>
|
||||
<field name="street">2 Impasse de la Soif</field>
|
||||
<field name="type">default</field>
|
||||
<field name="partner_id" ref="res_partner_5"/>
|
||||
</record>
|
||||
<record id="res_partner_address_zen" model="res.partner.address">
|
||||
<field name="city">Shanghai</field>
|
||||
<field name="name">Zen</field>
|
||||
<field name="zip">4785552</field>
|
||||
<field name="title">M.</field>
|
||||
<field name="country_id" model="res.country" search="[('name','=','China')]"/>
|
||||
<field name="street">52 Chop Suey street</field>
|
||||
<field name="type">default</field>
|
||||
<field name="partner_id" ref="res_partner_3"/>
|
||||
</record>
|
||||
<record id="res_partner_address_12" model="res.partner.address">
|
||||
<field name="type">default</field>
|
||||
<field name="name">Centrale</field>
|
||||
<field name="partner_id" ref="res_partner_10"/>
|
||||
</record>
|
||||
<record id="res_partner_address_13" model="res.partner.address">
|
||||
<field name="type">default</field>
|
||||
<field name="name">Centrale d'achats 1</field>
|
||||
<field name="partner_id" ref="res_partner_14"/>
|
||||
</record>
|
||||
<record id="res_partner_address_14" model="res.partner.address">
|
||||
<field name="type">default</field>
|
||||
<field name="name">Shop 1</field>
|
||||
<field name="partner_id" ref="res_partner_15"/>
|
||||
</record>
|
||||
<record id="res_partner_address_15" model="res.partner.address">
|
||||
<field name="type">default</field>
|
||||
<field name="name">Shop 2</field>
|
||||
<field name="partner_id" ref="res_partner_11"/>
|
||||
</record>
|
||||
<record id="res_partner_address_16" model="res.partner.address">
|
||||
<field name="type">default</field>
|
||||
<field name="name">Shop 3</field>
|
||||
<field name="partner_id" ref="res_partner_11"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data>
|
||||
<report string="Labels" model="res.partner" name="res.partner.address" xml="base/res/partner/report/partner_address.xml" xsl="base/res/partner/report/partner_address.xsl"/>
|
||||
<!--
|
||||
<report string="Business Cards" model="res.partner" name="res.partner.businesscard" xml="base/res/partner/report/business_card.xml" xsl="base/res/partner/report/business_card.xsl"/>
|
||||
-->
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,504 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data>
|
||||
<menuitem name="Partners" sequence="0" icon="terp-partner" id="menu_base_partner"/>
|
||||
<menuitem name="Partners/Configuration" groups="admin"/>
|
||||
|
||||
<!--
|
||||
================================
|
||||
Function
|
||||
================================
|
||||
-->
|
||||
<record model="ir.ui.view" id="view_partner_function_form">
|
||||
<field name="name">res.partner.function.form</field>
|
||||
<field name="model">res.partner.function</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Partner Functions">
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_partner_function_form">
|
||||
<field name="name">res.partner.function.form</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.partner.function</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem name="Partners/Configuration/Functions" groups="admin" action="action_partner_function_form" id="menu_partner_function_form"/>
|
||||
|
||||
<!--
|
||||
================================
|
||||
Country
|
||||
================================
|
||||
-->
|
||||
<record model="ir.ui.view" id="view_country_tree">
|
||||
<field name="name">res.country.tree</field>
|
||||
<field name="model">res.country</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Country">
|
||||
<field name="name" />
|
||||
<field name="code"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_country_form">
|
||||
<field name="name">res.country.form</field>
|
||||
<field name="model">res.country</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Country">
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_country">
|
||||
<field name="name">res.country.form</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.country</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem name="Partners/Configuration/Localisation/Countries" groups="admin" action="action_country" id="menu_country"/>
|
||||
|
||||
<!--
|
||||
================================
|
||||
State
|
||||
================================
|
||||
-->
|
||||
<record model="ir.ui.view" id="view_country_state_tree">
|
||||
<field name="name">res.country.state.tree</field>
|
||||
<field name="model">res.country.state</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="State">
|
||||
<field name="country_id"/>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_country_state_form">
|
||||
<field name="name">res.country.state.form</field>
|
||||
<field name="model">res.country.state</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="State">
|
||||
<field name="country_id" select="1"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_country_state">
|
||||
<field name="name">res.country.state</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.country.state</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_country_state_form"/>
|
||||
</record>
|
||||
<menuitem name="Partners/Configuration/Localisation/States" groups="admin" action="action_country_state" id="menu_country_state"/>
|
||||
|
||||
<!--
|
||||
=====================
|
||||
Partner Address
|
||||
=====================
|
||||
-->
|
||||
<record model="ir.ui.view" id="view_partner_address_tree">
|
||||
<field name="name">res.partner.address.tree</field>
|
||||
<field name="model">res.partner.address</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Partner Contacts">
|
||||
<field name="partner_id" />
|
||||
<field name="name" />
|
||||
<field name="zip"/>
|
||||
<field name="city"/>
|
||||
<field name="country_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_partner_addess_tree">
|
||||
<field name="name">res.partner.address.tree</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.partner.address</field>
|
||||
<field name="view_type">tree</field>
|
||||
<field name="view_id" ref="view_partner_address_tree"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_partner_address_form1">
|
||||
<field name="name">res.partner.address.form1</field>
|
||||
<field name="model">res.partner.address</field>
|
||||
<field name="type">form</field>
|
||||
<field name="priority" eval="8"/>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Partner Contacts">
|
||||
<field name="partner_id" colspan="3" select="1"/>
|
||||
<newline/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="title" domain="[('domain', '=', 'contact')]"/>
|
||||
<field name="function"/>
|
||||
<field name="type" select="1"/>
|
||||
<field name="street" select="1"/>
|
||||
<field name="street2"/>
|
||||
<newline/>
|
||||
<field name="zip" select="1"/>
|
||||
<field name="city" select="1"/>
|
||||
<newline/>
|
||||
<field name="country_id" select="1"/>
|
||||
<field name="state_id" select="1"/>
|
||||
<newline/>
|
||||
<field name="phone" select="1"/>
|
||||
<field name="fax"/>
|
||||
<newline/>
|
||||
<field name="mobile" select="1"/>
|
||||
<field name="email" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_partner_address_form">
|
||||
<field name="name">res.partner.address</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.partner.address</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_partner_address_form1"/>
|
||||
</record>
|
||||
<menuitem name="Partners/Partner Contacts" action="action_partner_address_form" id="menu_partner_address_form"/>
|
||||
|
||||
<!--
|
||||
=========================================
|
||||
the short form used in the partner form
|
||||
=========================================
|
||||
-->
|
||||
<record model="ir.ui.view" id="view_partner_address_form2">
|
||||
<field name="name">res.partner.address.form2</field>
|
||||
<field name="model">res.partner.address</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Contacts">
|
||||
<field name="name" select="1"/>
|
||||
<field name="title" domain="[('domain', '=', 'contact')]"/>
|
||||
<field name="street"/>
|
||||
<field name="street2"/>
|
||||
<field name="type" select="1"/>
|
||||
<field name="function"/>
|
||||
<newline/>
|
||||
<field name="zip" select="1"/>
|
||||
<field name="city" select="1"/>
|
||||
<newline/>
|
||||
<field name="country_id" select="1"/>
|
||||
<field name="state_id" select="1"/>
|
||||
<newline/>
|
||||
<field name="phone"/>
|
||||
<field name="fax"/>
|
||||
<newline/>
|
||||
<field name="mobile"/>
|
||||
<field name="email"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
=======================
|
||||
Partner Titles
|
||||
=======================
|
||||
-->
|
||||
<record model="ir.ui.view" id="view_partner_title_form">
|
||||
<field name="name">res.partner.title.form</field>
|
||||
<field name="model">res.partner.title</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Partners Titles">
|
||||
<field name="name" select="1"/>
|
||||
<field name="shortcut" select="1"/>
|
||||
<field name="domain"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_partner_title">
|
||||
<field name="name">res.partner.title</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.partner.title</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem name="Partners/Configuration/Titles" groups="admin" action="action_partner_title" id="menu_partner_title"/>
|
||||
|
||||
<!--
|
||||
=======================
|
||||
Partner
|
||||
=======================
|
||||
-->
|
||||
<record model="ir.ui.view" id="view_partner_tree">
|
||||
<field name="name">res.partner.tree</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="8"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Partners">
|
||||
<field name="name"/>
|
||||
<field name="ref"/>
|
||||
<field name="address"/>
|
||||
<field name="lang"/>
|
||||
<field name="category_id"/>
|
||||
<field name="vat"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_partner_form">
|
||||
<field name="name">res.partner.form</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Partners">
|
||||
<notebook>
|
||||
<page string="General">
|
||||
<separator string="General Information" colspan="4"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="title" domain="[('domain', '=', 'partner')]"/>
|
||||
<field name="ref" select="1"/>
|
||||
<field name="lang" select="1"/>
|
||||
<newline/>
|
||||
<field name="address" mode="form,tree" colspan="4" nolabel="1" select="1">
|
||||
<form string="Partner Contacts">
|
||||
<field name="name" select="1"/>
|
||||
<field name="title" domain="[('domain', '=', 'contact')]"/>
|
||||
<field name="function"/>
|
||||
<field name="type" select="1"/>
|
||||
<field name="street" select="1"/>
|
||||
<field name="street2"/>
|
||||
<newline/>
|
||||
<field name="zip" select="1"/>
|
||||
<field name="city" select="1"/>
|
||||
<newline/>
|
||||
<field name="country_id" select="1" completion="1"/>
|
||||
<field name="state_id" select="1"/>
|
||||
<newline/>
|
||||
<field name="phone"/>
|
||||
<field name="fax"/>
|
||||
<newline/>
|
||||
<field name="mobile"/>
|
||||
<field name="email" select="1" widget="email" />
|
||||
</form>
|
||||
</field>
|
||||
<separator string="Categories" colspan="4"/>
|
||||
<field name="category_id" colspan="4" select="1" nolabel="1"/>
|
||||
</page>
|
||||
<page string="Extra Info">
|
||||
<field name="vat" select="1"/>
|
||||
<field name="active" select="1" />
|
||||
<field name="credit_limit" select="1"/>
|
||||
<field name="user_id" select="1"/>
|
||||
<field name="parent_id" select="1"/>
|
||||
<field name="website" widget="url"/>
|
||||
<field name="date" select="1"/>
|
||||
<field name="bank_ids" colspan="4" nolabel="1"/>
|
||||
<separator string="Notes" colspan="4"/>
|
||||
<field name="comment" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
<page string="Event History">
|
||||
<field name="events" colspan="4" nolabel="1" widget="one2many_list"/>
|
||||
</page>
|
||||
<page string="Properties">
|
||||
<properties/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_partner_form">
|
||||
<field name="name">res.partner</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.partner</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_partner_form"/>
|
||||
</record>
|
||||
<menuitem name="Partners/Partners" action="action_partner_form" id="menu_partner_form"/>
|
||||
|
||||
<record model="ir.ui.view" id="view_payterm_form">
|
||||
<field name="name">res.payterm</field>
|
||||
<field name="model">res.payterm</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payment term">
|
||||
<field name="name" colspan="4" />
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_payterm_form">
|
||||
<field name="name">res.payterm</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.payterm</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_payterm_form"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_partner_bank_form">
|
||||
<field name="name">res.partner.bank.form</field>
|
||||
<field name="model">res.partner.bank</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Bank Details">
|
||||
<field name="name" select="1" colspan="3"/>
|
||||
<field name="sequence"/>
|
||||
<field name="active" select="1"/>
|
||||
<field name="iban" select="1"/>
|
||||
<field name="swift" select="1"/>
|
||||
<field name="bank_name" select="1"/>
|
||||
<field name="bank_guichet" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_partner_bank_tree">
|
||||
<field name="name">res.partner.bank.tree</field>
|
||||
<field name="model">res.partner.bank</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Bank Details">
|
||||
<field name="sequence"/>
|
||||
<field name="name"/>
|
||||
<field name="iban"/>
|
||||
<field name="swift"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
======================
|
||||
Company Architecture
|
||||
======================
|
||||
-->
|
||||
<record model="ir.ui.view" id="view_partner_tree2">
|
||||
<field name="name">res.partner.tree</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="field_parent">child_ids</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Partners">
|
||||
<field name="name"/>
|
||||
<field name="lang"/>
|
||||
<field name="ref"/>
|
||||
<field name="vat"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action2">
|
||||
<field name="name">Company Architecture</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.partner</field>
|
||||
<field name="domain">[('id','in',active_ids)]</field>
|
||||
<field name="view_type">tree</field>
|
||||
<field name="view_id" ref="view_partner_tree2"/>
|
||||
</record>
|
||||
<record model="ir.values" id="ir_partner_structure">
|
||||
<field name="key2" eval="'client_action_multi'"/>
|
||||
<field name="model" eval="'res.partner'"/>
|
||||
<field name="name">Company Architecture</field>
|
||||
<field name="value" eval="'ir.actions.act_window,'+str(action2)"/>
|
||||
<field name="object" eval="True"/>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
======================
|
||||
Categories
|
||||
======================
|
||||
-->
|
||||
<record model="ir.ui.view" id="view_partner_category_form">
|
||||
<field name="name">res.partner.category.form</field>
|
||||
<field name="model">res.partner.category</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Partner Categories">
|
||||
<field name="name" select="1"/>
|
||||
<field name="active" select="1" />
|
||||
<field name="type_id" select="1" />
|
||||
<field name="parent_id"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_partner_category_list">
|
||||
<field name="name">res.partner.category.list</field>
|
||||
<field name="model">res.partner.category</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="6"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Partner Categories">
|
||||
<field name="complete_name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_partner_category_tree">
|
||||
<field name="name">res.partner.category.tree</field>
|
||||
<field name="model">res.partner.category</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="field_parent">child_ids</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Partner Categories">
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_partner_category">
|
||||
<field name="name">res.partner.category</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.partner.category</field>
|
||||
<field name="view_type">tree</field>
|
||||
<field name="view_id" ref="view_partner_category_tree"/>
|
||||
<field name="domain">[('parent_id','=',False)]</field>
|
||||
</record>
|
||||
<menuitem name="Partners/Configuration/Categories" action="action_partner_category" id="menu_partner_category"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_partner_category_form">
|
||||
<field name="name">res.partner.category</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.partner.category</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_partner_category_form"/>
|
||||
</record>
|
||||
<menuitem name="Partners/Configuration/Categories/Edit Categories" action="action_partner_category_form" id="menu_partner_category_form"/>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_partner_category_type_form">
|
||||
<field name="name">res.partner.category.type.form</field>
|
||||
<field name="model">res.partner.category.type</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Partner Type of Categories">
|
||||
<field name="name" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_partner_category_type_form">
|
||||
<field name="name">res.partner.category.type.form</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.partner.category.type</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem name="Partners/Configuration/Categories/Type of Categories" groups="admin" action="action_partner_category_type_form" id="menu_partner_category_type_form"/>
|
||||
|
||||
# Admin config
|
||||
|
||||
<menuitem name="Administration/Configuration/Partner" sequence="3"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="open_module_type_partenaire">
|
||||
<field name="name">res.partner.category</field>
|
||||
<field name="res_model">res.partner.category</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Administration/Configuration/Partner/Define Partners categories" action="open_module_type_partenaire" sequence="1" id="menu_type_partenaire"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="open_module_def_partenaire">
|
||||
<field name="name">res.partner</field>
|
||||
<field name="res_model">res.partner</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem name="Administration/Configuration/Partner/Define Partners" action="open_module_def_partenaire" sequence="2" id="menu_partenaire_def"/>
|
||||
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data>
|
||||
<wizard string="Send SMS" model="res.partner" name="res.partner.sms_send"/>
|
||||
<wizard string="Mass Mailing" model="res.partner" name="res.partner.spam_send"/>
|
||||
<!--
|
||||
<wizard string="Check EAN13" model="res.partner" name="res.partner.ean13"/>
|
||||
<wizard string="Clear IDs" model="res.partner" name="res.partner.clear_ids"/>
|
||||
-->
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,32 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
#from report import report_sxw
|
||||
#report_sxw.report_sxw('report.partner.list', 'res.partner', 'addons/base/res/partner/report/partner_list.rml')
|
||||
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<addresses>
|
||||
<address type="fields" name="id">
|
||||
<name type="field" name="name"/>
|
||||
<role type="field" name="title"/>
|
||||
<phone type="field" name="phone"/>
|
||||
<email type="field" name="email"/>
|
||||
<mobile type="field" name="mobile"/>
|
||||
<company>Tiny sprl</company>
|
||||
<street>Rue du Vieux Chateau, 21</street>
|
||||
<zip>BE-1457</zip>
|
||||
<city>Walhain</city>
|
||||
<website>http://tiny.be</website>
|
||||
</address>
|
||||
</addresses>
|
|
@ -0,0 +1,79 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
|
||||
|
||||
<xsl:variable name="initial_bottom_pos">20.5</xsl:variable>
|
||||
<xsl:variable name="initial_left_pos">0.5</xsl:variable>
|
||||
<xsl:variable name="height_increment">5.5</xsl:variable>
|
||||
<xsl:variable name="width_increment">8.5</xsl:variable>
|
||||
<xsl:variable name="frame_height">5.5cm</xsl:variable>
|
||||
<xsl:variable name="frame_width">8.5cm</xsl:variable>
|
||||
<xsl:variable name="number_columns">3</xsl:variable>
|
||||
<xsl:variable name="max_cards">8</xsl:variable>
|
||||
|
||||
<xsl:template match="/">
|
||||
<xsl:apply-templates select="addresses"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="addresses">
|
||||
<document>
|
||||
<template leftMargin="2.0cm" rightMargin="2.0cm" topMargin="2.0cm" bottomMargin="2.0cm" title="Address list" author="Generated by Tiny ERP, Fabien Pinckaers">
|
||||
<pageTemplate id="all">
|
||||
<pageGraphics/>
|
||||
<xsl:apply-templates select="address" mode="frames"/>
|
||||
</pageTemplate>
|
||||
</template>
|
||||
<stylesheet>
|
||||
<paraStyle name="nospace" fontName="Courier" fontSize="12" spaceBefore="0" spaceAfter="0"/>
|
||||
</stylesheet>
|
||||
<story>
|
||||
<xsl:apply-templates select="address" mode="story"/>
|
||||
</story>
|
||||
</document>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="address" mode="frames">
|
||||
<xsl:if test="position() < $max_frames + 1">
|
||||
<frame>
|
||||
<xsl:attribute name="width">
|
||||
<xsl:value-of select="$frame_width"/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="height">
|
||||
<xsl:value-of select="$frame_height"/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="x1">
|
||||
<xsl:value-of select="$initial_left_pos + ((position()-1) mod $number_columns) * $width_increment"/>
|
||||
<xsl:text>cm</xsl:text>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="y1">
|
||||
<xsl:value-of select="$initial_bottom_pos - floor((position()-1) div $number_columns) * $height_increment"/>
|
||||
<xsl:text>cm</xsl:text>
|
||||
</xsl:attribute>
|
||||
</frame>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="address" mode="story">
|
||||
|
||||
<drawCentredString x="105mm" y="28cm" t="1">PICKINGLIST</drawCentredString>
|
||||
<image x="5mm" y="5m" file="addons/base/report/logo-tiny.png"/>
|
||||
<blockTable colWidths="3cm,3cm" style="infos">
|
||||
<tr>
|
||||
<td>Logo</td>
|
||||
<td/>
|
||||
</tr><tr>
|
||||
<td><para><xsl:value-of select="client-id"/></para></td>
|
||||
<td><para><xsl:value-of select="shipping-id"/></para></td>
|
||||
<td><para><xsl:value-of select="picking-date"/></para></td>
|
||||
<td><para><xsl:value-of select="expedition-date"/></para></td>
|
||||
<td><para><xsl:value-of select="command-number"/></para></td>
|
||||
</tr>
|
||||
</blockTable>
|
||||
|
||||
<para style="nospace"><xsl:value-of select="company"/></para>
|
||||
<para style="nospace"><xsl:value-of select="partner_name"/></para>
|
||||
<para style="nospace"><xsl:value-of select="street"/></para>
|
||||
<para style="nospace"><xsl:value-of select="zip"/><xsl:text> </xsl:text><xsl:value-of select="city"/></para>
|
||||
<para style="nospace"><xsl:value-of select="country"/></para>
|
||||
<nextFrame/>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<addresses>
|
||||
<address type="fields" name="id">
|
||||
<company-title type="field" name="title"/>
|
||||
<company-name type="field" name="name"/>
|
||||
<contact type="zoom" name="address">
|
||||
<type type="field" name="type"/>
|
||||
<title type="field" name="title"/>
|
||||
<name type="field" name="name"/>
|
||||
<street type="field" name="street"/>
|
||||
<street2 type="field" name="street2"/>
|
||||
<zip type="field" name="zip"/>
|
||||
<city type="field" name="city"/>
|
||||
<state type="field" name="state_id.name"/>
|
||||
<country type="field" name="country_id.name"/>
|
||||
</contact>
|
||||
</address>
|
||||
</addresses>
|
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
|
||||
<xsl:variable name="initial_bottom_pos">20.5</xsl:variable>
|
||||
<xsl:variable name="initial_left_pos">1</xsl:variable>
|
||||
<xsl:variable name="height_increment">6.5</xsl:variable>
|
||||
<xsl:variable name="width_increment">10</xsl:variable>
|
||||
<xsl:variable name="frame_height">5.5cm</xsl:variable>
|
||||
<xsl:variable name="frame_width">10cm</xsl:variable>
|
||||
<xsl:variable name="number_columns">2</xsl:variable>
|
||||
<xsl:variable name="max_frames">8</xsl:variable>
|
||||
|
||||
<xsl:template match="/">
|
||||
<xsl:apply-templates select="addresses"/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="addresses">
|
||||
<document>
|
||||
<template leftMargin="2.0cm" rightMargin="2.0cm" topMargin="2.0cm" bottomMargin="2.0cm" title="Address list" author="Generated by Tiny ERP">
|
||||
<pageTemplate id="all">
|
||||
<pageGraphics/>
|
||||
<xsl:apply-templates select="address" mode="frames"/>
|
||||
</pageTemplate>
|
||||
</template>
|
||||
<stylesheet>
|
||||
<paraStyle name="nospace" fontName="Courier" fontSize="12" spaceBefore="0" spaceAfter="0"/>
|
||||
</stylesheet>
|
||||
<story>
|
||||
<xsl:apply-templates select="address" mode="story">
|
||||
<xsl:sort select="contact/country"/>
|
||||
<xsl:sort select="contact/zip"/>
|
||||
<xsl:sort select="company-name"/>
|
||||
</xsl:apply-templates>
|
||||
</story>
|
||||
</document>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="address" mode="frames">
|
||||
<xsl:if test="position() < $max_frames + 1">
|
||||
<frame>
|
||||
<xsl:attribute name="width">
|
||||
<xsl:value-of select="$frame_width"/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="height">
|
||||
<xsl:value-of select="$frame_height"/>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="x1">
|
||||
<xsl:value-of select="$initial_left_pos + ((position()-1) mod $number_columns) * $width_increment"/>
|
||||
<xsl:text>cm</xsl:text>
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="y1">
|
||||
<xsl:value-of select="$initial_bottom_pos - floor((position()-1) div $number_columns) * $height_increment"/>
|
||||
<xsl:text>cm</xsl:text>
|
||||
</xsl:attribute>
|
||||
</frame>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="address" mode="story">
|
||||
<para style="nospace"><xsl:value-of select="company-title"/><xsl:text> </xsl:text><xsl:value-of select="company-name"/></para>
|
||||
<xsl:choose>
|
||||
<xsl:when test="count(contact[type='default']) >= 1">
|
||||
<!-- apply the first 'contact' node with the type 'default' -->
|
||||
<xsl:apply-templates select="contact[type='default'][1]"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="count(contact[type='']) >= 1">
|
||||
<!-- apply the first 'contact' node with an empty type -->
|
||||
<xsl:apply-templates select="contact[type=''][1]"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<!-- apply the first 'contact' node -->
|
||||
<xsl:apply-templates select="contact[1]"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<nextFrame/>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="contact">
|
||||
<para style="nospace"><xsl:value-of select="title"/><xsl:text> </xsl:text><xsl:value-of select="name"/></para>
|
||||
<para style="nospace"><xsl:value-of select="street"/></para>
|
||||
<para style="nospace"><xsl:value-of select="street2"/></para>
|
||||
<para style="nospace"><xsl:value-of select="zip"/><xsl:text> </xsl:text><xsl:value-of select="city"/></para>
|
||||
<para style="nospace"><xsl:value-of select="state"/></para>
|
||||
<para style="nospace"><xsl:value-of select="country"/></para>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
|
@ -0,0 +1,32 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard_sms
|
||||
import wizard_spam
|
||||
import wizard_clear_ids
|
||||
import wizard_ean_check
|
|
@ -0,0 +1,45 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import netsvc
|
||||
|
||||
class wizard_clear_ids(wizard.interface):
|
||||
def _clear_ids(self, cr, uid, data, context):
|
||||
service = netsvc.LocalService("object_proxy")
|
||||
service.execute(cr.dbname, uid, 'res.partner', 'write', data['ids'], {'ref': False})
|
||||
return {}
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [_clear_ids],
|
||||
'result': {'type':'state', 'state':'end'}
|
||||
}
|
||||
}
|
||||
wizard_clear_ids('res.partner.clear_ids')
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import math
|
||||
from osv import osv
|
||||
from tools.misc import UpdateableStr
|
||||
import pooler
|
||||
|
||||
def _is_pair(x):
|
||||
return not x%2
|
||||
|
||||
def _get_ean_key(string):
|
||||
if not string or string=='':
|
||||
return '0'
|
||||
if len(string)!=12:
|
||||
return '0'
|
||||
sum=0
|
||||
for i in range(12):
|
||||
if _is_pair(i):
|
||||
sum+=int(string[i])
|
||||
else:
|
||||
sum+=3*int(string[i])
|
||||
return str(int(math.ceil(sum/10.0)*10-sum))
|
||||
|
||||
#FIXME: this is not concurrency safe !!!!
|
||||
_check_arch = UpdateableStr()
|
||||
_check_fields = {}
|
||||
|
||||
def _check_key(self, cr, uid, data, context):
|
||||
partner_table=pooler.get_pool(cr.dbname).get('res.partner')
|
||||
partners = partner_table.browse(cr, uid, data['ids'])
|
||||
_check_arch_lst=['<?xml version="1.0"?>', '<form string="Check EAN13">', '<label string=""/>', '<label string=""/>','<label string="Original" />', '<label string="Computed" />']
|
||||
for partner in partners:
|
||||
if partner['ean13'] and len(partner['ean13'])>11 and len(partner['ean13'])<14:
|
||||
_check_arch_lst.append('<label colspan="2" string="%s" />' % partner['ean13']);
|
||||
key=_get_ean_key(partner['ean13'][:12])
|
||||
_check_arch_lst.append('<label string=""/>')
|
||||
if len(partner['ean13'])==12:
|
||||
_check_arch_lst.append('<label string="" />');
|
||||
else:
|
||||
_check_arch_lst.append('<label string="%s" />' % partner['ean13'][12])
|
||||
_check_arch_lst.append('<label string="%s" />' % key)
|
||||
_check_arch_lst.append('</form>')
|
||||
_check_arch.string = '\n'.join(_check_arch_lst)
|
||||
return {}
|
||||
|
||||
def _update_ean(self, cr, uid, data, context):
|
||||
partner_table = pooler.get_pool(cr.dbname).get('res.partner')
|
||||
partners = partner_table.browse(cr, uid, data['ids'])
|
||||
for partner in partners:
|
||||
partner_table.write(cr, uid, data['ids'], {
|
||||
'ean13': "%s%s" % (partner['ean13'][:12], _get_ean_key(partner['ean13'][:12]))
|
||||
})
|
||||
return {}
|
||||
|
||||
class wiz_ean_check(wizard.interface):
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [_check_key],
|
||||
'result': {
|
||||
'type': 'form',
|
||||
'arch': _check_arch,
|
||||
'fields': _check_fields,
|
||||
'state': (('end', 'Ignore'), ('correct', 'Correct EAN13'))
|
||||
}
|
||||
},
|
||||
'correct' : {
|
||||
'actions': [_update_ean],
|
||||
'result': {
|
||||
'type': 'state',
|
||||
'state': 'end'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wiz_ean_check('res.partner.ean13')
|
|
@ -0,0 +1,75 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import netsvc
|
||||
|
||||
sms_send_form = '''<?xml version="1.0"?>
|
||||
<form string="%s">
|
||||
<separator string="%s" colspan="4"/>
|
||||
<field name="app_id"/>
|
||||
<newline/>
|
||||
<field name="user"/>
|
||||
<field name="password"/>
|
||||
<newline/>
|
||||
<field name="text" colspan="3"/>
|
||||
</form>''' % ('SMS - Gateway: clickatell','Bulk SMS send')
|
||||
|
||||
sms_send_fields = {
|
||||
'app_id': {'string':'API ID', 'type':'char', 'required':True},
|
||||
'user': {'string':'Login', 'type':'char', 'required':True},
|
||||
'password': {'string':'Password', 'type':'char', 'required':True},
|
||||
'text': {'string':'SMS Message', 'type':'text', 'required':True}
|
||||
}
|
||||
|
||||
def _sms_send(self, cr, uid, data, context):
|
||||
service = netsvc.LocalService("object_proxy")
|
||||
res = service.execute(cr.dbname, uid, 'res.partner', 'read', data['ids'], ['gsm'])
|
||||
|
||||
nbr = 0
|
||||
for r in res:
|
||||
to = r['gsm']
|
||||
if to:
|
||||
tools.smssend(data['form']['user'], data['form']['password'], data['form']['app_id'], unicode(data['form']['text'], 'utf-8').encode('latin1'), to)
|
||||
nbr += 1
|
||||
return {'sms_sent': nbr}
|
||||
|
||||
class part_sms(wizard.interface):
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [],
|
||||
'result': {'type': 'form', 'arch':sms_send_form, 'fields': sms_send_fields, 'state':[('end','Cancel'), ('send','Send SMS')]}
|
||||
},
|
||||
'send': {
|
||||
'actions': [_sms_send],
|
||||
'result': {'type': 'state', 'state':'end'}
|
||||
}
|
||||
}
|
||||
part_sms('res.partner.sms_send')
|
||||
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# $Id: wizard_spam.py 1005 2005-07-25 08:41:42Z nicoe $
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import pooler
|
||||
import tools
|
||||
|
||||
email_send_form = '''<?xml version="1.0"?>
|
||||
<form string="Mass Mailing">
|
||||
<field name="from"/>
|
||||
<newline/>
|
||||
<field name="subject"/>
|
||||
<newline/>
|
||||
<field name="text"/>
|
||||
</form>'''
|
||||
|
||||
email_send_fields = {
|
||||
'from': {'string':"Sender's email", 'type':'char', 'size':64, 'required':True},
|
||||
'subject': {'string':'Subject', 'type':'char', 'size':64, 'required':True},
|
||||
'text': {'string':'Message', 'type':'text', 'required':True}
|
||||
}
|
||||
|
||||
# this sends an email to ALL the addresses of the selected partners.
|
||||
def _mass_mail_send(self, cr, uid, data, context):
|
||||
nbr = 0
|
||||
partners = pooler.get_pool(cr.dbname).get('res.partner').browse(cr, uid, data['ids'], context)
|
||||
for partner in partners:
|
||||
for adr in partner.address:
|
||||
if adr.email:
|
||||
name = adr.name or partner.name
|
||||
to = '%s <%s>' % (name, adr.email)
|
||||
#TODO: add some tests to check for invalid email addresses
|
||||
#CHECKME: maybe we should use res.partner/email_send
|
||||
tools.email_send(data['form']['from'], [to], data['form']['subject'], data['form']['text'])
|
||||
nbr += 1
|
||||
pooler.get_pool(cr.dbname).get('res.partner.event').create(cr, uid,
|
||||
{'name': 'Email sent through mass mailing',
|
||||
'partner_id': partner.id,
|
||||
'description': data['form']['text'], })
|
||||
#TODO: log number of message sent
|
||||
return {'email_sent': nbr}
|
||||
|
||||
class part_email(wizard.interface):
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [],
|
||||
'result': {'type': 'form', 'arch': email_send_form, 'fields': email_send_fields, 'state':[('end','Cancel'), ('send','Send Email')]}
|
||||
},
|
||||
'send': {
|
||||
'actions': [_mass_mail_send],
|
||||
'result': {'type': 'state', 'state':'end'}
|
||||
}
|
||||
}
|
||||
part_email('res.partner.spam_send')
|
|
@ -0,0 +1,105 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields,osv
|
||||
import tools
|
||||
|
||||
class res_company(osv.osv):
|
||||
_name = "res.company"
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Company Name', size=64, required=True),
|
||||
'parent_id': fields.many2one('res.company', 'Parent Company', select=True),
|
||||
'child_ids': fields.one2many('res.company', 'parent_id', 'Childs Company'),
|
||||
'partner_id': fields.many2one('res.partner', 'Partner', required=True),
|
||||
'rml_header1': fields.char('Report Header', size=200),
|
||||
'rml_footer1': fields.char('Report Footer 1', size=200),
|
||||
'rml_footer2': fields.char('Report Footer 2', size=200),
|
||||
'currency_id': fields.many2one('res.currency', 'Currency', required=True),
|
||||
}
|
||||
|
||||
def _get_child_ids(self, cr, uid, uid2, context={}):
|
||||
company = self.pool.get('res.users').company_get(cr, uid, uid2)
|
||||
ids = self._get_company_children(cr, uid, company)
|
||||
return ids
|
||||
|
||||
def _get_company_children(self, cr, uid=None, company=None):
|
||||
if not company:
|
||||
return []
|
||||
ids = self.search(cr, uid, [('parent_id','child_of',[company])])
|
||||
return ids
|
||||
_get_company_children = tools.cache()(_get_company_children)
|
||||
|
||||
def _get_partner_hierarchy(self, cr, uid, company_id, context={}):
|
||||
print "Company ID is %s: Looking for parent..." % company_id
|
||||
if company_id:
|
||||
parent_id = self.browse(cr, uid, company_id)['parent_id']
|
||||
if parent_id:
|
||||
return self._get_partner_hierarchy(cr, uid, parent_id.id, context)
|
||||
else:
|
||||
print "No parent: starting descendance search!"
|
||||
return self._get_partner_descendance(cr, uid, company_id, [], context)
|
||||
return []
|
||||
|
||||
def _get_partner_descendance(self, cr, uid, company_id, descendance, context={}):
|
||||
descendance.append(self.browse(cr, uid, company_id).partner_id.id)
|
||||
for child_id in self._get_company_children(cr, uid, company_id):
|
||||
if child_id != company_id:
|
||||
print "Hello, I'm %s, child of %s" % (child_id, company_id)
|
||||
descendance = self._get_partner_descendance(cr, uid, child_id, descendance)
|
||||
return descendance
|
||||
|
||||
def __init__(self, *args, **argv):
|
||||
return super(res_company, self).__init__(*args, **argv)
|
||||
|
||||
#
|
||||
# This function restart the cache on the _get_company_children method
|
||||
#
|
||||
def cache_restart(self, uid=None):
|
||||
self._get_company_children()
|
||||
|
||||
def create(self, *args, **argv):
|
||||
self.cache_restart()
|
||||
return super(res_company, self).create(*args, **argv)
|
||||
|
||||
def write(self, *args, **argv):
|
||||
self.cache_restart()
|
||||
return super(res_company, self).write(*args, **argv)
|
||||
|
||||
def _get_euro(self, cr, uid, context={}):
|
||||
try:
|
||||
return self.pool.get('res.currency').search(cr, uid, [('rate', '=', 1.0),])[0]
|
||||
except:
|
||||
return 1
|
||||
|
||||
_defaults = {
|
||||
'currency_id': _get_euro,
|
||||
}
|
||||
|
||||
res_company()
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# $Id: account.py 1005 2005-07-25 08:41:42Z nicoe $
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
import time
|
||||
import netsvc
|
||||
from osv import fields, osv
|
||||
import ir
|
||||
|
||||
from tools.misc import currency
|
||||
|
||||
#from _common import rounding
|
||||
|
||||
import mx.DateTime
|
||||
from mx.DateTime import RelativeDateTime, now, DateTime, localtime
|
||||
|
||||
class res_currency(osv.osv):
|
||||
_name = "res.currency"
|
||||
_description = "Currency"
|
||||
_columns = {
|
||||
'name': fields.char('Currency', size=32, required=True),
|
||||
'code': fields.char('Code', size=3),
|
||||
'date': fields.date('Last rate update', readonly=True),
|
||||
'rate': fields.float('Relative Change rate',digits=(12,6)),
|
||||
#'digits': fields.integer('Displayed Digits'),
|
||||
'accuracy': fields.integer('Computational Accuracy'),
|
||||
'rounding': fields.float('Rounding factor'),
|
||||
'active': fields.boolean('Active'),
|
||||
}
|
||||
_defaults = {
|
||||
'date': lambda *a: time.strftime('%Y-%m-%d'),
|
||||
'active': lambda *a: 1,
|
||||
}
|
||||
_order = "code"
|
||||
|
||||
def compute(self, cr, uid, from_currency_id, to_currency_id, from_amount):
|
||||
if to_currency_id==from_currency_id:
|
||||
return from_amount
|
||||
[from_currency]=self.read(cr, uid, [from_currency_id])
|
||||
[to_currency] = self.read(cr, uid, [to_currency_id])
|
||||
return currency(from_amount * from_currency['rate']/to_currency['rate'], to_currency['accuracy'], to_currency['rounding'])
|
||||
|
||||
|
||||
res_currency()
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data>
|
||||
|
||||
#---------------------------------------------------------
|
||||
# Currencies
|
||||
#---------------------------------------------------------
|
||||
<record model="ir.ui.view" id="view_currency_tree">
|
||||
<field name="name">res.currency.tree</field>
|
||||
<field name="model">res.currency</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Currencies">
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="rate"/>
|
||||
<field name="date"/>
|
||||
<field name="rounding"/>
|
||||
<field name="accuracy"/>
|
||||
<field name="active" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_currency_form">
|
||||
<field name="name">res.currency.form</field>
|
||||
<field name="model">res.currency</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Currency">
|
||||
<field name="name" select="1" colspan="3"/>
|
||||
<field name="code" select="1"/>
|
||||
<field name="active" select="1"/>
|
||||
<field name="rate"/>
|
||||
<field name="date" select="1"/>
|
||||
<field name="rounding"/>
|
||||
<field name="accuracy"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_currency_form">
|
||||
<field name="name">res.currency</field>
|
||||
<field name="res_model">res.currency</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem name="Partners/Configuration/Localisation/Currencies" action="action_currency_form" sequence="11"/>
|
||||
|
||||
<menuitem name="Administration/Configuration/Base/Define Currencies" action="action_currency_form" sequence="1" id="menu_currency_def"/>
|
||||
|
||||
</data>
|
||||
</terp>
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv, fields
|
||||
import time
|
||||
|
||||
def _links_get(self, cr, uid, context={}):
|
||||
obj = self.pool.get('res.request.link')
|
||||
ids = obj.search(cr, uid, [])
|
||||
res = obj.read(cr, uid, ids, ['object', 'name'], context)
|
||||
return [(r['object'], r['name']) for r in res]
|
||||
|
||||
class res_request(osv.osv):
|
||||
_name = 'res.request'
|
||||
|
||||
def request_send(self, cr, uid, ids, *args):
|
||||
for id in ids:
|
||||
cr.execute('update res_request set state=%s,date_sent=%s where id=%d', ('waiting', time.strftime('%Y-%m-%d %H:%M:%S'), id))
|
||||
cr.execute('select act_from,act_to,body,date_sent from res_request where id=%d', (id,))
|
||||
values = cr.dictfetchone()
|
||||
# this will be truncated automatically at creation
|
||||
values['name'] = values['body'] or '/'
|
||||
values['req_id'] = id
|
||||
self.pool.get('res.request.history').create(cr, uid, values)
|
||||
return True
|
||||
|
||||
def request_reply(self, cr, uid, ids, *args):
|
||||
for id in ids:
|
||||
cr.execute("update res_request set state='active', act_from=%d, act_to=act_from, trigger_date=NULL, body='' where id=%d", (uid,id))
|
||||
return True
|
||||
|
||||
def request_close(self, cr, uid, ids, *args):
|
||||
self.write(cr, uid, ids, {'state':'closed', 'active':False})
|
||||
return True
|
||||
|
||||
def request_get(self, cr, uid):
|
||||
cr.execute('select id from res_request where act_to=%d and (trigger_date<=%s or trigger_date is null) and active=True', (uid,time.strftime('%Y-%m-%d')))
|
||||
ids = map(lambda x:x[0], cr.fetchall())
|
||||
cr.execute('select id from res_request where act_from=%d and (act_to<>%d) and (trigger_date<=%s or trigger_date is null) and active=True', (uid,uid,time.strftime('%Y-%m-%d')))
|
||||
ids2 = map(lambda x:x[0], cr.fetchall())
|
||||
return (ids, ids2)
|
||||
|
||||
_columns = {
|
||||
'create_date': fields.datetime('Created date', readonly=True),
|
||||
'name': fields.char('Subject', states={'waiting':[('readonly',True)],'active':[('readonly',True)],'closed':[('readonly',True)]}, required=True, size=128),
|
||||
'active': fields.boolean('Active'),
|
||||
'priority': fields.selection([('0','Low'),('1','Normal'),('2','High')], 'Priority', states={'waiting':[('readonly',True)],'closed':[('readonly',True)]}, required=True),
|
||||
'act_from': fields.many2one('res.users', 'From', required=True, readonly=True, states={'closed':[('readonly',True)]}),
|
||||
'act_to': fields.many2one('res.users', 'To', required=True, states={'waiting':[('readonly',True)],'closed':[('readonly',True)]}),
|
||||
'body': fields.text('Request', states={'waiting':[('readonly',True)],'closed':[('readonly',True)]}),
|
||||
'date_sent': fields.datetime('Date', readonly=True),
|
||||
'trigger_date': fields.datetime('Trigger Date', states={'waiting':[('readonly',True)],'closed':[('readonly',True)]}),
|
||||
'ref_partner_id':fields.many2one('res.partner', 'Partner Ref.', states={'closed':[('readonly',True)]}),
|
||||
'ref_doc1':fields.reference('Document Ref 1', selection=_links_get, size=128, states={'closed':[('readonly',True)]}),
|
||||
'ref_doc2':fields.reference('Document Ref 2', selection=_links_get, size=128, states={'closed':[('readonly',True)]}),
|
||||
'state': fields.selection([('draft','draft'),('waiting','waiting'),('active','active'),('closed','closed')], 'State', required=True, readonly=True),
|
||||
'history': fields.one2many('res.request.history','req_id', 'History')
|
||||
}
|
||||
_defaults = {
|
||||
'act_from': lambda obj,cr,uid,context={}: uid,
|
||||
'act_to': lambda obj,cr,uid,context={}: uid,
|
||||
'state': lambda obj,cr,uid,context={}: 'draft',
|
||||
'active': lambda obj,cr,uid,context={}: True,
|
||||
'priority': lambda obj,cr,uid,context={}: '1',
|
||||
}
|
||||
_order = 'priority desc, trigger_date, create_date desc'
|
||||
_table = 'res_request'
|
||||
res_request()
|
||||
|
||||
class res_request_link(osv.osv):
|
||||
_name = 'res.request.link'
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True, translate=True),
|
||||
'object': fields.char('Object', size=64, required=True),
|
||||
'priority': fields.integer('Priority'),
|
||||
}
|
||||
_defaults = {
|
||||
'priority': lambda *a: 5,
|
||||
}
|
||||
_order = 'priority'
|
||||
res_request_link()
|
||||
|
||||
class res_request_history(osv.osv):
|
||||
_name = 'res.request.history'
|
||||
_columns = {
|
||||
'name': fields.char('Summary', size=128, states={'active':[('readonly',True)],'waiting':[('readonly',True)]}, required=True),
|
||||
'req_id': fields.many2one('res.request', 'Request', required=True, ondelete='cascade', select=True),
|
||||
'act_from': fields.many2one('res.users', 'From', required=True, readonly=True),
|
||||
'act_to': fields.many2one('res.users', 'To', required=True, states={'waiting':[('readonly',True)]}),
|
||||
'body': fields.text('Body', states={'waiting':[('readonly',True)]}),
|
||||
'date_sent': fields.datetime('Date sent', states={'waiting':[('readonly',True)]}, required=True)
|
||||
}
|
||||
_defaults = {
|
||||
'name': lambda *a: 'NoName',
|
||||
'act_from': lambda obj,cr,uid,context={}: uid,
|
||||
'act_to': lambda obj,cr,uid,context={}: uid,
|
||||
'date_sent': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
}
|
||||
res_request_history()
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="res_request_tree-view">
|
||||
<field name="name">res.request.tree</field>
|
||||
<field name="model">res.request</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Requests">
|
||||
<field name="create_date" />
|
||||
<field name="act_from"/>
|
||||
<field name="act_to"/>
|
||||
<field name="name"/>
|
||||
<!--
|
||||
<field name="act_title"/>
|
||||
-->
|
||||
<field name="priority"/>
|
||||
<field name="trigger_date"/>
|
||||
<!--
|
||||
<field name="ref_partner_id"/>
|
||||
-->
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="res_request-view">
|
||||
<field name="name">res.request.form</field>
|
||||
<field name="model">res.request</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Requests">
|
||||
<notebook>
|
||||
<page string="Request">
|
||||
<separator string="Description" colspan="4"/>
|
||||
<field name="act_from" select="1"/>
|
||||
<field name="act_to" select="1"/>
|
||||
<field name="name" colspan="3" select="1"/>
|
||||
<newline/>
|
||||
<field name="body" colspan="4" select="1"/>
|
||||
<field name="trigger_date" select="1"/>
|
||||
<group col="2" colspan="2">
|
||||
<button name="request_send" states="draft,active" string="Send" type="object"/>
|
||||
<button name="request_reply" states="waiting" string="Reply" type="object"/>
|
||||
</group>
|
||||
|
||||
<separator string="References" colspan="4"/>
|
||||
<field name="ref_partner_id"/>
|
||||
<field name="priority" select="1"/>
|
||||
<field name="ref_doc1" colspan="3"/>
|
||||
<field name="ref_doc2" colspan="3"/>
|
||||
<separator string="Status" colspan="4"/>
|
||||
<field name="state"/>
|
||||
<group col="3" colspan="2">
|
||||
<field name="active" select="1"/>
|
||||
<button name="request_close" states="waiting,draft,active" string="End of Request" type="object"/>
|
||||
</group>
|
||||
</page><page string="History">
|
||||
<field name="history" nolabel="1" colspan="4" widget="one2many_list"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="res_request-act">
|
||||
<field name="name">res.request.form</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.request</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="res_request-view"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low level/Base/Requests/All Requests" action="res_request-act"/>
|
||||
|
||||
<record model="ir.ui.view" id="res_request_link-view">
|
||||
<field name="name">res.request.link.form</field>
|
||||
<field name="model">res.request.link</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Request Link">
|
||||
<field name="name" select="1"/>
|
||||
<field name="object" select="1"/>
|
||||
<field name="priority"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="res_request_link-act">
|
||||
<field name="name">res.request.link.form</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.request.link</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="res_request_link-view"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low level/Base/Requests/Request Links" action="res_request_link-act"/>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="res_request_history_tree-view">
|
||||
<field name="name">res.request.history.tree</field>
|
||||
<field name="model">res.request.history</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Request History">
|
||||
<field name="act_from"/>
|
||||
<field name="act_to"/>
|
||||
<field name="date_sent"/>
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="res_request_history_form-view">
|
||||
<field name="name">res.request.history.form</field>
|
||||
<field name="model">res.request.history</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Request History">
|
||||
<field name="act_from"/>
|
||||
<field name="act_to"/>
|
||||
<field name="date_sent"/>
|
||||
<newline/>
|
||||
<field name="body" colspan="3"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,122 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import fields,osv
|
||||
import tools
|
||||
|
||||
class groups(osv.osv):
|
||||
_name = "res.groups"
|
||||
_columns = {
|
||||
'name': fields.char('Group Name', size=64, required=True),
|
||||
}
|
||||
groups()
|
||||
|
||||
|
||||
class roles(osv.osv):
|
||||
_name = "res.roles"
|
||||
_columns = {
|
||||
'name': fields.char('Role Name', size=64, required=True),
|
||||
'parent_id': fields.many2one('res.roles', 'Parent', select=True),
|
||||
'child_id': fields.one2many('res.roles', 'parent_id', 'Childs')
|
||||
}
|
||||
_defaults = {
|
||||
}
|
||||
def check(self, cr, uid, ids, role_id):
|
||||
if role_id in ids:
|
||||
return True
|
||||
cr.execute('select parent_id from res_roles where id=%d', (role_id,))
|
||||
roles = cr.fetchone()[0]
|
||||
if roles:
|
||||
return self.check(cr, uid, ids, roles[0])
|
||||
return False
|
||||
roles()
|
||||
|
||||
class lang(osv.osv):
|
||||
_name = "res.lang"
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True),
|
||||
'code': fields.char('Code', size=5, required=True),
|
||||
'translatable': fields.boolean('Translatable'),
|
||||
'active': fields.boolean('Active'),
|
||||
}
|
||||
_defaults = {
|
||||
'active': lambda *a: 1,
|
||||
'translatable': lambda *a: 0,
|
||||
}
|
||||
lang()
|
||||
|
||||
class users(osv.osv):
|
||||
_name = "res.users"
|
||||
_log_access = False
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True, select=True),
|
||||
'login': fields.char('Login', size=64, required=True),
|
||||
'password': fields.char('Password', size=64, invisible=True),
|
||||
'signature': fields.text('Signature', size=64),
|
||||
'address_id': fields.many2one('res.partner.address', 'Address'),
|
||||
'active': fields.boolean('Active'),
|
||||
'action_id': fields.many2one('ir.actions.actions', 'Action'),
|
||||
'groups_id': fields.many2many('res.groups', 'res_groups_users_rel', 'uid', 'gid', 'groups'),
|
||||
'roles_id': fields.many2many('res.roles', 'res_roles_users_rel', 'uid', 'rid', 'Roles'),
|
||||
'company_id': fields.many2one('res.company', 'Company'),
|
||||
}
|
||||
_sql_constraints = [
|
||||
('login_key', 'UNIQUE (login)', 'You can not have two users with the same login !')
|
||||
]
|
||||
_defaults = {
|
||||
'password' : lambda obj,cr,uid,context={} : '',
|
||||
'active' : lambda obj,cr,uid,context={} : True,
|
||||
}
|
||||
def company_get(self, cr, uid, uid2):
|
||||
company_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.id
|
||||
return company_id
|
||||
company_get = tools.cache()(company_get)
|
||||
|
||||
def write(self, cr, uid, *args, **argv):
|
||||
res = super(users, self).write(cr, uid, *args, **argv)
|
||||
# Restart the cache on the company_get method
|
||||
self.company_get()
|
||||
return res
|
||||
|
||||
def unlink(self, cr, uid, ids):
|
||||
if 1 in ids:
|
||||
raise osv.except_osv('Can not remove root user !', 'You can not remove the root user as it is used internally for resources created by Tiny ERP (updates, module installation, ...)')
|
||||
return super(users, self).unlink(cr, uid, ids)
|
||||
|
||||
def name_search(self, cr, user, name, args=[], operator='ilike', context={}):
|
||||
ids = self.search(cr, user, [('login','=',name)]+ args)
|
||||
if not ids:
|
||||
ids = self.search(cr, user, [('name',operator,name)]+ args)
|
||||
return self.name_get(cr, user, ids)
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context={}):
|
||||
login = self.read(cr, uid, [id], ['login'])[0]['login']
|
||||
default.update({'login': login+' (copy)'})
|
||||
return super(users, self).copy(cr, uid, id, default, context)
|
||||
users()
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
./module_graph.py | dot -Tpng -o > module_graph.png
|
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import os
|
||||
|
||||
print 'digraph G {'
|
||||
for f in os.listdir('.'):
|
||||
if os.path.isfile(os.path.join(f,"__terp__.py")):
|
||||
info=eval(file(os.path.join(f,"__terp__.py")).read())
|
||||
if info.get('active', True):
|
||||
for name in info['depends']:
|
||||
print '\t%s -> %s;' % (f, name)
|
||||
print '}'
|
|
@ -0,0 +1,278 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
|
@ -0,0 +1,6 @@
|
|||
Files downloaded on
|
||||
|
||||
2006-08-07
|
||||
|
||||
from
|
||||
http://tinyforge.org/softwaremap/trove_list.php?form_cat=309&discrim=309
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue