Django export to xlsx with lock columns - django

I have this code for exporting data to CSV.
How can I lock some columns in this file?
For example: lock 'id' and 'Subsidiary' that the the user won't be able to edit
views.py
def combinationExport(request):
combination = Combination.objects.all()
response = HttpResponse(content_type="text/csv")
response["Content-Disposition"] = 'attachment; filename="Combination.csv"'
writer = csv.writer(response)
writer.writerow(
[
"id",
"Subsidiary",
"Department",
"Account",
"Sub Budget",
"Budget Owner",
"Sub Budget Owner",
]
)
combo = combination.values_list(
"id",
"subsidiary__name",
"department__name",
"account__name",
"sub_budget__name",
"budget_owner__budget_owner__name",
"budget_owner__sub_budget_owner__name",
)
for q in combo:
writer.writerow(q)
# print(q)
return response
TNX

I found a solution.
class YearScenarioExportView(
Budgetlevel3Mixin, BudgetMixin, LoginRequiredMixin, DetailView
):
model = YearScenario
def get(self, request, pk: int):
self.object: YearScenario = self.get_object()
qs = self.object.rows.fast()
df = pd.DataFrame.from_records(
qs.values_list(
"code",
"scenario_year__scenario__scenario",
"scenario_year__year__year",
"scenario_year__version__version",
"combination__subsidiary__name",
"combination__department__name",
"combination__account__name",
"combination__sub_budget__name",
"combination__budget_owner__budget_owner__name",
"combination__budget_owner__sub_budget_owner__name",
"is_active",
"budget_q1",
"budget_q2",
"budget_q3",
"budget_q4",
"q1_comment",
"q2_comment",
"q3_comment",
"q4_comment",
),
columns=[
"code",
"scenario",
"year",
"version",
"subsidiary",
"department",
"account",
"sub_budget",
"budget_owner",
"sub_budget_owner",
"is_active",
"budget_q1",
"budget_q2",
"budget_q3",
"budget_q4",
"q1_comment",
"q2_comment",
"q3_comment",
"q4_comment",
],
)
# print(df)
output = io.BytesIO()
workbook = xlsxwriter.Workbook(output, {"in_memory": True})
worksheet = workbook.add_worksheet("Tablib Dataset")
unlocked = workbook.add_format({"locked": False})
worksheet.set_column("A:A", 40)
worksheet.protect()
bold = workbook.add_format({"bold": True})
# Write the title for every column in bold
worksheet.write("A1", "code", bold)
worksheet.write("B1", "scenario", bold)
worksheet.write("C1", "year", bold)
worksheet.write("D1", "version", bold)
worksheet.write("E1", "subsidiary", bold)
worksheet.write("F1", "department", bold)
worksheet.write("G1", "account", bold)
worksheet.write("H1", "sub_budget", bold)
worksheet.write("I1", "budget_owner", bold)
worksheet.write("J1", "sub_budget_owner", bold)
worksheet.write("K1", "is_active", bold)
worksheet.write("L1", "q1", bold)
worksheet.write("M1", "q2", bold)
worksheet.write("N1", "q3", bold)
worksheet.write("O1", "q4", bold)
worksheet.write("P1", "q1_comment", bold)
worksheet.write("Q1", "q2_comment", bold)
worksheet.write("R1", "q3_comment", bold)
worksheet.write("S1", "q4_comment", bold)
# Iterate over the data and write it out row by row.
for linea in df.index:
worksheet.write(f"A{linea+2}", df["code"][linea])
worksheet.write(f"B{linea+2}", df["scenario"][linea])
worksheet.write(f"C{linea+2}", df["year"][linea])
worksheet.write(f"D{linea+2}", df["version"][linea])
worksheet.write(f"E{linea+2}", df["subsidiary"][linea])
worksheet.write(f"F{linea+2}", df["department"][linea])
worksheet.write(f"G{linea+2}", df["account"][linea])
worksheet.write(f"H{linea+2}", df["sub_budget"][linea])
worksheet.write(f"I{linea+2}", df["budget_owner"][linea])
worksheet.write(f"J{linea+2}", df["sub_budget_owner"][linea])
worksheet.write(f"K{linea+2}", df["is_active"][linea], unlocked)
worksheet.write(f"L{linea+2}", df["budget_q1"][linea], unlocked)
worksheet.write(f"M{linea+2}", df["budget_q2"][linea], unlocked)
worksheet.write(f"N{linea+2}", df["budget_q3"][linea], unlocked)
worksheet.write(f"O{linea+2}", df["budget_q4"][linea], unlocked)
worksheet.write(f"P{linea+2}", df["q1_comment"][linea], unlocked)
worksheet.write(f"Q{linea+2}", df["q2_comment"][linea], unlocked)
worksheet.write(f"R{linea+2}", df["q3_comment"][linea], unlocked)
worksheet.write(f"S{linea+2}", df["q4_comment"][linea], unlocked)
workbook.close()
output.seek(0)
response = HttpResponse(
output.read(),
content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
)
file_name = f"{self.object.get_export_file_name_base()}"
response["Content-Disposition"] = f"attachment; filename={file_name}.xlsx"
return response
I converted my Query to Dataframe and export it via response

