def reset_password(request):
    args = {}
    args.update(csrf(request))
    if request.method == 'POST':
        form = PasswordResetForm(request.POST)
        args['form'] = form
        if form.is_valid():
            try:
                save_point = transaction.savepoint()
                password_reset_token = generate_activation_key(form.cleaned_data['email'])
                user = User.objects.get(email=form.cleaned_data['email'])
                user.userprofile.password_token = password_reset_token
                user.userprofile.save() 
                email_subject = 'Password reset confirmation'
                email_body = "Hi %s, to reset the password, click this link http://127.0.0.1:8000/reset_password_confirm/%s" % (user.username, password_reset_token)
                send_mail(email_subject, email_body, settings.EMAIL_HOST_USER, [user.email], fail_silently=False)
            except:
                transaction.savepoint_rollback(save_point)
                err_message = (sys.exc_info()[1])
                messages.add_message(request,messages.ERROR,err_message)
            else:
                transaction.savepoint_commit(save_point)
                messages.add_message(request,messages.SUCCESS,'The Password reset confirmation link has been sent to your email')
                args['form'] = PasswordResetForm()        
    else:
        args['form'] = PasswordResetForm()
    return render_to_response('reset_password.html', args, context_instance=RequestContext(request))
Esempio n. 2
0
	def FetchOrCreate(cls,s):
		"""
		Find an entry for this set of intolerances, check the cache first.
		Otherwise check the database, if necessary creating a new item.
		"""
		if s in cls.__cache:
			return cls.__cache[s];
		
		while True:
			created =False
			try:
				sid = transaction.savepoint()
				e, created = cls.objects.get_or_create(intolerant_for_extension = s)
				transaction.savepoint_commit(sid)
			except DatabaseError:
				transaction.savepoint_rollback(sid)
				time.sleep(0.1)
				continue
			except IntegrityError:
				transaction.savepoint_rollback(sid)
				time.sleep(0.1)
				continue
			break;

		if not created:
			cls.__cache[s]=e
		return e;
Esempio n. 3
0
	def FetchOrCreateItem(cls,**params):
		"""
		Either find an existing entry matching the config & results in the
		params dictionary, or create a new entry.
		"""
		key = cls._CalculateKey(**params)
		
		if key in cls.__cache:
			return cls.__cache[key];
		
		params1 = dict(params)
		params1.pop("servername",None)
		params1.pop("part_of_run", None)
		
		while True:
			created =False
			try:
				sid = transaction.savepoint()
				item,created = ProbeCommonResultEntry.objects.get_or_create(key=key, defaults=params1)
				transaction.savepoint_commit(sid)
			except DatabaseError:
				transaction.savepoint_rollback(sid)
				time.sleep(0.1)
				continue
			except IntegrityError:
				transaction.savepoint_rollback(sid)
				time.sleep(0.1)
				continue
			break;
		
		if not created:
			cls.__cache[key] = item
		return item
def reset_password_confirm(request,password_reset_token):
    args = {}
    args.update(csrf(request))
    args['link_expired'] = False 
    args['password_reset_token'] = password_reset_token
    try:
        user_profile = get_object_or_404(UserProfile,password_token=password_reset_token)
        if request.method == 'POST':
            form = PasswordResetConfirmForm(request.POST)
            args['form'] = form
            if form.is_valid():
                try:
                    save_point = transaction.savepoint()
                    if user_profile.user.check_password(form.cleaned_data['password2']):
                       raise forms.ValidationError('New password should not be the same as old password')
                    user_profile.user.set_password(form.cleaned_data['password2'])
                    user_profile.user.save()
                    user_profile.password_token=None
                    user_profile.save()
                except forms.ValidationError as e:
                    transaction.savepoint_rollback(save_point)
                    messages.add_message(request,messages.ERROR,e.message)
                except:
                    transaction.savepoint_rollback(save_point)
                    err_message = (sys.exc_info()[1])
                    messages.add_message(request,messages.ERROR,err_message)
                else:
                    transaction.savepoint_commit(save_point)
                    messages.add_message(request,messages.SUCCESS,'Password has been successfully changed and the link has been expired')
                    args['link_expired'] = True               
        else:
            args['form'] = PasswordResetConfirmForm()
    except Http404 as e:
        args['link_expired'] = True
    return render_to_response('reset_password_confirm.html', args, context_instance=RequestContext(request))
Esempio n. 5
0
	def GetIPLock(cls,run, ip_address, server_item):
		"""
		Obtain a lock for this particular IP address in this run
		If an entry already exists, report that back, along with the entry  
		"""

		while True:
			try:
				ip = IP_Address.objects.extra(where=['"probedata2_ip_address"."ip_address" = INET(E\''+ip_address+'\')'])[0]
			except (IP_Address.DoesNotExist, IndexError):
				try:
					sid = transaction.savepoint()
					ip = IP_Address.objects.create(ip_address=ip_address);
					ip.Construct()
					sid = transaction.savepoint_commit(sid)
				except:
					sid = transaction.savepoint_rollback(sid)
					continue
			break;
		while True:
			try:
				sid = transaction.savepoint()
				(probedalready,created) = cls.objects.get_or_create(
													part_of_run=run, 
													ip_address=ip,
													port = server_item.port,
													protocol =server_item.protocol,
													defaults={"server":server_item})
				sid = transaction.savepoint_commit(sid)
			except:
				sid = transaction.savepoint_rollback(sid)
				time.sleep(0.1)
				continue;
			break;
		return (probedalready,created)
    def save(self, actor, organization, ip_address):
        om = super(InviteOrganizationMemberForm, self).save(commit=False)
        om.organization = organization
        om.type = OrganizationMemberType.MEMBER

        try:
            existing = OrganizationMember.objects.filter(organization=organization, user__email__iexact=om.email)[0]
        except IndexError:
            pass
        else:
            return existing, False

        sid = transaction.savepoint(using="default")
        try:
            om.save()
        except IntegrityError:
            transaction.savepoint_rollback(sid, using="default")
            return OrganizationMember.objects.get(email__iexact=om.email, organization=organization), False
        transaction.savepoint_commit(sid, using="default")

        AuditLogEntry.objects.create(
            organization=organization,
            actor=actor,
            ip_address=ip_address,
            target_object=om.id,
            event=AuditLogEntryEvent.MEMBER_INVITE,
            data=om.get_audit_log_data(),
        )

        om.send_invite_email()

        return om, True
Esempio n. 7
0
 def get_or_create(self, **kwargs):
     """
     Looks up an object with the given kwargs, creating one if necessary.
     Returns a tuple of (object, created), where created is a boolean
     specifying whether an object was created.
     """
     assert kwargs, \
             'get_or_create() must be passed at least one keyword argument'
     defaults = kwargs.pop('defaults', {})
     try:
         return self.get(**kwargs), False
     except self.model.DoesNotExist:
         try:
             params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
             params.update(defaults)
             obj = self.model(**params)
             sid = transaction.savepoint()
             obj.save(force_insert=True)
             transaction.savepoint_commit(sid)
             return obj, True
         except IntegrityError, e:
             transaction.savepoint_rollback(sid)
             try:
                 return self.get(**kwargs), False
             except self.model.DoesNotExist:
                 raise e
Esempio n. 8
0
    def save(self, *args, **kwargs):
        if not self.pk and not self.slug:
            self.slug = self.slugify(self.name)
            if django.VERSION >= (1, 2):
                from django.db import router

                using = kwargs.get("using") or router.db_for_write(type(self), instance=self)
                # Make sure we write to the same db for all attempted writes,
                # with a multi-master setup, theoretically we could try to
                # write and rollback on different DBs
                kwargs["using"] = using
                trans_kwargs = {"using": using}
            else:
                trans_kwargs = {}
            i = 0
            while True:
                i += 1
                try:
                    sid = transaction.savepoint(**trans_kwargs)
                    res = super(TagBase, self).save(*args, **kwargs)
                    transaction.savepoint_commit(sid, **trans_kwargs)
                    return res
                except IntegrityError:
                    transaction.savepoint_rollback(sid, **trans_kwargs)
                    self.slug = self.slugify(self.name, i)
        else:
            return super(TagBase, self).save(*args, **kwargs)
Esempio n. 9
0
    def bulk_insert(cursor, rpm_nevra, filename, srpm_nevra=None):
        nvra = parse_nvra(rpm_nevra)
        if srpm_nevra:
            srpm_name = parse_nvra(srpm_nevra)["name"]
        else:
            srpm_name = nvra["name"]

        sql = add_returning("""INSERT INTO %s (name, epoch, version, release, arch, srpm_nevra, srpm_name, filename)
                               VALUES (%%s, %%s, %%s, %%s, %%s, %%s, %%s, %%s)""" % RPM._meta.db_table)

        try:
            sid = transaction.savepoint()
            RPM.check_srpm_nevra(rpm_nevra, srpm_nevra)
            cursor.execute(sql, [nvra["name"], nvra["epoch"], nvra["version"], nvra["release"],
                                 nvra["arch"], srpm_nevra, srpm_name, filename])
            if connection.features.can_return_id_from_insert:
                insert_id = connection.ops.fetch_returned_insert_id(cursor)
            else:
                insert_id = connection.ops.last_insert_id(cursor, RPM._meta.db_table, "id")
        except (IntegrityError, ValidationError):
            transaction.savepoint_rollback(sid)
            cursor.execute("""SELECT %s FROM %s WHERE name=%%s AND epoch=%%s AND
                              version=%%s and release=%%s AND arch=%%s""" % ("id", RPM._meta.db_table),
                           [nvra["name"], nvra["epoch"], nvra["version"], nvra["release"], nvra["arch"]])
            insert_id = int(cursor.fetchone()[0])
        transaction.savepoint_commit(sid)
        return insert_id
Esempio n. 10
0
def accept_results(request):
    """accept data submissions from the lab via POST. see connection() in extract.py
    for how to submit; attempts to save raw data/partial data if for some reason the
    full content is not parseable or does not validate to the model schema"""

    if request.META['CONTENT_TYPE'] != 'text/json':
        logger.warn('incoming post does not have text/json content type')

    content = request.raw_post_data

    payload_date = datetime.now()
    payload_user = request.user
    try:
        data = json.loads(content)
    except:
        data = None
    #safety -- no matter what else happens, we'll have the original data
    payload = labresults.Payload.objects.create(incoming_date=payload_date,
                                                auth_user=payload_user,
                                                parsed_json=data is not None,
                                                raw=content)
    sid = transaction.savepoint()
    if not data:
        #if payload does not parse as valid json, save raw content and return error
        return HttpResponse('CANNOT PARSE (%d bytes received)' % len(content))
    try:
        process_payload(payload, data)
    except:
        logging.exception('second stage result parsing failed; rolling back '
                          'to savepoint.')
        transaction.savepoint_rollback(sid)
    return HttpResponse('SUCCESS')
Esempio n. 11
0
 def __exit__(self, exc_type, exc_value, traceback):
     if exc_value is None:
         # commit operation
         if self.sid is None:
             # Outer transaction
             try:
                 transaction.commit(self.using)
             except:
                 transaction.rollback(self.using)
                 raise
             finally:
                 self._leave_transaction_management()
         else:
             # Inner savepoint
             try:
                 transaction.savepoint_commit(self.sid, self.using)
             except:
                 transaction.savepoint_rollback(self.sid, self.using)
                 raise
     else:
         # rollback operation
         if self.sid is None:
             # Outer transaction
             transaction.rollback(self.using)
             self._leave_transaction_management()
         else:
             # Inner savepoint
             transaction.savepoint_rollback(self.sid, self.using)
     
     return False
Esempio n. 12
0
 def get_or_create(self, **kwargs):
     """
     This is a copy of QuerySet.get_or_create, that forces calling our custom
     create method when the get fails.
     """
     assert kwargs, \
             'get_or_create() must be passed at least one keyword argument'
     defaults = kwargs.pop('defaults', {})
     try:
         self._for_write = True
         return self.get(**kwargs), False
     except self.actual_model.DoesNotExist:
         params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
         params.update(defaults)
         obj = self.model(**params)
         self._for_write = True
         self._instance = obj
         using = self.db
         try:
             sid = transaction.savepoint(using=using)
             obj.save(force_insert=True, using=using)
         except IntegrityError, e:
             transaction.savepoint_rollback(sid, using=using)
             try:
                 return self.get(**kwargs), False
             except self.actual_model.DoesNotExist, e:
                 raise self.actual_model.DoesNotExist(unicode(e).replace(self.model.__name__, self.actual_model.__name__))
 def forwards(self, orm):
     
     # Changing field 'Tale.slug'
     db.alter_column('tales_tale', 'slug', self.gf('django.db.models.fields.SlugField')(max_length=100, unique=True, null=True, db_index=False))
     if not db.dry_run:
         orm.Tale.objects.all().update(slug=None)
     
     # Adding unique constraint on 'Tale', fields ['slug']
     db.create_unique('tales_tale', ['slug'])
     if not db.dry_run:
         for tale in orm.Tale.objects.order_by('pk'):
             tale.slug = slugify(tale.title)
             i = 0
             while True:
                 i += 1
                 try:
                     sid = transaction.savepoint()
                     tale.save()
                     transaction.savepoint_commit(sid)
                     break
                 except IntegrityError:
                     transaction.savepoint_rollback(sid)
                     tale.slug = slugify(tale.title, i)
 
         # Removing null=True. We need it only for update.
         db.alter_column('tales_tale', 'slug', self.gf('django.db.models.fields.SlugField')(max_length=100, unique=True, null=False, db_index=False))
def save_manager_information(request):
    sid = transaction.savepoint()
    try:
        if request.method == "POST":
            rm_obj = RelationShipManager(
                rm_first_name = request.POST.get('first_name'),
                rm_last_name       = request.POST.get('last_name'),
                rm_email   = request.POST.get('manager_email'),
                rm_contactno   = request.POST.get('manager_number'),
                rm_status   = 1,
                rm_creation_date=datetime.datetime.now()
                )
            rm_obj.save()
            print "done"
            rm_obj.rm_unique_id=str('RM'+ datetime.date.today().strftime('%d%m%y') + str(rm_obj.relationship_manager_id).zfill(4))
            rm_obj.save()
            transaction.savepoint_commit(sid)
            data = {'success': 'true', 'manager_id':rm_obj.relationship_manager_id, 'manager_name':rm_obj.rm_first_name +" "+ rm_obj.rm_last_name  }
        else:
            print 'Invalid Request'
            data = {'sucess': 'false' , ExceptionLabel.ERROR_MESSAGE :'Invalid Request'}
    except Exception, e:
        transaction.savepoint_rollback(sid)
        print 'error',e
        data = {'sucess': 'false', ExceptionLabel.ERROR_MESSAGE :'Server Error'}
Esempio n. 15
0
    def test_prevent_rollback(self):
        with transaction.atomic():
            Reporter.objects.create(first_name="Tintin")
            sid = transaction.savepoint()
            # trigger a database error inside an inner atomic without savepoint
            with self.assertRaises(DatabaseError):
                with transaction.atomic(savepoint=False):
                    connection.cursor().execute(
                        "SELECT no_such_col FROM transactions_reporter"
                    )
            # prevent atomic from rolling back since we're recovering manually
            self.assertTrue(transaction.get_rollback())
            transaction.set_rollback(False)
            transaction.savepoint_rollback(sid)
        self.assertQuerysetEqual(Reporter.objects.all(),
                                 ['<Reporter: Tintin>'])
        self.assertAtomicSignalCalls(
            # Enter atomic transaction block.
            enter_block_atomic_signal_call_sequence(True) +

            # Create Reporter.
            create_model_atomic_signal_call_sequence() +

            # Enter and leave atomic transaction block.
            enter_block_atomic_signal_call_sequence(False, savepoint=False) +
            leave_block_atomic_signal_call_sequence(False, False,
                                                    savepoint=False) +

            # Leave atomic transaction with recovered rollback.
            leave_block_atomic_signal_call_sequence(True, True)
        )
Esempio n. 16
0
def create(row, model, model_attrs, related_attrs, processor):
    sid = transaction.savepoint()

    try:
        with transaction.atomic():
            _create_instances(model, model_attrs, related_attrs)
    except (Error, ValueError,
            AttributeError, TypeError, IndexError):

        transaction.savepoint_rollback(sid)
        error_message = traceback.format_exc()
        if 'File' in error_message:
            error_message = 'File{}'.format(
                error_message.split('File')[-1])

        value = {
            'model_attrs': model_attrs,
            'related_attrs': related_attrs
        }

        error_raised.send(processor,
            error=error_message,
            position=row,
            value=value,
            step=ErrorChoicesMixin.IMPORT_DATA)
def save_company_information(request):
    # pdb.set_trace()
    sid = transaction.savepoint()
    try:
        if request.method == "POST":
            company_obj = Company(
                company_name = request.POST.get('company_name'),
                company_email       = request.POST.get('company_email'),
                company_phone_no   = request.POST.get('contact_number'),
                company_address   = request.POST.get('address_line'),
                company_city   = request.POST.get('city'),
                company_state   = request.POST.get('state'),
                company_country   = request.POST.get('country'),
                company_pincode   = request.POST.get('pincode'),
                company_creation_date=datetime.datetime.now()
                )
            company_obj.save()
            print "done"
            company_obj.company_unique_id=str('CO'+ datetime.date.today().strftime('%d%m%y') + str(company_obj.company_id).zfill(4))
            company_obj.save()
            transaction.savepoint_commit(sid)
            data = {'success': 'true', 'company_id':company_obj.company_id, 'company_name':company_obj.company_name }
        else:
            print 'Invalid Request'
            transaction.savepoint_rollback(sid)
            data = {'sucess': 'false' , ExceptionLabel.ERROR_MESSAGE :'Invalid Request'}
    except Exception, e:
        transaction.savepoint_rollback(sid)
        print 'error',e
        data = {'sucess': 'false', ExceptionLabel.ERROR_MESSAGE :'Server Error'}
