Merge lp:~extra-addons-commiter/e-commerce-addons/trunk into lp:~extra-addons-commiter/e-commerce-addons/7.0

Proposed by Sébastien BEAU - http://www.akretion.com
Status: Merged
Merged at revision: 280
Proposed branch: lp:~extra-addons-commiter/e-commerce-addons/trunk
Merge into: lp:~extra-addons-commiter/e-commerce-addons/7.0
Diff against target: 1108 lines (+424/-248)
33 files modified
base_sale_export_partner/__openerp__.py (+1/-1)
base_sale_export_product/__openerp__.py (+1/-1)
base_sale_multichannels/__openerp__.py (+1/-1)
base_sale_multichannels/connector.py (+37/-0)
base_sale_multichannels/partner.py (+1/-0)
base_sale_multichannels/sale.py (+3/-1)
base_sale_report_synchronizer/__openerp__.py (+1/-1)
product_custom_attributes_shop/__openerp__.py (+1/-1)
product_images_sync/__openerp__.py (+1/-1)
product_links/__openerp__.py (+1/-1)
product_links_goodies/__openerp__.py (+1/-1)
product_links_sync/__openerp__.py (+1/-1)
sale_automatic_workflow/__init__.py (+2/-1)
sale_automatic_workflow/__openerp__.py (+6/-2)
sale_automatic_workflow/automatic_workflow_job.py (+1/-1)
sale_automatic_workflow/invoice.py (+112/-0)
sale_automatic_workflow/sale.py (+1/-75)
sale_automatic_workflow/stock.py (+65/-0)
sale_exceptions/__openerp__.py (+1/-1)
sale_exceptions/sale.py (+4/-4)
sale_exceptions/sale_view.xml (+6/-33)
sale_exceptions/wizard/sale_exception_confirm_view.xml (+17/-18)
sale_quick_payment/__init__.py (+1/-3)
sale_quick_payment/__openerp__.py (+5/-5)
sale_quick_payment/account_voucher.py (+33/-0)
sale_quick_payment/company.py (+0/-33)
sale_quick_payment/company_view.xml (+0/-25)
sale_quick_payment/migrations/0.1/post-migration.py (+35/-0)
sale_quick_payment/sale.py (+31/-11)
sale_quick_payment/sale_view.xml (+10/-2)
sale_quick_payment/settings/sale.exception.csv (+3/-0)
sale_quick_payment/wizard/pay_sale_order.py (+29/-9)
sale_quick_payment/wizard/pay_sale_order.xml (+12/-15)
To merge this branch: bzr merge lp:~extra-addons-commiter/e-commerce-addons/trunk
Reviewer Review Type Date Requested Status
Guewen Baconnier @ Camptocamp Approve
Review via email: mp+142952@code.launchpad.net

Description of the change

this was the previous trunk branch and as some module have been ported we should merge it in stable

