Make a developed function in a custom odoo 9 module work in odoo 11 - python-3.5

I'm using odoo 11 and I want to create a custom module to add stamp tax in each invoice automatically. I have such module developped in odoo 9 but it does not work in odoo 11 after installing it. Here is the code of python (v2.7) file:
from openerp import tools
from openerp.osv import fields, osv
class res_partner(osv.osv):
_name = "res.company"
_inherit = "res.company"
_columns = {
"default_stamp_tax_account": fields.many2one('account.account', "stamp tax account"),
"default_stamp_tax_value": fields.float('stamp tax value'),
}
class account_invoice(osv.osv):
_name = "account.invoice"
_inherit = "account.invoice"
def create(self, cr, uid, values, context=None):
invoice_id = super(account_invoice, self).create(cr, uid, values, context)
res_company = self.pool.get('res.company')
stamp_account = res_company.browse(cr, uid, values.get('company_id')).default_stamp_tax_account.id
tax_value = res_company.browse(cr, uid, values.get('company_id')).default_stamp_tax_value
if stamp_account:
account_invoice_tax = self.pool.get('account.invoice.tax')
tax_line_values = {'base': 0,
'amount': tax_value,
'name': 'Timbre',
'account_id': stamp_account,
'invoice_id': invoice_id
}
account_invoice_tax.create(cr, uid, tax_line_values)
return invoice_id
Any help please !!!

Related

Scriptrunner Create issue and assign to existing epic

While creating a new issue using scriptrunner, I would like to assign it an existing epic. it seems the issue.setCustomFieldValue(epicLinkCustomField) is not working. any help would be greatly appreciated. everything else works fine, im able to set name, summary, tittle, prio, description, assign reporter, projectkey, issue context, and issue type.
The code I have is below.
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.context.IssueContext
import com.atlassian.jira.issue.context.IssueContextImpl
import com.atlassian.jira.issue.fields.config.manager.PrioritySchemeManager
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.MutableIssue
import java.text.SimpleDateFormat
def date = new Date()
def sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")
// the project key under which the issue will get created
final projectKey = 'SEC'
// stores status
final statusKey = 'AN QUE'
// the issue type for the new issue
final issueTypeName = 'Task'
// user with that user key will be the reporter of the issue
final reporterKey = 'MV108788'
// the summary of the new issue
final summary = 'test' + date
// the priority of the new issue
final priorityName = 'Low'
// sets description
final description = 'this is a decription'
//epic
final epicIssueKey = 'test'
def issueService = ComponentAccessor.issueService
def constantsManager = ComponentAccessor.constantsManager
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def prioritySchemeManager = ComponentAccessor.getComponent(PrioritySchemeManager)
//finds epic
def epicLinkCustomField = ComponentAccessor.customFieldManager.getCustomFieldObjects().findByName(epicIssueKey)
//finds status key
def status = ComponentAccessor.constantsManager.getStatusByName(statusKey)
//finds project key
def project = ComponentAccessor.projectManager.getProjectObjByKey(projectKey)
assert project : "Could not find project with key $projectKey"
//finds issue types
def issueType = constantsManager.allIssueTypeObjects.findByName(issueTypeName)
assert issueType : "Could not find issue type with name $issueTypeName"
// if we cannot find user with the specified key or this is null, then set as a reporter the logged in user
def reporter = ComponentAccessor.userManager.getUserByKey(reporterKey) ?: loggedInUser
// if we cannot find the priority with the given name or if this is null, then set the default priority
def issueContext = new IssueContextImpl(project, issueType) as IssueContext
// finds priority
def priorityId = constantsManager.priorities.findByName(priorityName)?.id ?: prioritySchemeManager.getDefaultOption(issueContext)
//sets all issue settings
def issueInputParameters = issueService.newIssueInputParameters().with {
setStatusId(statusId) //not working
setProjectId(project.id)
setDescription(description)
setIssueTypeId(issueType.id)
setReporterId(reporter.name)
setSummary(summary)
setPriorityId(priorityId)
issue.setCustomFieldValue(epicLinkCustomField)
}
def validationResult = issueService.validateCreate(loggedInUser, issueInputParameters)
assert validationResult.valid : validationResult.errorCollection
def result = issueService.create(loggedInUser, validationResult)
assert result.valid : result.errorCollection

Django Create or update with unique together values