def migrate_app(sender, *args, **kwargs):
    """
    Migrate all models of this app registered
    """
    from .registration import registry
    if 'app_config' not in kwargs:
        return
    app_config = kwargs['app_config']

    app_name = app_config.label

    fields = [fld for fld in registry._field_registry.keys() if fld.startswith(app_name)]

    sid = transaction.savepoint()
    for fld in fields:
        model_name, field_name = fld.split('.')[1:]
        if field_exists(app_name, model_name, field_name):
            continue
        model = app_config.get_model(model_name)
        try:
            with connection.schema_editor() as schema_editor:
                schema_editor.add_field(model, registry._field_registry[fld])
                transaction.savepoint_commit(sid)
        except ProgrammingError:
            transaction.savepoint_rollback(sid)
            continue
Esempio n. 19
0
def testmail(request):

    try:
        kwargs = dict(instance=models.Email.objects.order_by("-id")[0])
    except IndexError:
        kwargs = {}
    form = forms.EmailForm(request.POST, **kwargs)
    if not form.is_valid():
        return JsonResp(request, form=form)

    email = bsdUsers.objects.get(bsdusr_username="******").bsdusr_email
    if not email:
        return JsonResp(request, error=True, message=_("You must configure the root email" " (Accounts->Users->root)"))

    sid = transaction.savepoint()
    form.save()

    error = False
    if request.is_ajax():
        sw_name = get_sw_name()
        error, errmsg = send_mail(
            subject=_("Test message from %s" % (sw_name)), text=_("This is a message test from %s" % (sw_name,))
        )
    if error:
        errmsg = _("Your test email could not be sent: %s") % errmsg
    else:
        errmsg = _("Your test email has been sent!")
    transaction.savepoint_rollback(sid)

    return JsonResp(request, error=error, message=errmsg)
Esempio n. 20
0
    def delete(self, request, *args, **kwargs):
        sid = transaction.savepoint()
        try:
            association = Association.objects.get(
                id=UserToken.get_association_id(request.session))
            if Enterprise.objects.filter(headquar__association_id=UserToken.get_association_id(request.session)).count() == 1:
                raise Exception(
                    (u"Asociación <b>%(name)s</b> no puede quedar sin ninguna sede asociada.") % {"name": association.name})

            d = self.get_object()
            # rastrear dependencias
            deps, msg = get_dep_objects(d)
            if deps:
                messages.warning(self.request,  _('Cannot delete %(name)s') % {
                    "name": capfirst(force_text(self.model._meta.verbose_name))
                    + ' "' + force_text(d) + '"'
                })
                raise Exception(msg)

            d.delete()
            msg = _('The %(name)s "%(obj)s" was deleted successfully.') % {
                'name': capfirst(force_text(self.model._meta.verbose_name)),
                'obj': force_text(d)
            }
            if not d.id:
                messages.success(self.request, msg)
                log.warning(msg, extra=log_params(self.request))
        except Exception, e:
            try:
                transaction.savepoint_rollback(sid)
            except:
                pass
            messages.error(request, e)
            log.warning(force_text(e), extra=log_params(self.request))
Esempio n. 21
0
    def form_valid(self, form):
        sid = transaction.savepoint()
        try:
            self.object = form.save(commit=True)
            headquar = Headquar()
            headquar.name = self.request.POST.get("sede")
            headquar.association_id = UserToken.get_association_id(
                self.request.session)
            headquar.enterprise = self.object
            headquar.save()

            msg = _('The %(name)s "%(obj)s" was added successfully.') % {
                'name': capfirst(force_text(self.model._meta.verbose_name)),
                'obj': force_text(self.object)
            }
            if self.object.id:
                messages.success(self.request, msg)
                log.warning(msg, extra=log_params(self.request))
            return super(EnterpriseCreateView, self).form_valid(form)
        except Exception, e:
            try:
                transaction.savepoint_rollback(sid)
            except:
                pass
            messages.success(self.request, e)
            log.warning(force_text(e), extra=log_params(self.request))
            return super(EnterpriseCreateView, self).form_invalid(form)
 def unregisterAgentForServiceToday(self,ani,connection=0,date=None):
     """
     """
     log.info("in unregisterAgentForServiceToday for agent.ani: " + ani)
     assert(ani)
     today = date or datetime.date.today()        
     sid = None
     try:
         #verify agent is active
         if (self.isANICurrentlyActive(ani)):
             log.info("in unregisterAgentForServiceToday. Agent exists and currently active. About to set as inactive")
             log.info(today.__str__())
             #unregister agent
             agent = Agents.objects.filter(ani=ani, connection_status=1).extra(where=["added between %s and %s"],
                                                                   params=["%s 00:00:00" % (today.__str__()), "%s 24:00:00" % (today.__str__())])[0]
             #set agent as off
             log.info(agent)
             agent.connection_status=0
             log.info("agent connection status:%s ani: %s " % (agent.connection_status,agent.ani))
             assert(agent.connection_status == connection)
             log.info("in unregisterAgentForServiceToday about to save agent")
             agent.save()
             log.info("in unregisterAgentForServiceToday agent saved")
             sid = transaction.savepoint()
             transaction.savepoint_commit(sid)
             return agent
         else:
             #agent was not registered for service
             return None
     except Exception as e:
         log.info("services.gateway.unregisterAgentForServiceToday: " + e)
         transaction.savepoint_rollback(sid)
         return None