To post a comment you must log in.
Revision history for this message
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'base_sale_export_partner/__openerp__.py'
--- base_sale_export_partner/__openerp__.py 2012-11-21 13:48:17 +0000
+++ base_sale_export_partner/__openerp__.py 2013-01-11 17:08:20 +0000
@@ -36,6 +36,6 @@
36 'wizard/export_partner.xml',36 'wizard/export_partner.xml',
37 ],37 ],
38 'demo_xml': [],38 'demo_xml': [],
39 'installable': True,39 'installable': False,
40 'active': False,40 'active': False,
41}41}
4242
=== modified file 'base_sale_export_product/__openerp__.py'
--- base_sale_export_product/__openerp__.py 2012-11-21 13:48:17 +0000
+++ base_sale_export_product/__openerp__.py 2013-01-11 17:08:20 +0000
@@ -36,6 +36,6 @@
36 'wizard/export_product.xml',36 'wizard/export_product.xml',
37 ],37 ],
38 'demo_xml': [],38 'demo_xml': [],
39 'installable': True,39 'installable': False,
40 'active': False,40 'active': False,
41}41}
4242
=== modified file 'base_sale_multichannels/__openerp__.py'
--- base_sale_multichannels/__openerp__.py 2012-11-30 12:02:42 +0000
+++ base_sale_multichannels/__openerp__.py 2013-01-11 17:08:20 +0000
@@ -72,7 +72,7 @@
72 'account_view.xml',72 'account_view.xml',
73 ],73 ],
74 'demo_xml': [],74 'demo_xml': [],
75 'installable': True,75 'installable': False,
76 'certificate': '',76 'certificate': '',
77}77}
78# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:78# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
7979
=== added file 'base_sale_multichannels/connector.py'
--- base_sale_multichannels/connector.py 1970-01-01 00:00:00 +0000
+++ base_sale_multichannels/connector.py 2013-01-11 17:08:20 +0000
@@ -0,0 +1,37 @@
1# -*- encoding: utf-8 -*-
2###############################################################################
3# #
4# product_custom_attributes for OpenERP #
5# Copyright (C) 2012 Camptocamp Alexandre Fayolle <alexandre.fayolle@camptocamp.com> #
6# Copyright (C) 2012 Akretion Sebastien Beau <sebastien.beau@akretion.com> #
7# #
8# This program is free software: you can redistribute it and/or modify #
9# it under the terms of the GNU Affero General Public License as #
10# published by the Free Software Foundation, either version 3 of the #
11# License, or (at your option) any later version. #
12# #
13# This program is distributed in the hope that it will be useful, #
14# but WITHOUT ANY WARRANTY; without even the implied warranty of #
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
16# GNU Affero General Public License for more details. #
17# #
18# You should have received a copy of the GNU Affero General Public License #
19# along with this program. If not, see <http://www.gnu.org/licenses/>. #
20# #
21###############################################################################
22
23from base_external_referentials.connector import AbstractConnector
24
25class BaseConnector(AbstractConnector):
26 def _get_import_defaults_res_partner(self, cr, uid, context=None):
27 pass
28 def _get_import_defaults_res_partner(self, cr, uid, context=None):
29 pass
30 def _get_import_defaults_external_shop_group(self, cr, uid, context=None):
31 pass
32
33 def _get_import_defaults_sale_order(self, cr, uid, context=None):
34 pass
35
36 def _record_one_sale_order(self, cr, uid, res_obj, resource, defaults, context):
37 pass
038
=== modified file 'base_sale_multichannels/partner.py'
--- base_sale_multichannels/partner.py 2012-10-24 20:17:59 +0000
+++ base_sale_multichannels/partner.py 2013-01-11 17:08:20 +0000
@@ -32,6 +32,7 @@
32 'shop_ids': fields.many2many('sale.shop', 'sale_shop_res_partner_rel', 'shop_id', 'partner_id', 'Present in Shops', readonly=True, help="List of shops in which this customer exists."),32 'shop_ids': fields.many2many('sale.shop', 'sale_shop_res_partner_rel', 'shop_id', 'partner_id', 'Present in Shops', readonly=True, help="List of shops in which this customer exists."),
33 }33 }
3434
35 # xxx move to BaseConnector _get_import_defaults_res_partner
35 def _get_default_import_values(self, cr, uid, external_session, mapping_id=None, defaults=None, context=None):36 def _get_default_import_values(self, cr, uid, external_session, mapping_id=None, defaults=None, context=None):
36 if external_session.sync_from_object._name == 'sale.shop':37 if external_session.sync_from_object._name == 'sale.shop':
37 shop = external_session.sync_from_object38 shop = external_session.sync_from_object
3839
=== modified file 'base_sale_multichannels/sale.py'
--- base_sale_multichannels/sale.py 2013-01-03 10:08:13 +0000
+++ base_sale_multichannels/sale.py 2013-01-11 17:08:20 +0000
@@ -63,7 +63,7 @@
63 'shop_ids': fields.one2many('sale.shop', 'shop_group_id', 'Sale Shops'),63 'shop_ids': fields.one2many('sale.shop', 'shop_group_id', 'Sale Shops'),
64 }64 }
6565
6666 # xxx move to BaseConnector _get_import_defaults_external_shop_group
67 def _get_default_import_values(self, cr, uid, external_session, **kwargs):67 def _get_default_import_values(self, cr, uid, external_session, **kwargs):
68 return {'referential_id' : external_session.referential_id.id}68 return {'referential_id' : external_session.referential_id.id}
6969
@@ -539,6 +539,7 @@
539 vals['update_state_date'] = datetime.now().strftime(DEFAULT_SERVER_DATETIME_FORMAT)539 vals['update_state_date'] = datetime.now().strftime(DEFAULT_SERVER_DATETIME_FORMAT)
540 return super(sale_order, self).write(cr, uid, ids, vals, context=context)540 return super(sale_order, self).write(cr, uid, ids, vals, context=context)
541541
542 # xxx move to BaseConnector _get_import_defaults_sale_order
542 def _get_default_import_values(self, cr, uid, external_session, mapping_id=None, defaults=None, context=None):543 def _get_default_import_values(self, cr, uid, external_session, mapping_id=None, defaults=None, context=None):
543 shop = False544 shop = False
544 if external_session.sync_from_object._name == 'sale.shop':545 if external_session.sync_from_object._name == 'sale.shop':
@@ -597,6 +598,7 @@
597598
598 return False599 return False
599600
601 # xxx a deplacer dans BaseConnector sale_order
600 @catch_error_in_report602 @catch_error_in_report
601 def _record_one_external_resource(self, cr, uid, external_session, resource, defaults=None,603 def _record_one_external_resource(self, cr, uid, external_session, resource, defaults=None,
602 mapping=None, mapping_id=None, context=None):604 mapping=None, mapping_id=None, context=None):
603605
=== modified file 'base_sale_report_synchronizer/__openerp__.py'
--- base_sale_report_synchronizer/__openerp__.py 2012-11-21 13:48:17 +0000
+++ base_sale_report_synchronizer/__openerp__.py 2013-01-11 17:08:20 +0000
@@ -41,7 +41,7 @@
41 'sale_view.xml',41 'sale_view.xml',
42 ],42 ],
43 'demo_xml': [],43 'demo_xml': [],
44 'installable': True,44 'installable': False,
45 'active': False,45 'active': False,
46}46}
4747
4848
=== modified file 'product_custom_attributes_shop/__openerp__.py'
--- product_custom_attributes_shop/__openerp__.py 2012-12-07 12:44:57 +0000
+++ product_custom_attributes_shop/__openerp__.py 2013-01-11 17:08:20 +0000
@@ -46,7 +46,7 @@
46 'security/ir.model.access.csv',46 'security/ir.model.access.csv',
47 ],47 ],
48 'demo_xml': [],48 'demo_xml': [],
49 'installable': True,49 'installable': False,
50 'active': False,50 'active': False,
51}51}
5252
5353
=== modified file 'product_images_sync/__openerp__.py'
--- product_images_sync/__openerp__.py 2012-12-07 12:44:57 +0000
+++ product_images_sync/__openerp__.py 2013-01-11 17:08:20 +0000
@@ -42,6 +42,6 @@
42 'update_xml': [42 'update_xml': [
43 ],43 ],
44 'demo_xml': [],44 'demo_xml': [],
45 'installable': True,45 'installable': False,
46 'active': False,46 'active': False,
47}47}
4848
=== modified file 'product_links/__openerp__.py'
--- product_links/__openerp__.py 2012-11-21 13:48:17 +0000
+++ product_links/__openerp__.py 2013-01-11 17:08:20 +0000
@@ -40,6 +40,6 @@
40 'product_links_view.xml',40 'product_links_view.xml',
41 ],41 ],
42 'demo_xml': [],42 'demo_xml': [],
43 'installable': True,43 'installable': False,
44 'active': False,44 'active': False,
45}45}
4646
=== modified file 'product_links_goodies/__openerp__.py'
--- product_links_goodies/__openerp__.py 2012-11-21 13:48:17 +0000
+++ product_links_goodies/__openerp__.py 2013-01-11 17:08:20 +0000
@@ -38,7 +38,7 @@
38 'product_goodies_data.xml',38 'product_goodies_data.xml',
39 ],39 ],
40 'demo_xml': [],40 'demo_xml': [],
41 'installable': True,41 'installable': False,
42 'active': False,42 'active': False,
43}43}
4444
4545
=== modified file 'product_links_sync/__openerp__.py'
--- product_links_sync/__openerp__.py 2012-11-21 13:48:17 +0000
+++ product_links_sync/__openerp__.py 2013-01-11 17:08:20 +0000
@@ -38,7 +38,7 @@
38 'sale_view.xml',38 'sale_view.xml',
39 ],39 ],
40 'demo_xml': [],40 'demo_xml': [],
41 'installable': True,41 'installable': False,
42 'active': False,42 'active': False,
43}43}
4444
4545
=== modified file 'sale_automatic_workflow/__init__.py'
--- sale_automatic_workflow/__init__.py 2012-04-22 12:49:21 +0000
+++ sale_automatic_workflow/__init__.py 2013-01-11 17:08:20 +0000
@@ -24,7 +24,8 @@
24import sale_workflow_process24import sale_workflow_process
25import payment_method25import payment_method
26import automatic_workflow_job26import automatic_workflow_job
2727import invoice
28import stock
2829
2930
3031
3132
=== modified file 'sale_automatic_workflow/__openerp__.py'
--- sale_automatic_workflow/__openerp__.py 2012-11-21 13:48:17 +0000
+++ sale_automatic_workflow/__openerp__.py 2013-01-11 17:08:20 +0000
@@ -22,13 +22,17 @@
2222
23{23{
24 'name': 'sale_automatic_workflow',24 'name': 'sale_automatic_workflow',
25 'version': '6.1.1',25 'version': '0.1',
26 'category': 'Generic Modules/Others',26 'category': 'Generic Modules/Others',
27 'license': 'AGPL-3',27 'license': 'AGPL-3',
28 'description': """empty""",28 'description': """empty""",
29 'author': 'Akretion',29 'author': 'Akretion',
30 'website': 'http://www.akretion.com/',30 'website': 'http://www.akretion.com/',
31 'depends': ['sale_quick_payment', 'framework_helpers'], 31 'depends': [
32 'sale_quick_payment',
33 'framework_helpers',
34 'stock',
35 ],
32 'init_xml': [],36 'init_xml': [],
33 'update_xml': [ 37 'update_xml': [
34 'sale_view.xml',38 'sale_view.xml',
3539
=== modified file 'sale_automatic_workflow/automatic_workflow_job.py'
--- sale_automatic_workflow/automatic_workflow_job.py 2012-11-21 12:46:53 +0000
+++ sale_automatic_workflow/automatic_workflow_job.py 2013-01-11 17:08:20 +0000
@@ -72,7 +72,7 @@
72 with commit_now(cr, logger) as cr:72 with commit_now(cr, logger) as cr:
73 invoice_obj.reconcile_invoice(cr, uid, [invoice_id], context=context)73 invoice_obj.reconcile_invoice(cr, uid, [invoice_id], context=context)
7474
75 picking_obj = self.pool.get('stock.picking')75 picking_obj = self.pool.get('stock.picking.out')
76 picking_ids = picking_obj.search(cr, uid, [('state', 'in', ['draft', 'confirmed', 'assigned']), ('workflow_process_id.validate_picking', '=',True)], context=context)76 picking_ids = picking_obj.search(cr, uid, [('state', 'in', ['draft', 'confirmed', 'assigned']), ('workflow_process_id.validate_picking', '=',True)], context=context)
77 if picking_ids:77 if picking_ids:
78 logger.debug(_('start to validate pickings : %s') %picking_ids)78 logger.debug(_('start to validate pickings : %s') %picking_ids)
7979
=== added file 'sale_automatic_workflow/invoice.py'
--- sale_automatic_workflow/invoice.py 1970-01-01 00:00:00 +0000
+++ sale_automatic_workflow/invoice.py 2013-01-11 17:08:20 +0000
@@ -0,0 +1,112 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3#
4# sale_automatic_workflow for OpenERP
5# Copyright (C) 2011-TODAY Akretion <http://www.akretion.com>.
6# All Rights Reserved
7# @author Sébastien BEAU <sebastien.beau@akretion.com>
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU Affero General Public License as
10# published by the Free Software Foundation, either version 3 of the
11# License, or (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU Affero General Public License for more details.
17#
18# You should have received a copy of the GNU Affero General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21###############################################################################
22from openerp.osv.orm import Model
23from openerp.osv import fields
24
25class account_invoice(Model):
26 _inherit = "account.invoice"
27 _columns = {
28 'workflow_process_id':fields.many2one('sale.workflow.process', 'Sale Workflow Process'),
29 #TODO propose a merge to add this field by default in acount module
30 'sale_ids': fields.many2many('sale.order', 'sale_order_invoice_rel', 'invoice_id', 'order_id', 'Sale Orders')
31 }
32
33 def _can_be_reconciled(self, cr, uid, invoice, context=None):
34 if not (invoice.sale_ids and invoice.sale_ids[0].payment_ids and invoice.move_id):
35 return False
36 #Check currency
37 for payment in invoice.sale_ids[0].payment_ids:
38 for move in payment.move_ids:
39 if (move.currency_id.id or invoice.company_id.currency_id.id) != invoice.currency_id.id:
40 return False
41 return True
42
43 def _get_sum_invoice_move_line(self, cr, uid, move_lines, context=None):
44 return self._get_sum_move_line(cr, uid, move_lines, 'debit', context=None)
45
46 def _get_sum_payment_move_line(self, cr, uid, move_lines, context=None):
47 return self._get_sum_move_line(cr, uid, move_lines, 'credit', context=None)
48
49 def _get_sum_move_line(self, cr, uid, move_lines, line_type, context=None):
50 res = {
51 'max_date': False,
52 'line_ids': [],
53 'total_amount': 0,
54 'total_amount_currency': 0,
55 }
56 for move_line in move_lines:
57 if move_line[line_type] > 0:
58 if move_line.date > res['max_date']:
59 res['max_date'] = move_line.date
60 res['line_ids'].append(move_line.id)
61 res['total_amount'] += move_line[line_type]
62 res['total_amount_currency'] += move_line.amount_currency
63 return res
64
65 def _prepare_write_off(self, cr, uid, invoice, res_invoice, res_payment, context=None):
66 if not context:
67 context = {}
68 ctx = context.copy()
69 if res_invoice['total_amount'] - res_payment['total_amount'] > 0:
70 writeoff_type = 'expense'
71 else:
72 writeoff_type = 'income'
73 account_id, journal_id = invoice.company_id.\
74 get_write_off_information('exchange', writeoff_type, context=context)
75 max_date = max(res_invoice['max_date'], res_payment['max_date'])
76 ctx['p_date'] = max_date
77 period_id = self.pool.get('account.period').find(cr, uid, max_date, context=context)[0]
78 return {
79 'type': 'auto',
80 'writeoff_acc_id': account_id,
81 'writeoff_period_id': period_id,
82 'writeoff_journal_id': journal_id,
83 'context': ctx,
84 }
85
86 def reconcile_invoice(self, cr, uid, ids, context=None):
87 """
88 Simple method to reconcile the invoice with the payment generated on the sale order
89 """
90 if not context:
91 context={}
92 precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
93 obj_move_line = self.pool.get('account.move.line')
94 for invoice in self.browse(cr, uid, ids, context=context):
95 use_currency = invoice.currency_id.id != invoice.company_id.currency_id.id
96 if self._can_be_reconciled(cr, uid, invoice, context=context):
97 payment_move_line = []
98 for payment in invoice.sale_ids[0].payment_ids:
99 payment_move_line += payment.move_ids
100 res_payment = self._get_sum_payment_move_line(cr, uid, payment_move_line, context=context)
101 res_invoice = self._get_sum_invoice_move_line(cr, uid, invoice.move_id.line_id, context=context)
102 line_ids = res_invoice['line_ids'] + res_payment['line_ids']
103 if not use_currency:
104 balance = abs(res_invoice['total_amount']-res_payment['total_amount'])
105 if line_ids and not round(balance, precision):
106 obj_move_line.reconcile(cr, uid, line_ids, context=context)
107 else:
108 balance = abs(res_invoice['total_amount_currency']-res_payment['total_amount_currency'])
109 if line_ids and not round(balance, precision):
110 kwargs = self._prepare_write_off(cr, uid, invoice, res_invoice, res_payment, context=context)
111 obj_move_line.reconcile(cr, uid, line_ids, **kwargs)
112 return True
0113
=== modified file 'sale_automatic_workflow/sale.py'
--- sale_automatic_workflow/sale.py 2012-09-19 13:24:46 +0000
+++ sale_automatic_workflow/sale.py 2013-01-11 17:08:20 +0000
@@ -1,4 +1,4 @@
1 # -*- encoding: utf-8 -*-1# -*- encoding: utf-8 -*-
2#################################################################################2#################################################################################
3# #3# #
4# sale_automatic_workflow for OpenERP #4# sale_automatic_workflow for OpenERP #
@@ -39,77 +39,3 @@
39 picking_vals = super(sale_order, self)._prepare_order_picking(cr, uid, order, context=context)39 picking_vals = super(sale_order, self)._prepare_order_picking(cr, uid, order, context=context)
40 picking_vals['workflow_process_id'] = order.workflow_process_id.id40 picking_vals['workflow_process_id'] = order.workflow_process_id.id
41 return picking_vals41 return picking_vals
42
43class stock_picking(Model):
44 _inherit = "stock.picking"
45 _columns = {
46 'workflow_process_id':fields.many2one('sale.workflow.process', 'Sale Workflow Process'),
47 }
48
49 def _prepare_invoice(self, cr, uid, picking, partner, inv_type, journal_id, context=None):
50 invoice_vals = super(stock_picking, self)._prepare_invoice(cr, uid, picking, partner, \
51 inv_type, journal_id, context=context)
52 invoice_vals['workflow_process_id'] = picking.workflow_process_id.id
53 if picking.workflow_process_id.invoice_date_is_order_date:
54 invoice_vals['date_invoice'] = picking.sale_id.date_order
55 return invoice_vals
56
57 def validate_picking(self, cr, uid, ids, context=None):
58 for picking in self.browse(cr, uid, ids, context=context):
59 self.force_assign(cr, uid, [picking.id])
60 partial_data = {}
61 for move in picking.move_lines:
62 partial_data["move" + str(move.id)] = {'product_qty': move.product_qty,
63 'product_uom': move.product_uom.id}
64 self.do_partial(cr, uid, [picking.id], partial_data)
65 return True
66
67#TODO reimplement me
68# def validate_manufactoring_order(self, cr, uid, origin, context=None): #we do not create class mrp.production to avoid dependence with the module mrp
69# if context is None:
70# context = {}
71# wf_service = netsvc.LocalService("workflow")
72# mrp_prod_obj = self.pool.get('mrp.production')
73# mrp_product_produce_obj = self.pool.get('mrp.product.produce')
74# production_ids = mrp_prod_obj.search(cr, uid, [('origin', 'ilike', origin)])
75# for production in mrp_prod_obj.browse(cr, uid, production_ids):
76# mrp_prod_obj.force_production(cr, uid, [production.id])
77# wf_service.trg_validate(uid, 'mrp.production', production.id, 'button_produce', cr)
78# context.update({'active_model': 'mrp.production', 'active_ids': [production.id], 'search_default_ready': 1, 'active_id': production.id})
79# produce = mrp_product_produce_obj.create(cr, uid, {'mode': 'consume_produce', 'product_qty': production.product_qty}, context)
80# mrp_product_produce_obj.do_produce(cr, uid, [produce], context)
81# self.validate_manufactoring_order(cr, uid, production.name, context)
82# return True
83#
84
85class account_invoice(Model):
86 _inherit = "account.invoice"
87 _columns = {
88 'workflow_process_id':fields.many2one('sale.workflow.process', 'Sale Workflow Process'),
89 #TODO propose a merge to add this field by default in acount module
90 'sale_ids': fields.many2many('sale.order', 'sale_order_invoice_rel', 'invoice_id', 'order_id', 'Sale Orders')
91 }
92
93 def reconcile_invoice(self, cr, uid, ids, context=None):
94 """
95 Simple method to reconcile the invoice with the payment generated on the sale order
96 """
97 obj_move_line = self.pool.get('account.move.line')
98 for invoice in self.browse(cr, uid, ids, context=context):
99 line_ids = []
100 payment_amount = 0
101 invoice_amount = 0
102 if invoice.sale_ids and invoice.sale_ids[0].payment_id and invoice.move_id:
103 for move in invoice.sale_ids[0].payment_id.move_ids:
104 if move.credit > 0 and not move.reconcile_id:
105 line_ids.append(move.id)
106 payment_amount += move.credit
107 for move in invoice.move_id.line_id:
108 if move.debit > 0 and not move.reconcile_id:
109 line_ids.append(move.id)
110 invoice_amount += move.debit
111 balance = abs(payment_amount-invoice_amount)
112 precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')
113 if line_ids and not round(balance, precision):
114 obj_move_line.reconcile(cr, uid, line_ids, context=context)
115 return True
11642
=== added file 'sale_automatic_workflow/stock.py'
--- sale_automatic_workflow/stock.py 1970-01-01 00:00:00 +0000
+++ sale_automatic_workflow/stock.py 2013-01-11 17:08:20 +0000
@@ -0,0 +1,65 @@
1# -*- coding: utf-8 -*-
2###############################################################################
3#
4# sale_automatic_workflow for OpenERP
5# Copyright (C) 2011-TODAY Akretion <http://www.akretion.com>.
6# All Rights Reserved
7# @author Sébastien BEAU <sebastien.beau@akretion.com>
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU Affero General Public License as
10# published by the Free Software Foundation, either version 3 of the
11# License, or (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU Affero General Public License for more details.
17#
18# You should have received a copy of the GNU Affero General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21###############################################################################
22from openerp.osv.orm import Model
23from openerp.osv import fields
24
25class stock_picking_out(Model):
26 _inherit = "stock.picking.out"
27 _columns = {
28 'workflow_process_id':fields.many2one('sale.workflow.process', 'Sale Workflow Process'),
29 }
30
31 def _prepare_invoice(self, cr, uid, picking, partner, inv_type, journal_id, context=None):
32 invoice_vals = super(stock_picking_out, self)._prepare_invoice(cr, uid, picking, partner, \
33 inv_type, journal_id, context=context)
34 invoice_vals['workflow_process_id'] = picking.workflow_process_id.id
35 if picking.workflow_process_id.invoice_date_is_order_date:
36 invoice_vals['date_invoice'] = picking.sale_id.date_order
37 return invoice_vals
38
39 def validate_picking(self, cr, uid, ids, context=None):
40 for picking in self.browse(cr, uid, ids, context=context):
41 self.force_assign(cr, uid, [picking.id])
42 partial_data = {}
43 for move in picking.move_lines:
44 partial_data["move" + str(move.id)] = {'product_qty': move.product_qty,
45 'product_uom': move.product_uom.id}
46 self.do_partial(cr, uid, [picking.id], partial_data)
47 return True
48
49#TODO reimplement me
50# def validate_manufactoring_order(self, cr, uid, origin, context=None): #we do not create class mrp.production to avoid dependence with the module mrp
51# if context is None:
52# context = {}
53# wf_service = netsvc.LocalService("workflow")
54# mrp_prod_obj = self.pool.get('mrp.production')
55# mrp_product_produce_obj = self.pool.get('mrp.product.produce')
56# production_ids = mrp_prod_obj.search(cr, uid, [('origin', 'ilike', origin)])
57# for production in mrp_prod_obj.browse(cr, uid, production_ids):
58# mrp_prod_obj.force_production(cr, uid, [production.id])
59# wf_service.trg_validate(uid, 'mrp.production', production.id, 'button_produce', cr)
60# context.update({'active_model': 'mrp.production', 'active_ids': [production.id], 'search_default_ready': 1, 'active_id': production.id})
61# produce = mrp_product_produce_obj.create(cr, uid, {'mode': 'consume_produce', 'product_qty': production.product_qty}, context)
62# mrp_product_produce_obj.do_produce(cr, uid, [produce], context)
63# self.validate_manufactoring_order(cr, uid, production.name, context)
64# return True
65#
066
=== modified file 'sale_exceptions/__openerp__.py'
--- sale_exceptions/__openerp__.py 2012-11-21 13:48:17 +0000
+++ sale_exceptions/__openerp__.py 2013-01-11 17:08:20 +0000
@@ -25,7 +25,7 @@
2525
26{26{
27 'name': 'Sale Exceptions',27 'name': 'Sale Exceptions',
28 'version': '6.1.0',28 'version': '0.1',
29 'category': 'Generic Modules/Sale',29 'category': 'Generic Modules/Sale',
30 'description': """30 'description': """
31This module allows you attach several customizable exceptions to your sale order in a way that you can filter orders by exceptions type and fix them.31This module allows you attach several customizable exceptions to your sale order in a way that you can filter orders by exceptions type and fix them.
3232
=== modified file 'sale_exceptions/sale.py'
--- sale_exceptions/sale.py 2012-12-07 14:11:56 +0000
+++ sale_exceptions/sale.py 2013-01-11 17:08:20 +0000
@@ -33,6 +33,7 @@
33class sale_exception(Model):33class sale_exception(Model):
34 _name = "sale.exception"34 _name = "sale.exception"
35 _description = "Sale Exceptions"35 _description = "Sale Exceptions"
36 _order="active desc, sequence asc"
36 _columns = {37 _columns = {
37 'name': fields.char('Exception Name', size=64, required=True, translate=True),38 'name': fields.char('Exception Name', size=64, required=True, translate=True),
38 'description': fields.text('Description', translate=True),39 'description': fields.text('Description', translate=True),
@@ -106,6 +107,7 @@
106 view_id = model_data_obj.get_object_reference(107 view_id = model_data_obj.get_object_reference(
107 cr, uid, 'sale_exceptions', 'view_sale_exception_confirm')[1]108 cr, uid, 'sale_exceptions', 'view_sale_exception_confirm')[1]
108 action = {109 action = {
110 'name': _("Exceptions On Sale Order"),
109 'type': 'ir.actions.act_window',111 'type': 'ir.actions.act_window',
110 'view_type': 'form',112 'view_type': 'form',
111 'view_mode': 'form',113 'view_mode': 'form',
@@ -117,14 +119,12 @@
117 }119 }
118 return action120 return action
119121
120 def button_order_confirm(self, cr, uid, ids, context=None):122 def action_button_confirm(self, cr, uid, ids, context=None):
121 exception_ids = self.detect_exceptions(cr, uid, ids, context=context)123 exception_ids = self.detect_exceptions(cr, uid, ids, context=context)
122 if exception_ids:124 if exception_ids:
123 return self._popup_exceptions(cr, uid, ids[0], context=context)125 return self._popup_exceptions(cr, uid, ids[0], context=context)
124 else:126 else:
125 wf_service = netsvc.LocalService("workflow")127 return super(sale_order, self).action_button_confirm(cr, uid, ids, context=context)
126 wf_service.trg_validate(uid, 'sale.order', ids[0], 'order_confirm', cr)
127 return True
128128
129 def test_exceptions(self, cr, uid, ids, context=None):129 def test_exceptions(self, cr, uid, ids, context=None):
130 """130 """
131131
=== modified file 'sale_exceptions/sale_view.xml'
--- sale_exceptions/sale_view.xml 2012-10-22 14:39:18 +0000
+++ sale_exceptions/sale_view.xml 2013-01-11 17:08:20 +0000
@@ -2,29 +2,13 @@
2<openerp>2<openerp>
3 <data>3 <data>
44
5 <record id="view_sale_exception_search" model="ir.ui.view">
6 <field name="name">sale.exception.view.search</field>
7 <field name="model">sale.exception</field>
8 <field name="type">search</field>
9 <field name="arch" type="xml">
10 <search string="Search Sale Exceptions">
11 <group>
12 <filter name="all" icon="gtk-fullscreen" string="See All" domain="['|', ('active','=', False), ('active','=', True)]" help="See all rule active or unactive"/>
13 </group>
14 <newline/>
15 <group>
16 <field name="name"/>
17 </group>
18 </search>
19 </field>
20 </record>
21
22 <record id="view_sale_exception_tree" model="ir.ui.view">5 <record id="view_sale_exception_tree" model="ir.ui.view">
23 <field name="name">sale.exception.tree</field>6 <field name="name">sale.exception.tree</field>
24 <field name="model">sale.exception</field>7 <field name="model">sale.exception</field>
25 <field name="type">tree</field>8 <field name="type">tree</field>
26 <field name="arch" type="xml">9 <field name="arch" type="xml">
27 <tree string="Sale Exception">10 <tree string="Sale Exception">
11 <field name="active"/>
28 <field name="name"/>12 <field name="name"/>
29 <field name="description"/>13 <field name="description"/>
30 <field name="model"/>14 <field name="model"/>
@@ -66,7 +50,7 @@
66 <field name="view_type">form</field>50 <field name="view_type">form</field>
67 <field name="view_mode">tree,form</field>51 <field name="view_mode">tree,form</field>
68 <field name="view_id" ref="view_sale_exception_tree"/>52 <field name="view_id" ref="view_sale_exception_tree"/>
69 <field name="search_view_id" ref="view_sale_exception_search"/>53 <field name="context">{'active_test': False}</field>
70 </record>54 </record>
7155
72 <menuitem action="action_sale_test_tree" id="menu_sale_test" parent="base.menu_sale_config_sales" />56 <menuitem action="action_sale_test_tree" id="menu_sale_test" parent="base.menu_sale_config_sales" />
@@ -79,28 +63,17 @@
79 <field name="priority">100</field>63 <field name="priority">100</field>
80 <field name="inherit_id" ref="sale.view_order_form"/>64 <field name="inherit_id" ref="sale.view_order_form"/>
81 <field name="arch" type="xml">65 <field name="arch" type="xml">
82 <xpath expr="/form/notebook/page[@string='Sales Order']/group/field[@name='state']"66 <field name="name" position="after">
83 position="after">
84 <field name="main_exception_id" nolabel="1"67 <field name="main_exception_id" nolabel="1"
85 attrs="{'invisible':[('main_exception_id','=', False)]}"/>68 attrs="{'invisible':[('main_exception_id','=', False)]}"/>
86 </xpath>69 </field>
87 <xpath expr="/form/notebook/page[@string='Other Information']/separator[@string='Notes']"70 <xpath expr="//page[@string='Other Information']/group"
88 position="before">71 position="inside">
89 <group name="exception" colspan="2" col="2">72 <group name="exception" colspan="2" col="2">
90 <separator string="Exception" colspan="2"/>73 <separator string="Exception" colspan="2"/>
91 <field name="exceptions_ids" colspan="2" nolabel="1"/>74 <field name="exceptions_ids" colspan="2" nolabel="1"/>
92 </group>75 </group>
93 <group name="notes" colspan="2" col="2">
94 <separator colspan="2" string="Notes"/>
95 <field colspan="2" name="note" nolabel="1"/>
96 </group>
97 </xpath>76 </xpath>
98 <xpath expr="/form/notebook/page[@string='Other Information']/separator[@string='Notes']" position="replace"/>
99 <xpath expr="/form/notebook/page[@string='Other Information']/field[@name='note']" position="replace"/>
100 <button name="order_confirm" position="attributes">
101 <attribute name="name">button_order_confirm</attribute>
102 <attribute name="type">object</attribute>
103 </button>
104 </field>77 </field>
105 </record>78 </record>
10679
10780
=== modified file 'sale_exceptions/wizard/sale_exception_confirm_view.xml'
--- sale_exceptions/wizard/sale_exception_confirm_view.xml 2012-03-23 14:41:24 +0000
+++ sale_exceptions/wizard/sale_exception_confirm_view.xml 2013-01-11 17:08:20 +0000
@@ -7,26 +7,25 @@
7 <field name="model">sale.exception.confirm</field>7 <field name="model">sale.exception.confirm</field>
8 <field name="type">form</field>8 <field name="type">form</field>
9 <field name="arch" type="xml">9 <field name="arch" type="xml">
10 <form string="Sale Exceptions">10 <form string="Sale Exceptions On Sale Order" version="7.0">
11 <separator colspan="4" string="Exceptions on the sale order" />11 <group>
12 <field name="exception_ids" nolabel="1" colspan="4">12 <field name="exception_ids" nolabel="1" colspan="4">
13 <form string="Sale Exception">13 <form string="Sale Exception">
14 <field name="name" colspan="4"/>14 <field name="name" colspan="4"/>
15 <field name="description" colspan="4"/>15 <field name="description" colspan="4"/>
16 </form>16 </form>
17 <tree string="Sale Exceptions">17 <tree string="Sale Exceptions">
18 <field name="name"/>18 <field name="name"/>
19 <field name="description"/>19 <field name="description"/>
20 </tree>20 </tree>
21 </field>21 </field>
22 <newline/>22 <newline/>
23 <field name="ignore" groups='base.group_sale_manager'/>23 <field name="ignore" groups='base.group_sale_manager'/>
24 <newline/>24 </group>
25 <separator colspan="4"/>25 <footer>
26 <group col="2" colspan="4">
27 <button name="action_confirm" string="_Ok"26 <button name="action_confirm" string="_Ok"
28 colspan="1" type="object" icon="gtk-ok" />27 colspan="1" type="object" icon="gtk-ok" />
29 </group>28 </footer>
30 </form>29 </form>
31 </field>30 </field>
32 </record>31 </record>
3332
=== modified file 'sale_quick_payment/__init__.py'
--- sale_quick_payment/__init__.py 2012-05-18 09:00:34 +0000
+++ sale_quick_payment/__init__.py 2013-01-11 17:08:20 +0000
@@ -23,6 +23,4 @@
23import sale23import sale
24import payment_method24import payment_method
25import wizard25import wizard
26import company26import account_voucher
27
28
2927
=== modified file 'sale_quick_payment/__openerp__.py'
--- sale_quick_payment/__openerp__.py 2012-12-07 12:44:57 +0000
+++ sale_quick_payment/__openerp__.py 2013-01-11 17:08:20 +0000
@@ -22,7 +22,7 @@
2222
23{23{
24 'name': 'sale_quick_payment',24 'name': 'sale_quick_payment',
25 'version': '6.1.0',25 'version': '0.1',
26 'category': 'Generic Modules/Others',26 'category': 'Generic Modules/Others',
27 'license': 'AGPL-3',27 'license': 'AGPL-3',
28 'description': """28 'description': """
@@ -36,16 +36,16 @@
36 'author': 'Akretion',36 'author': 'Akretion',
37 'website': 'http://www.akretion.com/',37 'website': 'http://www.akretion.com/',
38 'depends': [38 'depends': [
39 'sale',39 'sale_exceptions',
40 'account_voucher',40 'account_voucher',
41 ], 41 ],
42 'init_xml': [],42 'init_xml': [],
43 'update_xml': [ 43 'update_xml': [
44 'wizard/pay_sale_order.xml',
44 'sale_view.xml',45 'sale_view.xml',
45 'payment_method_view.xml',46 'payment_method_view.xml',
46 'wizard/pay_sale_order.xml',
47 'company_view.xml',
48 'security/ir.model.access.csv',47 'security/ir.model.access.csv',
48 'settings/sale.exception.csv',
49 ],49 ],
50 'demo_xml': [],50 'demo_xml': [],
51 'installable': True,51 'installable': True,
5252
=== added file 'sale_quick_payment/account_voucher.py'
--- sale_quick_payment/account_voucher.py 1970-01-01 00:00:00 +0000
+++ sale_quick_payment/account_voucher.py 2013-01-11 17:08:20 +0000
@@ -0,0 +1,33 @@
1# -*- encoding: utf-8 -*-
2###############################################################################
3#
4# sale_quick_payment for OpenERP
5# Copyright (C) 2012-TODAY Akretion <http://www.akretion.com>.
6# All Rights Reserved
7# @author Sébastien BEAU <sebastien.beau@akretion.com>
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU Affero General Public License as
10# published by the Free Software Foundation, either version 3 of the
11# License, or (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU Affero General Public License for more details.
17#
18# You should have received a copy of the GNU Affero General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21###############################################################################
22
23from openerp.osv.orm import Model
24from openerp.osv import fields
25
26class payment_method(Model):
27 _inherit = "account.voucher"
28
29 _columns = {
30 'order_ids': fields.many2many('sale.order', string='Sale Order'),
31 }
32
33
034
=== removed file 'sale_quick_payment/company.py'
--- sale_quick_payment/company.py 2012-08-21 13:57:44 +0000
+++ sale_quick_payment/company.py 1970-01-01 00:00:00 +0000
@@ -1,33 +0,0 @@
1# -*- encoding: utf-8 -*-
2#################################################################################
3# #
4# sale_quick_payment for OpenERP #
5# Copyright (C) 2011 Akretion Sébastien BEAU <sebastien.beau@akretion.com> #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU Affero General Public License as #
9# published by the Free Software Foundation, either version 3 of the #
10# License, or (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU Affero General Public License for more details. #
16# #
17# You should have received a copy of the GNU Affero General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20#################################################################################
21
22from openerp.osv.orm import Model
23from openerp.osv import fields
24from tools.translate import _
25
26class res_company(Model):
27 """Override company to add payment configuration"""
28 _inherit = "res.company"
29 _columns = {
30 'sale_order_must_be_paid':fields.boolean('Sale Order Must Be Paid',
31 help='If this option is check an order can not be validaded without payment'
32 ),
33 }
340
=== removed file 'sale_quick_payment/company_view.xml'
--- sale_quick_payment/company_view.xml 2012-05-18 09:00:34 +0000
+++ sale_quick_payment/company_view.xml 1970-01-01 00:00:00 +0000
@@ -1,25 +0,0 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!--
3 sale_quick_payment for OpenERP
4 Copyright (C) 2012 Akretion Sébastien BEAU <sebastien.beau@akretion.com>
5 The licence is in the file __openerp__.py
6-->
7
8
9<openerp>
10 <data>
11 <record model="ir.ui.view" id="view_company_form">
12 <field name="name">sale_quick_payment.view_company_form</field>
13 <field name="model">res.company</field>
14 <field name="inherit_id" ref="base.view_company_form"/>
15 <field name="type">form</field>
16 <field name="arch" type="xml">
17 <page string="Configuration" position="inside">
18 <separator string="Sale Configuration" colspan="4"/>
19 <field name="sale_order_must_be_paid"/>
20 </page>
21 </field>
22 </record>
23 </data>
24</openerp>
25
260
=== added directory 'sale_quick_payment/migrations'
=== added directory 'sale_quick_payment/migrations/0.1'
=== added file 'sale_quick_payment/migrations/0.1/post-migration.py'
--- sale_quick_payment/migrations/0.1/post-migration.py 1970-01-01 00:00:00 +0000
+++ sale_quick_payment/migrations/0.1/post-migration.py 2013-01-11 17:08:20 +0000
@@ -0,0 +1,35 @@
1# -*- encoding: utf-8 -*-
2###############################################################################
3#
4# sale_quick_payment for OpenERP
5# Copyright (C) 2012-TODAY Akretion <http://www.akretion.com>.
6# All Rights Reserved
7# @author Sébastien BEAU <sebastien.beau@akretion.com>
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU Affero General Public License as
10# published by the Free Software Foundation, either version 3 of the
11# License, or (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU Affero General Public License for more details.
17#
18# You should have received a copy of the GNU Affero General Public License
19# along with this program. If not, see <http://www.gnu.org/licenses/>.
20#
21###############################################################################
22
23""" r0.1: Migration 6.1 => 7.0.0.1
24 migrate the field payment_id from one2many to payment_ids many2many
25"""
26__name__ = ("sale.order:: V7 change/rename the field payment_id into a"
27 "many2many with the name payment_ids")
28
29def migrate(cr, version):
30 cr.execute("INSERT INTO account_voucher_sale_order_rel"
31 "(sale_order_id, account_voucher_id) "
32 "(SELECT id, payment_id FROM "
33 " sale_order "
34 "WHERE payment_id IS NOT NULL )")
35
036
=== modified file 'sale_quick_payment/sale.py'
--- sale_quick_payment/sale.py 2012-12-07 12:44:57 +0000
+++ sale_quick_payment/sale.py 2013-01-11 17:08:20 +0000
@@ -25,20 +25,48 @@
25import netsvc25import netsvc
26from collections import Iterable26from collections import Iterable
27from openerp.tools.translate import _27from openerp.tools.translate import _
28import decimal_precision as dp
2829
29class sale_order(Model):30class sale_order(Model):
30 _inherit = "sale.order"31 _inherit = "sale.order"
3132
33 def _get_order_from_voucher(self, cr, uid, ids, context=None):
34 result = []
35 for voucher in self.pool.get('account.voucher').browse(cr, uid, ids, context=context):
36 for order in voucher.order_ids:
37 result.append(order.id)
38 return list(set(result))
39
40 def _get_order_from_line(self, cr, uid, ids, context=None):
41 return self.pool.get('sale.order')._get_order(cr, uid, ids, context=context)
42
43 def _amount_residual(self, cr, uid, ids, field_name, args, context=None):
44 res = {}
45 #TODO add here the support of multi-currency payment if need
46 for order in self.browse(cr, uid, ids, context=context):
47 res[order.id] = order.amount_total
48 for payment in order.payment_ids:
49 if payment.state == 'posted':
50 res[order.id] -= payment.amount
51 return res
52
32 _columns = {53 _columns = {
33 'payment_id': fields.many2one('account.voucher', 'Payment'),54 'payment_ids': fields.many2many('account.voucher', string='Payments'),
34 'payment_method_id': fields.many2one('payment.method', 'Payment Method'),55 'payment_method_id': fields.many2one('payment.method', 'Payment Method'),
56 'residual': fields.function(_amount_residual, digits_compute=dp.get_precision('Account'), string='Balance',
57 store = {
58 'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line', 'payment_ids'], 10),
59 'sale.order.line': (_get_order_from_line, ['price_unit', 'tax_id', 'discount', 'product_uom_qty'], 20),
60 'account.voucher': (_get_order_from_voucher, ['amount'], 30),
61 },
62 ),
35 }63 }
3664
37 def copy(self, cr, uid, id, default=None, context=None):65 def copy(self, cr, uid, id, default=None, context=None):
38 if not default:66 if not default:
39 default = {}67 default = {}
40 default.update({68 default.update({
41 'payment_id': False,69 'payment_ids': False,
42 })70 })
43 return super(sale_order, self).copy(cr, uid, id, default, context=context)71 return super(sale_order, self).copy(cr, uid, id, default, context=context)
4472
@@ -132,14 +160,6 @@
132 wf_service = netsvc.LocalService("workflow")160 wf_service = netsvc.LocalService("workflow")
133 wf_service.trg_validate(161 wf_service.trg_validate(
134 uid, 'account.voucher', voucher_id, 'proforma_voucher', cr)162 uid, 'account.voucher', voucher_id, 'proforma_voucher', cr)
135 sale.write({'payment_id': voucher_id}, context=context)163 sale.write({'payment_ids': [(4,voucher_id)]}, context=context)
136 return True164 return True
137165
138 def button_order_confirm(self, cr, uid, ids, context=None):
139 for order in self.browse(cr, uid, ids, context=context):
140 if order.company_id.sale_order_must_be_paid and not order.payment_id:
141 raise except_osv(_('User Error!'),
142 _('The sale Order %s Must be paid before validation') % (order.name))
143 return super(sale_order, self).button_order_confirm(cr, uid, ids, context=context)
144
145
146166
=== modified file 'sale_quick_payment/sale_view.xml'
--- sale_quick_payment/sale_view.xml 2012-05-24 20:44:25 +0000
+++ sale_quick_payment/sale_view.xml 2013-01-11 17:08:20 +0000
@@ -17,15 +17,23 @@
17 <field eval="16" name="priority"/>17 <field eval="16" name="priority"/>
18 <field name="type">form</field>18 <field name="type">form</field>
19 <field name="arch" type="xml">19 <field name="arch" type="xml">
20 <button name="print_quotation" position="after">
21 <button name="%(open_pay_sale_order)d" string="Register Payments" type="action" states="draft,sent"/>
22 </button>
20 <page string="Other Information" position="after">23 <page string="Other Information" position="after">
21 <page name="automation_information" string="Automation Information">24 <page name="automation_information" string="Automation Information">
22 <group name="payment_information" colspan="4">25 <group name="payment_information" colspan="4">
23 <separator string="Payment Information" colspan="4"/>
24 <field name="payment_method_id" />26 <field name="payment_method_id" />
25 <field name="payment_id" />27 <group name="payments" colspan="4">
28 <separator string="Payments" colspan="4"/>
29 <field name="payment_ids" nolabel="1" />
30 </group>
26 </group>31 </group>
27 </page>32 </page>
28 </page>33 </page>
34 <field name="amount_total" position="after">
35 <field name="residual" invisible="1"/>
36 </field>
29 </field>37 </field>
30 </record>38 </record>
3139
3240
=== added directory 'sale_quick_payment/settings'
=== added file 'sale_quick_payment/settings/sale.exception.csv'
--- sale_quick_payment/settings/sale.exception.csv 1970-01-01 00:00:00 +0000
+++ sale_quick_payment/settings/sale.exception.csv 2013-01-11 17:08:20 +0000
@@ -0,0 +1,3 @@
1id,name,description,sequence,model,code
2must_be_paid,Sale order must be paid before validation,The sale order must be paid before the validation. Please fix it,50,sale.order,"if order.residual > 0:
3 failed = True"
04
=== modified file 'sale_quick_payment/wizard/pay_sale_order.py'
--- sale_quick_payment/wizard/pay_sale_order.py 2012-08-21 13:57:44 +0000
+++ sale_quick_payment/wizard/pay_sale_order.py 2013-01-11 17:08:20 +0000
@@ -25,6 +25,8 @@
25import decimal_precision as dp25import decimal_precision as dp
26from datetime import datetime26from datetime import datetime
2727
28#TODO add button on sale_form header instead of more button
29
28class pay_sale_order(TransientModel):30class pay_sale_order(TransientModel):
29 _name = 'pay.sale.order'31 _name = 'pay.sale.order'
30 _description = 'Wizard to generate a payment from the sale order'32 _description = 'Wizard to generate a payment from the sale order'
@@ -35,15 +37,21 @@
35 'date': fields.datetime('Payment Date'),37 'date': fields.datetime('Payment Date'),
36 }38 }
3739
38 def _get_journal_id(self, cr, uid, args):40 def _get_journal_id(self, cr, uid, context=None):
39 if args.get('payment_method_id'):41 if context is None:
40 payment_method = self.pool.get('payment.method').browse(cr, uid, args['payment_method_id'])42 context = {}
41 return payment_method.journal_id.id43 if context.get('active_id'):
44 order = self.pool.get('sale.order').browse(cr, uid, context['active_id'], context=context)
45 if order.payment_method_id:
46 return order.payment_method_id.journal_id.id
42 return False47 return False
4348
44 def _get_amount(self, cr, uid, args):49 def _get_amount(self, cr, uid, context=None):
45 if args.get('amount_total'):50 if context is None:
46 return args['amount_total']51 context = {}
52 if context.get('active_id'):
53 order = self.pool.get('sale.order').browse(cr, uid, context['active_id'], context=context)
54 return order.residual
47 return False55 return False
4856
49 _defaults = {57 _defaults = {
@@ -60,6 +68,18 @@
60 @param ids: List of account chart’s IDs68 @param ids: List of account chart’s IDs
61 @return: dictionary of Product list window for a given attributs set69 @return: dictionary of Product list window for a given attributs set
62 """70 """
63 for wizard in self.browse(cr, uid, ids, context=context):71 wizard = self.browse(cr, uid, ids[0], context=context)
64 self.pool.get('sale.order').pay_sale_order(cr, uid, context['active_id'], wizard.journal_id.id, wizard.amount, wizard.date, context=context)72 self.pool.get('sale.order').pay_sale_order(cr, uid, context['active_id'], wizard.journal_id.id, wizard.amount, wizard.date, context=context)
65 return {'type': 'ir.actions.act_window_close'}73 return {'type': 'ir.actions.act_window_close'}
74
75 def pay_sale_order_and_confirm(self, cr, uid, ids, context=None):
76 """
77 Pay the sale order
78 @param cr: the current row, from the database cursor,
79 @param uid: the current user’s ID for security checks,
80 @param ids: List of account chart’s IDs
81 @return: dictionary of Product list window for a given attributs set
82 """
83 self.pay_sale_order(cr, uid, ids, context=context)
84 return self.pool.get('sale.order').action_button_confirm(cr, uid, [context['active_id']], context=context)
85
6686
=== modified file 'sale_quick_payment/wizard/pay_sale_order.xml'
--- sale_quick_payment/wizard/pay_sale_order.xml 2012-04-22 12:48:34 +0000
+++ sale_quick_payment/wizard/pay_sale_order.xml 2013-01-11 17:08:20 +0000
@@ -6,14 +6,19 @@
6 <field name="model">pay.sale.order</field>6 <field name="model">pay.sale.order</field>
7 <field name="type">form</field>7 <field name="type">form</field>
8 <field name="arch" type="xml">8 <field name="arch" type="xml">
9 <form string="Pay Sale Order">9 <form string="Pay Sale Order" version="7.0">
10 <field name="journal_id" colspan="4"/>10 <group>
11 <field name="amount" colspan="4"/>11 <field name="journal_id" string="Journal"/>
12 <field name="date" colspan="4"/>12 <field name="amount" string="Paid Amount"/>
13 <group colspan="4">13 <field name="date" string="Date"/>
14 <button icon="gtk-cancel" special="cancel" string="Cancel"/>
15 <button icon="gtk-ok" name="pay_sale_order" string="Pay" type="object"/>
16 </group>14 </group>
15 <footer>
16 <button string="Pay" name="pay_sale_order" type="object" class="oe_highlight"/>
17 or
18 <button string="Pay And Confirm Order" name="pay_sale_order_and_confirm" type="object" class="oe_highlight"/>
19 or
20 <button string="Cancel" class="oe_link" special="cancel"/>
21 </footer>
17 </form>22 </form>
18 </field>23 </field>
19 </record>24 </record>
@@ -26,13 +31,5 @@
26 <field name="target">new</field>31 <field name="target">new</field>
27 <field name="view_id" ref="pay_sale_order_view"/>32 <field name="view_id" ref="pay_sale_order_view"/>
28 </record>33 </record>
29
30 <record id="ir_action_open_pay_sale_order" model="ir.values">
31 <field name="key2">client_action_multi</field>
32 <field name="model">sale.order</field>
33 <field name="name">Sale.Order</field>
34 <field eval="'ir.actions.act_window,%d'%open_pay_sale_order" name="value"/>
35 <field eval="True" name="object"/>
36 </record>
37 </data>34 </data>
38</openerp>35</openerp>

Subscribers

People subscribed via source and target branches