I'm trying to make an attendance system in the frontend I retrieve a list of users which the request.user can take attendance of, I'm using CreateAPIView but this won't get me the desired effect as I want the request.user to be able to toggle between Absent, Present, and on_leave even after the entry has been created on the first request
i have seen questions and answers about create or update here but i couldn't use them so any help would be appriciated
this is my view.py
class AttendanceListCreateAPIView(CreateAPIView):
permission_classes = [IsTeacher_Student]
queryset = Attendance.objects.all()
serializer_class = AttendanceSerializer
def post(self, request, *args, **kwargs):
user = request.user
data = request.data
serializer = AttendanceSerializer(data=data)
if serializer.is_valid():
data_user = serializer.validated_data['user']
## validation
return Response({"message": "Something is wrong, maybe you have already taken attendance for this user"},
status=status.HTTP_400_BAD_REQUEST)
my serializer.py
class AttendanceSerializer(serializers.ModelSerializer):
date = serializers.HiddenField(default=timezone.now)
leave_reason = serializers.CharField(required=False, default="")
class Meta:
model = Attendance
fields = ['user', 'presence', 'leave_reason', 'date']
extra_kwargs = {
'user': {'required': True},
'presence': {'required': True},
'leave_reason': {'required': False},
}
validators = [
UniqueForYearValidator(
queryset=Attendance.objects.all(),
field='user',
date_field='date',
message=("You have already taken the attendance")
)
]
def create(self, validated_data):
instance = Attendance.objects.create(
user=validated_data['user'],
presence=validated_data['presence'],
leave_reason=validated_data['leave_reason'],
date=validated_data['date'],
)
instance.save()
return instance
desired effect
the user fk and date are unique together meaning that if the date isn't unique for the user update it if it is create a new entry

How t return a json response in GET request?

Looking for some help as i am new to python and django ,I am trying to return a response in JSON of an API GET request as the data is to be returned is dictionary made from different instances of different model. but few things are not getting converted in JSON like datetime amount in decimal throwing an error saying not serializable.Also how can i get all the transfer for that perticular order in a list and each instance in a dictionary like[{},{}]
views.py
#api_view(['GET'])
def details(request,id):
if request.method=='GET':
order = get_object_or_404(Orders,id=id,applications=application)
collection = get_object_or_404(Payments,orders=id,direction='COLLECTION',is_active=True)
transfer = get_object_or_404(Payments,orders=order,direction='TRANSEFER',is_active=True)
content = {
'orders': {
"id":id,
"purpose_code":order.purpose_code,
"amount":order.amount,
'collection_payments':{
"id":collection_payments.id,
"amount":collection_payments.amount,
"datetime":collection_payments.datetime,
'transfer': [
{
"id":transfer.id,
"amount":transfer.amount,
"datetime":transfer.datetime,
}
]
}
}
}
return Response(content, status=status.HTTP_200_OK)
models.py
class Orders(models.Model):
id= models.AutoField(primary_key=True)
applications = models.ForeignKey(Applications, on_delete=models.CASCADE)
amount = models.DecimalField(max_digits=19, decimal_places=4)
class Payments(models.Model):
id = models.AutoField(primary_key=True)
orders = models.ForeignKey(Orders, on_delete=models.CASCADE)
direction = models.CharField(max_length=20,choices=[('COLLECTION','COLLECTION'),
('TRANSFER','TRANSFER')])
amount = models.DecimalField(max_digits=19, decimal_places=4, verbose_name='Price in INR')
datetime = models.DateTimeField(auto_now=False,auto_now_add=False)
is_active = models.BooleanField(default=True)

How to create dynamic rest ModelSerializer?