Esempio n. 23
0
    def save(self, force_insert=False, force_update=False, using=None):
        sid = transaction.savepoint()
        if self.pk is None:
            i = 1
            while self.pk is None:

                if i > 10:
                    sleep(0.001)

                if i > 20:
                    # Protection from infinite loop
                    raise IntegrityError("Too many iterations while generating " "unique Invoice number.")

                try:
                    self.created_on = datetime.utcnow()
                    self.created_on = self.created_on - timedelta(microseconds=self.created_on.microsecond % 100)

                    self.payment_no = (
                        self.created_on.hour * 3600 + self.created_on.minute * 60 + self.created_on.second
                    ) * 10000 + (self.created_on.microsecond // 100)
                    super(Invoice, self).save(force_insert, force_update)

                except IntegrityError:
                    transaction.savepoint_rollback(sid)

                i += 1
        else:
            super(Invoice, self).save(force_insert, force_update)

        transaction.savepoint_commit(sid)
        transaction.commit()
    def forwards(self, orm):

        # Adding model 'ProjectDomain'
        db.create_table('sentry_projectdomain', (
            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
            ('project', self.gf('django.db.models.fields.related.ForeignKey')(related_name='domain_set', to=orm['sentry.Project'])),
            ('domain', self.gf('django.db.models.fields.CharField')(max_length=128)),
        ))
        db.send_create_signal('sentry', ['ProjectDomain'])

        # Adding unique constraint on 'ProjectDomain', fields ['project', 'domain']
        db.create_unique('sentry_projectdomain', ['project_id', 'domain'])

        sid = transaction.savepoint()
        try:
            # Adding index on 'Message', fields ['checksum']
            db.create_index('sentry_message', ['checksum'])
        except:
            transaction.savepoint_rollback(sid)

        sid = transaction.savepoint()
        try:
            # Adding index on 'Message', fields ['checksum']
            db.create_index('sentry_groupedmessage', ['checksum'])
        except:
            transaction.savepoint_rollback(sid)
Esempio n. 25
0
    def test_construction(self):

        # Should be able to construct normally, UI or Admin
        try:
            ma = self.createMachineApp(TEST_ADMINAPPS, 1)
        except:
            self.fail('Unable to construct AdminApp with standard args')
        else:
            self.assertEqual(ma, MachineApp.objects.get(pk=ma.pk))

        try:
            ma2 = self.createMachineApp(TEST_UIAPPS, 1)
        except:
            self.fail('Unable to construct UIApp with standard args')
        else:
            sid = transaction.savepoint()
            self.assertEqual(ma2, MachineApp.objects.get(pk=ma2.pk))

        # Should not be able to construct two apps with same email
        try:
            ma3 = self.createMachineApp(TEST_ADMINAPPS, 1, force_create=True)
        except:
            transaction.savepoint_rollback(sid)
        else:
            self.fail('Constructed two AdminApps with the same email')

        # Even if they are different app types
        try:
            overrides = {'app_type':'chrome'}
            ma4 = self.createMachineApp(TEST_ADMINAPPS, 1, force_create=True, **overrides)
        except:
            transaction.rollback()
        else:
            self.fail('Constructed an AdminApp and a ChromeApp with the same email')
Esempio n. 26
0
def restore_models(zip_config, models_to_restore):
    """
    Add models in tuple of tuples models_to_restore to merengue database
    (ModelClass, "file_name")
    """
    sid = transaction.savepoint()
    try:
        models = set()
        for model_to_restore, file_name in models_to_restore:
            model_to_restore.objects.all().delete()  # we first delete all objects to avoid duplication problems
            format = 'xml'
            fixtures_file_name = "%s.%s" % (file_name, format)
            fixtures_data = zip_config.read(fixtures_file_name)
            fixtures = serializers.deserialize(format, fixtures_data)
            has_objects = False
            for fixture in fixtures:
                if fixture:
                    has_objects = True
                    fixture.save()
                models.add(fixture.object.__class__)
        # HACK: If we found even one object in a fixture, we need to reset
        # the database sequences.
        if has_objects:
            sequence_reset_sql(models)
    except:
        transaction.savepoint_rollback(sid)
        raise
    else:
        transaction.savepoint_commit(sid)
Esempio n. 27
0
    def save(self, *args, **kwargs):
        if not self.pk and not self.slug:
            self.slug = self.slugify(self.name)
            using = kwargs.get("using") or router.db_for_write(
                type(self), instance=self)
            # Make sure we write to the same db for all attempted writes,
            # with a multi-master setup, theoretically we could try to
            # write and rollback on different DBs
            kwargs["using"] = using
            trans_kwargs = {"using": using}
            i = 0
            while 1:
                i += 1
                try:
                    sid = transaction.savepoint(**trans_kwargs)
                    res = super(TagBase, self).save(*args, **kwargs)
                    transaction.savepoint_commit(sid, **trans_kwargs)
                except IntegrityError, e:
                    if 'slug' not in e.message:
                        raise

                    transaction.savepoint_rollback(sid, **trans_kwargs)
                    self.slug = self.slugify(self.name, i)
                else:
                    return res
Esempio n. 28
0
    def test_force_update(self):
        c = Counter.objects.create(name="one", name2="ONE", value=1)

        # The normal case
        c.value = 2
        c.save()
        # Same thing, via an update
        c.value = 3
        c.save(force_update=True)

        # Won't work because force_update and force_insert are mutually
        # exclusive
        c.value = 4
        self.assertRaises(ValueError, c.save, force_insert=True, force_update=True)

        # Try to update something that doesn't have a primary key in the first
        # place.
        c1 = Counter(name="two", name2="TWO", value=2)
        self.assertRaises(DatabaseError, c1.save, force_update=True)
        c1.save(force_insert=True)

        # Won't work because we can't insert a pk of the same value.
        sid = transaction.savepoint()
        c.value = 5
        self.assertRaises(IntegrityError, c.save, force_insert=True)
        transaction.savepoint_rollback(sid)

        # Trying to update should still fail, even with manual primary keys, if
        # the data isn't in the database already.
        obj = WithCustomPK(name=1, value=1)
        self.assertRaises(DatabaseError, obj.save, force_update=True)
Esempio n. 29
0
    def create_qark(attrs=None):
        """
        """

        # Wrap the creation of the facet and its attributes in a transaction savepoint
        # and ensure that a transaction is active
        assert transaction.is_managed(), "A managed transaction is required to create a Fact"
        sid = transaction.savepoint()

        try:
            # Create a QArk and save it; make sure it is new
            qark = QArk(nextrev=1)
            qark.save(force_insert=True)

            # Look up the id's of any attributes specified by name

            # Find all of the Facets by looking up the attributes specified

            # Create each of the attributes

            for attrdict in attrs:
                # Create a QArkAttr and save it; make sure it's new; and add it to the QArk
                attr = QArkAttr.create_qarkattr(**attrdict)
                attr.qark = qark
                attr.rev = 0
                attr.save(force_insert=True)

            return qark

        except:
            transaction.savepoint_rollback(sid)
            # TODO: Need an exception here that is meaningful to what went wrong
            raise
        else:
            transaction.savepoint_commit(sid)
Esempio n. 30
0
 def test_savepoint_rollback(self):
     """Tests rollbacks of savepoints"""
     from django.db import transaction
     from testapp.models import Genre, Publisher
     from johnny import cache
     if not connection.features.uses_savepoints:
         return
     self.failUnless(transaction.is_managed() == False)
     self.failUnless(transaction.is_dirty() == False)
     connection.queries = []
     cache.local.clear()
     transaction.enter_transaction_management()
     transaction.managed()
     g = Genre.objects.get(pk=1)
     start_title = g.title
     g.title = "Adventures in Savepoint World"
     g.save()
     g = Genre.objects.get(pk=1)
     self.failUnless(g.title == "Adventures in Savepoint World")
     sid = transaction.savepoint()
     g.title = "In the Void"
     g.save()
     g = Genre.objects.get(pk=1)
     self.failUnless(g.title == "In the Void")
     transaction.savepoint_rollback(sid)
     g = Genre.objects.get(pk=1)
     self.failUnless(g.title == "Adventures in Savepoint World")
     transaction.rollback()
     g = Genre.objects.get(pk=1)
     self.failUnless(g.title == start_title)
     transaction.managed(False)
     transaction.leave_transaction_management()
Esempio n. 31
0
    def post(self, request):
        '''订单创建'''
        # 判断用户是否登录
        user = request.user
        if not user.is_authenticated():
            # 用户未登录
            return JsonResponse({'res': 0, 'errmsg': '用户未登录'})

        # 接收参数
        addr_id = request.POST.get('addr_id')
        pay_method = request.POST.get('pay_method')
        sku_ids = request.POST.get('sku_ids')  # 1,3

        # 校验参数
        if not all([addr_id, pay_method, sku_ids]):
            return JsonResponse({'res': 1, 'errmsg': '参数不完整'})

        # 校验支付方式
        try:
            pay_method = int(pay_method)
        except ValueError:
            return JsonResponse({'res': 2, 'errmsg': '非法的支付方式'})

        if pay_method not in dict(OrderInfo.PAY_METHOD_CHOICES).keys():
            return JsonResponse({'res': 2, 'errmsg': '非法的支付方式'})

        # 校验地址
        try:
            addr = Address.objects.get(id=addr_id)
        except Address.DoesNotExist:
            # 地址不存在
            return JsonResponse({'res': 3, 'errmsg': '地址非法'})

        # todo: 创建订单核心业务

        # 组织参数
        # 订单id: 20171122181630+用户id

        order_id = datetime.datetime.today().strftime('%Y%m%d%H%M%S') + str(
            user.id)

        # 运费
        transit_price = 10

        # 总数目和总金额
        total_count = 0
        total_price = 0

        try:

            # 设置事务保存点
            save_point = transaction.savepoint()

            # todo: 向df_order_info表中添加一条记录
            order = OrderInfo.objects.create(order_id=order_id,
                                             user=user,
                                             addr=addr,
                                             pay_method=pay_method,
                                             total_count=total_count,
                                             total_price=total_price,
                                             transit_price=transit_price)

            # 模拟异常
            # num = 1/0

            # todo: 用户的订单中有几个商品,需要向df_order_goods表中加入几条记录
            conn = settings.REDIS_CONN
            cart_key = 'cart_%d' % user.id

            sku_ids = sku_ids.split(',')
            for sku_id in sku_ids:
                for i in range(3):
                    # 获取商品的信息
                    try:
                        sku = GoodsSKU.objects.get(id=sku_id)
                    except:
                        # 回滚
                        transaction.savepoint_rollback(save_point)
                        # 商品不存在
                        return JsonResponse({'res': 4, 'errmsg': '商品不存在'})

                    # 从redis中获取用户所要购买的商品的数量
                    count = conn.hget(cart_key, sku_id)

                    # todo: 判断商品的库存
                    if int(count) > sku.stock:
                        # 回滚
                        transaction.savepoint_rollback(save_point)
                        return JsonResponse({'res': 6, 'errmsg': '商品库存不足'})

                    # todo: 更新商品的库存和销量
                    orgin_stock = sku.stock
                    new_stock = orgin_stock - int(count)
                    new_sales = sku.sales + int(count)

                    # print('user:%d...stock:%d' % (user.id, sku.stock))
                    # import time
                    # time.sleep(10)

                    # 返回受影响的行数   update   xxx  where xxxx
                    res = GoodsSKU.objects.filter(
                        id=sku_id, stock=orgin_stock).update(stock=new_stock,
                                                             sales=new_sales)
                    if res == 0:
                        if i == 2:
                            transaction.savepoint_rollback(save_point)
                            return JsonResponse({
                                'res': 7,
                                'errmsg': '下单失败,并发'
                            })
                        continue

                    # todo: 向df_order_goods表中添加一条记录
                    OrderGoods.objects.create(order=order,
                                              sku=sku,
                                              count=count,
                                              price=sku.price)

                    # # todo: 更新商品的库存和销量
                    # sku.stock -= int(count)
                    # sku.sales += int(count)
                    # sku.save()

                    # todo: 累加计算订单商品的总数量和总价格
                    amount = sku.price * int(count)
                    total_count += int(count)
                    total_price += amount

                    break

            # todo: 更新订单信息表中的商品的总数量和总价格
            order.total_count = total_count
            order.total_price = total_price
            order.save()

            # 提交
            transaction.savepoint_commit(save_point)
        except Exception as e:
            # 回滚
            transaction.savepoint_rollback(save_point)
            print('1...')
            return JsonResponse({'res': 7, 'errmsg': '下单失败'})

        # todo: 清除用户购物车中对应的记录
        conn.hdel(cart_key, *sku_ids)

        # 返回应答
        return JsonResponse({'res': 5, 'message': '创建成功'})
    def import_data(self,
                    dataset,
                    dry_run=False,
                    raise_errors=False,
                    use_transactions=None,
                    **kwargs):
        """
        Imports data from ``tablib.Dataset``. Refer to :doc:`import_workflow`
        for a more complete description of the whole import process.

        :param dataset: A ``tablib.Dataset``

        :param raise_errors: Whether errors should be printed to the end user
            or raised regularly.

        :param use_transactions: If ``True`` import process will be processed
            inside transaction.

        :param dry_run: If ``dry_run`` is set, or error occurs, transaction
            will be rolled back.
        """
        result = Result()
        result.diff_headers = self.get_diff_headers()

        if use_transactions is None:
            use_transactions = self.get_use_transactions()

        if use_transactions is True:
            # when transactions are used we want to create/update/delete object
            # as transaction will be rolled back if dry_run is set
            real_dry_run = False
            sp1 = savepoint()
        else:
            real_dry_run = dry_run

        try:
            self.before_import(dataset, real_dry_run, **kwargs)
        except Exception as e:
            logging.exception(e)
            tb_info = traceback.format_exc()
            result.base_errors.append(Error(e, tb_info))
            if raise_errors:
                if use_transactions:
                    savepoint_rollback(sp1)
                raise

        instance_loader = self._meta.instance_loader_class(self, dataset)

        for row in dataset.dict:
            try:
                row_result = RowResult()
                instance, new = self.get_or_init_instance(instance_loader, row)
                if new:
                    row_result.import_type = RowResult.IMPORT_TYPE_NEW
                else:
                    row_result.import_type = RowResult.IMPORT_TYPE_UPDATE
                row_result.new_record = new
                original = deepcopy(instance)
                if self.for_delete(row, instance):
                    if new:
                        row_result.import_type = RowResult.IMPORT_TYPE_SKIP
                        row_result.diff = self.get_diff(
                            None, None, real_dry_run)
                    else:
                        row_result.import_type = RowResult.IMPORT_TYPE_DELETE
                        self.delete_instance(instance, real_dry_run)
                        row_result.diff = self.get_diff(
                            original, None, real_dry_run)
                else:
                    self.import_obj(instance, row, real_dry_run)
                    if self.skip_row(instance, original):
                        row_result.import_type = RowResult.IMPORT_TYPE_SKIP
                    else:
                        with transaction.atomic():
                            self.save_instance(instance, real_dry_run)
                        self.save_m2m(instance, row, real_dry_run)
                        # Add object info to RowResult for LogEntry
                        row_result.object_repr = force_text(instance)
                        row_result.object_id = instance.pk
                    row_result.diff = self.get_diff(original, instance,
                                                    real_dry_run)
            except Exception as e:
                # There is no point logging a transaction error for each row
                # when only the original error is likely to be relevant
                if not isinstance(e, TransactionManagementError):
                    logging.exception(e)
                tb_info = traceback.format_exc()
                row_result.errors.append(Error(e, tb_info, row))
                if raise_errors:
                    if use_transactions:
                        savepoint_rollback(sp1)
                    six.reraise(*sys.exc_info())
            if (row_result.import_type != RowResult.IMPORT_TYPE_SKIP
                    or self._meta.report_skipped):
                result.rows.append(row_result)

        # Reset the SQL sequences when new objects are imported
        # Adapted from django's loaddata
        if not dry_run and any(r.import_type == RowResult.IMPORT_TYPE_NEW
                               for r in result.rows):
            connection = connections[DEFAULT_DB_ALIAS]
            sequence_sql = connection.ops.sequence_reset_sql(
                no_style(), [self.Meta.model])
            if sequence_sql:
                with connection.cursor() as cursor:
                    for line in sequence_sql:
                        cursor.execute(line)

        if use_transactions:
            if dry_run or result.has_errors():
                savepoint_rollback(sp1)
            else:
                savepoint_commit(sp1)

        return result
Esempio n. 33
0
 def create_share_info(self, share_record, share_team, share_user,
                       share_info):
     # 开启事务
     sid = transaction.savepoint()
     try:
         # 删除历史数据
         ServiceShareRecordEvent.objects.filter(
             record_id=share_record.ID).delete()
         RainbondCenterApp.objects.filter(
             record_id=share_record.ID).delete()
         app_templete = {}
         # 处理基本信息
         try:
             app_templete["template_version"] = "v2"
             group_info = share_info["share_group_info"]
             app_templete["group_key"] = group_info["group_key"]
             app_templete["group_name"] = group_info["group_name"]
             app_templete["group_version"] = group_info["version"]
         except Exception as e:
             if sid:
                 transaction.savepoint_rollback(sid)
             logger.exception(e)
             return 500, "基本信息处理错误", None
         # 处理插件相关,v3.5暂时不实现
         try:
             # 确定分享的插件ID
             share_plugin_ids = {}
             plugins = share_info.get("share_plugin_list", None)
             if plugins:
                 share_plugins = list()
                 for plugin in plugins:
                     version = plugin.get("build_version", "")
                     plugin_id = plugin.get("plugin_id", "")
                     if version and plugin_id:
                         # 只有自己创建的插件需要分享出去
                         if plugin["origin"] == "source_code" and plugin[
                                 "is_share"]:
                             plugin_version = plugin_repo.get_plugin_buildversion(
                                 plugin_id, version)
                             if plugin_version and plugin_version.plugin_version_status != "fixed":
                                 plugin_version.plugin_version_status = "fixed"
                                 plugin_version.save()
                             plugin["config_groups"] = [
                                 group.to_dict() for group in
                                 plugin_repo.get_plugin_config_groups(
                                     plugin_id, version)
                             ]
                             plugin["config_items"] = [
                                 item.to_dict() for item in
                                 plugin_repo.get_plugin_config_items(
                                     plugin_id, version)
                             ]
                             plugin["version"] = plugin_version.to_dict()
                             # TODO: 插件应该单独分享,此处暂时不处理,分享到应用内部
                             share_plugin_ids[plugin_id] = True
                             share_plugins.append(plugin)
                 app_templete["plugins"] = share_plugins
         except Exception as e:
             if sid:
                 transaction.savepoint_rollback(sid)
             logger.exception(e)
             return 500, "插件处理发生错误", None
         # 处理应用相关
         try:
             services = share_info["share_service_list"]
             if services:
                 new_services = list()
                 for service in services:
                     image = service["image"]
                     # 源码应用
                     if image.startswith("goodrain.me/runner") and service[
                             "language"] != "dockerfile":
                         service[
                             'service_slug'] = app_store.get_slug_connection_info(
                                 group_info["scope"],
                                 share_team.tenant_name)
                         if not service['service_slug']:
                             if sid:
                                 transaction.savepoint_rollback(sid)
                             return 400, "获取源码包上传地址错误", None
                     else:
                         service[
                             "service_image"] = app_store.get_image_connection_info(
                                 group_info["scope"],
                                 share_team.tenant_name)
                         if not service["service_image"]:
                             if sid:
                                 transaction.savepoint_rollback(sid)
                             return 400, "获取镜像上传地址错误", None
                     if service.get("need_share", None):
                         ssre = ServiceShareRecordEvent(
                             team_id=share_team.tenant_id,
                             service_key=service["service_key"],
                             service_id=service["service_id"],
                             service_name=service["service_cname"],
                             service_alias=service["service_alias"],
                             record_id=share_record.ID,
                             team_name=share_team.tenant_name,
                             event_status="not_start")
                         ssre.save()
                     new_services.append(service)
                     # TODO:处理应用继承关系RainbondCenterAppInherit
                 app_templete["apps"] = new_services
             else:
                 if sid:
                     transaction.savepoint_rollback(sid)
                 return 400, "分享的应用信息不能为空", None
         except Exception as e:
             if sid:
                 transaction.savepoint_rollback(sid)
             logger.exception(e)
             return 500, "应用信息处理发生错误", None
         # 删除同个应用组分享的相同版本
         RainbondCenterApp.objects.filter(
             version=group_info["version"],
             tenant_service_group_id=share_record.group_id).delete()
         # 新增加
         app = RainbondCenterApp(
             group_key=app_templete["group_key"],
             group_name=app_templete["group_name"],
             share_user=share_user.user_id,
             share_team=share_team.tenant_name,
             tenant_service_group_id=share_record.group_id,
             pic=group_info.get("pic", ""),
             source="local",
             record_id=share_record.ID,
             version=group_info["version"],
             scope=group_info["scope"],
             describe=group_info["describe"],
             app_template=json.dumps(app_templete))
         app.save()
         share_record.step = 2
         share_record.update_time = datetime.datetime.now()
         share_record.save()
         # 提交事务
         if sid:
             transaction.savepoint_commit(sid)
         return 200, "分享信息处理成功", share_record.to_dict()
     except Exception as e:
         logger.exception(e)
         if sid:
             transaction.savepoint_rollback(sid)
         return 500, "应用分享处理发生错误", None
Esempio n. 34
0
 def sync_event(self, user, region_name, tenant_name, record_event):
     rc_apps = RainbondCenterApp.objects.filter(
         record_id=record_event.record_id)
     if not rc_apps:
         return 404, "分享的应用不存在", None
     rc_app = rc_apps[0]
     event_type = "share-yb"
     if rc_app.scope == "goodrain":
         event_type = "share-ys"
     event = self.create_publish_event(record_event, user.nick_name,
                                       event_type)
     record_event.event_id = event.event_id
     app_templetes = json.loads(rc_app.app_template)
     apps = app_templetes.get("apps", None)
     if not apps:
         return 500, "分享的应用信息获取失败", None
     new_apps = list()
     sid = transaction.savepoint()
     try:
         for app in apps:
             # 处理事件的应用
             if app["service_key"] == record_event.service_key:
                 body = {
                     "service_key": app["service_key"],
                     "app_version": rc_app.version,
                     "event_id": event.event_id,
                     "share_user": user.nick_name,
                     "share_scope": rc_app.scope,
                     "image_info": app.get("service_image", None),
                     "slug_info": app.get("service_slug", None)
                 }
                 try:
                     res, re_body = region_api.share_service(
                         region_name, tenant_name,
                         record_event.service_alias, body)
                     bean = re_body.get("bean")
                     if bean:
                         record_event.region_share_id = bean.get(
                             "share_id", None)
                         record_event.event_id = bean.get("event_id", None)
                         record_event.event_status = "start"
                         record_event.update_time = datetime.datetime.now()
                         record_event.save()
                         image_name = bean.get("image_name", None)
                         if image_name:
                             app["share_image"] = image_name
                         slug_path = bean.get("slug_path", None)
                         if slug_path:
                             app["share_slug_path"] = slug_path
                         new_apps.append(app)
                     else:
                         transaction.savepoint_rollback(sid)
                         return 400, "数据中心分享错误", None
                 except Exception as e:
                     logger.exception(e)
                     transaction.savepoint_rollback(sid)
                     if re_body:
                         logger.error(re_body)
                     return 500, "数据中心分享错误", None
             else:
                 new_apps.append(app)
         app_templetes["apps"] = new_apps
         rc_app.app_template = json.dumps(app_templetes)
         rc_app.update_time = datetime.datetime.now()
         rc_app.save()
         transaction.savepoint_commit(sid)
         return 200, "数据中心分享开始", record_event
     except Exception as e:
         logger.exception(e)
         if sid:
             transaction.savepoint_rollback(sid)
         return 500, "应用分享介质同步发生错误", None
Esempio n. 35
0
    def post(self, request):
        print("123")
        # 登录判断
        if not request.user.is_authenticated():
            return JsonResponse({'code': 1, 'errmsg': '请先登录'})

        # 获取请求参数:address_id, pay_method, sku_ids_str
        address_id = request.POST.get('address_id')
        pay_method = request.POST.get('pay_method')
        # 商品id,格式型如: 1,2,3
        sku_ids_str = request.POST.get('sku_ids_str')

        # 校验参数不能为空
        if not all([address_id, pay_method, sku_ids_str]):
            return JsonResponse({'code': 2, 'errmsg': '参数不完整'})

        # 判断地址是否存在
        try:
            address = Address.objects.get(id=address_id)
        except Address.DoesNotExist:
            return JsonResponse({'code': 3, 'errmsg': '地址不能为空'})

        # 创建保存点
        point = transaction.savepoint()
        try:
            # todo: 修改订单信息表: 保存订单数据到订单信息表中(新增一条数据)
            total_count = 0
            total_amount = 0
            trans_cost = 10

            # 时间+用户id
            order_id = datetime.now().strftime('%Y%m%d%H%M%S') + str(
                request.user.id)
            pay_method = int(pay_method)
            print("2")
            # order1 = None
            order = OrderInfo.objects.create(
                order_id=order_id,
                total_count=total_count,
                total_amount=total_amount,
                trans_cost=trans_cost,
                pay_method=pay_method,
                user=request.user,
                address=address,
            )
            # print("1")

            # 获取StrictRedis对象: cart_1 = {1: 2, 2: 2}
            strict_redis = get_redis_connection()  # type: StrictRedis
            key = 'cart_%s' % request.user.id
            sku_ids = sku_ids_str.split(',')  # str ——> list

            # todo: 核心业务: 遍历每一个商品, 并保存到订单商品表
            for sku_id in sku_ids:
                # 查询订单中的每一个商品对象
                try:
                    sku = GoodsSKU.objects.get(id=sku_id)
                except GoodsSKU.DoesNotExist:
                    # 回滚动到保存点,撤销所有的sql操作
                    # transaction.savepoint_rollback(point)

                    return JsonResponse({'code': 4, 'errmsg': '商品不存在'})

                # 获取商品数量,并判断库存
                count = strict_redis.hget(key, sku_id)
                count = int(count)  # bytes -> int
                if count > sku.stock:
                    # 回滚动到保存点,撤销所有的sql操作
                    # transaction.savepoint_rollback(point)
                    return JsonResponse({'code': 5, 'errmsg': '库存不足'})

                # todo: 修改订单商品表: 保存订单商品到订单商品表(新增多条数据)
                OrderGoods.objects.create(
                    count=count,
                    price=sku.price,
                    order=order,
                    sku=sku,
                )

                # todo: 修改商品sku表: 减少商品库存, 增加商品销量
                sku.stock -= count
                sku.sales += count
                sku.save()

                # 累加商品数量和总金额
                total_count += count
                total_amount += sku.price * count

                # todo: 修改订单信息表: 修改商品总数量和总金额
            order.total_count = total_count
            order.total_amount = total_amount
            order.save()
        except:
            # 回滚动到保存点,撤销所有的sql操作
            transaction.savepoint_rollback(point)
            return JsonResponse({'code': 6, 'errmsg': '创建订单失败'})

        # 提交事务(保存点)
        transaction.savepoint_commit(point)

        # 从Redis中删除购物车中的商品
        # cart_1 = {1: 2, 2: 2}
        # redis命令: hdel cart_1 1 2
        # 列表 -> 位置参数
        strict_redis.hdel(key, *sku_ids)

        # 订单创建成功, 响应请求,返回json
        return JsonResponse({'code': 0, 'message': '创建订单成功'})
Esempio n. 36
0
    def create(self, validated_data):
        # 获取当前下单用户
        user = self.context['request'].user
        # 生成订单编号 年月日时分秒+user.id
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + ('%09d' % user.id)
        address = validated_data['address']
        pay_method = validated_data['pay_method']

        with transaction.atomic():
            # 创建一个保存点
            save_id = transaction.savepoint()
            try:
                # 创建订单信息
                order = OrderInfo.objects.create(
                    order_id=order_id,
                    user=user,
                    address=address,
                    total_count=0,
                    total_amount=Decimal(0),
                    freight=Decimal(10),
                    pay_method=pay_method,
                    status=OrderInfo.ORDER_STATUS_ENUM['UNSEND']
                    if pay_method == OrderInfo.PAY_METHODS_ENUM['CASH'] else
                    OrderInfo.ORDER_STATUS_ENUM['UNPAID'])
                # 获取购物车信息
                redis_conn = get_redis_connection('cart')
                redis_cart = redis_conn.hgetall('cart_%s' % user.id)
                cart_selected = redis_conn.smembers('cart_selected_%s' %
                                                    user.id)

                # 将bytes类型转换成int类型
                cart = {}
                for sku_id in cart_selected:
                    cart[int(sku_id)] = int(redis_cart[sku_id])

                # 一次查询出所有商品数据
                skus = SKU.objects.filter(id__in=cart.keys())

                # 处理订单商品
                for sku in skus:
                    sku_count = cart[sku.id]
                    # 判断库存
                    origin_stock = sku.stock
                    origin_sales = sku.sales

                    if sku_count > origin_stock:
                        transaction.savepoint_rollback(save_id)
                        raise serializers.ValidationError('商品库存不足')

                    # new_stock = origin_stock - sku_count
                    # new_sales = origin_sales + sku_count
                    #
                    # sku.stock = new_stock
                    # sku.sales = new_sales
                    # sku.save()

                    # 用于演示并发下单
                    # time.sleep(5)

                    new_stock = origin_stock - sku_count
                    new_sales = origin_sales + sku_count
                    # 根据原始库存条件更新,返回更新的条目数,乐观锁
                    ret = SKU.objects.filter(
                        id=sku.id, stock=origin_stock).update(stock=new_stock,
                                                              sales=new_sales)
                    if ret == 0:
                        raise serializers.ValidationError('库存不足')

                    # 累计商品的SPU销量信息
                    sku.goods.sales += sku_count
                    sku.goods.save()

                    # 累计订单基本信息的数据
                    order.total_count += sku_count
                    order.total_amount += (sku.price * sku_count)

                    # 保存订单商品
                    OrderGoods.objects.create(
                        order=order,
                        sku=sku,
                        count=sku_count,
                        price=sku.price,
                    )
                    # 更新订单的金额数量信息
                    order.total_amount += order.freight
                    order.save()
            except ValidationError:
                raise
            except Exception as e:
                transaction.savepoint_rollback(save_id)
                raise

            transaction.savepoint_commit(save_id)

            # 更新redis中保存的购物车数据
            pl = redis_conn.pipeline()
            pl.hdel('cart_%s' % user.id, *cart_selected)
            pl.srem('cart_selected_%s' % user.id, *cart_selected)
            pl.execute()
            return order
Esempio n. 37
0
    def create(self, validated_data):
        """保存订单信息(订单并发-悲观锁)"""
        # 获取参数address和pay_method
        address = validated_data['address']
        pay_method = validated_data['pay_method']

        # 组织参数
        # 用户user
        user = self.context['request'].user

        # 订单id: '年月日时分秒'+用户id
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + ('%010d' % user.id)

        # 运费
        freight = Decimal(10)

        # 订单商品总数量和实付款
        total_count = 0
        total_amount = Decimal(0)

        # 订单状态
        # if pay_method == OrderInfo.PAY_METHODS_ENUM['CASH']:
        #     # 货到付款
        #     status = OrderInfo.ORDER_STATUS_ENUM['UNSEND'] # 待发货
        # else:
        #     # 在线支付
        #     status = OrderInfo.ORDER_STATUS_ENUM['UNPAID'] # 待支付

        status = OrderInfo.ORDER_STATUS_ENUM['UNSEND'] if pay_method == OrderInfo.PAY_METHODS_ENUM['CASH'] else OrderInfo.ORDER_STATUS_ENUM['UNPAID']

        # 获取redis链接
        redis_conn = get_redis_connection('cart')

        # 从redis中获取用户所要购买的商品sku_id  set
        cart_selected_key = 'cart_selected_%s' % user.id
        # (b'<sku_id>', ...)
        sku_ids = redis_conn.smembers(cart_selected_key)

        # 从redis中获取用户购物车商品的sku_id和对应的数量count  hash
        cart_key = 'cart_%s' % user.id
        # {
        #     b'<sku_id>': b'<count>',
        #     ...
        # }
        cart_dict = redis_conn.hgetall(cart_key)

        with transaction.atomic():
            # 在with语句块中代码,凡是涉及到数据库操作的代码,都会放到同一个事务中

            # 设置一个事务保存点
            sid = transaction.savepoint()

            try:
                # 1)向订单基本信息表添加一条记录
                order = OrderInfo.objects.create(
                    order_id=order_id,
                    user=user,
                    address=address,
                    total_count=total_count,
                    total_amount=total_amount,
                    freight=freight,
                    pay_method=pay_method,
                    status=status
                )

                # 2)订单中包含几个商品,就需要向订单商品表中添加几条记录
                for sku_id in sku_ids:
                    # 获取用户所要购买的该商品的数量count
                    count = cart_dict[sku_id]
                    count = int(count)

                    for i in range(3):
                        # 根据sku_id获取商品信息
                        # select * from tb_sku where id=<sku_id>;
                        sku = SKU.objects.get(id=sku_id)

                        # 判断商品库存是否充足
                        if count > sku.stock:
                            # 回滚到sid事务保存点
                            transaction.savepoint_rollback(sid)
                            raise serializers.ValidationError('商品库存不足')

                        # 记录商品原始库存
                        origin_stock = sku.stock
                        new_stock = origin_stock - count
                        new_sales = sku.sales + count

                        # 模拟订单并发问题
                        # print('user: %d times: %s stock: %s' % (user.id, i, origin_stock))
                        # import time
                        # time.sleep(10)

                        # 减少商品库存,增加销量
                        # update tb_sku
                        # set stock=<new_stock>, sales=<new_sales>
                        # where id=<sku_id> and stock=<origin_stock>;
                        # update方法返回的是更新的行数
                        res = SKU.objects.filter(id=sku_id, stock=origin_stock).update(stock=new_stock, sales=new_sales)

                        if res == 0:
                            if i == 2:
                                # 更新了3次,仍然失败,下单失败
                                # 回滚到sid事务保存点
                                transaction.savepoint_rollback(sid)
                                raise serializers.ValidationError('下单失败2')

                            # 更新失败,重新进行尝试
                            continue

                        # 向订单商品表中添加一条记录
                        OrderGoods.objects.create(
                            order=order,
                            sku=sku,
                            count=count,
                            price=sku.price
                        )

                        # 累加计算订单中商品总数量和总金额
                        total_count += count
                        total_amount += sku.price*count

                        # 更新成功,跳出循环
                        break

                # 实付款
                total_amount += freight
                # 更新订单记录中商品的总数量和实付款
                order.total_count = total_count
                order.total_amount = total_amount
                order.save()
            except serializers.ValidationError:
                # 继续向外抛出异常
                raise
            except Exception as e:
                # 回滚sid事务保存点
                transaction.savepoint_rollback(sid)
                raise serializers.ValidationError('下单失败1')

        # 3)清除购物车中对应的记录
        pl = redis_conn.pipeline()
        pl.hdel(cart_key, *sku_ids)
        pl.srem(cart_selected_key, *sku_ids)
        pl.execute()

        # 返回订单对象
        return order
Esempio n. 38
0
def OrderCommit(requset):
    if requset.method == 'POST':
        user = requset.user
        if not user.is_authenticated():
            # 用户未登录
            return JsonResponse({'res': 0, 'errmsg': '用户未登录'})
        # 接收参数
        addr_id = requset.POST.get('addr_id')
        pay_method = requset.POST.get('pay_method')
        sku_ids = requset.POST.get('sku_ids')

        # 检验参数
        if not all([addr_id, pay_method, sku_ids]):
            return JsonResponse({'res': 1, 'errmsg': '参数不完整'})

        # 校验支付方式
        if pay_method not in OrderInfo.PAY_METHODS.keys():
            return JsonResponse({'res': 2, 'errmsg': '非法的支付方式'})

        # 校验地址
        try:
            addr = Address.objects.get(id=addr_id)
        except Address.DoesNotExist:
            # 地址不存在
            return JsonResponse({'res': 3, 'errmsg': '地址不存在'})

        # todo:创建订单核心业务

        # 组织参数
        # 订单id:20171122181630+用户id
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + str(user.id)

        # 运费
        transit_price = 10

        # 总数目和总价格
        total_count = 0
        total_price = 0

        # 设置事务保存点
        save_id = transaction.savepoint()
        try:
            # todo:向df_order_info表中添加一条记录
            order = OrderInfo.objects.create(order_id=order_id,
                                             user=user,
                                             addr=addr,
                                             pay_method=pay_method,
                                             total_count=total_count,
                                             total_price=total_price,
                                             transit_price=transit_price)

            # todo:用户的订单中有几个商品,需要向df_order_goods表中加入几条记录
            conn = settings.REDIS_CONN
            cart_key = 'cart_%d' % user.id

            sku_ids = sku_ids.split(',')
            for sku_id in sku_ids:
                for i in range(3):
                    # 获取商品的信息
                    try:
                        # 解决订单并发情况(悲观锁)
                        # select * from df_goods_sku where id=sku_id for update;加锁
                        # sku = GoodsSKU.objects.select_for_update().get(id=sku_id)
                        sku = GoodsSKU.objects.get(id=sku_id)
                    except:
                        # 商品不存在
                        transaction.savepoint_rollback(save_id)  # 回滚到保存点
                        return JsonResponse({'res': 4, 'errmsg': '商品不存在'})

                    # 从redis中获取用户所要购买商品的数量
                    count = conn.hget(cart_key, sku_id)

                    # todo:判断商品的库存
                    if int(count) > sku.stock:
                        transaction.savepoint_rollback(save_id)  # 回滚到保存点
                        return JsonResponse({'res': 6, 'errmsg': '商品库存不足'})

                    # todo:更新商品的库存和销量
                    orgin_stock = sku.stock
                    new_stock = orgin_stock - int(count)
                    new_sales = sku.sales + int(count)

                    # print('user:%d times:%d stock:%d'%(user.id, i, sku.stock))
                    # import time
                    # time.sleep(5)

                    # 解决订单并发情况(乐观锁:冲突较少或者重复操作的代价大的时候使用)
                    # update df_goods_Sku set stock=new_stock, sales=new_sales
                    # where id=sku_id and stock=orgin_Stock
                    # 返回受影响的行数
                    res = GoodsSKU.objects.filter(
                        id=sku_id, stock=orgin_stock).update(stock=new_stock,
                                                             sales=new_sales)
                    if res == 0:
                        if i == 2:
                            # 尝试的第三次没有成功的话->下单失败
                            transaction.savepoint_rollback(sku_id)
                            return JsonResponse({'res': 7, 'errmsg': '下单失败2'})
                        continue

                    # todo:向df_order_goods表中添加一条记录
                    OrderGoods.objects.create(order=order,
                                              sku=sku,
                                              count=count,
                                              price=sku.price)

                    # todo:累加计算订单商品的总数量和总价格
                    amount = sku.price * int(count)
                    total_count += int(count)
                    total_price += amount

                    # 跳出循环进行后面操作
                    break

            # todo:更新订单信息表中的商品总数量和总价格
            order.total_count = total_count
            order.total_price = total_price
            order.save()
        except Exception as e:
            transaction.savepoint_rollback(save_id)  # 回滚到保存点
            return JsonResponse({'res': 7, 'errmsg': '下单失败'})

        # 提交事务
        transaction.savepoint_commit(save_id)

        # todo:清除用户购物车中对应的记录
        conn.hdel(cart_key, *sku_ids)

        # 返回应答
        return JsonResponse({'res': 5, 'message': '创建成功'})
Esempio n. 39
0
def import_invoice_sheet(worksheet,
                         invoice_reference=None,
                         customer_2_id_dict=None,
                         producer=None):
    error = False
    error_msg = None
    header = get_header(worksheet)
    if header:
        now = timezone.now().date()
        lut_reverse_vat = dict(LUT_ALL_VAT_REVERSE)
        import_counter = 0
        row_num = 1
        sid = transaction.savepoint()
        try:

            permanence = Permanence.objects.create(
                permanence_date=now,
                short_name=invoice_reference,
                status=PERMANENCE_SEND,
                highest_status=PERMANENCE_SEND)
            permanence.producers.add(producer)
            row = get_row(worksheet, header, row_num)
            while row and not error:
                customer_name = row[_("Customer")]
                if customer_name:
                    if customer_name in customer_2_id_dict:
                        customer_id = customer_2_id_dict[customer_name]
                    else:
                        error = True
                        error_msg = _(
                            "Row %(row_num)d : No valid customer") % {
                                'row_num': row_num + 1
                            }
                        break
                    product_reference = row[_("Reference")]
                    unit = row[_("Unit")]
                    order_unit = get_reverse_invoice_unit(unit)
                    vat = row[_("VAT level")]
                    vat_level = lut_reverse_vat[vat]
                    product = Product.objects.filter(
                        producer_id=producer.id,
                        reference=product_reference).order_by('?').first()
                    if product is None:
                        product = Product.objects.create(
                            producer=producer,
                            reference=product_reference,
                        )
                    product.long_name = row[_("Product")]
                    # The producer unit price is the imported customer unit price
                    # If the group get a reduction, this one must be mentionned into the producer admin screen
                    # into the "price_list_multiplier" field
                    product.producer_unit_price = row[_("Customer unit price")]
                    product.unit_deposit = row[_("Deposit")]
                    product.order_unit = order_unit
                    product.vat_level = vat_level
                    product.wrapped = row[_("Wrapped")]
                    product.save()
                    qty_and_price_display = product.get_qty_and_price_display(
                        customer_price=False)
                    if product.long_name.endswith(qty_and_price_display):
                        product.long_name = product.long_name[:-len(
                            qty_and_price_display)]
                        product.save()
                    offer_item = product.get_or_create_offer_item(
                        permanence, reset_add_2_stock=True)
                    create_or_update_one_purchase(customer_id,
                                                  offer_item,
                                                  q_order=Decimal(
                                                      row[_("Quantity")]),
                                                  status=PERMANENCE_SEND,
                                                  batch_job=True,
                                                  is_box_content=False,
                                                  comment=row[_("Comment")])
                    import_counter += 1

                row_num += 1
                row = get_row(worksheet, header, row_num)
            reorder_offer_items(permanence.id)
            reorder_purchases(permanence.id)

        except KeyError as e:
            # Missing field
            error = True
            error_msg = _(
                "Row %(row_num)d : A required column is missing %(error_msg)s."
            ) % {
                'row_num': row_num + 1,
                'error_msg': str(e)
            }
        except Exception as e:
            error = True
            error_msg = _("Row %(row_num)d : %(error_msg)s.") % {
                'row_num': row_num + 1,
                'error_msg': str(e)
            }
        if not error and import_counter == 0:
            error = True
            error_msg = "{}".format(_("Nothing to import."))
        if error:
            transaction.savepoint_rollback(sid)
        else:
            transaction.savepoint_commit(sid)
    return error, error_msg
Esempio n. 40
0
    def post(self, request):
        # 1、提取参数
        data = json.loads(request.body.decode())
        address_id = data.get('address_id')
        pay_method = data.get('pay_method')

        # 2、校验参数
        if not all([address_id, pay_method]):
            return JsonResponse({'code': 400, 'errmsg': '缺少参数'})

        try:
            address = Address.objects.get(pk=address_id)
        except Address.DoesNotExist as e:
            return JsonResponse({'code': 400, 'errmsg': '地址不存在'})

        # OrderInfo.PAY_METHODS_ENUM.values() --> [1, 2]
        if pay_method not in [
            OrderInfo.PAY_METHODS_ENUM['CASH'],
            OrderInfo.PAY_METHODS_ENUM['ALIPAY']
        ]:
            return JsonResponse({'code': 400, 'errmsg': '支付方式不支持'})

        # 3、业务数据处理
        user = request.user
        # 约定购物车字典格式数据
        cart_dict = {}  # {1: {"count": 5, "selected": True}}
        # 获取redis购物车数据
        conn = get_redis_connection('carts')
        redis_carts = conn.hgetall('carts_%s' % user.id)  # {b'1': b'5'}
        redis_selected = conn.smembers('selected_%s' % user.id)  # [b'1']
        sku_ids = redis_carts.keys()
        for sku_id in sku_ids:
            if sku_id in redis_selected:
                cart_dict[int(sku_id)] = {
                    'count': int(redis_carts[sku_id]),
                    'selected': sku_id in redis_selected  # True
                }

        # 3.1、新建订单 —— OrderInfo
        cur_time = timezone.localtime()
        # cur_time.strftime('%Y%m%d%H%M%S') # '20201224111256'
        # order_id =  '20201224111256'  +   "00000005"
        order_id = cur_time.strftime('%Y%m%d%H%M%S') + "%08d" % user.id

        with transaction.atomic():
            # (1)、设置一个保存点 —— 用于回滚
            save_id = transaction.savepoint()
            order = OrderInfo.objects.create(
                order_id=order_id,
                user=user,
                address=address,
                # address_id = address_id
                total_count=0,  # 初始化为0,后续统计订单商品的时候在修改
                total_amount=Decimal('0'),

                freight=Decimal('10.0'),  # 运费

                pay_method=pay_method,  # 支付方式
                # 如果用户选择支付宝,状态为未支付;如果用户选择货到付款,状态未未发货。
                status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'] if pay_method == OrderInfo.PAY_METHODS_ENUM['ALIPAY'] else
                OrderInfo.ORDER_STATUS_ENUM['UNSEND']
            )
            # 3.2、新建订单商品(就是用户redis购物车中选中的sku商品) —— OrderGoods
            sku_selected_ids = cart_dict.keys()  # 所有已经选中的商品的id
            for sku_id in sku_selected_ids:
                # sku_id是每一个被选中的sku的id
                count = cart_dict[sku_id]['count']  # 用户购买量

                while True:
                    # (1)、读取旧库存和销量数据
                    sku = SKU.objects.get(pk=sku_id)
                    old_stock = sku.stock  # 旧库存
                    old_sales = sku.sales  # 旧销量

                    # (2)、计算新库存和销量
                    new_stock = old_stock - count
                    new_sales = old_sales + count

                    # (3)、基于旧数据查找,并更新
                    # update函数返回值为一个整数表示受影响的数据条数
                    result = SKU.objects.filter(
                        pk=sku_id, stock=old_stock, sales=old_sales
                    ).update(
                        stock=new_stock, sales=new_sales
                    )
                    if result == 0:
                        # 如果result为0,说明没有数据被更新,说明filter没有过滤出任何数据,说明旧数据发生改变,说明有别的事务介入
                        continue
                    # result不为0,表示基于旧数据查找并成功更新库存和销量,针对此次sku的更新完成,跳出循环
                    break

                # TODO: 判断库存
                if count > old_stock:
                    # 库存不够 —— 下单失败
                    # (2)、回滚事务,到新建订单order之前的保存点
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'code': 400, 'errmsg': '%s,%d 库存不够' % (sku.name, sku.id)})

                # 新建OrderGoods对象保存数据库
                OrderGoods.objects.create(
                    order=order,
                    sku=sku,
                    count=count,
                    price=sku.price,  # 单价
                )

                spu = sku.spu  # 当前sku关联的spu
                spu.sales += count
                spu.save()

                # 更新订单的商品数量和总价格
                order.total_count += count
                order.total_amount += sku.price * count
            order.total_amount += order.freight  # 把运费累加到总价中
            order.save()
            # (3)、删除保存点
            transaction.savepoint_commit(save_id)

        # TODO: 清楚已经下单的购物车商品
        conn.hdel('carts_%s' % user.id, *sku_selected_ids)  # func(*[1,2]) --> func(1,2)
        conn.srem('selected_%s' % user.id, *sku_selected_ids)

        # 4、构建响应
        return JsonResponse({'code': 0, 'errmsg': 'ok', 'order_id': order_id})
