[MERGE] branch merged with lp:~openerp-dev/openobject-addons/trunk-dev-addons3
bzr revid: mtr@mtr-20101029052434-65iz1ts0s2wujxrc
This commit is contained in:
@@ -327,7 +327,7 @@ class account_cash_statement(osv.osv):
|
||||
for statement in statement_pool.browse(cr, uid, ids, context=context):
|
||||
vals = {}
|
||||
if not self._user_allow(cr, uid, statement.id, context=context):
|
||||
raise osv.except_osv(_('Error !'), _('User %s does not have rights to access %s journal !' % (statement.user_id.name, statement.journal_id.name)))
|
||||
raise osv.except_osv(_('Error !'), (_('User %s does not have rights to access %s journal !') % (statement.user_id.name, statement.journal_id.name)))
|
||||
|
||||
if statement.name and statement.name == '/':
|
||||
number = self.pool.get('ir.sequence').get(cr, uid, 'account.cash.statement')
|
||||
|
||||
@@ -6283,10 +6283,7 @@ msgstr ""
|
||||
#. module: account
|
||||
#: code:addons/account/account_cash_statement.py:0
|
||||
#, python-format
|
||||
msgid "User %s does not have rights to access %s journal !' % (statement.user_id.name, statement.journal_id.name)))\n"
|
||||
"\n"
|
||||
" if statement.name and statement.name == '/':\n"
|
||||
" number = self.pool.get('ir.sequence"
|
||||
msgid "User \"%s\" does not have rights to access \"%s\" journal !"
|
||||
msgstr ""
|
||||
|
||||
#. module: account
|
||||
|
||||
@@ -916,7 +916,7 @@ class calendar_event(osv.osv):
|
||||
return [(x.lower(), x) for x in pytz.all_timezones]
|
||||
|
||||
def onchange_allday(self, cr, uid, ids, allday, context=None):
|
||||
"""Sets duration as 24 Hours if event is selcted for all day
|
||||
"""Sets duration as 24 Hours if event is selected for all day
|
||||
@param self: The object pointer
|
||||
@param cr: the current row, from the database cursor,
|
||||
@param uid: the current user’s ID for security checks,
|
||||
@@ -1630,6 +1630,14 @@ true, it will allow you to hide the event alarm information without removing it.
|
||||
if vals.get('vtimezone', '') and vals.get('vtimezone', '').startswith('/freeassociation.sourceforge.net/tzfile/'):
|
||||
vals['vtimezone'] = vals['vtimezone'][40:]
|
||||
|
||||
updated_vals = self.onchange_dates(cr, uid, [],
|
||||
vals.get('date', False),
|
||||
vals.get('duration', False),
|
||||
vals.get('date_deadline', False),
|
||||
vals.get('allday', False),
|
||||
context=context)
|
||||
vals.update(updated_vals.get('value', {}))
|
||||
|
||||
res = super(calendar_event, self).create(cr, uid, vals, context)
|
||||
alarm_obj = self.pool.get('res.alarm')
|
||||
alarm_obj.do_alarm_create(cr, uid, [res], self._name, 'date', context=context)
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
<group col="6" colspan="4">
|
||||
<field name="name" select="1" string="Summary"
|
||||
colspan="4" required="1" />
|
||||
<field name="allday" colspan="2" on_change="onchange_allday(allday)" />
|
||||
<field name="allday" colspan="2" on_change="onchange_dates(date,False,False,allday)" />
|
||||
<newline/>
|
||||
<field name="date" string="Start Date" required="1" select="1"
|
||||
on_change="onchange_dates(date,duration,False,allday)" />
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<field name="categ_id" widget="selection"
|
||||
string="Meeting Type" groups="base.group_extended"
|
||||
domain="[('object_id.model', '=', 'crm.meeting')]" />
|
||||
<field name="allday" on_change="onchange_allday(allday)" />
|
||||
<field name="allday" on_change="onchange_dates(date,False,False,allday)" />
|
||||
<newline/>
|
||||
<field name="date" string="Start Date" required="1"
|
||||
on_change="onchange_dates(date,duration,False,allday)" />
|
||||
|
||||
@@ -64,7 +64,7 @@ class crm_helpdesk(crm.crm_case, osv.osv):
|
||||
'categ_id': fields.many2one('crm.case.categ', 'Category', \
|
||||
domain="[('section_id','=',section_id),\
|
||||
('object_id.model', '=', 'crm.helpdesk')]"),
|
||||
'duration': fields.float('Duration'),
|
||||
'duration': fields.float('Duration', states={'done': [('readonly', True)]}),
|
||||
'state': fields.selection(crm.AVAILABLE_STATES, 'State', size=16, readonly=True,
|
||||
help='The state is set to \'Draft\', when a case is created.\
|
||||
\nIf the case is in progress the state is set to \'Open\'.\
|
||||
|
||||
+1
-1
@@ -183,7 +183,7 @@ class hr_employee(osv.osv):
|
||||
return {'value': {'work_email' : work_email}}
|
||||
|
||||
def _get_photo(self, cr, uid, context=None):
|
||||
photo_path = addons.get_module_resource('hr','image','photo.png')
|
||||
photo_path = addons.get_module_resource('hr','image','photo.png')
|
||||
return open(photo_path, 'rb').read().encode('base64')
|
||||
|
||||
_defaults = {
|
||||
|
||||
@@ -42,18 +42,22 @@ class base_report(report_sxw.rml_parse):
|
||||
self.context = context
|
||||
|
||||
def _load(self, name, form):
|
||||
fiscalyear = self.pool.get('account.fiscalyear').browse(self.cr, self.uid, form['fiscalyear'])
|
||||
period_query_cond=self.pool.get('account.period').search(self.cr, self.uid, [('fiscalyear_id', '=', form['fiscalyear'])])
|
||||
fiscalyear = self.pool.get('account.fiscalyear').browse(self.cr, self.uid, form['fiscalyear_id'])
|
||||
period_ids=self.pool.get('account.period').search(self.cr, self.uid, [('fiscalyear_id', '=', form['fiscalyear_id'])])
|
||||
|
||||
self.cr.execute("SELECT MIN(date_start) AS date_start, MAX(date_stop) AS date_stop FROM account_period WHERE id IN %s", (tuple(period_query_cond),))
|
||||
dates = self.cr.dictfetchall()
|
||||
self._set_variable('date_start', dates[0]['date_start'])
|
||||
self._set_variable('date_stop', dates[0]['date_stop'])
|
||||
if period_ids:
|
||||
self.cr.execute("SELECT MIN(date_start) AS date_start, MAX(date_stop) AS date_stop FROM account_period WHERE id = ANY(%s)", (period_ids,))
|
||||
dates = self.cr.dictfetchall()
|
||||
else:
|
||||
dates = False
|
||||
if dates:
|
||||
self._set_variable('date_start', dates[0]['date_start'])
|
||||
self._set_variable('date_stop', dates[0]['date_stop'])
|
||||
|
||||
self.cr.execute("SELECT l10n_fr_line.code,definition FROM l10n_fr_line LEFT JOIN l10n_fr_report ON l10n_fr_report.id=report_id WHERE l10n_fr_report.code=%s",(name,))
|
||||
datas = self.cr.dictfetchall()
|
||||
for line in datas:
|
||||
self._load_accounts(form,line['code'],eval(line['definition']),fiscalyear,period_query_cond)
|
||||
self._load_accounts(form,line['code'],eval(line['definition']),fiscalyear,period_ids)
|
||||
|
||||
def _set_variable(self, variable, valeur):
|
||||
self.localcontext.update({variable: valeur})
|
||||
@@ -61,30 +65,35 @@ class base_report(report_sxw.rml_parse):
|
||||
def _get_variable(self, variable):
|
||||
return self.localcontext[variable]
|
||||
|
||||
def _load_accounts(self,form,code,definition,fiscalyear,period_query_cond):
|
||||
def _load_accounts(self, form, code, definition, fiscalyear, period_ids):
|
||||
accounts = {}
|
||||
for x in definition['load']:
|
||||
p = x.split(":")
|
||||
accounts[p[1]] = [p[0],p[2]]
|
||||
sum = 0.0
|
||||
if fiscalyear.state != 'done' or not code.startswith('bpcheck'):
|
||||
query_params = []
|
||||
query_cond = "("
|
||||
for account in accounts:
|
||||
query_cond += "aa.code LIKE '" + account + "%' OR "
|
||||
query_cond += "aa.code LIKE '" + account + "%%' OR "
|
||||
query_cond = query_cond[:-4]+")"
|
||||
|
||||
if len(definition['except']) > 0:
|
||||
query_cond = query_cond+" and ("
|
||||
for account in definition['except']:
|
||||
query_cond += "aa.code NOT LIKE '"+account+"%' AND "
|
||||
query_cond += "aa.code NOT LIKE '"+account+"%%' AND "
|
||||
query_cond = query_cond[:-5]+")"
|
||||
|
||||
closed_cond = ""
|
||||
if fiscalyear.state == 'done':
|
||||
closed_cond=" AND (aml.move_id NOT IN (SELECT account_move.id as move_id FROM account_move WHERE period_id IN "+str(tuple(period_query_cond))+" AND journal_id=(SELECT res_id FROM ir_model_data WHERE name='closing_journal' AND module='l10n_fr')) OR (aa.type != 'income' AND aa.type !='expense'))"
|
||||
closed_cond=" AND (aml.move_id NOT IN (SELECT account_move.id as move_id FROM account_move WHERE period_id = ANY(%s) AND journal_id=(SELECT res_id FROM ir_model_data WHERE name='closing_journal' AND module='l10n_fr')) OR (aa.type != 'income' AND aa.type !='expense'))"
|
||||
query_params.append(list(period_ids))
|
||||
|
||||
query = "SELECT aa.code AS code, SUM(debit) as debit, SUM(credit) as credit FROM account_move_line aml LEFT JOIN account_account aa ON aa.id=aml.account_id WHERE "+query_cond+closed_cond+" AND aml.state='valid' AND aml.period_id IN "+str(tuple(period_query_cond))+" GROUP BY code"
|
||||
self.cr.execute(query)
|
||||
query = "SELECT aa.code AS code, SUM(debit) as debit, SUM(credit) as credit " \
|
||||
" FROM account_move_line aml LEFT JOIN account_account aa ON aa.id=aml.account_id "\
|
||||
" WHERE "+query_cond+closed_cond+" AND aml.state='valid' AND aml.period_id = ANY(%s) GROUP BY code"
|
||||
query_params.append(list(period_ids))
|
||||
self.cr.execute(query, query_params)
|
||||
|
||||
lines =self.cr.dictfetchall()
|
||||
for line in lines:
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
date_start: '2012-01-01'
|
||||
date_stop: '2012-12-31'
|
||||
name: Fiscal Year 2012
|
||||
-
|
||||
I create the fiscal periods
|
||||
-
|
||||
!python {model: account.fiscalyear}:
|
||||
self.create_period(cr, uid, [ref('account_fiscalyear_01'),])
|
||||
-
|
||||
In order to test the PDF reports defined on a l10n_fr, we will print an Account Move Line Report for l10n_fr
|
||||
-
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
<field name="password">jth</field>
|
||||
</record>
|
||||
<record id="res_users_tester" model="res.users">
|
||||
<field name="name">Alien</field>
|
||||
<field name="name">Aline</field>
|
||||
<field eval="[(6, 0, [ref('base.group_user'), ref('project.group_project_user')])]" name="groups_id"/>
|
||||
<field name="login">apr</field>
|
||||
<field name="password">apr</field>
|
||||
|
||||
@@ -187,7 +187,7 @@ class purchase_order(osv.osv):
|
||||
help="From Order: a draft invoice will be pre-generated based on the purchase order. The accountant " \
|
||||
"will just have to validate this invoice for control.\n" \
|
||||
"From Picking: a draft invoice will be pre-generated based on validated receptions.\n" \
|
||||
"Manual: no invoice will be pre-generated. The accountant will have to encode manually."
|
||||
"Manual: allows you to generate suppliers invoices by chosing in the uninvoiced lines of all manual purchase orders."
|
||||
),
|
||||
'minimum_planned_date':fields.function(_minimum_planned_date, fnct_inv=_set_minimum_planned_date, method=True,store=True, string='Expected Date', type='date', help="This is computed as the minimum scheduled date of all purchase order lines' products."),
|
||||
'amount_untaxed': fields.function(_amount_all, method=True, digits_compute= dp.get_precision('Purchase Price'), string='Untaxed Amount',
|
||||
@@ -597,7 +597,7 @@ class purchase_order_line(osv.osv):
|
||||
_columns = {
|
||||
'name': fields.char('Description', size=256, required=True),
|
||||
'product_qty': fields.float('Quantity', required=True, digits=(16,2)),
|
||||
'date_planned': fields.date('Scheduled date', required=True),
|
||||
'date_planned': fields.date('Scheduled Date', required=True),
|
||||
'taxes_id': fields.many2many('account.tax', 'purchase_order_taxe', 'ord_id', 'tax_id', 'Taxes'),
|
||||
'product_uom': fields.many2one('product.uom', 'Product UOM', required=True),
|
||||
'product_id': fields.many2one('product.product', 'Product', domain=[('purchase_ok','=',True)], change_default=True),
|
||||
@@ -616,7 +616,7 @@ class purchase_order_line(osv.osv):
|
||||
\n* The \'Cancelled\' state is set automatically when user cancel purchase order.'),
|
||||
'invoice_lines': fields.many2many('account.invoice.line', 'purchase_order_line_invoice_rel', 'order_line_id', 'invoice_id', 'Invoice Lines', readonly=True),
|
||||
'invoiced': fields.boolean('Invoiced', readonly=True),
|
||||
'partner_id': fields.related('order_id','partner_id',string='Partner',readonly=True,type="many2one", relation="res.partner"),
|
||||
'partner_id': fields.related('order_id','partner_id',string='Partner',readonly=True,type="many2one", relation="res.partner", store=True),
|
||||
'date_order': fields.related('order_id','date_order',string='Order Date',readonly=True,type="date")
|
||||
|
||||
}
|
||||
|
||||
@@ -144,10 +144,10 @@
|
||||
<button name="action_cancel" states="approved,except_picking,except_invoice" string="Cancel Purchase Order" type="object" icon="gtk-cancel"/>
|
||||
<button name="picking_ok" states="except_picking" string="Manually Corrected" icon="gtk-convert"/>
|
||||
<button name="invoice_ok" states="except_invoice" string="Manually Corrected" icon="gtk-convert"/>
|
||||
<button name="purchase_confirm" states="draft" string="Confirm Purchase Order" icon="gtk-go-forward"/>
|
||||
<button name="purchase_confirm" states="draft" string="Convert to Purchase Order" icon="gtk-go-forward"/>
|
||||
<button name="purchase_appbuyer" states="wait_auth" string="Approve Purchase" icon="gtk-ok"/>
|
||||
<button name="purchase_approve" states="confirmed" string="Approved by Supplier" icon="gtk-go-forward"/>
|
||||
<button name="%(report_purchase_order)d" string="Print" states="approved" type="action" icon="gtk-print"/>
|
||||
<button name="%(report_purchase_order)d" string="Print" states="approved" type="action" icon="gtk-print"/>
|
||||
|
||||
</group>
|
||||
</page>
|
||||
@@ -307,12 +307,16 @@
|
||||
<tree string="Purchase Order Lines">
|
||||
<field name="order_id"/>
|
||||
<field name="name"/>
|
||||
<field name="date_planned" widget="date" width="135"/>
|
||||
<field name="partner_id" string="Supplier" />
|
||||
<field name="product_id"/>
|
||||
<field name="product_qty"/>
|
||||
<field name="product_uom"/>
|
||||
<field name="price_unit"/>
|
||||
<field name="product_qty"/>
|
||||
<field name="product_uom"/>
|
||||
<field name="price_subtotal"/>
|
||||
<field name="date_planned" widget="date" width="135"/>
|
||||
|
||||
|
||||
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="invoiced" invisible="1"/>
|
||||
</tree>
|
||||
@@ -369,10 +373,12 @@
|
||||
<group>
|
||||
<field name="order_id"/>
|
||||
<field name="product_id"/>
|
||||
</group>
|
||||
<field name="partner_id" string="Supplier"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="Product" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by' : 'product_id'}" />
|
||||
<filter string="Supplier" icon="terp-gtk-jump-to-rtl" domain="[]" context="{'group_by' : 'partner_id'}" />
|
||||
<filter icon="terp-gtk-jump-to-rtl" string="Order Reference" domain="[]" context="{'group_by' :'order_id'}"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by' : 'state'}" />
|
||||
@@ -401,7 +407,7 @@
|
||||
<field name="name">Purchase Lines Not Invoiced</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">purchase.order.line</field>
|
||||
<field name="domain">[('state','in',('confirmed','done')), ('invoiced','=',False)]</field>
|
||||
<field name="domain">[('state','in',('confirmed','done')), ('invoiced', '=', False)]</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="purchase_order_line_search"/>
|
||||
|
||||
@@ -24,6 +24,7 @@ import ir
|
||||
from osv import osv
|
||||
from tools.translate import _
|
||||
|
||||
|
||||
class purchase_line_invoice(osv.osv_memory):
|
||||
|
||||
""" To create invoice for purchase order line"""
|
||||
@@ -31,7 +32,8 @@ class purchase_line_invoice(osv.osv_memory):
|
||||
_name = 'purchase.order.line_invoice'
|
||||
_description = 'Purchase Order Line Make Invoice'
|
||||
|
||||
def makeInvoices(self, cr, uid, ids, context):
|
||||
def makeInvoices(self, cr, uid, ids, context=None):
|
||||
|
||||
"""
|
||||
To get Purchase Order line and create Invoice
|
||||
@param self: The object pointer.
|
||||
@@ -39,7 +41,11 @@ class purchase_line_invoice(osv.osv_memory):
|
||||
@param uid: ID of the user currently logged in
|
||||
@param context: A standard dictionary
|
||||
@return : retrun view of Invoice
|
||||
"""
|
||||
"""
|
||||
|
||||
if context is None:
|
||||
context={}
|
||||
|
||||
record_ids = context.get('active_ids',[])
|
||||
if record_ids:
|
||||
res = False
|
||||
@@ -49,35 +55,63 @@ class purchase_line_invoice(osv.osv_memory):
|
||||
property_obj=self.pool.get('ir.property')
|
||||
account_fiscal_obj=self.pool.get('account.fiscal.position')
|
||||
invoice_line_obj=self.pool.get('account.invoice.line')
|
||||
|
||||
def make_invoice(order, lines):
|
||||
a = order.partner_id.property_account_payable.id
|
||||
if order.partner_id and order.partner_id.property_payment_term.id:
|
||||
pay_term = order.partner_id.property_payment_term.id
|
||||
|
||||
|
||||
def multiple_order_invoice_name(orders):
|
||||
name = "PO";
|
||||
for order in orders:
|
||||
name += "-%d" % order.id
|
||||
return name
|
||||
|
||||
def multiple_order_invoice_reference(partner, orders):
|
||||
reference = "P%dPO" % partner.id
|
||||
for order in orders:
|
||||
reference += "-%d" % order.id
|
||||
return reference
|
||||
|
||||
def multiple_order_invoice_notes(orders):
|
||||
notes = ""
|
||||
for order in orders:
|
||||
notes += "%s \n" % order.notes
|
||||
return notes
|
||||
|
||||
|
||||
|
||||
def make_invoice_by_partner(partner, orders, lines_ids):
|
||||
"""
|
||||
create a new invoice for one supplier
|
||||
@param partner : The object partner
|
||||
@param orders : The set of orders to add in the invoice
|
||||
@param lines : The list of line's id
|
||||
"""
|
||||
|
||||
a = partner.property_account_payable.id
|
||||
if partner and partner.property_payment_term.id:
|
||||
pay_term = partner.property_payment_term.id
|
||||
else:
|
||||
pay_term = False
|
||||
inv = {
|
||||
'name': order.name,
|
||||
'origin': order.name,
|
||||
'name': multiple_order_invoice_name(orders),
|
||||
'origin': multiple_order_invoice_name(orders),
|
||||
'type': 'in_invoice',
|
||||
'reference': "P%dPO%d" % (order.partner_id.id, order.id),
|
||||
'reference': multiple_order_invoice_reference(partner, orders),
|
||||
'account_id': a,
|
||||
'partner_id': order.partner_id.id,
|
||||
'address_invoice_id': order.partner_address_id.id,
|
||||
'address_contact_id': order.partner_address_id.id,
|
||||
'invoice_line': [(6,0,lines)],
|
||||
'currency_id' : order.pricelist_id.currency_id.id,
|
||||
'comment': order.notes,
|
||||
'partner_id': partner.id,
|
||||
'address_invoice_id': orders[0].partner_address_id.id,
|
||||
'address_contact_id': orders[0].partner_address_id.id,
|
||||
'invoice_line': [(6,0,lines_ids)],
|
||||
'currency_id' : orders[0].pricelist_id.currency_id.id,
|
||||
'comment': multiple_order_invoice_notes(orders),
|
||||
'payment_term': pay_term,
|
||||
'fiscal_position': order.partner_id.property_account_position.id
|
||||
'fiscal_position': partner.property_account_position.id
|
||||
}
|
||||
inv_id = invoice_obj.create(cr, uid, inv)
|
||||
return inv_id
|
||||
|
||||
for line in purchase_line_obj.browse(cr,uid,record_ids):
|
||||
if (not line.invoiced) and (line.state not in ('draft','cancel')):
|
||||
if not line.order_id.id in invoices:
|
||||
invoices[line.order_id.id] = []
|
||||
if not line.partner_id.id in invoices:
|
||||
invoices[line.partner_id.id] = []
|
||||
if line.product_id:
|
||||
a = line.product_id.product_tmpl_id.property_account_expense.id
|
||||
if not a:
|
||||
@@ -102,18 +136,19 @@ class purchase_line_invoice(osv.osv_memory):
|
||||
'uos_id': line.product_uom.id,
|
||||
'product_id': line.product_id.id or False,
|
||||
'invoice_line_tax_id': [(6, 0, [x.id for x in line.taxes_id])],
|
||||
'note': line.notes,
|
||||
'note': line.notes,
|
||||
'account_analytic_id': line.account_analytic_id and line.account_analytic_id.id or False,
|
||||
})
|
||||
cr.execute('insert into purchase_order_line_invoice_rel (order_line_id,invoice_id) values (%s,%s)', (line.id, inv_id))
|
||||
purchase_line_obj.write(cr, uid, [line.id], {'invoiced': True})
|
||||
invoices[line.order_id.id].append((line,inv_id))
|
||||
invoices[line.partner_id.id].append((line,inv_id))
|
||||
|
||||
res = []
|
||||
for result in invoices.values():
|
||||
order = result[0][0].order_id
|
||||
il = map(lambda x: x[1], result)
|
||||
res.append(make_invoice(order, il))
|
||||
orders = list(set(map(lambda x : x[0].order_id, result)))
|
||||
|
||||
res.append(make_invoice_by_partner(orders[0].partner_id, orders, il))
|
||||
|
||||
return {
|
||||
'domain': "[('id','in', ["+','.join(map(str,res))+"])]",
|
||||
|
||||
+6
-6
@@ -470,12 +470,13 @@ class sale_order(osv.osv):
|
||||
inv_ids = list(inv_ids1.difference(inv_ids))
|
||||
|
||||
res = mod_obj.get_object_reference(cr, uid, 'account', 'invoice_form')
|
||||
|
||||
result = {
|
||||
res_id = res and res[1] or False,
|
||||
|
||||
return {
|
||||
'name': 'Customer Invoices',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'view_id': [res] and [res[1]] or False,
|
||||
'view_id': [res_id],
|
||||
'res_model': 'account.invoice',
|
||||
'context': "{'type':'out_invoice'}",
|
||||
'type': 'ir.actions.act_window',
|
||||
@@ -483,7 +484,6 @@ class sale_order(osv.osv):
|
||||
'target': 'current',
|
||||
'res_id': inv_ids and inv_ids[0] or False,
|
||||
}
|
||||
return result
|
||||
|
||||
def action_invoice_create(self, cr, uid, ids, grouped=False, states=['confirmed', 'done', 'exception'], date_inv = False, context=None):
|
||||
res = False
|
||||
@@ -1221,8 +1221,8 @@ class sale_config_picking_policy(osv.osv_memory):
|
||||
if o.step == 'one':
|
||||
md = self.pool.get('ir.model.data')
|
||||
location_id = md.get_object_reference(cr, uid, 'stock', 'stock_location_output')
|
||||
search_id = location_id and location_id[1] or False
|
||||
self.pool.get('stock.location').write(cr, uid, search_id, {'chained_auto_packing': 'transparent'})
|
||||
location_id = location_id and location_id[1] or False
|
||||
self.pool.get('stock.location').write(cr, uid, [location_id], {'chained_auto_packing': 'transparent'})
|
||||
|
||||
sale_config_picking_policy()
|
||||
|
||||
|
||||
@@ -210,7 +210,7 @@
|
||||
<button name="ship_recreate" states="shipping_except" string="Recreate Procurement" icon="gtk-ok"/>
|
||||
<button name="ship_corrected" states="shipping_except" string="Procurement Corrected" icon="gtk-apply"/>
|
||||
<button name="action_cancel" states="manual,progress" string="Cancel Order" type="object" icon="gtk-cancel"/>
|
||||
<button name="manual_invoice" states="manual" string="Create Invoice" icon="gtk-go-forward" type="object"/>
|
||||
<button name="manual_invoice" states="manual" string="Create Final Invoice" icon="gtk-go-forward" type="object"/>
|
||||
<button name="ship_cancel" states="shipping_except" string="Cancel Order" icon="gtk-cancel"/>
|
||||
<button name="action_cancel_draft" states="cancel" string="Set to Draft" type="object" icon="gtk-convert"/>
|
||||
<button name="cancel" states="draft" string="Cancel Order" icon="gtk-cancel"/>
|
||||
|
||||
@@ -135,8 +135,8 @@ sale_advance_payment_inv()
|
||||
class sale_open_invoice(osv.osv_memory):
|
||||
_name = "sale.open.invoice"
|
||||
_description = "Sale Open Invoice"
|
||||
|
||||
def open_invoice(self, cr, uid, ids, context):
|
||||
|
||||
def open_invoice(self, cr, uid, ids, context=None):
|
||||
|
||||
"""
|
||||
To open invoice.
|
||||
@@ -148,7 +148,8 @@ class sale_open_invoice(osv.osv_memory):
|
||||
@return:
|
||||
|
||||
"""
|
||||
|
||||
if context is None:
|
||||
context = {}
|
||||
mod_obj = self.pool.get('ir.model.data')
|
||||
for advance_pay in self.browse(cr, uid, ids):
|
||||
form_res = mod_obj.get_object_reference(cr, uid, 'account', 'invoice_form')
|
||||
@@ -170,4 +171,4 @@ class sale_open_invoice(osv.osv_memory):
|
||||
|
||||
sale_open_invoice()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
@@ -1461,12 +1461,15 @@
|
||||
====================================
|
||||
Reception Picking (By Stock Move)
|
||||
====================================
|
||||
|
||||
<!-- from stock_partial_move_view -->
|
||||
|
||||
|
||||
|
||||
<record id="view_move_tree_reception_picking" model="ir.ui.view">
|
||||
<field name="name">stock.move.tree2</field>
|
||||
<field name="model">stock.move</field>
|
||||
<field name="type">tree</field>
|
||||
<field eval="6" name="priority"/>
|
||||
<field name="priority" eval="6" />
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="grey:state in ('cancel')" string="Moves">
|
||||
<field name="picking_id" string="Reference"/>
|
||||
@@ -1521,6 +1524,7 @@
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="view_move_form_reception_picking" model="ir.ui.view">
|
||||
<field name="name">stock.move.form2</field>
|
||||
@@ -1672,7 +1676,7 @@
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">['|','&',('picking_id','=',False),('location_id.usage', 'in', ['customer','supplier']),'&',('picking_id','!=',False),('picking_id.type','=','in')]</field>
|
||||
<field name="view_id" ref="view_move_tree_reception_picking"/>
|
||||
<field name="context" eval="'{\'search_default_receive\':1, \'default_location_id\':%d, \'default_location_dest_id\':%d}' % (ref('stock_location_suppliers'),ref('stock_location_stock'))"/>
|
||||
<field name="context" eval="'{\'search_default_receive\':1, \'product_receive\' : True, \'default_location_id\':%d, \'default_location_dest_id\':%d}' % (ref('stock_location_suppliers'),ref('stock_location_stock') )"/>
|
||||
<field name="search_view_id" ref="view_move_search_reception_incoming_picking"/>
|
||||
<field name="help">You will find here the list of all products you are waiting for, according to your preceding purchase orders. Once you receive an order, you can filter based on the name of the supplier or the purchase order reference. Then you can confirm all products received using the buttons on the right of each line.</field>
|
||||
</record>
|
||||
|
||||
@@ -23,164 +23,124 @@ from osv import fields, osv
|
||||
from tools.translate import _
|
||||
import time
|
||||
|
||||
|
||||
class stock_partial_move_memory(osv.osv_memory):
|
||||
_name = "stock.move.memory"
|
||||
_rec_name = 'product_id'
|
||||
_columns = {
|
||||
'product_id' : fields.many2one('product.product', string="Product", required=True, readonly=True),
|
||||
'quantity' : fields.float("Quantity", required=True),
|
||||
'product_uom': fields.many2one('product.uom', 'Unit of Measure', required=True, readonly=True),
|
||||
'prodlot_id' : fields.many2one('stock.production.lot', 'Production Lot'),
|
||||
'move_id' : fields.many2one('stock.move', "Move"),
|
||||
'wizard_id' : fields.many2one('stock.partial.move', string="Wizard"),
|
||||
'cost' : fields.float("Cost", help="Unit Cost for this product line", readonly=True),
|
||||
'currency' : fields.many2one('res.currency', string="Currency", help="Currency in which Unit cost is expressed", readonly=True),
|
||||
}
|
||||
|
||||
class stock_partial_move(osv.osv_memory):
|
||||
_name = "stock.partial.move"
|
||||
_description = "Partial Move"
|
||||
_columns = {
|
||||
'date': fields.datetime('Date', required=True),
|
||||
'type': fields.char("Type", size=3),
|
||||
'product_moves' : fields.one2many('stock.move.memory', 'wizard_id', 'Moves'),
|
||||
}
|
||||
|
||||
|
||||
def view_init(self, cr, uid, fields_list, context=None):
|
||||
res = super(stock_partial_move, self).view_init(cr, uid, fields_list, context=context)
|
||||
move_obj = self.pool.get('stock.move')
|
||||
|
||||
if not context:
|
||||
context={}
|
||||
for m in move_obj.browse(cr, uid, context.get('active_ids', [])):
|
||||
if m.state in ('done', 'cancel'):
|
||||
context = {}
|
||||
for move in move_obj.browse(cr, uid, context.get('active_ids', [])):
|
||||
if move.state in ('done', 'cancel'):
|
||||
raise osv.except_osv(_('Invalid action !'), _('Cannot deliver products which are already delivered !'))
|
||||
|
||||
if 'move%s_product_id'%(m.id) not in self._columns:
|
||||
self._columns['move%s_product_id'%(m.id)] = fields.many2one('product.product',string="Product")
|
||||
if 'move%s_product_qty'%(m.id) not in self._columns:
|
||||
self._columns['move%s_product_qty'%(m.id)] = fields.float("Quantity")
|
||||
if 'move%s_product_uom'%(m.id) not in self._columns:
|
||||
self._columns['move%s_product_uom'%(m.id)] = fields.many2one('product.uom',string="Product UOM")
|
||||
if 'move%s_prodlot_id'%(m.id) not in self._columns:
|
||||
self._columns['move%s_prodlot_id'%(m.id)] = fields.many2one('stock.production.lot', string="Lot")
|
||||
|
||||
if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
|
||||
if 'move%s_product_price'%(m.id) not in self._columns:
|
||||
self._columns['move%s_product_price'%(m.id)] = fields.float("Cost", help="Unit Cost for this product line")
|
||||
if 'move%s_product_currency'%(m.id) not in self._columns:
|
||||
self._columns['move%s_product_currency'%(m.id)] = fields.many2one('res.currency', string="Currency", help="Currency in which Unit cost is expressed")
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def __create_partial_move_memory(self, move):
|
||||
move_memory = {
|
||||
'product_id' : move.product_id.id,
|
||||
'quantity' : move.product_qty,
|
||||
'product_uom' : move.product_uom.id,
|
||||
'prodlot_id' : move.prodlot_id.id,
|
||||
'move_id' : move.id,
|
||||
}
|
||||
if move.picking_id.type == 'in':
|
||||
move_memory.update({
|
||||
'cost' : move.product_id.standard_price,
|
||||
'currency' : move.product_id.company_id.currency_id.id,
|
||||
})
|
||||
return move_memory
|
||||
|
||||
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False,submenu=False):
|
||||
result = super(stock_partial_move, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar,submenu)
|
||||
def __get_active_stock_moves(self, cr, uid, context=None):
|
||||
move_obj = self.pool.get('stock.move')
|
||||
move_ids = context.get('active_ids', False)
|
||||
move_ids = move_obj.search(cr, uid, [('id','in',move_ids)])
|
||||
_moves_arch_lst = """<form string="Deliver Products">
|
||||
<separator colspan="4" string="Delivery Information"/>
|
||||
<field name="date" colspan="2"/>
|
||||
<separator colspan="4" string="Move Detail"/>
|
||||
"""
|
||||
_moves_fields = result['fields']
|
||||
if move_ids and view_type in ['form']:
|
||||
for m in move_obj.browse(cr, uid, move_ids, context):
|
||||
if m.state in ('done', 'cancel'):
|
||||
continue
|
||||
_moves_fields.update({
|
||||
'move%s_product_id'%(m.id) : {
|
||||
'string': _('Product'),
|
||||
'type' : 'many2one',
|
||||
'relation': 'product.product',
|
||||
'required' : True,
|
||||
'readonly' : True,
|
||||
},
|
||||
'move%s_product_qty'%(m.id) : {
|
||||
'string': _('Quantity'),
|
||||
'type' : 'float',
|
||||
'required': True,
|
||||
},
|
||||
'move%s_product_uom'%(m.id) : {
|
||||
'string': _('Product UOM'),
|
||||
'type' : 'many2one',
|
||||
'relation': 'product.uom',
|
||||
'required' : True,
|
||||
'readonly' : True,
|
||||
},
|
||||
'move%s_prodlot_id'%(m.id): {
|
||||
'string': _('Production Lot'),
|
||||
'type': 'many2one',
|
||||
'relation': 'stock.production.lot',
|
||||
}
|
||||
})
|
||||
if not context:
|
||||
context = {}
|
||||
|
||||
res = []
|
||||
for move in move_obj.browse(cr, uid, context.get('active_ids', [])):
|
||||
if move.state in ('done', 'cancel'):
|
||||
continue
|
||||
res.append(self.__create_partial_move_memory(move))
|
||||
|
||||
return res
|
||||
|
||||
_defaults = {
|
||||
'product_moves' : __get_active_stock_moves,
|
||||
'date' : time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
}
|
||||
|
||||
|
||||
_moves_arch_lst += """
|
||||
<group colspan="4" col="10">
|
||||
<field name="move%s_product_id" nolabel="1"/>
|
||||
<field name="move%s_product_qty" string="Qty" />
|
||||
<field name="move%s_product_uom" nolabel="1" />
|
||||
<field name="move%s_prodlot_id" domain="[('product_id','=',move%s_product_id)]" groups="base.group_extended" />
|
||||
"""%(m.id, m.id, m.id,m.id,m.id)
|
||||
if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
|
||||
_moves_fields.update({
|
||||
'move%s_product_price'%(m.id) : {
|
||||
'string': _('Cost'),
|
||||
'type' : 'float',
|
||||
'help': _('Unit Cost for this product line'),
|
||||
},
|
||||
'move%s_product_currency'%(m.id): {
|
||||
'string': _('Currency'),
|
||||
'type' : 'many2one',
|
||||
'relation': 'res.currency',
|
||||
'help': _("Currency in which Unit Cost is expressed"),
|
||||
}
|
||||
})
|
||||
_moves_arch_lst += """
|
||||
<field name="move%s_product_price" />
|
||||
<field name="move%s_product_currency" nolabel="1"/>
|
||||
"""%(m.id, m.id)
|
||||
_moves_arch_lst += """
|
||||
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
|
||||
height = 2 * 25;
|
||||
message = {
|
||||
'title' : _('Deliver Products'),
|
||||
'info' : _('Delivery Information'),
|
||||
'button' : _('Deliver'),
|
||||
}
|
||||
if context:
|
||||
height = (len(context.get('active_ids', [])) + 1) * 25
|
||||
if context.get('product_receive', False):
|
||||
message = {
|
||||
'title' : _('Receive Products'),
|
||||
'info' : _('Receive Information'),
|
||||
'button' : _('Receive'),
|
||||
}
|
||||
message['height'] = height
|
||||
|
||||
|
||||
result = super(stock_partial_move, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar, submenu)
|
||||
_moves_fields = result['fields']
|
||||
_moves_fields.update({'product_moves' :
|
||||
{
|
||||
'relation': 'stock.move.memory',
|
||||
'type' : 'one2many',
|
||||
'string' : 'Product Moves',
|
||||
}
|
||||
})
|
||||
|
||||
_moves_arch_lst = """
|
||||
<form string="%(title)s">
|
||||
<separator colspan="4" string="%(info)s"/>
|
||||
<field name="date" colspan="2"/>
|
||||
<separator colspan="4" string="Move Detail"/>
|
||||
<field name="product_moves" colspan="4" nolabel="1" width="550" height="200" />
|
||||
<separator string="" colspan="4" />
|
||||
<label string="" colspan="2"/>
|
||||
<group col="2" colspan="2">
|
||||
<button icon='gtk-cancel' special="cancel" string="_Cancel" />
|
||||
<button name="do_partial" string="%(button)s"
|
||||
colspan="1" type="object" icon="gtk-apply" />
|
||||
</group>
|
||||
"""
|
||||
_moves_arch_lst += """
|
||||
<separator string="" colspan="4" />
|
||||
<label string="" colspan="2"/>
|
||||
<group col="2" colspan="2">
|
||||
<button icon='gtk-cancel' special="cancel"
|
||||
string="_Cancel" />
|
||||
<button name="do_partial" string="_Deliver"
|
||||
colspan="1" type="object" icon="gtk-apply" />
|
||||
</group>
|
||||
</form>"""
|
||||
</form> """ % message
|
||||
|
||||
result['arch'] = _moves_arch_lst
|
||||
result['fields'] = _moves_fields
|
||||
return result
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
""" To get default values for the object.
|
||||
@param self: The object pointer.
|
||||
@param cr: A database cursor
|
||||
@param uid: ID of the user currently logged in
|
||||
@param fields: List of fields for which we want default values
|
||||
@param context: A standard dictionary
|
||||
@return: A dictionary which of fields with values.
|
||||
"""
|
||||
|
||||
res = super(stock_partial_move, self).default_get(cr, uid, fields, context=context)
|
||||
move_obj = self.pool.get('stock.move')
|
||||
if not context:
|
||||
context={}
|
||||
if 'date' in fields:
|
||||
res.update({'date': time.strftime('%Y-%m-%d %H:%M:%S')})
|
||||
move_ids = context.get('active_ids', [])
|
||||
move_ids = move_obj.search(cr, uid, [('id','in',move_ids)])
|
||||
for m in move_obj.browse(cr, uid, context.get('active_ids', [])):
|
||||
if m.state in ('done', 'cancel'):
|
||||
continue
|
||||
res['type'] = m.picking_id and m.picking_id.type or ''
|
||||
if 'move%s_product_id'%(m.id) in fields:
|
||||
res['move%s_product_id'%(m.id)] = m.product_id.id
|
||||
if 'move%s_product_qty'%(m.id) in fields:
|
||||
res['move%s_product_qty'%(m.id)] = m.product_qty
|
||||
if 'move%s_product_uom'%(m.id) in fields:
|
||||
res['move%s_product_uom'%(m.id)] = m.product_uom.id
|
||||
if 'move%s_prodlot_id'%(m.id) in fields:
|
||||
res['move%s_prodlot_id'%(m.id)] = m.prodlot_id.id
|
||||
if m.picking_id.type == 'in' and m.product_id.cost_method == 'average':
|
||||
# Always use default product cost and currency from Product Form,
|
||||
# which belong to the Company owning the product
|
||||
currency = m.product_id.company_id.currency_id.id
|
||||
price = m.product_id.standard_price
|
||||
if 'move%s_product_price'%(m.id) in fields:
|
||||
res['move%s_product_price'%(m.id)] = price
|
||||
if 'move%s_product_currency'%(m.id) in fields:
|
||||
res['move%s_product_currency'%(m.id)] = currency
|
||||
return res
|
||||
|
||||
|
||||
def do_partial(self, cr, uid, ids, context):
|
||||
""" Makes partial moves and pickings done.
|
||||
@param self: The object pointer.
|
||||
@@ -190,32 +150,44 @@ class stock_partial_move(osv.osv_memory):
|
||||
@param context: A standard dictionary
|
||||
@return: A dictionary which of fields with values.
|
||||
"""
|
||||
|
||||
|
||||
move_obj = self.pool.get('stock.move')
|
||||
|
||||
move_ids = context.get('active_ids', False)
|
||||
partial = self.browse(cr, uid, ids[0], context)
|
||||
partial_datas = {
|
||||
'delivery_date' : partial.date
|
||||
}
|
||||
for m in move_obj.browse(cr, uid, move_ids):
|
||||
if m.state in ('done', 'cancel'):
|
||||
|
||||
p_moves = {}
|
||||
for product_move in partial.product_moves:
|
||||
p_moves[product_move.move_id.id] = product_move
|
||||
|
||||
moves_ids_final = []
|
||||
for move in move_obj.browse(cr, uid, move_ids):
|
||||
if move.state in ('done', 'cancel'):
|
||||
continue
|
||||
partial_datas['move%s'%(m.id)] = {
|
||||
'product_id' : getattr(partial, 'move%s_product_id'%(m.id)).id,
|
||||
'product_qty' : getattr(partial, 'move%s_product_qty'%(m.id)),
|
||||
'product_uom' : getattr(partial, 'move%s_product_uom'%(m.id)).id,
|
||||
'prodlot_id' : getattr(partial, 'move%s_prodlot_id'%(m.id)).id
|
||||
if not p_moves.get(move.id, False):
|
||||
continue
|
||||
partial_datas['move%s' % (move.id)] = {
|
||||
'product_id' : p_moves[move.id].product_id.id,
|
||||
'product_qty' : p_moves[move.id].quantity,
|
||||
'product_uom' : p_moves[move.id].product_uom.id,
|
||||
'prodlot_id' : p_moves[move.id].prodlot_id.id,
|
||||
}
|
||||
|
||||
if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
|
||||
partial_datas['move%s'%(m.id)].update({
|
||||
'product_price' : getattr(partial, 'move%s_product_price'%(m.id)),
|
||||
'product_currency': getattr(partial, 'move%s_product_currency'%(m.id)).id
|
||||
moves_ids_final.append(move.id)
|
||||
if (move.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
|
||||
partial_datas['move%s' % (move.id)].update({
|
||||
'product_price' : p_moves[move.id].cost,
|
||||
'product_currency': p_moves[move.id].currency.id,
|
||||
})
|
||||
move_obj.do_partial(cr, uid, move_ids, partial_datas, context=context)
|
||||
|
||||
|
||||
move_obj.do_partial(cr, uid, moves_ids_final, partial_datas, context=context)
|
||||
return {}
|
||||
|
||||
stock_partial_move()
|
||||
|
||||
stock_partial_move_memory()
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
||||
@@ -2,13 +2,49 @@
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<act_window name="Deliver Products"
|
||||
<act_window name="Deliver/Receive Products"
|
||||
res_model="stock.partial.move"
|
||||
src_model="stock.move"
|
||||
view_mode="form"
|
||||
multi="True"
|
||||
target="new"
|
||||
key2="client_action_multi"
|
||||
id="action_partial_move"/>
|
||||
|
||||
id="action_partial_move"></act_window>
|
||||
|
||||
|
||||
<record id="stock_move_memory_tree" model="ir.ui.view">
|
||||
<field name="name">stock.move.memory.tree</field>
|
||||
<field name="model">stock.move.memory</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom" string="Product Moves">
|
||||
<field name="product_id" readonly="1" />
|
||||
<field name="quantity" ></field>
|
||||
<field name="product_uom"></field>
|
||||
<field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" ></field>
|
||||
<field name="cost"></field>
|
||||
<field name="currency" ></field>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="stock_move_memory_form" model="ir.ui.view">
|
||||
<field name="name">stock.move.memory.form</field>
|
||||
<field name="model">stock.move.memory</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<field name="product_id" readonly="1" />
|
||||
<field name="quantity" ></field>
|
||||
<field name="product_uom"></field>
|
||||
<field name="prodlot_id" domain="[('product_id', '=', product_id)]" groups="base.group_extended" ></field>
|
||||
<field name="cost"></field>
|
||||
<field name="currency"></field>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -231,7 +231,8 @@ sale_order_line()
|
||||
class purchase_order_line(osv.osv):
|
||||
_inherit = 'purchase.order.line'
|
||||
def product_id_change(self,cr, uid, ids, pricelist, product, qty, uom,
|
||||
partner_id, date_order=False, fiscal_position=False):
|
||||
partner_id, date_order=False, fiscal_position=False, date_planned=False,
|
||||
name=False, price_unit=False, notes=False):
|
||||
warning = {}
|
||||
if not product:
|
||||
return {'value': {'price_unit': 0.0, 'name':'','notes':'', 'product_uom' : False}, 'domain':{'product_uom':[]}}
|
||||
|
||||
Reference in New Issue
Block a user