I'm currently working on a big code base and i need to send emails from any potential module, that conduct in Circular Dependencies issues in python
so i tried to use apps.get_model() from django.apps but when serializers are declared the models are not ready.
So i'm trying to create a factory function who build the class at runtime instead of launch time
from rest_framework.serializers import ModelSerializer
def make_serializer(model: str, fields: tuple, options = None, **nested_fields) -> ModelSerializer:
"""Generate a new serializer "On the fly", so the model does not have to be imported at launch time.
"""
model_object = apps.get_model(model)
input_fields = fields
if options is None:
options = {}
class Serializer(ModelSerializer):
class Meta:
model = model_object
fields = input_fields
def create(self, validated_data):
# we won't permit to create data from thoses serializers.
raise NotImplementedError
# configure nested serializers.
for nested_field in nested_fields.values():
for key, nested_serializer_class in nested_field.items():
serializer_instance = nested_serializer_class(**options.get(key, {}))
print(model, key, serializer_instance)
setattr(Serializer, key, serializer_instance)
return Serializer
my tests models looks like
class Band(Model):
name = Charfield(max_length=255)
class Influencer(Model):
entity = Charfield(max_length=255)
class Submission(Model):
influencer = ForeignKey(Influencer, ...)
class Campaign(Model):
band = ForeignKey('band.Band', ...)
submissions = ManyToMany(Submission)
and my testing function is:
def test():
serializer = make_serializer(
model='submission.Campaign',
fields=['pk', 'submissions', 'band'],
options={'submissions': {'many': True}},
nested_fields={
'submissions': make_serializer(
model='submission.Submission',
fields=('influencer',),
nested_fields={
'influencer': make_serializer('influencer.Influencer', ('entity',))
},
),
'band': make_serializer('band.Band', ('name',))
}
)
return serializer
instead of having my fields correly with test()(Campaign.objects.last()).data i only got "pks" and my serialiser looks like:
Serializer():
pk = IntegerField(label='ID', read_only=True)
submissions = PrimaryKeyRelatedField(many=True, queryset=Submission.objects.all())
band = PrimaryKeyRelatedField(allow_null=True, queryset=Band.objects.all(), required=False)
i except and output like:
{
"pk": 1,
"band": {
"name": "BobMarley",
},
"submissions": [
{
"influencer": {"entity": "The influencer's name"}
}
]
}
but i got a ReturnDict containing:
{
"pk": 1,
"band": 523,
"submissions": [6, 7, 8]
}
thanks for your time
well after many headcaches i've found out that i CAN'T setattr on a class after it's declaration, so i use a trick based on a dict
def make_serializer(model: str, fields: tuple, options = None, **nested_fields) -> ModelSerializer:
"""Generate a new serializer "On the fly", so the model does not have to be imported at launch time.
"""
name = f'Serializer_{model}'
model_object = apps.get_model(model)
input_fields = fields
if options is None:
options = {}
def create(self, validated_data):
# we won't permit to create data from thoses serializers.
raise NotImplementedError
class Meta:
model = model_object
fields = input_fields
attrs = {"Meta": Meta}
# configure nested serializers.
for key, nested_serializer_class in nested_fields.items():
attrs[key] = nested_serializer_class(**options.get(key, {}))
attrs['create'] = create
return type(ModelDictSerializer)(name, (ModelDictSerializer,), attrs)
the syntax is something like:
campaign_serializer = make_serializer(
model='submission.Campaign',
fields=['pk', 'submissions', 'band'],
options={'submissions': {'many': True}},
submissions=make_serializer(
model='submission.Submission',
fields=('influencer',),
influencer=make_serializer('influencer.Influencer', ('entity',))
),
band=make_serializer('band.Band', ('name',))
)
and it's working like a charm:
Serializer_submission.Campaign(<Campaign: Campaign object (9665)>):
pk = IntegerField(label='ID', read_only=True)
submissions = Serializer_submission.Submission(many=True):
influencer = Serializer_influencer.Influencer():
entity = CharField(allow_blank=True, max_length=255, required=False)
band = Serializer_band.Band():
name = CharField(max_length=255)
i hope this will help someone else

make some model field conditionally visible in django

I have two field in my django model they should be editable only if user have selected 'type' as 'Dimention' otherwise they should not be visible to user.
My model is look like this code
from django.db import models
class Configuration(models.Model):
name = models.CharField(max_length=30)
user_defined_name = models.CharField(max_length=50)
FieldTypes = (('aD', 'Dimension'), ('aM', 'Measure'))
type = models.CharField(max_length=11, choices=FieldTypes)
is_key = models.BooleanField(default=False, editable=False)
unit = models.CharField(max_length=30, null=True, blank=True, editable=False)
def __str__(self):
return self.name
I know it is possible by using JavaScript but, I don't want to write html or js myself,Thus Can't use JavaScript for doing this.
A pure Django-only way to achieve this is to simply reset the fields from your ModelForm if type is not equal to Dimension. This will appear like magic/unintended behavior; so be careful of the implementation.
For example (assuming you are using the admin interface: the same is valid for a custom ModelForm View):
class ConfigurationAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
# At this point; the object already has the new values set; we will have to reset as needed
conditional_editable_fields = ['is_key', 'unit']
config_type = form.cleaned_data.get('type')
if config_type != 'aD':
for field in conditional_editable_fields:
if field in form.changed_data: # The value has been changed by the user
setattr(obj, field, form.initial.get(field)) # Set the initial value
self.message_user(request, "Cannot edit field: {}; value has been reset".format(field), messages.WARNING) # Inform the user that we reset the value
return super(ConfigurationAdmin, self).save_mode(request, obj, form, change)
I use similar approach for this.
I it works great
In My admin.py
`
fieldsets = (
(None, {
'fields': ('name', 'user_defined_name', 'type', 'is_active')
}),
('Advanced', {
'classes': ('toggle',),
'fields': ('is_kpi', 'unit'),
})
)
actions = [disable_multiple_column, activate_multiple_column]
class Media:
js = ("jquery.js", "my_code.js",)`
I use that JS file to show and hide .
`$(document).ready(function(){
show_hide();
$('#id_type').change(function(){
show_hide();
});
function show_hide(){
if ($("#id_type").val() == 'aM' ){
$(".module")[1].style.display="block"
}
else{
$(".module")[1].style.display="none"
}
}
});`
And in case use already entered values and then change Choice of type or from some other reason these hidden field still have data. I override the save Method of models.py
`
def save(self, *args, **kwargs):
if self.type != 'aM':
self.is_kpi = False
self.unit = None
super(Configuration, self).save(*args, **kwargs)
`

Resources