Esempio n. 41
0
    def post(self, request):
        # 1.接收非表单 参数
        json_dict = json.loads(request.body.decode())
        address_id = json_dict.get('address_id')
        pay_method = json_dict.get('pay_method')

        # 2.校验参数
        try:
            address = Address.objects.get(pk=address_id)
        except:
            return http.HttpResponseNotFound('地址不存在!')

        # 校验支付方式 : 1.支付宝 alipay 2.货到付款 cash
        if pay_method not in [OrderInfo.PAY_METHODS_ENUM['CASH'], OrderInfo.PAY_METHODS_ENUM['ALIPAY']]:
            return http.HttpResponseForbidden('美多商城暂不支持{}支付方式'.format(pay_method))

        # 3. 新增 OrderInfo 添加数据
        user = request.user
        #         年月日 时分秒 + 9个0 + user.id
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + ("%09d" % user.id)
        # 添加 局部 事务
        from django.db import transaction
        with transaction.atomic():

            # 设置 事务开始点-- 保存点
            sid = transaction.savepoint()

            try:
                order = OrderInfo.objects.create(order_id=order_id, user=user, address_id=address.id,
                                                 freight=Decimal('10.00'), pay_method=pay_method,
                                                 status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'], total_count=0,
                                                 total_amount=Decimal('0.00'))

                # 4. 新增 OrderGoods 添加数据--
                # - 已经选中的商品SKU---redis
                client = get_redis_connection('carts')
                redis_carts = client.hgetall(user.id)
                selected_dict = {}
                for k, v in redis_carts.items():
                    sku_id = int(k.decode())
                    sku_dict = json.loads(v.decode())

                    # 选中的商品 True
                    if sku_dict['selected']:
                        selected_dict[sku_id] = sku_dict

                for sku_id in selected_dict.keys():

                    while True:
                        # 当前购买的 sku的 所有信息--时时信息
                        sku = SKU.objects.get(pk=sku_id)

                        # 获取老库存 和 老销量
                        origin_stock = sku.stock
                        origin_sale = sku.sales

                        cart_count = selected_dict.get(sku_id).get('count')
                        # 判断库存 ;  购买个数 大于> sku的库存stock
                        if cart_count > sku.stock:
                            # 事务回滚
                            transaction.savepoint_rollback(sid)
                            return http.JsonResponse({'code': RETCODE.STOCKERR, 'errmsg': '{}-库存不足!'.format(sku.name)})

                        # 加延迟 10s中---测试 并发下单
                        # time.sleep(10)

                        # sku 库存减少 销量增加
                        # sku.stock -= cart_count
                        # sku.sales += cart_count
                        # sku.save()

                        # 计算 将来修改的 库存 和销量只 ---加锁
                        new_stock = origin_stock - cart_count
                        new_sales = origin_sale + cart_count
                        result=SKU.objects.filter(id=sku.id, stock=origin_stock).update(stock=new_stock, sales=new_sales)


                        # 如果 库存非常充足, 只是 在下单的时候  老库存修改了, 应该是 能够下单成功的---内部自动继续下单
                        if result == 0:
                            continue

                        # spu  销量增加
                        sku.spu.sales += cart_count
                        sku.spu.save()

                        # 订单商品表的 必传字段 填写全了
                        OrderGoods.objects.create(order=order,sku=sku,
                            count=cart_count,
                            price=sku.price
                        )

                        # 计算 总计金额 总个数
                        order.total_count += cart_count
                        order.total_amount += sku.price * cart_count

                        # 下单成功--跳出循环
                        break

                # 最后 总的 支付金额 == 累加金额 +  运费
                order.total_amount += order.freight
                order.save()

            except Exception as e:
                logger.error(e)

                # 事务回滚
                transaction.savepoint_rollback(sid)
                # 返回响应对象
                return http.JsonResponse({'code': 0, 'errmsg': '下单失败了'})

            # 事务提交
            transaction.savepoint_commit(sid)

        # 清空redis数据库 中选中的商品
        client.hdel(user.id, *selected_dict)

        # 返回响应对象
        return http.JsonResponse({'code': 0, 'errmsg': '下单成功', 'order_id': order.order_id})
