class BalanceGASForm(BalanceForm): wallet_gasmembers = CurrencyField(label=_('Wallet GASMembers'), required=False, max_digits=8, decimal_places=2) wallet_suppliers = CurrencyField(label=_('Solidal cash flow'), required=False, max_digits=8, decimal_places=2) # orders_grd = forms.MultipleChoiceField( # label=_('Insolutes'), choices=GASSupplierOrder.objects.none(), # required=False, # widget=forms.CheckboxSelectMultiple # ) # # wallet_insolute = CurrencyField(label=_('Wallet Insolute'), required=False, max_digits=8, decimal_places=2) def __init__(self, request, *args, **kw): super(BalanceGASForm, self).__init__(request, *args, **kw) eco_state = request.resource.balance_gasmembers eco_class = get_eco_class(eco_state) self.fields['wallet_gasmembers'].initial = ( "%.2f" % round(eco_state, 2)).replace('.', '€') self.fields['wallet_gasmembers'].widget.attrs['class'] = eco_class eco_state = request.resource.balance_suppliers eco_class = get_eco_class(eco_state) self.fields['wallet_suppliers'].initial = ( "%.2f" % round(eco_state, 2)).replace('.', '€') self.fields['wallet_suppliers'].widget.attrs['class'] = eco_class # Set readonly fields for wallet_* for field_name in ('wallet_gasmembers', 'wallet_suppliers'): self.fields[field_name].widget.attrs['readonly'] = True self.fields[field_name].widget.attrs['disabled'] = 'disabled' #show insolutes _choice, stat = get_html_insolutes(request.resource.gas.insolutes, EURO_LABEL)
class InvoiceOrderForm(forms.Form): amount = CurrencyField( label=_('Actual total'), required=True, max_digits=8, decimal_places=2, error_messages={'required': _('You must insert an postive amount')}) note = forms.CharField(label=_('Note'), required=False, widget=forms.Textarea) def __init__(self, request, *args, **kw): super(InvoiceOrderForm, self).__init__(*args, **kw) self.__order = request.resource.order if self.__order: # display statistic stat = ugettext(u"%(state)s - %(totals)s") % { 'state': self.__order.current_state.name, 'totals': self.__order.display_totals.replace( "euro", EURO_HTML) } self.fields['amount'].help_text = stat #set invoice data if self.__order.invoice_amount: self.fields['amount'].initial = "%.2f" % round( self.__order.invoice_amount, 2) if self.__order.invoice_note: self.fields['note'].initial = self.__order.invoice_note self.fields['amount'].widget.attrs['class'] = 'balance input_payment' if not self.__order.is_unpaid() and not self.__order.is_closed(): self.fields['amount'].widget.attrs['readonly'] = True self.fields['amount'].widget.attrs['disabled'] = 'disabled' self.__loggedusr = request.user self.__gas = self.__order.gas def clean(self): cleaned_data = super(InvoiceOrderForm, self).clean() try: cleaned_data['invoice_amount'] = abs(cleaned_data['amount']) cleaned_data['invoice_note'] = cleaned_data['note'] except KeyError, e: log.error("InvoiceOrderForm: cannot retrieve invoice data: " + e.message) raise forms.ValidationError( ugettext("Cannot retrieve invoice data: ") + e.message) return cleaned_data
class BalanceForm(forms.Form): balance = CurrencyField(label=_('Balance'), required=False, max_digits=8, decimal_places=2) def __init__(self, request, *args, **kw): super(BalanceForm, self).__init__(*args, **kw) #self.__gas_list = request.resource.gas_list eco_state = request.resource.balance eco_class = get_eco_class(eco_state) self.fields['balance'].initial = ( "%.2f" % round(request.resource.balance, 2)).replace('.', '€') self.fields['balance'].widget.attrs['class'] = eco_class self.__loggedusr = request.user # LF: Balance is a readonly field field_name = 'balance' self.fields[field_name].widget.attrs['readonly'] = True self.fields[field_name].widget.attrs['disabled'] = 'disabled'
class SingleSupplierStockForm(forms.Form): #For editing id = forms.IntegerField(required=False, widget=forms.HiddenInput) pk = forms.IntegerField(required=False) #code = forms.CharField(required=False) product = forms.CharField(required=True, widget=forms.TextInput(attrs={'size': '85'}), max_length=200) # description = forms.CharField(required=False, widget=forms.TextInput(), max_length=500) # product = forms.ModelChoiceField( # queryset = Product.objects.all(), # widget = RelatedFieldWidgetCanAdd(related_model=Product) # ) price = CurrencyField() availability = forms.BooleanField(required=False) def __init__(self, request, *args, **kw): super(SingleSupplierStockForm, self).__init__(*args, **kw) instance = getattr(self, 'instance', None) #if instance and instance.id: # self.fields['id'].widget.attrs['readonly'] = True self.fields['pk'].widget.attrs['readonly'] = True self.fields['pk'].widget.attrs['disabled'] = 'disabled' self.fields['pk'].widget.attrs['class'] = 'input_small' # self.fields['product'].widget.attrs['class'] = 'input_medium' # self.fields['description'].widget.attrs['class'] = 'input_long' self.fields['price'].widget.attrs['class'] = 'input_short taright' self.__supplier = request.resource # def clean_id(self): # return instance.id def save(self): #log.debug("Save SingleSupplierStockForm") if self.cleaned_data.get('id'): updated = False ss = SupplierStock.objects.get(pk=self.cleaned_data['id']) #prd = Product.objects.get(pk=ss.product.pk) prd = ss.product log.debug("SingleSupplierStockForm id_ss(%s) id_prd(%s)" % (ss.pk, prd.pk)) try: #ss.code = self.cleaned_data.get('code') #ss.supplier = self.__supplier if prd.name != self.cleaned_data['product']: prd.name = self.cleaned_data['product'] # prd.description = self.cleaned_data['description'] prd.save() #"SupplierStock.product" must be a "Product" instance #ss.product = self.cleaned_data['product'] #ss.product.description = self.cleaned_data['description'] old_price = ss.price ss.price = self.cleaned_data['price'] if old_price != ss.price: updated = True #CASCADING price has changed log.debug( "SingleSupplierStockForm price changed old(%s) new(%s)" % (old_price, ss.price)) old_amount = ss.amount_available ss.amount_available = [0, ALWAYS_AVAILABLE ][self.cleaned_data.get('availability')] if old_amount != ss.amount_available: updated = True #CASCADING product availability has changed log.debug( "SingleSupplierStockForm product availability has changed old(%s) new(%s)" % (old_amount, ss.amount_available)) if updated: log.debug( "Save SingleSupplierStockForm id_ss(%s) id_prd(%s)" % (ss.pk, prd.pk)) ss.save() except Exception, e: raise log.debug("Save SingleSupplierStockForm error(%s)" % str(e)) Exception("Save SingleSupplierStockForm error: %s", str(e)) else:
class EditStockForm(forms.ModelForm): """Edit form for mixed-in Product and SupplierStock attributes. WARNIG: this form is valid only in an update-context """ product_name = forms.CharField(required=True, label=_("Name"), widget=forms.TextInput(attrs={'size': '40'}, ), max_length=200) price = CurrencyField(label=_("Price (vat included)")) product_vat_percent = forms.IntegerField(required=True, initial=20, label=_("VAT percent")) availability = forms.BooleanField(required=False, label=_("Availability")) product_description = forms.CharField(required=False, label=_("Description"), widget=forms.TextInput(), max_length=500) product_pu = forms.ModelChoiceField(ProductPU.objects.all(), label=_("Package"), required=True) product_mu = forms.ModelChoiceField(ProductMU.objects.all(), required=False, label=_("Units")) product_muppu = TolerantDecimalField(label=_('of'), initial=1, min_value=Decimal('0.01'), max_value=Decimal('10000')) product_category = forms.ModelChoiceField( ProductCategory.objects.all(), label=ProductCategory._meta.verbose_name) # increment step (in Product units) for amounts exceeding minimum; # useful when a Product ships in packages containing multiple units. units_per_box = TolerantDecimalField( label=_("units per box").capitalize(), ) ## constraints posed by the Supplier on orders issued by *every* GASMember ## they act as default when creating a GASSupplierSolidalPact # minimum amount of Product units a GASMember can order detail_minimum_amount = TolerantDecimalField( label=_('detail minimum amount').capitalize(), ) # increment step (in Product units) for amounts exceeding minimum; # useful when a Product has a fixed step of increment detail_step = TolerantDecimalField(label=_("detail step").capitalize()) def __init__(self, request, *args, **kw): self.request = request super(EditStockForm, self).__init__(*args, **kw) self._supplier = request.resource.supplier self._product = request.resource.product self.fields['product_name'].initial = self._product.name self.fields['product_name'].widget.attrs['class'] = 'input_medium' self.fields['product_description'].widget.attrs['class'] = 'input_long' self.fields['product_pu'].initial = self._product.pu self.fields['product_mu'].initial = self._product.mu self.fields['product_muppu'].initial = self._product.muppu self.fields['product_vat_percent'].initial = int( self._product.vat_percent * 100) self.fields['product_category'].initial = self._product.category self.fields['availability'].initial = bool( request.resource.amount_available) # If Supplier is not the Producer ==> # can't change product info! if self._supplier != self._product.producer: for k, v in self.fields.items(): if k.startswith('product_'): self.fields[k].widget.attrs['disabled'] = 'disabled' self.fields['supplier_category'].queryset = self.fields[ 'supplier_category'].queryset.filter(supplier=self._supplier) def clean(self): cleaned_data = super(EditStockForm, self).clean() cleaned_data['supplier'] = self._supplier cleaned_data['amount_available'] = [ 0, ALWAYS_AVAILABLE ][self.cleaned_data.get('availability')] cleaned_data['product_vat_percent'] = Decimal( cleaned_data['product_vat_percent']) / 100 #MU and PU settings must be compatible with UnitsConversion table pu = cleaned_data['product_pu'] mu = cleaned_data.get('product_mu') mu_qs = ProductMU.objects.filter(symbol__exact=pu.symbol) # Update product with new info for k, v in cleaned_data.items(): if k.startswith('product_'): setattr(self._product, k[len('product_'):], v) cleaned_data['product'] = self._product log.debug(self.errors) return cleaned_data def save(self): log.info(u"[%s] user:%s, resource:%s, cleaned_data:%s" % (self.__class__.__name__, self.request.user.username, self.instance, tuple(u"%s=%s" % (k, unicode(v)) for k, v in self.cleaned_data.items()))) product = self.cleaned_data['product'] product.save() self.instance.product = product self.instance.amount_available = self.cleaned_data['amount_available'] self.instance.save() class Meta: model = SupplierStock exclude = ('supplier', 'amount_available', 'product') gf_fieldsets = ((None, { 'fields': ( 'product_name', 'product_description', ('price', 'product_vat_percent'), 'product_category', ) }), (_("Distribution info"), { 'fields': ( ('product_pu', 'product_muppu', 'product_mu'), ('units_minimum_amount', 'units_per_box'), ('detail_minimum_amount', 'detail_step'), 'availability', ) }), (_("Supplier info"), { 'fields': (('code', 'supplier_category'), ) }))
class TransationPACTForm(BalanceForm): #DT Use this if we have to insert this block in the GAS economic Tab too #LF pact = forms.ModelChoiceField(label=_('pact'), queryset=GASSupplierSolidalPact.objects.none(), required=False, error_messages={'required': _('You must select one pact (or create it in your GAS details if empty)')}) amount = CurrencyField( label=_('cash amount').capitalize(), required=True, max_digits=8, decimal_places=2, help_text=_('Insert the amount of money (no sign)'), error_messages={ 'required': _('You must insert an postive or negative amount for the operation' ) }) TARGET_CHOICES = [ (INCOME, _('Correction in favor to supplier: +Supplier -GAS')), (EXPENSE, _('Correction in favor to GAS: +GAS -Supplier ')), (INVOICE_COLLECTION, _('Orders payment')) ] target = forms.ChoiceField( required=True, choices=TARGET_CHOICES, widget=forms.RadioSelect, #help_text = _("select the kind for this operation"), label=_("operation kind").capitalize(), error_messages={ 'required': _('You must select the type of operation') }) orders = forms.MultipleChoiceField( label=_("Insolute order(s)"), required=False, help_text= _("If chosen operation kind is order payment, you must select at least one order to pay" ), widget=forms.CheckboxSelectMultiple) causal = forms.CharField( label=_('Causal'), required=True, widget=forms.TextInput, help_text=_('Reason of the movement'), error_messages={ 'required': _('You must declare the causal of this transaction') }) date = forms.DateField(initial=datetime.date.today, required=True, label=_("Date"), help_text=_("Adjust the operation date if needed"), widget=DateFormatAwareWidget) def __init__(self, request, *args, **kw): super(TransationPACTForm, self).__init__(request, *args, **kw) self.__loggedusr = request.user self.__gas = request.resource.gas self.__pact = request.resource.pact self.fields['amount'].widget.attrs['class'] = 'balance input_payment' self.fields['causal'].widget.attrs['class'] = 'input_long' _choice = self.fields['target'].choices #Avoid multiple delete during post (in case of raise some exception) insolutes = self.__pact.insolutes if not insolutes: # Hide Insolute choice _choice = self.fields['target'].choices if len( _choice ) > 2: #FIXME (related to ##) BAD CHECK NO NEED if we do choices modification for form instance del _choice[-1] #FIXME (id:##) AAAA WARNING WE ARE CHANGING a CLASS ATTRIBUTE (field!) #CHECK if it is possible to do choices update in form instance #rather than in form class. Now we fix with a corresponding bad code #in the "else" branch. self.fields['target'].choices = _choice #Hide order form field del self.fields['orders'] else: #FIXME (related to ##) bad code to FIX weird behaviour described before self.fields['target'].choices = TransationPACTForm.TARGET_CHOICES choices, stat = get_html_insolutes(insolutes) self.fields['orders'].choices = choices self.fields['amount'].help_text = stat # _choice = [] # tot_orders = 0 # tot_ordered = 0 # tot_invoiced = 0 # tot_eco_entries = 0 # stat = '' # for ins in insolutes: # #WAS: #In the SUPPLIER FORM we only pay unpayed orders. # #WAS: #to modify one payed order: go to it's sheet. # #WAS: yet_payed, descr, date_payed =self.__gas.accounting.get_supplier_order_data(ins) # #WAS: yet_payed == 0: # #LF: insolutes are unpaid, so I can't see why it is needed this further check # tot_orders += 1 # tot_ordered += ins.tot_price # tot_invoiced += ins.invoice_amount or 0 # tot_eco_entries += ins.tot_curtail # stat = "Ord.%(order)s %(state)s -Fam: %(fam)s (euro)s --> Fatt: %(fatt)s (euro)s --> Pag: %(eco)s (euro)s" % { # 'fam' : "%.2f" % round(ins.tot_price, 2) # , 'fatt' : "%.2f" % round(ins.invoice_amount or 0, 2) # , 'eco' : "%.2f" % round(ins.tot_curtail, 2) # , 'state' : ins.current_state.name # , 'order' : str(ins.pk) + " - " + short_date(ins.datetime_end) # } # _choice.append((ins.pk, stat.replace('(euro)s',EURO_LABEL))) # self.fields['orders'].choices = _choice # # #set order informations # stat = "Orders(%(num)s) - Total --> Fam: %(fam)s (euro)s --> Fatt: %(fatt)s (euro)s --> Pag: %(eco)s (euro)s" % { # 'fam' : "%.2f" % round(tot_ordered, 2) # , 'fatt' : "%.2f" % round(tot_invoiced, 2) # , 'eco' : "%.2f" % round(tot_eco_entries, 2) # , 'num' : str(tot_orders) # } # self.fields['amount'].help_text = stat.replace('(euro)s',EURO_HTML) #LF # SOLIDAL PACT #LF pacts = request.resource.pacts #LF if pacts and pacts.count() > 0: #LF self.fields['pact'].queryset = pacts #LF# self.fields['pact'].initial = pacts[0] def clean(self): cleaned_data = super(TransationPACTForm, self).clean() #log.debug(u"TransationPACTForm cleaned_data %s" % cleaned_data) try: cleaned_data['economic_amount'] = abs(cleaned_data['amount']) cleaned_data['economic_target'] = cleaned_data['target'] cleaned_data['economic_causal'] = cleaned_data['causal'] if cleaned_data['economic_causal'] == '': log.error( "TransationPACTForm: transaction require a causal explanation" ) raise forms.ValidationError( ugettext("Transaction require a causal explanation")) if cleaned_data['economic_target'] == INVOICE_COLLECTION: cleaned_data['economic_orders'] = cleaned_data['orders'] if not cleaned_data['economic_orders'] or len( cleaned_data['economic_orders']) <= 0: self._errors["orders"] = self.error_class([ ugettext( "Insolute transaction require almost one order to be payed" ) ]) cleaned_data['economic_date'] = cleaned_data['date'] except KeyError, e: log.error("TransationPACTForm: cannot retrieve economic data: " + e.message) raise forms.ValidationError( ugettext("Cannot retrieve economic data: ") + e.message) # try: # GASSupplierSolidalPact.objects.get(gas=self._gas, supplier=cleaned_data['supplier']) # except GASSupplierSolidalPact.DoesNotExist: # #ok # pass # else: # raise ValidationError(ugettext("Pact between this GAS and this Supplier already exists")) return cleaned_data
class TransationGASForm(BalanceGASForm): amount = CurrencyField( label=_('cash amount').capitalize(), required=True, max_digits=8, decimal_places=2, help_text=_('Insert the amount of money (no sign)'), error_messages={ 'required': _('You must insert an postive or negative amount for the operation' ) }) target = forms.ChoiceField( required=True, choices= [(INCOME, _('Income: Event, Donate, Sponsor, Fund... +GAS')), (EXPENSE, _('Expense: Expenditure, Invoice, Bank, Administration, Event, Rent... -GAS' ))], widget=forms.RadioSelect, #help_text = _("select the kind for this operation"), label=_("operation kind").capitalize(), error_messages={ 'required': _('You must select the type of operation') }) causal = forms.CharField( label=_('Causal'), required=True, widget=forms.TextInput, help_text=_('Reason of the movement'), error_messages={ 'required': _('You must declare the causal of this transaction') }) date = forms.DateField(initial=datetime.date.today, required=True, label=_("Date"), help_text=_("Adjust the operation date if needed"), widget=DateFormatAwareWidget) def __init__(self, request, *args, **kw): super(TransationGASForm, self).__init__(request, *args, **kw) self.__loggedusr = request.user self.__gas = request.resource.gas self.fields['amount'].widget.attrs['class'] = 'balance input_payment' self.fields['causal'].widget.attrs['class'] = 'input_long' def clean(self): cleaned_data = super(TransationGASForm, self).clean() #log.debug(u"TransationGASForm cleaned_data %s" % cleaned_data) try: cleaned_data['economic_amount'] = abs(cleaned_data['amount']) cleaned_data['economic_target'] = cleaned_data['target'] cleaned_data['economic_causal'] = cleaned_data['causal'] if cleaned_data['economic_causal'] == '': log.error( "TransationGASForm: transaction require a causal explanation" ) raise forms.ValidationError( ugettext("Transaction require a causal explanation")) cleaned_data['economic_date'] = cleaned_data['date'] except KeyError, e: log.error("TransationGASForm: cannot retrieve economic data: " + e.message) raise forms.ValidationError( ugettext("Cannot retrieve economic data: ") + e.message) return cleaned_data
class InsoluteOrderForm(forms.Form): orders = forms.MultipleChoiceField( label=_("Insolute order(s)"), required=True, help_text=_("Select one or multiple orders to pay in this operation."), widget=forms.CheckboxSelectMultiple) amount = CurrencyField(label=_('Payment'), required=True, max_digits=8, decimal_places=2) causal = forms.CharField( label=_('Causal'), required=True, widget=forms.TextInput, help_text= _('Some indication about the payment: by bank or cash, bank number transaction...' ), error_messages={ 'required': _('You must declare the causal of this payment') }) date = forms.DateField(initial=datetime.date.today, required=True, label=_("Date"), help_text=_("Adjust the operation date if needed"), widget=DateFormatAwareWidget) def __init__(self, request, *args, **kw): super(InsoluteOrderForm, self).__init__(*args, **kw) #TODO: refactor for SOLIDAL PACT --> do not use order as ressource but insolutes self.__order = request.resource.order self.__gas = request.resource.gas if self.__order: #set insolute data and informations yet_payed, descr, date_payed = self.__gas.accounting.get_supplier_order_data( self.__order) if yet_payed > 0: self.fields['amount'].initial = "%.2f" % round(yet_payed, 2) self.fields['causal'].initial = descr self.fields['causal'].widget.attrs['readonly'] = True self.fields['causal'].widget.attrs['disabled'] = 'disabled' self.fields['causal'].help_text = '' self.fields['causal'].required = False self.fields['date'].initial = date_payed self.fields['date'].help_text = '' del self.fields['orders'] #set order informations stat = ugettext(u"%(state)s - %(totals)s") % { 'state': self.__order.current_state.name, 'totals': self.__order.display_totals.replace("euro", EURO_HTML) } else: insolutes = self.__order.insolutes _choice, stat = get_html_insolutes(insolutes) self.fields['orders'].choices = _choice self.fields['amount'].help_text = stat self.fields['amount'].widget.attrs['class'] = 'balance input_payment' if not self.__order.is_unpaid() and not self.__order.is_closed(): self.fields['amount'].widget.attrs['readonly'] = True self.fields['amount'].widget.attrs['disabled'] = 'disabled' self.fields['causal'].widget.attrs['class'] = 'input_long' self.__loggedusr = request.user self.__gas = self.__order.gas def clean(self): cleaned_data = super(InsoluteOrderForm, self).clean() try: cleaned_data['insolute_amount'] = abs(cleaned_data['amount']) except KeyError, e: log.error("InsoluteOrderForm: cannot retrieve economic data: " + e.message) raise forms.ValidationError( ugettext("Cannot retrieve economic data: ") + e.message) return cleaned_data
class EcoGASMemberForm(forms.Form): """Return form class for row level operation on cash ordered data use in Curtail Movement between GASMember.account --> GAS.account """ gm_id = forms.IntegerField(widget=forms.HiddenInput) original_amounted = CurrencyField(required=False, widget=forms.HiddenInput()) amounted = CurrencyField(required=False, initial=0, max_digits=8, decimal_places=2) #, widget=forms.TextInput()) applied = forms.BooleanField(required=False) #TODO: domthu: note and delete #note = forms.CharField(required=False, widget=forms.TextInput(), max_length=64) def __init__(self, request, *args, **kw): super(EcoGASMemberForm, self).__init__(*args, **kw) self.fields['amounted'].widget.attrs['class'] = 'taright' self.__loggedusr = request.user self.__order = request.resource.order def clean(self): cleaned_data = super(EcoGASMemberForm, self).clean() try: cleaned_data['gasmember'] = GASMember.objects.get( pk=cleaned_data['gm_id']) except KeyError as e: log.error(u"EcoGASMemberForm: cannot retrieve gasmember: " + e.message) raise forms.ValidationError( ugettext("Cannot retrieve gasmember: ") + e.message) except GASMember.DoesNotExist: log.error(u"EcoGASMemberForm: cannot retrieve gasmember with id " + str(cleaned_data['gm_id'])) raise forms.ValidationError( ugettext("Cannot retrieve gasmember with id ") + str(cleaned_data['gm_id'])) amounted = cleaned_data.get('amounted') enabled = cleaned_data.get('applied') if enabled: log.debug("Curtail applied. Amounted = %s" % amounted) if amounted is None: raise forms.ValidationError( ugettext( "You have to write a number (even 0) for a curtail that you want to apply" )) return cleaned_data @transaction.commit_on_success def save(self): #Control logged user KO if superuser #DT: refs = gas.cash_referrers #DT: if refs and request.user in refs: if not self.__loggedusr.has_perm(CASH, obj=ObjectWithContext(self.__order.gas)) and \ not self.__loggedusr == self.__order.referrer_person.user: raise PermissionDenied( ugettext( "You are not a cash_referrer or the order's referrer, you cannot update GASMembers cash!" )) if not self.__order.is_unpaid() and not self.__order.is_closed(): log.debug("PermissionDenied %s Order not in state closed (%s)" % (self.__loggedusr, self.__order.current_state.name)) raise PermissionDenied( ugettext("order is not in the right state!")) gm = self.cleaned_data['gasmember'] #Do economic work amounted = self.cleaned_data.get('amounted') enabled = self.cleaned_data.get('applied') if enabled and amounted is not None: log.debug(u"Save EcoGASMemberForm enabled for %s (amount=%s)" % (gm, amounted)) # This kind of amount is ever POSITIVE! amounted = abs(amounted) refs = [gm, self.__order] original_amounted = self.cleaned_data['original_amounted'] # If this is an update -> the amount of the NEW transaction # is the difference between this and the previous one comment = u"" if original_amounted is not None: comment = _( "[MOD] old_amount=%(old).2f -> new_amount=%(new).2f") % { 'old': original_amounted, 'new': amounted } amounted -= original_amounted #KO 14-04-01: # A ledger entry already exists #KO 14-04-01: if original_amounted != amounted: #KO 14-04-01: gm.gas.accounting.withdraw_from_member_account_update( #KO 14-04-01: gm, amounted, refs #KO 14-04-01: ) #KO 14-04-01: else: if amounted or (amounted is 0 and original_amounted is None): gm.gas.accounting.withdraw_from_member_account(gm, amounted, refs, self.__order, comment=comment) # # Only for test Control if yet exist some transaction for this refs. # computed_amount, existing_txs = gm.gas.accounting.get_amount_by_gas_member(gm, self.__order) # log.debug("BEFORE %(original_amounted)s %(computed_amount)s %(existing_txs)s" % { # 'computed_amount': computed_amount, # 'existing_txs': existing_txs, # 'original_amounted': original_amounted # }) #Update State if possible self.__order.control_economic_state()
class EcoGASMemberRechargeForm(forms.Form): """Return form class for row level operation on cash ordered data use in Recharge Movement between GASMember.account --> GAS.GASMember.account """ gm_id = forms.IntegerField(widget=forms.HiddenInput) recharged = CurrencyField(required=False, initial=0, max_digits=8, decimal_places=2) #TODO: domthu: note and delete #note = forms.CharField(required=False, widget=forms.TextInput(), max_length=64) def __init__(self, request, *args, **kw): super(EcoGASMemberRechargeForm, self).__init__(*args, **kw) self.fields['recharged'].widget.attrs['class'] = 'taright' self.__loggedusr = request.user self.__gas = request.resource.gas def clean(self): cleaned_data = super(EcoGASMemberRechargeForm, self).clean() try: cleaned_data['gasmember'] = GASMember.objects.get( pk=cleaned_data['gm_id']) except KeyError: log.debug( u"EcoGASMemberRechargeForm: cannot retrieve GASMember identifier. FORM ATTACK!" ) raise except GASMember.DoesNotExist: log.debug( u"EcoGASMemberRechargeForm: cannot retrieve GASMember instance. Identifier (%s)." % cleaned_data['gm_id']) raise return cleaned_data @transaction.commit_on_success def save(self): # Do economic work recharged = self.cleaned_data.get('recharged') if not recharged: # Skip without doing anything else return #Control logged user #if self.__loggedusr not in self.__order.cash_referrers: KO if superuser if not self.__loggedusr.has_perm(CASH, obj=ObjectWithContext(self.__gas)): raise PermissionDenied( ugettext( "You are not a cash_referrer, you cannot update GASMembers cash!" )) gm = self.cleaned_data['gasmember'] if not gm in self.__gas.gasmembers: log.debug( u"PermissionDenied %s in cash recharge for gasmember %s not in this gas %s" % self.__loggedusr, gm, self.__gas) raise PermissionDenied( ugettext( "You are not a cash referrer for the GAS, you cannot recharge GASMembers cash!" )) # This kind of amount is ever POSITIVE! gm.person.accounting.do_recharge(self.__gas, recharged)
class NewEcoGASMemberForm(forms.Form): """Return an empty form class for row level operation on cash ordered data use in Curtail -> ADD FAMILY Movement between GASMember.account --> GAS.account """ gasmember = forms.ModelChoiceField(queryset=GASMember.objects.none(), required=False) amounted = CurrencyField(required=False, initial=0, max_digits=8, decimal_places=2) applied = forms.BooleanField(required=False, initial=False) def __init__(self, request, *args, **kw): super(NewEcoGASMemberForm, self).__init__(*args, **kw) gm_qs = request.resource.gasmembers purchs_ids = map(lambda gm: gm.pk, request.resource.purchasers) self.fields['gasmember'].queryset = gm_qs.exclude(pk__in=purchs_ids) self.fields['amounted'].widget.attrs['class'] = 'taright' self.__loggedusr = request.user self.__order = request.resource.order def create_fake_purchaser(self, purchaser, price, note): return GASMemberOrder.objects.create( ordered_product=self.__order.orderable_products[0], ordered_amount=1, withdrawn_amount=FAKE_WITHDRAWN_AMOUNT, is_confirmed=True, note="[NEW FAM] %s" % note, #LF: ordered_price should be 0, otherwise expected amount will vary ordered_price=0, purchaser=purchaser) def clean(self): cleaned_data = super(NewEcoGASMemberForm, self).clean() return cleaned_data @transaction.commit_on_success def save(self): #Control logged user KO if superuser if not self.__loggedusr.has_perm(CASH, obj=ObjectWithContext(self.__order.gas)) and \ not self.__loggedusr == self.__order.referrer_person.user: raise PermissionDenied( ugettext( "You are not a cash_referrer or the order's referrer, you cannot update GASMembers cash!" )) if not self.__order.is_unpaid() and not self.__order.is_closed(): log.debug("PermissionDenied %s Order not in state closed (%s)" % (self.__loggedusr, self.__order.current_state.name)) raise PermissionDenied(ugettext("order is not in good state!")) #Do economic work gm = self.cleaned_data['gasmember'] amounted = self.cleaned_data.get('amounted') or 0 enabled = self.cleaned_data.get('applied') if amounted > 0 and enabled: log.debug(u"Save NewEcoGASMemberForm enabled(%s) for %s" % (enabled, gm)) amounted = abs(amounted) self.create_fake_purchaser(gm, amounted, note=ugettext("added by: %s") % self.__loggedusr) refs = [gm, self.__order] gm.gas.accounting.withdraw_from_member_account( gm, amounted, refs, self.__order)
class TransationGMForm(BalanceForm): #DT Use this if we have to insert this block in the GAS economic Tab too #LF person = forms.ModelChoiceField(queryset=Person.objects.none(), required=False, label=_("Person")) amount = CurrencyField( label=_('cash amount').capitalize(), required=True, max_digits=8, decimal_places=2, help_text=_('Insert the amount of money (no sign)'), error_messages={ 'required': _('You must insert an postive or negative amount for the operation' ) }) target = forms.ChoiceField( required=True, choices=[ (INCOME, _('Correction in favor to gasmember: +gasmember -GAS')), (EXPENSE, _('Correction in favor to GAS: +GAS -gasmember ')), (ASSET, _('Detraction from Gasmember: -gasmember ')), (LIABILITY, _('Addition to Gasmember: +gasmember ')), (EQUITY, _('Restitution in favor to gasmember: empty container +gasmember -GAS' )) ], widget=forms.RadioSelect, #help_text = _("select the kind for this operation"), label=_("operation kind").capitalize(), error_messages={ 'required': _('You must select the type of operation') }) causal = forms.CharField( label=_('Causal'), required=True, widget=forms.TextInput, help_text=_('Reason of the movement'), error_messages={ 'required': _('You must declare the causal of this transaction') }) date = forms.DateField(initial=datetime.date.today, required=True, label=_("Date"), help_text=_("Adjust the operation date if needed"), widget=DateFormatAwareWidget) def __init__(self, request, *args, **kw): super(TransationGMForm, self).__init__(request, *args, **kw) self.__loggedusr = request.user self.__gas = request.resource.gas self.__gm = request.resource.gasmember self.fields['amount'].widget.attrs['class'] = 'balance input_payment' self.fields['causal'].widget.attrs['class'] = 'input_long' def clean(self): cleaned_data = super(TransationGMForm, self).clean() #log.debug(u"TransationGMForm cleaned_data %s" % cleaned_data) try: cleaned_data['economic_amount'] = abs(cleaned_data['amount']) cleaned_data['economic_target'] = cleaned_data['target'] cleaned_data['economic_causal'] = cleaned_data['causal'] if cleaned_data['economic_causal'] == '': log.error( "TransationGMForm: transaction require a causal explanation" ) raise forms.ValidationError( ugettext("Transaction require a causal explanation")) cleaned_data['economic_date'] = cleaned_data['date'] except KeyError, e: log.error("TransationGMForm: cannot retrieve economic data: " + e.message) raise forms.ValidationError( ugettext("Cannot retrieve economic data: ") + e.message) #LF # MEMBERS #LF gms = request.resource.gasmembers #LF if gms and gms.count() > 0: #LF self.fields['person'].queryset = gms return cleaned_data