+51
-14
@@ -160,14 +160,29 @@ class account_account(osv.osv):
|
||||
return super(account_account,self).search(cr, uid, args, offset, limit,
|
||||
order, context=context, count=count)
|
||||
|
||||
def _get_children_and_consol(self, cr, uid, ids, context={}):
|
||||
#this function search for all the children and all consolidated children (recursively) of the given account ids
|
||||
res = self.search(cr, uid, [('parent_id', 'child_of', ids)])
|
||||
for id in res:
|
||||
this = self.browse(cr, uid, id, context)
|
||||
for child in this.child_consol_ids:
|
||||
if child.id not in res:
|
||||
res.append(child.id)
|
||||
if len(res) != len(ids):
|
||||
return self._get_children_and_consol(cr, uid, res, context)
|
||||
return res
|
||||
|
||||
def __compute(self, cr, uid, ids, field_names, arg, context={}, query=''):
|
||||
#compute the balance/debit/credit accordingly to the value of field_name for the given account ids
|
||||
mapping = {
|
||||
'balance': "COALESCE(SUM(l.debit) - SUM(l.credit), 0) as balance ",
|
||||
'debit': "COALESCE(SUM(l.debit), 0) as debit ",
|
||||
'credit': "COALESCE(SUM(l.credit), 0) as credit "
|
||||
}
|
||||
ids2 = self.search(cr, uid, [('parent_id', 'child_of', ids)])
|
||||
#get all the necessary accounts
|
||||
ids2 = self._get_children_and_consol(cr, uid, ids, context)
|
||||
acc_set = ",".join(map(str, ids2))
|
||||
#compute for each account the balance/debit/credit from the move lines
|
||||
accounts = {}
|
||||
if ids2:
|
||||
query = self.pool.get('account.move.line')._query_get(cr, uid,
|
||||
@@ -184,13 +199,29 @@ class account_account(osv.osv):
|
||||
for res in cr.dictfetchall():
|
||||
accounts[res['id']] = res
|
||||
|
||||
#for the asked accounts, get from the dictionnary 'accounts' the value of it
|
||||
res = {}
|
||||
for id in ids:
|
||||
res[id] = {}.fromkeys(field_names, 0.0)
|
||||
ids2 = self.search(cr, uid, [('parent_id', 'child_of', [id])])
|
||||
res[id] = self._get_account_values(cr, uid, id, accounts, field_names, context)
|
||||
return res
|
||||
|
||||
def _get_account_values(self, cr, uid, id, accounts, field_names, context={}):
|
||||
res = {}.fromkeys(field_names, 0.0)
|
||||
browse_rec = self.browse(cr, uid, id)
|
||||
if browse_rec.type == 'consolidation':
|
||||
ids2 = self.read(cr, uid, [browse_rec.id], ['child_consol_ids'], context)[0]['child_consol_ids']
|
||||
for t in self.search(cr, uid, [('parent_id', 'child_of', [browse_rec.id])]):
|
||||
if t not in ids2 and t != browse_rec.id:
|
||||
ids2.append(t)
|
||||
for i in ids2:
|
||||
tmp = self._get_account_values(cr, uid, i, accounts, field_names, context)
|
||||
for a in field_names:
|
||||
res[a] += tmp[a]
|
||||
else:
|
||||
ids2 = self.search(cr, uid, [('parent_id', 'child_of', [browse_rec.id])])
|
||||
for i in ids2:
|
||||
for a in field_names:
|
||||
res[id][a] += accounts.get(i, {}).get(a, 0.0)
|
||||
res[a] += accounts.get(i, {}).get(a, 0.0)
|
||||
return res
|
||||
|
||||
def _get_company_currency(self, cr, uid, ids, field_name, arg, context={}):
|
||||
@@ -216,7 +247,7 @@ class account_account(osv.osv):
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=128, required=True, select=True),
|
||||
'currency_id': fields.many2one('res.currency', 'Secondary Currency', help="Force all moves for this account to have this secondary currency."),
|
||||
'code': fields.char('Code', size=64),
|
||||
'code': fields.char('Code', size=64, required=True),
|
||||
'type': fields.selection([
|
||||
('receivable','Receivable'),
|
||||
('payable','Payable'),
|
||||
@@ -229,7 +260,7 @@ class account_account(osv.osv):
|
||||
'user_type': fields.many2one('account.account.type', 'Account Type', required=True),
|
||||
'parent_id': fields.many2one('account.account','Parent', ondelete='cascade'),
|
||||
'child_parent_ids':fields.one2many('account.account','parent_id','Children'),
|
||||
'child_consol_ids':fields.many2many('account.account', 'account_account_consol_rel', 'child_id', 'parent_id', 'Consolidated Children',domain=[('type', '=', 'consolidation')]),
|
||||
'child_consol_ids':fields.many2many('account.account', 'account_account_consol_rel', 'child_id', 'parent_id', 'Consolidated Children'),
|
||||
'child_id': fields.function(_get_child_ids, method=True, type='many2many',relation="account.account",string="Children Accounts"),
|
||||
'balance': fields.function(__compute, digits=(16,2), method=True, string='Balance', multi='balance'),
|
||||
'credit': fields.function(__compute, digits=(16,2), method=True, string='Credit', multi='balance'),
|
||||
@@ -245,7 +276,7 @@ class account_account(osv.osv):
|
||||
|
||||
'parent_left': fields.integer('Parent Left', select=1),
|
||||
'parent_right': fields.integer('Parent Right', select=1),
|
||||
'check_history': fields.boolean('Display History', help="Check this box if you want to print all entries otherwise it will print balance of this account")
|
||||
'check_history': fields.boolean('Display History', help="Check this box if you want to print all entries when printing the General Ledger, otherwise it will only print its balance.")
|
||||
}
|
||||
|
||||
def _default_company(self, cr, uid, context={}):
|
||||
@@ -924,15 +955,21 @@ class account_move_reconcile(osv.osv):
|
||||
{'reconcile_id': rec.id }
|
||||
)
|
||||
return True
|
||||
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
result = {}
|
||||
if not len(ids):
|
||||
return []
|
||||
result = []
|
||||
for r in self.browse(cr, uid, ids, context):
|
||||
total = reduce(lambda y,t: (t.debit or 0.0) - (t.credit or 0.0) + y, r.line_partial_ids, 0.0)
|
||||
if total:
|
||||
result[r.id] = '%s (%.2f)' % (r.name, total)
|
||||
name = '%s (%.2f)' % (r.name, total)
|
||||
result.append((r.id,name))
|
||||
else:
|
||||
result[r.id] = r.name
|
||||
result.append((r.id,r.name))
|
||||
return result
|
||||
|
||||
|
||||
account_move_reconcile()
|
||||
|
||||
#----------------------------------------------------------
|
||||
@@ -1510,7 +1547,7 @@ class account_config_wizard(osv.osv_memory):
|
||||
}
|
||||
|
||||
def install_account_chart(self, cr, uid,ids, context=None):
|
||||
for res in self.read(cr,uid,ids):
|
||||
for res in self.read(cr,uid,ids):
|
||||
id = res['charts']
|
||||
def install(id):
|
||||
mod_obj = self.pool.get('ir.module.module')
|
||||
@@ -1558,7 +1595,7 @@ class account_config_wizard(osv.osv_memory):
|
||||
'target':'new',
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
account_config_wizard()
|
||||
|
||||
@@ -2036,8 +2073,8 @@ class wizard_multi_charts_accounts(osv.osv_memory):
|
||||
'res_model': 'ir.module.module.configuration.wizard',
|
||||
'type': 'ir.actions.act_window',
|
||||
'target':'new',
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
wizard_multi_charts_accounts()
|
||||
|
||||
|
||||
@@ -167,8 +167,8 @@ class account_bank_statement(osv.osv):
|
||||
|
||||
if not (abs(st.balance_end - st.balance_end_real) < 0.0001):
|
||||
raise osv.except_osv(_('Error !'),
|
||||
_('The statement balance is incorrect !\n'
|
||||
'Check that the ending balance equals the computed one.'))
|
||||
_('The statement balance is incorrect !\n') +
|
||||
_('The expected balance (%.2f) is different than the computed one. (%.2f)') % (st.balance_end_real, st.balance_end))
|
||||
if (not st.journal_id.default_credit_account_id) \
|
||||
or (not st.journal_id.default_debit_account_id):
|
||||
raise osv.except_osv(_('Configration Error !'),
|
||||
@@ -177,7 +177,7 @@ class account_bank_statement(osv.osv):
|
||||
for line in st.move_line_ids:
|
||||
if line.state <> 'valid':
|
||||
raise osv.except_osv(_('Error !'),
|
||||
_('The account entries lines are not valid.'))
|
||||
_('The account entries lines are not in valid state.'))
|
||||
|
||||
for move in st.line_ids:
|
||||
move_id = account_move_obj.create(cr, uid, {
|
||||
|
||||
@@ -175,15 +175,14 @@
|
||||
</field>
|
||||
</group>
|
||||
<group col="4" colspan="2">
|
||||
<label colspan="2"/>
|
||||
<field name="amount_untaxed"/>
|
||||
<button colspan="2" name="button_reset_taxes" states="draft" string="Reset taxes" type="object"/>
|
||||
<field name="amount_tax"/>
|
||||
<field name="amount_untaxed"/>
|
||||
<button colspan="2" name="button_compute" states="draft" string="Compute" type="object"/>
|
||||
<field name="amount_total"/>
|
||||
<field name="amount_tax"/>
|
||||
<field name="reconciled"/>
|
||||
<field name="residual"/>
|
||||
<field name="amount_total"/>
|
||||
<field name="state" select="2"/>
|
||||
<field name="residual"/>
|
||||
<group col="3" colspan="4">
|
||||
<button name="invoice_open" states="draft,proforma" string="Validate"/>
|
||||
<button name="invoice_cancel" states="draft,proforma,sale,open" string="Cancel"/>
|
||||
@@ -258,15 +257,14 @@
|
||||
</field>
|
||||
</group>
|
||||
<group col="4" colspan="2">
|
||||
<label colspan="2"/>
|
||||
<field name="amount_untaxed"/>
|
||||
<button colspan="2" name="button_reset_taxes" states="draft" string="Reset taxes" type="object"/>
|
||||
<field name="amount_tax"/>
|
||||
<field name="amount_untaxed"/>
|
||||
<button colspan="2" name="button_compute" states="draft" string="Compute" type="object"/>
|
||||
<field name="amount_total"/>
|
||||
<field name="amount_tax"/>
|
||||
<field name="reconciled"/>
|
||||
<field name="residual"/>
|
||||
<field name="amount_total"/>
|
||||
<field name="state" select="2"/>
|
||||
<field name="residual"/>
|
||||
<group col="3" colspan="4">
|
||||
<button name="invoice_proforma" states="draft" string="PRO-FORMA"/>
|
||||
<button name="invoice_open" states="draft,proforma" string="Create"/>
|
||||
@@ -420,6 +418,7 @@
|
||||
<field name="name">Draft Customer Invoices</field>
|
||||
<field name="res_model">account.invoice</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph</field>
|
||||
<field name="domain">[('state','=','draft'),('type','=','out_invoice')]</field>
|
||||
<field name="context">{'type':'out_invoice'}</field>
|
||||
</record>
|
||||
@@ -441,6 +440,7 @@
|
||||
<field name="name">PRO-FORMA Customer Invoices</field>
|
||||
<field name="res_model">account.invoice</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph</field>
|
||||
<field name="domain">[('state','=','proforma'),('type','=','out_invoice')]</field>
|
||||
<field name="context">{'type':'out_invoice'}</field>
|
||||
</record>
|
||||
@@ -462,6 +462,7 @@
|
||||
<field name="name">Unpaid Customer Invoices</field>
|
||||
<field name="res_model">account.invoice</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph</field>
|
||||
<field name="domain">[('state','!=','draft'),('reconciled','=',False),('type','=','out_invoice')]</field>
|
||||
<field name="context">{'type':'out_invoice'}</field>
|
||||
</record>
|
||||
@@ -483,6 +484,7 @@
|
||||
<field name="name">Draft Supplier Invoices</field>
|
||||
<field name="res_model">account.invoice</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph</field>
|
||||
<field name="domain">[('state','=','draft'),('type','=','in_invoice')]</field>
|
||||
<field name="context">{'type':'in_invoice'}</field>
|
||||
</record>
|
||||
@@ -504,6 +506,7 @@
|
||||
<field name="name">Unpaid Supplier Invoices</field>
|
||||
<field name="res_model">account.invoice</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph</field>
|
||||
<field name="domain">[('state','!=','draft'),('reconciled','=',False),('type','=','in_invoice')]</field>
|
||||
<field name="context">{'type':'in_invoice'}</field>
|
||||
</record>
|
||||
@@ -525,6 +528,7 @@
|
||||
<field name="name">Draft Customer Refunds</field>
|
||||
<field name="res_model">account.invoice</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph</field>
|
||||
<field name="domain">[('state','=','draft'),('type','=','out_refund')]</field>
|
||||
<field name="context">{'type':'out_refund'}</field>
|
||||
</record>
|
||||
@@ -546,6 +550,7 @@
|
||||
<field name="name">Unpaid Customer Refunds</field>
|
||||
<field name="res_model">account.invoice</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph</field>
|
||||
<field name="domain">[('state','!=','draft'),('reconciled','=',False),('type','=','out_refund')]</field>
|
||||
<field name="context">{'type':'out_refund'}</field>
|
||||
</record>
|
||||
@@ -567,6 +572,7 @@
|
||||
<field name="name">Draft Supplier Refunds</field>
|
||||
<field name="res_model">account.invoice</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph</field>
|
||||
<field name="domain">[('state','=','draft'),('type','=','in_refund')]</field>
|
||||
<field name="context">{'type':'in_refund'}</field>
|
||||
</record>
|
||||
@@ -588,6 +594,7 @@
|
||||
<field name="name">Unpaid Supplier Refunds</field>
|
||||
<field name="res_model">account.invoice</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph</field>
|
||||
<field name="domain">[('state','!=','draft'),('reconciled','=',False),('type','=','in_refund')]</field>
|
||||
<field name="context">{'type':'in_refund'}</field>
|
||||
</record>
|
||||
|
||||
@@ -305,6 +305,8 @@ class account_move_line(osv.osv):
|
||||
'analytic_account_id' : fields.many2one('account.analytic.account', 'Analytic Account'),
|
||||
#TODO: remove this
|
||||
'amount_taxed':fields.float("Taxed Amount",digits=(16,2)),
|
||||
'parent_move_lines':fields.many2many('account.move.line', 'account_move_line_rel', 'child_id', 'parent_id', 'Parent'),
|
||||
'reconcile_implicit':fields.boolean('Implicit Reconciliaiton')
|
||||
}
|
||||
|
||||
def _get_date(self, cr, uid, context):
|
||||
@@ -435,7 +437,11 @@ class account_move_line(osv.osv):
|
||||
currency = 0.0
|
||||
account_id = False
|
||||
partner_id = False
|
||||
implicit_lines = []
|
||||
for line in unrec_lines:
|
||||
if line.parent_move_lines:
|
||||
for i in line.parent_move_lines:
|
||||
implicit_lines.append(i.id)
|
||||
if line.state <> 'valid':
|
||||
raise osv.except_osv(_('Error'),
|
||||
_('Entry "%s" is not valid !') % line.name)
|
||||
@@ -481,7 +487,7 @@ class account_move_line(osv.osv):
|
||||
self_debit = -writeoff
|
||||
|
||||
# If comment exist in context, take it
|
||||
if context['comment']:
|
||||
if 'comment' in context and context['comment']:
|
||||
libelle=context['comment']
|
||||
else:
|
||||
libelle='Write-Off'
|
||||
@@ -531,9 +537,13 @@ class account_move_line(osv.osv):
|
||||
'line_id': map(lambda x: (4,x,False), ids),
|
||||
'line_partial_ids': map(lambda x: (3,x,False), ids)
|
||||
})
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
if implicit_lines:
|
||||
self.write(cr, uid, implicit_lines, {'reconcile_implicit':True,'reconcile_id':r_id})
|
||||
for id in implicit_lines:
|
||||
wf_service.trg_trigger(uid, 'account.move.line', id, cr)
|
||||
# the id of the move.reconcile is written in the move.line (self) by the create method above
|
||||
# because of the way the line_id are defined: (4, x, False)
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
for id in ids:
|
||||
wf_service.trg_trigger(uid, 'account.move.line', id, cr)
|
||||
return r_id
|
||||
@@ -629,7 +639,7 @@ class account_move_line(osv.osv):
|
||||
|
||||
if raise_ex:
|
||||
raise osv.except_osv(_('Wrong Accounting Entry!'), _('Both Credit and Debit cannot be zero!'))
|
||||
|
||||
account_obj = self.pool.get('account.account')
|
||||
if ('account_id' in vals) and not account_obj.read(cr, uid, vals['account_id'], ['active'])['active']:
|
||||
raise osv.except_osv(_('Bad account!'), _('You can not use an inactive account!'))
|
||||
if update_check:
|
||||
|
||||
@@ -116,19 +116,19 @@
|
||||
<field name="type" select="1"/>
|
||||
<field name="company_id" select="2"/>
|
||||
<field name="parent_id"/>
|
||||
<field name="active"/>
|
||||
<field name="user_type" select="1"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="General Information">
|
||||
<newline/>
|
||||
<field name="user_type" select="1"/>
|
||||
<field name="currency_id" select="2"/>
|
||||
<field name="active" select="2"/>
|
||||
<field name="reconcile"/>
|
||||
<field name="check_history"/>
|
||||
<newline/>
|
||||
<newline/>
|
||||
<field name="child_consol_ids" colspan="4"/>
|
||||
<field colspan="4" name="tax_ids" domain="[('parent_id','=',False)]"/>
|
||||
<field name="child_consol_ids" colspan="4" attrs="{'readonly':[('type','!=','consolidation')]}"/>/>
|
||||
</page>
|
||||
<page string="Notes">
|
||||
<field colspan="4" name="note" nolabel="1"/>
|
||||
@@ -654,6 +654,7 @@
|
||||
<field name="state"/>
|
||||
<field name="reconcile_id"/>
|
||||
<field name="reconcile_partial_id"/>
|
||||
<field colspan="4" name="reconcile_implicit"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -705,6 +706,10 @@
|
||||
<page string="Analytic Lines">
|
||||
<field colspan="4" name="analytic_lines" nolabel="1"/>
|
||||
</page>
|
||||
<page string="Move Lines">
|
||||
<field colspan="4" name="reconcile_implicit"/>
|
||||
<field colspan="4" name="parent_move_lines" nolabel="0"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
@@ -744,7 +749,7 @@
|
||||
<newline/>
|
||||
<field name="account_tax_id" domain="[('parent_id','=',False)]"/>
|
||||
<field name="analytic_account_id"/>
|
||||
|
||||
<field colspan="4" name="reconcile_implicit"/>
|
||||
<separator colspan="4" string="State"/>
|
||||
<newline/>
|
||||
<field name="reconcile_id"/>
|
||||
@@ -1285,6 +1290,7 @@
|
||||
<field name="credit" sum="Total credit"/>
|
||||
<field name="account_tax_id"/>
|
||||
<field name="analytic_account_id"/>
|
||||
<field colspan="4" name="reconcile_implicit"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
@@ -1354,10 +1360,10 @@
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- register configuration wizard -->
|
||||
@@ -1367,8 +1373,8 @@
|
||||
<field name="note">Define Fiscal Years and Select Charts of Account</field>
|
||||
<field name="action_id" ref="action_account_config_wizard_form"/>
|
||||
<field name="state">open</field>
|
||||
</record>
|
||||
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
<!-- Account Templates -->
|
||||
|
||||
@@ -21,15 +21,20 @@
|
||||
<field name="code">liability</field>
|
||||
<field name="close_method">balance</field>
|
||||
</record>
|
||||
<record id="account_type_cash_equity" model="account.account.type">
|
||||
<field name="name">Equity</field>
|
||||
<field name="code">equity</field>
|
||||
<field name="close_method">balance</field>
|
||||
</record>
|
||||
<record id="account_type_income" model="account.account.type">
|
||||
<field name="name">Income</field>
|
||||
<field name="code">income</field>
|
||||
<field name="close_method">none</field>
|
||||
<field name="close_method">unreconciled</field>
|
||||
</record>
|
||||
<record id="account_type_expense" model="account.account.type">
|
||||
<field name="name">Expense</field>
|
||||
<field name="code">expense</field>
|
||||
<field name="close_method">none</field>
|
||||
<field name="close_method">unreconciled</field>
|
||||
</record>
|
||||
<record id="account_type_cash_moves" model="account.account.type">
|
||||
<field name="name">Cash</field>
|
||||
|
||||
@@ -150,7 +150,9 @@
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_account_analytic_line_tree"/>
|
||||
</record>
|
||||
<menuitem id="next_id_41" name="Analytic Entries" parent="account.menu_finance_entries"/><menuitem action="action_account_analytic_line_form" id="account_entries_analytic_entries" parent="next_id_41"/>
|
||||
<wizard id="action_account_analytic_line" menu="False" model="account.analytic.line" name="account.analytic.line" string="Entries Encoding by Line"/>
|
||||
<menuitem id="next_id_41" name="Analytic Entries" parent="account.menu_finance_entries"/>
|
||||
<menuitem type="wizard" icon="STOCK_JUSTIFY_FILL" action="action_account_analytic_line" id="account_entries_analytic_entries" parent="next_id_41"/>
|
||||
|
||||
|
||||
<record id="action_account_tree1" model="ir.actions.act_window">
|
||||
@@ -238,7 +240,7 @@
|
||||
#
|
||||
|
||||
<record id="action_account_analytic_journal_open_form" model="ir.actions.act_window">
|
||||
<field name="name">account.analytic.journal.open.form</field>
|
||||
<field name="name">Entries of Open Analytic Journals</field>
|
||||
<field name="res_model">account.analytic.line</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
|
||||
@@ -34,6 +34,7 @@ import wizard_account_analytic_inverted_balance_report
|
||||
import wizard_account_analytic_cost_ledger_report
|
||||
import wizard_account_analytic_cost_ledger_for_journal_report
|
||||
import wizard_account_analytic_analytic_check
|
||||
import wizard_account_analytic_line
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2008 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.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import wizard
|
||||
import pooler
|
||||
import time
|
||||
|
||||
def _action_open_window(self, cr, uid, data, context):
|
||||
domain=[]
|
||||
from_date= data['form']['from_date']
|
||||
to_date=data['form']['to_date']
|
||||
if from_date and to_date:
|
||||
domain=[('date','>=',from_date),('date','<=',to_date)]
|
||||
elif from_date:
|
||||
domain=[('date','>=',from_date)]
|
||||
elif to_date:
|
||||
domain=[('date','<=',to_date)]
|
||||
return {
|
||||
'name': 'Analytic Entries',
|
||||
'view_type': 'form',
|
||||
"view_mode": 'tree,form',
|
||||
'res_model': 'account.analytic.line',
|
||||
'type': 'ir.actions.act_window',
|
||||
'domain': domain}
|
||||
|
||||
|
||||
class account_analytic_line(wizard.interface):
|
||||
form1 = '''<?xml version="1.0"?>
|
||||
<form string="View Account Analytic Lines">
|
||||
<separator string="Account Analytic Lines Analysis" colspan="4"/>
|
||||
<field name="from_date"/>
|
||||
<newline/>
|
||||
<field name="to_date"/>
|
||||
<newline/>
|
||||
<label string=""/>
|
||||
<label string="(Keep empty to open the current situation)" align="0.0" colspan="3"/>
|
||||
</form>'''
|
||||
form1_fields = {
|
||||
'from_date': {
|
||||
'string': 'From',
|
||||
'type': 'date',
|
||||
},
|
||||
'to_date': {
|
||||
'string': 'To',
|
||||
'type': 'date',
|
||||
},
|
||||
}
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [],
|
||||
'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, 'state': [('end', 'Cancel','gtk-cancel'),('open', 'Open Entries','gtk-ok')]}
|
||||
},
|
||||
'open': {
|
||||
'actions': [],
|
||||
'result': {'type': 'action', 'action': _action_open_window, 'state':'end'}
|
||||
}
|
||||
}
|
||||
account_analytic_line('account.analytic.line')
|
||||
@@ -110,7 +110,7 @@ def _data_save(self, cr, uid, data, context):
|
||||
offset = 0
|
||||
limit = 100
|
||||
while True:
|
||||
cr.execute('SELECT name, quantity, debit, credit, account_id, ref, ' \
|
||||
cr.execute('SELECT id, name, quantity, debit, credit, account_id, ref, ' \
|
||||
'amount_currency, currency_id, blocked, partner_id, ' \
|
||||
'date_maturity, date_created ' \
|
||||
'FROM account_move_line ' \
|
||||
@@ -123,10 +123,13 @@ def _data_save(self, cr, uid, data, context):
|
||||
if not result:
|
||||
break
|
||||
for move in result:
|
||||
parent_id = move['id']
|
||||
move.pop('id')
|
||||
move.update({
|
||||
'date': period.date_start,
|
||||
'journal_id': new_journal.id,
|
||||
'period_id': period.id,
|
||||
'parent_move_lines':[(6,0,[parent_id])]
|
||||
})
|
||||
pool.get('account.move.line').create(cr, uid, move, {
|
||||
'journal_id': new_journal.id,
|
||||
@@ -137,7 +140,7 @@ def _data_save(self, cr, uid, data, context):
|
||||
offset = 0
|
||||
limit = 100
|
||||
while True:
|
||||
cr.execute('SELECT name, quantity, debit, credit, account_id, ref, ' \
|
||||
cr.execute('SELECT id, name, quantity, debit, credit, account_id, ref, ' \
|
||||
'amount_currency, currency_id, blocked, partner_id, ' \
|
||||
'date_maturity, date_created ' \
|
||||
'FROM account_move_line ' \
|
||||
@@ -149,10 +152,13 @@ def _data_save(self, cr, uid, data, context):
|
||||
if not result:
|
||||
break
|
||||
for move in result:
|
||||
parent_id = move['id']
|
||||
move.pop('id')
|
||||
move.update({
|
||||
'date': period.date_start,
|
||||
'journal_id': new_journal.id,
|
||||
'period_id': period.id,
|
||||
'parent_move_lines':[(6,0,[parent_id])]
|
||||
})
|
||||
pool.get('account.move.line').create(cr, uid, move)
|
||||
offset += limit
|
||||
|
||||
@@ -124,7 +124,7 @@ def _get_period(self, cr, uid, data, context={}):
|
||||
raise wizard.except_wizard(_('Error !'), _('Can not pay draft invoice.'))
|
||||
return {
|
||||
'period_id': period_id,
|
||||
'amount': invoice.amount_total,
|
||||
'amount': invoice.residual,
|
||||
'date': time.strftime('%Y-%m-%d')
|
||||
}
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ crossovered_budget()
|
||||
|
||||
class crossovered_budget_lines(osv.osv):
|
||||
|
||||
def _pra_amt(self, cr, uid, ids,name,args,context):
|
||||
def _prac_amt(self, cr, uid, ids,context={}):
|
||||
res = {}
|
||||
for line in self.browse(cr, uid, ids):
|
||||
acc_ids = ','.join([str(x.id) for x in line.general_budget_id.account_ids])
|
||||
@@ -157,7 +157,14 @@ class crossovered_budget_lines(osv.osv):
|
||||
res[line.id]=result
|
||||
return res
|
||||
|
||||
def _theo_amt(self, cr, uid, ids,name,args,context):
|
||||
def _prac(self, cr, uid, ids,name,args,context):
|
||||
res={}
|
||||
for line in self.browse(cr, uid, ids):
|
||||
res[line.id]=self._prac_amt(cr,uid,[line.id],context=context)[line.id]
|
||||
|
||||
return res
|
||||
|
||||
def _theo_amt(self, cr, uid, ids,context={}):
|
||||
res = {}
|
||||
for line in self.browse(cr, uid, ids):
|
||||
today=datetime.datetime.today()
|
||||
@@ -184,6 +191,13 @@ class crossovered_budget_lines(osv.osv):
|
||||
res[line.id]=theo_amt
|
||||
return res
|
||||
|
||||
def _theo(self, cr, uid, ids,name,args,context):
|
||||
res={}
|
||||
for line in self.browse(cr, uid, ids):
|
||||
res[line.id]=self._theo_amt(cr,uid,[line.id],context=context)[line.id]
|
||||
|
||||
return res
|
||||
|
||||
def _perc(self, cr, uid, ids,name,args,context):
|
||||
res = {}
|
||||
for line in self.browse(cr, uid, ids):
|
||||
@@ -201,58 +215,13 @@ class crossovered_budget_lines(osv.osv):
|
||||
'date_from': fields.date('Start Date',required=True),
|
||||
'date_to': fields.date('End Date',required=True),
|
||||
'paid_date': fields.date('Paid Date'),
|
||||
'planned_amount':fields.float('Planned Amount',required=True),
|
||||
'practical_amount':fields.function(_pra_amt,method=True, string='Practical Amount',type='float'),
|
||||
'theoritical_amount':fields.function(_theo_amt,method=True, string='Theoritical Amount',type='float'),
|
||||
'planned_amount':fields.float('Planned Amount',required=True,digits=(16,2)),
|
||||
'practical_amount':fields.function(_prac,method=True, string='Practical Amount',type='float',digits=(16,2)),
|
||||
'theoritical_amount':fields.function(_theo,method=True, string='Theoritical Amount',type='float',digits=(16,2)),
|
||||
'percentage':fields.function(_perc,method=True, string='Percentage',type='float'),
|
||||
}
|
||||
crossovered_budget_lines()
|
||||
|
||||
|
||||
|
||||
#class account_budget_post(osv.osv): #old code
|
||||
# _name = 'account.budget.post'
|
||||
# _inherit = 'account.budget.post'
|
||||
# _columns = {
|
||||
# 'crossovered_budget_line': fields.one2many('crossovered.budget.lines', 'general_budget_id', 'Budget Lines'),
|
||||
# }
|
||||
#account_budget_post()
|
||||
#
|
||||
#class account_budget_post_dotation(osv.osv):
|
||||
# _name = 'account.budget.post.dotation'
|
||||
# _inherit = 'account.budget.post.dotation'
|
||||
#
|
||||
# def _tot_planned(self, cr, uid, ids,name,args,context):
|
||||
# res={}
|
||||
# for line in self.browse(cr, uid, ids):
|
||||
# if line.period_id:
|
||||
# obj_period=self.pool.get('account.period').browse(cr, uid,line.period_id.id)
|
||||
#
|
||||
# total_days=strToDate(obj_period.date_stop) - strToDate(obj_period.date_start)
|
||||
# budget_id=line.post_id and line.post_id.id or False
|
||||
# query="select id from crossovered_budget_lines where general_budget_id= '"+ str(budget_id) + "' AND (date_from >='" +obj_period.date_start +"' and date_from <= '"+obj_period.date_stop + "') OR (date_to >='" +obj_period.date_start +"' and date_to <= '"+obj_period.date_stop + "') OR (date_from <'" +obj_period.date_start +"' and date_to > '"+obj_period.date_stop + "')"
|
||||
# cr.execute(query)
|
||||
# res1=cr.fetchall()
|
||||
#
|
||||
# tot_planned=0.00
|
||||
# for record in res1:
|
||||
# obj_lines = self.pool.get('crossovered.budget.lines').browse(cr, uid,record[0])
|
||||
# count_days = min(strToDate(obj_period.date_stop),strToDate(obj_lines.date_to)) - max(strToDate(obj_period.date_start), strToDate(obj_lines.date_from))
|
||||
# days_in_period = count_days.days +1
|
||||
# count_days = strToDate(obj_lines.date_to) - strToDate(obj_lines.date_from)
|
||||
# total_days_of_rec = count_days.days +1
|
||||
# tot_planned += obj_lines.planned_amount/total_days_of_rec* days_in_period
|
||||
# res[line.id]=tot_planned
|
||||
# else:
|
||||
# res[line.id]=0.00
|
||||
# return res
|
||||
#
|
||||
# _columns = {
|
||||
# 'tot_planned':fields.function(_tot_planned,method=True, string='Total Planned Amount',type='float',store=True),
|
||||
# }
|
||||
#
|
||||
#account_budget_post_dotation()
|
||||
|
||||
class account_analytic_account(osv.osv):
|
||||
_name = 'account.analytic.account'
|
||||
_inherit = 'account.analytic.account'
|
||||
@@ -266,7 +235,7 @@ account_analytic_account()
|
||||
#--------------------------------------------------------------
|
||||
# moved from account/project/project.py
|
||||
# ---------------------------------------------------------
|
||||
# Budgets
|
||||
# Budgets.
|
||||
# ---------------------------------------------------------
|
||||
|
||||
#class account_analytic_budget_post(osv.osv):
|
||||
|
||||
@@ -1,310 +0,0 @@
|
||||
# Translation of OpenERP Server.
|
||||
# This file containt the translation of the following modules:
|
||||
# * account_budget_crossover
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OpenERP Server 4.3.0"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com"
|
||||
"POT-Creation-Date: 2008-09-10 12:47:16+0000"
|
||||
"PO-Revision-Date: 2008-09-10 12:47:16+0000"
|
||||
"Last-Translator: <>"
|
||||
"Language-Team: "
|
||||
"MIME-Version: 1.0"
|
||||
"Content-Type: text/plain; charset=UTF-8"
|
||||
"Content-Transfer-Encoding: "
|
||||
"Plural-Forms: "
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: field:crossovered.budget,creating_user_id:0
|
||||
msgid "Responsible User"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: selection:crossovered.budget,state:0
|
||||
msgid "Confirmed"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: constraint:ir.model:0
|
||||
msgid "The Object name must start with x_ and not contain any special character !"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: rml:account.analytic.account.budget:0
|
||||
#: rml:crossovered.budget.report:0
|
||||
msgid "Printed at:"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: view:crossovered.budget:0
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: field:crossovered.budget,validating_user_id:0
|
||||
msgid "Validate User"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: field:crossovered.budget.lines,analytic_account_id:0
|
||||
msgid "Analytic Account Ref"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: rml:account.analytic.account.budget:0
|
||||
#: rml:crossovered.budget.report:0
|
||||
msgid "Currency:"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: selection:crossovered.budget,state:0
|
||||
msgid "Draft"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: rml:account.analytic.account.budget:0
|
||||
#: rml:crossovered.budget.report:0
|
||||
msgid "at"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: model:ir.actions.report.xml,name:account_budget_crossover.account_analytic_account_budget
|
||||
#: model:ir.actions.report.xml,name:account_budget_crossover.report_crossovered_budget
|
||||
#: model:ir.actions.wizard,name:account_budget_crossover.account_analytic_account_budget_report
|
||||
#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu
|
||||
msgid "Print Budgets"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: wizard_button:wizard.analytic.account.budget.report,init,report:0
|
||||
#: wizard_button:wizard.crossovered.budget,init,report:0
|
||||
#: wizard_button:wizard.crossovered.budget.summary,init,report:0
|
||||
msgid "Print"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: field:crossovered.budget.lines,percentage:0
|
||||
msgid "Percentage"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: selection:crossovered.budget,state:0
|
||||
msgid "Validated"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: model:ir.model,name:account_budget_crossover.model_crossovered_budget_lines
|
||||
msgid "Crossovered Budget Lines"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: field:crossovered.budget,name:0
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: field:crossovered.budget,state:0
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: rml:account.analytic.account.budget:0
|
||||
#: rml:crossovered.budget.report:0
|
||||
msgid "%"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: rml:account.analytic.account.budget:0
|
||||
#: rml:crossovered.budget.report:0
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: rml:account.analytic.account.budget:0
|
||||
msgid "Analytic Account :"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: field:crossovered.budget.lines,crossovered_budget_id:0
|
||||
msgid "Budget Ref"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: rml:account.analytic.account.budget:0
|
||||
#: rml:crossovered.budget.report:0
|
||||
msgid "to"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: rml:account.analytic.account.budget:0
|
||||
#: rml:crossovered.budget.report:0
|
||||
#: field:crossovered.budget.lines,planned_amount:0
|
||||
msgid "Planned Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget_entries
|
||||
msgid "Entries"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: view:crossovered.budget:0
|
||||
msgid "Validate"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: wizard_view:wizard.crossovered.budget,init:0
|
||||
#: wizard_view:wizard.crossovered.budget.summary,init:0
|
||||
msgid "Select Options"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: rml:account.analytic.account.budget:0
|
||||
#: rml:crossovered.budget.report:0
|
||||
#: field:crossovered.budget.lines,practical_amount:0
|
||||
msgid "Practical Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: field:crossovered.budget,date_to:0
|
||||
#: field:crossovered.budget.lines,date_to:0
|
||||
msgid "End Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: field:crossovered.budget.lines,theoritical_amount:0
|
||||
msgid "Theoritical Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: rml:account.analytic.account.budget:0
|
||||
#: rml:crossovered.budget.report:0
|
||||
msgid "Total:"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: selection:crossovered.budget,state:0
|
||||
msgid "Cancelled"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: field:crossovered.budget.lines,general_budget_id:0
|
||||
msgid "Master Budget Ref"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: view:account.analytic.account:0
|
||||
msgid "Lines"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_view
|
||||
#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_view
|
||||
#: view:crossovered.budget:0
|
||||
msgid "Budget"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: wizard_view:wizard.analytic.account.budget.report,init:0
|
||||
msgid "Select Dates Period"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: field:crossovered.budget.lines,paid_date:0
|
||||
msgid "Paid Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: model:ir.ui.menu,name:account_budget_crossover.menu_financial_reporting_budget_budget
|
||||
msgid "Budgets"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: wizard_field:wizard.analytic.account.budget.report,init,date_to:0
|
||||
#: wizard_field:wizard.crossovered.budget,init,date_to:0
|
||||
#: wizard_field:wizard.crossovered.budget.summary,init,date_to:0
|
||||
msgid "End of period"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: model:ir.model,name:account_budget_crossover.model_crossovered_budget
|
||||
msgid "Crossovered Budget"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: wizard_field:wizard.analytic.account.budget.report,init,date_from:0
|
||||
#: wizard_field:wizard.crossovered.budget,init,date_from:0
|
||||
#: wizard_field:wizard.crossovered.budget.summary,init,date_from:0
|
||||
msgid "Start of period"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: model:ir.actions.wizard,name:account_budget_crossover.wizard_crossovered_budget_menu_1
|
||||
msgid "Print Summary of Budgets"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: field:crossovered.budget,code:0
|
||||
msgid "Code"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: rml:account.analytic.account.budget:0
|
||||
#: rml:crossovered.budget.report:0
|
||||
msgid "Theoretical Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: rml:crossovered.budget.report:0
|
||||
msgid "Budget :"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: selection:crossovered.budget,state:0
|
||||
#: view:crossovered.budget:0
|
||||
msgid "Done"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: model:ir.actions.act_window,name:account_budget_crossover.act_crossovered_budget_lines_view
|
||||
#: field:account.analytic.account,crossovered_budget_line:0
|
||||
#: field:account.budget.post,crossovered_budget_line:0
|
||||
#: field:crossovered.budget,crossovered_budget_line:0
|
||||
#: model:ir.ui.menu,name:account_budget_crossover.menu_act_crossovered_budget_lines_view
|
||||
#: view:crossovered.budget:0
|
||||
#: view:account.analytic.account:0
|
||||
#: view:crossovered.budget.lines:0
|
||||
msgid "Budget Lines"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: wizard_button:wizard.analytic.account.budget.report,init,end:0
|
||||
#: wizard_button:wizard.crossovered.budget,init,end:0
|
||||
#: wizard_button:wizard.crossovered.budget.summary,init,end:0
|
||||
#: view:crossovered.budget:0
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: field:account.budget.post.dotation,tot_planned:0
|
||||
msgid "Total Planned Amount"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: field:crossovered.budget,date_from:0
|
||||
#: field:crossovered.budget.lines,date_from:0
|
||||
msgid "Start Date"
|
||||
msgstr ""
|
||||
|
||||
#. module: account_budget_crossover
|
||||
#: rml:account.analytic.account.budget:0
|
||||
#: rml:crossovered.budget.report:0
|
||||
msgid "Analysis from"
|
||||
msgstr ""
|
||||
|
||||
@@ -63,6 +63,7 @@ class budget_report(report_sxw.rml_parse):
|
||||
|
||||
budgets = self.pool.get('crossovered.budget').browse(self.cr, self.uid, [object.id], self.context.copy())
|
||||
|
||||
c_b_lines_obj=self.pool.get('crossovered.budget.lines')
|
||||
for budget_id in budgets:
|
||||
|
||||
res={}
|
||||
@@ -90,6 +91,7 @@ class budget_report(report_sxw.rml_parse):
|
||||
self.cr.execute('select distinct(analytic_account_id) from crossovered_budget_lines where id in (%s)'%(b_line_ids))
|
||||
an_ids=self.cr.fetchall()
|
||||
|
||||
context={'wizard_date_from':d_from,'wizard_date_to':d_to}
|
||||
for i in range(0,len(an_ids)):
|
||||
|
||||
analytic_name=self.pool.get('account.analytic.account').browse(self.cr, self.uid,[an_ids[i][0]])
|
||||
@@ -106,9 +108,9 @@ class budget_report(report_sxw.rml_parse):
|
||||
}
|
||||
result.append(res)
|
||||
|
||||
line_ids = self.pool.get('crossovered.budget.lines').search(self.cr, self.uid, [('id', 'in', budget_ids),('analytic_account_id','=',an_ids[i][0])])
|
||||
line_ids = c_b_lines_obj.search(self.cr, self.uid, [('id', 'in', budget_ids),('analytic_account_id','=',an_ids[i][0])])
|
||||
|
||||
line_id = self.pool.get('crossovered.budget.lines').browse(self.cr,self.uid,line_ids)
|
||||
line_id = c_b_lines_obj.browse(self.cr,self.uid,line_ids)
|
||||
tot_theo=tot_pln=tot_prac=tot_perc=0.00
|
||||
|
||||
done_budget=[]
|
||||
@@ -116,8 +118,8 @@ class budget_report(report_sxw.rml_parse):
|
||||
|
||||
if line.id in budget_lines:
|
||||
theo=pract=0.00
|
||||
theo=line._theo_amt(self.cr, self.uid, [line.id],"theoritical_amount",None,context={'wizard_date_from':d_from,'wizard_date_to':d_to})[line.id]
|
||||
pract=line._pra_amt(self.cr, self.uid, [line.id],"practical_amount",None,context={'wizard_date_from':d_from,'wizard_date_to':d_to})[line.id]
|
||||
theo=c_b_lines_obj._theo_amt(self.cr, self.uid, [line.id],context)[line.id]
|
||||
pract=c_b_lines_obj._prac_amt(self.cr, self.uid, [line.id],context)[line.id]
|
||||
|
||||
if line.general_budget_id.id in done_budget:
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@ class followup_all_print(wizard.interface):
|
||||
def _get_partners(self, cr, uid, data, context):
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
cr.execute(
|
||||
"SELECT l.partner_id, l.followup_line_id, l.date, l.id "\
|
||||
"SELECT l.partner_id, l.followup_line_id,l.date_maturity, l.date, l.id "\
|
||||
"FROM account_move_line AS l "\
|
||||
"LEFT JOIN account_account AS a "\
|
||||
"ON (l.account_id=a.id) "\
|
||||
@@ -251,14 +251,17 @@ class followup_all_print(wizard.interface):
|
||||
|
||||
partner_list = []
|
||||
to_update = {}
|
||||
for partner_id, followup_line_id, date, id in move_lines:
|
||||
for partner_id, followup_line_id, date_maturity,date, id in move_lines:
|
||||
if not partner_id:
|
||||
continue
|
||||
if partner_id in partner_list:
|
||||
to_update[str(id)] = fups[followup_line_id][1]
|
||||
if followup_line_id not in fups:
|
||||
continue
|
||||
if date <= fups[followup_line_id][0].strftime('%Y-%m-%d'):
|
||||
if date_maturity and date_maturity <= fups[followup_line_id][0].strftime('%Y-%m-%d'):
|
||||
partner_list.append(partner_id)
|
||||
to_update[str(id)] = fups[followup_line_id][1]
|
||||
elif date and date <= fups[followup_line_id][0].strftime('%Y-%m-%d'):
|
||||
partner_list.append(partner_id)
|
||||
to_update[str(id)] = fups[followup_line_id][1]
|
||||
return {'partner_ids': partner_list, 'to_update': to_update}
|
||||
|
||||
@@ -142,10 +142,12 @@ class account_invoice_line(osv.osv):
|
||||
'sequence': fields.integer('Sequence Number'),
|
||||
'functional_field': fields.function(_fnct, arg=None, fnct_inv=None, fnct_inv_arg=None, type='char', fnct_search=None, obj=None, method=True, store=False, string="Source Account"),
|
||||
}
|
||||
|
||||
def _default_account(self, cr, uid, context=None):
|
||||
cr.execute("select id from account_account where code = 0 LIMIT 1")
|
||||
cr.execute("select id from account_account where parent_id IS NULL LIMIT 1")
|
||||
res=cr.fetchone()
|
||||
return res[0]
|
||||
|
||||
_defaults = {
|
||||
'state': lambda *a: 'article',
|
||||
# 'account_id': _default_account
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<wizard string="Formatted Inv. + Message"
|
||||
<wizard string="Invoice + Message"
|
||||
model="account.invoice"
|
||||
name="wizard.notify_message"
|
||||
id="wizard_notify_message"
|
||||
@@ -9,7 +9,7 @@
|
||||
/>
|
||||
|
||||
<report id="account_invoices_1"
|
||||
string="Formatted Inv."
|
||||
string="Invoice"
|
||||
model="account.invoice"
|
||||
name="account.invoice.layout"
|
||||
rml="account_invoice_layout/report/report_account_invoice_layout.rml"
|
||||
|
||||
@@ -58,13 +58,12 @@
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Delivery grids">
|
||||
<field name="name" select="1"/>
|
||||
<field name="active" select="1"/>
|
||||
<field name="carrier_id" select="1"/>
|
||||
<field name="sequence" select="1"/>
|
||||
<notebook>
|
||||
<page string="Grid definition">
|
||||
<field name="name" select="1"/>
|
||||
<field name="active" select="1"/>
|
||||
<field name="carrier_id" select="1"/>
|
||||
<field name="sequence" select="1"/>
|
||||
<separator colspan="4" string="Grid Lines"/>
|
||||
<field colspan="4" name="line_ids" nolabel="1" select="1"/>
|
||||
</page>
|
||||
<page string="Destination">
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
</field>
|
||||
</record>
|
||||
<record id="action2" model="ir.actions.act_window">
|
||||
<field name="name">Hierarchical view of this employee</field>
|
||||
<field name="name">Employee Hierarchy</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">hr.employee</field>
|
||||
<field name="domain">[('id','in',active_ids)]</field>
|
||||
|
||||
+24
-25
@@ -383,17 +383,17 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_production_graph">
|
||||
<field name="name">mrp.production.graph</field>
|
||||
<field name="model">mrp.production</field>
|
||||
<field name="type">graph</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Production orders" type="bar">
|
||||
<field name="product_id"/>
|
||||
<field name="product_qty" operator="+"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_production_graph">
|
||||
<field name="name">mrp.production.graph</field>
|
||||
<field name="model">mrp.production</field>
|
||||
<field name="type">graph</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Production orders" type="bar">
|
||||
<field name="product_id"/>
|
||||
<field name="product_qty" operator="+"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="mrp_production_form_view" model="ir.ui.view">
|
||||
@@ -439,7 +439,7 @@
|
||||
<page string="Finnished Products">
|
||||
<field colspan="4" name="move_created_ids" nolabel="1"/>
|
||||
</page>
|
||||
<page string="Operations">
|
||||
<page string="Work Orders">
|
||||
<field colspan="4" name="workcenter_lines" nolabel="1" widget="one2many_list"/>
|
||||
</page>
|
||||
<page string="Extra Information">
|
||||
@@ -448,7 +448,7 @@
|
||||
<field name="picking_id"/>
|
||||
<field name="move_prod_id"/>
|
||||
<field name="sale_name"/>
|
||||
<field name="sale_ref"/>
|
||||
<field name="sale_ref"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
@@ -623,20 +623,19 @@
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Procurement">
|
||||
<group col="2" colspan="2">
|
||||
<separator colspan="2" string="References"/>
|
||||
<field name="name" select="1" string="Procurement Reason"/>
|
||||
<field name="origin" select="2"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator colspan="2" string="Planification"/>
|
||||
<field name="date_planned" select="1"/>
|
||||
<field name="procure_method" select="2"/>
|
||||
<field name="priority"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Procurement Details">
|
||||
<group col="2" colspan="2">
|
||||
<separator colspan="2" string="References"/>
|
||||
<field name="name" select="1" string="Procurement Reason"/>
|
||||
<field name="origin" select="2"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator colspan="2" string="Planification"/>
|
||||
<field name="date_planned" select="1"/>
|
||||
<field name="procure_method" select="2"/>
|
||||
<field name="priority"/>
|
||||
</group>
|
||||
|
||||
<separator colspan="4" string="Product & Location"/>
|
||||
<field name="product_id" select="1"/>
|
||||
<field name="location_id" select="2"/>
|
||||
|
||||
+140
-44
@@ -63,6 +63,29 @@ class process_process(osv.osv):
|
||||
'active' : lambda *a: True,
|
||||
}
|
||||
|
||||
def search_by_model(self, cr, uid, res_model, context):
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
|
||||
model_ids = pool.get('ir.model').search(cr, uid, [('model', '=', res_model)])
|
||||
if not model_ids:
|
||||
return []
|
||||
|
||||
nodes = pool.get('process.node').search(cr, uid, [('model_id', 'in', model_ids)])
|
||||
if not nodes:
|
||||
return []
|
||||
|
||||
nodes = pool.get('process.node').browse(cr, uid, nodes, context)
|
||||
|
||||
unique = []
|
||||
result = []
|
||||
|
||||
for node in nodes:
|
||||
if node.process_id.id not in unique:
|
||||
result.append((node.process_id.id, node.process_id.name))
|
||||
unique.append(node.process_id.id)
|
||||
|
||||
return result
|
||||
|
||||
def graph_get(self, cr, uid, id, res_model, res_id, scale, context):
|
||||
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
@@ -72,38 +95,7 @@ class process_process(osv.osv):
|
||||
current_user = pool.get('res.users').browse(cr, uid, [uid], context)[0]
|
||||
|
||||
expr_context = Env(current_object, current_user)
|
||||
|
||||
def get_resource_info(node):
|
||||
ret = False
|
||||
|
||||
src_model = res_model
|
||||
src_id = res_id
|
||||
|
||||
if node.transition_in:
|
||||
tr = node.transition_in[0]
|
||||
src = nodes.get(tr.source_node_id.id)
|
||||
if src['res']:
|
||||
src_model = src['res']['model']
|
||||
src_id = src['res']['id']
|
||||
else:
|
||||
return False
|
||||
|
||||
fields = pool.get(src_model).fields_get(cr, uid, context=context)
|
||||
|
||||
for name, field in fields.items():
|
||||
if node.model_id and field.get('relation', False) == node.model_id.model:
|
||||
src_obj = pool.get(src_model).browse(cr, uid, [src_id], context)[0]
|
||||
rel = src_obj[name]
|
||||
if rel:
|
||||
if isinstance(rel, (list, tuple)):
|
||||
rel = rel[0]
|
||||
ret = {}
|
||||
ret['name'] = rel.name_get(context)[0][1]
|
||||
ret['model'] = field['relation']
|
||||
ret['id'] = rel.id
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
notes = process.note
|
||||
nodes = {}
|
||||
start = []
|
||||
@@ -112,6 +104,8 @@ class process_process(osv.osv):
|
||||
states = dict(pool.get(res_model).fields_get(cr, uid, context=context).get('state', {}).get('selection', {}))
|
||||
title = "%s - Resource: %s, State: %s" % (process.name, current_object.name, states.get(getattr(current_object, 'state'), 'N/A'))
|
||||
|
||||
perm = pool.get(res_model).perm_read(cr, uid, [res_id], context)[0]
|
||||
|
||||
for node in process.node_ids:
|
||||
data = {}
|
||||
data['name'] = node.name
|
||||
@@ -121,18 +115,12 @@ class process_process(osv.osv):
|
||||
data['notes'] = node.note
|
||||
data['active'] = False
|
||||
data['gray'] = False
|
||||
data['res'] = get_resource_info(node)
|
||||
data['url'] = node.help_url
|
||||
|
||||
if node.menu_id:
|
||||
data['menu'] = {'name': node.menu_id.complete_name, 'id': node.menu_id.id}
|
||||
|
||||
if node.model_id and node.model_id.model == res_model:
|
||||
|
||||
data['res'] = resource = {}
|
||||
resource['name'] = current_object.name_get(context)[0][1]
|
||||
resource['model'] = res_model
|
||||
resource['id'] = res_id
|
||||
|
||||
try:
|
||||
data['active'] = eval(node.model_states, expr_context)
|
||||
except Exception, e:
|
||||
@@ -178,12 +166,60 @@ class process_process(osv.osv):
|
||||
roles.append(role)
|
||||
transitions[tr.id] = data
|
||||
|
||||
# now populate resource information
|
||||
def update_relatives(nid, ref_id, ref_model):
|
||||
relatives = []
|
||||
|
||||
for tid, tr in transitions.items():
|
||||
if tr['source'] == nid:
|
||||
relatives.append(tr['target'])
|
||||
if tr['target'] == nid:
|
||||
relatives.append(tr['source'])
|
||||
|
||||
if not ref_id:
|
||||
nodes[nid]['res'] = False
|
||||
return
|
||||
|
||||
nodes[nid]['res'] = resource = {'id': ref_id, 'model': ref_model}
|
||||
|
||||
refobj = pool.get(ref_model).browse(cr, uid, [ref_id], context)[0]
|
||||
fields = pool.get(ref_model).fields_get(cr, uid, context=context)
|
||||
|
||||
resource['name'] = refobj.name_get(context)[0][1]
|
||||
resource['perm'] = pool.get(ref_model).perm_read(cr, uid, [ref_id], context)[0]
|
||||
|
||||
for r in relatives:
|
||||
node = nodes[r]
|
||||
if 'res' not in node:
|
||||
for n, f in fields.items():
|
||||
if node['model'] == ref_model:
|
||||
update_relatives(r, ref_id, ref_model)
|
||||
|
||||
elif f.get('relation') == node['model']:
|
||||
rel = refobj[n]
|
||||
if rel and isinstance(rel, list) :
|
||||
rel = rel[0]
|
||||
if isinstance(rel, basestring):
|
||||
print "XXX: ", rel
|
||||
try: # XXXXXXXXXXXXXXXXXXX
|
||||
_id = (rel or False) and rel.id
|
||||
_model = node['model']
|
||||
update_relatives(r, _id, _model)
|
||||
except:
|
||||
pass
|
||||
|
||||
for nid, node in nodes.items():
|
||||
if not node['gray'] and (node['active'] or node['model'] == res_model):
|
||||
update_relatives(nid, res_id, res_model)
|
||||
break
|
||||
|
||||
# calculate graph layout
|
||||
g = tools.graph(nodes.keys(), map(lambda x: (x['source'], x['target']), transitions.values()))
|
||||
g.process(start)
|
||||
#g.scale(100, 100, 180, 120)
|
||||
g.scale(*scale)
|
||||
g.process(start)
|
||||
g.scale(*scale) #g.scale(100, 100, 180, 120)
|
||||
graph = g.result_get()
|
||||
|
||||
# fix the height problem
|
||||
miny = -1
|
||||
for k,v in nodes.items():
|
||||
x = graph[k]['y']
|
||||
@@ -198,7 +234,45 @@ class process_process(osv.osv):
|
||||
y = v['y']
|
||||
v['y'] = min(y - miny + 10, y)
|
||||
|
||||
return dict(title=title, notes=notes, nodes=nodes, transitions=transitions)
|
||||
return dict(title=title, perm=perm, notes=notes, nodes=nodes, transitions=transitions)
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context={}):
|
||||
""" Deep copy the entire process.
|
||||
"""
|
||||
|
||||
if not default:
|
||||
default = {}
|
||||
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
process = pool.get('process.process').browse(cr, uid, [id], context)[0]
|
||||
|
||||
nodes = {}
|
||||
transitions = {}
|
||||
|
||||
# first copy all nodes and and map the new nodes with original for later use in transitions
|
||||
for node in process.node_ids:
|
||||
for t in node.transition_in:
|
||||
tr = transitions.setdefault(t.id, {})
|
||||
tr['target'] = node.id
|
||||
for t in node.transition_out:
|
||||
tr = transitions.setdefault(t.id, {})
|
||||
tr['source'] = node.id
|
||||
nodes[node.id] = pool.get('process.node').copy(cr, uid, node.id, context=context)
|
||||
|
||||
# then copy transitions with new nodes
|
||||
for tid, tr in transitions.items():
|
||||
vals = {
|
||||
'source_node_id': nodes[tr['source']],
|
||||
'target_node_id': nodes[tr['target']]
|
||||
}
|
||||
tr = pool.get('process.transition').copy(cr, uid, tid, default=vals, context=context)
|
||||
|
||||
# and finally copy the process itself with new nodes
|
||||
default.update({
|
||||
'active': True,
|
||||
'node_ids': [(6, 0, nodes.values())]
|
||||
})
|
||||
return super(process_process, self).copy(cr, uid, id, default, context)
|
||||
|
||||
process_process()
|
||||
|
||||
@@ -217,13 +291,24 @@ class process_node(osv.osv):
|
||||
'flow_start': fields.boolean('Starting Flow'),
|
||||
'transition_in': fields.one2many('process.transition', 'target_node_id', 'Starting Transitions'),
|
||||
'transition_out': fields.one2many('process.transition', 'source_node_id', 'Ending Transitions'),
|
||||
'condition_ids': fields.one2many('process.condition', 'node_id', 'Conditions')
|
||||
'condition_ids': fields.one2many('process.condition', 'node_id', 'Conditions'),
|
||||
'help_url': fields.char('Help URL', size=255)
|
||||
}
|
||||
_defaults = {
|
||||
'kind': lambda *args: 'state',
|
||||
'model_states': lambda *args: False,
|
||||
'flow_start': lambda *args: False,
|
||||
}
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context={}):
|
||||
if not default:
|
||||
default = {}
|
||||
default.update({
|
||||
'transition_in': [],
|
||||
'transition_out': []
|
||||
})
|
||||
return super(process_node, self).copy(cr, uid, id, default, context)
|
||||
|
||||
process_node()
|
||||
|
||||
class process_node_condition(osv.osv):
|
||||
@@ -271,5 +356,16 @@ class process_transition_action(osv.osv):
|
||||
_defaults = {
|
||||
'state': lambda *args: 'dummy',
|
||||
}
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context={}):
|
||||
if not default:
|
||||
default = {}
|
||||
|
||||
state = self.pool.get('process.transition.action').browse(cr, uid, [id], context)[0].state
|
||||
if state:
|
||||
default['state'] = state
|
||||
|
||||
return super(process_transition_action, self).copy(cr, uid, id, default, context)
|
||||
|
||||
process_transition_action()
|
||||
|
||||
|
||||
@@ -21,17 +21,25 @@
|
||||
<notebook colspan="4">
|
||||
<page string="Nodes">
|
||||
<field name="node_ids" colspan="4" nolabel="1">
|
||||
<tree string="Process Nodes">
|
||||
<field name="name"/>
|
||||
<field name="model_id" select="1"/>
|
||||
<field name="kind" select="1"/>
|
||||
<field name="flow_start"/>
|
||||
</tree>
|
||||
<form string="Process Node">
|
||||
<group colspan="4" string="Details">
|
||||
<field name="name" select="1"/>
|
||||
<field name="flow_start"/>
|
||||
<newline/>
|
||||
<field name="process_id" invisible="1" readonly="1" required="0"/> <!-- used by transition_out -->
|
||||
<newline/>
|
||||
<field name="model_id" select="1"/>
|
||||
<field name="menu_id" select="2"/>
|
||||
<newline/>
|
||||
<field name="kind" select="1"/>
|
||||
<field name="help_url" widget="url"/>
|
||||
<field name="model_states"/>
|
||||
<field name="subflow_id"/>
|
||||
<field name="subflow_id" domain="[('name', '!=', parent.name)]"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Outgoing Transitions">
|
||||
@@ -44,7 +52,7 @@
|
||||
<group colspan="4" string="Details">
|
||||
<field name="name"/>
|
||||
<newline/>
|
||||
<field name="target_node_id"/>
|
||||
<field name="target_node_id" domain="[('process_id', '=', parent.process_id)]"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Buttons">
|
||||
@@ -159,6 +167,7 @@
|
||||
<field name="menu_id" select="2"/>
|
||||
<newline/>
|
||||
<field name="kind" select="1"/>
|
||||
<field name="help_url" widget="url"/>
|
||||
<field name="model_states"/>
|
||||
<field name="subflow_id"/>
|
||||
</group>
|
||||
@@ -173,7 +182,7 @@
|
||||
<group colspan="4" string="Details">
|
||||
<field name="name"/>
|
||||
<newline/>
|
||||
<field name="target_node_id"/>
|
||||
<field name="target_node_id" domain="[('process_id', '=', parent.process_id)]"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Buttons">
|
||||
|
||||
@@ -329,10 +329,9 @@ product_template()
|
||||
class product_product(osv.osv):
|
||||
def view_header_get(self, cr, uid, view_id, view_type, context):
|
||||
res = super(product_product, self).view_header_get(cr, uid, view_id, view_type, context)
|
||||
if res: return res
|
||||
if (not context.get('categ_id', False)):
|
||||
return False
|
||||
return _('Products: ')+self.pool.get('product.category').browse(cr, uid, context['categ_id'], context).name
|
||||
if (context.get('categ_id', False)):
|
||||
return _('Products: ')+self.pool.get('product.category').browse(cr, uid, context['categ_id'], context).name
|
||||
return res
|
||||
|
||||
def _product_price(self, cr, uid, ids, name, arg, context={}):
|
||||
res = {}
|
||||
@@ -589,6 +588,7 @@ class product_supplierinfo(osv.osv):
|
||||
}
|
||||
_defaults = {
|
||||
'qty': lambda *a: 0.0,
|
||||
'sequence': lambda *a: 1,
|
||||
'delay': lambda *a: 1,
|
||||
}
|
||||
_order = 'sequence'
|
||||
|
||||
@@ -260,7 +260,7 @@ class task(osv.osv):
|
||||
'sequence': fields.integer('Sequence'),
|
||||
'type': fields.many2one('project.task.type', 'Type'),
|
||||
'state': fields.selection([('draft', 'Draft'),('open', 'Open'),('pending', 'Pending'), ('cancelled', 'Cancelled'), ('done', 'Done')], 'Status', readonly=True, required=True),
|
||||
'date_start': fields.datetime('Date'),
|
||||
'date_start': fields.datetime('Date Opened'),
|
||||
'date_deadline': fields.datetime('Deadline'),
|
||||
'date_close': fields.datetime('Date Closed', readonly=True),
|
||||
'project_id': fields.many2one('project.project', 'Project', ondelete='cascade'),
|
||||
@@ -289,7 +289,7 @@ class task(osv.osv):
|
||||
'active': lambda *a: True,
|
||||
'date_start': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
}
|
||||
_order = "state, sequence, priority, date_deadline, id"
|
||||
_order = "sequence, priority, date_deadline, id"
|
||||
|
||||
#
|
||||
# Override view according to the company definition
|
||||
|
||||
@@ -14,10 +14,9 @@ class project_work(osv.osv):
|
||||
vals_line={}
|
||||
obj_task = self.pool.get('project.task').browse(cr, uid, vals['task_id'])
|
||||
|
||||
vals_line['name']=vals['name']
|
||||
vals_line['name']=obj_task.name + ': ' + vals['name']
|
||||
vals_line['user_id']=vals['user_id']
|
||||
c_date=datetime.date(int(vals['date'][:4]),int(vals['date'][5:7]),int(vals['date'][8:10]))
|
||||
vals_line['date']=c_date
|
||||
vals_line['date']=vals['date'][:10]
|
||||
vals_line['unit_amount']=vals['hours']
|
||||
vals_line['account_id']=obj_task.project_id.category_id.id
|
||||
vals_line['amount']=00.0
|
||||
@@ -32,17 +31,21 @@ class project_work(osv.osv):
|
||||
def write(self, cr, uid, ids,vals,context={}):
|
||||
vals_line={}
|
||||
|
||||
line_id=self.pool.get('project.task.work').browse(cr,uid,ids)[0].hr_analytic_timesheet_id
|
||||
task=self.pool.get('project.task.work').browse(cr,uid,ids)[0]
|
||||
line_id=task.hr_analytic_timesheet_id
|
||||
# in case,if a record is deleted from timesheet,but we change it from tasks!
|
||||
list_avail_ids=self.pool.get('hr.analytic.timesheet').search(cr,uid,[])
|
||||
if line_id in list_avail_ids:
|
||||
obj = self.pool.get('hr.analytic.timesheet')
|
||||
vals_line['name']=vals['name']
|
||||
vals_line['user_id']=vals['user_id']
|
||||
c_date=datetime.date(int(vals['date'][:4]),int(vals['date'][5:7]),int(vals['date'][8:10]))
|
||||
vals_line['date']=c_date
|
||||
vals_line['unit_amount']=vals['hours']
|
||||
vals_line['amount']=(-1) * vals['hours'] * obj.browse(cr,uid,line_id).product_id.standard_price
|
||||
if 'name' in vals:
|
||||
vals_line['name']=task.name+': '+vals['name']
|
||||
if 'user_id' in vals:
|
||||
vals_line['user_id']=vals['user_id']
|
||||
if 'date' in vals:
|
||||
vals_line['date']=vals['date'][:10]
|
||||
if 'hours' in vals:
|
||||
vals_line['unit_amount']=vals['hours']
|
||||
vals_line['amount']=(-1) * vals['hours'] * obj.browse(cr,uid,line_id).product_id.standard_price
|
||||
obj.write(cr, uid,[line_id],vals_line,{})
|
||||
|
||||
return super(project_work,self).write(cr, uid, ids,vals,context)
|
||||
@@ -62,5 +65,16 @@ class project_work(osv.osv):
|
||||
|
||||
|
||||
project_work()
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
class project_project(osv.osv):
|
||||
_inherit = "project.project"
|
||||
def name_get(self, cr, user, ids, context=None):
|
||||
result = []
|
||||
for project in self.browse(cr, user, ids, context):
|
||||
if project.category_id:
|
||||
result.append((project.id, '['+(project.category_id.code or '')+'] '+project.name))
|
||||
else:
|
||||
result.append((project.id, '[?] '+project.name))
|
||||
return result
|
||||
project_project()
|
||||
|
||||
|
||||
@@ -169,9 +169,9 @@
|
||||
<form string="Purchase Order Line">
|
||||
<notebook>
|
||||
<page string="Order Line">
|
||||
<field colspan="4" context="partner_id=parent.partner_id,quantity=product_qty,pricelist=parent.pricelist_id,uom=product_uom,warehouse=parent.warehouse_id" name="product_id" on_change="product_id_change(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order)"/>
|
||||
<field name="product_qty"/>
|
||||
<field name="product_uom" on_change="product_uom_change(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order)"/>
|
||||
<field colspan="4" context="partner_id=parent.partner_id,quantity=product_qty,pricelist=parent.pricelist_id,uom=product_uom,warehouse=parent.warehouse_id" name="product_id" on_change="product_id_change(parent.pricelist_id,product_id,product_qty,product_uom,parent.partner_id, parent.date_order)"/>
|
||||
<field colspan="4" name="name"/>
|
||||
<field name="date_planned"/>
|
||||
<field name="price_unit"/>
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
import sale
|
||||
import stock
|
||||
import partner
|
||||
import product
|
||||
|
||||
import wizard
|
||||
import report
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
"sale_report.xml",
|
||||
"sale_wizard.xml",
|
||||
"stock_view.xml",
|
||||
"product_view.xml",
|
||||
],
|
||||
"active": False,
|
||||
"installable": True
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2008 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
|
||||
from tools import config
|
||||
|
||||
class product_pricelist(osv.osv):
|
||||
_inherit = "product.pricelist"
|
||||
def _compute_price(self, cr, uid, ids, field_name, arg, context):
|
||||
res = {}
|
||||
for id in ids:
|
||||
res[id]=0.0
|
||||
return res
|
||||
_columns = {
|
||||
'price': fields.function(_compute_price, type='float', method=True, string='Price', digits=(16, int(config['price_accuracy']))),
|
||||
}
|
||||
product_pricelist()
|
||||
|
||||
class product_product(osv.osv):
|
||||
_name = 'product.product'
|
||||
_inherit = 'product.product'
|
||||
|
||||
def _pricelist_sale_ids(self, cr, uid, ids, name, arg, context=None):
|
||||
result = {}
|
||||
if not context:
|
||||
context={}
|
||||
pricelist_obj=self.pool.get('product.pricelist')
|
||||
for product in self.browse(cr, uid, ids, context):
|
||||
pricelist_ids=pricelist_obj.search(cr,uid,[('type','=','sale')], context=context)
|
||||
result[product.id]=pricelist_ids
|
||||
return result
|
||||
|
||||
def _pricelist_purchase_ids(self, cr, uid, ids, name, arg, context=None):
|
||||
result = {}
|
||||
pricelist_obj=self.pool.get('product.pricelist')
|
||||
for product in self.browse(cr, uid, ids, context):
|
||||
pricelist_ids=pricelist_obj.search(cr,uid,[('type','=','purchase')])
|
||||
result[product.id]=pricelist_ids
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
'pricelist_sale':fields.function(
|
||||
_pricelist_sale_ids,
|
||||
method=True,
|
||||
relation='product.pricelist',
|
||||
string='Sale Pricelists',
|
||||
type="many2many"),
|
||||
'pricelist_purchase':fields.function(
|
||||
_pricelist_purchase_ids,
|
||||
method=True,
|
||||
relation='product.pricelist',
|
||||
string='Purchase Pricelists',
|
||||
type="many2many"),
|
||||
}
|
||||
|
||||
product_product()
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="view_product_pricelists_function_form" model="ir.ui.view">
|
||||
<field name="name">view.product.pricelists.function.form.inherit</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="product.product_normal_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<field colspan="4" name="seller_ids" nolabel="1" position="after">
|
||||
<group colspan="4" groups="base.group_extended">
|
||||
<separator string="Sale Pricelists" colspan="2"/>
|
||||
<separator string="Purchase Pricelists" colspan="2"/>
|
||||
<field nolabel="1" name="pricelist_sale" colspan="2">
|
||||
<tree string="Sale Price List">
|
||||
<field name="name"/>
|
||||
<field name="price" context="{'product_id':parent.id}"/>
|
||||
</tree>
|
||||
</field>
|
||||
<field nolabel="1" name="pricelist_purchase" colspan="2" context="product_id=parent.id">
|
||||
<tree string="Purchase Price List" context="product_id=parent.id">
|
||||
<field name="name"/>
|
||||
<field name="price" context="product_id=parent.id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
+17
-4
@@ -214,7 +214,8 @@ class sale_order(osv.osv):
|
||||
'partner_shipping_id':fields.many2one('res.partner.address', 'Shipping Address', readonly=True, required=True, states={'draft':[('readonly',False)]}),
|
||||
|
||||
'incoterm': fields.selection(_incoterm_get, 'Incoterm',size=3),
|
||||
'picking_policy': fields.selection([('direct','Partial Delivery'),('one','Complete Delivery')], 'Packing Policy', required=True),
|
||||
'picking_policy': fields.selection([('direct','Partial Delivery'),('one','Complete Delivery')],
|
||||
'Packing Policy', required=True, help="""If you don't have enough stock available to deliver all at once, do you accept partial shippings or not."""),
|
||||
'order_policy': fields.selection([
|
||||
('prepaid','Payment before delivery'),
|
||||
('manual','Shipping & Manual Invoice'),
|
||||
@@ -928,15 +929,27 @@ class sale_config_picking_policy(osv.osv_memory):
|
||||
_name='sale.config.picking_policy'
|
||||
_columns = {
|
||||
'name':fields.char('Name', size=64),
|
||||
'picking_policy': fields.selection([('direct','Direct Delivery'),('one','All at once')], 'Packing Policy', required=True ),
|
||||
'picking_policy': fields.selection([
|
||||
('direct','Direct Delivery'),
|
||||
('one','All at once')
|
||||
], 'Packing Policy', required=True ),
|
||||
'order_policy': fields.selection([
|
||||
('manual','Invoice based on Sales Orders'),
|
||||
('picking','Invoice based on Deliveries'),
|
||||
], 'Shipping Policy', required=True, readonly=True, states={'draft':[('readonly',False)]}),
|
||||
}
|
||||
_defaults={
|
||||
'picking_policy': lambda *a: 'direct',
|
||||
'order_policy': lambda *a: 'picking'
|
||||
}
|
||||
def set_default(self, cr, uid, ids, context=None):
|
||||
if 'name' in context:
|
||||
print context
|
||||
for o in self.browse(cr, uid, ids, context=context):
|
||||
print o.picking_policy, o.order_policy
|
||||
ir_values_obj = self.pool.get('ir.values')
|
||||
ir_values_obj.set(cr,uid,'default',False,'picking_policy',['sale.order'],context['picking_policy'])
|
||||
ir_values_obj.set(cr,uid,'default',False,'picking_policy',['sale.order'],o.picking_policy)
|
||||
ir_values_obj = self.pool.get('ir.values')
|
||||
ir_values_obj.set(cr,uid,'default',False,'order_policy',['sale.order'],o.order_policy)
|
||||
return {
|
||||
'view_type': 'form',
|
||||
"view_mode": 'form',
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">sale.shop</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_shop_tree"/>
|
||||
</record>
|
||||
<menuitem id="menu_shop_configuration" name="Configuration" parent="sale.menu_sale_root" sequence="1"/>
|
||||
@@ -93,7 +94,7 @@
|
||||
<form string="Sales order">
|
||||
<group col="6" colspan="4">
|
||||
<field name="name" select="1"/>
|
||||
<field name="client_order_ref"/>
|
||||
<field name="client_order_ref" select="2"/>
|
||||
<field name="shipped" select="2"/>
|
||||
<field name="shop_id" on_change="onchange_shop_id(shop_id)" select="2"/>
|
||||
<field name="date_order" select="1"/>
|
||||
@@ -221,6 +222,7 @@
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">sale.order</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form,calendar,graph</field>
|
||||
</record>
|
||||
<menuitem action="action_order_form" id="menu_sale_order" parent="sale.menu_sale_root"/>
|
||||
|
||||
@@ -453,10 +455,12 @@
|
||||
<field name="model">sale.config.picking_policy</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Configure Picking Policy for Sale Order">
|
||||
<separator col="4" colspan="4" string="Configure Picking Policy for Sale Order"/>
|
||||
<form string="Sales Configuration">
|
||||
<separator colspan="4" string="Configure Sale Order Logistic"/>
|
||||
<newline/>
|
||||
<field name="picking_policy"/>
|
||||
<newline/>
|
||||
<field name="order_policy"/>
|
||||
<group col="4" colspan="4">
|
||||
<button icon="gtk-cancel" name="action_cancel" type="object" special="cancel" string="Cancel"/>
|
||||
<button icon="gtk-ok" name="set_default" string="Set Default" type="object"/>
|
||||
|
||||
+154
-37
@@ -32,63 +32,180 @@ from osv import fields, osv
|
||||
|
||||
class product_product(osv.osv):
|
||||
_inherit = "product.product"
|
||||
# def view_header_get(self, cr, user, view_id, view_type, context):
|
||||
# print self, cr, user
|
||||
# res = super(product_product, self).view_header_get(cr, user, view_id, view_type, context)
|
||||
# if res: return res
|
||||
# if (not context.get('location', False)):
|
||||
# return False
|
||||
# cr.execute('select name from stock_location where id=%d', (context['location'],))
|
||||
# j = cr.fetchone()[0]
|
||||
# if j:
|
||||
# return 'Products: '+j
|
||||
# return False
|
||||
#
|
||||
def _get_product_available_func(states, what):
|
||||
def _product_available(self, cr, uid, ids, name, arg, context={}):
|
||||
if context.get('shop', False):
|
||||
cr.execute('select warehouse_id from sale_shop where id=%d', (int(context['shop']),))
|
||||
res2 = cr.fetchone()
|
||||
if res2:
|
||||
context['warehouse'] = res2[0]
|
||||
def view_header_get(self, cr, user, view_id, view_type, context):
|
||||
res = super(product_product, self).view_header_get(cr, user, view_id, view_type, context)
|
||||
if res: return res
|
||||
if (context.get('location', False)):
|
||||
return _('Products: ')+self.pool.get('stock.location').browse(cr, user, context['location'], context).name
|
||||
return res
|
||||
|
||||
if context.get('warehouse', False):
|
||||
cr.execute('select lot_stock_id from stock_warehouse where id=%d', (int(context['warehouse']),))
|
||||
res2 = cr.fetchone()
|
||||
if res2:
|
||||
context['location'] = res2[0]
|
||||
def get_product_available(self,cr,uid,ids,context=None):
|
||||
if not context:
|
||||
context = {}
|
||||
print 'CONTEXT', context
|
||||
states=context.get('states',[])
|
||||
what=context.get('what',())
|
||||
if not ids:
|
||||
ids = self.search(cr, uid, [])
|
||||
res = {}.fromkeys(ids, 0.0)
|
||||
if not ids:
|
||||
return res
|
||||
|
||||
if context.get('location', False):
|
||||
if context.get('shop', False):
|
||||
cr.execute('select warehouse_id from sale_shop where id=%d', (int(context['shop']),))
|
||||
res2 = cr.fetchone()
|
||||
if res2:
|
||||
context['warehouse'] = res2[0]
|
||||
|
||||
if context.get('warehouse', False):
|
||||
cr.execute('select lot_stock_id from stock_warehouse where id=%d', (int(context['warehouse']),))
|
||||
res2 = cr.fetchone()
|
||||
if res2:
|
||||
context['location'] = res2[0]
|
||||
|
||||
if context.get('location', False):
|
||||
if type(context['location']) == type(1):
|
||||
location_ids = [context['location']]
|
||||
else:
|
||||
cr.execute("select lot_stock_id from stock_warehouse")
|
||||
location_ids = [id for (id,) in cr.fetchall()]
|
||||
location_ids = context['location']
|
||||
else:
|
||||
cr.execute("select lot_stock_id from stock_warehouse")
|
||||
location_ids = [id for (id,) in cr.fetchall()]
|
||||
|
||||
# build the list of ids of children of the location given by id
|
||||
location_ids = self.pool.get('stock.location').search(cr, uid, [('location_id', 'child_of', location_ids)])
|
||||
res = self.pool.get('stock.location')._product_get_multi_location(cr, uid, location_ids, ids, context, states, what)
|
||||
# build the list of ids of children of the location given by id
|
||||
location_ids = self.pool.get('stock.location').search(cr, uid, [('location_id', 'child_of', location_ids)])
|
||||
|
||||
states_str = ','.join(map(lambda s: "'%s'" % s, states))
|
||||
|
||||
product2uom = {}
|
||||
for product in self.browse(cr, uid, ids, context=context):
|
||||
product2uom[product.id] = product.uom_id.id
|
||||
|
||||
prod_ids_str = ','.join(map(str, ids))
|
||||
location_ids_str = ','.join(map(str, location_ids))
|
||||
results = []
|
||||
results2 = []
|
||||
|
||||
from_date=context.get('from_date',False)
|
||||
to_date=context.get('to_date',False)
|
||||
date_str=False
|
||||
if from_date and to_date:
|
||||
date_str="date>='%s' and date<=%s"%(from_date,to_date)
|
||||
elif from_date:
|
||||
date_str="date>='%s'"%(from_date)
|
||||
elif to_date:
|
||||
date_str="date<='%s'"%(to_date)
|
||||
|
||||
if 'in' in what:
|
||||
# all moves from a location out of the set to a location in the set
|
||||
cr.execute(
|
||||
'select sum(product_qty), product_id, product_uom '\
|
||||
'from stock_move '\
|
||||
'where location_id not in ('+location_ids_str+') '\
|
||||
'and location_dest_id in ('+location_ids_str+') '\
|
||||
'and product_id in ('+prod_ids_str+') '\
|
||||
'and state in ('+states_str+') '+ (date_str and 'and '+date_str+' ' or '') +''\
|
||||
'group by product_id,product_uom'
|
||||
)
|
||||
results = cr.fetchall()
|
||||
if 'out' in what:
|
||||
# all moves from a location in the set to a location out of the set
|
||||
cr.execute(
|
||||
'select sum(product_qty), product_id, product_uom '\
|
||||
'from stock_move '\
|
||||
'where location_id in ('+location_ids_str+') '\
|
||||
'and location_dest_id not in ('+location_ids_str+') '\
|
||||
'and product_id in ('+prod_ids_str+') '\
|
||||
'and state in ('+states_str+') '+ (date_str and 'and '+date_str+' ' or '') + ''\
|
||||
'group by product_id,product_uom'
|
||||
)
|
||||
results2 = cr.fetchall()
|
||||
uom_obj = self.pool.get('product.uom')
|
||||
for amount, prod_id, prod_uom in results:
|
||||
amount = uom_obj._compute_qty(cr, uid, prod_uom, amount,
|
||||
context.get('uom', False) or product2uom[prod_id])
|
||||
res[prod_id] += amount
|
||||
for amount, prod_id, prod_uom in results2:
|
||||
amount = uom_obj._compute_qty(cr, uid, prod_uom, amount,
|
||||
context.get('uom', False) or product2uom[prod_id])
|
||||
res[prod_id] -= amount
|
||||
return res
|
||||
|
||||
def _get_product_available_func(states, what):
|
||||
def _product_available(self, cr, uid, ids, field_names=False, arg=False, context={}):
|
||||
context.update({
|
||||
'states':states,
|
||||
'what':what
|
||||
})
|
||||
stock=self.get_product_available(cr,uid,ids,context=context)
|
||||
res = {}
|
||||
for id in ids:
|
||||
res.setdefault(id, 0.0)
|
||||
res[id] = {}.fromkeys(field_names, 0.0)
|
||||
for a in field_names:
|
||||
res[id][a] = stock.get(id, 0.0)
|
||||
return res
|
||||
|
||||
return _product_available
|
||||
|
||||
_product_qty_available = _get_product_available_func(('done',), ('in', 'out'))
|
||||
_product_virtual_available = _get_product_available_func(('confirmed','waiting','assigned','done'), ('in', 'out'))
|
||||
_product_outgoing_qty = _get_product_available_func(('confirmed','waiting','assigned'), ('out',))
|
||||
_product_incoming_qty = _get_product_available_func(('confirmed','waiting','assigned'), ('in',))
|
||||
|
||||
|
||||
_columns = {
|
||||
'qty_available': fields.function(_product_qty_available, method=True, type='float', string='Real Stock', help="Current quantities of products in selected locations or all internal if none have been selected."),
|
||||
'virtual_available': fields.function(_product_virtual_available, method=True, type='float', string='Virtual Stock', help="Futur stock for this product according to the selected location or all internal if none have been selected. Computed as: Real Stock - Outgoing + Incoming."),
|
||||
'incoming_qty': fields.function(_product_incoming_qty, method=True, type='float', string='Incoming', help="Quantities of products that are planned to arrive in selected locations or all internal if none have been selected."),
|
||||
'outgoing_qty': fields.function(_product_outgoing_qty, method=True, type='float', string='Outgoing', help="Quantities of products that are planned to leave in selected locations or all internal if none have been selected."),
|
||||
'qty_available': fields.function(_product_qty_available, method=True, type='float', string='Real Stock',multi='qty_available', help="Current quantities of products in selected locations or all internal if none have been selected."),
|
||||
'virtual_available': fields.function(_product_virtual_available, method=True, type='float', string='Virtual Stock',multi='qty_available', help="Futur stock for this product according to the selected location or all internal if none have been selected. Computed as: Real Stock - Outgoing + Incoming."),
|
||||
'incoming_qty': fields.function(_product_incoming_qty, method=True, type='float', string='Incoming',multi='qty_available', help="Quantities of products that are planned to arrive in selected locations or all internal if none have been selected."),
|
||||
'outgoing_qty': fields.function(_product_outgoing_qty, method=True, type='float', string='Outgoing',multi='qty_available', help="Quantities of products that are planned to leave in selected locations or all internal if none have been selected."),
|
||||
'track_production' : fields.boolean('Track Production Lots' , help="Force to use a Production Lot during production order"),
|
||||
'track_incoming' : fields.boolean('Track Incomming Lots', help="Force to use a Production Lot during receptions"),
|
||||
'track_outgoing' : fields.boolean('Track Outging Lots', help="Force to use a Production Lot during deliveries"),
|
||||
}
|
||||
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False):
|
||||
res = super(product_product,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar)
|
||||
if ('location' in context) and context['location']:
|
||||
location_info = self.pool.get('stock.location').browse(cr, uid, context['location'])
|
||||
fields=res.get('fields',{})
|
||||
if fields:
|
||||
if location_info.usage == 'supplier':
|
||||
if fields.get('virtual_available'):
|
||||
res['fields']['virtual_available']['string'] = 'Futur Receptions'
|
||||
if fields.get('qty_available'):
|
||||
res['fields']['qty_available']['string'] = 'Received Qty'
|
||||
|
||||
if location_info.usage == 'internal':
|
||||
if fields.get('virtual_available'):
|
||||
res['fields']['virtual_available']['string'] = 'Futur Stock'
|
||||
|
||||
if location_info.usage == 'customer':
|
||||
if fields.get('virtual_available'):
|
||||
res['fields']['virtual_available']['string'] = 'Futur Deliveries'
|
||||
if fields.get('qty_available'):
|
||||
res['fields']['qty_available']['string'] = 'Delivered Qty'
|
||||
|
||||
if location_info.usage == 'inventory':
|
||||
if fields.get('virtual_available'):
|
||||
res['fields']['virtual_available']['string'] = 'Futur P&L'
|
||||
res['fields']['qty_available']['string'] = 'P&L Qty'
|
||||
|
||||
if location_info.usage == 'procurement':
|
||||
if fields.get('virtual_available'):
|
||||
res['fields']['virtual_available']['string'] = 'Futur Qty'
|
||||
if fields.get('qty_available'):
|
||||
res['fields']['qty_available']['string'] = 'Unplanned Qty'
|
||||
|
||||
if location_info.usage == 'production':
|
||||
if fields.get('virtual_available'):
|
||||
res['fields']['virtual_available']['string'] = 'Futur Productions'
|
||||
if fields.get('qty_available'):
|
||||
res['fields']['qty_available']['string'] = 'Produced Qty'
|
||||
|
||||
return res
|
||||
product_product()
|
||||
|
||||
|
||||
class product_product(osv.osv):
|
||||
class product_template(osv.osv):
|
||||
_name = 'product.template'
|
||||
_inherit = 'product.template'
|
||||
_columns = {
|
||||
@@ -126,7 +243,7 @@ class product_product(osv.osv):
|
||||
help='This account will be used, instead of the default one, to value output stock'),
|
||||
}
|
||||
|
||||
product_product()
|
||||
product_template()
|
||||
|
||||
|
||||
class product_category(osv.osv):
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<group name="status" position="after">
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Stocks" colspan="4"/>
|
||||
<separator string="Stocks" colspan="4"/>
|
||||
<field name="qty_available"/>
|
||||
<field name="virtual_available"/>
|
||||
<field name="incoming_qty"/>
|
||||
|
||||
@@ -79,6 +79,8 @@ class report_stock(report_int):
|
||||
for (qty, dt, prod_id) in cr.fetchall():
|
||||
if dt<=dt_from:
|
||||
dt= (DateTime.now() + DateTime.RelativeDateTime(days=1)).strftime('%Y-%m-%d')
|
||||
else:
|
||||
dt = dt[:10]
|
||||
products.setdefault(prod_id, [])
|
||||
products[prod_id].append((dt,-qty))
|
||||
|
||||
@@ -86,6 +88,8 @@ class report_stock(report_int):
|
||||
for (qty, dt, prod_id) in cr.fetchall():
|
||||
if dt<=dt_from:
|
||||
dt= (DateTime.now() + DateTime.RelativeDateTime(days=1)).strftime('%Y-%m-%d')
|
||||
else:
|
||||
dt = dt[:10]
|
||||
products.setdefault(prod_id, [])
|
||||
products[prod_id].append((dt,qty))
|
||||
|
||||
|
||||
+11
-100
@@ -201,69 +201,14 @@ class stock_location(osv.osv):
|
||||
})
|
||||
return result
|
||||
|
||||
def _product_get_multi_location(self, cr, uid, ids, product_ids=False, context={}, states=['done'], what=('in', 'out')):
|
||||
|
||||
product_obj = self.pool.get('product.product')
|
||||
states_str = ','.join(map(lambda s: "'%s'" % s, states))
|
||||
if not product_ids:
|
||||
product_ids = product_obj.search(cr, uid, [])
|
||||
res = {}.fromkeys(product_ids, 0.0)
|
||||
if not ids:
|
||||
return res
|
||||
|
||||
product2uom = {}
|
||||
for product in product_obj.browse(cr, uid, product_ids, context=context):
|
||||
product2uom[product.id] = product.uom_id.id
|
||||
|
||||
prod_ids_str = ','.join(map(str, product_ids))
|
||||
location_ids_str = ','.join(map(str, ids))
|
||||
results = []
|
||||
results2 = []
|
||||
|
||||
from_date=context.get('from_date',False)
|
||||
to_date=context.get('to_date',False)
|
||||
date_str=False
|
||||
if from_date and to_date:
|
||||
date_str="date>='%s' and date<=%s"%(from_date,to_date)
|
||||
elif from_date:
|
||||
date_str="date>='%s'"%(from_date)
|
||||
elif to_date:
|
||||
date_str="date<='%s'"%(to_date)
|
||||
|
||||
if 'in' in what:
|
||||
# all moves from a location out of the set to a location in the set
|
||||
cr.execute(
|
||||
'select sum(product_qty), product_id, product_uom '\
|
||||
'from stock_move '\
|
||||
'where location_id not in ('+location_ids_str+') '\
|
||||
'and location_dest_id in ('+location_ids_str+') '\
|
||||
'and product_id in ('+prod_ids_str+') '\
|
||||
'and state in ('+states_str+') '+ (date_str and 'and '+date_str+' ' or '') +''\
|
||||
'group by product_id,product_uom'
|
||||
)
|
||||
results = cr.fetchall()
|
||||
if 'out' in what:
|
||||
# all moves from a location in the set to a location out of the set
|
||||
cr.execute(
|
||||
'select sum(product_qty), product_id, product_uom '\
|
||||
'from stock_move '\
|
||||
'where location_id in ('+location_ids_str+') '\
|
||||
'and location_dest_id not in ('+location_ids_str+') '\
|
||||
'and product_id in ('+prod_ids_str+') '\
|
||||
'and state in ('+states_str+') '+ (date_str and 'and '+date_str+' ' or '') + ''\
|
||||
'group by product_id,product_uom'
|
||||
)
|
||||
results2 = cr.fetchall()
|
||||
uom_obj = self.pool.get('product.uom')
|
||||
for amount, prod_id, prod_uom in results:
|
||||
amount = uom_obj._compute_qty(cr, uid, prod_uom, amount,
|
||||
context.get('uom', False) or product2uom[prod_id])
|
||||
res[prod_id] += amount
|
||||
for amount, prod_id, prod_uom in results2:
|
||||
amount = uom_obj._compute_qty(cr, uid, prod_uom, amount,
|
||||
context.get('uom', False) or product2uom[prod_id])
|
||||
res[prod_id] -= amount
|
||||
return res
|
||||
def _product_get_multi_location(self, cr, uid, ids, product_ids=False, context={}, states=['done'], what=('in', 'out')):
|
||||
product_obj = self.pool.get('product.product')
|
||||
context.update({
|
||||
'states':states,
|
||||
'what':what,
|
||||
'location':ids
|
||||
})
|
||||
return product_obj.get_product_available(cr,uid,product_ids,context=context)
|
||||
|
||||
def _product_get(self, cr, uid, id, product_ids=False, context={}, states=['done']):
|
||||
ids = id and [id] or []
|
||||
@@ -434,7 +379,8 @@ class stock_picking(osv.osv):
|
||||
], 'Status', readonly=True, select=True),
|
||||
'min_date': fields.function(get_min_max_date, fnct_inv=_set_minimum_date, multi="min_max_date",
|
||||
method=True,store=True, type='datetime', string='Planned Date', select=1),
|
||||
'date':fields.datetime('Date create'),
|
||||
'date':fields.datetime('Date Order'),
|
||||
'date_done':fields.datetime('Date Done'),
|
||||
'max_date': fields.function(get_min_max_date, fnct_inv=_set_maximum_date, multi="min_max_date",
|
||||
method=True,store=True, type='datetime', string='Max. Planned Date', select=2),
|
||||
'move_lines': fields.one2many('stock.move', 'picking_id', 'Move lines'),
|
||||
@@ -569,7 +515,7 @@ class stock_picking(osv.osv):
|
||||
# TODO: change and create a move if not parents
|
||||
#
|
||||
def action_done(self, cr, uid, ids, context=None):
|
||||
self.write(cr,uid, ids, {'state':'done'})
|
||||
self.write(cr,uid, ids, {'state':'done', 'date_done': time.strftime('%Y-%m-%d %H:%M:%S')})
|
||||
return True
|
||||
|
||||
def action_move(self, cr, uid, ids, context={}):
|
||||
@@ -1383,39 +1329,4 @@ class stock_picking_move_wizard(osv.osv_memory):
|
||||
return {'type':'ir.actions.act_window_close' }
|
||||
|
||||
stock_picking_move_wizard()
|
||||
|
||||
class product_product(osv.osv):
|
||||
_inherit = 'product.product'
|
||||
|
||||
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False):
|
||||
res = super(product_product,self).fields_view_get(cr, uid, view_id, view_type, context, toolbar)
|
||||
if ('location' in context) and context['location']:
|
||||
location_info = self.pool.get('stock.location').browse(cr, uid, context['location'])
|
||||
|
||||
if location_info.usage == 'supplier':
|
||||
res['fields']['virtual_available']['string'] = 'Futur Receptions'
|
||||
res['fields']['qty_available']['string'] = 'Received Qty'
|
||||
|
||||
if location_info.usage == 'internal':
|
||||
res['fields']['virtual_available']['string'] = 'Futur Stock'
|
||||
|
||||
if location_info.usage == 'customer':
|
||||
res['fields']['virtual_available']['string'] = 'Futur Deliveries'
|
||||
res['fields']['qty_available']['string'] = 'Delivered Qty'
|
||||
|
||||
if location_info.usage == 'inventory':
|
||||
res['fields']['virtual_available']['string'] = 'Futur P&L'
|
||||
res['fields']['qty_available']['string'] = 'P&L Qty'
|
||||
|
||||
if location_info.usage == 'procurement':
|
||||
res['fields']['virtual_available']['string'] = 'Futur Qty'
|
||||
res['fields']['qty_available']['string'] = 'Unplanned Qty'
|
||||
|
||||
if location_info.usage == 'production':
|
||||
res['fields']['virtual_available']['string'] = 'Futur Productions'
|
||||
res['fields']['qty_available']['string'] = 'Produced Qty'
|
||||
|
||||
return res
|
||||
|
||||
product_product()
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
@@ -492,12 +492,12 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree color="red:state=='cancel'" string="Packing list">
|
||||
<field name="name"/>
|
||||
<field name="address_id" select="1"/>
|
||||
<field name="invoice_state"/>
|
||||
<field name="origin"/>
|
||||
<field name="address_id" select="1"/>
|
||||
<field name="backorder_id"/>
|
||||
<field name="date"/>
|
||||
<field name="min_date"/>
|
||||
<field name="invoice_state"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
@@ -568,6 +568,7 @@
|
||||
<field name="active" select="2"/>
|
||||
<field name="auto_picking"/>
|
||||
<field name="invoice_state" select="2"/>
|
||||
<field name="date_done" select="2"/>
|
||||
<newline/>
|
||||
<field name="move_type"/>
|
||||
</page>
|
||||
@@ -587,8 +588,9 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree color="red:state=='cancel'" string="Packing list">
|
||||
<field name="name"/>
|
||||
<field name="address_id" select="1"/>
|
||||
<field name="origin"/>
|
||||
<field name="address_id" select="1"/>
|
||||
<field name="backorder_id"/>
|
||||
<field name="date" select="1"/>
|
||||
<field name="min_date" select="1"/>
|
||||
<field name="state" select="1"/>
|
||||
@@ -655,8 +657,9 @@
|
||||
<field name="auto_picking"/>
|
||||
<field name="active" select="2"/>
|
||||
<newline/>
|
||||
<field name="move_type"/>
|
||||
<field name="date" select="1"/>
|
||||
<field name="date_done" select="2"/>
|
||||
<field name="move_type"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
@@ -771,10 +774,12 @@
|
||||
<field name="arch" type="xml">
|
||||
<tree color="red:state=='cancel'" string="Packing list">
|
||||
<field name="name"/>
|
||||
<field name="origin"/>
|
||||
<field name="address_id"/>
|
||||
<field name="backorder_id"/>
|
||||
<field name="date"/>
|
||||
<field name="min_date"/>
|
||||
<field name="invoice_state"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
@@ -839,8 +844,9 @@
|
||||
<field name="active" select="2"/>
|
||||
<field name="auto_picking"/>
|
||||
<newline/>
|
||||
<field name="move_type"/>
|
||||
<field name="date" select="2"/>
|
||||
<field name="date_done" select="2"/>
|
||||
<field name="move_type"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
@@ -940,13 +946,13 @@
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree color="red:state=='cancel'" string="Packing list">
|
||||
<field colspan="4" name="name"/>
|
||||
<field name="address_id" select="1"/>
|
||||
<field name="invoice_state"/>
|
||||
<field name="name"/>
|
||||
<field name="origin"/>
|
||||
<field name="address_id"/>
|
||||
<field name="backorder_id"/>
|
||||
<field name="date"/>
|
||||
<field name="min_date"/>
|
||||
<field name="invoice_state"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
||||
@@ -34,24 +34,27 @@ import time
|
||||
|
||||
def _action_open_window(self, cr, uid, data, context):
|
||||
return {
|
||||
'view_type': 'form',
|
||||
"view_mode": 'tree,form',
|
||||
'res_model': 'product.product',
|
||||
'type': 'ir.actions.act_window',
|
||||
'context':{'location': data['ids'][0],'from_date':data['form']['from_date'],'to_date':data['form']['to_date']},
|
||||
'domain':[('type','<>','service')]
|
||||
}
|
||||
'name': False,
|
||||
'view_type': 'form',
|
||||
"view_mode": 'tree,form',
|
||||
'res_model': 'product.product',
|
||||
'type': 'ir.actions.act_window',
|
||||
'context':{'location': data['ids'][0],'from_date':data['form']['from_date'],'to_date':data['form']['to_date']},
|
||||
'domain':[('type','<>','service')]
|
||||
}
|
||||
|
||||
|
||||
class product_by_location(wizard.interface):
|
||||
|
||||
form1 = '''<?xml version="1.0"?>
|
||||
<form string="View Stock of Products">
|
||||
<separator string="Stock Location Analysis" colspan="4"/>
|
||||
<field name="from_date"/>
|
||||
<newline/>
|
||||
<field name="to_date"/>
|
||||
<newline/>
|
||||
<label string=""/>
|
||||
<label string="(Keep empty to open the current situation)" align="0.0" colspan="3"/>
|
||||
</form>'''
|
||||
|
||||
form1_fields = {
|
||||
'from_date': {
|
||||
'string': 'From',
|
||||
@@ -66,13 +69,11 @@ class product_by_location(wizard.interface):
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [],
|
||||
'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, 'state': [ ('open', 'Open Products'),('end', 'Cancel')]}
|
||||
'result': {'type': 'form', 'arch':form1, 'fields':form1_fields, 'state': [('end', 'Cancel','gtk-cancel'),('open', 'Open Products','gtk-ok')]}
|
||||
},
|
||||
'open': {
|
||||
'actions': [],
|
||||
'result': {'type': 'action', 'action': _action_open_window, 'state':'end'}
|
||||
}
|
||||
}
|
||||
|
||||
product_by_location('stock.location.products')
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
||||
Reference in New Issue
Block a user