Esempio n. 42
0
    def handle(self, *args, **options):

        accountings = []
        period = models.PeriodeBudget.active.first()
        self.errors = []

        # Structure du fichier :

        # Année
        # Structure
        # Plan de financement
        # Dépense/recette
        # Enveloppe
        # Nature comptable
        # Domaine fonctionnel
        # AE
        # CP
        # Charges/immos
        # AR
        # RE
        # Produits/ressources
        # Commentaire

        structures = {
            s.code: s
            for s in structure_models.Structure.active.all()
        }
        pfis = {
            pfi.code: pfi
            for pfi in structure_models.PlanFinancement.active.all()
        }
        dan = {(an.code_nature_comptable, an.is_fleche): an
               for an in structure_models.NatureComptableDepense.active.all()}
        ran = {(an.code_nature_comptable, an.is_fleche): an
               for an in structure_models.NatureComptableRecette.active.all()}
        domains = {
            d.code: d
            for d in structure_models.DomaineFonctionnel.active.all()
        }

        for filename in options.get('filename'):
            # Detect charset with chardet ?
            # Windows encoding
            with open(filename, encoding='iso-8859-1') as h:
                reader = csv.reader(h, delimiter=';', quotechar='"')
                for index, row in enumerate(reader):
                    if index == 0:
                        # Ignore header
                        continue

                    try:
                        (year, structure, pfi, accounting_type, enveloppe,
                         nature, domain, ae, cp, d_dc, ar, re, r_dc,
                         commentary) = row

                        pfi = self.get_object(pfis, pfi, 'PFI')
                        if accounting_type.lower().startswith('d'):
                            # Dépense
                            model = models.Depense
                            nature = self.get_object(dan,
                                                     (nature, pfi.is_fleche),
                                                     'nature')
                            functional_domain = self.get_object(
                                domains,
                                domain,
                                'domaine fonctionnel',
                                msg=f'- nature : {nature}')

                            amounts = {
                                'montant_dc': to_decimal(d_dc),
                                'montant_cp': to_decimal(cp),
                                'montant_ae': to_decimal(ae),
                                'naturecomptabledepense': nature,
                                'domainefonctionnel': functional_domain,
                            }
                        else:
                            # Recette
                            model = models.Recette
                            nature = self.get_object(ran,
                                                     (nature, pfi.is_fleche),
                                                     'nature')

                            amounts = {
                                'montant_dc': to_decimal(r_dc),
                                'montant_re': to_decimal(re),
                                'montant_ar': to_decimal(ar),
                                'naturecomptablerecette': nature,
                                'domainefonctionnel': domain,
                            }

                        structure = self.get_object(structures, structure,
                                                    'structure')
                        accountings.append(
                            model(pfi=pfi,
                                  structure=structure,
                                  commentaire=commentary or None,
                                  periodebudget=period,
                                  annee=year,
                                  **amounts))

                    except RowError:
                        continue

        if self.errors:
            print('ERRORS :\n\n{}'.format('\n'.join(self.errors)))
        else:
            sid = transaction.savepoint()
            try:
                for obj in accountings:
                    obj.save()
                print(f'{len(accountings)} accountings created')
            except Exception as e:
                print(f'Exception on save : {e}')
                transaction.savepoint_rollback(sid)
            else:
                transaction.savepoint_commit(sid)
Esempio n. 43
0
    def post(self, request):
        '''订单创建'''
        #判断用户是否登陆
        user = request.user
        if not user.is_authenticated:
            #用户未登陆
            return JsonResponse({'res': 0, 'errmsg': '用户未登录'})

        #接收参数
        addr_id = request.POST.get('addr_id')
        pay_method = request.POST.get('pay_method')
        sku_ids = request.POST.get('sku_ids')

        #校验参数
        if not all((addr_id, pay_method, sku_ids)):
            return JsonResponse({'res': 1, 'errmsg': '参数不完整'})

        #校验支付方式
        if pay_method not in OrderInfo.PAY_METHODS.keys():
            return JsonResponse({'res': 2, 'errmsg': '无效的支付方式'})

        #校验地址
        try:
            addr = Address.objects.get(id=addr_id)
        except Address.DoesNotExist:
            #地址不存在
            return JsonResponse({'res': 3, 'errmsg': '地址非法'})

        #todo:创建订单核心业务
        #订单信息表:df_order_info,订单商品表:df_order_goods
        #todo:用户每下一个订单,就需要向df_order_info表中加入一条记录,用户订单中有几个商品就需要向df_order_goods表中加入几条记录
        #组织参数
        #订单id:20200103+用户id
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + str(user.id)
        #运费
        transit_price = 10

        #总数目和总金额
        total_count = 0
        total_price = 0
        #设置事物保存点
        save_id = transaction.savepoint()
        #todo:向df_order_info表中添加一条记录
        try:
            # todo: 向df_order_info表中添加一条记录
            order = OrderInfo.objects.create(order_id=order_id,
                                             user=user,
                                             address=addr,
                                             pay_method=pay_method,
                                             total_count=total_count,
                                             total_price=total_price,
                                             transit_price=transit_price)

            # todo: 向df_order_goods表中添加记录
            conn = get_redis_connection('default')
            cart_key = 'cart_{0}'.format(user.id)

            sku_ids = sku_ids.split(',')
            for sku_id in sku_ids:
                # 使用乐观锁,需多重复几次,需要数据库的隔离级别为:提交读Read committed。
                for i in range(3):
                    # 获取商品信息
                    try:
                        sku = GoodsSKU.objects.get(id=sku_id)
                    except Exception as e:
                        transaction.savepoint_rollback(save_id)
                        return JsonResponse({'res': 4, 'errmsg': '商品不存在'})

                    # 从redis中获取商品的数量
                    count = conn.hget(cart_key, sku_id)

                    # todo: 判断某一个商品的库存
                    if int(count) > sku.stock:
                        transaction.savepoint_rollback(save_id)
                        return JsonResponse({'res': 6, 'errmsg': '商品库存不足'})

                    # todo: 更新商品的库存和销量
                    orgin_stock = sku.stock
                    orgin_sales = sku.sales
                    new_stock = orgin_stock - int(count)
                    new_sales = orgin_sales + int(count)

                    # 加乐观锁
                    # update df_goods_sku set stock=new_stock, sales=new_sales
                    # where id=sku_id and stock=orgin_stock;
                    res = GoodsSKU.objects.filter(
                        id=sku_id, stock=orgin_stock).update(stock=new_stock,
                                                             sales=new_sales)
                    if res == 0:
                        if i == 2:
                            transaction.savepoint_rollback(save_id)
                            return JsonResponse({'res': 7, 'errmsg': '下单失败2'})
                        continue

                    # todo: 向df_order_goods表中添加一条记录
                    OrderGoods.objects.create(order=order,
                                              sku=sku,
                                              count=count,
                                              price=sku.price)

                    # todo: 累加计算订单商品的总数量和总价格
                    amount = sku.price * int(count)
                    total_count += int(count)
                    total_price += amount

                    # 如果成功了,跳出循环
                    break

            # todo: 更新订单信息表中的商品的总数量和总价格
            order.total_price = total_price
            order.total_count = total_count
            order.save()
        except Exception as e:
            transaction.savepoint_rollback(save_id)
            return JsonResponse({'res': 7, 'errmsg': '下单失败'})
        #提交事务
        transaction.savepoint_commit(save_id)

        #todo:清除用户购物车中对应的记录[1,3]
        conn.hdel(cart_key, *sku_ids)
        #返回应答
        return JsonResponse({'res': 5, 'message': '创建成功'})
Esempio n. 44
0
        def post(self, request):
            """保存订单信息和订单商品信息"""
            # 获取当前保存订单时需要的信息
            # 接收参数
            json_dict = json.loads(request.body.decode())
            address_id = json_dict.get("address_id")
            pay_method = json_dict.get("pay_method")
            pay_method = int(pay_method)
             # 校验参数
            if not all([address_id, pay_method]):
                return http.HttpResponseForbidden('缺少必传参数')
                # 判断address_id是否合法
            try:
                address = Address.objects.get(id=address_id)
            except Exception:
                return http.HttpResponseForbidden('参数address_id错误')
                # 判断pay_method是否合法
            if pay_method not in [OrderInfo.PAY_METHODS_ENUM['CASH'], OrderInfo.PAY_METHODS_ENUM['ALIPAY']]:
                return http.HttpResponseForbidden('参数pay_method错误')

            # 显式的开启一个事务
            from django.db import transaction
            # 设置事物起始
            with transaction.atomic():

                # 事物保存点
                save_id = transaction.savepoint()
                try:
                    # 1.保存订单基本信息
                    user = request.user

                    # 生成订单编号 年月日时分秒 + 9位用户编号
                    order_id = datetime.now().strftime('%Y%m%d%H%M%S') + ('%09d' % user.id)

                    # 保存订单基本信息
                    order = OrderInfo.objects.create(
                        order_id=order_id,
                        user=user,
                        address= address,
                        total_count=0,
                        total_amount=Decimal('0'),
                        freight=Decimal('10.00'),
                        pay_method=pay_method,
                        status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'] if pay_method == OrderInfo.PAY_METHODS_ENUM[
                            'ALIPAY'] else
                        OrderInfo.ORDER_STATUS_ENUM['UNSEND']
                    )

                    # 2.保存相关商品信息
                    # 从购物车 取出选中的商品
                    redis_client = get_redis_connection('carts')
                    carts_data = redis_client.hgetall(user.id)
                    carts_dict = {}
                    for data in carts_data.items():
                        sku_id = int(data[0].decode())
                        sku_dict = json.loads(data[1].decode())
                        if sku_dict['selected']:
                            carts_dict[sku_id] = sku_dict

                    # 遍历 商品信息
                    sku_ids = carts_dict.keys()
                    for sku_id in sku_ids:

                        while True:
                            sku = SKU.objects.get(id=sku_id)

                            # 原始销量 和  库存量
                            origin_sales = sku.sales
                            origin_stock = sku.stock

                            # 判断库存是否充足
                            sku_count = carts_dict[sku_id]['count']
                            if sku_count > sku.stock:
                                # 事物回滚
                                transaction.savepoint_rollback(save_id)
                                return http.JsonResponse({'code': RETCODE.STOCKERR, 'errmsg': '库存不足'})

                            # 模拟资源抢夺
                            # time.sleep(10)
                            # sku减少库存, 增加销量
                            # sku.stock -= sku_count
                            # sku.sales += sku_count
                            # sku.save()

                            # 使用乐观锁 更新库存量
                            new_stock = origin_stock - sku_count
                            new_sales = origin_sales + sku_count
                            result = SKU.objects.filter(id=sku_id, stock=origin_stock).update(stock=new_stock,
                                                                                              sales=new_sales)

                            # 如果下单下单失败,库存足够则继续下单,直到下单成功或者库存不足
                            if result == 0:
                                continue
                            else:
                                # SPU 增加销量
                                sku.spu.sales += sku_count
                                sku.spu.save()

                                # 保存订单商品信息
                                OrderGoods.objects.create(
                                    order=order,
                                    sku=sku,
                                    count=sku_count,
                                    price=sku.price,
                                )

                                # 保存商品订单中总价和总数量
                                order.total_count += sku_count
                                order.total_amount += (sku_count * sku.price)

                                # 下单成功 或失败跳出
                                break

                    # 添加邮费和保存订单
                    order.total_amount += order.freight
                    order.save()

                except:
                    # 事物回滚
                    transaction.savepoint_rollback(save_id)
                    return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '下单失败'})

                # 提交事物
                transaction.savepoint_commit(save_id)

            # 清除购物车已经结算过的商品
            redis_client.hdel(user.id, *carts_dict)

            # 返回响应结果
            return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '下单成功', 'order_id': order.order_id})