Related

Retrieving Stripe metadata and process it

I am sending cart data from the cookies to Stripe and retrieving it, but I am unable to find a solution to process it correctly.
Please help!
I am learning Django and wanted to save the cart items of non-logged users into the cookies and send it to Stripe, as Metadata.
From there retrieve it and if the checkout is completed to process the order, but I am unsuccessful to process the data that is retrieved to be able to save the order.
Stripe Checkout Session:
#csrf_exempt
def create_checkout_session(request):
stripe.api_key = settings.STRIPE_SECRET_KEY
domain_url = 'http://localhost:8000/checkout/'
if request.user.is_authenticated:
customer = request.user.customer
else:
data = json.loads(request.body)
total = data['form']['total'].replace('.', '')
email = data['form']['email']
first_name = data['form']['first_name']
last_name = data['form']['last_name']
customer, created = Customer.objects.get_or_create(
email=email
)
customer.first_name = first_name
customer.last_name = last_name
customer.save()
cart_info = cart_details(request)
cart_items = cart_info['cart_items']
order = cart_info['order']
items = cart_info['items']
print(items)
if request.method == 'GET':
checkout_session = stripe.checkout.Session.create(
shipping_address_collection={
"allowed_countries":
["US", "CA", "NL", "GB"]
},
client_reference_id=request.user.id,
customer_email=request.user.email,
success_url=domain_url + 'success?session_id={CHECKOUT_SESSION_ID}',
cancel_url=domain_url + 'cancelled/',
payment_method_types=['card'],
mode='payment',
line_items=[
{
'name': 'Kenpachi Katana Store',
'quantity': 1,
'currency': 'usd',
'amount': int(order.get_cart_total*100),
}
]
)
return JsonResponse({'sessionId': checkout_session['id']})
else:
checkout_session = stripe.checkout.Session.create(
shipping_address_collection={
"allowed_countries":
["US", "CA", "NL"]
},
**metadata=[items]**,
client_reference_id=customer.id,
customer_email=email,
success_url=domain_url + 'success?session_id={CHECKOUT_SESSION_ID}',
cancel_url=domain_url + 'cancelled/',
payment_method_types=['card'],
mode='payment',
line_items=[
{
'name': 'Kenpachi Katana Store',
'quantity': 1,
'currency': 'usd',
'amount': total,
}
]
)
return JsonResponse({'sessionId': checkout_session['id']})
Terminal Output with the Cookie Cart variable:
print(type(items))
<class 'list'>
And:
[{'product':
`{'id': 1,
'name': 'Sasuke Katana',
'price': Decimal('270.00'),
'imageURL': '/media/1_ccbb983f-a35d-40f8-8efb-dc55db02ad8f_700x.webp'},
'quantity': 1,
'get_total': Decimal('270.00')},
`
{'product':
{'id': 3,
'name': 'Zoro Katana',
'price': Decimal('260.00'),
'imageURL': '/media/1_466b0afb-d483-4a32-b0bb-89388aeccaa4_700x.webp'},
'quantity': 1,
'get_total': Decimal('260.00')
}]
And it easy to loop through it
for item in items:
print(item)
Output:
enter image description here
After the the order is completed, I retrieve the Stripe Session to fulfill the order
#csrf_exempt
def stripe_webhook(request):
stripe.api_key = settings.STRIPE_SECRET_KEY
endpoint_secret = settings.STRIPE_ENDPOINT_SECRET
payload = request.body
sig_header = request.META['HTTP_STRIPE_SIGNATURE']
event = None
try:
event = stripe.Webhook.construct_event(
payload,
sig_header,
endpoint_secret
)
except ValueError as e:
return HttpResponse(status=400)
except stripe.error.SignatureVerificationError as e:
return HttpResponse(status=400)
if event['type'] == 'checkout.session.completed':
session = event['data']['object']
session = stripe.checkout.Session.retrieve(
event['data']['object']['id'],
expand=['line_items'],
)
stripe_metadata = session['metadata'].setdefault('0')
print(stripe_metadata)
print(type(stripe_metadata))
# Fulfill the purchase...
# TODO: drill down on the metadata from stripe
transaction_id = datetime.datetime.now().timestamp()
total = session['amount_total']
customer_id = session['client_reference_id']
customer = Customer.objects.get(pk=customer_id)
order, created = Order.objects.get_or_create(
customer=customer,
complete=False
)
order.transaction_id = transaction_id
if (total / 100) == int(order.get_cart_total):
order.complete = True
ShippingAddress.objects.create(
customer=customer,
order=order,
address=session['shipping']['address']['line1'],
city=session['shipping']['address']['city'],
state=session['shipping']['address']['state'],
zipcode=session['shipping']['address']['postal_code'],
country=session['shipping']['address']['country'],
)
order.save()
print('Order was added to the database')
return HttpResponse(status=200)
Terminal Output:
enter image description here
What would be the best option to retrieve it in the same format, to be able to iterate through the products of the cart.
Any help would be deeply appreciated.
GitHub repo with the cookie cart function:
https://github.com/GeorgianF/Kenpachi-P5-CI/blob/main/cart/utils.py
Thank you!
Maybe you can try
stripe_metadata = json.loads(str(stripe_metadata))
to convert string to JSON format

IntegrityError in djnago

Can't find a solution to this error please help or show me how to fix this.
The error is showing as follows:
(1048, "Column 'targetDefn_id' cannot be null") this error is showing when I post data.
This is my views.py in Post method I m getting this error:
def setTarget(request):
if request.method == 'POST':
data=JSONParser().parse(request)
print(data)
serial=TargetSerializers(data=data)
print(serial)
if serial.is_valid():
serial.save()
print("done")
return JsonResponse(serial.data,status=status.HTTP_200_OK,safe=False)
return JsonResponse(serial.errors, status=status.HTTP_400_BAD_REQUEST)
This is my Serializer.py as follows:
class TargetSerializers(serializers.ModelSerializer):
targetDefn=serializers.SerializerMethodField()
roleId=serializers.SerializerMethodField()
empId=serializers.SerializerMethodField()
class Meta:
model = Target
fields = (
'id',
'targetDefn',
'roleId',
'empId',
'startDate',
'endDate',
'value'
)
def get_targetDefn(self,obj):
trgt = TargetDefination.objects.get(id=obj.targetDefn_id)
serial = TargetDefinationSerializers(trgt)
return serial.data
def get_empId(self,obj):
emp= Employee.objects.get(id=obj.empId_id)
serial= OnlyEmployeeSerializers(emp)
return serial.data
def get_roleId(self,obj):
role=Role.objects.get(id=obj.roleId_id)
serial=RoleSerializers(role)
return serial.data
This is models.py as follows:
class Target(models.Model):
targetDefn=models.ForeignKey(TargetDefination,on_delete=models.CASCADE)
roleId=models.ForeignKey(Role,on_delete=models.CASCADE)
empId=models.ForeignKey(Employee,on_delete=models.CASCADE)
startDate= models.DateField(default=datetime.date.today)
endDate= models.DateField(null=True,blank=True)
value=models.PositiveIntegerField(default=0)
def __str__(self):
return str(self.empId) + ' ' +str(self.targetDefn)
Updated:
My Post query:
{
"targetDefn": {
"id": 1,
"targetName": "MIN SALES",
"displayName": "MIN SALES"
},
"roleId": {
"id": 3,
"roleName": "CIO",
"description": "chief information officer",
"roleReportsTo": 5,
"roleReportsToName": "SeniorVP(M)"
},
"empId": {
"id": 2,
"empName": "Emp02",
"startDate": "2021-04-01",
"termDate": null
},
"startDate": "2021-05-11",
"endDate": "2021-05-20",
"value": "123"
}
Know that the SerializerMethodField is READ-ONLY. It means that the data of those fields will not be written in the database. They will be computed and sent to your user, but never written in the DB. So, when you're saving your serializer, those fields are ignored.
I've noticed that you've created SerializerMethodField for all your foreign keys, only for their get_[field] method to return literally the serialized object. So why not simply use their nested-serializer right away?
class TargetSerializers(serializers.ModelSerializer):
targetDefn=TargetDefinationSerializers()
roleId=OnlyEmployeeSerializers()
empId=serializers.SerializerMethodField()
class Meta:
model = Target
fields = (
'id',
'targetDefn',
'roleId',
'empId',
'startDate',
'endDate',
'value'
)
If you cannot get it to work or wish to keep your SerializerMethodField structure, then we must add the data of those 3 fields before saving. You can either pass the data as parameter in the serializer, like so:
serializer.save(targetDefn=variable_1, roleId=variable_2, empId=variable_3)
Or you can override the create and update serializer methods to do it there, example:
def create(self, validated_data):
targetDefn = validated_data["targetDefn"]
roleId = validated_data["roleId"]
emp_id = validated_data["emp_id"]
# preprocess those data if needed
# Then create your model
Target.objects.create(targetDefn=targetDefn, ...)

Django - needs to have a value for field "id" before this many-to-many relationship can be used

I have two serializers
class CheckItemSerializer(serializers.ModelSerializer):
class Meta:
model = CheckItem
fields = (
'item_name',
'amount',
)
class PaymentActionSerializer(serializers.ModelSerializer):
items = CheckItemSerializer(many=True, required=False)
class Meta:
model = PaymentAction
fields = [
'booking_number',
'date',
'guest_name',
'isRefund',
'lcode',
'payment_type',
'positions',
'total',
'items',
'id'
]
def create(self, validated_data):
action = PaymentAction.objects.create(**validated_data)
action.save()
if validated_data.get('items', None) is not None:
items = validated_data.pop('items')
if items is not None:
for item in items:
item_name = item['item_name']
amount = item['amount']
new_item = CheckItem.objects.create(
item_name=item_name,
amount=amount
)
new_item.save()
action.items.add(new_item)
action.save()
return action
and json
{"lcode": 123,
"total": 1,
"isRefund": false,
"booking_number": "333",
"guest_name": "me",
"positions": "1 night",
"date": "2019-07-22 00:00",
"payment_type": "nal",
"items": [
{
"item_name": "glazka",
"amount": "100"
},
{
"item_name": "glazka2",
"amount": "150"
}
]
}
and I get error
"<PaymentAction: PaymentAction object>" needs to have a value for field "id" before this many-to-many relationship can be used.
What am I doing wrong ?
You passed the items parameter to your PaymentAction object as well, but since at that point, your PaymentAction has not (yet) a primary key, it can not add these items to a many-to-many field.
You thus should pop that from the validated_data first:
def create(self, validated_data):
items = validated_data.pop('items', None)
action = PaymentAction.objects.create(**validated_data)
if items is not None:
items = [CheckItem.objects.create(**item) for item in items]
action.items.add(*items)
return action

How to get the field value that is excluded in order to change the row background

I want to display a table in which some fields are excluded, because I do not want to display them in a table.
At the same time, I want to change the color in the row based on the values ​​that are excluded. Is it possible to do this with django-table2 ?
import django_tables2 as tables
from web_logic.models import Stations
from django_tables2.utils import A
class StationTable(tables.Table):
"""
"""
station_id = tables.LinkColumn()
rack_sum = tables.LinkColumn("racks_page", args=[A('pk')], verbose_name='Кол-во стоек')
status = tables.BooleanColumn()
def __init__(self, *args, **kwargs):
super(StationTable, self).__init__(*args, **kwargs)
def render_station_id(self, value):
print(value)
return "%s " % value
class Meta:
model = Stations
exclude = (
"id",
"onboot_time",
'certificat_key',
'private_key',
"status",
"ipadress",
'latitude',
'longitude',
)
template_name = 'django_tables2/bootstrap.html'
attrs = {
"class": "table",
"td": {"class": "table-hover",},
"thead": {"class": "table-dark"},
}
For example, the status field describes a state for the entire row. It can be True or False. I do not want to display the column with this field, but I want to highlight (change the color of the line) based on the value for this field. How can i do this ?
Yes, you can do this using row_attrs:
class StationTable(tables.Table):
station_id = tables.LinkColumn()
rack_sum = tables.LinkColumn("racks_page", args=[A('pk')], verbose_name='Кол-во стоек')
def render_station_id(self, value):
return "%s " % value
class Meta:
model = Stations
exclude = (
"id",
"onboot_time",
'certificat_key',
'private_key',
"status",
"ipadress",
'latitude',
'longitude',
)
template_name = 'django_tables2/bootstrap.html'
attrs = {
"class": "table",
"td": {"class": "table-hover",},
"thead": {"class": "table-dark"},
}
row_attrs = {
"class": lambda record: "info" if record.status else ""
}
This will add attribute class="info" to the <tr>-tag of rows with status = True.

Invoice number and taxes amounts creating invoices from custom Odoo module

I'm migrating invoices from OpenERP 7 database to Odoo8. I'm retrieving OERP7 data with psycopg2 and then using envs and model.create() to insert invoices into Odoo8 database. In general, the code works fine, but Odoo8 is not generating the invoice number (associated to account_move table) and amount_tax.
My codes are the following:
Import Account Invoice
class ImportAccountInvoice(Command):
"""Import account invoices from source DB"""
def process_account_invoice(self, model, data):
if not data:
return
# Model structure
model.create({
'account_id': data['account_id'],
'amount_tax': data['amount_tax'],
'amount_total': data['amount_total'],
'amount_untaxed': data['amount_untaxed'],
'check_total': data['check_total'],
'company_id': data['company_id'],
'currency_id': data['currency_id'],
'date_due': data['date_due'],
'date_invoice': data['date_invoice'],
'fiscal_position': data['fiscal_position'],
'internal_number': data['internal_number'],
'move_name': data['move_name'],
'name': data['name'],
'origin': data['origin'],
'partner_id': data['partner_id'],
'period_id': data['period_id'],
'reconciled': data['reconciled'],
'reference': data['reference'],
'residual': data['residual'],
'state': data['state'],
'type': data['type'],
'ship_addr_city': data['ship_addr_city'],
'ship_addr_name': data['ship_addr_name'],
'client_notes': data['client_notes'],
'ship_addr_state': data['ship_addr_state'],
'ship_addr_street': data['ship_addr_street'],
'ship_addr_phone': data['ship_addr_phone'],
'ship_addr_zip': data['ship_addr_zip'],
'drupal_order_name': data['drupal_order_name'],
'payment_method': data['payment_method'],
'drupal_total': data['drupal_total']
})
def run(self, cmdargs):
print "Importing account invoices"
execute_old_database_query("""
SELECT i.id, i.account_id, i.amount_tax, i.amount_total, i.amount_untaxed, i.check_total, i.company_id, i.currency_id, i.date_due,
i.date_invoice, i.fiscal_position, i.internal_number, i.journal_id, i.move_name, i.name, i.origin, i.partner_id, i.period_id,
i.reconciled, i.reference, i.residual, i.sent, i.state, i.type, i.x_dir_city, i.x_dir_name, i.x_dir_observations,
i.x_dir_state, i.x_dir_street, i.x_dir_telephone, i.x_dir_zip, i.x_drupal_order, i.x_pago, i.x_total,
rp.id, rp.email, rp.name, rp.type, rp.vat, rp.street,
rc.id, rc.name,
aa.id, aa.code, aa.name,
ap.id, ap.code, ap.name, ap.date_start, ap.date_stop,
aj.type, aj.code,
fp.name
FROM account_invoice i
LEFT JOIN res_partner rp
ON rp.id = i.partner_id
LEFT JOIN res_currency rc
ON rc.id = i.currency_id
LEFT JOIN account_account aa
ON aa.id = i.account_id
LEFT JOIN account_period ap
ON ap.id = i.partner_id
LEFT JOIN account_journal aj
ON aj.id = i.journal_id
LEFT JOIN account_fiscal_position fp
ON fp.id = i.fiscal_position
ORDER BY i.id;
""")
openerp.tools.config.parse_config(cmdargs)
dbname = openerp.tools.config['db_name']
r = modules.registry.RegistryManager.get(dbname)
cr = r.cursor()
with api.Environment.manage():
env = api.Environment(cr, 1, {})
# Define target model
account_invoice = env['account.invoice']
id_ptr = None
c_data = {}
while True:
r = src_cr.fetchone()
if not r:
self.process_account_invoice(account_invoice, c_data)
break
print r
account = env['account.account'].search([('code','=',r[43]),('name','=',r[44]),])
currency = env['res.currency'].search([('name','=',r[41]),])
period = match_account_period(env,code=r[46],name=r[47],date_start=r[48],date_stop=r[49])
journal = match_account_journal(env,type=r[50],code=r[51])
fiscal_position = match_account_fiscal_position(env,name=r[52])
company_id = 1
if r[38] is not None and r[39] is not None:
partner = env['res.partner'].search([('email','=',r[35]),('name','=',r[36]),('type','=',r[37]),('vat','=',r[38]),('street','=',r[39])])
elif r[38] is not None:
partner = env['res.partner'].search([('email','=',r[35]),('name','=',r[36]),('type','=',r[37]),('vat','=',r[38])])
elif r[39] is not None:
partner = env['res.partner'].search([('email','=',r[35]),('name','=',r[36]),('type','=',r[37]),('street','=',r[39])])
else:
partner = env['res.partner'].search([('email','=',r[35]),('name','=',r[36]),('type','=',r[37])])
# Take one when partners are duplicated
partner_id = partner.id if len(list(partner)) <= 1 else partner[0].id
fiscal_position_id = fiscal_position.id if fiscal_position else None
if id_ptr != r[0]:
self.process_account_invoice(account_invoice, c_data)
id_ptr = r[0]
c_data = {
'id': r[0],
'account_id': account.id,
'amount_tax': r[2],
'amount_total': r[3],
'amount_untaxed': r[4],
'check_total': r[5],
'company_id': company_id,
'currency_id': currency.id,
'date_due': r[8],
'date_invoice': r[9],
'fiscal_position': fiscal_position_id,
'internal_number': r[11],
'journal_id': journal.id,
'move_name': r[13],
'name': r[14],
'origin': r[15],
'partner_id': partner_id,
'partner_invoice_id': partner_id,
'partner_shipping_id': partner_id,
'period_id': period.id,
'reconciled': r[18],
'reference': r[19],
'residual': r[20],
'sent': r[21],
'state': r[22],
'type': r[23],
'ship_addr_city': r[24],
'ship_addr_name': r[25],
'client_notes': r[26],
'ship_addr_state': r[27],
'ship_addr_country': '',
'ship_addr_street': r[28],
'ship_addr_phone': r[29],
'ship_addr_zip': r[30],
'drupal_order_name': r[31],
'payment_method': r[32],
'drupal_total': r[33]
}
cr.commit()
cr.close()
Import Account Invoice Lines
class ImportAccountInvoiceLine(Command):
"""Import account invoice lines from source DB"""
def process_account_invoice_line(self, model, data):
if not data:
return
# Model structure
m = {
'account_id': data['account_id'],
'create_date': data['create_date'],
'company_id': data['company_id'],
'discount': data['discount'],
'invoice_id': data['invoice_id'],
'name': data['name'],
'partner_id': data['partner_id'],
'product_id': data['product_id'],
'quantity': data['quantity'],
'price_unit': data['price_unit'],
'price_subtotal': data['price_subtotal'],
'supplier_name': data['supplier_name'],
'supplier_ref': data['supplier_ref'],
'item_lot_number': data['item_lot_number'],
'item_expiration': data['item_expiration'],
'item_delivery_note': data['item_delivery_note'],
}
if not data['invoice_line_tax_id'] is None:
m['invoice_line_tax_id'] = [(4,data['invoice_line_tax_id'])] # http://stackoverflow.com/questions/31853402/filling-many2many-field-odoo-8
print model.create(m)
def recalculate_tax_amount(self,cr):
with api.Environment.manage():
env = api.Environment(cr, 1, {})
invoices = env['account.invoice'].search([])
account_invoice_tax = env['account.invoice.tax']
print "Recalculating invoice taxes"
for invoice in invoices:
print invoice
print invoice.action_move_create()
# print invoice.button_reset_taxes()
if invoice.id <= 32600:
break
def run(self, cmdargs):
print "Importing account invoice lines"
execute_old_database_query("""
SELECT il.id, il.account_id, il.create_date, il.company_id, il.discount, il.invoice_id, il.name, il.partner_id, il.price_unit,
il.price_subtotal, il.product_id, il.quantity, il.x_prov, il.x_ref_prov, il.x_lote, il.x_caducidad, il.x_albaran,
i.internal_number, i.name, i.origin, i.reference, i.type, i.x_drupal_order, i.date_invoice,
rp.email, rp.name, rp.type, rp.vat, rp.street,
pp.default_code, pp.name_template, pp.x_subcategoria, pp.x_marca,
at.type_tax_use, at.name
FROM account_invoice_line il
LEFT JOIN account_invoice i
ON i.id = il.invoice_id
LEFT JOIN res_partner rp
ON rp.id = il.partner_id
LEFT JOIN product_product pp
ON pp.id = il.product_id
LEFT JOIN account_invoice_line_tax ailt
ON ailt.invoice_line_id = il.id
LEFT JOIN account_tax at
ON at.id = ailt.tax_id
WHERE il.id > 28700
ORDER BY il.id DESC;
""")
openerp.tools.config.parse_config(cmdargs)
dbname = openerp.tools.config['db_name']
r = modules.registry.RegistryManager.get(dbname)
cr = r.cursor()
with api.Environment.manage():
env = api.Environment(cr, 1, {})
# Define target model
account_invoice_line = env['account.invoice.line']
id_ptr = None
c_data = {}
company_id = 1
while True:
r = src_cr.fetchone()
if not r:
self.process_account_invoice_line(account_invoice_line, c_data)
break
print r
print r[17],r[18],r[19],r[20],r[21]
if not (r[17] is None and r[18] is None and r[19] is None and r[20] is None):
account_invoice = env['account.invoice'].search([('internal_number','=',r[17]),('name','=',r[18]),('origin','=',r[19]),('reference','=',r[20]),('type','=',r[21]),('drupal_order_name','=',r[22]),('date_invoice','=',r[23])])
print "normal"
else:
print "parner"
if r[27] is not None and r[28] is not None:
partner = env['res.partner'].search([('email','=',r[24]),('name','=',r[25]),('type','=',r[26]),('vat','=',r[27]),('street','=',r[28])])
elif r[27] is not None:
partner = env['res.partner'].search([('email','=',r[24]),('name','=',r[25]),('type','=',r[26]),('vat','=',r[27])])
elif r[28] is not None:
partner = env['res.partner'].search([('email','=',r[24]),('name','=',r[25]),('type','=',r[26]),('street','=',r[28])])
else:
partner = env['res.partner'].search([('email','=',r[24]),('name','=',r[25]),('type','=',r[26])])
# Take one when partners are duplicated
partner_id = partner.id if len(list(partner)) <= 1 else partner[0].id
account_invoice = env['account.invoice'].search([('internal_number','=',r[17]),('name','=',r[18]),('origin','=',r[19]),('reference','=',r[20]),('type','=',r[21]),('drupal_order_name','=',r[22]),('date_invoice','=',r[23]),('partner_id','=',partner_id)])
if not account_invoice: # If there is not an account_invoice for this partner, continue with the next row
print "^ NO INVOICE FOR THIS LINE ^"
continue
product = env['product.product'].search([('default_code','=',r[29]),('name_template','=',r[30]),('subcategory_txt','=',r[31]),('brand','=',r[32])])
# Take one when invoices are duplicated
invoice = account_invoice if len(list(account_invoice)) <= 1 else account_invoice[0]
# Take one when products are duplicated
product_id = product.id if len(list(product)) <= 1 else product[0].id
print r[33],r[34]
if r[33] is None and r[34] is None:
tax_id = None
else:
tax = match_account_tax(env, r[33], r[34])
tax_id = tax.id
if id_ptr != r[0]:
self.process_account_invoice_line(account_invoice_line, c_data)
id_ptr = r[0]
c_data = {
'id': r[0],
'account_id': invoice.account_id.id,
'create_date': r[2],
'company_id': r[3],
'discount': r[4],
'invoice_id': invoice.id,
'name': r[6],
'partner_id': invoice.partner_id.id,
'price_unit': r[8],
'price_subtotal': r[9],
'product_id': product_id,
'quantity': r[11],
'supplier_name': r[12],
'supplier_ref': r[13],
'item_lot_number': r[14],
'item_expiration': r[15],
'item_delivery_note': r[16],
'invoice_line_tax_id': tax_id
}
cr.commit()
self.recalculate_tax_amount(cr)
cr.close()
I have associated Journals, Periods... but I can't get Odoo creates the account.move and compute all taxes. What should I do?
IMPORTANT: I need to assign the same number each invoice already have in old database.
The solution was to create a function to update invoice taxes and move, at the end of invoice lines insertion and before commit.
The function:
def refresh_invoices_and_recompute_taxes(self, model, invoice_ids):
for i in invoice_ids:
print "Updating invoice", i
invoice = model.browse(i)
print "- Computing taxes"
invoice.button_compute(set_total=True)
invoice.action_date_assign()
print "- Creating account move"
invoice.action_move_create()
print "- Assigning number"
invoice.action_number()
My class:
class ImportAccountInvoiceLine(Command):
"""Import account invoice lines from source DB"""
def process_account_invoice_line(self, model, data):
if not data:
return
m = {
'account_id': data['account_id'],
'create_date': data['create_date'],
'company_id': data['company_id'],
'discount': data['discount'],
'invoice_id': data['invoice_id'],
'name': data['name'],
'partner_id': data['partner_id'],
'product_id': data['product_id'],
'quantity': data['quantity'],
'price_unit': data['price_unit'],
'price_subtotal': data['price_subtotal'],
'supplier_name': data['supplier_name'],
'supplier_ref': data['supplier_ref'],
'item_lot_number': data['item_lot_number'],
'item_expiration': data['item_expiration'],
'item_delivery_note': data['item_delivery_note'],
}
if not data['invoice_line_tax_id'] is None:
m['invoice_line_tax_id'] = [(4,data['invoice_line_tax_id'])] # http://stackoverflow.com/questions/31853402/filling-many2many-field-odoo-8
# Model structure
model.create(m)
def refresh_invoices_and_recompute_taxes(self, model,invoice_ids):
for i in invoice_ids:
print "Updating invoice", i
invoice = model.browse(i)
print "- Computing taxes"
invoice.button_compute(set_total=True)
invoice.action_date_assign()
print "- Creating account move"
invoice.action_move_create()
print "- Assigning number"
invoice.action_number()
def run(self, cmdargs):
print "Importing account invoice lines"
execute_old_database_query("""
SELECT il.id, il.account_id, il.create_date, il.company_id, il.discount, il.invoice_id, il.name, il.partner_id, il.price_unit,
il.price_subtotal, il.product_id, il.quantity, il.x_prov, il.x_ref_prov, il.x_lote, il.x_caducidad, il.x_albaran,
i.internal_number, i.name, i.origin, i.reference, i.type, i.x_drupal_order, i.date_invoice,
rp.email, rp.name, rp.type, rp.vat, rp.street,
pp.default_code, pp.name_template, pp.x_subcategoria, pp.x_marca,
at.type_tax_use, at.name
FROM account_invoice_line il
LEFT JOIN account_invoice i
ON i.id = il.invoice_id
LEFT JOIN res_partner rp
ON rp.id = il.partner_id
LEFT JOIN product_product pp
ON pp.id = il.product_id
LEFT JOIN account_invoice_line_tax ailt
ON ailt.invoice_line_id = il.id
LEFT JOIN account_tax at
ON at.id = ailt.tax_id
ORDER BY il.invoice_id ASC, il.id ASC
LIMIT 10000;
""")
openerp.tools.config.parse_config(cmdargs)
dbname = openerp.tools.config['db_name']
r = modules.registry.RegistryManager.get(dbname)
cr = r.cursor()
invoice_ids = []
inv_id = 0
with api.Environment.manage():
env = api.Environment(cr, 1, {})
# Define target model
account_invoice_line = env['account.invoice.line']
id_ptr = None
c_data = {}
company_id = 1
while True:
r = src_cr.fetchone()
if not r:
self.process_account_invoice_line(account_invoice_line, c_data)
break
if not (r[17] is None and r[18] is None and r[19] is None and r[20] is None):
account_invoice = env['account.invoice'].search([('internal_number','=',r[17]),('name','=',r[18]),('origin','=',r[19]),('reference','=',r[20]),('type','=',r[21]),('drupal_order_name','=',r[22]),('date_invoice','=',r[23])])
else:
if r[27] is not None and r[28] is not None:
partner = env['res.partner'].search([('email','=',r[24]),('name','=',r[25]),('type','=',r[26]),('vat','=',r[27]),('street','=',r[28])])
elif r[27] is not None:
partner = env['res.partner'].search([('email','=',r[24]),('name','=',r[25]),('type','=',r[26]),('vat','=',r[27])])
elif r[28] is not None:
partner = env['res.partner'].search([('email','=',r[24]),('name','=',r[25]),('type','=',r[26]),('street','=',r[28])])
else:
partner = env['res.partner'].search([('email','=',r[24]),('name','=',r[25]),('type','=',r[26])])
# Take one when partners are duplicated
partner_id = partner.id if len(list(partner)) <= 1 else partner[0].id
account_invoice = env['account.invoice'].search([('internal_number','=',r[17]),('name','=',r[18]),('origin','=',r[19]),('reference','=',r[20]),('type','=',r[21]),('drupal_order_name','=',r[22]),('date_invoice','=',r[23]),('partner_id','=',partner_id)])
if not account_invoice: # If there is not an account_invoice for this partner, continue with the next row
print "^ NO INVOICE FOR THIS LINE ^"
continue
product = env['product.product'].search([('default_code','=',r[29]),('name_template','=',r[30]),('subcategory_txt','=',r[31]),('brand','=',r[32])])
# Take one when invoices are duplicated
invoice = account_invoice if len(list(account_invoice)) <= 1 else account_invoice[0]
# Take one when products are duplicated
product_id = product.id if len(list(product)) <= 1 else product[0].id
if not invoice:
continue
else:
if inv_id != invoice.id:
inv_id = invoice.id
invoice_ids.append(inv_id)
tax = match_account_tax(env, r[33], r[34])
tax_id = tax.id if tax is not None and tax else None
if id_ptr != r[0]:
id_ptr = r[0]
c_data = {
'id': r[0],
'account_id': invoice.account_id.id,
'create_date': r[2],
'company_id': r[3],
'discount': r[4],
'invoice_id': invoice.id,
'name': r[6],
'partner_id': invoice.partner_id.id,
'price_unit': r[8],
'price_subtotal': r[9],
'product_id': product_id,
'quantity': r[11],
'supplier_name': r[12],
'supplier_ref': r[13],
'item_lot_number': r[14],
'item_expiration': r[15],
'item_delivery_note': r[16],
'invoice_line_tax_id': tax_id
}
self.process_account_invoice_line(account_invoice_line, c_data)
self.refresh_invoices_and_recompute_taxes(env['account.invoice'], invoice_ids)
cr.commit()
cr.close()