Esempio n. 45
0
def do_import(request, import_log_id):
    """ Import the data! """
    import_log = get_object_or_404(ImportLog, id=import_log_id)
    if import_log.import_type == "N" and 'undo' in request.GET and request.GET['undo'] == "True":
        import_log.undo()
        return HttpResponseRedirect(reverse(
                    'simple_import:simple_import-do_import',
                    kwargs={'import_log_id': import_log.id}) + '?success_undo=True')

    if 'success_undo' in request.GET and request.GET['success_undo'] == "True":
        success_undo = True
    else:
        success_undo = False

    model_class = import_log.import_setting.content_type.model_class()
    import_data = import_log.get_import_file_as_list()
    header_row = import_data.pop(0)
    header_row_field_names = []
    header_row_default = []
    header_row_null_on_empty = []
    error_data = [header_row + ['Error Type', 'Error Details']]
    create_count = 0
    update_count = 0
    fail_count = 0
    if 'commit' in request.GET and request.GET['commit'] == "True":
        commit = True
    else:
        commit = False

    key_column_name = None
    if import_log.update_key and import_log.import_type in ["U", "O"]:
        key_match = import_log.import_setting.columnmatch_set.get(column_name=import_log.update_key)
        key_column_name = key_match.column_name
        key_field_name = key_match.field_name
    for i, cell in enumerate(header_row):
        match = import_log.import_setting.columnmatch_set.get(column_name=cell)
        header_row_field_names += [match.field_name]
        header_row_default += [match.default_value]
        header_row_null_on_empty += [match.null_on_empty]
        if key_column_name != None and key_column_name.lower() == cell.lower():
            key_index = i

    with transaction.atomic():
        sid = transaction.savepoint()
        for row in import_data:
            try:
                with transaction.atomic():
                    is_created = True
                    if import_log.import_type == "N":
                        new_object = model_class()
                    elif import_log.import_type == "O":
                        filters = {key_field_name: row[key_index]}
                        new_object = model_class.objects.get(**filters)
                        is_created = False
                    elif import_log.import_type == "U":
                        filters = {key_field_name: row[key_index]}
                        new_object = model_class.objects.filter(**filters).first()
                        if new_object == None:
                            new_object = model_class()
                            is_created = False

                    new_object.simple_import_m2ms = {} # Need to deal with these after saving
                    for i, cell in enumerate(row):
                        if header_row_field_names[i]: # skip blank
                            if not import_log.is_empty(cell) or header_row_null_on_empty[i]:
                                set_field_from_cell(import_log, new_object, header_row_field_names[i], cell)
                            elif header_row_default[i]:
                                set_field_from_cell(import_log, new_object, header_row_field_names[i], header_row_default[i])
                    new_object.save()

                    for i, cell in enumerate(row):
                        if header_row_field_names[i]: # skip blank
                            if not import_log.is_empty(cell) or header_row_null_on_empty[i]:
                                set_method_from_cell(import_log, new_object, header_row_field_names[i], cell)
                            elif header_row_default[i]:
                                set_method_from_cell(import_log, new_object, header_row_field_names[i], header_row_default[i])
                    new_object.save()

                    for key in new_object.simple_import_m2ms.keys():
                        value = new_object.simple_import_m2ms[key]
                        m2m = getattr(new_object, key)
                        m2m_model = type(m2m.model())
                        related_field_name = RelationalMatch.objects.get(import_log=import_log, field_name=key).related_field_name
                        m2m_object = m2m_model.objects.get(**{related_field_name:value})
                        m2m.add(m2m_object)

                    if is_created:
                        LogEntry.objects.log_action(
                            user_id         = request.user.pk,
                            content_type_id = ContentType.objects.get_for_model(new_object).pk,
                            object_id       = new_object.pk,
                            object_repr     = smart_text(new_object),
                            action_flag     = ADDITION
                        )
                        create_count += 1
                    else:
                        LogEntry.objects.log_action(
                            user_id         = request.user.pk,
                            content_type_id = ContentType.objects.get_for_model(new_object).pk,
                            object_id       = new_object.pk,
                            object_repr     = smart_text(new_object),
                            action_flag     = CHANGE
                        )
                        update_count += 1
                    ImportedObject.objects.create(
                        import_log = import_log,
                        object_id = new_object.pk,
                        content_type = import_log.import_setting.content_type)
            except IntegrityError:
                exc = sys.exc_info()
                error_data += [row + ["Integrity Error", smart_text(exc[1])]]
                fail_count += 1
            except ObjectDoesNotExist:
                exc = sys.exc_info()
                error_data += [row + ["No Record Found to Update", smart_text(exc[1])]]
                fail_count += 1
            except ValueError:
                exc = sys.exc_info()
                if str(exc[1]).startswith('invalid literal for int() with base 10'):
                    error_data += [row + ["Incompatible Data - A number was expected, but a character was used", smart_text(exc[1])]]
                else:
                    error_data += [row + ["Value Error", smart_text(exc[1])]]
                fail_count += 1
            except:
                error_data += [row + ["Unknown Error"]]
                fail_count += 1
        if not commit:
            transaction.savepoint_rollback(sid)


    if fail_count:
        from io import StringIO
        from django.core.files.base import ContentFile
        from openpyxl.workbook import Workbook
        from openpyxl.writer.excel import save_virtual_workbook

        wb = Workbook()
        ws = wb.worksheets[0]
        ws.title = "Errors"
        filename = 'Errors.xlsx'
        for row in error_data:
            ws.append(row)
        buf = StringIO()
        # Not Python 3 compatible
        #buf.write(str(save_virtual_workbook(wb)))
        import_log.error_file.save(filename, ContentFile(save_virtual_workbook(wb)))
        import_log.save()

    return render(
        request,
        'simple_import/do_import.html',
        {
            'error_data': error_data,
            'create_count': create_count,
            'update_count': update_count,
            'fail_count': fail_count,
            'import_log': import_log,
            'commit': commit,
            'success_undo': success_undo,},
    )
Esempio n. 46
0
    def post(self, request):
        '''订单创建'''
        #判断用户是否登陆
        user = request.user
        if not user.is_authenticated:
            #用户未登陆
            return JsonResponse({'res': 0, 'errmsg': '用户未登录'})

        #接收参数
        addr_id = request.POST.get('addr_id')
        pay_method = request.POST.get('pay_method')
        sku_ids = request.POST.get('sku_ids')

        #校验参数
        if not all((addr_id, pay_method, sku_ids)):
            return JsonResponse({'res': 1, 'errmsg': '参数不完整'})

        #校验支付方式
        if pay_method not in OrderInfo.PAY_METHODS.keys():
            return JsonResponse({'res': 2, 'errmsg': '无效的支付方式'})

        #校验地址
        try:
            addr = Address.objects.get(id=addr_id)
        except Address.DoesNotExist:
            #地址不存在
            return JsonResponse({'res': 3, 'errmsg': '地址非法'})

        #todo:创建订单核心业务
        #订单信息表:df_order_info,订单商品表:df_order_goods
        #todo:用户每下一个订单,就需要向df_order_info表中加入一条记录,用户订单中有几个商品就需要向df_order_goods表中加入几条记录
        #组织参数
        #订单id:20200103+用户id
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + str(user.id)
        #运费
        transit_price = 10

        #总数目和总金额
        total_count = 0
        total_price = 0
        #设置事物保存点
        save_id = transaction.savepoint()
        #todo:向df_order_info表中添加一条记录
        try:
            order = OrderInfo.objects.create(
                order_id=order_id,
                user=user,
                addr=addr,
                pay_method=pay_method,
                total_count=total_count,
                total_price=total_price,
                transit_price=transit_price,
            )
            #todo:用户的订单中有几个商品,需要向df_order_goods表中加入几条记录
            conn = get_redis_connection('default')
            cart_key = 'cart_%s' % user.id
            sku_ids = sku_ids.split(',')

            for sku_id in sku_ids:
                #获取商品信息
                try:
                    #悲观锁加锁
                    #select * from df_goods_sku where id=sku_id for update;
                    sku = GoodsSKU.objects.select_for_update().get(id=sku_id)
                except:
                    #商品不存在
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'res': 4, 'errmsg': '商品不存在'})

                #从redis中获取用户所要购买的商品数量
                count = conn.hget(cart_key, sku_id)

                #todo:判断商品的库存
                if int(count) > sku.stock:
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'res': 6, 'errmsg': '商品库存不足'})

                #todo:向df_order_goods表中添加一条记录
                OrderGoods.objects.create(order=order,
                                          sku=sku,
                                          count=count,
                                          price=sku.price)
                #todo:更新商品的库存和销量
                sku.stock -= int(count)
                sku.sales += int(count)
                sku.save()

                #todo:累加计算订单商品的总数量和总价格
                amount = sku.price * int(count)
                total_count += int(count)
                total_price += amount

            #todo:更新订单信息表中的商品的总数量和总价格
            order.total_price = total_price
            order.total_count = total_count
            order.save()
        except Exception as e:
            transaction.savepoint_rollback(save_id)
            return JsonResponse({'res': 7, 'errmsg': '下单失败'})

        #提交事务
        transaction.savepoint_commit(save_id)

        #todo:清除用户购物车中对应的记录[1,3]
        conn.hdel(cart_key, *sku_ids)
        #返回应答
        return JsonResponse({'res': 5, 'message': '创建成功'})
Esempio n. 47
0
    def post(self, request):
        """
            1. 收货地址address_id
            2. 商品sku_ids(多个 request.POST.getlist("sku_ids"))
            3. 配送方式transport
        """
        # 获取到保存到session里面的用户id
        user_id = request.session.get('user_id')
        try:
            user = User.objects.get(pk=user_id)
        except:
            return JsonResponse({'error': 1, 'erg': '登录错误!'})
        # 获取请求的数据
        address_id = request.POST.get('address_id')
        transport_id = request.POST.get('transport')
        sku_id = request.POST.getlist('sku_id')
        # 判断请求的数据
        if not all((address_id, transport_id, sku_id)):
            return JsonResponse({'error': 2, 'erg': '参数错误!'})
        # 收货地址
        try:
            address = ReceivingAddress.objects.filter(
                is_delete=0, user_id=user_id).get(pk=address_id)
        except:
            return JsonResponse({'error': 3, 'erg': '获取地址不纯在!'})
        # 配送方式
        try:
            transport = Hauling.objects.filter(is_delete=0).get(
                pk=transport_id)
        except:
            return JsonResponse({'error': 4, 'erg': '配送方式不纯在!'})
        """
        添加订单数据
        """
        # 设置一个保存点,(事务回滚,回滚到该位置)以后回滚到该保存点位置
        sid = transaction.savepoint()

        # 生成一个订单编号
        order_sn = "{}{}{}".format(datetime.now().strftime("%Y%m%d%H%M%S"),
                                   random.randint(1000, 9999), user_id)
        # 生成一个地址
        order_address = '{}{}{}{}'.format(address.hcity, address.hproper,
                                          address.harea,
                                          address.detailed_description)
        print(order_address)
        print(order_sn)
        try:
            orderInfo = OrderInfo.objects.create(
                order_sn=order_sn,
                user=user,
                receiver=address.name,
                receiver_phone=address.phone,
                address=order_address,
                transport=transport,
                transport_price=transport.money,
            )
            print(orderInfo)
        except:
            return JsonResponse({'error': 5, 'erg': '订单添加失败!'})

        # 连接redis
        cnn = get_redis_connection("default")
        hset_id = 'car_%s' % user_id

        # 定义一个订单总价格
        order_money = 0
        # 获取商品信息
        for skuid in sku_id:
            try:
                goods_sku = GoodsSkuInfo.objects.select_for_update().get(
                    pk=skuid)  # 加锁(解决高并发问题)
            except:
                # 手动回滚事务
                transaction.savepoint_rollback(sid)
                return JsonResponse({"error": 6, "msg": "商品不存在!"})

            # 获取购物车中商品的数量
            count = cnn.hget(hset_id, skuid)
            print(count)
            count = int(count)

            # 判断库存是否足够
            if goods_sku.goods_inventory < count:
                # 手动回滚事务
                transaction.savepoint_rollback(sid)
                return JsonResponse({"error": 7, "msg": "商品库存不足!"})

            # 保存订单商品表的数据
            try:
                order_goods = OrderGoods.objects.create(
                    order=orderInfo,
                    goods_sku=goods_sku,
                    price=goods_sku.goods_price,
                    count=count)
            except:
                # 手动回滚事务
                transaction.savepoint_rollback(sid)
                return JsonResponse({"error": 8, "msg": "创建订单商品数据失败!"})

            # 订单商品表保存成功, 说明该商品的库存减少
            goods_sku.goods_inventory -= count
            # 销量增加
            goods_sku.goods_sales += count
            goods_sku.save()

            # 累计计算订单总价
            order_money += count * goods_sku.goods_price

        # 将订单商品总价保存在订单基本信息表中
        try:
            orderInfo.order_money = order_money
            orderInfo.save()
        except:
            # 手动回滚事务
            transaction.savepoint_rollback(sid)
            return JsonResponse({"error": 9, "msg": "更新订单价格失败!"})

        # 清空购物车
        cnn.hdel(hset_id, *sku_id)
        # 提交事务
        transaction.savepoint_commit(sid)

        return JsonResponse({
            "error": 0,
            "msg": "创建订单成功",
            "order_sn": order_sn
        })
Esempio n. 48
0
    def post(self, request):
        user = request.user
        if not user.is_authenticated():
            return JsonResponse({'res': -1, 'error': '用户未登录'})

        addr_id = request.POST.get('addr_id')
        pay_method = request.POST.get('pay_method')
        sku_ids = request.POST.get('sku_ids')
        if not all([addr_id, pay_method, sku_ids]):
            return JsonResponse({'res': -2, 'error': '数据不完整'})

        if pay_method not in OrderInfo.PAY_METHODS.keys():
            return JsonResponse({'res': -3, 'error': '非法的支付方式'})

        try:
            addr = Address.objects.get(id=addr_id)
        except Address.DoesNotExist:
            return JsonResponse({'res': -4, 'error': '非法的地址'})

        # 订单id格式:年月日时分秒+用户id
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + str(user.id)

        # 运费
        transit_price = 10

        # 总数目和总价
        total_count = 0
        total_price = 0

        # 设置事务保存点
        save_id = transaction.savepoint()

        try:
            # 向order_info表中添加一条记录
            order = OrderInfo.objects.create(order_id=order_id,
                                             user=user,
                                             addr=addr,
                                             pay_method=pay_method,
                                             total_count=total_count,
                                             total_price=total_price,
                                             transit_price=transit_price)

            # 用户的订单有几个商品,就需要在order_goods表中加入几条记录
            conn = get_redis_connection('default')
            cart_key = 'cart_%d' % user.id
            sku_ids = sku_ids.split(',')
            for sku_id in sku_ids:
                # 乐观锁,尝试三次
                for i in range(3):
                    try:
                        sku = GoodsSKU.objects.get(id=sku_id)
                        # 加上悲观锁   等效SQL语句:select * from goods_sku where id=sku_id for update;
                        # 当rollback或者commit后,自动释放锁
                        #sku = GoodsSKU.objects.select_for_update().get(id=sku_id)
                    except:
                        # 回滚到保存点
                        transaction.rollback(save_id)
                        return JsonResponse({'res': -5, 'error': '商品不存在'})

                    # 从redis中获取用户所需要购买的商品数量
                    count = conn.hget(cart_key, sku_id)

                    # 判断商品库存
                    if int(count) > sku.stock:
                        # 回滚到保存点
                        transaction.rollback(save_id)
                        return JsonResponse({'res': -6, 'error': '商品库存不足'})

                    # 更新商品库存和销量
                    # sku.stock -= int(count)
                    # sku.sales += int(count)
                    # sku.save()

                    orign_stock = sku.stock
                    new_stock = orign_stock - int(count)
                    new_sales = sku.sales + int(count)
                    # 乐观锁,等效SQL语句:
                    # update goods_sku set stock=new_stock, sales=new_sales where id=sku_id and stock=origin_stock;
                    # 返回受影响的行数
                    res = GoodsSKU.objects.filter(
                        id=sku_id, stock=orign_stock).update(stock=new_stock,
                                                             sales=new_sales)
                    if res == 0:
                        # 尝试到第三次还是失败的情况
                        if i == 2:
                            transaction.savepoint_rollback(save_id)
                            return JsonResponse({'res': -7, 'error': '下单失败'})
                        continue

                    # order_goods表中加入记录
                    OrderGoods.objects.create(order=order,
                                              sku=sku,
                                              count=count,
                                              price=sku.price)

                    # 累加计算订单商品总数和总价
                    amount = sku.price * int(count)
                    total_count += int(count)
                    total_price += amount

                    break

            # 更新订单信息表中的商品总数和总价
            order.total_count = total_count
            order.total_price = total_price
            order.save()

        except Exception:
            # 回滚到保存点
            transaction.rollback(save_id)
            return JsonResponse({'res': -7, 'error': '下单失败'})

        # 提交事务
        transaction.savepoint_commit(save_id)

        # 清除用户购物车中对应记录
        # *sku_ids: 将列表拆包
        conn.hdel(cart_key, *sku_ids)

        return JsonResponse({'res': 1, 'msg': '创建成功'})
Esempio n. 49
0
def obraCrear(request):
    form = None
    if request.method == 'POST':
        sid = transaction.savepoint()
        try:
            proceso = json.loads(request.POST.get('proceso'))
            print proceso
            print("en try")
            if 'clienProv' not in proceso:
                msg = 'El cliente no ha sido selecionado'
                raise Exception(msg)
            # if len(proceso['producto'])<=0:
            #     msg = 'No se ha selecionado ningun producto'
            #     raise Exception(msg)
            # if len(proceso['obrero']) <=0:
            #     msg = 'No selecciono ningun obrero'
            #     raise Exception(msg)
            #hasta aca era lo de obligatorio

            # for k in proceso['producto']:
            #     print(k['codigo'])
            #     producto = producto.objects.get(codigo=k['codigo'])

            crearObra = Obra(
                cliente=Cliente.objects.get(dni=proceso['clienProv']),
                fecha=timezone.now(),
                usuario=request.user,
                descripcion=proceso['descripcion'],
                direccion=proceso['direccion'],
                fechaInicio=proceso['fechaInicio'],
                fechaFinalizacion=proceso['fechaFinal'],
                porcentajeA=proceso['porcentajeA'],
                valorA=proceso['valorA'],
                porcentajeI=proceso['porcentajeI'],
                valorI=proceso['valorI'],
                porcentajeU=proceso['porcentajeU'],
                valorU=proceso['valorU'],
                formaPago=proceso['tipoPago'],
                iva=proceso['ivaU'],
                subtotal=proceso['subtotal'],
                total=proceso['total'],
                estado=proceso['estado'],
            )
            crearObra.save()
            print "factura Guardada"
            print crearObra
            for k in proceso['producto']:
                producto = Producto.objects.get(codigo=k['codigo'])
                print(producto)
                crearDetalleProducto = DetalleObra(
                    producto=producto,
                    usuario=request.user,
                    descripcion=producto.descripcion,
                    cantidad=int(k['cantidad']),
                    fecha=timezone.now(),
                    obra=crearObra,
                )
                crearDetalleProducto.save()
                print("Despues de crearDetalleProducto")
            for i in proceso['obrero']:
                obrero = Obrero.objects.get(dni=i['dni'])
                print(obrero)
                crearDetalleObrero = DetalleObreroObra(
                    obra=crearObra,
                    obrero=obrero,
                    usuario=request.user,
                )
                crearDetalleObrero.save()
            messages.success(request, 'La venta se ha realizado')
        except Exception, e:
            try:
                transaction.savepoint_rollback(sid)
            except:
                pass
            messages.error(request, e)
Esempio n. 50
0
    def create(self, validated_data):
        """
                保存订单
                """
        # 获取当前下单用户
        user = self.context['request'].user

        # 组织订单编号 20170903153611+user.id
        # timezone.now() -> datetime
        order_id = timezone.now().strftime('%Y%m%d%H%M%S') + ('%09d' % user.id)

        address = validated_data['address']
        pay_method = validated_data['pay_method']

        # 生成订单
        with transaction.atomic():
            # 创建一个保存点
            save_id = transaction.savepoint()

            try:
                # 创建订单信息
                order = OrderInfo.objects.create(
                    order_id=order_id,
                    user=user,
                    address=address,
                    total_count=0,
                    total_amount=Decimal(0),
                    freight=Decimal(10),
                    pay_method=pay_method,
                    status=OrderInfo.ORDER_STATUS_ENUM['UNSEND']
                    if pay_method == OrderInfo.PAY_METHODS_ENUM['CASH'] else
                    OrderInfo.ORDER_STATUS_ENUM['UNPAID'])
                # 获取购物车信息
                redis_conn = get_redis_connection("cart")
                redis_cart = redis_conn.hgetall("cart_%s" % user.id)
                cart_selected = redis_conn.smembers('cart_selected_%s' %
                                                    user.id)

                # 将bytes类型转换为int类型
                cart = {}
                for sku_id in cart_selected:
                    cart[int(sku_id)] = int(redis_cart[sku_id])

                # # 一次查询出所有商品数据
                # skus = SKU.objects.filter(id__in=cart.keys())

                # 处理订单商品
                sku_id_list = cart.keys()
                for sku_id in sku_id_list:
                    while True:
                        sku = SKU.objects.get(id=sku_id)

                        sku_count = cart[sku.id]

                        # 判断库存
                        origin_stock = sku.stock  # 原始库存
                        origin_sales = sku.sales  # 原始销量

                        if sku_count > origin_stock:
                            transaction.savepoint_rollback(save_id)
                            raise serializers.ValidationError('商品库存不足')

                        # 用于演示并发下单
                        # import time
                        # time.sleep(5)

                        # 减少库存
                        # sku.stock -= sku_count
                        # sku.sales += sku_count
                        # sku.save()
                        new_stock = origin_stock - sku_count
                        new_sales = origin_sales + sku_count

                        # 根据原始库存条件更新,返回更新的条目数,乐观锁
                        ret = SKU.objects.filter(id=sku.id,
                                                 stock=origin_stock).update(
                                                     stock=new_stock,
                                                     sales=new_sales)
                        if ret == 0:
                            continue

                        # 累计商品的SPU 销量信息
                        sku.goods.sales += sku_count
                        sku.goods.save()

                        # 累计订单基本信息的数据
                        order.total_count += sku_count  # 累计总金额
                        order.total_amount += (sku.price * sku_count)  # 累计总额

                        # 保存订单商品
                        OrderGoods.objects.create(
                            order=order,
                            sku=sku,
                            count=sku_count,
                            price=sku.price,
                        )

                        # 更新成功
                        break

                # 更新订单的金额数量信息
                order.total_amount += order.freight
                order.save()

            except serializers.ValidationError:
                raise
            except Exception as e:
                # logger.error(e)
                transaction.savepoint_rollback(save_id)
                raise

            # 提交事务
            transaction.savepoint_commit(save_id)

            # 更新redis中保存的购物车数据
            pl = redis_conn.pipeline()
            pl.hdel('cart_%s' % user.id, *cart_selected)
            pl.srem('cart_selected_%s' % user.id, *cart_selected)
            pl.execute()
            return order
Esempio n. 51
0
    def post(self, request):
        """保存订单信息和订单商品信息"""
        json_dict = json.loads(request.body.decode())
        address_id = json_dict.get('address_id')
        pay_method = json_dict.get('pay_method')
        # 校验参数
        if not all([address_id, pay_method]):
            return http.HttpResponseForbidden('缺少必传参数')
        # 判断address_id是否合法
        try:
            address = Address.objects.get(id=address_id)
        except Exception:
            return http.HttpResponseForbidden('参数address_id错误')
        # 判断pay_method是否合法
        if pay_method not in [
                OrderInfo.PAY_METHODS_ENUM['CASH'],
                OrderInfo.PAY_METHODS_ENUM['ALIPAY']
        ]:
            return http.HttpResponseForbidden('参数pay_method错误')

        # 获取登录用户
        user = request.user
        # 生成订单编号:年月日时分秒+用户编号
        order_id = timezone.localtime().strftime('%Y%m%d%H%M%S') + ('%09d' %
                                                                    user.id)
        # 显式的开启一个事务
        with transaction.atomic():
            # 创建事务保存点
            save_id = transaction.savepoint()

            # 保存订单基本信息 OrderInfo(一)
            order = OrderInfo.objects.create(
                order_id=order_id,
                user=user,
                address=address,
                total_count=0,
                total_amount=Decimal('0'),
                freight=Decimal('10.00'),
                pay_method=pay_method,
                status=OrderInfo.ORDER_STATUS_ENUM['UNPAID']
                if pay_method == OrderInfo.PAY_METHODS_ENUM['ALIPAY'] else
                OrderInfo.ORDER_STATUS_ENUM['UNSEND'])

            # 从redis读取购物车中被勾选的商品信息
            redis_conn = get_redis_connection('carts')
            redis_cart = redis_conn.hgetall('carts_%s' % user.id)
            selected = redis_conn.smembers('selected_%s' % user.id)
            carts = {}
            for sku_id in selected:
                carts[int(sku_id)] = int(redis_cart[sku_id])
            sku_ids = carts.keys()

            # 遍历购物车中被勾选的商品信息
            for sku_id in sku_ids:
                # 查询SKU信息
                # 增加的代码: 增加一个死循环
                while True:
                    # 查询SKU信息
                    sku = SKU.objects.get(id=sku_id)

                    # 增加的代码: 读取原始库存
                    origin_stock = sku.stock
                    origin_sales = sku.sales

                    # 判断SKU库存
                    sku_count = carts[sku.id]
                    if sku_count > sku.stock:
                        # 事务回滚
                        transaction.savepoint_rollback(save_id)
                        return http.JsonResponse({
                            'code': 400,
                            'errmsg': '库存不足'
                        })

                    # 模拟延迟
                    # import time
                    # time.sleep(5)

                    # SKU减少库存,增加销量
                    # sku.stock -= sku_count
                    # sku.sales += sku_count
                    # sku.save()

                    # 增加的代码: 乐观锁更新库存和销量
                    # 计算差值
                    new_stock = origin_stock - sku_count
                    new_sales = origin_sales + sku_count
                    result = SKU.objects.filter(
                        id=sku_id, stock=origin_stock).update(stock=new_stock,
                                                              sales=new_sales)
                    # 如果下单失败,但是库存足够时,
                    # 继续下单,直到下单成功或者库存不足为止
                    if result == 0:
                        continue

                    # 修改SPU销量
                    sku.goods.sales += sku_count
                    sku.goods.save()

                    # 保存订单商品信息 OrderGoods(多)
                    OrderGoods.objects.create(
                        order=order,
                        sku=sku,
                        count=sku_count,
                        price=sku.price,
                    )

                    # 保存商品订单中总价和总数量
                    order.total_count += sku_count
                    order.total_amount += (sku_count * sku.price)

                    # 增加的代码:
                    # 下单成功或者失败就跳出循环
                    break

                # 添加邮费和保存订单信息
                order.total_amount += order.freight
                order.save()
                # 清除保存点
            transaction.savepoint_commit(save_id)

            # 清除购物车中已结算的商品
            pl = redis_conn.pipeline()
            pl.hdel('carts_%s' % user.id, *selected)
            pl.srem('selected_%s' % user.id, *selected)
            pl.execute()

            # 响应提交订单结果
            return http.JsonResponse({
                'code': 0,
                'errmsg': '下单成功',
                'order_id': order.order_id
            })
Esempio n. 52
0
    def save_data(self, project, data, raw=False):
        # TODO: this function is way too damn long and needs refactored
        # the inner imports also suck so let's try to move it away from
        # the objects manager

        # TODO: culprit should default to "most recent" frame in stacktraces when
        # it's not provided.
        from sentry.plugins import plugins
        from sentry.models import Event, Project, EventMapping

        project = Project.objects.get_from_cache(id=project)

        # First we pull out our top-level (non-data attr) kwargs
        event_id = data.pop('event_id')
        message = data.pop('message')
        culprit = data.pop('culprit') or ''
        level = data.pop('level')
        time_spent = data.pop('time_spent')
        logger_name = data.pop('logger')
        server_name = data.pop('server_name')
        site = data.pop('site')
        date = data.pop('timestamp')
        checksum = data.pop('checksum')
        platform = data.pop('platform')

        kwargs = {
            'message': message,
            'platform': platform,
        }

        event = Event(project=project,
                      event_id=event_id,
                      data=data,
                      time_spent=time_spent,
                      datetime=date,
                      **kwargs)

        # Calculate the checksum from the first highest scoring interface
        if not checksum:
            checksum = get_checksum_from_event(event)

        event.checksum = checksum

        group_kwargs = kwargs.copy()
        group_kwargs.update({
            'culprit': culprit,
            'logger': logger_name,
            'level': level,
            'last_seen': date,
            'first_seen': date,
            'time_spent_total': time_spent or 0,
            'time_spent_count': time_spent and 1 or 0,
        })

        tags = data['tags']
        tags.append(('level', LOG_LEVELS[level]))
        if logger:
            tags.append(('logger', logger_name))
        if server_name:
            tags.append(('server_name', server_name))
        if site:
            tags.append(('site', site))

        for plugin in plugins.for_project(project):
            added_tags = safe_execute(plugin.get_tags, event)
            if added_tags:
                tags.extend(added_tags)

        try:
            group, is_new, is_regression, is_sample = self._create_group(
                event=event, tags=data['tags'], **group_kwargs)
        except Exception as exc:
            # TODO: should we mail admins when there are failures?
            try:
                logger.exception(u'Unable to process log entry: %s', exc)
            except Exception as exc:
                warnings.warn(u'Unable to process log entry: %s', exc)
            return

        using = group._state.db

        event.group = group

        # save the event unless its been sampled
        if not is_sample:
            sid = transaction.savepoint(using=using)
            try:
                event.save()
            except IntegrityError:
                transaction.savepoint_rollback(sid, using=using)
                return event
            transaction.savepoint_commit(sid, using=using)

        sid = transaction.savepoint(using=using)
        try:
            EventMapping.objects.create(project=project,
                                        group=group,
                                        event_id=event_id)
        except IntegrityError:
            transaction.savepoint_rollback(sid, using=using)
            return event
        transaction.savepoint_commit(sid, using=using)
        transaction.commit_unless_managed(using=using)

        if not raw:
            send_group_processors(
                group=group,
                event=event,
                is_new=is_new or is_regression,  # backwards compat
                is_sample=is_sample,
                is_regression=is_regression,
            )

        index_event.delay(event)

        # TODO: move this to the queue
        if is_new and not raw:
            regression_signal.send_robust(sender=self.model, instance=group)

        return event
Esempio n. 53
0
    def post(self,request):
        """保持订单信息"""
        data=json.loads(request.body.decode())
        address_id=data.get('address_id')
        pay_method=data.get('pay_method')
        #数据校验
        if not all([address_id,pay_method]):
            return JsonResponse({
                'code':400,
                'errmsg':'缺少必要参数'
            })
        try:
            address=Address.objects.get(pk=address_id)
        except Exception as e:
            return ({
                'code':400,
                'errmsg':'地址错误'
            })
        if pay_method not in [1,2]:
            return JsonResponse({
                'code':400,
                'errmsg':'不支持的付款方式'
            })

        user=request.user
        order_id=timezone.localtime().strftime("%Y%m%d%H%M%S")+"%09d"%user.id
        #保存顶单信息
        with transaction.atomic():
            save_id=transaction.savepoint()#事务执行保存点
            order=OrderInfo.objects.create(
                order_id=order_id,
                user=user,
                address=address,
                total_count=0,
                total_amount=Decimal('0'),
                freight=Decimal('10.00'),
                pay_method=pay_method,
                status=OrderInfo.ORDER_STATUS_ENUM['UNPAID'] if
                pay_method==OrderInfo.PAY_METHODS_ENUM['ALIPAY']
                else OrderInfo.ORDER_STATUS_ENUM['UNSEND']
            )

            #读取购物车被勾选商品
            redis_conn=get_redis_connection("carts")
            cart_dict=redis_conn.hgetall('carts_%s'%user.id)
            selected_redis=redis_conn.smembers('selected_%s'%user.id)
            carts={}
            for k,v in cart_dict.items():
                if k in selected_redis:
                    carts[int(k)] = int(v)

            #获取商品id
            sku_ids=carts.keys()

            #便利查询商品信息
            for sku_id in sku_ids:
                while True:
                    sku=SKU.objects.get(id=sku_id)
                    old_stock=sku.stock
                    old_sales=sku.sales
                    #判断库存
                    sku_count=carts[sku.id]
                    if sku_count > sku.stock:
                        transaction.savepoint_rollback(save_id) #回滚
                        return JsonResponse({
                            'code':400,
                            'errmsg':'库存不足'
                        })
                    #修改数据库
                    # sku.stock-=sku_count
                    # sku.sales+=sku_count
                    # sku.save()
                    new_stock=old_stock-sku_count
                    new_sales=old_sales+sku_count
                    result=SKU.objects.filter(id=sku.id,
                                              stock=old_stock,
                                              sales=old_sales).update(
                        stock=new_stock,sales=old_sales
                    )
                    if result==0:
                        continue
                    break

                #修改spu销量
                # sku.goods.sales+=sku_count
                # sku.goods.save()

                #保存订单商品信息
                OrderGoods.objects.create(
                    order=order,
                    sku=sku,
                    count=carts[sku_id],
                    price=sku.price
                )
                order.total_count+=sku_count
                order.total_amount+=(sku_count*sku.price)
            order.total_amount+=order.freight
            order.save()
            transaction.savepoint_commit(save_id)


        #清楚购物车结算商品
        redis_conn.hdel('carts_%s'%user.id,*selected_redis)
        redis_conn.srem('selected_%s'%user.id,*selected_redis)

        #返回响应
        return JsonResponse({
            'code':0,
            'errmsg':'下单成功',
            'order_id':order.order_id

        })
Esempio n. 54
0
    def import_data_inner(self, dataset, dry_run, raise_errors,
                          using_transactions, collect_failed_rows, **kwargs):
        result = self.get_result_class()()
        result.diff_headers = self.get_diff_headers()
        result.total_rows = len(dataset)

        if using_transactions:
            # when transactions are used we want to create/update/delete object
            # as transaction will be rolled back if dry_run is set
            sp1 = savepoint()

        try:
            self.before_import(dataset, using_transactions, dry_run, **kwargs)
        except Exception as e:
            logging.exception(e)
            tb_info = traceback.format_exc()
            result.append_base_error(self.get_error_result_class()(e, tb_info))
            if raise_errors:
                if using_transactions:
                    savepoint_rollback(sp1)
                raise

        instance_loader = self._meta.instance_loader_class(self, dataset)

        # Update the total in case the dataset was altered by before_import()
        result.total_rows = len(dataset)

        if collect_failed_rows:
            result.add_dataset_headers(dataset.headers)

        for row in dataset.dict:
            row_result = self.import_row(row,
                                         instance_loader,
                                         using_transactions=using_transactions,
                                         dry_run=dry_run,
                                         **kwargs)
            result.increment_row_result_total(row_result)
            if row_result.errors:
                if collect_failed_rows:
                    result.append_failed_row(row, row_result.errors[0])
                if raise_errors:
                    if using_transactions:
                        savepoint_rollback(sp1)
                    raise row_result.errors[-1].error
            if (row_result.import_type != RowResult.IMPORT_TYPE_SKIP
                    or self._meta.report_skipped):
                result.append_row_result(row_result)

        try:
            self.after_import(dataset, result, using_transactions, dry_run,
                              **kwargs)
        except Exception as e:
            logging.exception(e)
            tb_info = traceback.format_exc()
            result.append_base_error(self.get_error_result_class()(e, tb_info))
            if raise_errors:
                if using_transactions:
                    savepoint_rollback(sp1)
                raise

        if using_transactions:
            if dry_run or result.has_errors():
                savepoint_rollback(sp1)
            else:
                savepoint_commit(sp1)

        return result
Esempio n. 55
0
    def put(self, request, *args, **kwargs):
        """
        修改构建源
        ---
        """
        s_id = transaction.savepoint()
        try:
            image = request.data.get("image", None)
            cmd = request.data.get("cmd", None)
            service_source = request.data.get("service_source")
            git_url = request.data.get("git_url", None)
            code_version = request.data.get("code_version", None)
            user_name = request.data.get("user_name", None)
            password = request.data.get("password", None)
            is_oauth = request.data.get("is_oauth", False)
            user_id = request.user.user_id
            oauth_service_id = request.data.get("service_id")
            git_full_name = request.data.get("full_name")

            if not service_source:
                return Response(general_message(400, "param error", "参数错误"), status=400)

            service_source_user = service_source_repo.get_service_source(
                team_id=self.service.tenant_id, service_id=self.service.service_id)

            if not service_source_user:
                service_source_info = {
                    "service_id": self.service.service_id,
                    "team_id": self.service.tenant_id,
                    "user_name": user_name,
                    "password": password,
                    "create_time": datetime.datetime.now().strftime('%Y%m%d%H%M%S')
                }
                service_source_repo.create_service_source(**service_source_info)
            else:
                service_source_user.user_name = user_name
                service_source_user.password = password
                service_source_user.save()
            if service_source == "source_code":
                if code_version:
                    self.service.code_version = code_version
                else:
                    self.service.code_version = "master"
                if git_url:
                    if is_oauth:
                        try:
                            oauth_service = oauth_repo.get_oauth_services_by_service_id(service_id=oauth_service_id)
                            oauth_user = oauth_user_repo.get_user_oauth_by_user_id(service_id=oauth_service_id, user_id=user_id)
                        except Exception as e:
                            logger.debug(e)
                            rst = {"data": {"bean": None}, "status": 400, "msg_show": u"未找到OAuth服务, 请检查该服务是否存在且属于开启状态"}
                            return Response(rst, status=200)
                        try:
                            instance = get_oauth_instance(oauth_service.oauth_type, oauth_service, oauth_user)
                        except Exception as e:
                            logger.debug(e)
                            rst = {"data": {"bean": None}, "status": 400, "msg_show": u"未找到OAuth服务"}
                            return Response(rst, status=200)
                        if not instance.is_git_oauth():
                            rst = {"data": {"bean": None}, "status": 400, "msg_show": u"该OAuth服务不是代码仓库类型"}
                            return Response(rst, status=200)
                        service_code_from = "oauth_" + oauth_service.oauth_type
                        self.service.code_from = service_code_from
                        self.service.git_url = git_url
                        self.service.git_full_name = git_full_name
                        self.service.oauth_service_id = oauth_service_id
                        self.service.creater = user_id
                    else:
                        self.service.git_url = git_url
                self.service.save()
                transaction.savepoint_commit(s_id)
            elif service_source == "docker_run":
                if image:
                    version = image.split(':')[-1]
                    if not version:
                        version = "latest"
                        image = image + ":" + version
                    self.service.image = image
                    self.service.version = version
                self.service.cmd = cmd
                self.service.save()
                transaction.savepoint_commit(s_id)
            result = general_message(200, "success", "修改成功")
        except Exception as e:
            logger.exception(e)
            result = error_message(e.message)
            transaction.savepoint_rollback(s_id)
        return Response(result, status=result["code"])
Esempio n. 56
0
    def post(self, request):
        # 获取参数
        #  user 地址id  支付方式  商品id  数量(从购物车中获取)
        user = request.user
        address_id = request.POST.get("address_id")
        sku_ids = request.POST.get("sku_ids")  # "1,2,3,4"
        pay_method = request.POST.get("pay_method")

        # 校验参数
        if not all([address_id, sku_ids, pay_method]):
            return JsonResponse({"code": 2, "message": "参数缺失"})
        # 判断地址是否存在
        try:
            address = Address.objects.get(id=address_id)
        except Address.DoesNotExist:
            return JsonResponse({"code": 3, "message": "地址不存在"})

        # 判断支付方式
        pay_method = int(pay_method)
        if pay_method not in OrderInfo.PAY_METHODS.keys():
            return JsonResponse({"code": 4, "message": "支付方式错误"})

        # 判断商品
        sku_ids = sku_ids.split(",")   # ["1", "2"]
        redis_conn = get_redis_connection("default")
        cart = redis_conn.hgetall("cart_%s" % user.id)

        # 创建一个订单基本信息表数据

        # 自定义的order_id  "20171026111111用户id"
        order_id = timezone.now().strftime("%Y%m%d%H%M%S") + str(user.id)

        # 创建事务保存点
        save_id = transaction.savepoint()
        try:
            order = OrderInfo.objects.create(
                order_id=order_id,
                user=user,
                address=address,
                total_amount=0,
                trans_cost=10,
                pay_method=pay_method,
            )

            total_count = 0  # 总数
            total_amount = 0  # 总金额
            for sku_id in sku_ids:
                for i in range(3):
                    try:
                        sku = GoodsSKU.objects.get(id=sku_id)
                    except GoodsSKU.DoesNotExist:
                        # 回退的保存点的状态
                        transaction.savepoint_rollback(save_id)
                        return JsonResponse({"code": 5, "message": "商品有误"})

                    # 获取订购的商品数量,判断库存
                    sku_count = cart.get(sku_id.encode())
                    sku_count = int(sku_count)
                    if sku_count > sku.stock:
                        # 回退的保存点的状态
                        transaction.savepoint_rollback(save_id)
                        return JsonResponse({"code": 6, "message": "库存不足"})

                    # 减少商品的库存, 增加商品的销量
                    origin_stock = sku.stock
                    new_stock = origin_stock - sku_count
                    new_sales = sku.sales + sku_count
                    # update操作会返回受影响的行数,即更新成功的函数
                    result = GoodsSKU.objects.filter(id=sku_id, stock=origin_stock).update(stock=new_stock, sales=new_sales)
                    if result == 0 and i < 2:
                        # 表示更新失败
                        continue
                    elif result == 0 and i == 2:
                        # 表示尝试三次失败
                        transaction.savepoint_rollback(save_id)
                        return JsonResponse({"code": 7, "message": "下单失败"})

                    # 保存订单商品
                    OrderGoods.objects.create(
                        order=order,
                        sku=sku,
                        count=sku_count,
                        price=sku.price,
                    )

                    # 累计计算总数
                    total_count += sku_count
                    # 累计计算总金额
                    total_amount += (sku.price * sku_count)

                    # 跳出三次循环,处理下一个商品
                    break

            # 修改订单基本信息表中的统计数据字段
            order.total_count = total_count
            order.total_amount = total_amount + 10
            order.save()

        except Exception:
            # 出现任何异常,都要回退的保存点的状态
            transaction.savepoint_rollback(save_id)
            return JsonResponse({"code": 8, "message": "下单失败"})

        # 执行成功,提交事务
        transaction.savepoint_commit(save_id)

        # 保存最新的购物车数据
        redis_conn.hdel("cart_%s" % user.id, *sku_ids)  # 删除订购的商品

        # 返回前端json状态
        return JsonResponse({"code": 0, "message": "创建订单成功"})
Esempio n. 57
0
    def post(self, request):

        user = request.user
        if not user.is_authenticated:
            return JsonResponse({'res': 0, 'errmsg': 'Please login first'})

        addr_id = request.POST.get('addr_id')
        pay_method = int(request.POST.get('pay_method'))
        sku_ids = request.POST.get('sku_ids')  # sku_ids = 1,3,5,16....

        if not all([addr_id, pay_method, sku_ids]):
            return JsonResponse({
                'res': 1,
                'errmsg': 'Address fields is incomplete'
            })

        if pay_method not in OrderInfo.PAYMENT_METHODS.keys():
            return JsonResponse({'res': 2, 'errmsg': 'Invalid payment method'})

        try:
            addr = Address.objects.get(id=addr_id)
        except Address.DoesNotExist:
            return JsonResponse({'res': 3, 'errmsg': 'Invalid address'})

        # Implement create order service
        # Create order_info 1st, then order_goods because there's order_info_id foreign key in order_goods
        # Ex: order_id = 20190722160830+user.id
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + str(user.id)

        # goods total_count & total price
        total_count = 0
        total_price = 0

        # Setup savepoints
        save_id = transaction.savepoint()

        try:
            order = OrderInfo.objects.create(
                order_id=order_id,
                user=user,
                addr=addr,
                payment_method=pay_method,
                goods_total_count=total_count,
                goods_total_price=total_price,
            )

            # For any sku items in user's cart,
            # we need to create each sku order_gooods model & record it
            conn = get_redis_connection('default')
            cart_key = 'cart_{user_id}'.format(user_id=user.id)

            sku_ids = sku_ids.split(',')
            for sku_id in sku_ids:
                try:
                    # MySQL syntax: select * from sf_goods_sku where id=sku_id for update;
                    sku = GoodsSKU.objects.select_for_update().get(id=sku_id)
                except:
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({
                        'res': 4,
                        'errmsg': 'SKU id does not exists'
                    })

                count = conn.hget(cart_key, sku_id)
                count = int(count)

                # Verify whether intend to purchase item's sku quantity exceed item's sku stock or not,
                # if it is rollback to save point
                if count > sku.stock:
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'res': 5, 'errmsg': 'Out of stock'})

                OrderGoods.objects.create(order=order,
                                          sku=sku,
                                          count=count,
                                          price=sku.price)

                # Update GoodsSKU stock & sales
                sku.stock -= count
                sku.sales += count
                sku.save()

                # Update / accumulate order item's count and amount to total_count & total_price
                amount = sku.price * count
                total_count += count
                total_price += amount

            order.goods_total_count = total_count
            order.goods_total_price = total_price
            order.save()

        except Exception as e:
            transaction.savepoint_rollback(save_id)
            return JsonResponse({
                'res':
                6,
                'errmsg':
                'You already added this order in your order page'
            })

        # After purchased all the selected goods from cart, we need to remove these goods'
        # sku id from Redis with key = cart_user.id
        transaction.savepoint_commit(save_id)
        conn.hdel(cart_key, *sku_ids)
        return JsonResponse({'res': 7, 'message': 'Checkout successfully!'})
Esempio n. 58
0
    def post(self, request):
        # 获取登录的用户
        user = request.user

        # 判断用户是否登录
        if not user.is_authenticated():
            # 未登录
            return JsonResponse({'res': 0, 'errmsg': '请先登录'})

        # 接收参数
        sku_ids = request.POST.get('sku_ids')
        addr_id = request.POST.get('addr_id')
        pay_method = request.POST.get('pay_method')
        print(pay_method)

        # 校验参数
        if not all([sku_ids, addr_id, pay_method]):
            return JsonResponse({'res': 1, 'errmsg': '数据不完整'})

        # 校验支付方式是否存在
        if pay_method not in OrderInfo.PAY_METHODS.keys():
            # 非法支付方式
            return JsonResponse({'res': 2, 'errmsg': '非法支付方式'})

        # 判断地址是否存在
        try:
            addr = Address.objects.get(id=addr_id)
        except Address.DoesNotExist:
            return JsonResponse({'res': 3, 'errmsg': '地址不存在'})

        # 业务处理: 订单创建

        # 组织参数
        # 订单id: 时间 + user.id == 202001081010+user.id
        order_id = datetime.now().strftime("%Y%m%d%H%M%S") + str(user.id)

        # 运费
        transit_price = 10

        # 总数目和总价格
        total_count = 0
        total_price = 0

        # 设置保存点
        save_id = transaction.savepoint()
        try:
            # 向p1_order_info中添加一条信息
            order = OrderInfo.objects.create(order_id=order_id,
                                     user=user,
                                     addr=addr,
                                     pay_method=pay_method,
                                     total_price=total_price,
                                     total_count=total_count,
                                     transit_price=transit_price)

            # 订单中有几个商品需要向订单商品表中添加几条信息: p1_order_goods
            conn = get_redis_connection('default')
            cart_key = 'cart_%d'%user.id
            sku_ids = sku_ids.split(',')
            for sku_id in sku_ids:
                # 获取商品不存在
                try:
                    # 悲观锁 高并发
                    sku = GoodsSKU.objects.select_for_update().get(id=sku_id)
                except GoodsSKU.DoesNotExist:
                    # 商品不存在
                    # 事务回滚save_id
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'res': 4, 'errmsg': '商品不存在'})

                # 测试悲观锁
                print("user_id: %d, stock: %d" %(user.id, sku.stock))

                import time
                time.sleep(10)

                # 从redis中获取用户购买商品的数量
                count = conn.hget(cart_key, sku_id)

                # 判断商品的库存
                if int(count) > sku.stock:
                    transaction.savepoint_rollback(save_id)
                    return JsonResponse({'res': 6, 'errmsg': '商品库存不足'})

                # 向表中添加一条数据
                OrderGoods.objects.create(order=order,
                                          sku=sku,
                                          count=count,
                                          price=sku.price)

                # 更新商品的库存和销量
                sku.stock -= int(count)
                sku.sales += int(count)
                sku.save()

                # 累加计算商品的总数量和总价格
                amount = sku.price * int(count)

                total_count += int(count)
                total_price += amount

            # 更新订单信息表中的总数量和总价格
            order.total_count = total_count
            order.total_price = total_price

            order.save()
        except Exception as e:
            transaction.savepoint_rollback(save_id)
            return JsonResponse({'res': 7, 'errmsg': '下单失败'})

        # 业务提交
        transaction.savepoint_commit(save_id)

        # 清除用户购物车记录
        conn.hdel(cart_key, *sku_ids)

        # 返回应答
        return JsonResponse({'res': 5, 'message': '创建成功'})
Esempio n. 59
0
def addon_view_or_download_file(auth, path, provider, **kwargs):
    extras = request.args.to_dict()
    extras.pop('_', None)  # Clean up our url params a bit
    action = extras.get('action', 'view')
    node = kwargs.get('node') or kwargs['project']

    node_addon = node.get_addon(provider)

    provider_safe = markupsafe.escape(provider)
    path_safe = markupsafe.escape(path)
    project_safe = markupsafe.escape(node.project_or_component)

    if not path:
        raise HTTPError(httplib.BAD_REQUEST)

    if not isinstance(node_addon, BaseStorageAddon):
        raise HTTPError(httplib.BAD_REQUEST, data={
            'message_short': 'Bad Request',
            'message_long': 'The {} add-on containing {} is no longer connected to {}.'.format(provider_safe, path_safe, project_safe)
        })

    if not node_addon.has_auth:
        raise HTTPError(httplib.UNAUTHORIZED, data={
            'message_short': 'Unauthorized',
            'message_long': 'The {} add-on containing {} is no longer authorized.'.format(provider_safe, path_safe)
        })

    if not node_addon.complete:
        raise HTTPError(httplib.BAD_REQUEST, data={
            'message_short': 'Bad Request',
            'message_long': 'The {} add-on containing {} is no longer configured.'.format(provider_safe, path_safe)
        })

    savepoint_id = transaction.savepoint()
    file_node = BaseFileNode.resolve_class(provider, BaseFileNode.FILE).get_or_create(node, path)

    # Note: Cookie is provided for authentication to waterbutler
    # it is overriden to force authentication as the current user
    # the auth header is also pass to support basic auth
    version = file_node.touch(
        request.headers.get('Authorization'),
        **dict(
            extras,
            cookie=request.cookies.get(settings.COOKIE_NAME)
        )
    )
    if version is None:
        # File is either deleted or unable to be found in the provider location
        # Rollback the insertion of the file_node
        transaction.savepoint_rollback(savepoint_id)
        if not file_node.pk:
            file_node = BaseFileNode.load(path)
            # Allow osfstorage to redirect if the deep url can be used to find a valid file_node
            if file_node and file_node.provider == 'osfstorage' and not file_node.is_deleted:
                return redirect(
                    file_node.node.web_url_for('addon_view_or_download_file', path=file_node._id, provider=file_node.provider)
                )
        return addon_deleted_file(file_node=file_node, path=path, **kwargs)
    else:
        transaction.savepoint_commit(savepoint_id)

    # TODO clean up these urls and unify what is used as a version identifier
    if request.method == 'HEAD':
        return make_response(('', httplib.FOUND, {
            'Location': file_node.generate_waterbutler_url(**dict(extras, direct=None, version=version.identifier, _internal=extras.get('mode') == 'render'))
        }))

    if action == 'download':
        format = extras.get('format')
        _, extension = os.path.splitext(file_node.name)
        # avoid rendering files with the same format type.
        if format and '.{}'.format(format.lower()) != extension.lower():
            return redirect('{}/export?format={}&url={}'.format(MFR_SERVER_URL, format, urllib.quote(file_node.generate_waterbutler_url(
                **dict(extras, direct=None, version=version.identifier, _internal=extras.get('mode') == 'render')
            ))))
        return redirect(file_node.generate_waterbutler_url(**dict(extras, direct=None, version=version.identifier, _internal=extras.get('mode') == 'render')))

    if action == 'get_guid':
        draft_id = extras.get('draft')
        draft = DraftRegistration.load(draft_id)
        if draft is None or draft.is_approved:
            raise HTTPError(httplib.BAD_REQUEST, data={
                'message_short': 'Bad Request',
                'message_long': 'File not associated with required object.'
            })
        guid = file_node.get_guid(create=True)
        guid.referent.save()
        return dict(guid=guid._id)

    if len(request.path.strip('/').split('/')) > 1:
        guid = file_node.get_guid(create=True)
        return redirect(furl.furl('/{}/'.format(guid._id)).set(args=extras).url)
    return addon_view_file(auth, node, file_node, version)
Esempio n. 60
0
def facturaCrear(request):

    form = None
    if request.method == 'POST':
        sid = transaction.savepoint()
        try:
            proceso = json.loads(request.POST.get('proceso'))
            print proceso
            if 'serie' not in proceso:
                msg = 'Ingrese Serie'
                raise Exception(msg)

            if 'numero' not in proceso:
                msg = 'Ingrese Numero'
                raise Exception(msg)

            if 'clienProv' not in proceso:
                msg = 'No ha seleccionado al cliente'
                raise Exception(msg)

            if len(proceso['producto']) <= 0:
                msg = 'No ha seleccionado ningun producto'
                raise Exception(msg)

            total = 0

            for k in proceso['producto']:
                producto = Medicamentos.objects.get(id=k['serial'])
                subTotal = (producto.precio_venta) * int(k['cantidad'])
                total += subTotal

            crearFactura = Factura(
                serie=proceso['serie'],
                numero=proceso['numero'],

                cliente=Cliente.objects.get(id=proceso['clienProv']),
                fecha=timezone.now(),
                total=total,
                vendedor=request.user
            )
            crearFactura.save()
            print "Factura guardada"
            print crearFactura.id
            for k in proceso['producto']:
                producto = Medicamentos.objects.get(id=k['serial'])
                crearDetalle = DetalleFactura(
                    producto=producto,
                    descripcion=producto.nombre,
                    precio = producto.precio_venta,
                    cantidad=int(k['cantidad']),
                    impuesto=producto.igv* int(k['cantidad']),
                    subtotal=producto.precio_venta * int(k['cantidad']),
                    factura = crearFactura,
                    )
                crearDetalle.save()

            messages.success(
                request, 'La venta se ha realizado correctamente')
        except Exception, e:
            try:
                transaction.savepoint_rollback(sid)
            except:
                pass
            messages.error(request, e)